Convert coffee tests to js

This commit is contained in:
Blade Barringer
2015-11-15 08:19:29 -06:00
parent e5d99ce271
commit da881153b9
18 changed files with 2184 additions and 1837 deletions

View File

@@ -1,346 +0,0 @@
'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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, res) ->
request.post(baseURL + "/user/tasks/clear-completed").end (err, 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 (err, 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, {new: true}, (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 (err, 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
, {new: 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 (err, 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 (err, 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,
, {new: true}
, (err, user) ->
expect(err).to.not.be.ok
request.post(baseURL + "/challenges").send(
group: group._id
dailys: []
todos: []
rewards: []
habits: []
prize: 10
).end (err, 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 (err, 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,
, {new: true}
, (err, user) ->
expect(err).to.not.be.ok
request.post(baseURL + "/challenges").send(
group: 'habitrpg'
dailys: []
todos: []
rewards: []
habits: []
prize: 10
).end (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 (err, 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 }, {new: true}, done)
it 'can edit challenge', (done) ->
challenge.name = 'foobar'
request.post(baseURL + "/challenges/" + challenge._id)
.send(challenge)
.end (err, 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 (err, 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 (err, res) ->
expect(res.body.err).to.not.exist
request.get(baseURL + "/challenges/" + challenge._id)
.end (err, res) ->
error = res.body.err
expect(error).to.eql("Challenge #{challenge._id} not found")
done()

View File

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

View File

@@ -1,73 +0,0 @@
'use strict'
diff = require("deep-diff")
Group = require("../../website/src/models/group").model
app = require("../../website/src/server")
describe "Chat", ->
group = undefined
before (done) ->
async.waterfall [
(cb) ->
registerNewUser(cb, true)
(user, cb) ->
request.post(baseURL + "/groups").send(
name: "TestGroup"
type: "party"
).end (err, res) ->
expectCode res, 200
group = res.body
expect(group.members.length).to.equal 1
expect(group.leader).to.equal user._id
cb()
], done
chat = undefined
it "removes a user's chat notifications when user is kicked", (done) ->
userToRemove = null
async.waterfall [
(cb) ->
registerManyUsers 1, cb
(members, cb) ->
userToRemove = members[0]
request.post(baseURL + "/groups/" + group._id + "/invite").send(
uuids: [userToRemove._id]
)
.end -> cb()
(cb) ->
request.post(baseURL + "/groups/" + group._id + "/join")
.set("X-API-User", userToRemove._id)
.set("X-API-Key", userToRemove.apiToken)
.end (err, res) -> cb()
(cb) ->
msg = "TestMsg"
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg)
.end (err, res) -> cb()
(cb) ->
request.get(baseURL + "/user")
.set("X-API-User", userToRemove._id)
.set("X-API-Key", userToRemove.apiToken)
.end (err, res) ->
expect(res.body.newMessages[group._id]).to.exist
cb()
(cb) ->
request.post(baseURL + "/groups/" + group._id + "/removeMember?uuid=" + userToRemove._id)
.end (err, res) -> cb()
(cb) ->
request.get(baseURL + "/user")
.set("X-API-User", userToRemove._id)
.set("X-API-Key", userToRemove.apiToken)
.end (err, res) ->
expect(res.body.newMessages[group._id]).to.not.exist
cb()
], done

75
test/api-legacy/chat.js Normal file
View File

@@ -0,0 +1,75 @@
(function() {
'use strict';
var Group, app, diff;
diff = require("deep-diff");
Group = require("../../website/src/models/group").model;
app = require("../../website/src/server");
describe("Chat", function() {
var chat, group;
group = void 0;
before(function(done) {
return async.waterfall([
function(cb) {
return registerNewUser(cb, true);
}, function(user, cb) {
return request.post(baseURL + "/groups").send({
name: "TestGroup",
type: "party"
}).end(function(err, res) {
expectCode(res, 200);
group = res.body;
expect(group.members.length).to.equal(1);
expect(group.leader).to.equal(user._id);
return cb();
});
}
], done);
});
chat = void 0;
return it("removes a user's chat notifications when user is kicked", function(done) {
var userToRemove;
userToRemove = null;
return async.waterfall([
function(cb) {
return registerManyUsers(1, cb);
}, function(members, cb) {
userToRemove = members[0];
return request.post(baseURL + "/groups/" + group._id + "/invite").send({
uuids: [userToRemove._id]
}).end(function() {
return cb();
});
}, function(cb) {
return request.post(baseURL + "/groups/" + group._id + "/join").set("X-API-User", userToRemove._id).set("X-API-Key", userToRemove.apiToken).end(function(err, res) {
return cb();
});
}, function(cb) {
var msg;
msg = "TestMsg";
return request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg).end(function(err, res) {
return cb();
});
}, function(cb) {
return request.get(baseURL + "/user").set("X-API-User", userToRemove._id).set("X-API-Key", userToRemove.apiToken).end(function(err, res) {
expect(res.body.newMessages[group._id]).to.exist;
return cb();
});
}, function(cb) {
return request.post(baseURL + "/groups/" + group._id + "/removeMember?uuid=" + userToRemove._id).end(function(err, res) {
return cb();
});
}, function(cb) {
return request.get(baseURL + "/user").set("X-API-User", userToRemove._id).set("X-API-Key", userToRemove.apiToken).end(function(err, res) {
expect(res.body.newMessages[group._id]).to.not.exist;
return cb();
});
}
], done);
});
});
}).call(this);

View File

@@ -1,191 +0,0 @@
'use strict'
app = require("../../website/src/server")
Coupon = require("../../website/src/models/coupon").model
makeSudoUser = (usr, cb) ->
registerNewUser ->
sudoUpdate = { "$set" : { "contributor.sudo" : true } }
User.findByIdAndUpdate user._id, sudoUpdate, {new: true}, (err, _user) ->
usr = _user
cb()
, true
describe "Coupons", ->
before (done) ->
async.parallel [
(cb) ->
mongoose.connection.collections['coupons'].drop (err) ->
cb()
(cb) ->
mongoose.connection.collections['users'].drop (err) ->
cb()
], done
coupons = null
describe "POST /api/v2/coupons/generate/:event", ->
context "while sudo user", ->
before (done) ->
makeSudoUser(user, done)
it "generates coupons", (done) ->
queries = '?count=10'
request
.post(baseURL + '/coupons/generate/wondercon' + queries)
.end (err, res) ->
expectCode res, 200
Coupon.find { event: 'wondercon' }, (err, _coupons) ->
coupons = _coupons
expect(coupons.length).to.equal 10
_(coupons).each (c)->
expect(c.event).to.equal 'wondercon'
done()
context "while regular user", ->
before (done) ->
registerNewUser(done, true)
it "does not generate coupons", (done) ->
queries = '?count=10'
request
.post(baseURL + '/coupons/generate/wondercon' + queries)
.end (err, res) ->
expectCode res, 401
expect(res.body.err).to.equal 'You don\'t have admin access'
done()
describe "GET /api/v2/coupons", ->
context "while sudo user", ->
before (done) ->
makeSudoUser(user, done)
it "gets coupons", (done) ->
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken
request
.get(baseURL + '/coupons' + queries)
.end (err, res) ->
expectCode res, 200
codes = res.text
expect(codes).to.contain('code')
# Expect each coupon code _id to exist in response
_(coupons).each (c) -> expect(codes).to.contain(c._id)
done()
it "gets first 5 coupons out of 10 when a limit of 5 is set", (done) ->
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&limit=5'
request
.get(baseURL + '/coupons' + queries)
.end (err, res) ->
expectCode res, 200
codes = res.text
sortedCoupons = _.sortBy(coupons, 'seq')
firstHalf = sortedCoupons[0..4]
secondHalf = sortedCoupons[5..9]
# First five coupons should be present in codes
_(firstHalf).each (c) -> expect(codes).to.contain(c._id)
# Second five coupons should not be present in codes
_(secondHalf).each (c) -> expect(codes).to.not.contain(c._id)
done()
it "gets last 5 coupons out of 10 when a limit of 5 is set", (done) ->
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&skip=5'
request
.get(baseURL + '/coupons' + queries)
.end (err, res) ->
expectCode res, 200
codes = res.text
sortedCoupons = _.sortBy(coupons, 'seq')
firstHalf = sortedCoupons[0..4]
secondHalf = sortedCoupons[5..9]
# First five coupons should not be present in codes
_(firstHalf).each (c) -> expect(codes).to.not.contain(c._id)
# Second five coupons should be present in codes
_(secondHalf).each (c) -> expect(codes).to.contain(c._id)
done()
context "while regular user", ->
before (done) ->
registerNewUser(done, true)
it "does not get coupons", (done) ->
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken
request
.get(baseURL + '/coupons' + queries)
.end (err, res) ->
expectCode res, 401
expect(res.body.err).to.equal 'You don\'t have admin access'
done()
describe "POST /api/v2/user/coupon/:code", ->
specialGear = (gear, has) ->
items = ['body_special_wondercon_gold'
'body_special_wondercon_black'
'body_special_wondercon_red'
'back_special_wondercon_red'
'back_special_wondercon_black'
'back_special_wondercon_red'
'eyewear_special_wondercon_black'
'eyewear_special_wondercon_red']
_(items).each (i) ->
if(has)
expect(gear[i]).to.exist
else
expect(gear[i]).to.not.exist
beforeEach (done) ->
registerNewUser ->
gear = user.items.gear.owned
specialGear(gear, false)
done()
, true
context "unused coupon", ->
it "applies coupon and awards equipment", (done) ->
code = coupons[0]._id
request
.post(baseURL + '/user/coupon/' + code)
.end (err, res) ->
expectCode res, 200
gear = res.body.items.gear.owned
specialGear(gear, true)
done()
context "already used coupon", ->
it "does not apply coupon and does not award equipment", (done) ->
code = coupons[0]._id
request
.post(baseURL + '/user/coupon/' + code)
.end (err, res) ->
expectCode res, 400
expect(res.body.err).to.equal "Coupon already used"
User.findById user._id, (err, _user) ->
gear = _user.items.gear.owned
specialGear(gear, false)
done()
context "invalid coupon", ->
it "does not apply coupon and does not award equipment", (done) ->
code = "not-a-real-coupon"
request
.post(baseURL + '/user/coupon/' + code)
.end (err, res) ->
expectCode res, 400
expect(res.body.err).to.equal "Invalid coupon code"
User.findById user._id, (err, _user) ->
gear = _user.items.gear.owned
specialGear(gear, false)
done()

222
test/api-legacy/coupons.js Normal file
View File

@@ -0,0 +1,222 @@
(function() {
'use strict';
var Coupon, app, makeSudoUser;
app = require("../../website/src/server");
Coupon = require("../../website/src/models/coupon").model;
makeSudoUser = function(usr, cb) {
return registerNewUser(function() {
var sudoUpdate;
sudoUpdate = {
"$set": {
"contributor.sudo": true
}
};
return User.findByIdAndUpdate(user._id, sudoUpdate, {
"new": true
}, function(err, _user) {
usr = _user;
return cb();
});
}, true);
};
describe("Coupons", function() {
var coupons;
before(function(done) {
return async.parallel([
function(cb) {
return mongoose.connection.collections['coupons'].drop(function(err) {
return cb();
});
}, function(cb) {
return mongoose.connection.collections['users'].drop(function(err) {
return cb();
});
}
], done);
});
coupons = null;
describe("POST /api/v2/coupons/generate/:event", function() {
context("while sudo user", function() {
before(function(done) {
return makeSudoUser(user, done);
});
return it("generates coupons", function(done) {
var queries;
queries = '?count=10';
return request.post(baseURL + '/coupons/generate/wondercon' + queries).end(function(err, res) {
expectCode(res, 200);
return Coupon.find({
event: 'wondercon'
}, function(err, _coupons) {
coupons = _coupons;
expect(coupons.length).to.equal(10);
_(coupons).each(function(c) {
return expect(c.event).to.equal('wondercon');
});
return done();
});
});
});
});
return context("while regular user", function() {
before(function(done) {
return registerNewUser(done, true);
});
return it("does not generate coupons", function(done) {
var queries;
queries = '?count=10';
return request.post(baseURL + '/coupons/generate/wondercon' + queries).end(function(err, res) {
expectCode(res, 401);
expect(res.body.err).to.equal('You don\'t have admin access');
return done();
});
});
});
});
describe("GET /api/v2/coupons", function() {
context("while sudo user", function() {
before(function(done) {
return makeSudoUser(user, done);
});
it("gets coupons", function(done) {
var queries;
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken;
return request.get(baseURL + '/coupons' + queries).end(function(err, res) {
var codes;
expectCode(res, 200);
codes = res.text;
expect(codes).to.contain('code');
_(coupons).each(function(c) {
return expect(codes).to.contain(c._id);
});
return done();
});
});
it("gets first 5 coupons out of 10 when a limit of 5 is set", function(done) {
var queries;
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&limit=5';
return request.get(baseURL + '/coupons' + queries).end(function(err, res) {
var codes, firstHalf, secondHalf, sortedCoupons;
expectCode(res, 200);
codes = res.text;
sortedCoupons = _.sortBy(coupons, 'seq');
firstHalf = sortedCoupons.slice(0, 5);
secondHalf = sortedCoupons.slice(5, 10);
_(firstHalf).each(function(c) {
return expect(codes).to.contain(c._id);
});
_(secondHalf).each(function(c) {
return expect(codes).to.not.contain(c._id);
});
return done();
});
});
return it("gets last 5 coupons out of 10 when a limit of 5 is set", function(done) {
var queries;
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&skip=5';
return request.get(baseURL + '/coupons' + queries).end(function(err, res) {
var codes, firstHalf, secondHalf, sortedCoupons;
expectCode(res, 200);
codes = res.text;
sortedCoupons = _.sortBy(coupons, 'seq');
firstHalf = sortedCoupons.slice(0, 5);
secondHalf = sortedCoupons.slice(5, 10);
_(firstHalf).each(function(c) {
return expect(codes).to.not.contain(c._id);
});
_(secondHalf).each(function(c) {
return expect(codes).to.contain(c._id);
});
return done();
});
});
});
return context("while regular user", function() {
before(function(done) {
return registerNewUser(done, true);
});
return it("does not get coupons", function(done) {
var queries;
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken;
return request.get(baseURL + '/coupons' + queries).end(function(err, res) {
expectCode(res, 401);
expect(res.body.err).to.equal('You don\'t have admin access');
return done();
});
});
});
});
return describe("POST /api/v2/user/coupon/:code", function() {
var specialGear;
specialGear = function(gear, has) {
var items;
items = ['body_special_wondercon_gold', 'body_special_wondercon_black', 'body_special_wondercon_red', 'back_special_wondercon_red', 'back_special_wondercon_black', 'back_special_wondercon_red', 'eyewear_special_wondercon_black', 'eyewear_special_wondercon_red'];
return _(items).each(function(i) {
if (has) {
return expect(gear[i]).to.exist;
} else {
return expect(gear[i]).to.not.exist;
}
});
};
beforeEach(function(done) {
return registerNewUser(function() {
var gear;
gear = user.items.gear.owned;
specialGear(gear, false);
return done();
}, true);
});
context("unused coupon", function() {
return it("applies coupon and awards equipment", function(done) {
var code;
code = coupons[0]._id;
return request.post(baseURL + '/user/coupon/' + code).end(function(err, res) {
var gear;
expectCode(res, 200);
gear = res.body.items.gear.owned;
specialGear(gear, true);
return done();
});
});
});
context("already used coupon", function() {
return it("does not apply coupon and does not award equipment", function(done) {
var code;
code = coupons[0]._id;
return request.post(baseURL + '/user/coupon/' + code).end(function(err, res) {
expectCode(res, 400);
expect(res.body.err).to.equal("Coupon already used");
return User.findById(user._id, function(err, _user) {
var gear;
gear = _user.items.gear.owned;
specialGear(gear, false);
return done();
});
});
});
});
return context("invalid coupon", function() {
return it("does not apply coupon and does not award equipment", function(done) {
var code;
code = "not-a-real-coupon";
return request.post(baseURL + '/user/coupon/' + code).end(function(err, res) {
expectCode(res, 400);
expect(res.body.err).to.equal("Invalid coupon code");
return User.findById(user._id, function(err, _user) {
var gear;
gear = _user.items.gear.owned;
specialGear(gear, false);
return done();
});
});
});
});
});
});
}).call(this);

View File

@@ -1,281 +0,0 @@
'use strict'
app = require('../../website/src/server')
rewire = require('rewire')
sinon = require('sinon')
inApp = rewire('../../website/src/controllers/payments/iap')
iapMock = { }
inApp.__set__('iap', iapMock)
describe 'In-App Purchases', ->
describe 'Android', ->
req = {
body: {
transaction: {
reciept: 'foo'
signature: 'sig'
}
}
}
res = {
locals: { user: { _id: 'user' } }
json: sinon.spy()
}
next = -> true
paymentSpy = sinon.spy()
before ->
inApp.__set__('payments.buyGems', paymentSpy)
afterEach ->
paymentSpy.reset()
res.json.reset()
context 'successful app purchase', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapGoogle, iapBodyReciept, cb)-> return cb(null, true)
iapMock.isValidated = (googleRes)-> return googleRes
iapMock.GOOGLE = 'google'
it 'calls res.json with succesful result object', ->
expectedResObj = {
ok: true
data: true
}
inApp.androidVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'calls payments.buyGems function', ->
inApp.androidVerify(req, res, next)
expect(paymentSpy).to.be.calledOnce
expect(paymentSpy).to.be.calledWith({user: res.locals.user, paymentMethod:'IAP GooglePlay'})
context 'error in setup', ->
before ->
iapMock.setup = (cb)-> return cb("error in setup")
it 'calls res.json with setup error object', ->
expectedResObj = {
ok: false
data: 'IAP Error'
}
inApp.androidVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.androidVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'error in validation', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapGoogle, iapBodyReciept, cb)-> return cb('error in validation', true)
it 'calls res.json with validation error object', ->
expectedResObj = {
ok: false
data: {
code: 6778001
message: 'error in validation'
}
}
inApp.androidVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.androidVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'iap is not valid', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapGoogle, iapBodyReciept, cb)-> return cb(null, false)
iapMock.isValidated = (googleRes)-> return googleRes
it 'does not call res.json', ->
inApp.androidVerify(req, res, next)
expect(res.json).to.not.be.called
it 'does not calls payments.buyGems function', ->
inApp.androidVerify(req, res, next)
expect(paymentSpy).to.not.be.called
describe 'iOS', ->
req = { body: { transaction: { reciept: 'foo' } } }
res = {
locals: { user: { _id: 'user' } }
json: sinon.spy()
}
next = -> true
paymentSpy = sinon.spy()
before ->
inApp.__set__('payments.buyGems', paymentSpy)
afterEach ->
paymentSpy.reset()
res.json.reset()
context 'successful app purchase', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapApple, iapBodyReciept, cb)-> return cb(null, true)
iapMock.isValidated = (appleRes)-> return appleRes
iapMock.getPurchaseData = (appleRes)->
return [{ productId: 'com.habitrpg.ios.Habitica.20gems' }]
iapMock.APPLE = 'apple'
it 'calls res.json with succesful result object', ->
expectedResObj = {
ok: true
data: true
}
inApp.iosVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.be.calledOnce
expect(paymentSpy).to.be.calledWith({user: res.locals.user, paymentMethod:'IAP AppleStore', amount: 5.25})
context 'error in setup', ->
before ->
iapMock.setup = (cb)-> return cb("error in setup")
it 'calls res.json with setup error object', ->
expectedResObj = {
ok: false
data: 'IAP Error'
}
inApp.iosVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'error in validation', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapApple, iapBodyReciept, cb)-> return cb('error in validation', true)
it 'calls res.json with validation error object', ->
expectedResObj = {
ok: false
data: {
code: 6778001
message: 'error in validation'
}
}
inApp.iosVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'iap is not valid', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapApple, iapBodyReciept, cb)-> return cb(null, false)
iapMock.isValidated = (appleRes)-> return appleRes
it 'does not call res.json', ->
inApp.iosVerify(req, res, next)
expectedResObj = {
ok: false
data: {
code: 6778001
message: 'Invalid receipt'
}
}
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'iap is valid but has no purchaseDataList', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapApple, iapBodyReciept, cb)-> return cb(null, true)
iapMock.isValidated = (appleRes)-> return appleRes
iapMock.getPurchaseData = (appleRes)->
return []
iapMock.APPLE = 'apple'
it 'calls res.json with succesful result object', ->
expectedResObj = {
ok: false
data: {
code: 6778001
message: 'Incorrect receipt content'
}
}
inApp.iosVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.not.be.called
context 'iap is valid, has purchaseDataList, but productId does not match', ->
before ->
iapMock.setup = (cb)-> return cb(null)
iapMock.validate = (iapApple, iapBodyReciept, cb)-> return cb(null, true)
iapMock.isValidated = (appleRes)-> return appleRes
iapMock.getPurchaseData = (appleRes)->
return [{ productId: 'com.another.company' }]
iapMock.APPLE = 'apple'
it 'calls res.json with incorrect reciept obj', ->
expectedResObj = {
ok: false
data: {
code: 6778001
message: 'Incorrect receipt content'
}
}
inApp.iosVerify(req, res, next)
expect(res.json).to.be.calledOnce
expect(res.json).to.be.calledWith(expectedResObj)
it 'does not calls payments.buyGems function', ->
inApp.iosVerify(req, res, next)
expect(paymentSpy).to.not.be.called

View File

@@ -0,0 +1,370 @@
(function() {
'use strict';
var app, iapMock, inApp, rewire, sinon;
app = require('../../website/src/server');
rewire = require('rewire');
sinon = require('sinon');
inApp = rewire('../../website/src/controllers/payments/iap');
iapMock = {};
inApp.__set__('iap', iapMock);
describe('In-App Purchases', function() {
describe('Android', function() {
var next, paymentSpy, req, res;
req = {
body: {
transaction: {
reciept: 'foo',
signature: 'sig'
}
}
};
res = {
locals: {
user: {
_id: 'user'
}
},
json: sinon.spy()
};
next = function() {
return true;
};
paymentSpy = sinon.spy();
before(function() {
return inApp.__set__('payments.buyGems', paymentSpy);
});
afterEach(function() {
paymentSpy.reset();
return res.json.reset();
});
context('successful app purchase', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
return cb(null, true);
};
iapMock.isValidated = function(googleRes) {
return googleRes;
};
return iapMock.GOOGLE = 'google';
});
it('calls res.json with succesful result object', function() {
var expectedResObj;
expectedResObj = {
ok: true,
data: true
};
inApp.androidVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('calls payments.buyGems function', function() {
inApp.androidVerify(req, res, next);
expect(paymentSpy).to.be.calledOnce;
return expect(paymentSpy).to.be.calledWith({
user: res.locals.user,
paymentMethod: 'IAP GooglePlay'
});
});
});
context('error in setup', function() {
before(function() {
return iapMock.setup = function(cb) {
return cb("error in setup");
};
});
it('calls res.json with setup error object', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: 'IAP Error'
};
inApp.androidVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.androidVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
context('error in validation', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
return iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
return cb('error in validation', true);
};
});
it('calls res.json with validation error object', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: {
code: 6778001,
message: 'error in validation'
}
};
inApp.androidVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.androidVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
return context('iap is not valid', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
return cb(null, false);
};
return iapMock.isValidated = function(googleRes) {
return googleRes;
};
});
it('does not call res.json', function() {
inApp.androidVerify(req, res, next);
return expect(res.json).to.not.be.called;
});
return it('does not calls payments.buyGems function', function() {
inApp.androidVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
});
return describe('iOS', function() {
var next, paymentSpy, req, res;
req = {
body: {
transaction: {
reciept: 'foo'
}
}
};
res = {
locals: {
user: {
_id: 'user'
}
},
json: sinon.spy()
};
next = function() {
return true;
};
paymentSpy = sinon.spy();
before(function() {
return inApp.__set__('payments.buyGems', paymentSpy);
});
afterEach(function() {
paymentSpy.reset();
return res.json.reset();
});
context('successful app purchase', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
return cb(null, true);
};
iapMock.isValidated = function(appleRes) {
return appleRes;
};
iapMock.getPurchaseData = function(appleRes) {
return [
{
productId: 'com.habitrpg.ios.Habitica.20gems'
}
];
};
return iapMock.APPLE = 'apple';
});
it('calls res.json with succesful result object', function() {
var expectedResObj;
expectedResObj = {
ok: true,
data: true
};
inApp.iosVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
expect(paymentSpy).to.be.calledOnce;
return expect(paymentSpy).to.be.calledWith({
user: res.locals.user,
paymentMethod: 'IAP AppleStore',
amount: 5.25
});
});
});
context('error in setup', function() {
before(function() {
return iapMock.setup = function(cb) {
return cb("error in setup");
};
});
it('calls res.json with setup error object', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: 'IAP Error'
};
inApp.iosVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
context('error in validation', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
return iapMock.validate = function(iapApple, iapBodyReciept, cb) {
return cb('error in validation', true);
};
});
it('calls res.json with validation error object', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: {
code: 6778001,
message: 'error in validation'
}
};
inApp.iosVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
context('iap is not valid', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
return cb(null, false);
};
return iapMock.isValidated = function(appleRes) {
return appleRes;
};
});
it('does not call res.json', function() {
var expectedResObj;
inApp.iosVerify(req, res, next);
expectedResObj = {
ok: false,
data: {
code: 6778001,
message: 'Invalid receipt'
}
};
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
context('iap is valid but has no purchaseDataList', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
return cb(null, true);
};
iapMock.isValidated = function(appleRes) {
return appleRes;
};
iapMock.getPurchaseData = function(appleRes) {
return [];
};
return iapMock.APPLE = 'apple';
});
it('calls res.json with succesful result object', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: {
code: 6778001,
message: 'Incorrect receipt content'
}
};
inApp.iosVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
return context('iap is valid, has purchaseDataList, but productId does not match', function() {
before(function() {
iapMock.setup = function(cb) {
return cb(null);
};
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
return cb(null, true);
};
iapMock.isValidated = function(appleRes) {
return appleRes;
};
iapMock.getPurchaseData = function(appleRes) {
return [
{
productId: 'com.another.company'
}
];
};
return iapMock.APPLE = 'apple';
});
it('calls res.json with incorrect reciept obj', function() {
var expectedResObj;
expectedResObj = {
ok: false,
data: {
code: 6778001,
message: 'Incorrect receipt content'
}
};
inApp.iosVerify(req, res, next);
expect(res.json).to.be.calledOnce;
return expect(res.json).to.be.calledWith(expectedResObj);
});
return it('does not calls payments.buyGems function', function() {
inApp.iosVerify(req, res, next);
return expect(paymentSpy).to.not.be.called;
});
});
});
});
}).call(this);

