mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-07-11 14:39:37 +00:00
Merge pull request #6062 from crookedneighbor/new_api_test_infrastructure
New api test infrastructure
This commit is contained in:
commit
ff64523ae4
34 changed files with 1679 additions and 794 deletions
|
|
@ -72,7 +72,7 @@
|
|||
"request": "~2.44.0",
|
||||
"s3-upload-stream": "^1.0.6",
|
||||
"stripe": "*",
|
||||
"superagent": "~0.15.7",
|
||||
"superagent": "~1.4.0",
|
||||
"swagger-node-express": "lefnire/swagger-node-express#habitrpg",
|
||||
"universal-analytics": "~0.3.2",
|
||||
"validator": "~3.19.0",
|
||||
|
|
@ -121,13 +121,15 @@
|
|||
"karma-script-launcher": "~0.1.0",
|
||||
"lcov-result-merger": "^1.0.2",
|
||||
"mocha": "~1.12.1",
|
||||
"mongodb": "^2.0.46",
|
||||
"mongoskin": "~0.6.1",
|
||||
"protractor": "~2.0.0",
|
||||
"rewire": "^2.3.3",
|
||||
"shelljs": "^0.4.0",
|
||||
"sinon": "1.15.4",
|
||||
"sinon-chai": "^2.7.0",
|
||||
"superagent-defaults": "~0.1.5",
|
||||
"superagent-defaults": "^0.1.13",
|
||||
"uuid": "^2.0.1",
|
||||
"vinyl-source-stream": "^1.0.0",
|
||||
"vinyl-transform": "^1.0.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,21 +4,26 @@ import mongoose from 'mongoose';
|
|||
import { exec } from 'child_process';
|
||||
import psTree from 'ps-tree';
|
||||
import gulp from 'gulp';
|
||||
import { sync as glob } from 'glob';
|
||||
import Q from 'q';
|
||||
import Mocha from 'mocha';
|
||||
import { resolve } from 'path';
|
||||
|
||||
const TEST_SERVER_PORT = 3001
|
||||
const E2E_TEST_SERVER_PORT = 3001
|
||||
const API_TEST_SERVER_PORT = 3003
|
||||
const TEST_DB = 'habitrpg_test'
|
||||
|
||||
const TEST_DB_URI = `mongodb://localhost/${TEST_DB}`
|
||||
|
||||
const API_TEST_COMMAND = 'mocha test/api';
|
||||
const COMMON_TEST_COMMAND = 'mocha test/common';
|
||||
const CONTENT_TEST_COMMAND = 'mocha test/content --opts test/content/mocha.content.opts';
|
||||
const API_TEST_COMMAND = 'mocha test/api --recursive --compilers js:babel/register';
|
||||
const LEGACY_API_TEST_COMMAND = 'mocha test/api-legacy';
|
||||
const COMMON_TEST_COMMAND = 'mocha test/common --compilers coffee:coffee-script';
|
||||
const CONTENT_TEST_COMMAND = 'mocha test/content --compilers js:babel/register';
|
||||
const CONTENT_OPTIONS = {maxBuffer: 1024 * 500};
|
||||
const KARMA_TEST_COMMAND = 'karma start';
|
||||
const SERVER_SIDE_TEST_COMMAND = 'mocha test/server_side';
|
||||
|
||||
const INSTANBUL_TEST_COMMAND = `istanbul cover -i "website/src/**" --dir coverage/api $(npm bin)/${API_TEST_COMMAND}`;
|
||||
const ISTANBUL_TEST_COMMAND = `istanbul cover -i "website/src/**" --dir coverage/api ./node_modules/.bin/${LEGACY_API_TEST_COMMAND}`;
|
||||
|
||||
/* Helper methods for reporting test summary */
|
||||
let testResults = [];
|
||||
|
|
@ -32,7 +37,8 @@ let testBin = (string) => {
|
|||
};
|
||||
|
||||
gulp.task('test:prepare:mongo', (cb) => {
|
||||
mongoose.connect(TEST_DB_URI, () => {
|
||||
mongoose.connect(TEST_DB_URI, (err) => {
|
||||
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
|
||||
mongoose.connection.db.dropDatabase();
|
||||
mongoose.connection.close();
|
||||
cb();
|
||||
|
|
@ -149,9 +155,9 @@ gulp.task('test:server_side:safe', ['test:prepare:build'], (cb) => {
|
|||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api', ['test:prepare:mongo'], (cb) => {
|
||||
gulp.task('test:api-legacy', ['test:prepare:mongo'], (cb) => {
|
||||
let runner = exec(
|
||||
testBin(INSTANBUL_TEST_COMMAND),
|
||||
testBin(ISTANBUL_TEST_COMMAND),
|
||||
(err, stdout, stderr) => {
|
||||
cb(err);
|
||||
}
|
||||
|
|
@ -159,12 +165,12 @@ gulp.task('test:api', ['test:prepare:mongo'], (cb) => {
|
|||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api:safe', ['test:prepare:mongo'], (cb) => {
|
||||
gulp.task('test:api-legacy:safe', ['test:prepare:mongo'], (cb) => {
|
||||
let runner = exec(
|
||||
testBin(INSTANBUL_TEST_COMMAND),
|
||||
testBin(ISTANBUL_TEST_COMMAND),
|
||||
(err, stdout, stderr) => {
|
||||
testResults.push({
|
||||
suite: 'API Specs\t',
|
||||
suite: 'API (legacy) Specs',
|
||||
pass: testCount(stdout, /(\d+) passing/),
|
||||
fail: testCount(stderr, /(\d+) failing/),
|
||||
pend: testCount(stdout, /(\d+) pending/)
|
||||
|
|
@ -175,15 +181,15 @@ gulp.task('test:api:safe', ['test:prepare:mongo'], (cb) => {
|
|||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api:clean', (cb) => {
|
||||
pipe(exec(testBin(API_TEST_COMMAND), () => cb()));
|
||||
gulp.task('test:api-legacy:clean', (cb) => {
|
||||
pipe(exec(testBin(LEGACY_API_TEST_COMMAND), () => cb()));
|
||||
});
|
||||
|
||||
gulp.task('test:api:watch', [
|
||||
gulp.task('test:api-legacy:watch', [
|
||||
'test:prepare:mongo',
|
||||
'test:api:clean'
|
||||
'test:api-legacy:clean'
|
||||
], () => {
|
||||
gulp.watch(['website/src/**', 'test/api/**'], ['test:api:clean']);
|
||||
gulp.watch(['website/src/**', 'test/api-legacy/**'], ['test:api-legacy:clean']);
|
||||
});
|
||||
|
||||
gulp.task('test:karma', ['test:prepare:build'], (cb) => {
|
||||
|
|
@ -225,7 +231,7 @@ gulp.task('test:karma:safe', ['test:prepare:build'], (cb) => {
|
|||
gulp.task('test:e2e', ['test:prepare'], (cb) => {
|
||||
let support = [
|
||||
'Xvfb :99 -screen 0 1024x768x24 -extension RANDR',
|
||||
`NODE_DB_URI="${TEST_DB_URI}" PORT="${TEST_SERVER_PORT}" node ./website/src/server.js`,
|
||||
`NODE_DB_URI="${TEST_DB_URI}" PORT="${E2E_TEST_SERVER_PORT}" node ./website/src/server.js`,
|
||||
'./node_modules/protractor/bin/webdriver-manager start',
|
||||
].map(exec);
|
||||
|
||||
|
|
@ -250,7 +256,7 @@ gulp.task('test:e2e', ['test:prepare'], (cb) => {
|
|||
gulp.task('test:e2e:safe', ['test:prepare'], (cb) => {
|
||||
let support = [
|
||||
'Xvfb :99 -screen 0 1024x768x24 -extension RANDR',
|
||||
`NODE_DB_URI="${TEST_DB_URI}" PORT="${TEST_SERVER_PORT}" node ./website/src/server.js`,
|
||||
`NODE_DB_URI="${TEST_DB_URI}" PORT="${E2E_TEST_SERVER_PORT}" node ./website/src/server.js`,
|
||||
'./node_modules/protractor/bin/webdriver-manager start',
|
||||
].map(exec);
|
||||
|
||||
|
|
@ -279,13 +285,64 @@ gulp.task('test:e2e:safe', ['test:prepare'], (cb) => {
|
|||
});
|
||||
});
|
||||
|
||||
gulp.task('test:api', ['test:prepare:mongo'], (done) => {
|
||||
require('../test/helpers/globals.helper');
|
||||
|
||||
let server = exec(`NODE_DB_URI="${TEST_DB_URI}" PORT="${API_TEST_SERVER_PORT}" node ./website/src/server.js`);
|
||||
|
||||
awaitPort(API_TEST_SERVER_PORT).then(() => {
|
||||
let mocha = new Mocha({reporter: 'spec'});
|
||||
let tests = glob('./test/api/**/*.js');
|
||||
|
||||
tests.forEach((test) => {
|
||||
delete require.cache[resolve(test)];
|
||||
mocha.addFile(test);
|
||||
});
|
||||
|
||||
mocha.run((numberOfFailures) => {
|
||||
if (!process.env.RUN_INTEGRATION_TEST_FOREVER) {
|
||||
kill(server);
|
||||
process.exit(numberOfFailures);
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test:api:watch', () => {
|
||||
process.env.RUN_INTEGRATION_TEST_FOREVER = true;
|
||||
gulp.watch(['website/src/**', 'test/api/**'], ['test:api']);
|
||||
});
|
||||
|
||||
gulp.task('test:api:safe', ['test:prepare:mongo'], (done) => {
|
||||
let server = exec(`NODE_DB_URI="${TEST_DB_URI}" PORT="${API_TEST_SERVER_PORT}" node ./website/src/server.js`);
|
||||
|
||||
awaitPort(API_TEST_SERVER_PORT).then(() => {
|
||||
let runner = exec(
|
||||
testBin(API_TEST_COMMAND),
|
||||
(err, stdout, stderr) => {
|
||||
testResults.push({
|
||||
suite: 'API Specs\t',
|
||||
pass: testCount(stdout, /(\d+) passing/),
|
||||
fail: testCount(stderr, /(\d+) failing/),
|
||||
pend: testCount(stdout, /(\d+) pending/)
|
||||
});
|
||||
kill(server);
|
||||
done();
|
||||
}
|
||||
);
|
||||
pipe(runner);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test', [
|
||||
'test:e2e:safe',
|
||||
'test:common:safe',
|
||||
'test:content:safe',
|
||||
// 'test:content:safe',
|
||||
'test:server_side:safe',
|
||||
'test:karma:safe',
|
||||
'test:api-legacy:safe',
|
||||
'test:api:safe',
|
||||
'test:e2e:safe'
|
||||
], () => {
|
||||
let totals = [0,0,0];
|
||||
|
||||
|
|
@ -312,5 +369,6 @@ gulp.task('test', [
|
|||
if (totals[1] > 0) throw "ERROR: There are failing tests!"
|
||||
else {
|
||||
console.log('\n\x1b[36mThanks for helping keep Habitica clean!\x1b[0m');
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
5
test/api-legacy/README.md
Normal file
5
test/api-legacy/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Legacy API Tests
|
||||
|
||||
These tests have been deprecated. Any tests that you see in this folder should be converted to ES2015 and ported to the `/test/api` directory.
|
||||
|
||||
Once all tests have been ported, this directory will be removed.
|
||||
|
|
@ -10,7 +10,7 @@ describe "GET /api/v2/user/anonymized", ->
|
|||
# TODO: Seed user with messages, rewards, dailys, checklists, webhooks, etc
|
||||
registerNewUser ->
|
||||
request.get(baseURL + "/user/anonymized")
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
anon = res.body
|
||||
done()
|
||||
, true
|
||||
90
test/api-legacy/api-helper.js
Normal file
90
test/api-legacy/api-helper.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
require('coffee-script');
|
||||
var path, superagentDefaults;
|
||||
|
||||
superagentDefaults = require("superagent-defaults");
|
||||
|
||||
global.request = superagentDefaults();
|
||||
|
||||
global.mongoose = require("mongoose");
|
||||
|
||||
global.moment = require("moment");
|
||||
|
||||
global.async = require("async");
|
||||
|
||||
global._ = require("lodash");
|
||||
|
||||
global.shared = require("../../common");
|
||||
|
||||
global.User = require("../../website/src/models/user").model;
|
||||
|
||||
global.chai = require("chai");
|
||||
|
||||
chai.use(require("sinon-chai"));
|
||||
|
||||
global.expect = chai.expect;
|
||||
|
||||
path = require("path");
|
||||
|
||||
global.conf = require("nconf");
|
||||
|
||||
conf.argv().env().file({
|
||||
file: path.join(__dirname, "../config.json")
|
||||
}).defaults();
|
||||
|
||||
conf.set("PORT", "1337");
|
||||
|
||||
process.env.NODE_DB_URI = "mongodb://localhost/habitrpg_test_api_legacy";
|
||||
|
||||
global.baseURL = "http://localhost:" + conf.get("PORT") + "/api/v2";
|
||||
|
||||
global.user = void 0;
|
||||
|
||||
global.expectCode = function(res, code) {
|
||||
if (code === 200) {
|
||||
expect(res.body.err).to.not.exist;
|
||||
}
|
||||
return expect(res.statusCode).to.equal(code);
|
||||
};
|
||||
|
||||
global.registerNewUser = function(cb, main) {
|
||||
var password, randomID, username;
|
||||
if (main == null) {
|
||||
main = true;
|
||||
}
|
||||
randomID = shared.uuid();
|
||||
if (main) {
|
||||
username = password = randomID;
|
||||
}
|
||||
return request.post(baseURL + "/register").set("Accept", "application/json").set("X-API-User", null).set("X-API-Key", null).send({
|
||||
username: randomID,
|
||||
password: randomID,
|
||||
confirmPassword: randomID,
|
||||
email: randomID + "@gmail.com"
|
||||
}).end(function(err, res) {
|
||||
var _id, apiToken;
|
||||
if (!main) {
|
||||
return cb(null, res.body);
|
||||
}
|
||||
_id = res.body._id;
|
||||
apiToken = res.body.apiToken;
|
||||
return User.findOne({
|
||||
_id: _id,
|
||||
apiToken: apiToken
|
||||
}, function(err, _user) {
|
||||
expect(err).to.not.be.ok;
|
||||
global.user = _user;
|
||||
request.set("Accept", "application/json").set("X-API-User", _id).set("X-API-Key", apiToken);
|
||||
return cb(null, res.body);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
global.registerManyUsers = function(number, callback) {
|
||||
return async.times(number, function(n, next) {
|
||||
return registerNewUser(function(err, user) {
|
||||
return next(err, user);
|
||||
}, false);
|
||||
}, function(err, users) {
|
||||
return callback(err, users);
|
||||
});
|
||||
};
|
||||
|
|
@ -18,7 +18,7 @@ describe "Challenges", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -38,7 +38,7 @@ describe "Challenges", ->
|
|||
}]
|
||||
rewards: []
|
||||
habits: []
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
challenge = res.body
|
||||
done()
|
||||
]
|
||||
|
|
@ -64,7 +64,7 @@ describe "Challenges", ->
|
|||
rewards: []
|
||||
habits: []
|
||||
official: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
async.parallel [
|
||||
(cb) ->
|
||||
|
|
@ -84,7 +84,7 @@ describe "Challenges", ->
|
|||
updateTodo.notes = "User overriden notes"
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (res) ->
|
||||
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (err, res) ->
|
||||
cb()
|
||||
, (cb) ->
|
||||
Challenge.findById challenge._id, cb
|
||||
|
|
@ -93,7 +93,7 @@ describe "Challenges", ->
|
|||
cb()
|
||||
, (cb) ->
|
||||
request.get(baseURL + "/user/tasks/" + updateTodo.id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expect(res.body.notes).to.eql("User overriden notes")
|
||||
done()
|
||||
]
|
||||
|
|
@ -102,7 +102,7 @@ describe "Challenges", ->
|
|||
challenge.dailys[0].text = "Updated Daily"
|
||||
request.post(baseURL + "/challenges/" + challenge._id)
|
||||
.send(challenge)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
challenge = res.body
|
||||
expect(challenge.dailys[0].text).to.equal "Updated Daily"
|
||||
User.findById user._id, (err, _user) ->
|
||||
|
|
@ -114,7 +114,7 @@ describe "Challenges", ->
|
|||
challenge.todos[0].notes = "Challenge Updated Todo Notes"
|
||||
request.post(baseURL + "/challenges/" + challenge._id)
|
||||
.send(challenge)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
challenge = res.body
|
||||
expect(challenge.todos[0].notes).to.equal "Challenge Updated Todo Notes"
|
||||
User.findById user._id, (err, _user) ->
|
||||
|
|
@ -128,7 +128,7 @@ describe "Challenges", ->
|
|||
updateTodo.notes = "User overriden notes"
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (res) ->
|
||||
request.put(baseURL + "/user/tasks/" + updateTodo.id).send(updateTodo).end (err, res) ->
|
||||
cb()
|
||||
, (cb) ->
|
||||
Challenge.findById challenge._id, cb
|
||||
|
|
@ -136,7 +136,7 @@ describe "Challenges", ->
|
|||
expect(chal.todos[0].notes).to.eql("Challenge Notes")
|
||||
cb()
|
||||
, (cb) ->
|
||||
request.get(baseURL + "/challenges/" + challenge._id + "/member/" + user._id).end (res) ->
|
||||
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()
|
||||
]
|
||||
|
|
@ -145,14 +145,14 @@ describe "Challenges", ->
|
|||
User.findById user._id, (err, _user) ->
|
||||
u = _user
|
||||
numTasks = (_.size(u.todos))
|
||||
request.post(baseURL + "/user/tasks/" + u.todos[0].id + "/up").end (res) ->
|
||||
request.post(baseURL + "/user/tasks/clear-completed").end (res) ->
|
||||
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 (res) ->
|
||||
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]
|
||||
|
|
@ -164,7 +164,7 @@ describe "Challenges", ->
|
|||
User.findByIdAndUpdate user._id, unset, (err, user) ->
|
||||
expect(err).to.not.exist
|
||||
expect(user.dailys[len].challenge.broken).to.not.exist
|
||||
request.post(baseURL + "/user/tasks/" + daily.id + "/up").end (res) ->
|
||||
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"
|
||||
|
|
@ -186,7 +186,7 @@ describe "Challenges", ->
|
|||
rewards: []
|
||||
habits: []
|
||||
official: false
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expect(res.body.official).to.equal false
|
||||
cb()
|
||||
(cb) ->
|
||||
|
|
@ -197,7 +197,7 @@ describe "Challenges", ->
|
|||
rewards: []
|
||||
habits: []
|
||||
official: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expect(res.body.official).to.equal true
|
||||
cb()
|
||||
], done
|
||||
|
|
@ -215,7 +215,7 @@ describe "Challenges", ->
|
|||
rewards: []
|
||||
habits: []
|
||||
prize: 10
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expect(res.body.prize).to.equal 10
|
||||
async.parallel [
|
||||
(cb) ->
|
||||
|
|
@ -226,7 +226,7 @@ describe "Challenges", ->
|
|||
user = results[0]
|
||||
challenge = results[1]
|
||||
expect(user.balance).to.equal 5.5
|
||||
request.del(baseURL + "/challenges/" + challenge._id).end (res) ->
|
||||
request.del(baseURL + "/challenges/" + challenge._id).end (err, res) ->
|
||||
User.findById user._id, (err, _user) ->
|
||||
expect(_user.balance).to.equal 8
|
||||
done()
|
||||
|
|
@ -244,7 +244,7 @@ describe "Challenges", ->
|
|||
rewards: []
|
||||
habits: []
|
||||
prize: 10
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expect(res.body.prize).to.equal 10
|
||||
async.parallel [
|
||||
(cb) ->
|
||||
|
|
@ -255,7 +255,7 @@ describe "Challenges", ->
|
|||
user = results[0]
|
||||
challenge = results[1]
|
||||
expect(user.balance).to.equal 5.5
|
||||
request.del(baseURL + "/challenges/" + challenge._id).end (res) ->
|
||||
request.del(baseURL + "/challenges/" + challenge._id).end (err, res) ->
|
||||
User.findById user._id, (err, _user) ->
|
||||
expect(_user.balance).to.equal 5.5
|
||||
done()
|
||||
|
|
@ -273,7 +273,7 @@ describe "Challenges", ->
|
|||
type: "daily"
|
||||
text: "Challenge Daily"
|
||||
]
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
challenge = res.body
|
||||
cb()
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ describe "Challenges", ->
|
|||
challenge.name = 'foobar'
|
||||
request.post(baseURL + "/challenges/" + challenge._id)
|
||||
.send(challenge)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
error = res.body.err
|
||||
|
||||
expect(error).to.eql("You don't have permissions to edit this challenge")
|
||||
|
|
@ -295,7 +295,7 @@ describe "Challenges", ->
|
|||
|
||||
it 'can not close challenge', (done) ->
|
||||
request.post(baseURL + "/challenges/" + challenge._id + "/close?uid=" + user._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
error = res.body.err
|
||||
|
||||
expect(error).to.eql("You don't have permissions to close this challenge")
|
||||
|
|
@ -303,7 +303,7 @@ describe "Challenges", ->
|
|||
|
||||
it 'can not delete challenge', (done) ->
|
||||
request.del(baseURL + "/challenges/" + challenge._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
error = res.body.err
|
||||
|
||||
expect(error).to.eql("You don't have permissions to delete this challenge")
|
||||
|
|
@ -318,7 +318,7 @@ describe "Challenges", ->
|
|||
challenge.name = 'foobar'
|
||||
request.post(baseURL + "/challenges/" + challenge._id)
|
||||
.send(challenge)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expect(res.body.err).to.not.exist
|
||||
Challenge.findById challenge._id, (err, chal) ->
|
||||
expect(chal.name).to.eql('foobar')
|
||||
|
|
@ -326,7 +326,7 @@ describe "Challenges", ->
|
|||
|
||||
it 'can close challenge', (done) ->
|
||||
request.post(baseURL + "/challenges/" + challenge._id + "/close?uid=" + user._id)
|
||||
.end (res) ->
|
||||
.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)
|
||||
|
|
@ -334,10 +334,10 @@ describe "Challenges", ->
|
|||
|
||||
it 'can delete challenge', (done) ->
|
||||
request.del(baseURL + "/challenges/" + challenge._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expect(res.body.err).to.not.exist
|
||||
request.get(baseURL + "/challenges/" + challenge._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
error = res.body.err
|
||||
expect(error).to.eql("Challenge #{challenge._id} not found")
|
||||
done()
|
||||
|
|
@ -16,7 +16,7 @@ describe "Chat", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -28,7 +28,7 @@ describe "Chat", ->
|
|||
chat = undefined
|
||||
it "posts a message to party chat", (done) ->
|
||||
msg = "TestMsg"
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg).end (res) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg).end (err, res) ->
|
||||
expectCode res, 200
|
||||
chat = res.body.message
|
||||
expect(chat.id).to.be.ok
|
||||
|
|
@ -47,14 +47,14 @@ describe "Chat", ->
|
|||
it "does not post an empty message", (done) ->
|
||||
msg = ""
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg).send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 400
|
||||
expect(res.body.err).to.equal 'You cannot send a blank message'
|
||||
done()
|
||||
|
||||
it "can not like own chat message", (done) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat/" + chat.id + "/like").send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 401
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Can't like your own message. Don't be that person."
|
||||
|
|
@ -62,7 +62,7 @@ describe "Chat", ->
|
|||
|
||||
it "can not flag own message", (done) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat/" + chat.id + "/flag").send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 401
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Can't report your own message."
|
||||
|
|
@ -70,7 +70,7 @@ describe "Chat", ->
|
|||
|
||||
it "gets chat messages from party chat", (done) ->
|
||||
request.get(baseURL + "/groups/" + group._id + "/chat").send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
message = res.body[0]
|
||||
expect(message.id).to.equal chat.id
|
||||
|
|
@ -86,14 +86,14 @@ describe "Chat", ->
|
|||
|
||||
it "deletes a chat messages from party chat", (done) ->
|
||||
request.del(baseURL + "/groups/" + group._id + "/chat/" + chat.id).send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 204
|
||||
expect(res.body).to.be.empty
|
||||
done()
|
||||
|
||||
it "can not delete already deleted message", (done) ->
|
||||
request.del(baseURL + "/groups/" + group._id + "/chat/" + chat.id).send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 404
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Message not found!"
|
||||
|
|
@ -116,30 +116,30 @@ describe "Chat", ->
|
|||
request.post(baseURL + "/groups/" + group._id + "/join")
|
||||
.set("X-API-User", userToRemove._id)
|
||||
.set("X-API-Key", userToRemove.apiToken)
|
||||
.end (res) -> cb()
|
||||
.end (err, res) -> cb()
|
||||
|
||||
(cb) ->
|
||||
msg = "TestMsg"
|
||||
request.post(baseURL + "/groups/" + group._id + "/chat?message=" + msg)
|
||||
.end (res) -> cb()
|
||||
.end (err, res) -> cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/user")
|
||||
.set("X-API-User", userToRemove._id)
|
||||
.set("X-API-Key", userToRemove.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expect(res.body.newMessages[group._id]).to.exist
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/removeMember?uuid=" + userToRemove._id)
|
||||
.end (res) -> cb()
|
||||
.end (err, res) -> cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/user")
|
||||
.set("X-API-User", userToRemove._id)
|
||||
.set("X-API-Key", userToRemove.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expect(res.body.newMessages[group._id]).to.not.exist
|
||||
cb()
|
||||
], done
|
||||
|
|
@ -34,7 +34,7 @@ describe "Coupons", ->
|
|||
queries = '?count=10'
|
||||
request
|
||||
.post(baseURL + '/coupons/generate/wondercon' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
Coupon.find { event: 'wondercon' }, (err, _coupons) ->
|
||||
coupons = _coupons
|
||||
|
|
@ -52,7 +52,7 @@ describe "Coupons", ->
|
|||
queries = '?count=10'
|
||||
request
|
||||
.post(baseURL + '/coupons/generate/wondercon' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 401
|
||||
expect(res.body.err).to.equal 'You don\'t have admin access'
|
||||
done()
|
||||
|
|
@ -68,7 +68,7 @@ describe "Coupons", ->
|
|||
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken
|
||||
request
|
||||
.get(baseURL + '/coupons' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
codes = res.text
|
||||
expect(codes).to.contain('code')
|
||||
|
|
@ -81,7 +81,7 @@ describe "Coupons", ->
|
|||
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&limit=5'
|
||||
request
|
||||
.get(baseURL + '/coupons' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
codes = res.text
|
||||
sortedCoupons = _.sortBy(coupons, 'seq')
|
||||
|
|
@ -98,7 +98,7 @@ describe "Coupons", ->
|
|||
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken + '&skip=5'
|
||||
request
|
||||
.get(baseURL + '/coupons' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
codes = res.text
|
||||
sortedCoupons = _.sortBy(coupons, 'seq')
|
||||
|
|
@ -121,7 +121,7 @@ describe "Coupons", ->
|
|||
queries = '?_id=' + user._id + '&apiToken=' + user.apiToken
|
||||
request
|
||||
.get(baseURL + '/coupons' + queries)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 401
|
||||
expect(res.body.err).to.equal 'You don\'t have admin access'
|
||||
done()
|
||||
|
|
@ -156,7 +156,7 @@ describe "Coupons", ->
|
|||
code = coupons[0]._id
|
||||
request
|
||||
.post(baseURL + '/user/coupon/' + code)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
gear = res.body.items.gear.owned
|
||||
specialGear(gear, true)
|
||||
|
|
@ -168,7 +168,7 @@ describe "Coupons", ->
|
|||
code = coupons[0]._id
|
||||
request
|
||||
.post(baseURL + '/user/coupon/' + code)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 400
|
||||
expect(res.body.err).to.equal "Coupon already used"
|
||||
User.findById user._id, (err, _user) ->
|
||||
|
|
@ -182,7 +182,7 @@ describe "Coupons", ->
|
|||
code = "not-a-real-coupon"
|
||||
request
|
||||
.post(baseURL + '/user/coupon/' + code)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 400
|
||||
expect(res.body.err).to.equal "Invalid coupon code"
|
||||
User.findById user._id, (err, _user) ->
|
||||
|
|
@ -16,7 +16,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -28,7 +28,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 400
|
||||
expect(res.body.err).to.equal "Already in a party, try refreshing."
|
||||
done()
|
||||
|
|
@ -44,7 +44,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -55,7 +55,7 @@ describe "Party", ->
|
|||
it "can be found by querying for group type party", (done) ->
|
||||
request.get(baseURL + "/groups/").send(
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
party = _.find res.body, (g) -> return g._id == group._id
|
||||
expect(party._id).to.equal group._id
|
||||
|
|
@ -76,7 +76,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -89,7 +89,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups/" + group._id + "/join").send()
|
||||
.set("X-API-User", user._id)
|
||||
.set("X-API-Key", user.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 401
|
||||
expect(res.body.err).to.equal "Can't join a group you're not invited to."
|
||||
done()
|
||||
|
|
@ -114,7 +114,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups/" + group._id + "/join")
|
||||
.set("X-API-User", tmpUser._id)
|
||||
.set("X-API-Key", tmpUser.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ describe "Party", ->
|
|||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
group = res.body
|
||||
expect(group.members.length).to.equal 1
|
||||
|
|
@ -164,13 +164,13 @@ describe "Party", ->
|
|||
request.post(baseURL + '/user/tasks').send({
|
||||
type: 'daily'
|
||||
text: 'daily one'
|
||||
}).end (res) ->
|
||||
}).end (err, res) ->
|
||||
cb()
|
||||
(cb) ->
|
||||
request.post(baseURL + '/user/tasks').send({
|
||||
type: 'daily'
|
||||
text: 'daily two'
|
||||
}).end (res) ->
|
||||
}).end (err, res) ->
|
||||
cb()
|
||||
(cb) ->
|
||||
User.findByIdAndUpdate user._id,
|
||||
|
|
@ -198,7 +198,7 @@ describe "Party", ->
|
|||
body:
|
||||
"stats.lvl": 50
|
||||
}
|
||||
]).end (res) ->
|
||||
]).end (err, res) ->
|
||||
user = res.body
|
||||
expect(user.party.quest.progress.up).to.be.above 0
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ describe "Party", ->
|
|||
(cb2) ->
|
||||
request.post(inviteURL).send(
|
||||
uuids: [party[2]._id]
|
||||
).end (res)->
|
||||
).end (err, res)->
|
||||
cb2()
|
||||
], cb
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ describe "Party", ->
|
|||
# Start the quest
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (res) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (err, res) ->
|
||||
expectCode res, 400
|
||||
User.findByIdAndUpdate user._id,
|
||||
$set:
|
||||
|
|
@ -263,7 +263,7 @@ describe "Party", ->
|
|||
, cb
|
||||
|
||||
(_user, cb) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (res) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept?key=vice3").end (err, res) ->
|
||||
expectCode res, 200
|
||||
Group.findById group._id, cb
|
||||
|
||||
|
|
@ -271,8 +271,8 @@ describe "Party", ->
|
|||
expect(_group.quest.key).to.equal "vice3"
|
||||
expect(_group.quest.active).to.equal false
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[0]._id).set("X-API-Key", party[0].apiToken).end ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questAccept").set("X-API-User", party[1]._id).set("X-API-Key", party[1].apiToken).end (res) ->
|
||||
request.post(baseURL + "/groups/" + group._id + "/questReject").set("X-API-User", party[2]._id).set("X-API-Key", party[2].apiToken).end (res) ->
|
||||
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()
|
||||
|
|
@ -282,12 +282,12 @@ describe "Party", ->
|
|||
|
||||
it "Casts a spell", (done) ->
|
||||
mp = user.stats.mp
|
||||
request.get(baseURL + "/members/" + party[0]._id).end (res) ->
|
||||
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 (res) ->
|
||||
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 (res) ->
|
||||
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
|
||||
|
|
@ -295,18 +295,18 @@ describe "Party", ->
|
|||
expect(_.size(difference)).to.equal 2
|
||||
|
||||
# level up user so str is > 0
|
||||
request.put(baseURL + "/user").send("stats.lvl": 5).end (res) ->
|
||||
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 (res) ->
|
||||
request.post(baseURL + "/user/class/cast/valorousPresence?targetType=party").end (res) ->
|
||||
request.get(baseURL + "/members/" + member._id).end (res) ->
|
||||
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 (res) ->
|
||||
request.get(baseURL + "/groups/" + group._id).end (err, res) ->
|
||||
expect(_.size(res.body.quest.members)).to.equal 3
|
||||
done()
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ describe "Party", ->
|
|||
done()
|
||||
|
||||
xit "Hurts the boss", (done) ->
|
||||
request.post(baseURL + "/user/batch-update").end (res) ->
|
||||
request.post(baseURL + "/user/batch-update").end (err, res) ->
|
||||
user = res.body
|
||||
up = user.party.quest.progress.up
|
||||
expect(up).to.be.above 0
|
||||
|
|
@ -344,10 +344,10 @@ describe "Party", ->
|
|||
body:
|
||||
lastCron: moment().subtract(1, "days")
|
||||
}
|
||||
]).end (res) ->
|
||||
]).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 (res) ->
|
||||
request.get(baseURL + "/groups/party").end (err, res) ->
|
||||
|
||||
# Check boss damage
|
||||
async.waterfall [
|
||||
|
|
@ -419,7 +419,7 @@ describe "Party", ->
|
|||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/user/batch-update").end (res) ->
|
||||
request.post(baseURL + "/user/batch-update").end (err, res) ->
|
||||
cb null, res.body
|
||||
|
||||
(_user, cb) ->
|
||||
|
|
@ -15,7 +15,7 @@ describe "Push-Notifications", ->
|
|||
it "Registers a DeviceID", (done) ->
|
||||
request.post(baseURL + "/user/pushDevice").send(
|
||||
{ regId: "123123", type: "android"}
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
|
||||
User.findOne
|
||||
|
|
@ -11,9 +11,9 @@ describe "Score", ->
|
|||
request.post(baseURL + "/user/tasks/withUp/up").send(
|
||||
type: "todo"
|
||||
text: "withUp"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withUp").end (res) ->
|
||||
request.get(baseURL + "/user/tasks/withUp").end (err, res) ->
|
||||
upTodo = res.body
|
||||
expect(upTodo.completed).to.equal true
|
||||
done()
|
||||
|
|
@ -22,9 +22,9 @@ describe "Score", ->
|
|||
request.post(baseURL + "/user/tasks/withDown/down").send(
|
||||
type: "todo"
|
||||
text: "withDown"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withDown").end (res) ->
|
||||
request.get(baseURL + "/user/tasks/withDown").end (err, res) ->
|
||||
downTodo = res.body
|
||||
expect(downTodo.completed).to.equal false
|
||||
done()
|
||||
|
|
@ -34,9 +34,9 @@ describe "Score", ->
|
|||
type: "todo"
|
||||
text: "withUpWithComplete"
|
||||
completed: false
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withUpWithComplete").end (res) ->
|
||||
request.get(baseURL + "/user/tasks/withUpWithComplete").end (err, res) ->
|
||||
upTodo = res.body
|
||||
expect(upTodo.completed).to.equal true
|
||||
done()
|
||||
|
|
@ -46,9 +46,9 @@ describe "Score", ->
|
|||
type: "todo"
|
||||
text: "withDownWithUncomplete"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withDownWithUncomplete").end (res) ->
|
||||
request.get(baseURL + "/user/tasks/withDownWithUncomplete").end (err, res) ->
|
||||
downTodo = res.body
|
||||
expect(downTodo.completed).to.equal false
|
||||
done()
|
||||
|
|
@ -58,13 +58,13 @@ describe "Score", ->
|
|||
request.post(baseURL + "/user/tasks").send(
|
||||
type: "todo"
|
||||
text: "Sample Todo"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
unCompletedTodo = res.body
|
||||
expect(unCompletedTodo.completed).to.equal false
|
||||
request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").end (res) ->
|
||||
request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/"+unCompletedTodo._id).end (res) ->
|
||||
request.get(baseURL + "/user/tasks/"+unCompletedTodo._id).end (err, res) ->
|
||||
unCompletedTodo = res.body
|
||||
expect(unCompletedTodo.completed).to.equal true
|
||||
done()
|
||||
|
|
@ -74,13 +74,13 @@ describe "Score", ->
|
|||
type: "todo"
|
||||
text: "Sample Todo"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
completedTodo = res.body
|
||||
expect(completedTodo.completed).to.equal true
|
||||
request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").end (res) ->
|
||||
request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/"+completedTodo._id).end (res) ->
|
||||
request.get(baseURL + "/user/tasks/"+completedTodo._id).end (err, res) ->
|
||||
completedTodo = res.body
|
||||
expect(completedTodo.completed).to.equal false
|
||||
done()
|
||||
|
|
@ -91,9 +91,9 @@ describe "Score", ->
|
|||
type: "habit"
|
||||
text: "testTitle"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/habitWithUp").end (res) ->
|
||||
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")
|
||||
|
|
@ -105,9 +105,9 @@ describe "Score", ->
|
|||
type: "habit"
|
||||
text: "testTitle"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/habitWithDown").end (res) ->
|
||||
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")
|
||||
|
|
@ -31,7 +31,7 @@ describe "Todos", ->
|
|||
body:
|
||||
type: "todo"
|
||||
}
|
||||
]).end (res) ->
|
||||
]).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
|
||||
|
|
@ -56,7 +56,7 @@ describe "Todos", ->
|
|||
direction: "up"
|
||||
id: res.body.todos[2].id
|
||||
}
|
||||
]).end (res) ->
|
||||
]).end (err, res) ->
|
||||
expectCode res, 200
|
||||
expect(_.size(res.body.todos)).to.equal numTasks
|
||||
request.post(baseURL + "/user/batch-update?_v=997").send([
|
||||
|
|
@ -76,7 +76,7 @@ describe "Todos", ->
|
|||
body:
|
||||
dateCompleted: moment().subtract(4, "days")
|
||||
}
|
||||
]).end (res) ->
|
||||
]).end (err, res) ->
|
||||
# Expect todos to be 2 less than the total count
|
||||
expect(_.size(res.body.todos)).to.equal numTasks - 2
|
||||
done()
|
||||
|
|
@ -89,7 +89,7 @@ describe "Todos", ->
|
|||
request.post(baseURL + "/user/tasks").send(
|
||||
type: "todo"
|
||||
text: "Sample Todo"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
todo = res.body
|
||||
expect(todo.text).to.equal "Sample Todo"
|
||||
|
|
@ -110,10 +110,10 @@ describe "Todos", ->
|
|||
}
|
||||
request.post(baseURL + "/user/tasks").send(
|
||||
original_todo
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
request.post(baseURL + "/user/tasks").send(
|
||||
duplicate_id_todo
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 409
|
||||
expect(res.body.err).to.eql('A task with that ID already exists.')
|
||||
done()
|
||||
|
|
@ -122,7 +122,7 @@ describe "Todos", ->
|
|||
it "Does not update id of todo", (done) ->
|
||||
request.put(baseURL + "/user/tasks/" + todo.id).send(
|
||||
id: "a-new-id"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
updateTodo = res.body
|
||||
expect(updateTodo.id).to.equal todo.id
|
||||
|
|
@ -131,7 +131,7 @@ describe "Todos", ->
|
|||
it "Does not update type of todo", (done) ->
|
||||
request.put(baseURL + "/user/tasks/" + todo.id).send(
|
||||
type: "habit"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
updateTodo = res.body
|
||||
expect(updateTodo.type).to.equal todo.type
|
||||
|
|
@ -144,7 +144,7 @@ describe "Todos", ->
|
|||
priority: 1.5
|
||||
value: 5
|
||||
notes: "Some notes"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
todo = res.body
|
||||
expect(todo.text).to.equal "Changed Title"
|
||||
|
|
@ -157,7 +157,7 @@ describe "Todos", ->
|
|||
describe "Deleting todos", ->
|
||||
it "Does delete todo", (done) ->
|
||||
request.del(baseURL + "/user/tasks/" + todo.id).send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 200
|
||||
body = res.body
|
||||
expect(body).to.be.empty
|
||||
|
|
@ -165,7 +165,7 @@ describe "Todos", ->
|
|||
|
||||
it "Does not delete already deleted todo", (done) ->
|
||||
request.del(baseURL + "/user/tasks/" + todo.id).send(
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 404
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Task not found."
|
||||
|
|
@ -178,7 +178,7 @@ describe "Todos", ->
|
|||
priority: 1
|
||||
value: 4
|
||||
notes: "Other notes"
|
||||
).end (res) ->
|
||||
).end (err, res) ->
|
||||
expectCode res, 404
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Task not found."
|
||||
|
|
@ -5,30 +5,6 @@ app = require("../../website/src/server")
|
|||
|
||||
describe "Users", ->
|
||||
|
||||
describe "GET /user without token or user id", ->
|
||||
|
||||
it "/api/v2/user", (done) ->
|
||||
request
|
||||
.get(baseURL + "/user")
|
||||
.set("Accept", "application/json")
|
||||
.set("X-API-User", '')
|
||||
.set("X-API-Key", '')
|
||||
.end (res) ->
|
||||
expect(res.statusCode).to.equal 401
|
||||
expect(res.body.err).to.equal "You must include a token and uid (user id) in your request"
|
||||
done()
|
||||
|
||||
describe "GET /user with token or user id", ->
|
||||
|
||||
before (done) ->
|
||||
registerNewUser(done, true)
|
||||
|
||||
it "/api/v2/user", (done) ->
|
||||
request.get(baseURL + "/user").set("Accept", "application/json").end (res) ->
|
||||
expect(res.statusCode).to.equal 200
|
||||
expect(res.body._id).to.equal user._id
|
||||
done()
|
||||
|
||||
describe "Deleting Users", ->
|
||||
|
||||
before (done) ->
|
||||
|
|
@ -46,10 +22,10 @@ describe "Users", ->
|
|||
request.del(baseURL + "/user")
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/" + userToDelete._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 404
|
||||
cb()
|
||||
|
||||
|
|
@ -80,7 +56,7 @@ describe "Users", ->
|
|||
)
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
guildToHaveNewLeader = res.body
|
||||
expect(guildToHaveNewLeader.leader).to.eql(userToDelete._id)
|
||||
|
|
@ -90,7 +66,7 @@ describe "Users", ->
|
|||
inviteURL = baseURL + "/groups/" + guildToHaveNewLeader._id + "/invite"
|
||||
request.post(inviteURL)
|
||||
.send( uuids: [userToBecomeLeader._id])
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -98,7 +74,7 @@ describe "Users", ->
|
|||
request.post(baseURL + "/groups/" + guildToHaveNewLeader._id + "/join")
|
||||
.set("X-API-User", userToBecomeLeader._id)
|
||||
.set("X-API-Key", userToBecomeLeader.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -106,7 +82,7 @@ describe "Users", ->
|
|||
request.del(baseURL + "/user")
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -114,7 +90,7 @@ describe "Users", ->
|
|||
request.get(baseURL + "/groups/" + guildToHaveNewLeader._id)
|
||||
.set("X-API-User", userToBecomeLeader._id)
|
||||
.set("X-API-Key", userToBecomeLeader.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
|
||||
|
|
@ -138,7 +114,7 @@ describe "Users", ->
|
|||
name: "TestPrivateGroup"
|
||||
type: "party"
|
||||
)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
party = res.body
|
||||
cb()
|
||||
|
|
@ -148,7 +124,7 @@ describe "Users", ->
|
|||
name: "TestPrivateGroup"
|
||||
type: "guild"
|
||||
)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
guild = res.body
|
||||
cb()
|
||||
|
|
@ -167,7 +143,7 @@ describe "Users", ->
|
|||
inviteURL = baseURL + "/groups/" + party._id + "/invite"
|
||||
request.post(inviteURL)
|
||||
.send( uuids: [userToDelete._id])
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -175,7 +151,7 @@ describe "Users", ->
|
|||
inviteURL = baseURL + "/groups/" + guild._id + "/invite"
|
||||
request.post(inviteURL)
|
||||
.send( uuids: [userToDelete._id])
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -183,7 +159,7 @@ describe "Users", ->
|
|||
request.post(baseURL + "/groups/" + party._id + "/join")
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -191,7 +167,7 @@ describe "Users", ->
|
|||
request.post(baseURL + "/groups/" + guild._id + "/join")
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -199,13 +175,13 @@ describe "Users", ->
|
|||
request.del(baseURL + "/user")
|
||||
.set("X-API-User", userToDelete._id)
|
||||
.set("X-API-Key", userToDelete.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + party._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
|
||||
|
|
@ -214,7 +190,7 @@ describe "Users", ->
|
|||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; );
|
||||
|
|
@ -235,7 +211,7 @@ describe "Users", ->
|
|||
inviteURL = baseURL + "/groups/" + party._id + "/invite"
|
||||
request.post(inviteURL)
|
||||
.send( uuids: [userToDeleteInvites._id])
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -243,7 +219,7 @@ describe "Users", ->
|
|||
inviteURL = baseURL + "/groups/" + guild._id + "/invite"
|
||||
request.post(inviteURL)
|
||||
.send( uuids: [userToDeleteInvites._id])
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
|
|
@ -251,13 +227,13 @@ describe "Users", ->
|
|||
request.del(baseURL + "/user")
|
||||
.set("X-API-User", userToDeleteInvites._id)
|
||||
.set("X-API-Key", userToDeleteInvites.apiToken)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + party._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
|
||||
|
|
@ -266,7 +242,7 @@ describe "Users", ->
|
|||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
|
||||
|
|
@ -1,32 +1,83 @@
|
|||
# API Tests
|
||||
# So you want to write API integration tests?
|
||||
|
||||
Our API tests are written in [coffeescript](http://coffeescript.org/) using the [Mocha testing framework](http://mochajs.org/).
|
||||
That's great! This README will serve as a quick primer for style conventions and practices for these tests.
|
||||
|
||||
There's a variety of ways to run the tests:
|
||||
## What is this?
|
||||
|
||||
These are integration tests for the Habitica API. They are performed by making REST requests to the API's endpoints and asserting on the data that is returned.
|
||||
|
||||
If the javascript looks weird to you, that's because it's written in [ES2015](http://www.ecma-international.org/ecma-262/6.0/) and transpiled by [Babel](https://babeljs.io/docs/learn-es2015/).
|
||||
|
||||
## How to run the tests
|
||||
|
||||
First, install gulp.
|
||||
|
||||
```bash
|
||||
# Individually
|
||||
mocha test/api/name_of_test.coffee
|
||||
# The entire collection of api tests
|
||||
mocha test/api
|
||||
# As part of the whole test suite
|
||||
npm test
|
||||
$ npm install -g gulp
|
||||
```
|
||||
|
||||
### Modules
|
||||
To run the api tests, make sure the mongo db is up and running and then type this on the command line:
|
||||
|
||||
Some modules are declared in the [api-helper.coffee](api-helper.coffee) file for use in any of the api tests:
|
||||
```bash
|
||||
$ gulp test:api
|
||||
```
|
||||
|
||||
* `moment` - time manipulation
|
||||
* `async` - run async processes, good for before blocks
|
||||
* `lodash (_)` - many utilities
|
||||
* `shared` - generate uuids
|
||||
* `expect` - making assertions
|
||||
* `User` - look up a User in the db
|
||||
It may take a little while to get going, since it requires the web server to start up before the tests can run.
|
||||
|
||||
### Helper Methods
|
||||
You can also run a watch command for the api tests. This will allow the tests to re-run automatically when you make changes in the `/test/api/` or `/website/src/` directories.
|
||||
|
||||
There are helper methods declared in the [api-helper.coffee](api-helper.coffee) file. Some useful methods contained there:
|
||||
```bash
|
||||
$ gulp test:api:watch
|
||||
```
|
||||
|
||||
* `registerNewUser(callback, main)` - Theres a global user variable that gets overwritten with the new user whenever you call `registerNewUser` unless you pass false in as the second argument.
|
||||
* `registerManyUsers(number, callback)` - Good for testing things that require many users. The callback function returns new users as and array in the second argument.
|
||||
One caveat. If you have a severe syntax error in your files the tests may fail to run, but they won't alert you that they are not running. If you ever find your test hanging for a while, run this to get the stackstrace. Once you've fixed the problem, you can resume running the watch comand.
|
||||
|
||||
```bash
|
||||
$ gulp test:api:safe
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
Each top level route has it's own directory. So, all the routes that begin with `/groups/` live in `/test/api/groups/`.
|
||||
|
||||
Each test should:
|
||||
|
||||
* encompase a single route
|
||||
* begin with the REST parameter for the route
|
||||
* display the full name of the route, swapping out `/` for `_`
|
||||
* end with test.js
|
||||
|
||||
So, for the `POST` route `/groups/:id/leave`, it would be
|
||||
|
||||
```bash
|
||||
POST-groups_id_leave.test.js
|
||||
```
|
||||
|
||||
## Promises
|
||||
|
||||
To mitigate [callback hell](http://callbackhell.com/) :imp:, we've written helper methods that [return promises](https://babeljs.io/docs/learn-es2015/#promises). This makes it very easy to chain together commands. All you need to do to make a subsequent request is return another promise and then call `.then((result) => {})` on the surrounding block, like so:
|
||||
|
||||
```js
|
||||
it('does something', (done) => { // Since it's an asynronous test, we need to pass the done callback
|
||||
let request;
|
||||
generateUser().then((user) => {
|
||||
request = requester(user);
|
||||
return request.post('/groups', {
|
||||
type: 'party',
|
||||
});
|
||||
}).then((party) => { // the result of the promise above is the argument of the function
|
||||
return request.put(`/groups/${party._id}`, {
|
||||
name: 'My party',
|
||||
});
|
||||
}).then((result) => {
|
||||
return request.get('/groups/party');
|
||||
}).then((party) => {
|
||||
expect(party.name).to.eql('My party');
|
||||
done(); // Call this function to end the test
|
||||
}).catch(done); // If there is an error, it'll call the function done with that error, which will fail the test
|
||||
});
|
||||
```
|
||||
|
||||
## Questions?
|
||||
|
||||
Ask in the [Aspiring Coder's Guild](https://habitica.com/#/options/groups/guilds/68d4a01e-db97-4786-8ee3-05d612c5af6f)!
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
##############################
|
||||
# Global modules
|
||||
##############################
|
||||
superagentDefaults = require("superagent-defaults")
|
||||
global.request = superagentDefaults()
|
||||
|
||||
global.mongoose = require("mongoose")
|
||||
global.moment = require("moment")
|
||||
global.async = require("async")
|
||||
global._ = require("lodash")
|
||||
global.shared = require("../../common")
|
||||
global.User = require("../../website/src/models/user").model
|
||||
|
||||
global.chai = require("chai")
|
||||
chai.use(require("sinon-chai"))
|
||||
global.expect = chai.expect
|
||||
|
||||
##############################
|
||||
# Nconf config
|
||||
##############################
|
||||
path = require("path")
|
||||
global.conf = require("nconf")
|
||||
conf.argv().env().file(file: path.join(__dirname, "../config.json")).defaults()
|
||||
conf.set "PORT", "1337"
|
||||
|
||||
##############################
|
||||
# Node ENV and global variables
|
||||
##############################
|
||||
process.env.NODE_DB_URI = "mongodb://localhost/habitrpg_test"
|
||||
global.baseURL = "http://localhost:" + conf.get("PORT") + "/api/v2"
|
||||
global.user = undefined
|
||||
|
||||
##############################
|
||||
# Helper Methods
|
||||
##############################
|
||||
global.expectCode = (res, code) ->
|
||||
expect(res.body.err).to.not.exist if code is 200
|
||||
expect(res.statusCode).to.equal code
|
||||
|
||||
global.registerNewUser = (cb, main) ->
|
||||
main = true unless main?
|
||||
randomID = shared.uuid()
|
||||
username = password = randomID if main
|
||||
request
|
||||
.post(baseURL + "/register")
|
||||
.set("Accept", "application/json")
|
||||
.set("X-API-User", null)
|
||||
.set("X-API-Key", null)
|
||||
.send
|
||||
username: randomID
|
||||
password: randomID
|
||||
confirmPassword: randomID
|
||||
email: randomID + "@gmail.com"
|
||||
.end (res) ->
|
||||
return cb(null, res.body) unless main
|
||||
_id = res.body._id
|
||||
apiToken = res.body.apiToken
|
||||
User.findOne
|
||||
_id: _id
|
||||
apiToken: apiToken
|
||||
, (err, _user) ->
|
||||
expect(err).to.not.be.ok
|
||||
global.user = _user
|
||||
request
|
||||
.set("Accept", "application/json")
|
||||
.set("X-API-User", _id)
|
||||
.set("X-API-Key", apiToken)
|
||||
cb null, res.body
|
||||
|
||||
global.registerManyUsers = (number, callback) ->
|
||||
async.times number, (n, next) ->
|
||||
registerNewUser (err, user) ->
|
||||
next(err, user)
|
||||
, false
|
||||
, (err, users) ->
|
||||
callback(err, users)
|
||||
|
|
@ -1,500 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
diff = require("deep-diff")
|
||||
|
||||
Group = require("../../website/src/models/group").model
|
||||
app = require("../../website/src/server")
|
||||
|
||||
describe "Guilds", ->
|
||||
context "creating groups", ->
|
||||
before (done) ->
|
||||
registerNewUser ->
|
||||
User.findByIdAndUpdate user._id,
|
||||
$set:
|
||||
"balance": 40
|
||||
, (err, _user) ->
|
||||
done()
|
||||
, true
|
||||
|
||||
it "can create a public guild", (done) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "guild",
|
||||
privacy: "public"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
guild = res.body
|
||||
expect(guild.members.length).to.equal 1
|
||||
expect(guild.leader).to.equal user._id
|
||||
done()
|
||||
|
||||
it "can create a private guild", (done) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "guild",
|
||||
privacy: "private"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
guild = res.body
|
||||
expect(guild.members.length).to.equal 1
|
||||
expect(guild.leader).to.equal user._id
|
||||
done()
|
||||
|
||||
it "prevents user from creating a guild when the user has 0 gems", (done) ->
|
||||
registerNewUser (err, user_with_0_gems) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "guild",
|
||||
)
|
||||
.set("X-API-User", user_with_0_gems._id)
|
||||
.set("X-API-Key", user_with_0_gems.apiToken)
|
||||
.end (res) ->
|
||||
expectCode res, 401
|
||||
done()
|
||||
, false
|
||||
|
||||
context "get guilds", ->
|
||||
guild = undefined
|
||||
|
||||
beforeEach (done)->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup2"
|
||||
type: "guild"
|
||||
).end (res) ->
|
||||
guild = res.body
|
||||
done()
|
||||
|
||||
it "can find a guild", (done) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
expect(res.body._id).to.equal res.body._id
|
||||
done()
|
||||
|
||||
it "transforms members array to an arrray of user objects", (done) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
members = res.body.members
|
||||
# @TODO: would be more instructive if it had more members in guild :(
|
||||
_(members).each (member) ->
|
||||
expect(member).to.be.an 'object'
|
||||
expect(member.profile.name).to.exist
|
||||
done()
|
||||
|
||||
it "transforms leader id to a user object", (done) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
leader = res.body.leader
|
||||
expect(leader).to.be.an 'object'
|
||||
expect(leader.profile.name).to.exist
|
||||
done()
|
||||
|
||||
it "can list guilds", (done) ->
|
||||
request.get(baseURL + "/groups").send()
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
guild = res.body[0]
|
||||
expect(guild).to.exist
|
||||
done()
|
||||
|
||||
context "updating groups", ->
|
||||
groupToUpdate = undefined
|
||||
before (done) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroup"
|
||||
type: "guild"
|
||||
description: "notUpdatedDesc"
|
||||
).end (res) ->
|
||||
groupToUpdate = res.body
|
||||
done()
|
||||
|
||||
it "prevents user from updating a party when they aren't the leader", (done) ->
|
||||
registerNewUser (err, tmpUser) ->
|
||||
request.post(baseURL + "/groups/" + groupToUpdate._id).send(
|
||||
name: "TestGroupName"
|
||||
description: "updatedDesc"
|
||||
)
|
||||
.set("X-API-User", tmpUser._id)
|
||||
.set("X-API-Key", tmpUser.apiToken)
|
||||
.end (res) ->
|
||||
expectCode res, 401
|
||||
expect(res.body.err).to.equal "Only the group leader can update the group!"
|
||||
done()
|
||||
, false
|
||||
|
||||
it "allows user to update a group", (done) ->
|
||||
request.post(baseURL + "/groups/" + groupToUpdate._id).send(
|
||||
description: "updatedDesc"
|
||||
)
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
request.get(baseURL + "/groups/" + groupToUpdate._id).send()
|
||||
.end (res) ->
|
||||
updatedGroup = res.body
|
||||
expect(updatedGroup.description).to.equal "updatedDesc"
|
||||
done()
|
||||
|
||||
context "leaving groups", ->
|
||||
it "can leave a guild", (done) ->
|
||||
guildToLeave = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroupToLeave"
|
||||
type: "guild"
|
||||
).end (res) ->
|
||||
guildToLeave = res.body
|
||||
request.post(baseURL + "/groups/" + guildToLeave._id + "/leave")
|
||||
.send()
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
done()
|
||||
|
||||
it "deletes a group when the last member leaves", (done) ->
|
||||
groupToDeleteAfterLeave = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroupToDeleteAfteLeave"
|
||||
type: "guild"
|
||||
privacy: "private"
|
||||
).end (res) ->
|
||||
groupToDeleteAfterLeave = res.body
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id + "/leave")
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id)
|
||||
.end (res) ->
|
||||
expectCode res, 404
|
||||
cb()
|
||||
], done
|
||||
|
||||
it "deletes all invites to a group (guild) when the last member leaves", (done) ->
|
||||
groupToDeleteAfterLeave = undefined
|
||||
userToRemoveInvite = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGroupToDeleteAfterLeave"
|
||||
type: "guild"
|
||||
privacy: "private"
|
||||
).end (res) ->
|
||||
groupToDeleteAfterLeave = res.body
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerManyUsers 1, cb
|
||||
|
||||
(_members, cb) ->
|
||||
userToRemoveInvite = _members[0]
|
||||
inviteURL = baseURL + "/groups/" + groupToDeleteAfterLeave._id + "/invite"
|
||||
request.post(inviteURL).send(
|
||||
uuids: [userToRemoveInvite._id]
|
||||
)
|
||||
.end ->
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id + "/leave")
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + '/user')
|
||||
.set("X-API-User", userToRemoveInvite._id)
|
||||
.set("X-API-Key", userToRemoveInvite.apiToken)
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
groupInvitation = _.find(res.body.invitations.guilds, {id: groupToDeleteAfterLeave._id})
|
||||
expect(groupInvitation).to.not.exist
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id)
|
||||
.end (res) ->
|
||||
expectCode res, 404
|
||||
cb()
|
||||
], done
|
||||
|
||||
it "deletes all invites to a group (party) when the last member leaves", (done) ->
|
||||
partyToDeleteAfterLeave = undefined
|
||||
userToRemovePartyInvite = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestPartyToDeleteAfterLeave"
|
||||
type: "party"
|
||||
).end (res) ->
|
||||
partyToDeleteAfterLeave = res.body
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerManyUsers 1, cb
|
||||
|
||||
(_members, cb) ->
|
||||
userToRemovePartyInvite = _members[0]
|
||||
inviteURL = baseURL + "/groups/" + partyToDeleteAfterLeave._id + "/invite"
|
||||
request.post(inviteURL).send(
|
||||
uuids: [userToRemovePartyInvite._id]
|
||||
)
|
||||
.end ->
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + partyToDeleteAfterLeave._id + "/leave")
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + '/user')
|
||||
.set("X-API-User", userToRemovePartyInvite._id)
|
||||
.set("X-API-Key", userToRemovePartyInvite.apiToken)
|
||||
.end (err, res) ->
|
||||
expectCode res, 200
|
||||
party = partyToDeleteAfterLeave
|
||||
partyInvitation = _.find(res.body.invitations.party, (invite) ->
|
||||
return invite == party._id
|
||||
)
|
||||
expect(partyInvitation).to.not.exist
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + partyToDeleteAfterLeave._id)
|
||||
.end (res) ->
|
||||
expectCode res, 404
|
||||
cb()
|
||||
], done
|
||||
|
||||
context "removing users groups", ->
|
||||
it "allows guild leaders to remove a member (but not themselves)", (done) ->
|
||||
guildToRemoveMember = undefined
|
||||
members = undefined
|
||||
userToRemove = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGuildToRemoveMember"
|
||||
type: "guild"
|
||||
).end (res) ->
|
||||
guildToRemoveMember = res.body
|
||||
#Add members to guild
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerManyUsers 1, cb
|
||||
|
||||
(_members, cb) ->
|
||||
userToRemove = _members[0]
|
||||
members = _members
|
||||
inviteURL = baseURL + "/groups/" + guildToRemoveMember._id + "/invite"
|
||||
request.post(inviteURL).send(
|
||||
uuids: [userToRemove._id]
|
||||
)
|
||||
.end ->
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + guildToRemoveMember._id + "/join")
|
||||
.set("X-API-User", userToRemove._id)
|
||||
.set("X-API-Key", userToRemove.apiToken)
|
||||
.end (res) ->
|
||||
cb()
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + guildToRemoveMember._id + "/removeMember?uuid=" + guildToRemoveMember.leader)
|
||||
.send().end (res) ->
|
||||
expectCode res, 401
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + guildToRemoveMember._id + "/removeMember?uuid=" + userToRemove._id)
|
||||
.send().end (res) ->
|
||||
expectCode res, 204
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + guildToRemoveMember._id)
|
||||
.send()
|
||||
.end (res) ->
|
||||
g = res.body
|
||||
userInGroup = _.find g.members, (member) -> return member._id == userToRemove._id
|
||||
expect(userInGroup).to.not.exist
|
||||
cb()
|
||||
|
||||
], done
|
||||
|
||||
describe "Private Guilds", ->
|
||||
guild = undefined
|
||||
before (done) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestPrivateGroup"
|
||||
type: "guild"
|
||||
privacy: "private"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
guild = res.body
|
||||
expect(guild.members.length).to.equal 1
|
||||
expect(guild.leader).to.equal user._id
|
||||
#Add members to guild
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerManyUsers 15, cb
|
||||
|
||||
(_members, cb) ->
|
||||
members = _members
|
||||
|
||||
joinGuild = (member, callback) ->
|
||||
request.post(baseURL + "/groups/" + guild._id + "/join")
|
||||
.set("X-API-User", member._id)
|
||||
.set("X-API-Key", member.apiToken)
|
||||
.end ->
|
||||
callback(null, null)
|
||||
|
||||
async.map members, joinGuild, (err, results) -> cb()
|
||||
|
||||
], done
|
||||
|
||||
it "includes user in private group member list when user is a member", (done) ->
|
||||
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
g = res.body
|
||||
userInGroup = _.find g.members, (member) -> return member._id == user._id
|
||||
expect(userInGroup).to.exist
|
||||
done()
|
||||
|
||||
it "excludes user from viewing private group member list when user is not a member", (done) ->
|
||||
|
||||
request.post(baseURL + "/groups/" + guild._id + "/leave")
|
||||
.end (res) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
expect res, 404
|
||||
done()
|
||||
|
||||
describe "Public Guilds", ->
|
||||
before (done) ->
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerNewUser ->
|
||||
User.findByIdAndUpdate user._id, {$set: { "balance": 10 } }, (err, _user) ->
|
||||
cb()
|
||||
, true
|
||||
], done
|
||||
|
||||
context "joining groups", ->
|
||||
it "makes user a group leader when group is empty", (done) ->
|
||||
guildToEmptyAndAssignLeader = undefined
|
||||
members = undefined
|
||||
userToBecomeLeader = undefined
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestGuildToEmptyAndAssignLeader"
|
||||
type: "guild",
|
||||
privacy: "public"
|
||||
).end (res) ->
|
||||
guildToEmptyAndAssignLeader = res.body
|
||||
#Add members to guild
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerManyUsers 1, cb
|
||||
|
||||
(_members, cb) ->
|
||||
userToBecomeLeader = _members[0]
|
||||
members = _members
|
||||
inviteURL = baseURL + "/groups/" + guildToEmptyAndAssignLeader._id + "/invite"
|
||||
request.post(inviteURL).send(
|
||||
uuids: [userToBecomeLeader._id]
|
||||
)
|
||||
.end ->
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + guildToEmptyAndAssignLeader._id + "/leave")
|
||||
.send()
|
||||
.end (res) ->
|
||||
expectCode res, 204
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups/" + guildToEmptyAndAssignLeader._id + "/join")
|
||||
.set("X-API-User", userToBecomeLeader._id)
|
||||
.set("X-API-Key", userToBecomeLeader.apiToken)
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
request.get(baseURL + "/groups/" + guildToEmptyAndAssignLeader._id)
|
||||
.set("X-API-User", userToBecomeLeader._id)
|
||||
.set("X-API-Key", userToBecomeLeader.apiToken)
|
||||
.send()
|
||||
.end (res) ->
|
||||
expectCode res, 200
|
||||
g = res.body
|
||||
expect(g.leader._id).to.equal(userToBecomeLeader._id)
|
||||
cb()
|
||||
|
||||
], done
|
||||
|
||||
context "viewing", ->
|
||||
guild = undefined
|
||||
before (done) ->
|
||||
async.waterfall [
|
||||
(cb) ->
|
||||
registerNewUser ->
|
||||
User.findByIdAndUpdate user._id, {$set: { "balance": 10 } }, (err, _user) ->
|
||||
cb()
|
||||
, true
|
||||
(cb) ->
|
||||
request.post(baseURL + "/groups").send(
|
||||
name: "TestPublicGroup"
|
||||
type: "guild"
|
||||
privacy: "public"
|
||||
).end (res) ->
|
||||
guild = res.body
|
||||
expect(guild.members.length).to.equal 1
|
||||
expect(guild.leader).to.equal user._id
|
||||
#Add members to guild
|
||||
cb()
|
||||
|
||||
(cb) ->
|
||||
registerManyUsers 15, cb
|
||||
|
||||
(_members, cb) ->
|
||||
members = _members
|
||||
|
||||
joinGuild = (member, callback) ->
|
||||
request.post(baseURL + "/groups/" + guild._id + "/join")
|
||||
.set("X-API-User", member._id)
|
||||
.set("X-API-Key", member.apiToken)
|
||||
.end ->
|
||||
callback(null, null)
|
||||
|
||||
async.map members, joinGuild, (err, results) -> cb()
|
||||
|
||||
], done
|
||||
|
||||
context "is a member", ->
|
||||
before (done) ->
|
||||
registerNewUser ->
|
||||
request.post(baseURL + "/groups/" + guild._id + "/join")
|
||||
.end (res)->
|
||||
done()
|
||||
, true
|
||||
|
||||
it "includes user in public group member list", (done) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
g = res.body
|
||||
expect(g.members.length).to.equal 15
|
||||
userInGroup = _.find g.members, (member) -> return member._id == user._id
|
||||
expect(userInGroup).to.exist
|
||||
done()
|
||||
|
||||
context "is not a member", ->
|
||||
before (done) ->
|
||||
registerNewUser done, true
|
||||
|
||||
it "excludes user in public group member list", (done) ->
|
||||
request.get(baseURL + "/groups/" + guild._id)
|
||||
.end (res) ->
|
||||
g = res.body
|
||||
expect(g.members.length).to.equal 15
|
||||
userInGroup = _.find g.members, (member) -> return member._id == user._id
|
||||
expect(userInGroup).to.not.exist
|
||||
done()
|
||||
143
test/api/groups/GET-groups.test.js
Normal file
143
test/api/groups/GET-groups.test.js
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import {
|
||||
generateGroup,
|
||||
generateUser,
|
||||
resetHabiticaDB,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('GET /groups', () => {
|
||||
let user, api;
|
||||
|
||||
before((done) => {
|
||||
let leader, createdGroup;
|
||||
|
||||
// Set up a world with a mixture of public and private guilds
|
||||
// Invite user to a few of them
|
||||
resetHabiticaDB().then(() => {
|
||||
return generateUser();
|
||||
}).then((_user) => {
|
||||
user = _user;
|
||||
|
||||
return generateUser({
|
||||
balance: 10,
|
||||
});
|
||||
}).then((_user) => {
|
||||
leader = _user;
|
||||
api = requester(leader);
|
||||
|
||||
let publicGuildWithUserAsMember = generateGroup(leader, {
|
||||
name: 'public guild - is member',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
members: [leader._id, user._id],
|
||||
});
|
||||
|
||||
let publicGuildWithoutUserAsMember = generateGroup(leader, {
|
||||
name: 'public guild - is not member',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
});
|
||||
|
||||
let privateGuildWithUserAsMember = generateGroup(leader, {
|
||||
name: 'private guild - is member',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
members: [leader._id, user._id],
|
||||
});
|
||||
|
||||
let privateGuildWithoutUserAsMember = generateGroup(leader, {
|
||||
name: 'private guild - is not member',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
});
|
||||
|
||||
let partyWithoutUserAsMember = generateGroup(leader, {
|
||||
name: 'party name',
|
||||
type: 'party',
|
||||
privacy: 'private',
|
||||
});
|
||||
|
||||
let promises = [
|
||||
publicGuildWithUserAsMember,
|
||||
publicGuildWithoutUserAsMember,
|
||||
privateGuildWithUserAsMember,
|
||||
privateGuildWithoutUserAsMember,
|
||||
partyWithoutUserAsMember,
|
||||
];
|
||||
|
||||
return Promise.all(promises);
|
||||
}).then((groups) => {
|
||||
api = requester(user);
|
||||
return api.post('/groups', {
|
||||
type: 'party',
|
||||
name: 'user\'s party',
|
||||
privacy: 'private',
|
||||
});
|
||||
})
|
||||
.then((party) => {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
context('no query passed in', () => {
|
||||
|
||||
xit('lists all public guilds, the tavern, user\'s party, and any private guilds that user is a part of - TODO query includes duplicates - IE, tavern is included as tavern and part of public guilds. Refactor so this is not the case', (done) => {
|
||||
api.get('/groups').then((groups) => {
|
||||
expect(groups.length).to.eql(4);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('tavern passed in as query', () => {
|
||||
|
||||
it('returns only the tavern', (done) => {
|
||||
api.get('/groups', null, {type: 'tavern'}).then((groups) => {
|
||||
expect(groups).to.have.a.lengthOf(1);
|
||||
|
||||
let tavern = groups[0];
|
||||
expect(tavern._id).to.eql('habitrpg');
|
||||
done();
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('party passed in as query', () => {
|
||||
|
||||
it('returns only the user\'s party', (done) => {
|
||||
api.get('/groups', null, {type: 'party'}).then((groups) => {
|
||||
expect(groups).to.have.a.lengthOf(1);
|
||||
|
||||
let party = groups[0];
|
||||
expect(party.leader).to.eql(user._id);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('public passed in as query', () => {
|
||||
|
||||
it('returns all public guilds', (done) => {
|
||||
api.get('/groups', null, {type: 'public'}).then((groups) => {
|
||||
expect(groups).to.have.a.lengthOf(3);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('guilds passed in as query', () => {
|
||||
|
||||
it('returns all guilds user is a part of ', (done) => {
|
||||
api.get('/groups', null, {type: 'guilds'}).then((groups) => {
|
||||
expect(groups).to.have.a.lengthOf(2);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
253
test/api/groups/GET-groups_id.test.js
Normal file
253
test/api/groups/GET-groups_id.test.js
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
import {
|
||||
createAndPopulateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
import {
|
||||
find,
|
||||
each
|
||||
} from 'lodash';
|
||||
|
||||
describe('GET /groups/:id', () => {
|
||||
|
||||
let typesOfGroups = {};
|
||||
typesOfGroups['public guild'] = { type: 'guild', privacy: 'public' };
|
||||
typesOfGroups['private guild'] = { type: 'guild', privacy: 'private' };
|
||||
typesOfGroups['party'] = { type: 'party', privacy: 'private' };
|
||||
|
||||
each(typesOfGroups, (groupData, groupType) => {
|
||||
context(`Member of a ${groupType}`, () => {
|
||||
let leader, member, createdGroup;
|
||||
|
||||
before((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 30,
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
member = res.members[0];
|
||||
createdGroup = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns the group object', (done) => {
|
||||
let api = requester(member);
|
||||
api.get(`/groups/${createdGroup._id}`)
|
||||
.then((group) => {
|
||||
expect(group._id).to.eql(createdGroup._id);
|
||||
expect(group.name).to.eql(createdGroup.name);
|
||||
expect(group.type).to.eql(createdGroup.type);
|
||||
expect(group.privacy).to.eql(createdGroup.privacy);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('transforms members array to an array of user objects', (done) => {
|
||||
let api = requester(member);
|
||||
api.get(`/groups/${createdGroup._id}`).then((group) => {
|
||||
let foundMember = group.members[0];
|
||||
expect(foundMember._id).to.exist;
|
||||
expect(foundMember.profile.name).to.exist;
|
||||
expect(foundMember.items).to.exist;
|
||||
expect(foundMember.stats).to.exist;
|
||||
expect(foundMember.achievements).to.exist;
|
||||
expect(foundMember.contributor).to.exist;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('transforms leader id to leader object', (done) => {
|
||||
let api = requester(member);
|
||||
api.get(`/groups/${createdGroup._id}`).then((group) => {
|
||||
expect(group.leader._id).to.eql(leader._id);
|
||||
expect(group.leader.profile.name).to.eql(leader.profile.name);
|
||||
expect(group.leader.items).to.exist;
|
||||
expect(group.leader.stats).to.exist;
|
||||
expect(group.leader.achievements).to.exist;
|
||||
expect(group.leader.contributor).to.exist;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('includes the user in the members list', (done) => {
|
||||
let api = requester(member);
|
||||
api.get(`/groups/${createdGroup._id}`).then((group) => {
|
||||
let members = group.members;
|
||||
let userInGroup = find(members, (user) => {
|
||||
return member._id === user._id;
|
||||
});
|
||||
expect(userInGroup).to.be.ok;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Non-member of a public guild', () => {
|
||||
let leader, nonMember, createdGroup;
|
||||
|
||||
before((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 1,
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
createdGroup = res.group;
|
||||
return generateUser();
|
||||
}).then((user) => {
|
||||
nonMember = user;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns the group object for a non-member', (done) => {
|
||||
let api = requester(nonMember);
|
||||
api.get(`/groups/${createdGroup._id}`)
|
||||
.then((group) => {
|
||||
expect(group._id).to.eql(createdGroup._id);
|
||||
expect(group.name).to.eql(createdGroup.name);
|
||||
expect(group.type).to.eql(createdGroup.type);
|
||||
expect(group.privacy).to.eql(createdGroup.privacy);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not include user in members list', (done) => {
|
||||
let api = requester(nonMember);
|
||||
api.get(`/groups/${createdGroup._id}`)
|
||||
.then((group) => {
|
||||
let userInGroup = find(group.members, (user) => {
|
||||
return nonMember._id === user._id;
|
||||
});
|
||||
expect(userInGroup).to.not.be.ok;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('Private Guilds', () => {
|
||||
let leader, nonMember, createdGroup;
|
||||
|
||||
before((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 1,
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
createdGroup = res.group;
|
||||
return generateUser();
|
||||
}).then((user) => {
|
||||
nonMember = user;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not return the group object for a non-member', (done) => {
|
||||
let api = requester(nonMember);
|
||||
api.get(`/groups/${createdGroup._id}`)
|
||||
.then((done)).catch((err) => {
|
||||
expect(err.code).to.eql(404);
|
||||
expect(err.text).to.eql('Group not found or you don\'t have access.');
|
||||
done()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Non-member of a party', () => {
|
||||
let leader, nonMember, createdGroup;
|
||||
|
||||
before((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 1,
|
||||
groupDetails: {
|
||||
name: 'test party',
|
||||
type: 'party',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
createdGroup = res.group;
|
||||
return generateUser();
|
||||
}).then((user) => {
|
||||
nonMember = user;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not return the group object for a non-member', (done) => {
|
||||
let api = requester(nonMember);
|
||||
api.get(`/groups/${createdGroup._id}`)
|
||||
.then((done)).catch((err) => {
|
||||
expect(err.code).to.eql(404);
|
||||
expect(err.text).to.eql('Group not found or you don\'t have access.');
|
||||
done()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Member of a party', () => {
|
||||
let leader, member, createdGroup;
|
||||
|
||||
before((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 1,
|
||||
groupDetails: {
|
||||
name: 'test party',
|
||||
type: 'party',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
createdGroup = res.group;
|
||||
member = res.members[0];
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns the user\'s party if an id of "party" is passed in', (done) => {
|
||||
let api = requester(member);
|
||||
api.get('/groups/party')
|
||||
.then((group) => {
|
||||
expect(group._id).to.eql(createdGroup._id);
|
||||
expect(group.name).to.eql(createdGroup.name);
|
||||
expect(group.type).to.eql(createdGroup.type);
|
||||
expect(group.privacy).to.eql(createdGroup.privacy);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('Non-existent group', () => {
|
||||
let user;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser().then((_user) => {
|
||||
user = _user;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns error if group does not exist', (done) => {
|
||||
let api = requester(user);
|
||||
api.get('/groups/group-that-does-not-exist')
|
||||
.then((done)).catch((err) => {
|
||||
expect(err.code).to.eql(404);
|
||||
expect(err.text).to.eql('Group not found or you don\'t have access.');
|
||||
done()
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
209
test/api/groups/POST-groups.test.js
Normal file
209
test/api/groups/POST-groups.test.js
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
import {
|
||||
generateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('POST /groups', () => {
|
||||
|
||||
context('All groups', () => {
|
||||
let api, leader;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser().then((user) => {
|
||||
leader = user;
|
||||
api = requester(user);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
xit('returns defaults? (TODO: it\'s possible to create a group without a type. Should the group default to party? Should we require type to be set?', (done) => {
|
||||
api.post('/groups').then((group) => {
|
||||
expect(group._id).to.exist;
|
||||
expect(group.name).to.eql(`${leader.profile.name}'s group`);
|
||||
expect(group.type).to.eql('party');
|
||||
expect(group.privacy).to.eql('private');
|
||||
done();
|
||||
}).catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a group object', (done) => {
|
||||
let group = {
|
||||
name: 'Test Group',
|
||||
type: 'party',
|
||||
leaderOnly: { challenges: true },
|
||||
description: 'Test Group Description',
|
||||
leaderMessage: 'Test Group Message',
|
||||
};
|
||||
|
||||
api.post('/groups',
|
||||
group
|
||||
).then((createdGroup) => {
|
||||
expect(createdGroup._id).to.exist;
|
||||
expect(createdGroup.leader).to.eql(leader._id);
|
||||
expect(createdGroup.name).to.eql(group.name);
|
||||
expect(createdGroup.description).to.eql(group.description);
|
||||
expect(createdGroup.leaderMessage).to.eql(group.leaderMessage);
|
||||
expect(createdGroup.leaderOnly.challenges).to.eql(group.leaderOnly.challenges);
|
||||
expect(createdGroup.memberCount).to.eql(1);
|
||||
expect(createdGroup.members).to.have.a.lengthOf(1);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a populated members array', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'party',
|
||||
}).then((createdGroup) => {
|
||||
let member = createdGroup.members[0];
|
||||
|
||||
expect(member._id).to.eql(leader._id);
|
||||
expect(member.profile.name).to.eql(leader.profile.name);
|
||||
expect(member.items).to.exist;
|
||||
expect(member.stats).to.exist;
|
||||
expect(member.achievements).to.exist;
|
||||
expect(member.contributor).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Parties', () => {
|
||||
let api, leader;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser().then((user) => {
|
||||
leader = user;
|
||||
api = requester(user);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('allows party creation without gems', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'party',
|
||||
})
|
||||
.then((group) => {
|
||||
expect(group._id).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('prevents party creation if user is already in party', (done) => {
|
||||
generateGroup(leader, {
|
||||
type: 'party',
|
||||
}).then((group) => {
|
||||
return api.post('/groups', {
|
||||
type: 'party',
|
||||
});
|
||||
}).then((group) => {
|
||||
done('Unexpected success');
|
||||
})
|
||||
.catch((err) => {
|
||||
expect(err.code).to.eql(400);
|
||||
expect(err.text).to.eql('Already in a party, try refreshing.');
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
xit('prevents creating a public party. TODO: it is possible to create a public party. Should we send back an error? Automatically switch the privacy to private?', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'party',
|
||||
privacy: 'public',
|
||||
})
|
||||
.then((group) => {
|
||||
done('Unexpected success');
|
||||
})
|
||||
.catch((err) => {
|
||||
expect(err.code).to.eql(400);
|
||||
expect(err.text).to.eql('Parties must be private');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Guilds', () => {
|
||||
let api, leader;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser({
|
||||
balance: 2,
|
||||
}).then((user) => {
|
||||
leader = user;
|
||||
api = requester(user);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('prevents guild creation when user does not have enough gems', (done) => {
|
||||
generateUser({
|
||||
balance: 0.75,
|
||||
}).then((user) => {
|
||||
api = requester(user);
|
||||
return api.post('/groups', {
|
||||
type: 'guild',
|
||||
});
|
||||
}).then((group) => {
|
||||
done('Unexpected success');
|
||||
}).catch((err) => {
|
||||
expect(err.code).to.eql(401);
|
||||
expect(err.text).to.eql('Not enough gems!');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('can create a public guild', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
}).then((group) => {
|
||||
expect(group.leader).to.eql(leader._id);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('can create a private guild', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
}).then((group) => {
|
||||
expect(group.leader).to.eql(leader._id);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('deducts gems from user and adds them to guild bank', (done) => {
|
||||
api.post('/groups', {
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
}).then((group) => {
|
||||
expect(group.balance).to.eql(1);
|
||||
return api.get('/user');
|
||||
}).then((user) => {
|
||||
expect(user.balance).to.eql(1);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
78
test/api/groups/POST-groups_id.test.js
Normal file
78
test/api/groups/POST-groups_id.test.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import {
|
||||
generateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('POST /groups/:id', () => {
|
||||
|
||||
context('user is not the leader of the group', () => {
|
||||
let api, user, otherUser, groupUserDoesNotOwn;
|
||||
|
||||
beforeEach((done) => {
|
||||
Promise.all([
|
||||
generateUser({ balance: 10 }),
|
||||
generateUser({ balance: 10 }),
|
||||
]).then((users) => {
|
||||
user = users[0];
|
||||
otherUser = users[1];
|
||||
api = requester(user);
|
||||
|
||||
return generateGroup(otherUser, {
|
||||
name: 'Group not Owned By User',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
members: [user, otherUser],
|
||||
});
|
||||
}).then((group) => {
|
||||
groupUserDoesNotOwn = group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not allow user to update group', (done) => {
|
||||
api.post(`/groups/${groupUserDoesNotOwn._id}`, {
|
||||
name: 'Change'
|
||||
}).then(done).catch((err) => {
|
||||
expect(err.code).to.eql(401);
|
||||
expect(err.text).to.eql('Only the group leader can update the group!');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('user is the leader of the group', () => {
|
||||
let api, user, usersGroup;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser({
|
||||
balance: 10,
|
||||
}).then((_user) => {
|
||||
user = _user;
|
||||
api = requester(user);
|
||||
|
||||
return generateGroup(user, {
|
||||
name: 'Original Group Title',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
});
|
||||
}).then((group) => {
|
||||
usersGroup = group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('allows user to update group', (done) => {
|
||||
api.post(`/groups/${usersGroup._id}`, {
|
||||
name: 'New Group Title',
|
||||
description: 'New group description',
|
||||
}).then((group) => {
|
||||
return api.get(`/groups/${usersGroup._id}`);
|
||||
}).then((group) => {
|
||||
expect(group.name).to.eql('New Group Title');
|
||||
expect(group.description).to.eql('New group description');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
44
test/api/groups/POST-groups_id_join.test.js
Normal file
44
test/api/groups/POST-groups_id_join.test.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import {
|
||||
createAndPopulateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('POST /groups/:id/join', () => {
|
||||
|
||||
context('user is already a member of the group', () => {
|
||||
it('returns an error');
|
||||
});
|
||||
|
||||
context('public guild has no leader', () => {
|
||||
let user, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
group = res.group;
|
||||
return requester(res.leader).post(`/groups/${group._id}/leave`);
|
||||
}).then((res) => {
|
||||
return generateUser();
|
||||
}).then((generatedUser) => {
|
||||
user = generatedUser;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('makes the joining user the leader', (done) => {
|
||||
let api = requester(user);
|
||||
api.post(`/groups/${group._id}/join`).then((result) => {
|
||||
return api.get(`/groups/${group._id}`);
|
||||
}).then((group) => {
|
||||
expect(group.leader._id).to.eql(user._id);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
169
test/api/groups/POST-groups_id_leave.test.js
Normal file
169
test/api/groups/POST-groups_id_leave.test.js
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
import {
|
||||
createAndPopulateGroup,
|
||||
generateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('POST /groups/:id/leave', () => {
|
||||
|
||||
context('user is not member of the group', () => {
|
||||
it('returns an error');
|
||||
});
|
||||
|
||||
context('user is a non-leader member of a guild', () => {
|
||||
let api, user, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 3,
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
user = res.members[0];
|
||||
api = requester(user);
|
||||
group = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('leaves the group', (done) => {
|
||||
api.post(`/groups/${group._id}/leave`).then((result) => {
|
||||
return api.get(`/groups/${group._id}`);
|
||||
}).then((group) => {
|
||||
expect(group.members).to.not.include(user._id);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('user is the last member of a public guild', () => {
|
||||
let api, user, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
user = res.leader;
|
||||
api = requester(user);
|
||||
group = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('leaves the group accessible', (done) => {
|
||||
api.post(`/groups/${group._id}/leave`).then((result) => {
|
||||
return api.get(`/groups/${group._id}`);
|
||||
}).then((group) => {
|
||||
expect(group._id).to.eql(group._id);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('user is the last member of a private group', () => {
|
||||
let api, user, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
user = res.leader;
|
||||
api = requester(user);
|
||||
group = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('group is not accessible after leaving', (done) => {
|
||||
api.post(`/groups/${group._id}/leave`).then((result) => {
|
||||
return api.get(`/groups/${group._id}`);
|
||||
}).then(done).catch((err) => {
|
||||
expect(err.code).to.eql(404);
|
||||
expect(err.text).to.eql('Group not found or you don\'t have access.');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('user is the last member of a private group with pending invites', () => {
|
||||
let api, user, inviteeRequest1, inviteeRequest2, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
invites: 2,
|
||||
groupDetails: {
|
||||
name: 'test guild',
|
||||
type: 'guild',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
user = res.leader;
|
||||
inviteeRequest1 = requester(res.invitees[0]);
|
||||
inviteeRequest2 = requester(res.invitees[1]);
|
||||
api = requester(user);
|
||||
group = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('deletes the group invitations from users', (done) => {
|
||||
api.post(`/groups/${group._id}/leave`).then((result) => {
|
||||
return Promise.all([
|
||||
inviteeRequest1.get(`/user`),
|
||||
inviteeRequest2.get(`/user`),
|
||||
]);
|
||||
}).then((users) => {
|
||||
expect(users[0].invitations.guilds[0]).to.not.exist;
|
||||
expect(users[1].invitations.guilds[0]).to.not.exist;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
context('user is the last member of a party with pending invites', () => {
|
||||
let api, user, inviteeRequest1, inviteeRequest2, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
invites: 2,
|
||||
groupDetails: {
|
||||
name: 'test party',
|
||||
type: 'party',
|
||||
privacy: 'private',
|
||||
},
|
||||
}).then((res) => {
|
||||
user = res.leader;
|
||||
inviteeRequest1 = requester(res.invitees[0]);
|
||||
inviteeRequest2 = requester(res.invitees[1]);
|
||||
api = requester(user);
|
||||
group = res.group;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('deletes the group invitations from users', (done) => {
|
||||
api.post(`/groups/${group._id}/leave`).then((result) => {
|
||||
return Promise.all([
|
||||
inviteeRequest1.get(`/user`),
|
||||
inviteeRequest2.get(`/user`),
|
||||
]);
|
||||
}).then((users) => {
|
||||
expect(users[0].invitations.party).to.be.empty;
|
||||
expect(users[1].invitations.party).to.be.empty;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
61
test/api/groups/POST-groups_id_removeMember.test.js
Normal file
61
test/api/groups/POST-groups_id_removeMember.test.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import {
|
||||
createAndPopulateGroup,
|
||||
generateGroup,
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('POST /groups/:id/removeMember', () => {
|
||||
|
||||
context('user is not member of the group', () => {
|
||||
it('returns an error');
|
||||
});
|
||||
|
||||
context('user is a non-leader member of a guild', () => {
|
||||
it('returns an error');
|
||||
});
|
||||
|
||||
context('user is the leader of a guild', () => {
|
||||
let api, leader, member, group;
|
||||
|
||||
beforeEach((done) => {
|
||||
createAndPopulateGroup({
|
||||
members: 1,
|
||||
groupDetails: {
|
||||
name: 'test group',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
}).then((res) => {
|
||||
leader = res.leader;
|
||||
member = res.members[0];
|
||||
group = res.group;
|
||||
|
||||
api = requester(leader);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not allow leader to remove themselves', (done) => {
|
||||
api.post(`/groups/${group._id}/removeMember`, null, {
|
||||
uuid: leader._id,
|
||||
}).then(done).catch((err) => {
|
||||
expect(err.code).to.eql(401);
|
||||
expect(err.text).to.eql('You cannot remove yourself!');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can remove other members of guild', (done) => {
|
||||
api.post(`/groups/${group._id}/removeMember`, null, {
|
||||
uuid: member._id,
|
||||
}).then((res) => {
|
||||
return api.get(`/groups/${group._id}`);
|
||||
}).then((guild) => {
|
||||
expect(guild.members).to.have.a.lengthOf(1);
|
||||
expect(guild.members[0]._id).to.not.eql(member._id);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
31
test/api/register/POST-register.test.js
Normal file
31
test/api/register/POST-register.test.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import {requester} from '../../helpers/api.helper';
|
||||
import {v4 as generateRandomUserName} from 'uuid';
|
||||
|
||||
describe('POST /register', () => {
|
||||
let api;
|
||||
|
||||
beforeEach(() => {
|
||||
api = requester();
|
||||
});
|
||||
|
||||
it('registers a new user', (done) => {
|
||||
let username = generateRandomUserName();
|
||||
let email = `${username}@example.com`;
|
||||
let password = 'password';
|
||||
|
||||
api.post('/register', {
|
||||
username: username,
|
||||
email: email,
|
||||
password: password,
|
||||
confirmPassword: password,
|
||||
}).then((user) => {
|
||||
expect(user._id).to.exist;
|
||||
expect(user.auth.local.username).to.eql(username);
|
||||
expect(user.auth.local.email).to.eql(`${username}@example.com`);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
app = require("../../website/src/server")
|
||||
|
||||
describe "Site Status", ->
|
||||
|
||||
describe "GET /status", ->
|
||||
|
||||
it "/api/v2/status", (done) ->
|
||||
request.get(baseURL + "/status").set("Accept", "application/json").end (res) ->
|
||||
expect(res.statusCode).to.equal 200
|
||||
expect(res.body.status).to.equal "up"
|
||||
done()
|
||||
20
test/api/status/GET-status.test.js
Normal file
20
test/api/status/GET-status.test.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import {requester} from '../../helpers/api.helper';
|
||||
|
||||
describe('Status', () => {
|
||||
let api;
|
||||
|
||||
beforeEach(() => {
|
||||
api = requester();
|
||||
});
|
||||
|
||||
it('returns a status of up when server is up', (done) => {
|
||||
api.get('/status')
|
||||
.then((res) => {
|
||||
expect(res.status).to.eql('up');
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
45
test/api/user/DELETE-user.test.js
Normal file
45
test/api/user/DELETE-user.test.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import {
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('DELETE /user', () => {
|
||||
let api;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser().then((usr) => {
|
||||
api = requester(usr);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('deletes the user', (done) => {
|
||||
api.del('/user')
|
||||
.then((fetchedUser) => {
|
||||
return api.get('/user')
|
||||
})
|
||||
.then((deletedUser) => {
|
||||
done('Unexpected user');
|
||||
})
|
||||
.catch((err) => {
|
||||
expect(err.code).to.eql(401);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
context('user in solo group', () => {
|
||||
|
||||
it('deletes party when user is the only member');
|
||||
|
||||
it('deletes private guild when user is the only member');
|
||||
});
|
||||
|
||||
context('user in group with members', () => {
|
||||
|
||||
it('removes user from all groups user was a part of');
|
||||
|
||||
it('chooses new group leader for any group user was the leader of');
|
||||
|
||||
it('removes invitations from groups');
|
||||
});
|
||||
});
|
||||
28
test/api/user/GET-user.test.js
Normal file
28
test/api/user/GET-user.test.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import {
|
||||
generateUser,
|
||||
requester,
|
||||
} from '../../helpers/api.helper';
|
||||
|
||||
describe('GET /user', () => {
|
||||
let api, user;
|
||||
|
||||
beforeEach((done) => {
|
||||
generateUser().then((usr) => {
|
||||
user = usr;
|
||||
api = requester(usr);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('gets the user object', (done) => {
|
||||
api.get('/user')
|
||||
.then((fetchedUser) => {
|
||||
expect(fetchedUser._id).to.eql(user._id);
|
||||
expect(fetchedUser.todos).to.eql(user.todos);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
--colors
|
||||
--reporter spec
|
||||
--timeout 8000
|
||||
--check-leaks
|
||||
--growl
|
||||
--compilers js:babel/register
|
||||
--require ./test/helpers/content.helper.js
|
||||
217
test/helpers/api.helper.js
Normal file
217
test/helpers/api.helper.js
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
import {
|
||||
assign,
|
||||
each,
|
||||
isEmpty,
|
||||
times,
|
||||
} from 'lodash';
|
||||
import {MongoClient as mongo} from 'mongodb';
|
||||
import {v4 as generateUUID} from 'uuid';
|
||||
import superagent from 'superagent';
|
||||
|
||||
const API_TEST_SERVER_PORT = 3003;
|
||||
|
||||
// Sets up an abject that can make all REST requests
|
||||
// If a user is passed in, the uuid and api token of
|
||||
// the user are used to make the requests
|
||||
export function requester(user={}) {
|
||||
return {
|
||||
get: _requestMaker(user, 'get'),
|
||||
post: _requestMaker(user, 'post'),
|
||||
put: _requestMaker(user, 'put'),
|
||||
del: _requestMaker(user, 'del'),
|
||||
}
|
||||
};
|
||||
|
||||
// Creates a new user and returns it
|
||||
// If you need the user to have specific requirements,
|
||||
// such as a balance > 0, just pass in the adjustment
|
||||
// to the update object. If you want to adjust a nested
|
||||
// paramter, such as the number of wolf eggs the user has,
|
||||
// , you can do so by passing in the full path as a string:
|
||||
// { 'items.eggs.Wolf': 10 }
|
||||
export function generateUser(update={}) {
|
||||
let username = generateUUID();
|
||||
let password = 'password'
|
||||
let email = username + '@example.com';
|
||||
|
||||
let request = _requestMaker({}, 'post');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request('/register', {
|
||||
username: username,
|
||||
email: email,
|
||||
password: password,
|
||||
confirmPassword: password,
|
||||
}).then((user) => {
|
||||
_updateDocument('users', user, update, () => {
|
||||
resolve(user);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Generates a new group. Requires a user object, which
|
||||
// will will become the groups leader. Takes an update
|
||||
// argument which will update group
|
||||
export function generateGroup(leader, update={}) {
|
||||
let request = _requestMaker(leader, 'post');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request('/groups').then((group) => {
|
||||
_updateDocument('groups', group, update, () => {
|
||||
resolve(group);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// This is generate group + the ability to create
|
||||
// real users to populate it. The settings object
|
||||
// takes in:
|
||||
// members: Number - the number of group members to create. Defaults to 0.
|
||||
// inivtes: Number - the number of users to create and invite to the group. Defaults to 0.
|
||||
// groupDetails: Object - how to initialize the group
|
||||
// leaderDetails: Object - defaults for the leader, defaults with a gem balance so the user
|
||||
// can create the group
|
||||
//
|
||||
// Returns an object with
|
||||
// members: an array of user objects that correspond to the members of the group
|
||||
// invitees: an array of user objects that correspond to the invitees of the group
|
||||
// leader: the leader user object
|
||||
// group: the group object
|
||||
export function createAndPopulateGroup(settings={}) {
|
||||
let request, leader, members, invitees, group;
|
||||
|
||||
let numberOfMembers = settings.members || 0;
|
||||
let numberOfInvites = settings.invites || 0;
|
||||
let groupDetails = settings.groupDetails;
|
||||
let leaderDetails = settings.leaderDetails || { balance: 10 };
|
||||
|
||||
let leaderPromise = generateUser(leaderDetails);
|
||||
|
||||
let memberPromises = Promise.all(
|
||||
times(numberOfMembers, () => {
|
||||
return generateUser();
|
||||
})
|
||||
);
|
||||
|
||||
let invitePromises = Promise.all(
|
||||
times(numberOfInvites, () => {
|
||||
return generateUser();
|
||||
})
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return leaderPromise.then((user) => {
|
||||
leader = user;
|
||||
request = _requestMaker(leader, 'post');
|
||||
return memberPromises;
|
||||
}).then((users) => {
|
||||
members = users;
|
||||
groupDetails.members = groupDetails.members || [leader._id];
|
||||
|
||||
each(members, (member) => {
|
||||
groupDetails.members.push(member._id);
|
||||
});
|
||||
|
||||
return generateGroup(leader, groupDetails);
|
||||
}).then((createdGroup) => {
|
||||
group = createdGroup;
|
||||
return invitePromises;
|
||||
}).then((users) => {
|
||||
invitees = users;
|
||||
|
||||
let invitePromises = [];
|
||||
|
||||
each(invitees, (invitee) => {
|
||||
let invitePromise = request(`/groups/${group._id}/invite`, {
|
||||
uuids: [invitee._id]
|
||||
});
|
||||
invitePromises.push(invitePromise);
|
||||
});
|
||||
|
||||
return Promise.all(invitePromises);
|
||||
}).then((inviteResults) => {
|
||||
resolve({
|
||||
leader: leader,
|
||||
group: group,
|
||||
members: members,
|
||||
invitees: invitees,
|
||||
});
|
||||
}).catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
// Specifically helpful for the GET /groups tests,
|
||||
// resets the db to an empty state and creates a tavern document
|
||||
export function resetHabiticaDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
mongo.connect('mongodb://localhost/habitrpg_test', (err, db) => {
|
||||
if (err) return reject(err);
|
||||
|
||||
db.dropDatabase((err) => {
|
||||
if (err) return reject(err);
|
||||
let groups = db.collection('groups');
|
||||
groups.insertOne({
|
||||
_id: 'habitrpg',
|
||||
chat: [],
|
||||
leader: '9',
|
||||
name: 'HabitRPG',
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
members: [],
|
||||
}, (err) => {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _requestMaker(user, method) {
|
||||
return (route, send, query) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let request = superagent[method](`http://localhost:${API_TEST_SERVER_PORT}/api/v2${route}`)
|
||||
.accept('application/json');
|
||||
|
||||
if (user._id && user.apiToken) {
|
||||
request
|
||||
.set('x-api-user', user._id)
|
||||
.set('x-api-key', user.apiToken);
|
||||
}
|
||||
|
||||
request
|
||||
.query(query)
|
||||
.send(send)
|
||||
.end((err, response) => {
|
||||
if (err) {
|
||||
if (!err.response) return reject(err);
|
||||
let errorString = JSON.parse(err.response.text).err;
|
||||
return reject({
|
||||
code: err.response.statusCode,
|
||||
text: errorString,
|
||||
});
|
||||
}
|
||||
|
||||
resolve(response.body);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _updateDocument(collectionName, doc, update, cb) {
|
||||
if (isEmpty(update)) { return cb(); }
|
||||
|
||||
mongo.connect('mongodb://localhost/habitrpg_test', (err, db) => {
|
||||
if (err) throw `Error connecting to database when updating ${collectionName} collection: ${err}`;
|
||||
|
||||
let collection = db.collection(collectionName);
|
||||
|
||||
collection.update({ _id: doc._id }, { $set: update }, (err, result) => {
|
||||
if (err) throw `Error updating ${collectionName}: ${err}`;
|
||||
assign(doc, update);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -6,4 +6,5 @@
|
|||
--debug
|
||||
--compilers coffee:coffee-script
|
||||
--globals io
|
||||
--require test/api/api-helper
|
||||
--require test/api-legacy/api-helper
|
||||
--require ./test/helpers/globals.helper
|
||||
|
|
|
|||
Loading…
Reference in a new issue