Merge branch 'develop' into negue-WIP-Push-notifications

This commit is contained in:
Blade Barringer 2015-05-11 08:18:11 -05:00
commit a7fa8dc9a4
8 changed files with 122 additions and 117 deletions

View file

@ -79,6 +79,7 @@
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html"
},
"devDependencies": {
"chai": "^2.3.0",
"coffee-coverage": "~0.4.2",
"csv": "~0.3.6",
"deep-diff": "~0.1.4",

View file

@ -8,18 +8,19 @@ global.mongoose = require("mongoose")
global.moment = require("moment")
global.async = require("async")
global._ = require("lodash")
global.expect = require("expect.js")
global.shared = require("../../common")
global.User = require("../../website/src/models/user").model
global.chai = require("chai")
global.expect = require("chai").expect
##############################
# Nconf config
##############################
path = require("path")
conf = require("nconf")
global.conf = require("nconf")
conf.argv().env().file(file: path.join(__dirname, "../config.json")).defaults()
conf.set "PORT", "1337"
global.conf = conf
##############################
# Node ENV and global variables
@ -32,8 +33,8 @@ global.user = undefined
# Helper Methods
##############################
global.expectCode = (res, code) ->
global.expect(res.body.err).to.be `undefined` if code is 200
global.expect(res.statusCode).to.be code
expect(res.body.err).to.not.exist if code is 200
expect(res.statusCode).to.equal code
global.registerNewUser = (cb, main) ->
main = true unless main?
@ -53,11 +54,11 @@ global.registerNewUser = (cb, main) ->
return cb(null, res.body) unless main
_id = res.body._id
apiToken = res.body.apiToken
global.User.findOne
User.findOne
_id: _id
apiToken: apiToken
, (err, _user) ->
expect(err).to.not.be.ok()
expect(err).to.not.be.ok
global.user = _user
request
.set("Accept", "application/json")
@ -66,8 +67,8 @@ global.registerNewUser = (cb, main) ->
cb null, res.body
global.registerManyUsers = (number, callback) ->
global.async.times number, (n, next) ->
global.registerNewUser (err, user) ->
async.times number, (n, next) ->
registerNewUser (err, user) ->
next(err, user)
, false
, (err, users) ->

View file

@ -21,8 +21,8 @@ describe "Challenges", ->
).end (res) ->
expectCode res, 200
group = res.body
expect(group.members.length).to.be 1
expect(group.leader).to.be user._id
expect(group.members.length).to.equal 1
expect(group.leader).to.equal user._id
done()
]
@ -55,10 +55,10 @@ describe "Challenges", ->
], (err, results) ->
_user = results[0]
challenge = results[1]
expect(_user.dailys[_user.dailys.length - 1].text).to.be "Challenge Daily"
expect(_user.dailys[_user.dailys.length - 1].text).to.equal "Challenge Daily"
updateTodo = _user.todos[_user.todos.length - 1]
expect(updateTodo.text).to.be "Challenge Todo 2"
expect(challenge.official).to.be false
expect(updateTodo.text).to.equal "Challenge Todo 2"
expect(challenge.official).to.equal false
user = _user
done()
@ -74,16 +74,16 @@ describe "Challenges", ->
setTimeout (->
User.findById user._id, (err, _user) ->
expectCode res, 200
expect(_user.dailys[_user.dailys.length - 1].text).to.be "Updated Daily"
expect(res.body.todos[0].notes).to.be "Challenge Updated Todo Notes"
expect(_user.todos[_user.todos.length - 1].notes).to.be "User overriden notes"
expect(_user.dailys[_user.dailys.length - 1].text).to.equal "Updated Daily"
expect(res.body.todos[0].notes).to.equal "Challenge Updated Todo Notes"
expect(_user.todos[_user.todos.length - 1].notes).to.equal "User overriden notes"
user = _user
done()
), 500 # we have to wait a while for users' tasks to be updated, called async on server
it "Shows user notes on challenge page", (done) ->
request.get(baseURL + "/challenges/" + challenge._id + "/member/" + user._id).end (res) ->
expect(res.body.todos[res.body.todos.length - 1].notes).to.be "User overriden notes"
expect(res.body.todos[res.body.todos.length - 1].notes).to.equal "User overriden notes"
done()
it "Complete To-Dos", (done) ->
@ -92,7 +92,7 @@ describe "Challenges", ->
numTasks = (_.size(u.todos))
request.post(baseURL + "/user/tasks/" + u.todos[0].id + "/up").end (res) ->
request.post(baseURL + "/user/tasks/clear-completed").end (res) ->
expect(_.size(res.body)).to.be numTasks - 1
expect(_.size(res.body)).to.equal numTasks - 1
done()
it "Challenge deleted, breaks task link", (done) ->
@ -101,18 +101,18 @@ describe "Challenges", ->
User.findById user._id, (err, user) ->
len = user.dailys.length - 1
daily = user.dailys[user.dailys.length - 1]
expect(daily.challenge.broken).to.be "CHALLENGE_DELETED"
expect(daily.challenge.broken).to.equal "CHALLENGE_DELETED"
# Now let's handle if challenge was deleted, but didn't get to update all the users (an error)
unset = $unset: {}
unset["$unset"]["dailys." + len + ".challenge.broken"] = 1
User.findByIdAndUpdate user._id, unset, (err, user) ->
expect(err).to.not.be.ok()
expect(user.dailys[len].challenge.broken).to.not.be.ok()
expect(err).to.not.exist
expect(user.dailys[len].challenge.broken).to.not.exist
request.post(baseURL + "/user/tasks/" + daily.id + "/up").end (res) ->
setTimeout (->
User.findById user._id, (err, user) ->
expect(user.dailys[len].challenge.broken).to.be "CHALLENGE_DELETED"
expect(user.dailys[len].challenge.broken).to.equal "CHALLENGE_DELETED"
done()
), 100 # we need to wait for challenge to update user, it's a background job for perf reasons
@ -121,7 +121,7 @@ describe "Challenges", ->
$set:
"contributor.admin": true
, (err, _user) ->
expect(err).to.not.be.ok()
expect(err).to.not.exist
async.parallel [
(cb) ->
request.post(baseURL + "/challenges").send(
@ -132,7 +132,7 @@ describe "Challenges", ->
habits: []
official: false
).end (res) ->
expect(res.body.official).to.be false
expect(res.body.official).to.equal false
cb()
(cb) ->
request.post(baseURL + "/challenges").send(
@ -143,6 +143,6 @@ describe "Challenges", ->
habits: []
official: true
).end (res) ->
expect(res.body.official).to.be true
expect(res.body.official).to.equal true
cb()
], done

