Files
habitica/test/api/challenges.coffee
2015-08-16 09:45:01 -05:00

344 lines
11 KiB
CoffeeScript

'use strict'
app = require("../../website/src/server")
Group = require("../../website/src/models/group").model
Challenge = require("../../website/src/models/challenge").model
describe "Challenges", ->
challenge = undefined
updateTodo = undefined
group = undefined
beforeEach (done) ->
async.waterfall [
(cb) ->
registerNewUser(cb, true)
, (user, cb) ->
request.post(baseURL + "/groups").send(
name: "TestGroup"
type: "party"
).end (res) ->
expectCode res, 200
group = res.body
expect(group.members.length).to.equal 1
expect(group.leader).to.equal user._id
cb()
, (cb) ->
request.post(baseURL + "/challenges").send(
group: group._id
dailys: [
type: "daily"
text: "Challenge Daily"
]
todos: [{
type: "todo"
text: "Challenge Todo 1"
notes: "Challenge Notes"
}]
rewards: []
habits: []
).end (res) ->
challenge = res.body
done()
]
describe 'POST /challenge', ->
it "Creates a challenge", (done) ->
request.post(baseURL + "/challenges").send(
group: group._id
dailys: [
type: "daily"
text: "Challenge Daily"
]
todos: [{
type: "todo"
text: "Challenge Todo 1"
notes: "Challenge Notes"
}, {
type: "todo"
text: "Challenge Todo 2"
notes: "Challenge Notes"
}]
rewards: []
habits: []
official: true
).end (res) ->
expectCode res, 200
async.parallel [
(cb) ->
User.findById user._id, cb
(cb) ->
Challenge.findById res.body._id, cb
], (err, results) ->
user = results[0]
challenge = results[1]
expect(user.dailys[user.dailys.length - 1].text).to.equal "Challenge Daily"
expect(challenge.official).to.equal false
done()
describe 'POST /challenge/:cid', ->
it "updates the notes on user's version of a challenge task's note without updating the challenge", (done) ->
updateTodo = challenge.todos[0]
updateTodo.notes = "User overriden notes"
async.waterfall [
(cb) ->
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (res) ->
cb()
, (cb) ->
Challenge.findById challenge._id, cb
, (chal, cb) ->
expect(chal.todos[0].notes).to.eql("Challenge Notes")
cb()
, (cb) ->
request.get(baseURL + "/user/tasks/" + updateTodo.id)
.end (res) ->
expect(res.body.notes).to.eql("User overriden notes")
done()
]
it "changes user's copy of challenge tasks when the challenge is updated", (done) ->
challenge.dailys[0].text = "Updated Daily"
request.post(baseURL + "/challenges/" + challenge._id)
.send(challenge)
.end (res) ->
challenge = res.body
expect(challenge.dailys[0].text).to.equal "Updated Daily"
User.findById user._id, (err, _user) ->
expectCode res, 200
expect(_user.dailys[_user.dailys.length - 1].text).to.equal "Updated Daily"
done()
it "does not changes user's notes on tasks when challenge task notes are updated", (done) ->
challenge.todos[0].notes = "Challenge Updated Todo Notes"
request.post(baseURL + "/challenges/" + challenge._id)
.send(challenge)
.end (res) ->
challenge = res.body
expect(challenge.todos[0].notes).to.equal "Challenge Updated Todo Notes"
User.findById user._id, (err, _user) ->
expectCode res, 200
expect(_user.todos[_user.todos.length - 1].notes).to.equal "Challenge Notes"
done()
it "shows user notes on challenge page", (done) ->
updateTodo = challenge.todos[0]
updateTodo.notes = "User overriden notes"
async.waterfall [
(cb) ->
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (res) ->
cb()
, (cb) ->
Challenge.findById challenge._id, cb
, (chal, cb) ->
expect(chal.todos[0].notes).to.eql("Challenge Notes")
cb()
, (cb) ->
request.get(baseURL + "/challenges/" + challenge._id + "/member/" + user._id).end (res) ->
expect(res.body.todos[res.body.todos.length - 1].notes).to.equal "User overriden notes"
done()
]
it "Complete To-Dos", (done) ->
User.findById user._id, (err, _user) ->
u = _user
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.equal numTasks - 1
done()
it "Challenge deleted, breaks task link", (done) ->
itThis = this
request.del(baseURL + "/challenges/" + challenge._id).end (res) ->
User.findById user._id, (err, user) ->
len = user.dailys.length - 1
daily = user.dailys[user.dailys.length - 1]
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.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.equal "CHALLENGE_DELETED"
done()
), 100 # we need to wait for challenge to update user, it's a background job for perf reasons
it "admin creates a challenge", (done) ->
User.findByIdAndUpdate user._id,
$set:
"contributor.admin": true
, (err, _user) ->
expect(err).to.not.exist
async.parallel [
(cb) ->
request.post(baseURL + "/challenges").send(
group: group._id
dailys: []
todos: []
rewards: []
habits: []
official: false
).end (res) ->
expect(res.body.official).to.equal false
cb()
(cb) ->
request.post(baseURL + "/challenges").send(
group: group._id
dailys: []
todos: []
rewards: []
habits: []
official: true
).end (res) ->
expect(res.body.official).to.equal true
cb()
], done
it "User creates a non-tavern challenge with prize, deletes it, gets refund", (done) ->
User.findByIdAndUpdate user._id,
$set:
"balance": 8
, (err, user) ->
expect(err).to.not.be.ok
request.post(baseURL + "/challenges").send(
group: group._id
dailys: []
todos: []
rewards: []
habits: []
prize: 10
).end (res) ->
expect(res.body.prize).to.equal 10
async.parallel [
(cb) ->
User.findById user._id, cb
(cb) ->
Challenge.findById res.body._id, cb
], (err, results) ->
user = results[0]
challenge = results[1]
expect(user.balance).to.equal 5.5
request.del(baseURL + "/challenges/" + challenge._id).end (res) ->
User.findById user._id, (err, _user) ->
expect(_user.balance).to.equal 8
done()
it "User creates a tavern challenge with prize, deletes it, and does not get refund", (done) ->
User.findByIdAndUpdate user._id,
$set:
"balance": 8
, (err, user) ->
expect(err).to.not.be.ok
request.post(baseURL + "/challenges").send(
group: 'habitrpg'
dailys: []
todos: []
rewards: []
habits: []
prize: 10
).end (res) ->
expect(res.body.prize).to.equal 10
async.parallel [
(cb) ->
User.findById user._id, cb
(cb) ->
Challenge.findById res.body._id, cb
], (err, results) ->
user = results[0]
challenge = results[1]
expect(user.balance).to.equal 5.5
request.del(baseURL + "/challenges/" + challenge._id).end (res) ->
User.findById user._id, (err, _user) ->
expect(_user.balance).to.equal 5.5
done()
describe "non-owner permissions", () ->
challenge = undefined
beforeEach (done) ->
async.waterfall [
(cb) ->
request.post(baseURL + "/challenges").send(
group: group._id
name: 'challenge name'
dailys: [
type: "daily"
text: "Challenge Daily"
]
).end (res) ->
challenge = res.body
cb()
(cb) ->
registerNewUser(done, true)
]
context "non-owner", () ->
it 'can not edit challenge', (done) ->
challenge.name = 'foobar'
request.post(baseURL + "/challenges/" + challenge._id)
.send(challenge)
.end (res) ->
error = res.body.err
expect(error).to.eql("You don't have permissions to edit this challenge")
done()
it 'can not close challenge', (done) ->
request.post(baseURL + "/challenges/" + challenge._id + "/close?uid=" + user._id)
.end (res) ->
error = res.body.err
expect(error).to.eql("You don't have permissions to close this challenge")
done()
it 'can not delete challenge', (done) ->
request.del(baseURL + "/challenges/" + challenge._id)
.end (res) ->
error = res.body.err
expect(error).to.eql("You don't have permissions to delete this challenge")
done()
context "non-owner that is an admin", () ->
beforeEach (done) ->
User.findByIdAndUpdate(user._id, { 'contributor.admin': true }, done)
it 'can edit challenge', (done) ->
challenge.name = 'foobar'
request.post(baseURL + "/challenges/" + challenge._id)
.send(challenge)
.end (res) ->
expect(res.body.err).to.not.exist
Challenge.findById challenge._id, (err, chal) ->
expect(chal.name).to.eql('foobar')
done()
it 'can close challenge', (done) ->
request.post(baseURL + "/challenges/" + challenge._id + "/close?uid=" + user._id)
.end (res) ->
expect(res.body.err).to.not.exist
User.findById user._id, (err, usr) ->
expect(usr.achievements.challenges[0]).to.eql(challenge.name)
done()
it 'can delete challenge', (done) ->
request.del(baseURL + "/challenges/" + challenge._id)
.end (res) ->
expect(res.body.err).to.not.exist
request.get(baseURL + "/challenges/" + challenge._id)
.end (res) ->
error = res.body.err
expect(error).to.eql("Challenge #{challenge._id} not found")
done()