View File

@@ -1,363 +0,0 @@
'use strict'
diff = require("deep-diff")
Group = require("../../website/src/models/group").model
app = require("../../website/src/server")
describe "Party", ->
context "Quests", ->
party = undefined
group = undefined
participating = []
notParticipating = []
beforeEach (done) ->
# Tavern boss, side-by-side
Group.update(
_id: "habitrpg"
,
$set:
quest:
key: "dilatory"
active: true
progress:
hp: shared.content.quests.dilatory.boss.hp
rage: 0
).exec()
# Tally some progress for later. Later we want to test that progress made before the quest began gets
# counted after the quest starts
async.waterfall [
(cb) ->
registerNewUser(cb, true)
(user, cb) ->
request.post(baseURL + "/groups").send(
name: "TestGroup"
type: "party"
).end (err, 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 + '/user/tasks').send({
type: 'daily'
text: 'daily one'
}).end (err, res) ->
cb()
(cb) ->
request.post(baseURL + '/user/tasks').send({
type: 'daily'
text: 'daily two'
}).end (err, res) ->
cb()
(cb) ->
User.findByIdAndUpdate user._id,
$set:
"stats.lvl": 50
, {new: true}
, (err, _user) ->
cb(null, _user)
(_user, cb) ->
user = _user
request.post(baseURL + "/user/batch-update").send([
{
op: "score"
params:
direction: "up"
id: user.dailys[0].id
}
{
op: "score"
params:
direction: "up"
id: user.dailys[0].id
}
{
op: "update"
body:
"stats.lvl": 50
}
]).end (err, res) ->
user = res.body
expect(user.party.quest.progress.up).to.be.above 0
# Invite some members
async.waterfall [
# Register new users
(cb) ->
registerManyUsers 3, cb
# Send them invitations
(_party, cb) ->
party = _party
inviteURL = baseURL + "/groups/" + group._id + "/invite"
async.parallel [
(cb2) ->
request.post(inviteURL).send(
uuids: [party[0]._id]
).end ->
cb2()
(cb2) ->
request.post(inviteURL).send(
uuids: [party[1]._id]
).end ->
cb2()
(cb2) ->
request.post(inviteURL).send(
uuids: [party[2]._id]
).end (err, res)->
cb2()
], cb
# Accept / Reject
(results, cb) ->
# series since they'll be modifying the same group record
series = _.reduce(party, (m, v, i) ->
m.push (cb2) ->
request.post(baseURL + "/groups/" + group._id + "/join").set("X-API-User", party[i]._id).set("X-API-Key", party[i].apiToken).end ->
cb2()
m
, [])
async.series series, cb
# Make sure the invites stuck
(whatever, cb) ->
Group.findById group._id, (err, g) ->
group = g
expect(g.members.length).to.equal 4
cb()
], ->
# Start the quest
async.waterfall [
(cb) ->
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (err, res) ->
expectCode res, 400
User.findByIdAndUpdate user._id,
$set:
"items.quests.vice3": 1
, {new: true}
, cb
(_user, cb) ->
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (err, res) ->
expectCode res, 200
Group.findById group._id, cb
(_group, cb) ->
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 (err, res) ->
request.post(baseURL + "/groups/" + group._id + "/questReject").set("X-API-User", party[2]._id).set("X-API-Key", party[2].apiToken).end (err, res) ->
group = res.body
expect(group.quest.active).to.equal true
cb()
], done
]
it "Casts a spell", (done) ->
mp = user.stats.mp
request.get(baseURL + "/members/" + party[0]._id).end (err, res) ->
party[0] = res.body
request.post(baseURL + "/user/class/cast/snowball?targetType=user&targetId=" + party[0]._id).end (err, res) ->
#expect(res.body.stats.mp).to.be.below(mp);
request.get(baseURL + "/members/" + party[0]._id).end (err, res) ->
member = res.body
expect(member.achievements.snowball).to.equal 1
expect(member.stats.buffs.snowball).to.exist
difference = diff(member, party[0])
expect(_.size(difference)).to.equal 2
# level up user so str is > 0
request.put(baseURL + "/user").send("stats.lvl": 5).end (err, res) ->
# Refill mana so user can cast
request.put(baseURL + "/user").send("stats.mp": 100).end (err, res) ->
request.post(baseURL + "/user/class/cast/valorousPresence?targetType=party").end (err, res) ->
request.get(baseURL + "/members/" + member._id).end (err, res) ->
expect(res.body.stats.buffs.str).to.be.above 0
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 (err, res) ->
expect(_.size(res.body.quest.members)).to.equal 3
done()
it "allows quest participants to leave quest", (done) ->
leavingMember = party[1]
expect(group.quest.members[leavingMember._id]).to.eql(true)
request.post(baseURL + "/groups/" + group._id + "/questLeave")
.set("X-API-User", leavingMember._id)
.set("X-API-Key", leavingMember.apiToken)
.end (err, res) ->
expectCode res, 204
request.get(baseURL + '/groups/party')
.end (err, res) ->
expect(res.body.quest.members[leavingMember._id]).to.not.be.ok
done()
xit "Hurts the boss", (done) ->
request.post(baseURL + "/user/batch-update").end (err, res) ->
user = res.body
up = user.party.quest.progress.up
expect(up).to.be.above 0
#{op:'score',params:{direction:'up',id:user.dailys[3].id}}, // leave one daily undone so Trapper hurts party
# set day to yesterday, cron will then be triggered on next action
request.post(baseURL + "/user/batch-update").send([
{
op: "score"
params:
direction: "up"
id: user.dailys[0].id
}
{
op: "update"
body:
lastCron: moment().subtract(1, "days")
}
]).end (err, res) ->
expect(res.body.party.quest.progress.up).to.be.above up
request.post(baseURL + "/user/batch-update").end ->
request.get(baseURL + "/groups/party").end (err, res) ->
# Check boss damage
async.waterfall [
(cb) ->
async.parallel [
#tavern boss
(cb2) ->
Group.findById "habitrpg",
quest: 1
, (err, tavern) ->
expect(tavern.quest.progress.hp).to.be.below shared.content.quests.dilatory.boss.hp
expect(tavern.quest.progress.rage).to.be.above 0
cb2()
# party boss
(cb2) ->
expect(res.body.quest.progress.hp).to.be.below shared.content.quests.vice3.boss.hp
_party = res.body.members
expect(_.find(_party,
_id: party[0]._id
).stats.hp).to.be.below 50
expect(_.find(_party,
_id: party[1]._id
).stats.hp).to.be.below 50
expect(_.find(_party,
_id: party[2]._id
).stats.hp).to.be 50
cb2()
], cb
# Kill the boss
(whatever, cb) ->
async.waterfall [
# tavern boss
(cb2) ->
expect(user.items.pets["MantisShrimp-Base"]).to.not.be.ok()
Group.update
_id: "habitrpg"
,
$set:
"quest.progress.hp": 0
, cb2
# party boss
(arg1, arg2, cb2) ->
expect(user.items.gear.owned.weapon_special_2).to.not.be.ok()
Group.findByIdAndUpdate group._id,
$set:
"quest.progress.hp": 0
, {new: true}
, cb2
], cb
(_group, cb) ->
# set day to yesterday, cron will then be triggered on next action
request.post(baseURL + "/user/batch-update").send([
{
op: "score"
params:
direction: "up"
id: user.dailys[1].id
}
{
op: "update"
body:
lastCron: moment().subtract(1, "days")
}
]).end ->
cb()
(cb) ->
request.post(baseURL + "/user/batch-update").end (err, res) ->
cb null, res.body
(_user, cb) ->
# need to load the user again, since tavern boss does update after user's cron
User.findById _user._id, cb
(_user, cb) ->
user = _user
Group.findById group._id, cb
(_group, cb) ->
cummExp = shared.content.quests.vice3.drop.exp + shared.content.quests.dilatory.drop.exp
cummGp = shared.content.quests.vice3.drop.gp + shared.content.quests.dilatory.drop.gp
#//FIXME check that user got exp, but user is leveling up making the exp check difficult
# expect(user.stats.exp).to.be.above(cummExp);
# expect(user.stats.gp).to.be.above(cummGp);
async.parallel [
# Tavern Boss
(cb2) ->
Group.findById "habitrpg", (err, tavern) ->
#use an explicit get because mongoose wraps the null in an object
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.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.equal true
cb3()
(cb3) ->
User.findById party[1].id, (err, mbr) ->
expect(mbr.items.gear.owned.weapon_special_2).to.equal true
cb3()
(cb3) ->
User.findById party[2].id, (err, mbr) ->
expect(mbr.items.gear.owned.weapon_special_2).to.not.be.ok()
cb3()
], cb2
], cb
], done

