Merge branch 'develop' into czan-develop

This commit is contained in:
Blade Barringer
2015-10-29 08:40:03 -05:00
381 changed files with 3600 additions and 2074 deletions
+103
View File
@@ -3,6 +3,7 @@ import {
generateUser,
requester,
} from '../../helpers/api.helper';
import { each, find } from 'lodash';
describe('POST /groups/:id/join', () => {
@@ -10,6 +11,108 @@ describe('POST /groups/:id/join', () => {
it('returns an error');
});
each({
'public guild': {type: 'guild', privacy: 'public'},
'private guild': {type: 'guild', privacy: 'private'},
'party': {type: 'party', privacy: 'private'},
}, (data, groupType) => {
context(`user has invitation to a ${groupType}`, () => {
let api, group, invitee;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: data.type,
privacy: data.privacy,
},
invites: 1,
}).then((res) => {
group = res.group;
invitee = res.invitees[0];
api = requester(invitee);
});
});
it(`allows user to join a ${groupType}`, () => {
return api.post(`/groups/${group._id}/join`).then((res) => {
return api.get(`/groups/${group._id}`);
}).then((_group) => {
let members = _group.members;
let userInGroup = find(members, (user) => {
return user._id === invitee._id;
});
expect(userInGroup).to.exist;
});
});
});
});
each({
'private guild': {type: 'guild', privacy: 'private'},
'party': {type: 'party', privacy: 'private'},
}, (data, groupType) => {
context(`user does not have an invitation to a ${groupType}`, () => {
let api, group, user;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: data.type,
privacy: data.privacy,
},
}).then((res) => {
group = res.group;
return generateUser();
}).then((generatedUser) => {
user = generatedUser;
api = requester(user);
});
});
it(`does not allow user to join a ${groupType}`, () => {
return expect(api.post(`/groups/${group._id}/join`).then((res) => {
return api.get(`/groups/${group._id}`);
})).to.eventually.be.rejected.and.eql({
code: 401,
text: 'Can\'t join a group you\'re not invited to.',
});
});
});
});
context('user does not have an invitation to a public group', () => {
let api, group, user;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
}).then((res) => {
group = res.group;
return generateUser();
}).then((generatedUser) => {
user = generatedUser;
api = requester(user);
});
});
it('allows user to join a public guild', () => {
return api.post(`/groups/${group._id}/join`).then((res) => {
return api.get(`/groups/${group._id}`);
}).then((_group) => {
let members = _group.members;
let userInGroup = find(members, (member) => {
return user._id === user._id;
});
expect(userInGroup).to.exist;
});
});
});
context('public guild has no leader', () => {
let user, group;
+18 -9
View File
@@ -6,19 +6,28 @@ import {
describe('GET /user', () => {
let user;
beforeEach(() => {
before(() => {
return generateUser().then((usr) => {
user = usr;
let api = requester(usr);
return api.get('/user');
}).then((fetchedUser) => {
user = fetchedUser;
});
});
it('gets the user object', () => {
let api = requester(user);
return api.get('/user').then((fetchedUser) => {
expect(fetchedUser._id).to.eql(user._id);
expect(fetchedUser.auth.local.username).to.eql(user.auth.local.username);
expect(fetchedUser.todos).to.eql(user.todos);
expect(fetchedUser.items).to.eql(user.items);
});
expect(user._id).to.eql(user._id);
expect(user.auth.local.username).to.eql(user.auth.local.username);
expect(user.todos).to.eql(user.todos);
expect(user.items).to.eql(user.items);
});
it('does not include password information', () => {
expect(user.auth.local.hashed_password).to.not.exist
expect(user.auth.local.salt).to.not.exist
});
it('does not include api token', () => {
expect(user.apiToken).to.not.exist
});
});
@@ -0,0 +1,102 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
import { each } from 'lodash';
describe('GET /user/anonymized', () => {
let api, user;
before(() => {
return generateUser({
'inbox.messages' : {
'the-message-id' : {
sort : 214,
user : 'Some user',
backer : {},
contributor : {
text : 'Blacksmith',
level : 2,
contributions : 'Made some contributions',
admin : false
},
uuid : 'some-users-uuid',
flagCount : 0,
flags : {},
likes : {},
timestamp : 1444154258699.0000000000000000,
text : 'Lorem ipsum',
id : 'the-messages-id',
sent : true
}
}
}).then((usr) => {
api = requester(usr);
return api.post('/user/tasks', {
text: 'some private text',
notes: 'some private notes',
checklist: [
{text: 'a private checklist'},
{text: 'another private checklist'},
],
type: 'daily',
});
}).then((result) => {
return api.get('/user/anonymized');
}).then((anonymizedUser) => {
user = anonymizedUser;
});
});
it('retains user id', () => {
expect(user._id).to.exist;
});
it('removes credentials and financial information', () => {
expect(user.apiToken).to.not.exist;
expect(user.auth.local).to.not.exist;
expect(user.auth.facebook).to.not.exist;
expect(user.purchased.plan).to.not.exist;
});
it('removes profile information', () => {
expect(user.profile).to.not.exist;
expect(user.contributor).to.not.exist;
expect(user.achievements.challenges).to.not.exist;
});
it('removes social information', () => {
expect(user.newMessages).to.not.exist;
expect(user.invitations).to.not.exist;
expect(user.items.special.nyeReceived).to.not.exist;
expect(user.items.special.valentineReceived).to.not.exist;
each(user.inbox.messages, (msg) => {
expect(msg.text).to.eql('inbox message text');
});
});
it('anonymizes task info', () => {
each(['habits', 'todos', 'dailys', 'rewards'], (tasks) => {
each(user[tasks], (task) => {
expect(task.text).to.eql('task text');
expect(task.notes).to.eql('task notes');
each(task.checklist, (box) => {
expect(box.text).to.match(/item\d*/);
});
});
});
});
it('anonymizes tags', () => {
each(user.tags, (tag) => {
expect(tag.name).to.eql('tag');
expect(tag.challenge).to.eql('challenge');
});
});
it('removes webhooks', () => {
expect(user.webhooks).to.not.exist;
});
});
@@ -0,0 +1,68 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
import { each } from 'lodash';
describe('POST /user/batch-update', () => {
let api, user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
api = requester(user);
});
});
context('allowed operations', () => {
it('makes batch operations', () => {
let task;
return api.get('/user/tasks').then((tasks) => {
task = tasks[0];
return api.post('/user/batch-update', [
{op: 'update', body: {'stats.hp': 30}},
{op: 'update', body: {'profile.name': 'Samwise'}},
{op: 'score', params: { direction: 'up', id: task.id }},
]);
}).then((user) => {
expect(user.stats.hp).to.eql(30);
expect(user.profile.name).to.eql('Samwise');
return api.get(`/user/tasks/${task.id}`);
}).then((task) => {
expect(task.value).to.be.greaterThan(0);
});
});
});
context('development only operations', () => {
let protectedOperations = {
'Add Ten Gems': 'addTenGems',
'Add Hourglass': 'addHourglass',
};
each(protectedOperations, (operation, description) => {
it(`it sends back a 500 error for ${description} operation`, () => {
return expect(api.post('/user/batch-update', [
{op: operation},
])).to.eventually.be.rejected.and.eql({
code: 500,
text: `${operation} operation not found`,
});
});
});
});
context('unknown operations', () => {
it('sends back a 500 error', () => {
return expect(api.post('/user/batch-update', [
{op: 'aNotRealOperation'},
])).to.eventually.be.rejected.and.eql({
code: 500,
text: 'aNotRealOperation operation not found',
});
});
});
});
@@ -0,0 +1,26 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('POST /user/pushDevice', () => {
let api;
beforeEach(() => {
return generateUser().then((user) => {
api = requester(user);
});
});
it('registers a device id', () => {
return api.post('/user/pushDevice', {
regId: '123123',
type: 'android',
}).then((devices) => {
let device = devices[0];
expect(device._id).to.exist;
expect(device.regId).to.eql('123123');
expect(device.type).to.eql('android');
});
});
});
@@ -0,0 +1,44 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('DELETE /user/tasks/:id', () => {
let api, user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
task = user.todos[0];
api = requester(user);
});
});
it('deletes a task', () => {
return expect(api.del(`/user/tasks/${task.id}`)
.then((res) => {
return api.get(`/user/tasks/${task.id}`);
})).to.eventually.be.rejected.and.eql({
code: 404,
text: 'No task found.',
});
});
it('returns an error if the task does not exist', () => {
return expect(api.del('/user/tasks/task-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: 'Task not found.',
});
});
it('does not delete another user\'s task', () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];
return api.del(`/user/tasks/${otherUsersTask.id}`);
})).to.eventually.be.rejected.and.eql({
code: 404,
text: 'Task not found.',
});
});
});
+27
View File
@@ -0,0 +1,27 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('GET /user/tasks/', () => {
let api, user;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
api = requester(user);
});
});
it('gets all tasks', () => {
return api.get(`/user/tasks/`).then((tasks) => {
expect(tasks).to.be.an('array');
expect(tasks.length).to.be.greaterThan(4);
let task = tasks[0];
expect(task.id).to.exist;
expect(task.type).to.exist;
expect(task.text).to.exist;
});
});
});
+44
View File
@@ -0,0 +1,44 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('GET /user/tasks/:id', () => {
let api, user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
task = user.todos[0];
api = requester(user);
});
});
it('gets a task', () => {
return api.get(`/user/tasks/${task.id}`).then((foundTask) => {
expect(foundTask.id).to.eql(task.id);
expect(foundTask.text).to.eql(task.text);
expect(foundTask.notes).to.eql(task.notes);
expect(foundTask.value).to.eql(task.value);
expect(foundTask.type).to.eql(task.type);
});
});
it('returns an error if the task does not exist', () => {
return expect(api.get('/user/tasks/task-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: 'No task found.',
});
});
it('does not get another user\'s task', () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];
return api.get(`/user/tasks/${otherUsersTask.id}`);
})).to.eventually.be.rejected.and.eql({
code: 404,
text: 'No task found.',
});
});
});
+70
View File
@@ -0,0 +1,70 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('POST /user/tasks', () => {
let api, user;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
api = requester(user);
});
});
it('creates a task', () => {
return api.post('/user/tasks').then((task) => {
expect(task.id).to.exist;
});
});
it('creates a habit by default', () => {
return expect(api.post('/user/tasks'))
.to.eventually.have.property('type', 'habit');
});
it('creates a task with specified values', () => {
return api.post('/user/tasks', {
type: 'daily',
text: 'My task',
notes: 'My notes',
frequency: 'daily',
}).then((task) => {
expect(task.type).to.eql('daily');
expect(task.text).to.eql('My task');
expect(task.notes).to.eql('My notes');
expect(task.frequency).to.eql('daily');
});
});
it('does not create a task with an id that already exists', () => {
let todo = user.todos[0];
return expect(api.post('/user/tasks', {
id: todo.id,
})).to.eventually.be.rejected.and.eql({
code: 409,
text: 'A task with that ID already exists.',
});
});
xit('TODO: no error is thrown - throws a 500 validation error if invalid type is posted', () => {
return expect(api.post('/user/tasks', {
type: 'not-valid',
})).to.eventually.be.rejected.and.eql({
code: 500,
text: 'Cannot call method \'indexOf\' of undefined',
});
});
xit('TODO: no error is thrown - throws a 500 validation error if invalid data is posted', () => {
return expect(api.post('/user/tasks', {
frequency: 'not-valid',
})).to.eventually.be.rejected.and.eql({
code: 500,
text: 'Task validation failed',
});
});
});
+70
View File
@@ -0,0 +1,70 @@
import {
generateUser,
requester,
} from '../../../helpers/api.helper';
describe('PUT /user/tasks/:id', () => {
let api, user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
api = requester(user);
task = user.todos[0];
});
});
it('does not update the id of the task', () => {
return api.put(`/user/tasks/${task.id}`, {
id: 'some-thing',
}).then((updatedTask) => {
expect(updatedTask.id).to.eql(task.id);
expect(updatedTask.id).to.not.eql('some-thing');
});
});
it('does not update the type of the task', () => {
return api.put(`/user/tasks/${task.id}`, {
type: 'habit',
}).then((updatedTask) => {
expect(updatedTask.type).to.eql(task.type);
expect(updatedTask.type).to.not.eql('habit');
});
});
it('updates text, attribute, priority, value and notes', () => {
return api.put(`/user/tasks/${task.id}`, {
text: 'new text',
notes: 'new notes',
value: 10000,
priority: .5,
attribute: 'str',
}).then((updatedTask) => {
expect(updatedTask.text).to.eql('new text');
expect(updatedTask.notes).to.eql('new notes');
expect(updatedTask.value).to.eql(10000);
expect(updatedTask.priority).to.eql(.5);
expect(updatedTask.attribute).to.eql('str');
});
});
it('returns an error if the task does not exist', () => {
return expect(api.put('/user/tasks/task-id-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: 'Task not found.',
});
});
it('does not update another user\'s task', () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];
return api.put(`/user/tasks/${otherUsersTask._id}`, {
name: 'some name',
});
})).to.eventually.be.rejected.and.eql({
code: 404,
text: 'Task not found.',
});
});
});