View file

@ -38,9 +38,9 @@ describe "Coupons", ->
expectCode res, 200
Coupon.find { event: 'wondercon' }, (err, _coupons) ->
coupons = _coupons
expect(coupons.length).to.be.eql 10
expect(coupons.length).to.equal 10
_(coupons).each (c)->
expect(c.event).to.be.eql 'wondercon'
expect(c.event).to.equal 'wondercon'
done()
context "while regular user", ->
@ -54,7 +54,7 @@ describe "Coupons", ->
.post(baseURL + '/coupons/generate/wondercon' + queries)
.end (res) ->
expectCode res, 401
expect(res.body.err).to.be.eql 'You don\'t have admin access'
expect(res.body.err).to.equal 'You don\'t have admin access'
done()
describe "GET /api/v2/coupons", ->
@ -123,7 +123,7 @@ describe "Coupons", ->
.get(baseURL + '/coupons' + queries)
.end (res) ->
expectCode res, 401
expect(res.body.err).to.be.eql 'You don\'t have admin access'
expect(res.body.err).to.equal 'You don\'t have admin access'
done()
describe "POST /api/v2/user/coupon/:code", ->
@ -131,7 +131,7 @@ describe "Coupons", ->
items = ['body_special_wondercon_gold'
'body_special_wondercon_black'
'body_special_wondercon_red'
'back_special_wondercon_gold'
'back_special_wondercon_red'
'back_special_wondercon_black'
'back_special_wondercon_red'
'eyewear_special_wondercon_black'
@ -139,9 +139,9 @@ describe "Coupons", ->
_(items).each (i) ->
if(has)
expect(gear[i]).to.be.ok
expect(gear[i]).to.exist
else
expect(gear[i]).to.not.be.ok
expect(gear[i]).to.not.exist
beforeEach (done) ->
registerNewUser ->
@ -170,7 +170,7 @@ describe "Coupons", ->
.post(baseURL + '/user/coupon/' + code)
.end (res) ->
expectCode res, 400
expect(res.body.err).to.be.eql "Coupon already used"
expect(res.body.err).to.equal "Coupon already used"
User.findById user._id, (err, _user) ->
gear = _user.items.gear.owned
specialGear(gear, false)
@ -184,7 +184,7 @@ describe "Coupons", ->
.post(baseURL + '/user/coupon/' + code)
.end (res) ->
expectCode res, 400
expect(res.body.err).to.be.eql "Invalid coupon code"
expect(res.body.err).to.equal "Invalid coupon code"
User.findById user._id, (err, _user) ->
gear = _user.items.gear.owned
specialGear(gear, false)

View file

@ -18,8 +18,8 @@ describe "Groups", ->
).end (res) ->
expectCode res, 200
group = res.body
expect(group.members.length).to.be 1
expect(group.leader).to.be user._id
expect(group.members.length).to.equal 1
expect(group.leader).to.equal user._id
done()
]
@ -42,8 +42,8 @@ describe "Groups", ->
).end (res) ->
expectCode res, 200
guild = res.body
expect(guild.members.length).to.be 1
expect(guild.leader).to.be user._id
expect(guild.members.length).to.equal 1
expect(guild.leader).to.equal user._id
#Add members to guild
async.waterfall [
(cb) ->
@ -69,7 +69,7 @@ describe "Groups", ->
.end (res) ->
g = res.body
userInGroup = _.find g.members, (member) -> return member._id == user._id
expect(userInGroup).to.not.be undefined
expect(userInGroup).to.exist
done()
it "excludes user from viewing private group member list when user is not a member", (done) ->
@ -91,8 +91,8 @@ describe "Groups", ->
).end (res) ->
expectCode res, 200
guild = res.body
expect(guild.members.length).to.be 1
expect(guild.leader).to.be user._id
expect(guild.members.length).to.equal 1
expect(guild.leader).to.equal user._id
#Add members to guild
async.waterfall [
(cb) ->
@ -116,9 +116,9 @@ describe "Groups", ->
request.get(baseURL + "/groups/" + guild._id)
.end (res) ->
g = res.body
expect(g.members.length).to.be 15
expect(g.members.length).to.equal 15
userInGroup = _.find g.members, (member) -> return member._id == user._id
expect(userInGroup).to.not.be undefined
expect(userInGroup).to.exist
done()
@ -130,9 +130,9 @@ describe "Groups", ->
request.get(baseURL + "/groups/" + guild._id)
.end (res) ->
g = res.body
expect(g.members.length).to.be 15
expect(g.members.length).to.equal 15
userInGroup = _.find g.members, (member) -> return member._id == user._id
expect(userInGroup).to.be undefined
expect(userInGroup).to.not.exist
done()
describe "Party", ->
it "can be found by querying for party", (done) ->
@ -142,11 +142,13 @@ describe "Groups", ->
expectCode res, 200
party = res.body[0]
expect(party._id).to.be group._id
expect(party.leader).to.be user._id
expect(party.name).to.be group.name
expect(party.quest).to.be.eql { progress: {} }
expect(party.memberCount).to.be group.memberCount
console.log("*******")
console.log(party.quest)
expect(party._id).to.equal group._id
expect(party.leader).to.equal user._id
expect(party.name).to.equal group.name
expect(party.quest).to.deep.equal { progress: {} }
expect(party.memberCount).to.equal group.memberCount
done()
describe "Chat", ->
@ -158,16 +160,16 @@ describe "Groups", ->
expectCode res, 200
chat = res.body.message
expect(chat.id).to.be.ok
expect(chat.text).to.be.eql msg
expect(chat.text).to.equal msg
expect(chat.timestamp).to.be.ok
expect(chat.likes).to.be.empty
expect(chat.flags).to.be.empty
expect(chat.flagCount).to.be 0
expect(chat.flagCount).to.equal 0
expect(chat.uuid).to.be.ok
expect(chat.contributor).to.be.empty
expect(chat.backer).to.be.empty
expect(chat.uuid).to.be user._id
expect(chat.user).to.be user.profile.name
expect(chat.uuid).to.equal user._id
expect(chat.user).to.equal user.profile.name
done()
it "Does not post an empty message", (done) ->
@ -175,7 +177,7 @@ describe "Groups", ->
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg).send(
).end (res) ->
expectCode res, 400
expect(res.body.err).to.be.eql 'You cannot send a blank message'
expect(res.body.err).to.equal 'You cannot send a blank message'
done()
it "can not like own chat message", (done) ->
@ -183,7 +185,7 @@ describe "Groups", ->
).end (res) ->
expectCode res, 401
body = res.body
expect(body.err).to.be "Can't like your own message. Don't be that person."
expect(body.err).to.equal "Can't like your own message. Don't be that person."
done()
it "can not flag own message", (done) ->
@ -191,7 +193,7 @@ describe "Groups", ->
).end (res) ->
expectCode res, 401
body = res.body
expect(body.err).to.be "Can't report your own message."
expect(body.err).to.equal "Can't report your own message."
done()
it "Gets chat messages from party chat", (done) ->
@ -199,15 +201,16 @@ describe "Groups", ->
).end (res) ->
expectCode res, 200
message = res.body[0]
expect(message.id).to.be chat.id
expect(message.timestamp).to.be chat.timestamp
expect(message.likes).to.be.eql chat.likes
expect(message.flags).to.be.eql chat.flags
expect(message.flagCount).to.be chat.flagCount
expect(message.uuid).to.be chat.uuid
expect(message.contributor).to.be.eql chat.contributor
expect(message.backer).to.be.eql chat.backer
expect(message.user).to.be chat.user
console.log(message)
expect(message.id).to.equal chat.id
expect(message.timestamp).to.equal chat.timestamp
expect(message.likes).to.deep.equal chat.likes
expect(message.flags).to.deep.equal chat.flags
expect(message.flagCount).to.equal chat.flagCount
expect(message.uuid).to.equal chat.uuid
expect(message.contributor).to.deep.equal chat.contributor
expect(message.backer).to.deep.equal chat.backer
expect(message.user).to.equal chat.user
done()
it "Deletes a chat messages from party chat", (done) ->
@ -222,7 +225,7 @@ describe "Groups", ->
).end (res) ->
expectCode res, 404
body = res.body
expect(body.err).to.be "Message not found!"
expect(body.err).to.equal "Message not found!"
done()
describe "Quests", ->
@ -333,7 +336,7 @@ describe "Groups", ->
(whatever, cb) ->
Group.findById group._id, (err, g) ->
group = g
expect(g.members.length).to.be 4
expect(g.members.length).to.equal 4
cb()
], ->
@ -354,13 +357,13 @@ describe "Groups", ->
Group.findById group._id, cb
(_group, cb) ->
expect(_group.quest.key).to.be "vice3"
expect(_group.quest.active).to.be false
expect(_group.quest.key).to.equal "vice3"
expect(_group.quest.active).to.equal false
request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[0]._id).set("X-API-Key", party[0].apiToken).end ->
request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[1]._id).set("X-API-Key", party[1].apiToken).end (res) ->
request.post(baseURL + "/groups/" + group._id + "/questReject").set("X-API-User", party[2]._id).set("X-API-Key", party[2].apiToken).end (res) ->
group = res.body
expect(group.quest.active).to.be true
expect(group.quest.active).to.equal true
cb()
], done
@ -375,10 +378,10 @@ describe "Groups", ->
#expect(res.body.stats.mp).to.be.below(mp);
request.get(baseURL + "/members/" + party[0]._id).end (res) ->
member = res.body
expect(member.achievements.snowball).to.be 1
expect(member.stats.buffs.snowball).to.be true
expect(member.achievements.snowball).to.equal 1
expect(member.stats.buffs.snowball).to.exist
difference = diff(member, party[0])
expect(_.size(difference)).to.be 2
expect(_.size(difference)).to.equal 2
# level up user so str is > 0
request.put(baseURL + "/user").send("stats.lvl": 5).end (res) ->
@ -388,12 +391,12 @@ describe "Groups", ->
request.post(baseURL + "/user/class/cast/valorousPresence?targetType=party").end (res) ->
request.get(baseURL + "/members/" + member._id).end (res) ->
expect(res.body.stats.buffs.str).to.be.above 0
expect(diff(res.body, member).length).to.be 1
expect(diff(res.body, member).length).to.equal 1
done()
it "Doesn't include people who aren't participating", (done) ->
request.get(baseURL + "/groups/" + group._id).end (res) ->
expect(_.size(res.body.quest.members)).to.be 3
expect(_.size(res.body.quest.members)).to.equal 3
done()
xit "Hurts the boss", (done) ->
@ -516,31 +519,31 @@ describe "Groups", ->
Group.findById "habitrpg", (err, tavern) ->
#use an explicit get because mongoose wraps the null in an object
expect(_.isEmpty(tavern.get("quest"))).to.be true
expect(user.items.pets["MantisShrimp-Base"]).to.be 5
expect(user.items.mounts["MantisShrimp-Base"]).to.be true
expect(user.items.eggs.Dragon).to.be 2
expect(user.items.hatchingPotions.Shade).to.be 2
expect(_.isEmpty(tavern.get("quest"))).to.equal true
expect(user.items.pets["MantisShrimp-Base"]).to.equal 5
expect(user.items.mounts["MantisShrimp-Base"]).to.equal true
expect(user.items.eggs.Dragon).to.equal 2
expect(user.items.hatchingPotions.Shade).to.equal 2
cb2()
# Party Boss
(cb2) ->
#use an explicit get because mongoose wraps the null in an object
expect(_.isEmpty(_group.get("quest"))).to.be true
expect(user.items.gear.owned.weapon_special_2).to.be true
expect(user.items.eggs.Dragon).to.be 2
expect(user.items.hatchingPotions.Shade).to.be 2
expect(_.isEmpty(_group.get("quest"))).to.equal true
expect(user.items.gear.owned.weapon_special_2).to.equal true
expect(user.items.eggs.Dragon).to.equal 2
expect(user.items.hatchingPotions.Shade).to.equal 2
# need to fetch users to get updated data
async.parallel [
(cb3) ->
User.findById party[0].id, (err, mbr) ->
expect(mbr.items.gear.owned.weapon_special_2).to.be true
expect(mbr.items.gear.owned.weapon_special_2).to.equal true
cb3()
(cb3) ->
User.findById party[1].id, (err, mbr) ->
expect(mbr.items.gear.owned.weapon_special_2).to.be true
expect(mbr.items.gear.owned.weapon_special_2).to.equal true
cb3()
(cb3) ->
User.findById party[2].id, (err, mbr) ->

View file

@ -8,8 +8,8 @@ describe "Site Status", ->
it "/api/v2/status", (done) ->
request.get(baseURL + "/status").set("Accept", "application/json").end (res) ->
expect(res.statusCode).to.be 200
expect(res.body.status).to.be "up"
expect(res.statusCode).to.equal 200
expect(res.body.status).to.equal "up"
done()
it "/api/v2/user", (done) ->
@ -19,8 +19,8 @@ describe "Site Status", ->
.set("X-API-User", '')
.set("X-API-Key", '')
.end (res) ->
expect(res.statusCode).to.be 401
expect(res.body.err).to.be "You must include a token and uid (user id) in your request"
expect(res.statusCode).to.equal 401
expect(res.body.err).to.equal "You must include a token and uid (user id) in your request"
done()
describe "With token or user id", ->
@ -30,12 +30,12 @@ describe "Site Status", ->
it "/api/v2/status", (done) ->
request.get(baseURL + "/status").set("Accept", "application/json").end (res) ->
expect(res.statusCode).to.be 200
expect(res.body.status).to.be "up"
expect(res.statusCode).to.equal 200
expect(res.body.status).to.equal "up"
done()
it "/api/v2/user", (done) ->
request.get(baseURL + "/user").set("Accept", "application/json").end (res) ->
expect(res.statusCode).to.be 200
expect(res.body._id).to.be user._id
expect(res.statusCode).to.equal 200
expect(res.body._id).to.equal user._id
done()

View file

@ -13,29 +13,29 @@ describe "Subscriptions", ->
user.lastCron = moment().subtract(1, "d")
user.fns.cron()
expect(user.purchased.plan.customerId).to.not.be.ok()
expect(user.purchased.plan.customerId).to.not.exist
payments.createSubscription
user: user
customerId: "123"
paymentMethod: "Stripe"
sub: {key: 'basic_6mo'}
expect(user.purchased.plan.customerId).to.be.ok()
expect(user.purchased.plan.customerId).to.exist
shared.wrap user
cron()
expect(user.purchased.plan.customerId).to.be.ok()
expect(user.purchased.plan.customerId).to.exist
payments.cancelSubscription user: user
cron()
expect(user.purchased.plan.customerId).to.be.ok()
expect(user.purchased.plan.dateTerminated).to.be.ok()
expect(user.purchased.plan.customerId).to.exist
expect(user.purchased.plan.dateTerminated).to.exist
user.purchased.plan.dateTerminated = moment().subtract(2, "d")
cron()
expect(user.purchased.plan.customerId).to.not.be.ok()
expect(user.purchased.plan.customerId).to.not.exist
payments.createSubscription
user: user
customerId: "123"
paymentMethod: "Stripe"
sub: {key: 'basic_6mo'}
expect(user.purchased.plan.dateTerminated).to.not.be.ok()
expect(user.purchased.plan.dateTerminated).to.not.exist
done()

View file

@ -34,7 +34,7 @@ describe "Todos", ->
]).end (res) ->
expectCode res, 200
# Expect number of todos to be 3 greater than the number the user started with
expect(_.size(res.body.todos)).to.be numTasks + 3
expect(_.size(res.body.todos)).to.equal numTasks + 3
# Assign new number to numTasks variable
numTasks += 3
request.post(baseURL + "/user/batch-update?_v=998").send([
@ -58,7 +58,7 @@ describe "Todos", ->
}
]).end (res) ->
expectCode res, 200
expect(_.size(res.body.todos)).to.be numTasks
expect(_.size(res.body.todos)).to.equal numTasks
request.post(baseURL + "/user/batch-update?_v=997").send([
{
op: "updateTask"
@ -78,7 +78,7 @@ describe "Todos", ->
}
]).end (res) ->
# Expect todos to be 2 less than the total count
expect(_.size(res.body.todos)).to.be numTasks - 2
expect(_.size(res.body.todos)).to.equal numTasks - 2
done()
describe "Creating, Updating, Deleting Todos", ->
@ -92,9 +92,9 @@ describe "Todos", ->
).end (res) ->
expectCode res, 200
todo = res.body
expect(todo.text).to.be "Sample Todo"
expect(todo.text).to.equal "Sample Todo"
expect(todo.id).to.be.ok
expect(todo.value).to.be 0
expect(todo.value).to.equal 0
done()
describe "Updating todos", ->
@ -104,7 +104,7 @@ describe "Todos", ->
).end (res) ->
expectCode res, 200
updateTodo = res.body
expect(updateTodo.id).to.be todo.id
expect(updateTodo.id).to.equal todo.id
done()
it "Does not update type of todo", (done) ->
@ -113,7 +113,7 @@ describe "Todos", ->
).end (res) ->
expectCode res, 200
updateTodo = res.body
expect(updateTodo.type).to.be todo.type
expect(updateTodo.type).to.equal todo.type
done()
it "Does update text, attribute, priority, value, notes", (done) ->
@ -126,11 +126,11 @@ describe "Todos", ->
).end (res) ->
expectCode res, 200
todo = res.body
expect(todo.text).to.be "Changed Title"
expect(todo.attribute).to.be "int"
expect(todo.priority).to.be 1.5
expect(todo.value).to.be 5
expect(todo.notes).to.be "Some notes"
expect(todo.text).to.equal "Changed Title"
expect(todo.attribute).to.equal "int"
expect(todo.priority).to.equal 1.5
expect(todo.value).to.equal 5
expect(todo.notes).to.equal "Some notes"
done()
describe "Deleting todos", ->
@ -147,7 +147,7 @@ describe "Todos", ->
).end (res) ->
expectCode res, 404
body = res.body
expect(body.err).to.be "Task not found."
expect(body.err).to.equal "Task not found."
done()
it "Does not update text, attribute, priority, value, notes if task is already deleted", (done) ->
@ -160,6 +160,6 @@ describe "Todos", ->
).end (res) ->
expectCode res, 404
body = res.body
expect(body.err).to.be "Task not found."
expect(body.err).to.equal "Task not found."
done()