376
test/api-legacy/party.js Normal file
View File

@@ -0,0 +1,376 @@
(function() {
'use strict';
var Group, app, diff;
diff = require("deep-diff");
Group = require("../../website/src/models/group").model;
app = require("../../website/src/server");
describe("Party", function() {
return context("Quests", function() {
var group, notParticipating, participating, party;
party = void 0;
group = void 0;
participating = [];
notParticipating = [];
beforeEach(function(done) {
Group.update({
_id: "habitrpg"
}, {
$set: {
quest: {
key: "dilatory",
active: true,
progress: {
hp: shared.content.quests.dilatory.boss.hp,
rage: 0
}
}
}
}).exec();
return async.waterfall([
function(cb) {
return registerNewUser(cb, true);
}, function(user, cb) {
return request.post(baseURL + "/groups").send({
name: "TestGroup",
type: "party"
}).end(function(err, res) {
expectCode(res, 200);
group = res.body;
expect(group.members.length).to.equal(1);
expect(group.leader).to.equal(user._id);
return cb();
});
}, function(cb) {
return request.post(baseURL + '/user/tasks').send({
type: 'daily',
text: 'daily one'
}).end(function(err, res) {
return cb();
});
}, function(cb) {
return request.post(baseURL + '/user/tasks').send({
type: 'daily',
text: 'daily two'
}).end(function(err, res) {
return cb();
});
}, function(cb) {
return User.findByIdAndUpdate(user._id, {
$set: {
"stats.lvl": 50
}
}, {
"new": true
}, function(err, _user) {
return cb(null, _user);
});
}, function(_user, cb) {
var user;
user = _user;
return request.post(baseURL + "/user/batch-update").send([
{
op: "score",
params: {
direction: "up",
id: user.dailys[0].id
}
}, {
op: "score",
params: {
direction: "up",
id: user.dailys[0].id
}
}, {
op: "update",
body: {
"stats.lvl": 50
}
}
]).end(function(err, res) {
user = res.body;
expect(user.party.quest.progress.up).to.be.above(0);
return async.waterfall([
function(cb) {
return registerManyUsers(3, cb);
}, function(_party, cb) {
var inviteURL;
party = _party;
inviteURL = baseURL + "/groups/" + group._id + "/invite";
return async.parallel([
function(cb2) {
return request.post(inviteURL).send({
uuids: [party[0]._id]
}).end(function() {
return cb2();
});
}, function(cb2) {
return request.post(inviteURL).send({
uuids: [party[1]._id]
}).end(function() {
return cb2();
});
}, function(cb2) {
return request.post(inviteURL).send({
uuids: [party[2]._id]
}).end(function(err, res) {
return cb2();
});
}
], cb);
}, function(results, cb) {
var series;
series = _.reduce(party, function(m, v, i) {
m.push(function(cb2) {
return request.post(baseURL + "/groups/" + group._id + "/join").set("X-API-User", party[i]._id).set("X-API-Key", party[i].apiToken).end(function() {
return cb2();
});
});
return m;
}, []);
return async.series(series, cb);
}, function(whatever, cb) {
return Group.findById(group._id, function(err, g) {
group = g;
expect(g.members.length).to.equal(4);
return cb();
});
}
], function() {
return async.waterfall([
function(cb) {
return request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end(function(err, res) {
expectCode(res, 400);
return User.findByIdAndUpdate(user._id, {
$set: {
"items.quests.vice3": 1
}
}, {
"new": true
}, cb);
});
}, function(_user, cb) {
return request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end(function(err, res) {
expectCode(res, 200);
return Group.findById(group._id, cb);
});
}, function(_group, cb) {
expect(_group.quest.key).to.equal("vice3");
expect(_group.quest.active).to.equal(false);
return request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[0]._id).set("X-API-Key", party[0].apiToken).end(function() {
return request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[1]._id).set("X-API-Key", party[1].apiToken).end(function(err, res) {
return request.post(baseURL + "/groups/" + group._id + "/questReject").set("X-API-User", party[2]._id).set("X-API-Key", party[2].apiToken).end(function(err, res) {
group = res.body;
expect(group.quest.active).to.equal(true);
return cb();
});
});
});
}
], done);
});
});
}
]);
});
it("Casts a spell", function(done) {
var mp;
mp = user.stats.mp;
return request.get(baseURL + "/members/" + party[0]._id).end(function(err, res) {
party[0] = res.body;
return request.post(baseURL + "/user/class/cast/snowball?targetType=user&targetId=" + party[0]._id).end(function(err, res) {
return request.get(baseURL + "/members/" + party[0]._id).end(function(err, res) {
var difference, member;
member = res.body;
expect(member.achievements.snowball).to.equal(1);
expect(member.stats.buffs.snowball).to.exist;
difference = diff(member, party[0]);
expect(_.size(difference)).to.equal(2);
return request.put(baseURL + "/user").send({
"stats.lvl": 5
}).end(function(err, res) {
return request.put(baseURL + "/user").send({
"stats.mp": 100
}).end(function(err, res) {
return request.post(baseURL + "/user/class/cast/valorousPresence?targetType=party").end(function(err, res) {
return request.get(baseURL + "/members/" + member._id).end(function(err, res) {
expect(res.body.stats.buffs.str).to.be.above(0);
expect(diff(res.body, member).length).to.equal(1);
return done();
});
});
});
});
});
});
});
});
it("Doesn't include people who aren't participating", function(done) {
return request.get(baseURL + "/groups/" + group._id).end(function(err, res) {
expect(_.size(res.body.quest.members)).to.equal(3);
return done();
});
});
it("allows quest participants to leave quest", function(done) {
var leavingMember;
leavingMember = party[1];
expect(group.quest.members[leavingMember._id]).to.eql(true);
return request.post(baseURL + "/groups/" + group._id + "/questLeave").set("X-API-User", leavingMember._id).set("X-API-Key", leavingMember.apiToken).end(function(err, res) {
expectCode(res, 204);
return request.get(baseURL + '/groups/party').end(function(err, res) {
expect(res.body.quest.members[leavingMember._id]).to.not.be.ok;
return done();
});
});
});
return xit("Hurts the boss", function(done) {
return request.post(baseURL + "/user/batch-update").end(function(err, res) {
var up, user;
user = res.body;
up = user.party.quest.progress.up;
expect(up).to.be.above(0);
return request.post(baseURL + "/user/batch-update").send([
{
op: "score",
params: {
direction: "up",
id: user.dailys[0].id
}
}, {
op: "update",
body: {
lastCron: moment().subtract(1, "days")
}
}
]).end(function(err, res) {
expect(res.body.party.quest.progress.up).to.be.above(up);
return request.post(baseURL + "/user/batch-update").end(function() {
return request.get(baseURL + "/groups/party").end(function(err, res) {
return async.waterfall([
function(cb) {
return async.parallel([
function(cb2) {
return Group.findById("habitrpg", {
quest: 1
}, function(err, tavern) {
expect(tavern.quest.progress.hp).to.be.below(shared.content.quests.dilatory.boss.hp);
expect(tavern.quest.progress.rage).to.be.above(0);
return cb2();
});
}, function(cb2) {
var _party;
expect(res.body.quest.progress.hp).to.be.below(shared.content.quests.vice3.boss.hp);
_party = res.body.members;
expect(_.find(_party, {
_id: party[0]._id
}).stats.hp).to.be.below(50);
expect(_.find(_party, {
_id: party[1]._id
}).stats.hp).to.be.below(50);
expect(_.find(_party, {
_id: party[2]._id
}).stats.hp).to.be(50);
return cb2();
}
], cb);
}, function(whatever, cb) {
return async.waterfall([
function(cb2) {
expect(user.items.pets["MantisShrimp-Base"]).to.not.be.ok();
return Group.update({
_id: "habitrpg"
}, {
$set: {
"quest.progress.hp": 0
}
}, cb2);
}, function(arg1, arg2, cb2) {
expect(user.items.gear.owned.weapon_special_2).to.not.be.ok();
return Group.findByIdAndUpdate(group._id, {
$set: {
"quest.progress.hp": 0
}
}, {
"new": true
}, cb2);
}
], cb);
}, function(_group, cb) {
return request.post(baseURL + "/user/batch-update").send([
{
op: "score",
params: {
direction: "up",
id: user.dailys[1].id
}
}, {
op: "update",
body: {
lastCron: moment().subtract(1, "days")
}
}
]).end(function() {
return cb();
});
}, function(cb) {
return request.post(baseURL + "/user/batch-update").end(function(err, res) {
return cb(null, res.body);
});
}, function(_user, cb) {
return User.findById(_user._id, cb);
}, function(_user, cb) {
user = _user;
return Group.findById(group._id, cb);
}, function(_group, cb) {
var cummExp, cummGp;
cummExp = shared.content.quests.vice3.drop.exp + shared.content.quests.dilatory.drop.exp;
cummGp = shared.content.quests.vice3.drop.gp + shared.content.quests.dilatory.drop.gp;
return async.parallel([
function(cb2) {
return Group.findById("habitrpg", function(err, tavern) {
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);
return cb2();
});
}, function(cb2) {
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);
return async.parallel([
function(cb3) {
return User.findById(party[0].id, function(err, mbr) {
expect(mbr.items.gear.owned.weapon_special_2).to.equal(true);
return cb3();
});
}, function(cb3) {
return User.findById(party[1].id, function(err, mbr) {
expect(mbr.items.gear.owned.weapon_special_2).to.equal(true);
return cb3();
});
}, function(cb3) {
return User.findById(party[2].id, function(err, mbr) {
expect(mbr.items.gear.owned.weapon_special_2).to.not.be.ok();
return cb3();
});
}
], cb2);
}
], cb);
}
], done);
});
});
});
});
});
});
});
}).call(this);

