Merge branch 'develop' into sabrecat/more-modals

Conflicts:
	common/dist/sprites/spritesmith-largeSprites-0.png
	common/locales/en/front.json
This commit is contained in:
Sabe Jones
2015-11-09 16:24:17 -05:00
182 changed files with 1709 additions and 818 deletions
-235
View File
@@ -1,235 +0,0 @@
'use strict'
User = require("../../website/src/models/user").model
app = require("../../website/src/server")
describe "Users", ->
describe "Deleting Users", ->
before (done) ->
registerNewUser ->
done()
, true
context "handle group changes when user cancels", ->
it "Should choose a new group leader when deleting a user", (done) ->
userToDelete = undefined
userToBecomeLeader = undefined
guildToHaveNewLeader = undefined
async.waterfall [
(cb) ->
registerManyUsers 2, cb
(_users, cb) ->
userToDelete = _users[0]
userToBecomeLeader = _users[1]
User.findByIdAndUpdate userToDelete._id,
$set:
"balance": 4
, {new: true}
, (err, _user) ->
cb()
(cb) ->
request.post(baseURL + "/groups").send(
name: "GuildToGainNewLeader"
type: "guild"
)
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (err, res) ->
expectCode res, 200
guildToHaveNewLeader = res.body
expect(guildToHaveNewLeader.leader).to.eql(userToDelete._id)
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guildToHaveNewLeader._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToBecomeLeader._id])
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.post(baseURL + "/groups/" + guildToHaveNewLeader._id + "/join")
.set("X-API-User", userToBecomeLeader._id)
.set("X-API-Key", userToBecomeLeader.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.get(baseURL + "/groups/" + guildToHaveNewLeader._id)
.set("X-API-User", userToBecomeLeader._id)
.set("X-API-Key", userToBecomeLeader.apiToken)
.end (err, res) ->
expectCode res, 200
g = res.body
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
expect(userInGroup).to.equal(undefined)
expect(g.leader._id).to.equal(userToBecomeLeader._id)
cb()
], done
context "handle group and invite removals", ->
guild = undefined
party = undefined
before (done) ->
User.findByIdAndUpdate user._id,
$set:
"balance": 4
, {new: true}
, (err, _user) ->
async.waterfall [
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "party"
)
.end (err, res) ->
expectCode res, 200
party = res.body
cb()
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "guild"
)
.end (err, res) ->
expectCode res, 200
guild = res.body
cb()
], done
it 'Should remove a user from a group when deleting a user', (done) ->
userToDelete = undefined
async.waterfall [
(cb) ->
registerManyUsers 1, cb
# Send them invitations
(_users, cb) ->
userToDelete = _users[0]
inviteURL = baseURL + "/groups/" + party._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDelete._id])
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guild._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDelete._id])
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.post(baseURL + "/groups/" + party._id + "/join")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.post(baseURL + "/groups/" + guild._id + "/join")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.get(baseURL + "/groups/" + party._id)
.end (err, res) ->
expectCode res, 200
g = res.body
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
expect(userInGroup).to.equal(undefined)
cb()
(cb) ->
request.get(baseURL + "/groups/" + guild._id)
.end (err, res) ->
expectCode res, 200
g = res.body
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; );
expect(userInGroup).to.equal(undefined)
cb()
], done
it 'Should remove invitations when deleting a user', (done) ->
userToDeleteInvites = undefined
async.waterfall [
(cb) ->
registerManyUsers 1, cb
# Send them invitations
(_users, cb) ->
userToDeleteInvites = _users[0]
inviteURL = baseURL + "/groups/" + party._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDeleteInvites._id])
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guild._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDeleteInvites._id])
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDeleteInvites._id)
.set("X-API-Key", userToDeleteInvites.apiToken)
.end (err, res) ->
expectCode res, 200
cb()
(cb) ->
request.get(baseURL + "/groups/" + party._id)
.end (err, res) ->
expectCode res, 200
g = res.body
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
expect(userInviteForGroup).to.equal(undefined)
cb()
(cb) ->
request.get(baseURL + "/groups/" + guild._id)
.end (err, res) ->
expectCode res, 200
g = res.body
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
expect(userInviteForGroup).to.equal(undefined)
cb()
], done
+126
View File
@@ -82,6 +82,132 @@ describe('GET /groups/:id', () => {
});
});
context('flagged messages', () => {
let group;
let chat1 = {
id: 'chat1',
text: 'chat 1',
flags: {},
};
let chat2 = {
id: 'chat2',
text: 'chat 2',
flags: {},
flagCount: 0,
};
let chat3 = {
id: 'chat3',
text: 'chat 3',
flags: {
'user-id': true,
},
flagCount: 1,
};
let chat4 = {
id: 'chat4',
text: 'chat 4',
flags: {
'user-id': true,
'other-user-id': true,
},
flagCount: 2,
};
let chat5 = {
id: 'chat5',
text: 'chat 5',
flags: {
'user-id': true,
'other-user-id': true,
'yet-another-user-id': true,
},
flagCount: 3,
};
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
chat: [
chat1,
chat2,
chat3,
chat4,
chat5,
],
},
}).then((res) => {
group = res.group;
});
});
context('non-admin', () => {
let api;
beforeEach(() => {
return generateUser().then((user) => {
api = requester(user);
});
});
it('does not include messages with a flag count of 2 or greater', () => {
return api.get(`/groups/${group._id}`).then((_group) => {
expect(_group.chat).to.have.lengthOf(3);
expect(_group.chat[0].id).to.eql(chat1.id);
expect(_group.chat[1].id).to.eql(chat2.id);
expect(_group.chat[2].id).to.eql(chat3.id);
});
});
it('does not include user ids in flags object', () => {
return api.get(`/groups/${group._id}`).then((_group) => {
let chatWithOneFlag = _group.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql({});
});
});
});
context('admin', () => {
let api;
beforeEach(() => {
return generateUser({
'contributor.admin': true,
}).then((user) => {
api = requester(user);
});
});
it('includes all messages', () => {
return api.get(`/groups/${group._id}`).then((_group) => {
expect(_group.chat).to.have.lengthOf(5);
expect(_group.chat[0].id).to.eql(chat1.id);
expect(_group.chat[1].id).to.eql(chat2.id);
expect(_group.chat[2].id).to.eql(chat3.id);
expect(_group.chat[3].id).to.eql(chat4.id);
expect(_group.chat[4].id).to.eql(chat5.id);
});
});
it('includes user ids in flags object', () => {
return api.get(`/groups/${group._id}`).then((_group) => {
let chatWithOneFlag = _group.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql(chat3.flags);
});
});
});
});
context('Non-member of a public guild', () => {
let leader, nonMember, createdGroup;
@@ -36,7 +36,7 @@ describe('POST /groups/:id/chat/:id/flag', () => {
return api.get(`/groups/${group._id}/chat`);
}).then((messages) => {
let message = messages[0];
expect(message.flags[user._id]).to.eql(true);
expect(message.flagCount).to.eql(1);
});
});
});
@@ -99,4 +99,42 @@ describe('POST /groups/:id/chat/:id/flag', () => {
});
});
});
context('admin flagging a message', () => {
let group, member, message, user;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
leaderDetails: {
'contributor.admin': true,
balance: 10,
},
members: 1,
}).then((res) => {
group = res.group;
user = res.leader;
member = res.members[0];
return requester(member)
.post(`/groups/${group._id}/chat`, null, { message: 'Group member message', });
}).then((res) => {
message = res.message;
});
});
it('sets flagCount to 5', () => {
let api = requester(user);
return api.post(`/groups/${group._id}/chat/${message.id}/flag`).then((messages) => {
return api.get(`/groups/${group._id}/chat`);
}).then((messages) => {
let message = messages[0];
expect(message.flagCount).to.eql(5);
});
});
});
});
+104 -1
View File
@@ -3,7 +3,8 @@ import {
requester,
translate as t,
} from '../../../helpers/api-integration.helper';
import {v4 as generateRandomUserName} from 'uuid';
import { v4 as generateRandomUserName } from 'uuid';
import { each } from 'lodash';
describe('POST /register', () => {
@@ -137,4 +138,106 @@ describe('POST /register', () => {
});
});
});
context('successful login via api', () => {
let api, username, email, password;
beforeEach(() => {
api = requester();
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all site tour values to -2 (already seen)', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tour, (value, attribute) => {
expect(value).to.eql(-2);
});
});
});
it('populates user with default todos, not no other task types', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
expect(user.dailys).to.be.empty;
expect(user.habits).to.be.empty;
expect(user.rewards).to.be.empty;
});
});
it('populates user with default tags', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;
});
});
});
context('successful login with habitica-web header', () => {
let api, username, email, password;
beforeEach(() => {
api = requester({}, {'x-client': 'habitica-web'});
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all common tutorial flags to true', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tutorial.common, (value, attribute) => {
expect(value).to.eql(true);
});
});
});
it('populates user with default todos, habits, and rewards', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
expect(user.dailys).to.be.empty;
expect(user.habits).to.not.be.empty;
expect(user.rewards).to.not.be.empty;
});
});
it('populates user with default tags', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;
});
});
});
});
+104 -4
View File
@@ -1,10 +1,12 @@
import {
checkExistence,
createAndPopulateGroup,
generateGroup,
generateUser,
requester,
translate as t,
} from '../../../helpers/api-integration.helper';
import { find } from 'lodash';
describe('DELETE /user', () => {
let api, user;
@@ -64,13 +66,111 @@ describe('DELETE /user', () => {
});
});
context('groups with multiple members', () => {
it('removes user from all groups user was a part of');
context('groups user is leader of', () => {
let api, group, oldLeader, newLeader;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
members: 3,
}).then((res) => {
group = res.group;
newLeader = res.members[0];
oldLeader = res.leader;
api = requester(oldLeader);
});
});
it('chooses new group leader for any group user was the leader of', () => {
return api.del('/user').then((res) => {
return requester(newLeader).get(`/groups/${group._id}`);
}).then((guild) => {
expect(guild.leader).to.exist;
expect(guild.leader._id).to.not.eql(oldLeader._id);
});
});
});
context('groups user is a part of', () => {
let api, group1, group2, userToDelete, otherUser;
beforeEach(() => {
return generateUser({
balance: 10,
}).then((user) => {
userToDelete = user;
api = requester(userToDelete);
return generateGroup(userToDelete, {
type: 'guild',
privacy: 'public',
});
}).then((newGroup) => {
group1 = newGroup;
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
members: 3,
});
}).then((res) => {
group2 = res.group;
otherUser = res.members[0];
return api.post(`/groups/${group2._id}/join`);
});
});
it('removes user from all groups user was a part of', () => {
return api.del('/user').then((res) => {
return requester(otherUser).get(`/groups/${group1._id}`);
}).then((fetchedGroup1) => {
expect(fetchedGroup1.members).to.be.empty;
return requester(otherUser).get(`/groups/${group2._id}`);
}).then((fetchedGroup2) => {
expect(fetchedGroup2.members).to.not.be.empty;
let userInGroup = find(fetchedGroup2.members, (member) => {
return member._id === userToDelete._id;
});
expect(userInGroup).to.not.be.ok;
});
});
it('chooses new group leader for any group user was the leader of');
});
context('pending invitation to group', () => {
it('removes invitations from groups');
let api, group, userToDelete, otherUser;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
members: 3,
invites: 2,
}).then((res) => {
group = res.group;
otherUser = res.members[0];
userToDelete = res.invitees[0];
});
});
it('removes invitations from groups', () => {
return requester(userToDelete).del('/user').then((res) => {
return requester(otherUser).get(`/groups/${group._id}`);
}).then((fetchedGroup) => {
expect(fetchedGroup.invites).to.have.a.lengthOf(1);
expect(fetchedGroup.invites[0]._id).to.not.eql(userToDelete._id);
});
});
});
});
+9 -2
View File
@@ -8,7 +8,14 @@ describe('GET /user/tasks/', () => {
let api, user;
beforeEach(() => {
return generateUser().then((_user) => {
return generateUser({
dailys: [
{text: 'daily', type: 'daily'},
{text: 'daily', type: 'daily'},
{text: 'daily', type: 'daily'},
{text: 'daily', type: 'daily'},
],
}).then((_user) => {
user = _user;
api = requester(user);
});
@@ -17,7 +24,7 @@ describe('GET /user/tasks/', () => {
it('gets all tasks', () => {
return api.get(`/user/tasks/`).then((tasks) => {
expect(tasks).to.be.an('array');
expect(tasks.length).to.be.greaterThan(4);
expect(tasks.length).to.be.greaterThan(3);
let task = tasks[0];
expect(task.id).to.exist;
+11 -7
View File
@@ -16,12 +16,12 @@ 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={}) {
export function requester(user={}, additionalSets) {
return {
get: _requestMaker(user, 'get'),
post: _requestMaker(user, 'post'),
put: _requestMaker(user, 'put'),
del: _requestMaker(user, 'del'),
get: _requestMaker(user, 'get', additionalSets),
post: _requestMaker(user, 'post', additionalSets),
put: _requestMaker(user, 'put', additionalSets),
del: _requestMaker(user, 'del', additionalSets),
}
};
@@ -207,18 +207,22 @@ export function resetHabiticaDB() {
});
}
function _requestMaker(user, method) {
function _requestMaker(user, method, additionalSets) {
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) {
if (user && user._id && user.apiToken) {
request
.set('x-api-user', user._id)
.set('x-api-key', user.apiToken);
}
if (additionalSets) {
request.set(additionalSets);
}
request
.query(query)
.send(send)