View File

@@ -1,346 +0,0 @@
'use strict'
#@TODO: Have to mock most things to get to the parts that
#call pushNotify. Consider refactoring group controller
#so things are easier to test
app = require("../../website/src/server")
rewire = require('rewire')
sinon = require('sinon')
describe "Push-Notifications", ->
before (done) ->
registerNewUser(done, true)
describe "Events that send push notifications", ->
pushSpy = { sendNotify: sinon.spy() }
afterEach (done) ->
pushSpy.sendNotify.reset()
done()
context "Challenges", ->
challenges = rewire("../../website/src/controllers/api-v2/challenges")
challenges.__set__('pushNotify', pushSpy)
challengeMock = {
findById: (arg, cb) ->
cb(null, {leader: user._id, name: 'challenge-name'})
}
userMock = {
findById: (arg, cb) ->
cb(null, user)
}
challenges.__set__('Challenge', challengeMock)
challenges.__set__('User', userMock)
challenges.__set__('closeChal', -> true)
beforeEach (done) ->
registerNewUser ->
user.preferences.emailNotifications.wonChallenge = false
user.save = (cb) -> cb(null, user)
done()
, true
it "sends a push notification when you win a challenge", (done) ->
req = {
params: { cid: 'challenge-id' }
query: {uid: 'user-id'}
}
res = {
locals: { user: user }
}
challenges.selectWinner req, res
setTimeout -> # Allow selectWinner to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
user,
'You won a Challenge!',
'challenge-name'
)
done()
, 100
context "Groups", ->
recipient = null
groups = rewire("../../website/src/controllers/api-v2/groups")
groups.__set__('pushNotify', pushSpy)
before (done) ->
registerNewUser (err,_user)->
recipient = _user
recipient.invitations.guilds = []
recipient.save = (cb) -> cb(null, recipient)
recipient.preferences.emailNotifications.invitedGuild = false
recipient.preferences.emailNotifications.invitedParty = false
recipient.preferences.emailNotifications.invitedQuest = false
userMock = {
findById: (arg, cb) ->
cb(null, recipient)
find: (arg, arg2, cb) ->
cb(null, [recipient])
update: (arg, arg2) ->
{ exec: -> true}
}
groups.__set__('User', userMock)
done()
, false
it "sends a push notification when invited to a guild", (done) ->
group = { _id: 'guild-id', name: 'guild-name', type: 'guild', members: [user._id], invites: [] }
group.save = (cb) -> cb(null, group)
req = {
body: { uuids: [recipient._id] }
}
res = {
locals: { group: group, user: user }
json: -> return true
}
groups.invite req, res
setTimeout -> # Allow invite to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Invited To Guild',
group.name
)
done()
, 100
it "sends a push notification when invited to a party", (done) ->
group = { _id: 'party-id', name: 'party-name', type: 'party', members: [user._id], invites: [] }
group.save = (cb) -> cb(null, group)
req = {
body: { uuids: [recipient._id] }
}
res = {
locals: { group: group, user: user }
json: -> return true
}
groups.invite req, res
setTimeout -> # Allow invite to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Invited To Party',
group.name
)
done()
, 100
it "sends a push notification when invited to a quest", (done) ->
group = { _id: 'party-id', name: 'party-name', type: 'party', members: [user._id, recipient._id], invites: [], quest: {}}
user.items.quests.hedgehog = 5
group.save = (cb) -> cb(null, group)
group.markModified = -> true
req = {
body: { uuids: [recipient._id] }
query: { key: 'hedgehog' }
}
res = {
locals: { group: group, user: user }
json: -> return true
}
groups.questAccept req, res
setTimeout -> # Allow questAccept to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Quest Invitation',
'Invitation for the Quest The Hedgebeast'
)
done()
, 100
it "sends a push notification to participating members when quest starts", (done) ->
group = { _id: 'party-id', name: 'party-name', type: 'party', members: [user._id, recipient._id], invites: []}
group.quest = {
key: 'hedgehog'
progress: { hp: 100 }
members: {}
}
group.quest.members[recipient._id] = true
group.save = (cb) -> cb(null, group)
group.markModified = -> true
req = {
body: { uuids: [recipient._id] }
query: { }
# force: true
}
res = {
locals: { group: group, user: user }
json: -> return true
}
userMock = {
findOne: (arg, arg2, cb) ->
cb(null, recipient)
update: (arg, arg2, cb) ->
if (cb)
return cb(null, user)
else
return {
exec: -> true
}
}
groups.__set__('User', userMock)
groups.__set__('populateQuery',
(arg, arg2, arg3) ->
return {
exec: -> group.members
}
)
groups.questAccept req, res
setTimeout -> # Allow questAccept to finish
expect(pushSpy.sendNotify).to.have.been.calledTwice
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'HabitRPG',
'Your Quest has Begun: The Hedgebeast'
)
done()
, 100
describe "Gifts", ->
recipient = null
before (done) ->
registerNewUser (err, _user) ->
recipient = _user
recipient.preferences.emailNotifications.giftedGems = false
user.balance = 4
user.save = -> return true
recipient.save = -> return true
done()
, false
context "sending gems from balance", ->
members = rewire("../../website/src/controllers/api-v2/members")
members.sendMessage = -> true
members.__set__('pushNotify', pushSpy)
members.__set__ 'fetchMember', (id) ->
return (cb) -> cb(null, recipient)
it "sends a push notification", (done) ->
req = {
params: { uuid: "uuid" },
body: {
type: 'gems',
gems: { amount: 1 }
}
}
res = { locals: { user: user } }
members.sendGift req, res
setTimeout -> # Allow sendGift to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Gifted Gems',
'1 Gems - by ' + user.profile.name
)
done()
, 100
describe "Purchases", ->
payments = rewire("../../website/src/controllers/payments")
payments.__set__('pushNotify', pushSpy)
membersMock = { sendMessage: -> true }
payments.__set__('members', membersMock)
context "buying gems as a purchased gift", ->
it "sends a push notification", (done) ->
data = {
user: user,
gift: {
member: recipient,
gems: { amount: 1 }
}
}
payments.buyGems data
setTimeout -> # Allow buyGems to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Gifted Gems',
'1 Gems - by ' + user.profile.name
)
done()
, 100
it "does not send a push notification if buying gems for self", (done) ->
data = {
user: user,
gift: {
member: user
gems: { amount: 1 }
}
}
payments.buyGems data
setTimeout -> # Allow buyGems to finish
expect(pushSpy.sendNotify).to.not.have.been.called
done()
, 100
context "sending a subscription as a purchased gift", ->
it "sends a push notification", (done) ->
data = {
user: user,
gift: {
member: recipient
subscription: { key: 'basic_6mo' }
}
}
payments.createSubscription data
setTimeout -> # Allow createSubscription to finish
expect(pushSpy.sendNotify).to.have.been.calledOnce
expect(pushSpy.sendNotify).to.have.been.calledWith(
recipient,
'Gifted Subscription',
'6 months - by ' + user.profile.name
)
done()
, 100
it "does not send a push notification if buying subscription for self", (done) ->
data = {
user: user,
gift: {
member: user
subscription: { key: 'basic_6mo' }
}
}
payments.createSubscription data
setTimeout -> # Allow buyGems to finish
expect(pushSpy.sendNotify).to.not.have.been.called
done()
, 100

View File

@@ -0,0 +1,434 @@
(function() {
'use strict';
var app, rewire, sinon;
app = require("../../website/src/server");
rewire = require('rewire');
sinon = require('sinon');
describe("Push-Notifications", function() {
before(function(done) {
return registerNewUser(done, true);
});
return describe("Events that send push notifications", function() {
var pushSpy;
pushSpy = {
sendNotify: sinon.spy()
};
afterEach(function(done) {
pushSpy.sendNotify.reset();
return done();
});
context("Challenges", function() {
var challengeMock, challenges, userMock;
challenges = rewire("../../website/src/controllers/api-v2/challenges");
challenges.__set__('pushNotify', pushSpy);
challengeMock = {
findById: function(arg, cb) {
return cb(null, {
leader: user._id,
name: 'challenge-name'
});
}
};
userMock = {
findById: function(arg, cb) {
return cb(null, user);
}
};
challenges.__set__('Challenge', challengeMock);
challenges.__set__('User', userMock);
challenges.__set__('closeChal', function() {
return true;
});
beforeEach(function(done) {
return registerNewUser(function() {
user.preferences.emailNotifications.wonChallenge = false;
user.save = function(cb) {
return cb(null, user);
};
return done();
}, true);
});
return it("sends a push notification when you win a challenge", function(done) {
var req, res;
req = {
params: {
cid: 'challenge-id'
},
query: {
uid: 'user-id'
}
};
res = {
locals: {
user: user
}
};
challenges.selectWinner(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(user, 'You won a Challenge!', 'challenge-name');
return done();
}, 100);
});
});
context("Groups", function() {
var groups, recipient;
recipient = null;
groups = rewire("../../website/src/controllers/api-v2/groups");
groups.__set__('pushNotify', pushSpy);
before(function(done) {
return registerNewUser(function(err, _user) {
var userMock;
recipient = _user;
recipient.invitations.guilds = [];
recipient.save = function(cb) {
return cb(null, recipient);
};
recipient.preferences.emailNotifications.invitedGuild = false;
recipient.preferences.emailNotifications.invitedParty = false;
recipient.preferences.emailNotifications.invitedQuest = false;
userMock = {
findById: function(arg, cb) {
return cb(null, recipient);
},
find: function(arg, arg2, cb) {
return cb(null, [recipient]);
},
update: function(arg, arg2) {
return {
exec: function() {
return true;
}
};
}
};
groups.__set__('User', userMock);
return done();
}, false);
});
it("sends a push notification when invited to a guild", function(done) {
var group, req, res;
group = {
_id: 'guild-id',
name: 'guild-name',
type: 'guild',
members: [user._id],
invites: []
};
group.save = function(cb) {
return cb(null, group);
};
req = {
body: {
uuids: [recipient._id]
}
};
res = {
locals: {
group: group,
user: user
},
json: function() {
return true;
}
};
groups.invite(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Invited To Guild', group.name);
return done();
}, 100);
});
it("sends a push notification when invited to a party", function(done) {
var group, req, res;
group = {
_id: 'party-id',
name: 'party-name',
type: 'party',
members: [user._id],
invites: []
};
group.save = function(cb) {
return cb(null, group);
};
req = {
body: {
uuids: [recipient._id]
}
};
res = {
locals: {
group: group,
user: user
},
json: function() {
return true;
}
};
groups.invite(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Invited To Party', group.name);
return done();
}, 100);
});
it("sends a push notification when invited to a quest", function(done) {
var group, req, res;
group = {
_id: 'party-id',
name: 'party-name',
type: 'party',
members: [user._id, recipient._id],
invites: [],
quest: {}
};
user.items.quests.hedgehog = 5;
group.save = function(cb) {
return cb(null, group);
};
group.markModified = function() {
return true;
};
req = {
body: {
uuids: [recipient._id]
},
query: {
key: 'hedgehog'
}
};
res = {
locals: {
group: group,
user: user
},
json: function() {
return true;
}
};
groups.questAccept(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Quest Invitation', 'Invitation for the Quest The Hedgebeast');
return done();
}, 100);
});
return it("sends a push notification to participating members when quest starts", function(done) {
var group, req, res, userMock;
group = {
_id: 'party-id',
name: 'party-name',
type: 'party',
members: [user._id, recipient._id],
invites: []
};
group.quest = {
key: 'hedgehog',
progress: {
hp: 100
},
members: {}
};
group.quest.members[recipient._id] = true;
group.save = function(cb) {
return cb(null, group);
};
group.markModified = function() {
return true;
};
req = {
body: {
uuids: [recipient._id]
},
query: {}
};
res = {
locals: {
group: group,
user: user
},
json: function() {
return true;
}
};
userMock = {
findOne: function(arg, arg2, cb) {
return cb(null, recipient);
},
update: function(arg, arg2, cb) {
if (cb) {
return cb(null, user);
} else {
return {
exec: function() {
return true;
}
};
}
}
};
groups.__set__('User', userMock);
groups.__set__('populateQuery', function(arg, arg2, arg3) {
return {
exec: function() {
return group.members;
}
};
});
groups.questAccept(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledTwice;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'HabitRPG', 'Your Quest has Begun: The Hedgebeast');
return done();
}, 100);
});
});
return describe("Gifts", function() {
var recipient;
recipient = null;
before(function(done) {
return registerNewUser(function(err, _user) {
recipient = _user;
recipient.preferences.emailNotifications.giftedGems = false;
user.balance = 4;
user.save = function() {
return true;
};
recipient.save = function() {
return true;
};
return done();
}, false);
});
context("sending gems from balance", function() {
var members;
members = rewire("../../website/src/controllers/api-v2/members");
members.sendMessage = function() {
return true;
};
members.__set__('pushNotify', pushSpy);
members.__set__('fetchMember', function(id) {
return function(cb) {
return cb(null, recipient);
};
});
return it("sends a push notification", function(done) {
var req, res;
req = {
params: {
uuid: "uuid"
},
body: {
type: 'gems',
gems: {
amount: 1
}
}
};
res = {
locals: {
user: user
}
};
members.sendGift(req, res);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Gifted Gems', '1 Gems - by ' + user.profile.name);
return done();
}, 100);
});
});
return describe("Purchases", function() {
var membersMock, payments;
payments = rewire("../../website/src/controllers/payments");
payments.__set__('pushNotify', pushSpy);
membersMock = {
sendMessage: function() {
return true;
}
};
payments.__set__('members', membersMock);
context("buying gems as a purchased gift", function() {
it("sends a push notification", function(done) {
var data;
data = {
user: user,
gift: {
member: recipient,
gems: {
amount: 1
}
}
};
payments.buyGems(data);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Gifted Gems', '1 Gems - by ' + user.profile.name);
return done();
}, 100);
});
return it("does not send a push notification if buying gems for self", function(done) {
var data;
data = {
user: user,
gift: {
member: user,
gems: {
amount: 1
}
}
};
payments.buyGems(data);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.not.have.been.called;
return done();
}, 100);
});
});
return context("sending a subscription as a purchased gift", function() {
it("sends a push notification", function(done) {
var data;
data = {
user: user,
gift: {
member: recipient,
subscription: {
key: 'basic_6mo'
}
}
};
payments.createSubscription(data);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.have.been.calledOnce;
expect(pushSpy.sendNotify).to.have.been.calledWith(recipient, 'Gifted Subscription', '6 months - by ' + user.profile.name);
return done();
}, 100);
});
return it("does not send a push notification if buying subscription for self", function(done) {
var data;
data = {
user: user,
gift: {
member: user,
subscription: {
key: 'basic_6mo'
}
}
};
payments.createSubscription(data);
return setTimeout(function() {
expect(pushSpy.sendNotify).to.not.have.been.called;
return done();
}, 100);
});
});
});
});
});
});
}).call(this);

View File

@@ -1,114 +0,0 @@
'use strict'
require("../../website/src/server")
describe "Score", ->
before (done) ->
registerNewUser done, true
context "Todos that did not previously exist", ->
it "creates a completed a todo when using up url", (done) ->
request.post(baseURL + "/user/tasks/withUp/up").send(
type: "todo"
text: "withUp"
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/withUp").end (err, res) ->
upTodo = res.body
expect(upTodo.completed).to.equal true
done()
it "creates an uncompleted todo when using down url", (done) ->
request.post(baseURL + "/user/tasks/withDown/down").send(
type: "todo"
text: "withDown"
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/withDown").end (err, res) ->
downTodo = res.body
expect(downTodo.completed).to.equal false
done()
it "creates a completed a todo overriding the complete parameter when using up url", (done) ->
request.post(baseURL + "/user/tasks/withUpWithComplete/up").send(
type: "todo"
text: "withUpWithComplete"
completed: false
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/withUpWithComplete").end (err, res) ->
upTodo = res.body
expect(upTodo.completed).to.equal true
done()
it "Creates an uncompleted todo overriding the completed parameter when using down url", (done) ->
request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send(
type: "todo"
text: "withDownWithUncomplete"
completed: true
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/withDownWithUncomplete").end (err, res) ->
downTodo = res.body
expect(downTodo.completed).to.equal false
done()
context "Todo that already exists", ->
it "It completes a todo when using up url", (done) ->
request.post(baseURL + "/user/tasks").send(
type: "todo"
text: "Sample Todo"
).end (err, res) ->
expectCode res, 200
unCompletedTodo = res.body
expect(unCompletedTodo.completed).to.equal false
request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/"+unCompletedTodo._id).end (err, res) ->
unCompletedTodo = res.body
expect(unCompletedTodo.completed).to.equal true
done()
it "It uncompletes a todo when using down url", (done) ->
request.post(baseURL + "/user/tasks").send(
type: "todo"
text: "Sample Todo"
completed: true
).end (err, res) ->
expectCode res, 200
completedTodo = res.body
expect(completedTodo.completed).to.equal true
request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/"+completedTodo._id).end (err, res) ->
completedTodo = res.body
expect(completedTodo.completed).to.equal false
done()
it "Creates and scores up a habit when using up url", (done) ->
upHabit = undefined
request.post(baseURL + "/user/tasks/habitWithUp/up").send(
type: "habit"
text: "testTitle"
completed: true
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/habitWithUp").end (err, res) ->
upHabit = res.body
expect(upHabit.value).to.be.at.least(1)
expect(upHabit.type).to.equal("habit")
done()
it "Creates and scores down a habit when using down url", (done) ->
downHabit = undefined
request.post(baseURL + "/user/tasks/habitWithDown/down").send(
type: "habit"
text: "testTitle"
completed: true
).end (err, res) ->
expectCode res, 200
request.get(baseURL + "/user/tasks/habitWithDown").end (err, res) ->
downHabit = res.body
expect(downHabit.value).to.have.at.most(-1)
expect(downHabit.type).to.equal("habit")
done()

146
test/api-legacy/score.js Normal file
View File

@@ -0,0 +1,146 @@
(function() {
'use strict';
require("../../website/src/server");
describe("Score", function() {
before(function(done) {
return registerNewUser(done, true);
});
context("Todos that did not previously exist", function() {
it("creates a completed a todo when using up url", function(done) {
return request.post(baseURL + "/user/tasks/withUp/up").send({
type: "todo",
text: "withUp"
}).end(function(err, res) {
expectCode(res, 200);
request.get(baseURL + "/user/tasks/withUp").end(function(err, res) {
var upTodo;
upTodo = res.body;
return expect(upTodo.completed).to.equal(true);
});
return done();
});
});
it("creates an uncompleted todo when using down url", function(done) {
return request.post(baseURL + "/user/tasks/withDown/down").send({
type: "todo",
text: "withDown"
}).end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/withDown").end(function(err, res) {
var downTodo;
downTodo = res.body;
expect(downTodo.completed).to.equal(false);
return done();
});
});
});
it("creates a completed a todo overriding the complete parameter when using up url", function(done) {
return request.post(baseURL + "/user/tasks/withUpWithComplete/up").send({
type: "todo",
text: "withUpWithComplete",
completed: false
}).end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/withUpWithComplete").end(function(err, res) {
var upTodo;
upTodo = res.body;
expect(upTodo.completed).to.equal(true);
return done();
});
});
});
return it("Creates an uncompleted todo overriding the completed parameter when using down url", function(done) {
return request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send({
type: "todo",
text: "withDownWithUncomplete",
completed: true
}).end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/withDownWithUncomplete").end(function(err, res) {
var downTodo;
downTodo = res.body;
expect(downTodo.completed).to.equal(false);
return done();
});
});
});
});
context("Todo that already exists", function() {
it("It completes a todo when using up url", function(done) {
return request.post(baseURL + "/user/tasks").send({
type: "todo",
text: "Sample Todo"
}).end(function(err, res) {
var unCompletedTodo;
expectCode(res, 200);
unCompletedTodo = res.body;
expect(unCompletedTodo.completed).to.equal(false);
return request.post(baseURL + "/user/tasks/" + unCompletedTodo._id + "/up").end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/" + unCompletedTodo._id).end(function(err, res) {
unCompletedTodo = res.body;
expect(unCompletedTodo.completed).to.equal(true);
return done();
});
});
});
});
return it("It uncompletes a todo when using down url", function(done) {
return request.post(baseURL + "/user/tasks").send({
type: "todo",
text: "Sample Todo",
completed: true
}).end(function(err, res) {
var completedTodo;
expectCode(res, 200);
completedTodo = res.body;
expect(completedTodo.completed).to.equal(true);
return request.post(baseURL + "/user/tasks/" + completedTodo._id + "/down").end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/" + completedTodo._id).end(function(err, res) {
completedTodo = res.body;
expect(completedTodo.completed).to.equal(false);
return done();
});
});
});
});
});
it("Creates and scores up a habit when using up url", function(done) {
var upHabit;
upHabit = void 0;
return request.post(baseURL + "/user/tasks/habitWithUp/up").send({
type: "habit",
text: "testTitle",
completed: true
}).end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/habitWithUp").end(function(err, res) {
upHabit = res.body;
expect(upHabit.value).to.be.at.least(1);
expect(upHabit.type).to.equal("habit");
return done();
});
});
});
return it("Creates and scores down a habit when using down url", function(done) {
var downHabit;
downHabit = void 0;
return request.post(baseURL + "/user/tasks/habitWithDown/down").send({
type: "habit",
text: "testTitle",
completed: true
}).end(function(err, res) {
expectCode(res, 200);
return request.get(baseURL + "/user/tasks/habitWithDown").end(function(err, res) {
downHabit = res.body;
expect(downHabit.value).to.have.at.most(-1);
expect(downHabit.type).to.equal("habit");
return done();
});
});
});
});
}).call(this);

View File

@@ -1,41 +0,0 @@
'use strict'
payments = require("../../website/src/controllers/payments")
app = require("../../website/src/server")
describe "Subscriptions", ->
before (done) ->
registerNewUser(done, true)
it "Handles unsubscription", (done) ->
cron = ->
user.lastCron = moment().subtract(1, "d")
user.fns.cron()
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.exist
shared.wrap user
cron()
expect(user.purchased.plan.customerId).to.exist
payments.cancelSubscription user: user
cron()
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.exist
payments.createSubscription
user: user
customerId: "123"
paymentMethod: "Stripe"
sub: {key: 'basic_6mo'}
expect(user.purchased.plan.dateTerminated).to.not.exist
done()

View File

@@ -0,0 +1,54 @@
(function() {
'use strict';
var app, payments;
payments = require("../../website/src/controllers/payments");
app = require("../../website/src/server");
describe("Subscriptions", function() {
before(function(done) {
return registerNewUser(done, true);
});
return it("Handles unsubscription", function(done) {
var cron;
cron = function() {
user.lastCron = moment().subtract(1, "d");
return user.fns.cron();
};
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.exist;
shared.wrap(user);
cron();
expect(user.purchased.plan.customerId).to.exist;
payments.cancelSubscription({
user: user
});
cron();
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.exist;
payments.createSubscription({
user: user,
customerId: "123",
paymentMethod: "Stripe",
sub: {
key: 'basic_6mo'
}
});
expect(user.purchased.plan.dateTerminated).to.not.exist;
return done();
});
});
}).call(this);

View File

@@ -1,82 +0,0 @@
'use strict'
require("../../website/src/server")
describe "Todos", ->
before (done) ->
registerNewUser done, true
beforeEach (done) ->
User.findById user._id, (err, _user) ->
user = _user
shared.wrap user
done()
it "Archives old todos", (done) ->
numTasks = _.size(user.todos)
request.post(baseURL + "/user/batch-update?_v=999").send([
{
op: "addTask"
body:
type: "todo"
}
{
op: "addTask"
body:
type: "todo"
}
{
op: "addTask"
body:
type: "todo"
}
]).end (err, 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.equal numTasks + 3
# Assign new number to numTasks variable
numTasks += 3
request.post(baseURL + "/user/batch-update?_v=998").send([
{
op: "score"
params:
direction: "up"
id: res.body.todos[0].id
}
{
op: "score"
params:
direction: "up"
id: res.body.todos[1].id
}
{
op: "score"
params:
direction: "up"
id: res.body.todos[2].id
}
]).end (err, res) ->
expectCode res, 200
expect(_.size(res.body.todos)).to.equal numTasks
request.post(baseURL + "/user/batch-update?_v=997").send([
{
op: "updateTask"
params:
id: res.body.todos[0].id
body:
dateCompleted: moment().subtract(4, "days")
}
{
op: "updateTask"
params:
id: res.body.todos[1].id
body:
dateCompleted: moment().subtract(4, "days")
}
]).end (err, res) ->
# Expect todos to be 2 less than the total count
expect(_.size(res.body.todos)).to.equal numTasks - 2
done()

91
test/api-legacy/todos.js Normal file
View File

@@ -0,0 +1,91 @@
(function() {
'use strict';
require("../../website/src/server");
describe("Todos", function() {
before(function(done) {
return registerNewUser(done, true);
});
beforeEach(function(done) {
return User.findById(user._id, function(err, _user) {
var user;
user = _user;
shared.wrap(user);
return done();
});
});
return it("Archives old todos", function(done) {
var numTasks;
numTasks = _.size(user.todos);
return request.post(baseURL + "/user/batch-update?_v=999").send([
{
op: "addTask",
body: {
type: "todo"
}
}, {
op: "addTask",
body: {
type: "todo"
}
}, {
op: "addTask",
body: {
type: "todo"
}
}
]).end(function(err, res) {
expectCode(res, 200);
expect(_.size(res.body.todos)).to.equal(numTasks + 3);
numTasks += 3;
return request.post(baseURL + "/user/batch-update?_v=998").send([
{
op: "score",
params: {
direction: "up",
id: res.body.todos[0].id
}
}, {
op: "score",
params: {
direction: "up",
id: res.body.todos[1].id
}
}, {
op: "score",
params: {
direction: "up",
id: res.body.todos[2].id
}
}
]).end(function(err, res) {
expectCode(res, 200);
expect(_.size(res.body.todos)).to.equal(numTasks);
return request.post(baseURL + "/user/batch-update?_v=997").send([
{
op: "updateTask",
params: {
id: res.body.todos[0].id
},
body: {
dateCompleted: moment().subtract(4, "days")
}
}, {
op: "updateTask",
params: {
id: res.body.todos[1].id
},
body: {
dateCompleted: moment().subtract(4, "days")
}
}
]).end(function(err, res) {
expect(_.size(res.body.todos)).to.equal(numTasks - 2);
return done();
});
});
});
});
});
}).call(this);