mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 21:27:23 +01:00
fix test lint
This commit is contained in:
@@ -79,7 +79,7 @@ module.exports = async function achievementRestore () {
|
|||||||
const userIds = [
|
const userIds = [
|
||||||
];
|
];
|
||||||
|
|
||||||
Promise.all(userIds.map(userId => (async () => {
|
await Promise.all(userIds.map(userId => (async () => {
|
||||||
const oldUser = await UsersOld.findOne({ _id: userId }, 'achievements');
|
const oldUser = await UsersOld.findOne({ _id: userId }, 'achievements');
|
||||||
const newUser = await Users.findOne({ _id: userId }, 'achievements');
|
const newUser = await Users.findOne({ _id: userId }, 'achievements');
|
||||||
const achievementUpdate = getAchievementUpdate(newUser, oldUser);
|
const achievementUpdate = getAchievementUpdate(newUser, oldUser);
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -4476,9 +4476,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-config-habitrpg": {
|
"eslint-config-habitrpg": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-habitrpg/-/eslint-config-habitrpg-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-habitrpg/-/eslint-config-habitrpg-6.0.7.tgz",
|
||||||
"integrity": "sha512-TYDXHE40Yu65uMHDqqepX0apOQvOGKZhvjz0Rki9CqL4HWO0QfHxv9Vi3mvVzY6+vrNvnUKs1s37SLTUMakiAg==",
|
"integrity": "sha512-hda2IKsfwE/94CjLtPI3Cgsq0capQCFKCiqPPNM7foeO/E6cZpXCSvMHdGt5TXy66DQxF5h+kz4xcheHdcaRcA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"eslint": "^6.5.1",
|
"eslint": "^6.5.1",
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
"npm": "^6"
|
"npm": "^6"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint --ext .js ./test --fix",
|
"lint": "eslint --ext .js .",
|
||||||
"test": "npm run lint && gulp test && gulp apidoc",
|
"test": "npm run lint && gulp test && gulp apidoc",
|
||||||
"test:build": "gulp test:prepare:build",
|
"test:build": "gulp test:prepare:build",
|
||||||
"test:api-v3": "gulp test:api-v3",
|
"test:api-v3": "gulp test:api-v3",
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.1",
|
||||||
"eslint": "^6.5.1",
|
"eslint": "^6.5.1",
|
||||||
"eslint-config-habitrpg": "^6.0.3",
|
"eslint-config-habitrpg": "^6.0.7",
|
||||||
"eslint-plugin-mocha": "^5.0.0",
|
"eslint-plugin-mocha": "^5.0.0",
|
||||||
"expect.js": "^0.3.1",
|
"expect.js": "^0.3.1",
|
||||||
"istanbul": "^1.1.0-alpha.1",
|
"istanbul": "^1.1.0-alpha.1",
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"habitrpg/lib/mocha",
|
|
||||||
],
|
|
||||||
"globals": {
|
|
||||||
"_": true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
|
||||||
import Amplitude from 'amplitude';
|
import Amplitude from 'amplitude';
|
||||||
import { Visitor } from 'universal-analytics';
|
import { Visitor } from 'universal-analytics';
|
||||||
|
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
||||||
|
|
||||||
describe('analyticsService', () => {
|
describe('analyticsService', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -16,7 +16,8 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#track', () => {
|
describe('#track', () => {
|
||||||
let eventType, data;
|
let eventType; let
|
||||||
|
data;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Visitor.prototype.event.yields();
|
Visitor.prototype.event.yields();
|
||||||
@@ -35,12 +36,10 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Amplitude', () => {
|
context('Amplitude', () => {
|
||||||
it('calls out to amplitude', () => {
|
it('calls out to amplitude', () => analyticsService.track(eventType, data)
|
||||||
return analyticsService.track(eventType, data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Amplitude.prototype.track).to.be.calledOnce;
|
||||||
expect(Amplitude.prototype.track).to.be.calledOnce;
|
}));
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses a dummy user id if none is provided', () => {
|
it('uses a dummy user id if none is provided', () => {
|
||||||
delete data.uuid;
|
delete data.uuid;
|
||||||
@@ -55,7 +54,7 @@ describe('analyticsService', () => {
|
|||||||
|
|
||||||
context('platform', () => {
|
context('platform', () => {
|
||||||
it('logs web platform', () => {
|
it('logs web platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-web'};
|
data.headers = { 'x-client': 'habitica-web' };
|
||||||
|
|
||||||
return analyticsService.track(eventType, data)
|
return analyticsService.track(eventType, data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -66,7 +65,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs iOS platform', () => {
|
it('logs iOS platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-ios'};
|
data.headers = { 'x-client': 'habitica-ios' };
|
||||||
|
|
||||||
return analyticsService.track(eventType, data)
|
return analyticsService.track(eventType, data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -77,7 +76,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs Android platform', () => {
|
it('logs Android platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-android'};
|
data.headers = { 'x-client': 'habitica-android' };
|
||||||
|
|
||||||
return analyticsService.track(eventType, data)
|
return analyticsService.track(eventType, data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -88,7 +87,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs 3rd Party platform', () => {
|
it('logs 3rd Party platform', () => {
|
||||||
data.headers = {'x-client': 'some-third-party'};
|
data.headers = { 'x-client': 'some-third-party' };
|
||||||
|
|
||||||
return analyticsService.track(eventType, data)
|
return analyticsService.track(eventType, data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -169,18 +168,16 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends details about event', () => {
|
it('sends details about event', () => analyticsService.track(eventType, data)
|
||||||
return analyticsService.track(eventType, data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Amplitude.prototype.track).to.be.calledWithMatch({
|
||||||
expect(Amplitude.prototype.track).to.be.calledWithMatch({
|
event_properties: {
|
||||||
event_properties: {
|
category: 'behavior',
|
||||||
category: 'behavior',
|
resting: true,
|
||||||
resting: true,
|
cronCount: 5,
|
||||||
cronCount: 5,
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('sends english item name for gear if itemKey is provided', () => {
|
it('sends english item name for gear if itemKey is provided', () => {
|
||||||
data.itemKey = 'headAccessory_special_foxEars';
|
data.itemKey = 'headAccessory_special_foxEars';
|
||||||
@@ -267,16 +264,18 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends user data if provided', () => {
|
it('sends user data if provided', () => {
|
||||||
let stats = { class: 'wizard', exp: 5, gp: 23, hp: 10, lvl: 4, mp: 30 };
|
const stats = {
|
||||||
let user = {
|
class: 'wizard', exp: 5, gp: 23, hp: 10, lvl: 4, mp: 30,
|
||||||
|
};
|
||||||
|
const user = {
|
||||||
stats,
|
stats,
|
||||||
contributor: { level: 1 },
|
contributor: { level: 1 },
|
||||||
purchased: { plan: { planId: 'foo-plan' } },
|
purchased: { plan: { planId: 'foo-plan' } },
|
||||||
flags: {tour: {intro: -2}},
|
flags: { tour: { intro: -2 } },
|
||||||
habits: [{_id: 'habit'}],
|
habits: [{ _id: 'habit' }],
|
||||||
dailys: [{_id: 'daily'}],
|
dailys: [{ _id: 'daily' }],
|
||||||
todos: [{_id: 'todo'}],
|
todos: [{ _id: 'todo' }],
|
||||||
rewards: [{_id: 'reward'}],
|
rewards: [{ _id: 'reward' }],
|
||||||
balance: 12,
|
balance: 12,
|
||||||
loginIncentives: 1,
|
loginIncentives: 1,
|
||||||
};
|
};
|
||||||
@@ -312,27 +311,24 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('GA', () => {
|
context('GA', () => {
|
||||||
it('calls out to GA', () => {
|
it('calls out to GA', () => analyticsService.track(eventType, data)
|
||||||
return analyticsService.track(eventType, data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Visitor.prototype.event).to.be.calledOnce;
|
||||||
expect(Visitor.prototype.event).to.be.calledOnce;
|
}));
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends details about event', () => {
|
it('sends details about event', () => analyticsService.track(eventType, data)
|
||||||
return analyticsService.track(eventType, data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Visitor.prototype.event).to.be.calledWith({
|
||||||
expect(Visitor.prototype.event).to.be.calledWith({
|
ea: 'Cron',
|
||||||
ea: 'Cron',
|
ec: 'behavior',
|
||||||
ec: 'behavior',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#trackPurchase', () => {
|
describe('#trackPurchase', () => {
|
||||||
let data, itemSpy;
|
let data; let
|
||||||
|
itemSpy;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Visitor.prototype.event.yields();
|
Visitor.prototype.event.yields();
|
||||||
@@ -361,12 +357,10 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Amplitude', () => {
|
context('Amplitude', () => {
|
||||||
it('calls out to amplitude', () => {
|
it('calls out to amplitude', () => analyticsService.trackPurchase(data)
|
||||||
return analyticsService.trackPurchase(data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Amplitude.prototype.track).to.be.calledOnce;
|
||||||
expect(Amplitude.prototype.track).to.be.calledOnce;
|
}));
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses a dummy user id if none is provided', () => {
|
it('uses a dummy user id if none is provided', () => {
|
||||||
delete data.uuid;
|
delete data.uuid;
|
||||||
@@ -381,7 +375,7 @@ describe('analyticsService', () => {
|
|||||||
|
|
||||||
context('platform', () => {
|
context('platform', () => {
|
||||||
it('logs web platform', () => {
|
it('logs web platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-web'};
|
data.headers = { 'x-client': 'habitica-web' };
|
||||||
|
|
||||||
return analyticsService.trackPurchase(data)
|
return analyticsService.trackPurchase(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -392,7 +386,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs iOS platform', () => {
|
it('logs iOS platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-ios'};
|
data.headers = { 'x-client': 'habitica-ios' };
|
||||||
|
|
||||||
return analyticsService.trackPurchase(data)
|
return analyticsService.trackPurchase(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -403,7 +397,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs Android platform', () => {
|
it('logs Android platform', () => {
|
||||||
data.headers = {'x-client': 'habitica-android'};
|
data.headers = { 'x-client': 'habitica-android' };
|
||||||
|
|
||||||
return analyticsService.trackPurchase(data)
|
return analyticsService.trackPurchase(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -414,7 +408,7 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs 3rd Party platform', () => {
|
it('logs 3rd Party platform', () => {
|
||||||
data.headers = {'x-client': 'some-third-party'};
|
data.headers = { 'x-client': 'some-third-party' };
|
||||||
|
|
||||||
return analyticsService.trackPurchase(data)
|
return analyticsService.trackPurchase(data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -495,33 +489,33 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends details about purchase', () => {
|
it('sends details about purchase', () => analyticsService.trackPurchase(data)
|
||||||
return analyticsService.trackPurchase(data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Amplitude.prototype.track).to.be.calledWithMatch({
|
||||||
expect(Amplitude.prototype.track).to.be.calledWithMatch({
|
event_properties: {
|
||||||
event_properties: {
|
gift: false,
|
||||||
gift: false,
|
itemPurchased: 'Gems',
|
||||||
itemPurchased: 'Gems',
|
paymentMethod: 'PayPal',
|
||||||
paymentMethod: 'PayPal',
|
purchaseType: 'checkout',
|
||||||
purchaseType: 'checkout',
|
quantity: 1,
|
||||||
quantity: 1,
|
sku: 'paypal-checkout',
|
||||||
sku: 'paypal-checkout',
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('sends user data if provided', () => {
|
it('sends user data if provided', () => {
|
||||||
let stats = { class: 'wizard', exp: 5, gp: 23, hp: 10, lvl: 4, mp: 30 };
|
const stats = {
|
||||||
let user = {
|
class: 'wizard', exp: 5, gp: 23, hp: 10, lvl: 4, mp: 30,
|
||||||
|
};
|
||||||
|
const user = {
|
||||||
stats,
|
stats,
|
||||||
contributor: { level: 1 },
|
contributor: { level: 1 },
|
||||||
purchased: { plan: { planId: 'foo-plan' } },
|
purchased: { plan: { planId: 'foo-plan' } },
|
||||||
flags: {tour: {intro: -2}},
|
flags: { tour: { intro: -2 } },
|
||||||
habits: [{_id: 'habit'}],
|
habits: [{ _id: 'habit' }],
|
||||||
dailys: [{_id: 'daily'}],
|
dailys: [{ _id: 'daily' }],
|
||||||
todos: [{_id: 'todo'}],
|
todos: [{ _id: 'todo' }],
|
||||||
rewards: [{_id: 'reward'}],
|
rewards: [{ _id: 'reward' }],
|
||||||
};
|
};
|
||||||
|
|
||||||
data.user = user;
|
data.user = user;
|
||||||
@@ -552,27 +546,23 @@ describe('analyticsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('GA', () => {
|
context('GA', () => {
|
||||||
it('calls out to GA', () => {
|
it('calls out to GA', () => analyticsService.trackPurchase(data)
|
||||||
return analyticsService.trackPurchase(data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Visitor.prototype.event).to.be.calledOnce;
|
||||||
expect(Visitor.prototype.event).to.be.calledOnce;
|
expect(Visitor.prototype.transaction).to.be.calledOnce;
|
||||||
expect(Visitor.prototype.transaction).to.be.calledOnce;
|
}));
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends details about purchase', () => {
|
it('sends details about purchase', () => analyticsService.trackPurchase(data)
|
||||||
return analyticsService.trackPurchase(data)
|
.then(() => {
|
||||||
.then(() => {
|
expect(Visitor.prototype.event).to.be.calledWith({
|
||||||
expect(Visitor.prototype.event).to.be.calledWith({
|
ea: 'checkout',
|
||||||
ea: 'checkout',
|
ec: 'commerce',
|
||||||
ec: 'commerce',
|
el: 'PayPal',
|
||||||
el: 'PayPal',
|
ev: 8,
|
||||||
ev: 8,
|
|
||||||
});
|
|
||||||
expect(Visitor.prototype.transaction).to.be.calledWith('user-id', 8);
|
|
||||||
expect(itemSpy).to.be.calledWith(8, 1, 'paypal-checkout', 'Gems', 'checkout');
|
|
||||||
});
|
});
|
||||||
});
|
expect(Visitor.prototype.transaction).to.be.calledWith('user-id', 8);
|
||||||
|
expect(itemSpy).to.be.calledWith(8, 1, 'paypal-checkout', 'Gems', 'checkout');
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ describe('API Messages', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('clones the passed variables', () => {
|
it('clones the passed variables', () => {
|
||||||
let vars = {a: 1};
|
const vars = { a: 1 };
|
||||||
sandbox.stub(_, 'clone').returns({});
|
sandbox.stub(_, 'clone').returns({});
|
||||||
apiError('guildsOnlyPaginate', vars);
|
apiError('guildsOnlyPaginate', vars);
|
||||||
expect(_.clone).to.have.been.calledOnce;
|
expect(_.clone).to.have.been.calledOnce;
|
||||||
@@ -19,8 +19,8 @@ describe('API Messages', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('pass the message through _.template', () => {
|
it('pass the message through _.template', () => {
|
||||||
let vars = {a: 1};
|
const vars = { a: 1 };
|
||||||
let stub = sinon.stub().returns('string');
|
const stub = sinon.stub().returns('string');
|
||||||
sandbox.stub(_, 'template').returns(stub);
|
sandbox.stub(_, 'template').returns(stub);
|
||||||
apiError('guildsOnlyPaginate', vars);
|
apiError('guildsOnlyPaginate', vars);
|
||||||
expect(_.template).to.have.been.calledOnce;
|
expect(_.template).to.have.been.calledOnce;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import baseModel from '../../../../website/server/libs/baseModel';
|
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
import baseModel from '../../../../website/server/libs/baseModel';
|
||||||
|
|
||||||
describe('Base model plugin', () => {
|
describe('Base model plugin', () => {
|
||||||
let schema;
|
let schema;
|
||||||
@@ -25,7 +25,7 @@ describe('Base model plugin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can add timestamps fields', () => {
|
it('can add timestamps fields', () => {
|
||||||
schema.plugin(baseModel, {timestamps: true});
|
schema.plugin(baseModel, { timestamps: true });
|
||||||
|
|
||||||
expect(schema.add).to.be.calledTwice;
|
expect(schema.add).to.be.calledTwice;
|
||||||
});
|
});
|
||||||
@@ -36,7 +36,7 @@ describe('Base model plugin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(schema.statics.sanitize).to.exist;
|
expect(schema.statics.sanitize).to.exist;
|
||||||
let sanitized = schema.statics.sanitize({ok: true, noUpdateForMe: true});
|
const sanitized = schema.statics.sanitize({ ok: true, noUpdateForMe: true });
|
||||||
|
|
||||||
expect(sanitized).to.have.property('ok');
|
expect(sanitized).to.have.property('ok');
|
||||||
expect(sanitized).not.to.have.property('noUpdateForMe');
|
expect(sanitized).not.to.have.property('noUpdateForMe');
|
||||||
@@ -49,7 +49,7 @@ describe('Base model plugin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(schema.statics.sanitize).to.exist;
|
expect(schema.statics.sanitize).to.exist;
|
||||||
let sanitized = schema.statics.sanitize({ok: true, noUpdateForMe: true, usuallySettable: true}, ['usuallySettable']);
|
const sanitized = schema.statics.sanitize({ ok: true, noUpdateForMe: true, usuallySettable: true }, ['usuallySettable']);
|
||||||
|
|
||||||
expect(sanitized).to.have.property('ok');
|
expect(sanitized).to.have.property('ok');
|
||||||
expect(sanitized).not.to.have.property('noUpdateForMe');
|
expect(sanitized).not.to.have.property('noUpdateForMe');
|
||||||
@@ -63,31 +63,31 @@ describe('Base model plugin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(schema.options.toJSON.transform).to.exist;
|
expect(schema.options.toJSON.transform).to.exist;
|
||||||
let objToTransform = {ok: true, amPrivate: true};
|
const objToTransform = { ok: true, amPrivate: true };
|
||||||
let privatized = schema.options.toJSON.transform({}, objToTransform);
|
const privatized = schema.options.toJSON.transform({}, objToTransform);
|
||||||
|
|
||||||
expect(privatized).to.have.property('ok');
|
expect(privatized).to.have.property('ok');
|
||||||
expect(privatized).not.to.have.property('amPrivate');
|
expect(privatized).not.to.have.property('amPrivate');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('accepts a further transform function for toJSON', () => {
|
it('accepts a further transform function for toJSON', () => {
|
||||||
let options = {
|
const options = {
|
||||||
private: ['amPrivate'],
|
private: ['amPrivate'],
|
||||||
toJSONTransform: sandbox.stub().returns(true),
|
toJSONTransform: sandbox.stub().returns(true),
|
||||||
};
|
};
|
||||||
|
|
||||||
schema.plugin(baseModel, options);
|
schema.plugin(baseModel, options);
|
||||||
|
|
||||||
let objToTransform = {ok: true, amPrivate: true};
|
const objToTransform = { ok: true, amPrivate: true };
|
||||||
let doc = {doc: true};
|
const doc = { doc: true };
|
||||||
let privatized = schema.options.toJSON.transform(doc, objToTransform);
|
const privatized = schema.options.toJSON.transform(doc, objToTransform);
|
||||||
|
|
||||||
expect(privatized).to.equals(true);
|
expect(privatized).to.equals(true);
|
||||||
expect(options.toJSONTransform).to.be.calledWith(objToTransform, doc);
|
expect(options.toJSONTransform).to.be.calledWith(objToTransform, doc);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('accepts a transform function for sanitize', () => {
|
it('accepts a transform function for sanitize', () => {
|
||||||
let options = {
|
const options = {
|
||||||
private: ['amPrivate'],
|
private: ['amPrivate'],
|
||||||
sanitizeTransform: sandbox.stub().returns(true),
|
sanitizeTransform: sandbox.stub().returns(true),
|
||||||
};
|
};
|
||||||
@@ -95,8 +95,8 @@ describe('Base model plugin', () => {
|
|||||||
schema.plugin(baseModel, options);
|
schema.plugin(baseModel, options);
|
||||||
|
|
||||||
expect(schema.options.toJSON.transform).to.exist;
|
expect(schema.options.toJSON.transform).to.exist;
|
||||||
let objToSanitize = {ok: true, noUpdateForMe: true};
|
const objToSanitize = { ok: true, noUpdateForMe: true };
|
||||||
let sanitized = schema.statics.sanitize(objToSanitize);
|
const sanitized = schema.statics.sanitize(objToSanitize);
|
||||||
|
|
||||||
expect(sanitized).to.equals(true);
|
expect(sanitized).to.equals(true);
|
||||||
expect(options.sanitizeTransform).to.be.calledWith(objToSanitize);
|
expect(options.sanitizeTransform).to.be.calledWith(objToSanitize);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
describe('Collection Manipulators', () => {
|
describe('Collection Manipulators', () => {
|
||||||
describe('removeFromArray', () => {
|
describe('removeFromArray', () => {
|
||||||
it('removes element from array', () => {
|
it('removes element from array', () => {
|
||||||
let array = ['a', 'b', 'c', 'd'];
|
const array = ['a', 'b', 'c', 'd'];
|
||||||
|
|
||||||
removeFromArray(array, 'c');
|
removeFromArray(array, 'c');
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ describe('Collection Manipulators', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('removes object from array', () => {
|
it('removes object from array', () => {
|
||||||
let array = [
|
const array = [
|
||||||
{ id: 'a', foo: 'bar' },
|
{ id: 'a', foo: 'bar' },
|
||||||
{ id: 'b', foo: 'bar' },
|
{ id: 'b', foo: 'bar' },
|
||||||
{ id: 'c', foo: 'bar' },
|
{ id: 'c', foo: 'bar' },
|
||||||
@@ -28,7 +28,7 @@ describe('Collection Manipulators', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not change array if value is not found', () => {
|
it('does not change array if value is not found', () => {
|
||||||
let array = ['a', 'b', 'c', 'd'];
|
const array = ['a', 'b', 'c', 'd'];
|
||||||
|
|
||||||
removeFromArray(array, 'z');
|
removeFromArray(array, 'z');
|
||||||
|
|
||||||
@@ -40,15 +40,15 @@ describe('Collection Manipulators', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns the removed element', () => {
|
it('returns the removed element', () => {
|
||||||
let array = ['a', 'b', 'c'];
|
const array = ['a', 'b', 'c'];
|
||||||
|
|
||||||
let result = removeFromArray(array, 'b');
|
const result = removeFromArray(array, 'b');
|
||||||
|
|
||||||
expect(result).to.eql('b');
|
expect(result).to.eql('b');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the removed object element', () => {
|
it('returns the removed object element', () => {
|
||||||
let array = [
|
const array = [
|
||||||
{ id: 'a', foo: 'bar' },
|
{ id: 'a', foo: 'bar' },
|
||||||
{ id: 'b', foo: 'bar' },
|
{ id: 'b', foo: 'bar' },
|
||||||
{ id: 'c', foo: 'bar' },
|
{ id: 'c', foo: 'bar' },
|
||||||
@@ -56,31 +56,31 @@ describe('Collection Manipulators', () => {
|
|||||||
{ id: 'e', foo: 'bar' },
|
{ id: 'e', foo: 'bar' },
|
||||||
];
|
];
|
||||||
|
|
||||||
let result = removeFromArray(array, { id: 'c' });
|
const result = removeFromArray(array, { id: 'c' });
|
||||||
|
|
||||||
expect(result).to.eql({ id: 'c', foo: 'bar' });
|
expect(result).to.eql({ id: 'c', foo: 'bar' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if item is not found', () => {
|
it('returns false if item is not found', () => {
|
||||||
let array = ['a', 'b', 'c'];
|
const array = ['a', 'b', 'c'];
|
||||||
|
|
||||||
let result = removeFromArray(array, 'z');
|
const result = removeFromArray(array, 'z');
|
||||||
|
|
||||||
expect(result).to.eql(false);
|
expect(result).to.eql(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('persists removal of element when mongoose document is saved', async () => {
|
it('persists removal of element when mongoose document is saved', async () => {
|
||||||
let schema = new mongoose.Schema({
|
const schema = new mongoose.Schema({
|
||||||
array: Array,
|
array: Array,
|
||||||
});
|
});
|
||||||
let Model = mongoose.model('ModelToTestRemoveFromArray', schema);
|
const Model = mongoose.model('ModelToTestRemoveFromArray', schema);
|
||||||
let model = await new Model({
|
const model = await new Model({
|
||||||
array: ['a', 'b', 'c'],
|
array: ['a', 'b', 'c'],
|
||||||
}).save(); // Initial creation
|
}).save(); // Initial creation
|
||||||
|
|
||||||
removeFromArray(model.array, 'b');
|
removeFromArray(model.array, 'b');
|
||||||
|
|
||||||
let savedModel = await model.save();
|
const savedModel = await model.save();
|
||||||
|
|
||||||
expect(savedModel.array).to.not.include('b');
|
expect(savedModel.array).to.not.include('b');
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -31,20 +31,20 @@ function getUser () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('emails', () => {
|
describe('emails', () => {
|
||||||
let pathToEmailLib = '../../../../website/server/libs/email';
|
const pathToEmailLib = '../../../../website/server/libs/email';
|
||||||
|
|
||||||
describe('getUserInfo', () => {
|
describe('getUserInfo', () => {
|
||||||
it('returns an empty object if no field request', () => {
|
it('returns an empty object if no field request', () => {
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let getUserInfo = attachEmail.getUserInfo;
|
const { getUserInfo } = attachEmail;
|
||||||
expect(getUserInfo({}, [])).to.be.empty;
|
expect(getUserInfo({}, [])).to.be.empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct user data', () => {
|
it('returns correct user data', () => {
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let getUserInfo = attachEmail.getUserInfo;
|
const { getUserInfo } = attachEmail;
|
||||||
let user = getUser();
|
const user = getUser();
|
||||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||||
|
|
||||||
expect(data).to.have.property('name', user.auth.local.username);
|
expect(data).to.have.property('name', user.auth.local.username);
|
||||||
expect(data).to.have.property('email', user.auth.local.email);
|
expect(data).to.have.property('email', user.auth.local.email);
|
||||||
@@ -53,13 +53,13 @@ describe('emails', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct user data [facebook users]', () => {
|
it('returns correct user data [facebook users]', () => {
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let getUserInfo = attachEmail.getUserInfo;
|
const { getUserInfo } = attachEmail;
|
||||||
let user = getUser();
|
const user = getUser();
|
||||||
delete user.profile.name;
|
delete user.profile.name;
|
||||||
delete user.auth.local.email;
|
delete user.auth.local.email;
|
||||||
|
|
||||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||||
|
|
||||||
expect(data).to.have.property('name', user.auth.local.username);
|
expect(data).to.have.property('name', user.auth.local.username);
|
||||||
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
||||||
@@ -68,13 +68,13 @@ describe('emails', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('has fallbacks for missing data', () => {
|
it('has fallbacks for missing data', () => {
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let getUserInfo = attachEmail.getUserInfo;
|
const { getUserInfo } = attachEmail;
|
||||||
let user = getUser();
|
const user = getUser();
|
||||||
delete user.auth.local.email;
|
delete user.auth.local.email;
|
||||||
delete user.auth.facebook;
|
delete user.auth.facebook;
|
||||||
|
|
||||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||||
|
|
||||||
expect(data).to.have.property('name', user.auth.local.username);
|
expect(data).to.have.property('name', user.auth.local.username);
|
||||||
expect(data).not.to.have.property('email');
|
expect(data).not.to.have.property('email');
|
||||||
@@ -85,18 +85,18 @@ describe('emails', () => {
|
|||||||
|
|
||||||
describe('getGroupUrl', () => {
|
describe('getGroupUrl', () => {
|
||||||
it('returns correct url if group is the tavern', () => {
|
it('returns correct url if group is the tavern', () => {
|
||||||
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
||||||
expect(getGroupUrl({_id: TAVERN_ID, type: 'guild'})).to.eql('/groups/tavern');
|
expect(getGroupUrl({ _id: TAVERN_ID, type: 'guild' })).to.eql('/groups/tavern');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct url if group is a guild', () => {
|
it('returns correct url if group is a guild', () => {
|
||||||
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
||||||
expect(getGroupUrl({_id: 'random _id', type: 'guild'})).to.eql('/groups/guild/random _id');
|
expect(getGroupUrl({ _id: 'random _id', type: 'guild' })).to.eql('/groups/guild/random _id');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct url if group is a party', () => {
|
it('returns correct url if group is a party', () => {
|
||||||
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
||||||
expect(getGroupUrl({_id: 'random _id', type: 'party'})).to.eql('party');
|
expect(getGroupUrl({ _id: 'random _id', type: 'party' })).to.eql('party');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,10 +111,10 @@ describe('emails', () => {
|
|||||||
|
|
||||||
it('can send a txn email to one recipient', () => {
|
it('can send a txn email to one recipient', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let sendTxnEmail = attachEmail.sendTxn;
|
const sendTxnEmail = attachEmail.sendTxn;
|
||||||
let emailType = 'an email type';
|
const emailType = 'an email type';
|
||||||
let mailingInfo = {
|
const mailingInfo = {
|
||||||
name: 'my name',
|
name: 'my name',
|
||||||
email: 'my@email',
|
email: 'my@email',
|
||||||
};
|
};
|
||||||
@@ -125,9 +125,7 @@ describe('emails', () => {
|
|||||||
body: {
|
body: {
|
||||||
data: {
|
data: {
|
||||||
emailType: sinon.match.same(emailType),
|
emailType: sinon.match.same(emailType),
|
||||||
to: sinon.match((value) => {
|
to: sinon.match(value => Array.isArray(value) && value[0].name === mailingInfo.name, 'matches mailing info array'),
|
||||||
return Array.isArray(value) && value[0].name === mailingInfo.name;
|
|
||||||
}, 'matches mailing info array'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@@ -135,10 +133,10 @@ describe('emails', () => {
|
|||||||
|
|
||||||
it('does not send email if address is missing', () => {
|
it('does not send email if address is missing', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let sendTxnEmail = attachEmail.sendTxn;
|
const sendTxnEmail = attachEmail.sendTxn;
|
||||||
let emailType = 'an email type';
|
const emailType = 'an email type';
|
||||||
let mailingInfo = {
|
const mailingInfo = {
|
||||||
name: 'my name',
|
name: 'my name',
|
||||||
// email: 'my@email',
|
// email: 'my@email',
|
||||||
};
|
};
|
||||||
@@ -149,10 +147,10 @@ describe('emails', () => {
|
|||||||
|
|
||||||
it('uses getUserInfo in case of user data', () => {
|
it('uses getUserInfo in case of user data', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let sendTxnEmail = attachEmail.sendTxn;
|
const sendTxnEmail = attachEmail.sendTxn;
|
||||||
let emailType = 'an email type';
|
const emailType = 'an email type';
|
||||||
let mailingInfo = getUser();
|
const mailingInfo = getUser();
|
||||||
|
|
||||||
sendTxnEmail(mailingInfo, emailType);
|
sendTxnEmail(mailingInfo, emailType);
|
||||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||||
@@ -168,28 +166,24 @@ describe('emails', () => {
|
|||||||
|
|
||||||
it('sends email with some default variables', () => {
|
it('sends email with some default variables', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
||||||
let attachEmail = requireAgain(pathToEmailLib);
|
const attachEmail = requireAgain(pathToEmailLib);
|
||||||
let sendTxnEmail = attachEmail.sendTxn;
|
const sendTxnEmail = attachEmail.sendTxn;
|
||||||
let emailType = 'an email type';
|
const emailType = 'an email type';
|
||||||
let mailingInfo = {
|
const mailingInfo = {
|
||||||
name: 'my name',
|
name: 'my name',
|
||||||
email: 'my@email',
|
email: 'my@email',
|
||||||
};
|
};
|
||||||
let variables = [1, 2, 3];
|
const variables = [1, 2, 3];
|
||||||
|
|
||||||
sendTxnEmail(mailingInfo, emailType, variables);
|
sendTxnEmail(mailingInfo, emailType, variables);
|
||||||
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
||||||
json: true,
|
json: true,
|
||||||
body: {
|
body: {
|
||||||
data: {
|
data: {
|
||||||
variables: sinon.match((value) => {
|
variables: sinon.match(value => value[0].name === 'BASE_URL', 'matches variables'),
|
||||||
return value[0].name === 'BASE_URL';
|
personalVariables: sinon.match(value => value[0].rcpt === mailingInfo.email
|
||||||
}, 'matches variables'),
|
&& value[0].vars[0].name === 'RECIPIENT_NAME'
|
||||||
personalVariables: sinon.match((value) => {
|
&& value[0].vars[1].name === 'RECIPIENT_UNSUB_URL', 'matches personal variables'),
|
||||||
return value[0].rcpt === mailingInfo.email &&
|
|
||||||
value[0].vars[0].name === 'RECIPIENT_NAME' &&
|
|
||||||
value[0].vars[1].name === 'RECIPIENT_UNSUB_URL';
|
|
||||||
}, 'matches personal variables'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import {
|
|||||||
|
|
||||||
describe('encryption', () => {
|
describe('encryption', () => {
|
||||||
it('can encrypt and decrypt', () => {
|
it('can encrypt and decrypt', () => {
|
||||||
let data = 'some secret text';
|
const data = 'some secret text';
|
||||||
let encrypted = encrypt(data);
|
const encrypted = encrypt(data);
|
||||||
let decrypted = decrypt(encrypted);
|
const decrypted = decrypt(encrypted);
|
||||||
|
|
||||||
expect(encrypted).not.to.equal(data);
|
expect(encrypted).not.to.equal(data);
|
||||||
expect(data).to.equal(decrypted);
|
expect(data).to.equal(decrypted);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import i18n from '../../../../website/common/script/i18n';
|
|||||||
describe('Custom Errors', () => {
|
describe('Custom Errors', () => {
|
||||||
describe('CustomError', () => {
|
describe('CustomError', () => {
|
||||||
it('is an instance of Error', () => {
|
it('is an instance of Error', () => {
|
||||||
let customError = new CustomError();
|
const customError = new CustomError();
|
||||||
|
|
||||||
expect(customError).to.be.an.instanceOf(Error);
|
expect(customError).to.be.an.instanceOf(Error);
|
||||||
});
|
});
|
||||||
@@ -20,25 +20,25 @@ describe('Custom Errors', () => {
|
|||||||
|
|
||||||
describe('NotAuthorized', () => {
|
describe('NotAuthorized', () => {
|
||||||
it('is an instance of CustomError', () => {
|
it('is an instance of CustomError', () => {
|
||||||
let notAuthorizedError = new NotAuthorized();
|
const notAuthorizedError = new NotAuthorized();
|
||||||
|
|
||||||
expect(notAuthorizedError).to.be.an.instanceOf(CustomError);
|
expect(notAuthorizedError).to.be.an.instanceOf(CustomError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it returns an http code of 401', () => {
|
it('it returns an http code of 401', () => {
|
||||||
let notAuthorizedError = new NotAuthorized();
|
const notAuthorizedError = new NotAuthorized();
|
||||||
|
|
||||||
expect(notAuthorizedError.httpCode).to.eql(401);
|
expect(notAuthorizedError.httpCode).to.eql(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a default message', () => {
|
it('returns a default message', () => {
|
||||||
let notAuthorizedError = new NotAuthorized();
|
const notAuthorizedError = new NotAuthorized();
|
||||||
|
|
||||||
expect(notAuthorizedError.message).to.eql('Not authorized.');
|
expect(notAuthorizedError.message).to.eql('Not authorized.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows a custom message', () => {
|
it('allows a custom message', () => {
|
||||||
let notAuthorizedError = new NotAuthorized('Custom Error Message');
|
const notAuthorizedError = new NotAuthorized('Custom Error Message');
|
||||||
|
|
||||||
expect(notAuthorizedError.message).to.eql('Custom Error Message');
|
expect(notAuthorizedError.message).to.eql('Custom Error Message');
|
||||||
});
|
});
|
||||||
@@ -46,25 +46,25 @@ describe('Custom Errors', () => {
|
|||||||
|
|
||||||
describe('NotFound', () => {
|
describe('NotFound', () => {
|
||||||
it('is an instance of CustomError', () => {
|
it('is an instance of CustomError', () => {
|
||||||
let notAuthorizedError = new NotFound();
|
const notAuthorizedError = new NotFound();
|
||||||
|
|
||||||
expect(notAuthorizedError).to.be.an.instanceOf(CustomError);
|
expect(notAuthorizedError).to.be.an.instanceOf(CustomError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it returns an http code of 404', () => {
|
it('it returns an http code of 404', () => {
|
||||||
let notAuthorizedError = new NotFound();
|
const notAuthorizedError = new NotFound();
|
||||||
|
|
||||||
expect(notAuthorizedError.httpCode).to.eql(404);
|
expect(notAuthorizedError.httpCode).to.eql(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a default message', () => {
|
it('returns a default message', () => {
|
||||||
let notAuthorizedError = new NotFound();
|
const notAuthorizedError = new NotFound();
|
||||||
|
|
||||||
expect(notAuthorizedError.message).to.eql('Not found.');
|
expect(notAuthorizedError.message).to.eql('Not found.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows a custom message', () => {
|
it('allows a custom message', () => {
|
||||||
let notAuthorizedError = new NotFound('Custom Error Message');
|
const notAuthorizedError = new NotFound('Custom Error Message');
|
||||||
|
|
||||||
expect(notAuthorizedError.message).to.eql('Custom Error Message');
|
expect(notAuthorizedError.message).to.eql('Custom Error Message');
|
||||||
});
|
});
|
||||||
@@ -89,25 +89,25 @@ describe('Custom Errors', () => {
|
|||||||
|
|
||||||
describe('BadRequest', () => {
|
describe('BadRequest', () => {
|
||||||
it('is an instance of CustomError', () => {
|
it('is an instance of CustomError', () => {
|
||||||
let badRequestError = new BadRequest();
|
const badRequestError = new BadRequest();
|
||||||
|
|
||||||
expect(badRequestError).to.be.an.instanceOf(CustomError);
|
expect(badRequestError).to.be.an.instanceOf(CustomError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it returns an http code of 401', () => {
|
it('it returns an http code of 401', () => {
|
||||||
let badRequestError = new BadRequest();
|
const badRequestError = new BadRequest();
|
||||||
|
|
||||||
expect(badRequestError.httpCode).to.eql(400);
|
expect(badRequestError.httpCode).to.eql(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a default message', () => {
|
it('returns a default message', () => {
|
||||||
let badRequestError = new BadRequest();
|
const badRequestError = new BadRequest();
|
||||||
|
|
||||||
expect(badRequestError.message).to.eql('Bad request.');
|
expect(badRequestError.message).to.eql('Bad request.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows a custom message', () => {
|
it('allows a custom message', () => {
|
||||||
let badRequestError = new BadRequest('Custom Error Message');
|
const badRequestError = new BadRequest('Custom Error Message');
|
||||||
|
|
||||||
expect(badRequestError.message).to.eql('Custom Error Message');
|
expect(badRequestError.message).to.eql('Custom Error Message');
|
||||||
});
|
});
|
||||||
@@ -115,25 +115,25 @@ describe('Custom Errors', () => {
|
|||||||
|
|
||||||
describe('InternalServerError', () => {
|
describe('InternalServerError', () => {
|
||||||
it('is an instance of CustomError', () => {
|
it('is an instance of CustomError', () => {
|
||||||
let internalServerError = new InternalServerError();
|
const internalServerError = new InternalServerError();
|
||||||
|
|
||||||
expect(internalServerError).to.be.an.instanceOf(CustomError);
|
expect(internalServerError).to.be.an.instanceOf(CustomError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it returns an http code of 500', () => {
|
it('it returns an http code of 500', () => {
|
||||||
let internalServerError = new InternalServerError();
|
const internalServerError = new InternalServerError();
|
||||||
|
|
||||||
expect(internalServerError.httpCode).to.eql(500);
|
expect(internalServerError.httpCode).to.eql(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a default message', () => {
|
it('returns a default message', () => {
|
||||||
let internalServerError = new InternalServerError();
|
const internalServerError = new InternalServerError();
|
||||||
|
|
||||||
expect(internalServerError.message).to.eql('An unexpected error occurred.');
|
expect(internalServerError.message).to.eql('An unexpected error occurred.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows a custom message', () => {
|
it('allows a custom message', () => {
|
||||||
let internalServerError = new InternalServerError('Custom Error Message');
|
const internalServerError = new InternalServerError('Custom Error Message');
|
||||||
|
|
||||||
expect(internalServerError.message).to.eql('Custom Error Message');
|
expect(internalServerError.message).to.eql('Custom Error Message');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import {
|
|||||||
} from '../../../../website/server/libs/i18n';
|
} from '../../../../website/server/libs/i18n';
|
||||||
|
|
||||||
describe('i18n', () => {
|
describe('i18n', () => {
|
||||||
let listOfLocales = approvedLanguages.sort();
|
const listOfLocales = approvedLanguages.sort();
|
||||||
|
|
||||||
describe('translations', () => {
|
describe('translations', () => {
|
||||||
it('includes a translation object for each locale', () => {
|
it('includes a translation object for each locale', () => {
|
||||||
listOfLocales.forEach((locale) => {
|
listOfLocales.forEach(locale => {
|
||||||
expect(translations[locale]).to.be.an('object');
|
expect(translations[locale]).to.be.an('object');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import winston from 'winston';
|
|||||||
import logger from '../../../../website/server/libs/logger';
|
import logger from '../../../../website/server/libs/logger';
|
||||||
import {
|
import {
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../../../../website/server/libs//errors';
|
} from '../../../../website/server/libs/errors';
|
||||||
|
|
||||||
describe('logger', () => {
|
describe('logger', () => {
|
||||||
let logSpy;
|
let logSpy;
|
||||||
@@ -34,7 +34,7 @@ describe('logger', () => {
|
|||||||
|
|
||||||
context('error object', () => {
|
context('error object', () => {
|
||||||
it('logs the stack and the err data', () => {
|
it('logs the stack and the err data', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
logger.error(errInstance, {
|
logger.error(errInstance, {
|
||||||
data: 1,
|
data: 1,
|
||||||
}, 2, 3);
|
}, 2, 3);
|
||||||
@@ -45,13 +45,13 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
{ data: 1, fullError: errInstance },
|
{ data: 1, fullError: errInstance },
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs the stack and the err data with it\'s own fullError property', () => {
|
it('logs the stack and the err data with it\'s own fullError property', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
let anotherError = new Error('another error');
|
const anotherError = new Error('another error');
|
||||||
|
|
||||||
logger.error(errInstance, {
|
logger.error(errInstance, {
|
||||||
data: 1,
|
data: 1,
|
||||||
@@ -64,12 +64,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
{ data: 1, fullError: anotherError },
|
{ data: 1, fullError: anotherError },
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs the error when errorData is null', () => {
|
it('logs the error when errorData is null', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
|
|
||||||
logger.error(errInstance, null, 2, 3);
|
logger.error(errInstance, null, 2, 3);
|
||||||
|
|
||||||
@@ -79,12 +79,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
null,
|
null,
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs the error when errorData is not an object', () => {
|
it('logs the error when errorData is not an object', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
|
|
||||||
logger.error(errInstance, true, 2, 3);
|
logger.error(errInstance, true, 2, 3);
|
||||||
|
|
||||||
@@ -94,12 +94,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
true,
|
true,
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs the error when errorData does not include isHandledError property', () => {
|
it('logs the error when errorData does not include isHandledError property', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
|
|
||||||
logger.error(errInstance, { httpCode: 400 }, 2, 3);
|
logger.error(errInstance, { httpCode: 400 }, 2, 3);
|
||||||
|
|
||||||
@@ -109,12 +109,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
{ httpCode: 400, fullError: errInstance },
|
{ httpCode: 400, fullError: errInstance },
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs the error when errorData includes isHandledError property but is a 500 error', () => {
|
it('logs the error when errorData includes isHandledError property but is a 500 error', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
|
|
||||||
logger.error(errInstance, {
|
logger.error(errInstance, {
|
||||||
isHandledError: true,
|
isHandledError: true,
|
||||||
@@ -127,12 +127,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
{ httpCode: 502, isHandledError: true, fullError: errInstance },
|
{ httpCode: 502, isHandledError: true, fullError: errInstance },
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs a warning when errorData includes isHandledError property and is not a 500 error', () => {
|
it('logs a warning when errorData includes isHandledError property and is not a 500 error', () => {
|
||||||
let errInstance = new Error('An error.');
|
const errInstance = new Error('An error.');
|
||||||
|
|
||||||
logger.error(errInstance, {
|
logger.error(errInstance, {
|
||||||
isHandledError: true,
|
isHandledError: true,
|
||||||
@@ -145,12 +145,12 @@ describe('logger', () => {
|
|||||||
errInstance.stack,
|
errInstance.stack,
|
||||||
{ httpCode: 403, isHandledError: true, fullError: errInstance },
|
{ httpCode: 403, isHandledError: true, fullError: errInstance },
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs additional data from a CustomError', () => {
|
it('logs additional data from a CustomError', () => {
|
||||||
let errInstance = new NotFound('An error.');
|
const errInstance = new NotFound('An error.');
|
||||||
|
|
||||||
errInstance.customField = 'Some interesting data';
|
errInstance.customField = 'Some interesting data';
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ describe('logger', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
2,
|
2,
|
||||||
3
|
3,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
|
import moment from 'moment';
|
||||||
import {
|
import {
|
||||||
encrypt,
|
encrypt,
|
||||||
} from '../../../../website/server/libs/encryption';
|
} from '../../../../website/server/libs/encryption';
|
||||||
import moment from 'moment';
|
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/api-integration/v3';
|
} from '../../../helpers/api-integration/v3';
|
||||||
@@ -20,11 +20,11 @@ import {
|
|||||||
describe('Password Utilities', () => {
|
describe('Password Utilities', () => {
|
||||||
describe('compare', () => {
|
describe('compare', () => {
|
||||||
it('can compare a correct password hashed with SHA1', async () => {
|
it('can compare a correct password hashed with SHA1', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
let hashedPassword = sha1EncryptPassword(textPassword, salt);
|
const hashedPassword = sha1EncryptPassword(textPassword, salt);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -34,16 +34,16 @@ describe('Password Utilities', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let isValidPassword = await compare(user, textPassword);
|
const isValidPassword = await compare(user, textPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can compare an invalid password hashed with SHA1', async () => {
|
it('can compare an invalid password hashed with SHA1', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
let hashedPassword = sha1EncryptPassword(textPassword, salt);
|
const hashedPassword = sha1EncryptPassword(textPassword, salt);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -53,15 +53,15 @@ describe('Password Utilities', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let isValidPassword = await compare(user, 'wrongPassword');
|
const isValidPassword = await compare(user, 'wrongPassword');
|
||||||
expect(isValidPassword).to.eql(false);
|
expect(isValidPassword).to.eql(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can compare a correct password hashed with bcrypt', async () => {
|
it('can compare a correct password hashed with bcrypt', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -70,15 +70,15 @@ describe('Password Utilities', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let isValidPassword = await compare(user, textPassword);
|
const isValidPassword = await compare(user, textPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can compare an invalid password hashed with bcrypt', async () => {
|
it('can compare an invalid password hashed with bcrypt', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -87,7 +87,7 @@ describe('Password Utilities', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let isValidPassword = await compare(user, 'wrongPassword');
|
const isValidPassword = await compare(user, 'wrongPassword');
|
||||||
expect(isValidPassword).to.eql(false);
|
expect(isValidPassword).to.eql(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -101,18 +101,18 @@ describe('Password Utilities', () => {
|
|||||||
|
|
||||||
it('throws an error if passwordToCheck is missing', async () => {
|
it('throws an error if passwordToCheck is missing', async () => {
|
||||||
try {
|
try {
|
||||||
await compare({a: true});
|
await compare({ a: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e.toString()).to.equal('Error: user and passwordToCheck are required parameters.');
|
expect(e.toString()).to.equal('Error: user and passwordToCheck are required parameters.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to SHA1 encryption if salt is provided', async () => {
|
it('defaults to SHA1 encryption if salt is provided', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
let hashedPassword = sha1EncryptPassword(textPassword, salt);
|
const hashedPassword = sha1EncryptPassword(textPassword, salt);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -122,7 +122,7 @@ describe('Password Utilities', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let isValidPassword = await compare(user, textPassword);
|
const isValidPassword = await compare(user, textPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -141,29 +141,29 @@ describe('Password Utilities', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if comparing the same password', async () => {
|
it('returns true if comparing the same password', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let isValidPassword = await bcryptCompare(textPassword, hashedPassword);
|
const isValidPassword = await bcryptCompare(textPassword, hashedPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if comparing a different password', async () => {
|
it('returns true if comparing a different password', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let isValidPassword = await bcryptCompare('anotherPassword', hashedPassword);
|
const isValidPassword = await bcryptCompare('anotherPassword', hashedPassword);
|
||||||
expect(isValidPassword).to.eql(false);
|
expect(isValidPassword).to.eql(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('convertToBcrypt', () => {
|
describe('convertToBcrypt', () => {
|
||||||
it('converts an user password hashed with sha1 to bcrypt', async () => {
|
it('converts an user password hashed with sha1 to bcrypt', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
let hashedPassword = sha1EncryptPassword(textPassword, salt);
|
const hashedPassword = sha1EncryptPassword(textPassword, salt);
|
||||||
|
|
||||||
let user = {
|
const user = {
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
hashed_password: hashedPassword,
|
hashed_password: hashedPassword,
|
||||||
@@ -178,7 +178,7 @@ describe('Password Utilities', () => {
|
|||||||
expect(user.auth.local.passwordHashMethod).to.equal('bcrypt');
|
expect(user.auth.local.passwordHashMethod).to.equal('bcrypt');
|
||||||
expect(user.auth.local.hashed_password).to.be.a.string;
|
expect(user.auth.local.hashed_password).to.be.a.string;
|
||||||
|
|
||||||
let isValidPassword = await compare(user, textPassword);
|
const isValidPassword = await compare(user, textPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ describe('Password Utilities', () => {
|
|||||||
|
|
||||||
it('throws an error if plainTextPassword is missing', async () => {
|
it('throws an error if plainTextPassword is missing', async () => {
|
||||||
try {
|
try {
|
||||||
await convertToBcrypt({a: true});
|
await convertToBcrypt({ a: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e.toString()).to.equal('Error: user and plainTextPassword are required parameters.');
|
expect(e.toString()).to.equal('Error: user and plainTextPassword are required parameters.');
|
||||||
}
|
}
|
||||||
@@ -201,18 +201,18 @@ describe('Password Utilities', () => {
|
|||||||
|
|
||||||
describe('validatePasswordResetCodeAndFindUser', () => {
|
describe('validatePasswordResetCodeAndFindUser', () => {
|
||||||
it('returns false if the code is missing', async () => {
|
it('returns false if the code is missing', async () => {
|
||||||
let res = await validatePasswordResetCodeAndFindUser();
|
const res = await validatePasswordResetCodeAndFindUser();
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the code is invalid json', async () => {
|
it('returns false if the code is invalid json', async () => {
|
||||||
let res = await validatePasswordResetCodeAndFindUser('invalid json');
|
const res = await validatePasswordResetCodeAndFindUser('invalid json');
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the code cannot be decrypted', async () => {
|
it('returns false if the code cannot be decrypted', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
let res = await validatePasswordResetCodeAndFindUser(JSON.stringify({ // not encrypted
|
const res = await validatePasswordResetCodeAndFindUser(JSON.stringify({ // not encrypted
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
expiresAt: new Date(),
|
expiresAt: new Date(),
|
||||||
}));
|
}));
|
||||||
@@ -220,71 +220,71 @@ describe('Password Utilities', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the code is expired', async () => {
|
it('returns false if the code is expired', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
expiresAt: moment().subtract({minutes: 1}),
|
expiresAt: moment().subtract({ minutes: 1 }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.update({
|
await user.update({
|
||||||
'auth.local.passwordResetCode': code,
|
'auth.local.passwordResetCode': code,
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = await validatePasswordResetCodeAndFindUser(code);
|
const res = await validatePasswordResetCodeAndFindUser(code);
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the user does not exist', async () => {
|
it('returns false if the user does not exist', async () => {
|
||||||
let res = await validatePasswordResetCodeAndFindUser(encrypt(JSON.stringify({
|
const res = await validatePasswordResetCodeAndFindUser(encrypt(JSON.stringify({
|
||||||
userId: Date.now().toString(),
|
userId: Date.now().toString(),
|
||||||
expiresAt: moment().add({days: 1}),
|
expiresAt: moment().add({ days: 1 }),
|
||||||
})));
|
})));
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the user has no local auth', async () => {
|
it('returns false if the user has no local auth', async () => {
|
||||||
let user = await generateUser({
|
const user = await generateUser({
|
||||||
auth: {
|
auth: {
|
||||||
facebook: {},
|
facebook: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let res = await validatePasswordResetCodeAndFindUser(encrypt(JSON.stringify({
|
const res = await validatePasswordResetCodeAndFindUser(encrypt(JSON.stringify({
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
expiresAt: moment().add({days: 1}),
|
expiresAt: moment().add({ days: 1 }),
|
||||||
})));
|
})));
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
|
it('returns false if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
expiresAt: moment().add({days: 1}),
|
expiresAt: moment().add({ days: 1 }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.update({
|
await user.update({
|
||||||
'auth.local.passwordResetCode': 'invalid',
|
'auth.local.passwordResetCode': 'invalid',
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = await validatePasswordResetCodeAndFindUser(code);
|
const res = await validatePasswordResetCodeAndFindUser(code);
|
||||||
expect(res).to.equal(false);
|
expect(res).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the user if the password reset code is valid', async () => {
|
it('returns the user if the password reset code is valid', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
expiresAt: moment().add({days: 1}),
|
expiresAt: moment().add({ days: 1 }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.update({
|
await user.update({
|
||||||
'auth.local.passwordResetCode': code,
|
'auth.local.passwordResetCode': code,
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = await validatePasswordResetCodeAndFindUser(code);
|
const res = await validatePasswordResetCodeAndFindUser(code);
|
||||||
expect(res).not.to.equal(false);
|
expect(res).not.to.equal(false);
|
||||||
expect(res._id).to.equal(user._id);
|
expect(res._id).to.equal(user._id);
|
||||||
});
|
});
|
||||||
@@ -293,8 +293,8 @@ describe('Password Utilities', () => {
|
|||||||
describe('bcrypt', () => {
|
describe('bcrypt', () => {
|
||||||
describe('Hash', () => {
|
describe('Hash', () => {
|
||||||
it('returns a hashed string', async () => {
|
it('returns a hashed string', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
expect(hashedPassword).to.be.a.string;
|
expect(hashedPassword).to.be.a.string;
|
||||||
});
|
});
|
||||||
@@ -302,18 +302,18 @@ describe('Password Utilities', () => {
|
|||||||
|
|
||||||
describe('Compare', () => {
|
describe('Compare', () => {
|
||||||
it('returns true if comparing the same password', async () => {
|
it('returns true if comparing the same password', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let isValidPassword = await bcryptCompare(textPassword, hashedPassword);
|
const isValidPassword = await bcryptCompare(textPassword, hashedPassword);
|
||||||
expect(isValidPassword).to.eql(true);
|
expect(isValidPassword).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if comparing a different password', async () => {
|
it('returns true if comparing a different password', async () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let hashedPassword = await bcryptHash(textPassword);
|
const hashedPassword = await bcryptHash(textPassword);
|
||||||
|
|
||||||
let isValidPassword = await bcryptCompare('anotherPassword', hashedPassword);
|
const isValidPassword = await bcryptCompare('anotherPassword', hashedPassword);
|
||||||
expect(isValidPassword).to.eql(false);
|
expect(isValidPassword).to.eql(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -322,19 +322,19 @@ describe('Password Utilities', () => {
|
|||||||
describe('SHA1', () => {
|
describe('SHA1', () => {
|
||||||
describe('Encrypt', () => {
|
describe('Encrypt', () => {
|
||||||
it('always encrypt the same password to the same value when using the same salt', () => {
|
it('always encrypt the same password to the same value when using the same salt', () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
let encryptedPassword = sha1EncryptPassword(textPassword, salt);
|
const encryptedPassword = sha1EncryptPassword(textPassword, salt);
|
||||||
|
|
||||||
expect(sha1EncryptPassword(textPassword, salt)).to.eql(encryptedPassword);
|
expect(sha1EncryptPassword(textPassword, salt)).to.eql(encryptedPassword);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('never encrypt the same password to the same value when using a different salt', () => {
|
it('never encrypt the same password to the same value when using a different salt', () => {
|
||||||
let textPassword = 'mySecretPassword';
|
const textPassword = 'mySecretPassword';
|
||||||
let aSalt = sha1MakeSalt();
|
const aSalt = sha1MakeSalt();
|
||||||
let anotherSalt = sha1MakeSalt();
|
const anotherSalt = sha1MakeSalt();
|
||||||
let anEncryptedPassword = sha1EncryptPassword(textPassword, aSalt);
|
const anEncryptedPassword = sha1EncryptPassword(textPassword, aSalt);
|
||||||
let anotherEncryptedPassword = sha1EncryptPassword(textPassword, anotherSalt);
|
const anotherEncryptedPassword = sha1EncryptPassword(textPassword, anotherSalt);
|
||||||
|
|
||||||
expect(anEncryptedPassword).not.to.eql(anotherEncryptedPassword);
|
expect(anEncryptedPassword).not.to.eql(anotherEncryptedPassword);
|
||||||
});
|
});
|
||||||
@@ -342,14 +342,14 @@ describe('Password Utilities', () => {
|
|||||||
|
|
||||||
describe('Make Salt', () => {
|
describe('Make Salt', () => {
|
||||||
it('creates a salt with length 10 by default', () => {
|
it('creates a salt with length 10 by default', () => {
|
||||||
let salt = sha1MakeSalt();
|
const salt = sha1MakeSalt();
|
||||||
|
|
||||||
expect(salt.length).to.eql(10);
|
expect(salt.length).to.eql(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can create a salt of any length', () => {
|
it('can create a salt of any length', () => {
|
||||||
let length = 24;
|
const length = 24;
|
||||||
let salt = sha1MakeSalt(length);
|
const salt = sha1MakeSalt(length);
|
||||||
|
|
||||||
expect(salt.length).to.eql(length);
|
expect(salt.length).to.eql(length);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,19 +2,20 @@ import moment from 'moment';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
import { createNonLeaderGroupMember } from '../paymentHelpers';
|
import { createNonLeaderGroupMember } from '../paymentHelpers';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Amazon Payments - Cancel Subscription', () => {
|
describe('Amazon Payments - Cancel Subscription', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
|
|
||||||
let user, group, headers, billingAgreementId, subscriptionBlock, subscriptionLength;
|
let user; let group; let headers; let billingAgreementId; let subscriptionBlock; let
|
||||||
|
subscriptionLength;
|
||||||
let getBillingAgreementDetailsSpy;
|
let getBillingAgreementDetailsSpy;
|
||||||
let paymentCancelSubscriptionSpy;
|
let paymentCancelSubscriptionSpy;
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
getBillingAgreementDetailsSpy = sinon.stub(amzLib, 'getBillingAgreementDetails')
|
getBillingAgreementDetailsSpy = sinon.stub(amzLib, 'getBillingAgreementDetails')
|
||||||
.resolves({
|
.resolves({
|
||||||
BillingAgreementDetails: {
|
BillingAgreementDetails: {
|
||||||
BillingAgreementStatus: {State: 'Open'},
|
BillingAgreementStatus: { State: 'Open' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -81,7 +82,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
getBillingAgreementDetailsSpy = sinon.stub(amzLib, 'getBillingAgreementDetails');
|
getBillingAgreementDetailsSpy = sinon.stub(amzLib, 'getBillingAgreementDetails');
|
||||||
getBillingAgreementDetailsSpy.resolves({
|
getBillingAgreementDetailsSpy.resolves({
|
||||||
BillingAgreementDetails: {
|
BillingAgreementDetails: {
|
||||||
BillingAgreementStatus: {State: 'Closed'},
|
BillingAgreementStatus: { State: 'Closed' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
paymentCancelSubscriptionSpy.resolves({});
|
paymentCancelSubscriptionSpy.resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
amzLib.getBillingAgreementDetails.restore();
|
amzLib.getBillingAgreementDetails.restore();
|
||||||
payments.cancelSubscription.restore();
|
payments.cancelSubscription.restore();
|
||||||
});
|
});
|
||||||
@@ -97,7 +98,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
it('should throw an error if we are missing a subscription', async () => {
|
it('should throw an error if we are missing a subscription', async () => {
|
||||||
user.purchased.plan.customerId = undefined;
|
user.purchased.plan.customerId = undefined;
|
||||||
|
|
||||||
await expect(amzLib.cancelSubscription({user}))
|
await expect(amzLib.cancelSubscription({ user }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -108,7 +109,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
it('should cancel a user subscription', async () => {
|
it('should cancel a user subscription', async () => {
|
||||||
billingAgreementId = user.purchased.plan.customerId;
|
billingAgreementId = user.purchased.plan.customerId;
|
||||||
|
|
||||||
await amzLib.cancelSubscription({user, headers});
|
await amzLib.cancelSubscription({ user, headers });
|
||||||
|
|
||||||
expectAmazonCancelUserSubscriptionSpy();
|
expectAmazonCancelUserSubscriptionSpy();
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
@@ -117,10 +118,10 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
it('should close a user subscription if amazon not closed', async () => {
|
it('should close a user subscription if amazon not closed', async () => {
|
||||||
amzLib.getBillingAgreementDetails.restore();
|
amzLib.getBillingAgreementDetails.restore();
|
||||||
expectBillingAggreementDetailSpy();
|
expectBillingAggreementDetailSpy();
|
||||||
let closeBillingAgreementSpy = sinon.stub(amzLib, 'closeBillingAgreement').resolves({});
|
const closeBillingAgreementSpy = sinon.stub(amzLib, 'closeBillingAgreement').resolves({});
|
||||||
billingAgreementId = user.purchased.plan.customerId;
|
billingAgreementId = user.purchased.plan.customerId;
|
||||||
|
|
||||||
await amzLib.cancelSubscription({user, headers});
|
await amzLib.cancelSubscription({ user, headers });
|
||||||
|
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
expect(closeBillingAgreementSpy).to.be.calledOnce;
|
expect(closeBillingAgreementSpy).to.be.calledOnce;
|
||||||
@@ -132,7 +133,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if group is not found', async () => {
|
it('should throw an error if group is not found', async () => {
|
||||||
await expect(amzLib.cancelSubscription({user, groupId: 'fake-id'}))
|
await expect(amzLib.cancelSubscription({ user, groupId: 'fake-id' }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 404,
|
httpCode: 404,
|
||||||
name: 'NotFound',
|
name: 'NotFound',
|
||||||
@@ -141,9 +142,9 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if user is not group leader', async () => {
|
it('should throw an error if user is not group leader', async () => {
|
||||||
let nonLeader = await createNonLeaderGroupMember(group);
|
const nonLeader = await createNonLeaderGroupMember(group);
|
||||||
|
|
||||||
await expect(amzLib.cancelSubscription({user: nonLeader, groupId: group._id}))
|
await expect(amzLib.cancelSubscription({ user: nonLeader, groupId: group._id }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -154,7 +155,7 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
it('should cancel a group subscription', async () => {
|
it('should cancel a group subscription', async () => {
|
||||||
billingAgreementId = group.purchased.plan.customerId;
|
billingAgreementId = group.purchased.plan.customerId;
|
||||||
|
|
||||||
await amzLib.cancelSubscription({user, groupId: group._id, headers});
|
await amzLib.cancelSubscription({ user, groupId: group._id, headers });
|
||||||
|
|
||||||
expectAmazonCancelGroupSubscriptionSpy(group._id);
|
expectAmazonCancelGroupSubscriptionSpy(group._id);
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
@@ -163,10 +164,10 @@ describe('Amazon Payments - Cancel Subscription', () => {
|
|||||||
it('should close a group subscription if amazon not closed', async () => {
|
it('should close a group subscription if amazon not closed', async () => {
|
||||||
amzLib.getBillingAgreementDetails.restore();
|
amzLib.getBillingAgreementDetails.restore();
|
||||||
expectBillingAggreementDetailSpy();
|
expectBillingAggreementDetailSpy();
|
||||||
let closeBillingAgreementSpy = sinon.stub(amzLib, 'closeBillingAgreement').resolves({});
|
const closeBillingAgreementSpy = sinon.stub(amzLib, 'closeBillingAgreement').resolves({});
|
||||||
billingAgreementId = group.purchased.plan.customerId;
|
billingAgreementId = group.purchased.plan.customerId;
|
||||||
|
|
||||||
await amzLib.cancelSubscription({user, groupId: group._id, headers});
|
await amzLib.cancelSubscription({ user, groupId: group._id, headers });
|
||||||
|
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
expect(closeBillingAgreementSpy).to.be.calledOnce;
|
expect(closeBillingAgreementSpy).to.be.calledOnce;
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
|||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Amazon Payments - Checkout', () => {
|
describe('Amazon Payments - Checkout', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, orderReferenceId, headers;
|
let user; let orderReferenceId; let
|
||||||
|
headers;
|
||||||
let setOrderReferenceDetailsSpy;
|
let setOrderReferenceDetailsSpy;
|
||||||
let confirmOrderReferenceSpy;
|
let confirmOrderReferenceSpy;
|
||||||
let authorizeSpy;
|
let authorizeSpy;
|
||||||
@@ -62,7 +63,7 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
expect(closeOrderReferenceSpy).to.be.calledWith({ AmazonOrderReferenceId: orderReferenceId });
|
expect(closeOrderReferenceSpy).to.be.calledWith({ AmazonOrderReferenceId: orderReferenceId });
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(() => {
|
||||||
user = new User();
|
user = new User();
|
||||||
headers = {};
|
headers = {};
|
||||||
orderReferenceId = 'orderReferenceId';
|
orderReferenceId = 'orderReferenceId';
|
||||||
@@ -88,7 +89,7 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
sinon.stub(common, 'uuid').returns('uuid-generated');
|
sinon.stub(common, 'uuid').returns('uuid-generated');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
amzLib.setOrderReferenceDetails.restore();
|
amzLib.setOrderReferenceDetails.restore();
|
||||||
amzLib.confirmOrderReference.restore();
|
amzLib.confirmOrderReference.restore();
|
||||||
amzLib.authorize.restore();
|
amzLib.authorize.restore();
|
||||||
@@ -101,7 +102,7 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
function expectBuyGemsStub (paymentMethod, gift) {
|
function expectBuyGemsStub (paymentMethod, gift) {
|
||||||
expect(paymentBuyGemsStub).to.be.calledOnce;
|
expect(paymentBuyGemsStub).to.be.calledOnce;
|
||||||
|
|
||||||
let expectedArgs = {
|
const expectedArgs = {
|
||||||
user,
|
user,
|
||||||
paymentMethod,
|
paymentMethod,
|
||||||
headers,
|
headers,
|
||||||
@@ -112,7 +113,7 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
|
|
||||||
it('should purchase gems', async () => {
|
it('should purchase gems', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(true);
|
sinon.stub(user, 'canGetGems').resolves(true);
|
||||||
await amzLib.checkout({user, orderReferenceId, headers});
|
await amzLib.checkout({ user, orderReferenceId, headers });
|
||||||
|
|
||||||
expectBuyGemsStub(amzLib.constants.PAYMENT_METHOD);
|
expectBuyGemsStub(amzLib.constants.PAYMENT_METHOD);
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
@@ -121,9 +122,9 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error if gem amount is too low', async () => {
|
it('should error if gem amount is too low', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
gems: {
|
gems: {
|
||||||
amount: 0,
|
amount: 0,
|
||||||
@@ -131,7 +132,9 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(amzLib.checkout({gift, user, orderReferenceId, headers}))
|
await expect(amzLib.checkout({
|
||||||
|
gift, user, orderReferenceId, headers,
|
||||||
|
}))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 400,
|
httpCode: 400,
|
||||||
message: 'Amount must be at least 1.',
|
message: 'Amount must be at least 1.',
|
||||||
@@ -141,18 +144,19 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
|
|
||||||
it('should error if user cannot get gems gems', async () => {
|
it('should error if user cannot get gems gems', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(false);
|
sinon.stub(user, 'canGetGems').resolves(false);
|
||||||
await expect(amzLib.checkout({user, orderReferenceId, headers})).to.eventually.be.rejected.and.to.eql({
|
await expect(amzLib.checkout({ user, orderReferenceId, headers }))
|
||||||
httpCode: 401,
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
message: i18n.t('groupPolicyCannotGetGems'),
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
message: i18n.t('groupPolicyCannotGetGems'),
|
||||||
});
|
name: 'NotAuthorized',
|
||||||
|
});
|
||||||
user.canGetGems.restore();
|
user.canGetGems.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should gift gems', async () => {
|
it('should gift gems', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
await receivingUser.save();
|
await receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
uuid: receivingUser._id,
|
uuid: receivingUser._id,
|
||||||
gems: {
|
gems: {
|
||||||
@@ -160,16 +164,18 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
amount = 16 / 4;
|
amount = 16 / 4;
|
||||||
await amzLib.checkout({gift, user, orderReferenceId, headers});
|
await amzLib.checkout({
|
||||||
|
gift, user, orderReferenceId, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expectBuyGemsStub(amzLib.constants.PAYMENT_METHOD_GIFT, gift);
|
expectBuyGemsStub(amzLib.constants.PAYMENT_METHOD_GIFT, gift);
|
||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should gift a subscription', async () => {
|
it('should gift a subscription', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'subscription',
|
type: 'subscription',
|
||||||
subscription: {
|
subscription: {
|
||||||
key: subKey,
|
key: subKey,
|
||||||
@@ -178,7 +184,9 @@ describe('Amazon Payments - Checkout', () => {
|
|||||||
};
|
};
|
||||||
amount = common.content.subscriptionBlocks[subKey].price;
|
amount = common.content.subscriptionBlocks[subKey].price;
|
||||||
|
|
||||||
await amzLib.checkout({user, orderReferenceId, headers, gift});
|
await amzLib.checkout({
|
||||||
|
user, orderReferenceId, headers, gift,
|
||||||
|
});
|
||||||
|
|
||||||
gift.member = receivingUser;
|
gift.member = receivingUser;
|
||||||
expect(paymentCreateSubscritionStub).to.be.calledOnce;
|
expect(paymentCreateSubscritionStub).to.be.calledOnce;
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ import cc from 'coupon-code';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
||||||
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Amazon Payments - Subscribe', () => {
|
describe('Amazon Payments - Subscribe', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, group, amount, billingAgreementId, sub, coupon, groupId, headers;
|
let user; let group; let amount; let billingAgreementId; let sub; let coupon; let groupId; let
|
||||||
|
headers;
|
||||||
let amazonSetBillingAgreementDetailsSpy;
|
let amazonSetBillingAgreementDetailsSpy;
|
||||||
let amazonConfirmBillingAgreementSpy;
|
let amazonConfirmBillingAgreementSpy;
|
||||||
let amazonAuthorizeOnBillingAgreementSpy;
|
let amazonAuthorizeOnBillingAgreementSpy;
|
||||||
@@ -60,7 +61,7 @@ describe('Amazon Payments - Subscribe', () => {
|
|||||||
sinon.stub(common, 'uuid').returns('uuid-generated');
|
sinon.stub(common, 'uuid').returns('uuid-generated');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
amzLib.setBillingAgreementDetails.restore();
|
amzLib.setBillingAgreementDetails.restore();
|
||||||
amzLib.confirmBillingAgreement.restore();
|
amzLib.confirmBillingAgreement.restore();
|
||||||
amzLib.authorizeOnBillingAgreement.restore();
|
amzLib.authorizeOnBillingAgreement.restore();
|
||||||
@@ -168,7 +169,7 @@ describe('Amazon Payments - Subscribe', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
await couponModel.save();
|
await couponModel.save();
|
||||||
|
|
||||||
@@ -195,9 +196,9 @@ describe('Amazon Payments - Subscribe', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
let updatedCouponModel = await couponModel.save();
|
const updatedCouponModel = await couponModel.save();
|
||||||
|
|
||||||
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,17 @@ import uuid from 'uuid';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import { model as Group } from '../../../../../../website/server/models/group';
|
import { model as Group } from '../../../../../../website/server/models/group';
|
||||||
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
|
|
||||||
describe('#upgradeGroupPlan', () => {
|
describe('#upgradeGroupPlan', () => {
|
||||||
let spy, data, user, group, uuidString;
|
let spy; let data; let user; let group; let
|
||||||
|
uuidString;
|
||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
user.profile.name = 'sender';
|
user.profile.name = 'sender';
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ describe('#upgradeGroupPlan', () => {
|
|||||||
data.sub.quantity = 3;
|
data.sub.quantity = 3;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
amzLib.authorizeOnBillingAgreement.restore();
|
amzLib.authorizeOnBillingAgreement.restore();
|
||||||
uuid.v4.restore();
|
uuid.v4.restore();
|
||||||
});
|
});
|
||||||
@@ -55,7 +56,7 @@ describe('#upgradeGroupPlan', () => {
|
|||||||
data.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
data.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
||||||
await payments.createSubscription(data);
|
await payments.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
|
|
||||||
updatedGroup.memberCount += 1;
|
updatedGroup.memberCount += 1;
|
||||||
await updatedGroup.save();
|
await updatedGroup.save();
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import iapModule from '../../../../../website/server/libs/inAppPurchases';
|
import moment from 'moment';
|
||||||
import payments from '../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../website/server/libs/payments/payments';
|
||||||
import applePayments from '../../../../../website/server/libs/payments/apple';
|
import applePayments from '../../../../../website/server/libs/payments/apple';
|
||||||
import iap from '../../../../../website/server/libs/inAppPurchases';
|
import iap from '../../../../../website/server/libs/inAppPurchases';
|
||||||
import {model as User} from '../../../../../website/server/models/user';
|
import { model as User } from '../../../../../website/server/models/user';
|
||||||
import common from '../../../../../website/common';
|
import common from '../../../../../website/common';
|
||||||
import moment from 'moment';
|
import { mockFindById, restoreFindById } from '../../../../helpers/mongoose.helper';
|
||||||
import {mockFindById, restoreFindById} from '../../../../helpers/mongoose.helper';
|
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Apple Payments', () => {
|
describe('Apple Payments', () => {
|
||||||
let subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
|
|
||||||
describe('verifyGemPurchase', () => {
|
describe('verifyGemPurchase', () => {
|
||||||
let sku, user, token, receipt, headers;
|
let sku; let user; let token; let receipt; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, paymentBuyGemsStub, iapGetPurchaseDataStub;
|
headers;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let paymentBuyGemsStub; let
|
||||||
|
iapGetPurchaseDataStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
token = 'testToken';
|
token = 'testToken';
|
||||||
@@ -24,33 +25,34 @@ describe('Apple Payments', () => {
|
|||||||
receipt = `{"token": "${token}", "productId": "${sku}"}`;
|
receipt = `{"token": "${token}", "productId": "${sku}"}`;
|
||||||
headers = {};
|
headers = {};
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({});
|
.resolves({});
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{productId: 'com.habitrpg.ios.Habitica.21gems',
|
.returns([{
|
||||||
transactionId: token,
|
productId: 'com.habitrpg.ios.Habitica.21gems',
|
||||||
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
|
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
payments.buyGems.restore();
|
payments.buyGems.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(applePayments.verifyGemPurchase({user, receipt, headers}))
|
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -60,9 +62,9 @@ describe('Apple Payments', () => {
|
|||||||
|
|
||||||
it('should throw an error if getPurchaseData is invalid', async () => {
|
it('should throw an error if getPurchaseData is invalid', async () => {
|
||||||
iapGetPurchaseDataStub.restore();
|
iapGetPurchaseDataStub.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData').returns([]);
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData').returns([]);
|
||||||
|
|
||||||
await expect(applePayments.verifyGemPurchase({user, receipt, headers}))
|
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -72,7 +74,7 @@ describe('Apple Payments', () => {
|
|||||||
|
|
||||||
it('errors if the user cannot purchase gems', async () => {
|
it('errors if the user cannot purchase gems', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(false);
|
sinon.stub(user, 'canGetGems').resolves(false);
|
||||||
await expect(applePayments.verifyGemPurchase({user, receipt, headers}))
|
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -85,12 +87,13 @@ describe('Apple Payments', () => {
|
|||||||
it('errors if amount does not exist', async () => {
|
it('errors if amount does not exist', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(true);
|
sinon.stub(user, 'canGetGems').resolves(true);
|
||||||
iapGetPurchaseDataStub.restore();
|
iapGetPurchaseDataStub.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{productId: 'badProduct',
|
.returns([{
|
||||||
transactionId: token,
|
productId: 'badProduct',
|
||||||
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
await expect(applePayments.verifyGemPurchase({user, receipt, headers}))
|
await expect(applePayments.verifyGemPurchase({ user, receipt, headers }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -126,13 +129,14 @@ describe('Apple Payments', () => {
|
|||||||
gemsCanPurchase.forEach(gemTest => {
|
gemsCanPurchase.forEach(gemTest => {
|
||||||
it(`purchases ${gemTest.productId} gems`, async () => {
|
it(`purchases ${gemTest.productId} gems`, async () => {
|
||||||
iapGetPurchaseDataStub.restore();
|
iapGetPurchaseDataStub.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{productId: gemTest.productId,
|
.returns([{
|
||||||
transactionId: token,
|
productId: gemTest.productId,
|
||||||
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
sinon.stub(user, 'canGetGems').resolves(true);
|
sinon.stub(user, 'canGetGems').resolves(true);
|
||||||
await applePayments.verifyGemPurchase({user, receipt, headers});
|
await applePayments.verifyGemPurchase({ user, receipt, headers });
|
||||||
|
|
||||||
expect(iapSetupStub).to.be.calledOnce;
|
expect(iapSetupStub).to.be.calledOnce;
|
||||||
expect(iapValidateStub).to.be.calledOnce;
|
expect(iapValidateStub).to.be.calledOnce;
|
||||||
@@ -160,13 +164,16 @@ describe('Apple Payments', () => {
|
|||||||
mockFindById(receivingUser);
|
mockFindById(receivingUser);
|
||||||
|
|
||||||
iapGetPurchaseDataStub.restore();
|
iapGetPurchaseDataStub.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{productId: gemsCanPurchase[0].productId,
|
.returns([{
|
||||||
transactionId: token,
|
productId: gemsCanPurchase[0].productId,
|
||||||
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
const gift = {uuid: receivingUser._id};
|
const gift = { uuid: receivingUser._id };
|
||||||
await applePayments.verifyGemPurchase({user, gift, receipt, headers});
|
await applePayments.verifyGemPurchase({
|
||||||
|
user, gift, receipt, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expect(iapSetupStub).to.be.calledOnce;
|
expect(iapSetupStub).to.be.calledOnce;
|
||||||
expect(iapValidateStub).to.be.calledOnce;
|
expect(iapValidateStub).to.be.calledOnce;
|
||||||
@@ -187,8 +194,11 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('subscribe', () => {
|
describe('subscribe', () => {
|
||||||
let sub, sku, user, token, receipt, headers, nextPaymentProcessing;
|
let sub; let sku; let user; let token; let receipt; let headers; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, paymentsCreateSubscritionStub, iapGetPurchaseDataStub;
|
nextPaymentProcessing;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub;
|
||||||
|
let paymentsCreateSubscritionStub; let
|
||||||
|
iapGetPurchaseDataStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sub = common.content.subscriptionBlocks[subKey];
|
sub = common.content.subscriptionBlocks[subKey];
|
||||||
@@ -197,25 +207,25 @@ describe('Apple Payments', () => {
|
|||||||
token = 'test-token';
|
token = 'test-token';
|
||||||
headers = {};
|
headers = {};
|
||||||
receipt = `{"token": "${token}"}`;
|
receipt = `{"token": "${token}"}`;
|
||||||
nextPaymentProcessing = moment.utc().add({days: 2});
|
nextPaymentProcessing = moment.utc().add({ days: 2 });
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({});
|
.resolves({});
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{
|
.returns([{
|
||||||
expirationDate: moment.utc().subtract({day: 1}).toDate(),
|
expirationDate: moment.utc().subtract({ day: 1 }).toDate(),
|
||||||
productId: sku,
|
productId: sku,
|
||||||
transactionId: token,
|
transactionId: token,
|
||||||
}, {
|
}, {
|
||||||
expirationDate: moment.utc().add({day: 1}).toDate(),
|
expirationDate: moment.utc().add({ day: 1 }).toDate(),
|
||||||
productId: 'wrongsku',
|
productId: 'wrongsku',
|
||||||
transactionId: token,
|
transactionId: token,
|
||||||
}, {
|
}, {
|
||||||
expirationDate: moment.utc().add({day: 1}).toDate(),
|
expirationDate: moment.utc().add({ day: 1 }).toDate(),
|
||||||
productId: sku,
|
productId: sku,
|
||||||
transactionId: token,
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
@@ -223,10 +233,10 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
if (payments.createSubscription.restore) payments.createSubscription.restore();
|
if (payments.createSubscription.restore) payments.createSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -240,8 +250,8 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(applePayments.subscribe(sku, user, receipt, headers, nextPaymentProcessing))
|
await expect(applePayments.subscribe(sku, user, receipt, headers, nextPaymentProcessing))
|
||||||
@@ -272,10 +282,10 @@ describe('Apple Payments', () => {
|
|||||||
];
|
];
|
||||||
subOptions.forEach(option => {
|
subOptions.forEach(option => {
|
||||||
it(`creates a user subscription for ${option.sku}`, async () => {
|
it(`creates a user subscription for ${option.sku}`, async () => {
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{
|
.returns([{
|
||||||
expirationDate: moment.utc().add({day: 1}).toDate(),
|
expirationDate: moment.utc().add({ day: 1 }).toDate(),
|
||||||
productId: option.sku,
|
productId: option.sku,
|
||||||
transactionId: token,
|
transactionId: token,
|
||||||
}]);
|
}]);
|
||||||
@@ -319,8 +329,10 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('cancelSubscribe ', () => {
|
describe('cancelSubscribe ', () => {
|
||||||
let user, token, receipt, headers, customerId, expirationDate;
|
let user; let token; let receipt; let headers; let customerId; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, iapGetPurchaseDataStub, paymentCancelSubscriptionSpy;
|
expirationDate;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let iapGetPurchaseDataStub; let
|
||||||
|
paymentCancelSubscriptionSpy;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
token = 'test-token';
|
token = 'test-token';
|
||||||
@@ -329,15 +341,15 @@ describe('Apple Payments', () => {
|
|||||||
customerId = 'test-customerId';
|
customerId = 'test-customerId';
|
||||||
expirationDate = moment.utc();
|
expirationDate = moment.utc();
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({
|
.resolves({
|
||||||
expirationDate,
|
expirationDate,
|
||||||
});
|
});
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{expirationDate: expirationDate.toDate()}]);
|
.returns([{ expirationDate: expirationDate.toDate() }]);
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
|
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -350,11 +362,11 @@ describe('Apple Payments', () => {
|
|||||||
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
payments.cancelSubscription.restore();
|
payments.cancelSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -370,9 +382,9 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if subscription is still valid', async () => {
|
it('should throw an error if subscription is still valid', async () => {
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{expirationDate: expirationDate.add({day: 1}).toDate()}]);
|
.returns([{ expirationDate: expirationDate.add({ day: 1 }).toDate() }]);
|
||||||
|
|
||||||
await expect(applePayments.cancelSubscribe(user, headers))
|
await expect(applePayments.cancelSubscribe(user, headers))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
@@ -383,8 +395,8 @@ describe('Apple Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(applePayments.cancelSubscribe(user, headers))
|
await expect(applePayments.cancelSubscribe(user, headers))
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import iapModule from '../../../../../website/server/libs/inAppPurchases';
|
import moment from 'moment';
|
||||||
import payments from '../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../website/server/libs/payments/payments';
|
||||||
import googlePayments from '../../../../../website/server/libs/payments/google';
|
import googlePayments from '../../../../../website/server/libs/payments/google';
|
||||||
import iap from '../../../../../website/server/libs/inAppPurchases';
|
import iap from '../../../../../website/server/libs/inAppPurchases';
|
||||||
import {model as User} from '../../../../../website/server/models/user';
|
import { model as User } from '../../../../../website/server/models/user';
|
||||||
import common from '../../../../../website/common';
|
import common from '../../../../../website/common';
|
||||||
import moment from 'moment';
|
import { mockFindById, restoreFindById } from '../../../../helpers/mongoose.helper';
|
||||||
import {mockFindById, restoreFindById} from '../../../../helpers/mongoose.helper';
|
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Google Payments', () => {
|
describe('Google Payments', () => {
|
||||||
let subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
|
|
||||||
describe('verifyGemPurchase', () => {
|
describe('verifyGemPurchase', () => {
|
||||||
let sku, user, token, receipt, signature, headers;
|
let sku; let user; let token; let receipt; let signature; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, paymentBuyGemsStub;
|
headers;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
|
||||||
|
paymentBuyGemsStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sku = 'com.habitrpg.android.habitica.iap.21gems';
|
sku = 'com.habitrpg.android.habitica.iap.21gems';
|
||||||
@@ -24,28 +25,30 @@ describe('Google Payments', () => {
|
|||||||
signature = '';
|
signature = '';
|
||||||
headers = {};
|
headers = {};
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({});
|
.resolves({});
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
|
paymentBuyGemsStub = sinon.stub(payments, 'buyGems').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
payments.buyGems.restore();
|
payments.buyGems.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(googlePayments.verifyGemPurchase({user, receipt, signature, headers}))
|
await expect(googlePayments.verifyGemPurchase({
|
||||||
|
user, receipt, signature, headers,
|
||||||
|
}))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -56,7 +59,9 @@ describe('Google Payments', () => {
|
|||||||
it('should throw an error if productId is invalid', async () => {
|
it('should throw an error if productId is invalid', async () => {
|
||||||
receipt = `{"token": "${token}", "productId": "invalid"}`;
|
receipt = `{"token": "${token}", "productId": "invalid"}`;
|
||||||
|
|
||||||
await expect(googlePayments.verifyGemPurchase({user, receipt, signature, headers}))
|
await expect(googlePayments.verifyGemPurchase({
|
||||||
|
user, receipt, signature, headers,
|
||||||
|
}))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -67,7 +72,9 @@ describe('Google Payments', () => {
|
|||||||
it('should throw an error if user cannot purchase gems', async () => {
|
it('should throw an error if user cannot purchase gems', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(false);
|
sinon.stub(user, 'canGetGems').resolves(false);
|
||||||
|
|
||||||
await expect(googlePayments.verifyGemPurchase({user, receipt, signature, headers}))
|
await expect(googlePayments.verifyGemPurchase({
|
||||||
|
user, receipt, signature, headers,
|
||||||
|
}))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -79,7 +86,9 @@ describe('Google Payments', () => {
|
|||||||
|
|
||||||
it('purchases gems', async () => {
|
it('purchases gems', async () => {
|
||||||
sinon.stub(user, 'canGetGems').resolves(true);
|
sinon.stub(user, 'canGetGems').resolves(true);
|
||||||
await googlePayments.verifyGemPurchase({user, receipt, signature, headers});
|
await googlePayments.verifyGemPurchase({
|
||||||
|
user, receipt, signature, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expect(iapSetupStub).to.be.calledOnce;
|
expect(iapSetupStub).to.be.calledOnce;
|
||||||
expect(iapValidateStub).to.be.calledOnce;
|
expect(iapValidateStub).to.be.calledOnce;
|
||||||
@@ -107,8 +116,10 @@ describe('Google Payments', () => {
|
|||||||
|
|
||||||
mockFindById(receivingUser);
|
mockFindById(receivingUser);
|
||||||
|
|
||||||
const gift = {uuid: receivingUser._id};
|
const gift = { uuid: receivingUser._id };
|
||||||
await googlePayments.verifyGemPurchase({user, gift, receipt, signature, headers});
|
await googlePayments.verifyGemPurchase({
|
||||||
|
user, gift, receipt, signature, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expect(iapSetupStub).to.be.calledOnce;
|
expect(iapSetupStub).to.be.calledOnce;
|
||||||
expect(iapValidateStub).to.be.calledOnce;
|
expect(iapValidateStub).to.be.calledOnce;
|
||||||
@@ -131,8 +142,10 @@ describe('Google Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('subscribe', () => {
|
describe('subscribe', () => {
|
||||||
let sub, sku, user, token, receipt, signature, headers, nextPaymentProcessing;
|
let sub; let sku; let user; let token; let receipt; let signature; let headers; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, paymentsCreateSubscritionStub;
|
nextPaymentProcessing;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
|
||||||
|
paymentsCreateSubscritionStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sub = common.content.subscriptionBlocks[subKey];
|
sub = common.content.subscriptionBlocks[subKey];
|
||||||
@@ -142,30 +155,31 @@ describe('Google Payments', () => {
|
|||||||
headers = {};
|
headers = {};
|
||||||
receipt = `{"token": "${token}"}`;
|
receipt = `{"token": "${token}"}`;
|
||||||
signature = '';
|
signature = '';
|
||||||
nextPaymentProcessing = moment.utc().add({days: 2});
|
nextPaymentProcessing = moment.utc().add({ days: 2 });
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({});
|
.resolves({});
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
paymentsCreateSubscritionStub = sinon.stub(payments, 'createSubscription').resolves({});
|
paymentsCreateSubscritionStub = sinon.stub(payments, 'createSubscription').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
payments.createSubscription.restore();
|
payments.createSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(googlePayments.subscribe(sku, user, receipt, signature, headers, nextPaymentProcessing))
|
await expect(googlePayments
|
||||||
|
.subscribe(sku, user, receipt, signature, headers, nextPaymentProcessing))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -176,7 +190,8 @@ describe('Google Payments', () => {
|
|||||||
it('should throw an error if sku is invalid', async () => {
|
it('should throw an error if sku is invalid', async () => {
|
||||||
sku = 'invalid';
|
sku = 'invalid';
|
||||||
|
|
||||||
await expect(googlePayments.subscribe(sku, user, receipt, signature, headers, nextPaymentProcessing))
|
await expect(googlePayments
|
||||||
|
.subscribe(sku, user, receipt, signature, headers, nextPaymentProcessing))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -203,15 +218,17 @@ describe('Google Payments', () => {
|
|||||||
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
|
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
|
||||||
sub,
|
sub,
|
||||||
headers,
|
headers,
|
||||||
additionalData: {data: receipt, signature},
|
additionalData: { data: receipt, signature },
|
||||||
nextPaymentProcessing,
|
nextPaymentProcessing,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('cancelSubscribe ', () => {
|
describe('cancelSubscribe ', () => {
|
||||||
let user, token, receipt, signature, headers, customerId, expirationDate;
|
let user; let token; let receipt; let signature; let headers; let customerId; let
|
||||||
let iapSetupStub, iapValidateStub, iapIsValidatedStub, iapGetPurchaseDataStub, paymentCancelSubscriptionSpy;
|
expirationDate;
|
||||||
|
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let iapGetPurchaseDataStub; let
|
||||||
|
paymentCancelSubscriptionSpy;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
token = 'test-token';
|
token = 'test-token';
|
||||||
@@ -221,15 +238,15 @@ describe('Google Payments', () => {
|
|||||||
customerId = 'test-customerId';
|
customerId = 'test-customerId';
|
||||||
expirationDate = moment.utc();
|
expirationDate = moment.utc();
|
||||||
|
|
||||||
iapSetupStub = sinon.stub(iapModule, 'setup')
|
iapSetupStub = sinon.stub(iap, 'setup')
|
||||||
.resolves();
|
.resolves();
|
||||||
iapValidateStub = sinon.stub(iapModule, 'validate')
|
iapValidateStub = sinon.stub(iap, 'validate')
|
||||||
.resolves({
|
.resolves({
|
||||||
expirationDate,
|
expirationDate,
|
||||||
});
|
});
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{expirationDate: expirationDate.toDate()}]);
|
.returns([{ expirationDate: expirationDate.toDate() }]);
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(true);
|
.returns(true);
|
||||||
|
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -237,16 +254,16 @@ describe('Google Payments', () => {
|
|||||||
user.purchased.plan.customerId = customerId;
|
user.purchased.plan.customerId = customerId;
|
||||||
user.purchased.plan.paymentMethod = googlePayments.constants.PAYMENT_METHOD_GOOGLE;
|
user.purchased.plan.paymentMethod = googlePayments.constants.PAYMENT_METHOD_GOOGLE;
|
||||||
user.purchased.plan.planId = subKey;
|
user.purchased.plan.planId = subKey;
|
||||||
user.purchased.plan.additionalData = {data: receipt, signature};
|
user.purchased.plan.additionalData = { data: receipt, signature };
|
||||||
|
|
||||||
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
iapModule.setup.restore();
|
iap.setup.restore();
|
||||||
iapModule.validate.restore();
|
iap.validate.restore();
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
payments.cancelSubscription.restore();
|
payments.cancelSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -262,9 +279,9 @@ describe('Google Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if subscription is still valid', async () => {
|
it('should throw an error if subscription is still valid', async () => {
|
||||||
iapModule.getPurchaseData.restore();
|
iap.getPurchaseData.restore();
|
||||||
iapGetPurchaseDataStub = sinon.stub(iapModule, 'getPurchaseData')
|
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||||
.returns([{expirationDate: expirationDate.add({day: 1}).toDate()}]);
|
.returns([{ expirationDate: expirationDate.add({ day: 1 }).toDate() }]);
|
||||||
|
|
||||||
await expect(googlePayments.cancelSubscribe(user, headers))
|
await expect(googlePayments.cancelSubscribe(user, headers))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
@@ -275,8 +292,8 @@ describe('Google Payments', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if receipt is invalid', async () => {
|
it('should throw an error if receipt is invalid', async () => {
|
||||||
iapModule.isValidated.restore();
|
iap.isValidated.restore();
|
||||||
iapIsValidatedStub = sinon.stub(iapModule, 'isValidated')
|
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
|
||||||
.returns(false);
|
.returns(false);
|
||||||
|
|
||||||
await expect(googlePayments.cancelSubscribe(user, headers))
|
await expect(googlePayments.cancelSubscribe(user, headers))
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import { model as User } from '../../../../../../website/server/models/user';
|
|||||||
import { model as Group } from '../../../../../../website/server/models/group';
|
import { model as Group } from '../../../../../../website/server/models/group';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import i18n from '../../../../../../website/common/script/i18n';
|
import i18n from '../../../../../../website/common/script/i18n';
|
||||||
|
|
||||||
describe('Canceling a subscription for group', () => {
|
describe('Canceling a subscription for group', () => {
|
||||||
let plan, group, user, data;
|
let plan; let group; let user; let
|
||||||
|
data;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -67,9 +68,9 @@ describe('Canceling a subscription for group', () => {
|
|||||||
data.groupId = group._id;
|
data.groupId = group._id;
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
|
expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
|
||||||
});
|
});
|
||||||
@@ -81,9 +82,9 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
|
expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
|
||||||
});
|
});
|
||||||
@@ -95,9 +96,9 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
|
expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
|
||||||
});
|
});
|
||||||
@@ -108,9 +109,9 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(13, 15);
|
expect(daysTillTermination).to.be.within(13, 15);
|
||||||
});
|
});
|
||||||
@@ -122,7 +123,7 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
expect(updatedGroup.purchased.plan.extraMonths).to.eql(0);
|
expect(updatedGroup.purchased.plan.extraMonths).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -134,12 +135,12 @@ describe('Canceling a subscription for group', () => {
|
|||||||
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(user._id);
|
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(user._id);
|
||||||
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-cancel-subscription');
|
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-cancel-subscription');
|
||||||
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prevents non group leader from managing subscription', async () => {
|
it('prevents non group leader from managing subscription', async () => {
|
||||||
let groupMember = new User();
|
const groupMember = new User();
|
||||||
data.user = groupMember;
|
data.user = groupMember;
|
||||||
data.groupId = group._id;
|
data.groupId = group._id;
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ describe('Canceling a subscription for group', () => {
|
|||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
let updatedGroup = await Group.findById(group._id).exec();
|
||||||
let newLeader = new User();
|
const newLeader = new User();
|
||||||
updatedGroup.leader = newLeader._id;
|
updatedGroup.leader = newLeader._id;
|
||||||
await updatedGroup.save();
|
await updatedGroup.save();
|
||||||
|
|
||||||
@@ -192,15 +193,15 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
now.setHours(0, 0, 0, 0);
|
now.setHours(0, 0, 0, 0);
|
||||||
let updatedLeader = await User.findById(user._id).exec();
|
const updatedLeader = await User.findById(user._id).exec();
|
||||||
let daysTillTermination = moment(updatedLeader.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(updatedLeader.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
expect(daysTillTermination).to.be.within(2, 3); // only a few days
|
expect(daysTillTermination).to.be.within(2, 3); // only a few days
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends an email to members of group', async () => {
|
it('sends an email to members of group', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
await recipient.save();
|
await recipient.save();
|
||||||
@@ -214,8 +215,8 @@ describe('Canceling a subscription for group', () => {
|
|||||||
expect(sender.sendTxn.thirdCall.args[0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.thirdCall.args[0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.thirdCall.args[1]).to.equal('group-member-cancel');
|
expect(sender.sendTxn.thirdCall.args[1]).to.equal('group-member-cancel');
|
||||||
expect(sender.sendTxn.thirdCall.args[2]).to.eql([
|
expect(sender.sendTxn.thirdCall.args[2]).to.eql([
|
||||||
{name: 'LEADER', content: user.profile.name},
|
{ name: 'LEADER', content: user.profile.name },
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ describe('Canceling a subscription for group', () => {
|
|||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.customerId = api.constants.UNLIMITED_CUSTOMER_ID;
|
plan.customerId = api.constants.UNLIMITED_CUSTOMER_ID;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -233,12 +234,12 @@ describe('Canceling a subscription for group', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let updatedLeader = await User.findById(user._id).exec();
|
const updatedLeader = await User.findById(user._id).exec();
|
||||||
expect(updatedLeader.purchased.plan.dateTerminated).to.not.exist;
|
expect(updatedLeader.purchased.plan.dateTerminated).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not cancel a user subscription if they are still in another active group plan', async () => {
|
it('does not cancel a user subscription if they are still in another active group plan', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
@@ -252,10 +253,10 @@ describe('Canceling a subscription for group', () => {
|
|||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
let updatedUser = await User.findById(recipient._id).exec();
|
||||||
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
const firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
||||||
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
const extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
||||||
|
|
||||||
let group2 = generateGroup({
|
const group2 = generateGroup({
|
||||||
name: 'test group2',
|
name: 'test group2',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -291,10 +292,10 @@ describe('Canceling a subscription for group', () => {
|
|||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(user._id).exec();
|
let updatedUser = await User.findById(user._id).exec();
|
||||||
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
const firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
||||||
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
const extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
||||||
|
|
||||||
let group2 = generateGroup({
|
const group2 = generateGroup({
|
||||||
name: 'test group2',
|
name: 'test group2',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { model as User } from '../../../../../../website/server/models/user';
|
|||||||
import { model as Group } from '../../../../../../website/server/models/group';
|
import { model as Group } from '../../../../../../website/server/models/group';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
describe('Purchasing a group plan for group', () => {
|
describe('Purchasing a group plan for group', () => {
|
||||||
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE = 'Google_subscription';
|
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE = 'Google_subscription';
|
||||||
@@ -19,10 +19,11 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL = 'normal_subscription';
|
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL = 'normal_subscription';
|
||||||
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE = 'no_subscription';
|
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE = 'no_subscription';
|
||||||
|
|
||||||
let plan, group, user, data;
|
let plan; let group; let user; let
|
||||||
let stripe = stripeModule('test');
|
data;
|
||||||
let groupLeaderName = 'sender';
|
const stripe = stripeModule('test');
|
||||||
let groupName = 'test group';
|
const groupLeaderName = 'sender';
|
||||||
|
const groupName = 'test group';
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -68,14 +69,17 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let subscriptionId = 'subId';
|
const subscriptionId = 'subId';
|
||||||
sinon.stub(stripe.customers, 'del').resolves({});
|
sinon.stub(stripe.customers, 'del').resolves({});
|
||||||
|
|
||||||
let currentPeriodEndTimeStamp = moment().add(3, 'months').unix();
|
const currentPeriodEndTimeStamp = moment().add(3, 'months').unix();
|
||||||
sinon.stub(stripe.customers, 'retrieve')
|
sinon.stub(stripe.customers, 'retrieve')
|
||||||
.resolves({
|
.resolves({
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
data: [{id: subscriptionId, current_period_end: currentPeriodEndTimeStamp}], // eslint-disable-line camelcase
|
data: [{
|
||||||
|
id: subscriptionId,
|
||||||
|
current_period_end: currentPeriodEndTimeStamp,
|
||||||
|
}], // eslint-disable-line camelcase
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,7 +99,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
|
|
||||||
expect(updatedGroup.purchased.plan.planId).to.eql('basic_3mo');
|
expect(updatedGroup.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
expect(updatedGroup.purchased.plan.customerId).to.eql('customer-id');
|
expect(updatedGroup.purchased.plan.customerId).to.eql('customer-id');
|
||||||
@@ -126,7 +130,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
expect(updatedGroup.purchased.plan.extraMonths).to.within(1.9, 2);
|
expect(updatedGroup.purchased.plan.extraMonths).to.within(1.9, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
expect(updatedGroup.purchased.plan.extraMonths).to.eql(0);
|
expect(updatedGroup.purchased.plan.extraMonths).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -150,7 +154,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
data.groupId = group._id;
|
data.groupId = group._id;
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
let updatedLeader = await User.findById(user._id).exec();
|
const updatedLeader = await User.findById(user._id).exec();
|
||||||
|
|
||||||
expect(updatedLeader.purchased.plan.planId).to.eql('group_plan_auto');
|
expect(updatedLeader.purchased.plan.planId).to.eql('group_plan_auto');
|
||||||
expect(updatedLeader.purchased.plan.customerId).to.eql('group-plan');
|
expect(updatedLeader.purchased.plan.customerId).to.eql('group-plan');
|
||||||
@@ -166,7 +170,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends an email to member of group who was not a subscriber', async () => {
|
it('sends an email to member of group who was not a subscriber', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
await recipient.save();
|
await recipient.save();
|
||||||
@@ -179,9 +183,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
||||||
{name: 'LEADER', content: user.profile.name},
|
{ name: 'LEADER', content: user.profile.name },
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE },
|
||||||
]);
|
]);
|
||||||
// confirm that the other email sent is appropriate:
|
// confirm that the other email sent is appropriate:
|
||||||
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
||||||
@@ -189,7 +193,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends one email to subscribed member of group, stating subscription is cancelled (Stripe)', async () => {
|
it('sends one email to subscribed member of group, stating subscription is cancelled (Stripe)', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -205,9 +209,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
||||||
{name: 'LEADER', content: user.profile.name},
|
{ name: 'LEADER', content: user.profile.name },
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
|
||||||
]);
|
]);
|
||||||
// confirm that the other email sent is not a cancel-subscription email:
|
// confirm that the other email sent is not a cancel-subscription email:
|
||||||
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
||||||
@@ -218,11 +222,11 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
sinon.stub(amzLib, 'getBillingAgreementDetails')
|
sinon.stub(amzLib, 'getBillingAgreementDetails')
|
||||||
.resolves({
|
.resolves({
|
||||||
BillingAgreementDetails: {
|
BillingAgreementDetails: {
|
||||||
BillingAgreementStatus: {State: 'Closed'},
|
BillingAgreementStatus: { State: 'Closed' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.planId = 'basic_earned';
|
plan.planId = 'basic_earned';
|
||||||
plan.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
plan.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
||||||
@@ -238,9 +242,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
||||||
{name: 'LEADER', content: user.profile.name},
|
{ name: 'LEADER', content: user.profile.name },
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
|
||||||
]);
|
]);
|
||||||
// confirm that the other email sent is not a cancel-subscription email:
|
// confirm that the other email sent is not a cancel-subscription email:
|
||||||
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
||||||
@@ -259,7 +263,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.planId = 'basic_earned';
|
plan.planId = 'basic_earned';
|
||||||
plan.paymentMethod = paypalPayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = paypalPayments.constants.PAYMENT_METHOD;
|
||||||
@@ -275,9 +279,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
expect(sender.sendTxn.firstCall.args[2]).to.eql([
|
||||||
{name: 'LEADER', content: user.profile.name},
|
{ name: 'LEADER', content: user.profile.name },
|
||||||
{name: 'GROUP_NAME', content: group.name},
|
{ name: 'GROUP_NAME', content: group.name },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
|
||||||
]);
|
]);
|
||||||
// confirm that the other email sent is not a cancel-subscription email:
|
// confirm that the other email sent is not a cancel-subscription email:
|
||||||
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
|
||||||
@@ -292,7 +296,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.customerId = 'random';
|
plan.customerId = 'random';
|
||||||
plan.paymentMethod = api.constants.GOOGLE_PAYMENT_METHOD;
|
plan.paymentMethod = api.constants.GOOGLE_PAYMENT_METHOD;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -310,9 +314,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
|
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.args[1][2]).to.eql([
|
expect(sender.sendTxn.args[1][2]).to.eql([
|
||||||
{name: 'LEADER', content: groupLeaderName},
|
{ name: 'LEADER', content: groupLeaderName },
|
||||||
{name: 'GROUP_NAME', content: groupName},
|
{ name: 'GROUP_NAME', content: groupName },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE },
|
||||||
]);
|
]);
|
||||||
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
|
||||||
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
|
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
|
||||||
@@ -325,7 +329,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.customerId = 'random';
|
plan.customerId = 'random';
|
||||||
plan.paymentMethod = api.constants.IOS_PAYMENT_METHOD;
|
plan.paymentMethod = api.constants.IOS_PAYMENT_METHOD;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -343,9 +347,9 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
|
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
|
||||||
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
|
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
|
||||||
expect(sender.sendTxn.args[1][2]).to.eql([
|
expect(sender.sendTxn.args[1][2]).to.eql([
|
||||||
{name: 'LEADER', content: groupLeaderName},
|
{ name: 'LEADER', content: groupLeaderName },
|
||||||
{name: 'GROUP_NAME', content: groupName},
|
{ name: 'GROUP_NAME', content: groupName },
|
||||||
{name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_IOS},
|
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_IOS },
|
||||||
]);
|
]);
|
||||||
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
|
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
|
||||||
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
|
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
|
||||||
@@ -354,7 +358,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members with existing gift subscription', async () => {
|
it('adds months to members with existing gift subscription', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -378,7 +382,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
||||||
@@ -392,7 +396,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members with existing multi-month gift subscription', async () => {
|
it('adds months to members with existing multi-month gift subscription', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -414,7 +418,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
||||||
@@ -428,7 +432,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members with existing recurring subscription (Stripe)', async () => {
|
it('adds months to members with existing recurring subscription (Stripe)', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -450,11 +454,11 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
sinon.stub(amzLib, 'getBillingAgreementDetails')
|
sinon.stub(amzLib, 'getBillingAgreementDetails')
|
||||||
.resolves({
|
.resolves({
|
||||||
BillingAgreementDetails: {
|
BillingAgreementDetails: {
|
||||||
BillingAgreementStatus: {State: 'Closed'},
|
BillingAgreementStatus: { State: 'Closed' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.planId = 'basic_earned';
|
plan.planId = 'basic_earned';
|
||||||
plan.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
plan.paymentMethod = amzLib.constants.PAYMENT_METHOD;
|
||||||
@@ -470,7 +474,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(3, 5);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(3, 5);
|
||||||
});
|
});
|
||||||
@@ -485,7 +489,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.planId = 'basic_earned';
|
plan.planId = 'basic_earned';
|
||||||
plan.paymentMethod = paypalPayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = paypalPayments.constants.PAYMENT_METHOD;
|
||||||
@@ -500,7 +504,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
||||||
paypalPayments.paypalBillingAgreementGet.restore();
|
paypalPayments.paypalBillingAgreementGet.restore();
|
||||||
@@ -511,7 +515,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
it('adds months to members with existing recurring subscription (iOS)');
|
it('adds months to members with existing recurring subscription (iOS)');
|
||||||
|
|
||||||
it('adds months to members who already cancelled but not yet terminated recurring subscription', async () => {
|
it('adds months to members who already cancelled but not yet terminated recurring subscription', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -527,13 +531,13 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members who already cancelled but not yet terminated group plan subscription', async () => {
|
it('adds months to members who already cancelled but not yet terminated group plan subscription', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = api.constants.GROUP_PLAN_PAYMENT_METHOD;
|
plan.paymentMethod = api.constants.GROUP_PLAN_PAYMENT_METHOD;
|
||||||
@@ -550,12 +554,12 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(3, 4);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(3, 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resets date terminated if user has old subscription', async () => {
|
it('resets date terminated if user has old subscription', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -570,13 +574,13 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.dateTerminated).to.not.exist;
|
expect(updatedUser.purchased.plan.dateTerminated).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members with existing recurring subscription and includes existing extraMonths', async () => {
|
it('adds months to members with existing recurring subscription and includes existing extraMonths', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -591,13 +595,13 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(7, 9);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(7, 9);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds months to members with existing recurring subscription and ignores existing negative extraMonths', async () => {
|
it('adds months to members with existing recurring subscription and ignores existing negative extraMonths', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
plan.paymentMethod = stripePayments.constants.PAYMENT_METHOD;
|
||||||
@@ -612,23 +616,23 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
expect(updatedUser.purchased.plan.extraMonths).to.within(2, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not override gemsBought, mysteryItems, dateCreated, and consective fields', async () => {
|
it('does not override gemsBought, mysteryItems, dateCreated, and consective fields', async () => {
|
||||||
let planCreatedDate = moment().toDate();
|
const planCreatedDate = moment().toDate();
|
||||||
let mysteryItem = {title: 'item'};
|
const mysteryItem = { title: 'item' };
|
||||||
let mysteryItems = [mysteryItem];
|
const mysteryItems = [mysteryItem];
|
||||||
let consecutive = {
|
const consecutive = {
|
||||||
trinkets: 3,
|
trinkets: 3,
|
||||||
gemCapExtra: 20,
|
gemCapExtra: 20,
|
||||||
offset: 1,
|
offset: 1,
|
||||||
count: 13,
|
count: 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
|
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
@@ -647,7 +651,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.gemsBought).to.equal(3);
|
expect(updatedUser.purchased.plan.gemsBought).to.equal(3);
|
||||||
expect(updatedUser.purchased.plan.mysteryItems[0]).to.eql(mysteryItem);
|
expect(updatedUser.purchased.plan.mysteryItems[0]).to.eql(mysteryItem);
|
||||||
@@ -659,7 +663,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not modify a user with a group subscription when they join another group', async () => {
|
it('does not modify a user with a group subscription when they join another group', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
@@ -673,10 +677,10 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
let updatedUser = await User.findById(recipient._id).exec();
|
||||||
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
const firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
||||||
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
const extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
||||||
|
|
||||||
let group2 = generateGroup({
|
const group2 = generateGroup({
|
||||||
name: 'test group2',
|
name: 'test group2',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -703,7 +707,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not remove a user who is in two groups plans and leaves one', async () => {
|
it('does not remove a user who is in two groups plans and leaves one', async () => {
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
@@ -717,10 +721,10 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
let updatedUser = await User.findById(recipient._id).exec();
|
||||||
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
const firstDateCreated = updatedUser.purchased.plan.dateCreated;
|
||||||
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
const extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
|
||||||
|
|
||||||
let group2 = generateGroup({
|
const group2 = generateGroup({
|
||||||
name: 'test group2',
|
name: 'test group2',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -733,7 +737,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
await updatedGroup.leave(recipient);
|
await updatedGroup.leave(recipient);
|
||||||
|
|
||||||
updatedUser = await User.findById(recipient._id).exec();
|
updatedUser = await User.findById(recipient._id).exec();
|
||||||
@@ -753,7 +757,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.key = 'basic_earned';
|
plan.key = 'basic_earned';
|
||||||
plan.customerId = api.constants.UNLIMITED_CUSTOMER_ID;
|
plan.customerId = api.constants.UNLIMITED_CUSTOMER_ID;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -765,7 +769,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql(api.constants.UNLIMITED_CUSTOMER_ID);
|
expect(updatedUser.purchased.plan.customerId).to.eql(api.constants.UNLIMITED_CUSTOMER_ID);
|
||||||
@@ -782,7 +786,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.customerId = 'random';
|
plan.customerId = 'random';
|
||||||
plan.paymentMethod = api.constants.GOOGLE_PAYMENT_METHOD;
|
plan.paymentMethod = api.constants.GOOGLE_PAYMENT_METHOD;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -794,7 +798,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql('random');
|
expect(updatedUser.purchased.plan.customerId).to.eql('random');
|
||||||
@@ -811,7 +815,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.customerId = 'random';
|
plan.customerId = 'random';
|
||||||
plan.paymentMethod = api.constants.IOS_PAYMENT_METHOD;
|
plan.paymentMethod = api.constants.IOS_PAYMENT_METHOD;
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -823,7 +827,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
expect(updatedUser.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql('random');
|
expect(updatedUser.purchased.plan.customerId).to.eql('random');
|
||||||
@@ -841,7 +845,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
plan.customerId = api.constants.GROUP_PLAN_CUSTOMER_ID;
|
plan.customerId = api.constants.GROUP_PLAN_CUSTOMER_ID;
|
||||||
plan.dateTerminated = moment().add(1, 'months');
|
plan.dateTerminated = moment().add(1, 'months');
|
||||||
|
|
||||||
let recipient = new User();
|
const recipient = new User();
|
||||||
recipient.profile.name = 'recipient';
|
recipient.profile.name = 'recipient';
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.guilds.push(group._id);
|
recipient.guilds.push(group._id);
|
||||||
@@ -853,7 +857,7 @@ describe('Purchasing a group plan for group', () => {
|
|||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
let updatedUser = await User.findById(recipient._id).exec();
|
const updatedUser = await User.findById(recipient._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql(api.constants.GROUP_PLAN_CUSTOMER_ID);
|
expect(updatedUser.purchased.plan.customerId).to.eql(api.constants.GROUP_PLAN_CUSTOMER_ID);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { model as User } from '../../../../../website/server/models/user';
|
import { model as User } from '../../../../../website/server/models/user';
|
||||||
|
|
||||||
export async function createNonLeaderGroupMember (group) {
|
export async function createNonLeaderGroupMember (group) { // eslint-disable-line import/prefer-default-export, max-len
|
||||||
let nonLeader = new User();
|
const nonLeader = new User();
|
||||||
nonLeader.guilds.push(group._id);
|
nonLeader.guilds.push(group._id);
|
||||||
return await nonLeader.save();
|
return nonLeader.save();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import { model as User } from '../../../../../website/server/models/user';
|
|||||||
import { translate as t } from '../../../../helpers/api-integration/v3';
|
import { translate as t } from '../../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../helpers/api-unit.helper.js';
|
} from '../../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
describe('payments/index', () => {
|
describe('payments/index', () => {
|
||||||
let user, group, data, plan;
|
let user; let group; let data; let
|
||||||
|
plan;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -102,7 +103,7 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not set negative extraMonths if plan has past dateTerminated date', async () => {
|
it('does not set negative extraMonths if plan has past dateTerminated date', async () => {
|
||||||
let dateTerminated = moment().subtract(2, 'months').toDate();
|
const dateTerminated = moment().subtract(2, 'months').toDate();
|
||||||
recipient.purchased.plan.dateTerminated = dateTerminated;
|
recipient.purchased.plan.dateTerminated = dateTerminated;
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
@@ -120,7 +121,7 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds to date terminated for an existing plan with a future terminated date', async () => {
|
it('adds to date terminated for an existing plan with a future terminated date', async () => {
|
||||||
let dateTerminated = moment().add(1, 'months').toDate();
|
const dateTerminated = moment().add(1, 'months').toDate();
|
||||||
recipient.purchased.plan = plan;
|
recipient.purchased.plan = plan;
|
||||||
recipient.purchased.plan.dateTerminated = dateTerminated;
|
recipient.purchased.plan.dateTerminated = dateTerminated;
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('replaces date terminated for an account with a past terminated date', async () => {
|
it('replaces date terminated for an account with a past terminated date', async () => {
|
||||||
let dateTerminated = moment().subtract(1, 'months').toDate();
|
const dateTerminated = moment().subtract(1, 'months').toDate();
|
||||||
recipient.purchased.plan.dateTerminated = dateTerminated;
|
recipient.purchased.plan.dateTerminated = dateTerminated;
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
@@ -208,18 +209,21 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
it('sends a private message about the gift', async () => {
|
it('sends a private message about the gift', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
let msg = '\`Hello recipient, sender has sent you 3 months of subscription!\`';
|
const msg = '`Hello recipient, sender has sent you 3 months of subscription!`';
|
||||||
|
|
||||||
expect(user.sendMessage).to.be.calledOnce;
|
expect(user.sendMessage).to.be.calledOnce;
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
|
expect(user.sendMessage).to.be.calledWith(
|
||||||
|
recipient,
|
||||||
|
{ receiverMsg: msg, senderMsg: msg, save: false },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends an email about the gift', async () => {
|
it('sends an email about the gift', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
expect(sender.sendTxn).to.be.calledWith(recipient, 'gifted-subscription', [
|
expect(sender.sendTxn).to.be.calledWith(recipient, 'gifted-subscription', [
|
||||||
{name: 'GIFTER', content: 'sender'},
|
{ name: 'GIFTER', content: 'sender' },
|
||||||
{name: 'X_MONTHS_SUBSCRIPTION', content: 3},
|
{ name: 'X_MONTHS_SUBSCRIPTION', content: 3 },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -416,8 +420,8 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
context('Mystery Items', () => {
|
context('Mystery Items', () => {
|
||||||
it('awards mystery items when within the timeframe for a mystery item', async () => {
|
it('awards mystery items when within the timeframe for a mystery item', async () => {
|
||||||
let mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
const mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
||||||
let fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
const fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
||||||
|
|
||||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||||
|
|
||||||
@@ -437,7 +441,7 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
it('does not awards mystery items when not within the timeframe for a mystery item', async () => {
|
it('does not awards mystery items when not within the timeframe for a mystery item', async () => {
|
||||||
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
||||||
let fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
const fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
||||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
@@ -449,7 +453,7 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
it('does not add a notification for mystery items if none was awarded', async () => {
|
it('does not add a notification for mystery items if none was awarded', async () => {
|
||||||
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
||||||
let fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
const fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
||||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
@@ -461,9 +465,9 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not award mystery item when user already owns the item', async () => {
|
it('does not award mystery item when user already owns the item', async () => {
|
||||||
let mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
const mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
||||||
let fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
const fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
||||||
let mayMysteryItem = 'armor_mystery_201605';
|
const mayMysteryItem = 'armor_mystery_201605';
|
||||||
user.items.gear.owned[mayMysteryItem] = true;
|
user.items.gear.owned[mayMysteryItem] = true;
|
||||||
|
|
||||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||||
@@ -477,9 +481,9 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not award mystery item when user already has the item in the mystery box', async () => {
|
it('does not award mystery item when user already has the item in the mystery box', async () => {
|
||||||
let mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
const mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
||||||
let fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
const fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
||||||
let mayMysteryItem = 'armor_mystery_201605';
|
const mayMysteryItem = 'armor_mystery_201605';
|
||||||
user.purchased.plan.mysteryItems = [mayMysteryItem];
|
user.purchased.plan.mysteryItems = [mayMysteryItem];
|
||||||
|
|
||||||
sandbox.spy(user.purchased.plan.mysteryItems, 'push');
|
sandbox.spy(user.purchased.plan.mysteryItems, 'push');
|
||||||
@@ -504,8 +508,8 @@ describe('payments/index', () => {
|
|||||||
it('adds a month termination date by default', async () => {
|
it('adds a month termination date by default', async () => {
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
|
expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
|
||||||
});
|
});
|
||||||
@@ -515,8 +519,8 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
|
expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
|
||||||
});
|
});
|
||||||
@@ -526,8 +530,8 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
|
expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
|
||||||
});
|
});
|
||||||
@@ -537,8 +541,8 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(13, 15);
|
expect(daysTillTermination).to.be.within(13, 15);
|
||||||
});
|
});
|
||||||
@@ -549,8 +553,8 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
await api.cancelSubscription(data);
|
await api.cancelSubscription(data);
|
||||||
|
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
|
||||||
|
|
||||||
expect(daysTillTermination).to.be.within(13, 15);
|
expect(daysTillTermination).to.be.within(13, 15);
|
||||||
});
|
});
|
||||||
@@ -641,9 +645,10 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
it('sends a message from purchaser to recipient', async () => {
|
it('sends a message from purchaser to recipient', async () => {
|
||||||
await api.buyGems(data);
|
await api.buyGems(data);
|
||||||
let msg = '\`Hello recipient, sender has sent you 4 gems!\`';
|
const msg = '`Hello recipient, sender has sent you 4 gems!`';
|
||||||
|
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
|
expect(user.sendMessage).to.be
|
||||||
|
.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends a message from purchaser to recipient wtih custom message', async () => {
|
it('sends a message from purchaser to recipient wtih custom message', async () => {
|
||||||
@@ -652,7 +657,8 @@ describe('payments/index', () => {
|
|||||||
await api.buyGems(data);
|
await api.buyGems(data);
|
||||||
|
|
||||||
const msg = `\`Hello recipient, sender has sent you 4 gems!\` ${data.gift.message}`;
|
const msg = `\`Hello recipient, sender has sent you 4 gems!\` ${data.gift.message}`;
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
|
expect(user.sendMessage).to.be
|
||||||
|
.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends a push notification if user did not gift to self', async () => {
|
it('sends a push notification if user did not gift to self', async () => {
|
||||||
@@ -671,8 +677,8 @@ describe('payments/index', () => {
|
|||||||
});
|
});
|
||||||
await api.buyGems(data);
|
await api.buyGems(data);
|
||||||
|
|
||||||
let [recipientsMessageContent, sendersMessageContent] = ['en', 'en'].map((lang) => {
|
const [recipientsMessageContent, sendersMessageContent] = ['en', 'en'].map(lang => {
|
||||||
let messageContent = t('giftedGemsFull', {
|
const messageContent = t('giftedGemsFull', {
|
||||||
username: recipient.profile.name,
|
username: recipient.profile.name,
|
||||||
sender: user.profile.name,
|
sender: user.profile.name,
|
||||||
gemAmount: data.gift.gems.amount,
|
gemAmount: data.gift.gems.amount,
|
||||||
@@ -681,7 +687,10 @@ describe('payments/index', () => {
|
|||||||
return `\`${messageContent}\``;
|
return `\`${messageContent}\``;
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: recipientsMessageContent, senderMsg: sendersMessageContent, save: false });
|
expect(user.sendMessage).to.be.calledWith(
|
||||||
|
recipient,
|
||||||
|
{ receiverMsg: recipientsMessageContent, senderMsg: sendersMessageContent, save: false },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -693,7 +702,7 @@ describe('payments/index', () => {
|
|||||||
|
|
||||||
await api.addSubToGroupUser(user, group);
|
await api.addSubToGroupUser(user, group);
|
||||||
|
|
||||||
let updatedUser = await User.findById(user._id).exec();
|
const updatedUser = await User.findById(user._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
|
||||||
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
|
||||||
@@ -709,17 +718,17 @@ describe('payments/index', () => {
|
|||||||
it('awards the Royal Purple Jackalope pet', async () => {
|
it('awards the Royal Purple Jackalope pet', async () => {
|
||||||
await api.addSubToGroupUser(user, group);
|
await api.addSubToGroupUser(user, group);
|
||||||
|
|
||||||
let updatedUser = await User.findById(user._id).exec();
|
const updatedUser = await User.findById(user._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.items.pets['Jackalope-RoyalPurple']).to.eql(5);
|
expect(updatedUser.items.pets['Jackalope-RoyalPurple']).to.eql(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('saves previously unused Mystery Items and Hourglasses for an expired subscription', async () => {
|
it('saves previously unused Mystery Items and Hourglasses for an expired subscription', async () => {
|
||||||
let planExpirationDate = new Date();
|
const planExpirationDate = new Date();
|
||||||
planExpirationDate.setDate(planExpirationDate.getDate() - 2);
|
planExpirationDate.setDate(planExpirationDate.getDate() - 2);
|
||||||
let mysteryItem = 'item';
|
const mysteryItem = 'item';
|
||||||
let mysteryItems = [mysteryItem];
|
const mysteryItems = [mysteryItem];
|
||||||
let consecutive = {
|
const consecutive = {
|
||||||
trinkets: 3,
|
trinkets: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -735,7 +744,7 @@ describe('payments/index', () => {
|
|||||||
await user.save();
|
await user.save();
|
||||||
await api.addSubToGroupUser(user, group);
|
await api.addSubToGroupUser(user, group);
|
||||||
|
|
||||||
let updatedUser = await User.findById(user._id).exec();
|
const updatedUser = await User.findById(user._id).exec();
|
||||||
|
|
||||||
expect(updatedUser.purchased.plan.mysteryItems[0]).to.eql(mysteryItem);
|
expect(updatedUser.purchased.plan.mysteryItems[0]).to.eql(mysteryItem);
|
||||||
expect(updatedUser.purchased.plan.consecutive.trinkets).to.equal(consecutive.trinkets);
|
expect(updatedUser.purchased.plan.consecutive.trinkets).to.equal(consecutive.trinkets);
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import { model as User } from '../../../../../../website/server/models/user';
|
|||||||
|
|
||||||
describe('checkout success', () => {
|
describe('checkout success', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, gift, customerId, paymentId;
|
let user; let gift; let customerId; let
|
||||||
let paypalPaymentExecuteStub, paymentBuyGemsStub, paymentsCreateSubscritionStub;
|
paymentId;
|
||||||
|
let paypalPaymentExecuteStub; let paymentBuyGemsStub; let
|
||||||
|
paymentsCreateSubscritionStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -25,7 +27,9 @@ describe('checkout success', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('purchases gems', async () => {
|
it('purchases gems', async () => {
|
||||||
await paypalPayments.checkoutSuccess({user, gift, paymentId, customerId});
|
await paypalPayments.checkoutSuccess({
|
||||||
|
user, gift, paymentId, customerId,
|
||||||
|
});
|
||||||
|
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
||||||
@@ -38,7 +42,7 @@ describe('checkout success', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('gifts gems', async () => {
|
it('gifts gems', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
await receivingUser.save();
|
await receivingUser.save();
|
||||||
gift = {
|
gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
@@ -48,7 +52,9 @@ describe('checkout success', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await paypalPayments.checkoutSuccess({user, gift, paymentId, customerId});
|
await paypalPayments.checkoutSuccess({
|
||||||
|
user, gift, paymentId, customerId,
|
||||||
|
});
|
||||||
|
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
||||||
@@ -62,7 +68,7 @@ describe('checkout success', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('gifts subscription', async () => {
|
it('gifts subscription', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
await receivingUser.save();
|
await receivingUser.save();
|
||||||
gift = {
|
gift = {
|
||||||
type: 'subscription',
|
type: 'subscription',
|
||||||
@@ -72,7 +78,9 @@ describe('checkout success', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await paypalPayments.checkoutSuccess({user, gift, paymentId, customerId});
|
await paypalPayments.checkoutSuccess({
|
||||||
|
user, gift, paymentId, customerId,
|
||||||
|
});
|
||||||
|
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
expect(paypalPaymentExecuteStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
expect(paypalPaymentExecuteStub).to.be.calledWith(paymentId, { payer_id: customerId });
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { model as User } from '../../../../../../website/server/models/user';
|
|||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const BASE_URL = nconf.get('BASE_URL');
|
const BASE_URL = nconf.get('BASE_URL');
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('checkout', () => {
|
describe('checkout', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
@@ -53,7 +53,7 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a link for gem purchases', async () => {
|
it('creates a link for gem purchases', async () => {
|
||||||
let link = await paypalPayments.checkout({user: new User()});
|
const link = await paypalPayments.checkout({ user: new User() });
|
||||||
|
|
||||||
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems', 5.00));
|
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems', 5.00));
|
||||||
@@ -61,9 +61,9 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error if gem amount is too low', async () => {
|
it('should error if gem amount is too low', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
gems: {
|
gems: {
|
||||||
amount: 0,
|
amount: 0,
|
||||||
@@ -71,7 +71,7 @@ describe('checkout', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(paypalPayments.checkout({gift}))
|
await expect(paypalPayments.checkout({ gift }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 400,
|
httpCode: 400,
|
||||||
message: 'Amount must be at least 1.',
|
message: 'Amount must be at least 1.',
|
||||||
@@ -80,10 +80,10 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error if the user cannot get gems', async () => {
|
it('should error if the user cannot get gems', async () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
sinon.stub(user, 'canGetGems').resolves(false);
|
sinon.stub(user, 'canGetGems').resolves(false);
|
||||||
|
|
||||||
await expect(paypalPayments.checkout({user})).to.eventually.be.rejected.and.to.eql({
|
await expect(paypalPayments.checkout({ user })).to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
message: i18n.t('groupPolicyCannotGetGems'),
|
message: i18n.t('groupPolicyCannotGetGems'),
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -91,9 +91,9 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a link for gifting gems', async () => {
|
it('creates a link for gifting gems', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
await receivingUser.save();
|
await receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
uuid: receivingUser._id,
|
uuid: receivingUser._id,
|
||||||
gems: {
|
gems: {
|
||||||
@@ -101,7 +101,7 @@ describe('checkout', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let link = await paypalPayments.checkout({gift});
|
const link = await paypalPayments.checkout({ gift });
|
||||||
|
|
||||||
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems (Gift)', '4.00'));
|
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems (Gift)', '4.00'));
|
||||||
@@ -109,9 +109,9 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a link for gifting a subscription', async () => {
|
it('creates a link for gifting a subscription', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
let gift = {
|
const gift = {
|
||||||
type: 'subscription',
|
type: 'subscription',
|
||||||
subscription: {
|
subscription: {
|
||||||
key: subKey,
|
key: subKey,
|
||||||
@@ -119,7 +119,7 @@ describe('checkout', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let link = await paypalPayments.checkout({gift});
|
const link = await paypalPayments.checkout({ gift });
|
||||||
|
|
||||||
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
expect(paypalPaymentCreateStub).to.be.calledOnce;
|
||||||
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('mo. Habitica Subscription (Gift)', '15.00'));
|
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('mo. Habitica Subscription (Gift)', '15.00'));
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ import paypalPayments from '../../../../../../website/server/libs/payments/paypa
|
|||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
|
|
||||||
describe('ipn', () => {
|
describe('ipn', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, group, txn_type, userPaymentId, groupPaymentId;
|
let user; let group; let txn_type; let userPaymentId; let
|
||||||
let ipnVerifyAsyncStub, paymentCancelSubscriptionSpy;
|
groupPaymentId;
|
||||||
|
let ipnVerifyAsyncStub; let
|
||||||
|
paymentCancelSubscriptionSpy;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
txn_type = 'recurring_payment_profile_cancel';
|
txn_type = 'recurring_payment_profile_cancel';
|
||||||
@@ -38,16 +40,16 @@ describe('ipn', () => {
|
|||||||
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
paypalPayments.ipnVerifyAsync.restore();
|
paypalPayments.ipnVerifyAsync.restore();
|
||||||
payments.cancelSubscription.restore();
|
payments.cancelSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should cancel a user subscription', async () => {
|
it('should cancel a user subscription', async () => {
|
||||||
await paypalPayments.ipn({txn_type, recurring_payment_id: userPaymentId});
|
await paypalPayments.ipn({ txn_type, recurring_payment_id: userPaymentId });
|
||||||
|
|
||||||
expect(ipnVerifyAsyncStub).to.be.calledOnce;
|
expect(ipnVerifyAsyncStub).to.be.calledOnce;
|
||||||
expect(ipnVerifyAsyncStub).to.be.calledWith({txn_type, recurring_payment_id: userPaymentId});
|
expect(ipnVerifyAsyncStub).to.be.calledWith({ txn_type, recurring_payment_id: userPaymentId });
|
||||||
|
|
||||||
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
||||||
expect(paymentCancelSubscriptionSpy.args[0][0].user._id).to.eql(user._id);
|
expect(paymentCancelSubscriptionSpy.args[0][0].user._id).to.eql(user._id);
|
||||||
@@ -55,10 +57,10 @@ describe('ipn', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should cancel a group subscription', async () => {
|
it('should cancel a group subscription', async () => {
|
||||||
await paypalPayments.ipn({txn_type, recurring_payment_id: groupPaymentId});
|
await paypalPayments.ipn({ txn_type, recurring_payment_id: groupPaymentId });
|
||||||
|
|
||||||
expect(ipnVerifyAsyncStub).to.be.calledOnce;
|
expect(ipnVerifyAsyncStub).to.be.calledOnce;
|
||||||
expect(ipnVerifyAsyncStub).to.be.calledWith({txn_type, recurring_payment_id: groupPaymentId});
|
expect(ipnVerifyAsyncStub).to.be.calledWith({ txn_type, recurring_payment_id: groupPaymentId });
|
||||||
|
|
||||||
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
||||||
expect(paymentCancelSubscriptionSpy).to.be.calledWith({ groupId: group._id, paymentMethod: 'Paypal' });
|
expect(paymentCancelSubscriptionSpy).to.be.calledWith({ groupId: group._id, paymentMethod: 'Paypal' });
|
||||||
|
|||||||
@@ -3,17 +3,19 @@ import paypalPayments from '../../../../../../website/server/libs/payments/paypa
|
|||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
import { createNonLeaderGroupMember } from '../paymentHelpers';
|
import { createNonLeaderGroupMember } from '../paymentHelpers';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('subscribeCancel', () => {
|
describe('subscribeCancel', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, group, groupId, customerId, groupCustomerId, nextBillingDate;
|
let user; let group; let groupId; let customerId; let groupCustomerId; let
|
||||||
let paymentCancelSubscriptionSpy, paypalBillingAgreementCancelStub, paypalBillingAgreementGetStub;
|
nextBillingDate;
|
||||||
|
let paymentCancelSubscriptionSpy; let paypalBillingAgreementCancelStub; let
|
||||||
|
paypalBillingAgreementGetStub;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
customerId = 'customer-id';
|
customerId = 'customer-id';
|
||||||
@@ -49,7 +51,7 @@ describe('subscribeCancel', () => {
|
|||||||
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
paymentCancelSubscriptionSpy = sinon.stub(payments, 'cancelSubscription').resolves({});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
paypalPayments.paypalBillingAgreementGet.restore();
|
paypalPayments.paypalBillingAgreementGet.restore();
|
||||||
paypalPayments.paypalBillingAgreementCancel.restore();
|
paypalPayments.paypalBillingAgreementCancel.restore();
|
||||||
payments.cancelSubscription.restore();
|
payments.cancelSubscription.restore();
|
||||||
@@ -58,7 +60,7 @@ describe('subscribeCancel', () => {
|
|||||||
it('should throw an error if we are missing a subscription', async () => {
|
it('should throw an error if we are missing a subscription', async () => {
|
||||||
user.purchased.plan.customerId = undefined;
|
user.purchased.plan.customerId = undefined;
|
||||||
|
|
||||||
await expect(paypalPayments.subscribeCancel({user}))
|
await expect(paypalPayments.subscribeCancel({ user }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -67,7 +69,7 @@ describe('subscribeCancel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if group is not found', async () => {
|
it('should throw an error if group is not found', async () => {
|
||||||
await expect(paypalPayments.subscribeCancel({user, groupId: 'fake-id'}))
|
await expect(paypalPayments.subscribeCancel({ user, groupId: 'fake-id' }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 404,
|
httpCode: 404,
|
||||||
name: 'NotFound',
|
name: 'NotFound',
|
||||||
@@ -76,9 +78,9 @@ describe('subscribeCancel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if user is not group leader', async () => {
|
it('should throw an error if user is not group leader', async () => {
|
||||||
let nonLeader = await createNonLeaderGroupMember(group);
|
const nonLeader = await createNonLeaderGroupMember(group);
|
||||||
|
|
||||||
await expect(paypalPayments.subscribeCancel({user: nonLeader, groupId: group._id}))
|
await expect(paypalPayments.subscribeCancel({ user: nonLeader, groupId: group._id }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -87,7 +89,7 @@ describe('subscribeCancel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should cancel a user subscription', async () => {
|
it('should cancel a user subscription', async () => {
|
||||||
await paypalPayments.subscribeCancel({user});
|
await paypalPayments.subscribeCancel({ user });
|
||||||
|
|
||||||
expect(paypalBillingAgreementGetStub).to.be.calledOnce;
|
expect(paypalBillingAgreementGetStub).to.be.calledOnce;
|
||||||
expect(paypalBillingAgreementGetStub).to.be.calledWith(customerId);
|
expect(paypalBillingAgreementGetStub).to.be.calledWith(customerId);
|
||||||
@@ -105,7 +107,7 @@ describe('subscribeCancel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should cancel a group subscription', async () => {
|
it('should cancel a group subscription', async () => {
|
||||||
await paypalPayments.subscribeCancel({user, groupId: group._id});
|
await paypalPayments.subscribeCancel({ user, groupId: group._id });
|
||||||
|
|
||||||
expect(paypalBillingAgreementGetStub).to.be.calledOnce;
|
expect(paypalBillingAgreementGetStub).to.be.calledOnce;
|
||||||
expect(paypalBillingAgreementGetStub).to.be.calledWith(groupCustomerId);
|
expect(paypalBillingAgreementGetStub).to.be.calledWith(groupCustomerId);
|
||||||
|
|||||||
@@ -3,14 +3,16 @@ import paypalPayments from '../../../../../../website/server/libs/payments/paypa
|
|||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
describe('subscribeSuccess', () => {
|
describe('subscribeSuccess', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let user, group, block, groupId, token, headers, customerId;
|
let user; let group; let block; let groupId; let token; let headers; let
|
||||||
let paypalBillingAgreementExecuteStub, paymentsCreateSubscritionStub;
|
customerId;
|
||||||
|
let paypalBillingAgreementExecuteStub; let
|
||||||
|
paymentsCreateSubscritionStub;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -40,7 +42,9 @@ describe('subscribeSuccess', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a user subscription', async () => {
|
it('creates a user subscription', async () => {
|
||||||
await paypalPayments.subscribeSuccess({user, block, groupId, token, headers});
|
await paypalPayments.subscribeSuccess({
|
||||||
|
user, block, groupId, token, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expect(paypalBillingAgreementExecuteStub).to.be.calledOnce;
|
expect(paypalBillingAgreementExecuteStub).to.be.calledOnce;
|
||||||
expect(paypalBillingAgreementExecuteStub).to.be.calledWith(token, {});
|
expect(paypalBillingAgreementExecuteStub).to.be.calledWith(token, {});
|
||||||
@@ -59,7 +63,9 @@ describe('subscribeSuccess', () => {
|
|||||||
it('create a group subscription', async () => {
|
it('create a group subscription', async () => {
|
||||||
groupId = group._id;
|
groupId = group._id;
|
||||||
|
|
||||||
await paypalPayments.subscribeSuccess({user, block, groupId, token, headers});
|
await paypalPayments.subscribeSuccess({
|
||||||
|
user, block, groupId, token, headers,
|
||||||
|
});
|
||||||
|
|
||||||
expect(paypalBillingAgreementExecuteStub).to.be.calledOnce;
|
expect(paypalBillingAgreementExecuteStub).to.be.calledOnce;
|
||||||
expect(paypalBillingAgreementExecuteStub).to.be.calledWith(token, {});
|
expect(paypalBillingAgreementExecuteStub).to.be.calledWith(token, {});
|
||||||
|
|||||||
@@ -6,16 +6,17 @@ import paypalPayments from '../../../../../../website/server/libs/payments/paypa
|
|||||||
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('subscribe', () => {
|
describe('subscribe', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
let coupon, sub, approvalHerf;
|
let coupon; let sub; let
|
||||||
|
approvalHerf;
|
||||||
let paypalBillingAgreementCreateStub;
|
let paypalBillingAgreementCreateStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
approvalHerf = 'approvalHerf-test';
|
approvalHerf = 'approvalHerf-test';
|
||||||
sub = Object.assign({}, common.content.subscriptionBlocks[subKey]);
|
sub = { ...common.content.subscriptionBlocks[subKey] };
|
||||||
|
|
||||||
paypalBillingAgreementCreateStub = sinon.stub(paypalPayments, 'paypalBillingAgreementCreate')
|
paypalBillingAgreementCreateStub = sinon.stub(paypalPayments, 'paypalBillingAgreementCreate')
|
||||||
.resolves({
|
.resolves({
|
||||||
@@ -30,7 +31,7 @@ describe('subscribe', () => {
|
|||||||
it('should throw an error when coupon code is missing', async () => {
|
it('should throw an error when coupon code is missing', async () => {
|
||||||
sub.discount = 40;
|
sub.discount = 40;
|
||||||
|
|
||||||
await expect(paypalPayments.subscribe({sub, coupon}))
|
await expect(paypalPayments.subscribe({ sub, coupon }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 400,
|
httpCode: 400,
|
||||||
name: 'BadRequest',
|
name: 'BadRequest',
|
||||||
@@ -43,13 +44,13 @@ describe('subscribe', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
await couponModel.save();
|
await couponModel.save();
|
||||||
|
|
||||||
sinon.stub(cc, 'validate').returns('invalid');
|
sinon.stub(cc, 'validate').returns('invalid');
|
||||||
|
|
||||||
await expect(paypalPayments.subscribe({sub, coupon}))
|
await expect(paypalPayments.subscribe({ sub, coupon }))
|
||||||
.to.eventually.be.rejected.and.to.eql({
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
httpCode: 401,
|
httpCode: 401,
|
||||||
name: 'NotAuthorized',
|
name: 'NotAuthorized',
|
||||||
@@ -63,17 +64,17 @@ describe('subscribe', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
let updatedCouponModel = await couponModel.save();
|
const updatedCouponModel = await couponModel.save();
|
||||||
|
|
||||||
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
||||||
|
|
||||||
let link = await paypalPayments.subscribe({sub, coupon});
|
const link = await paypalPayments.subscribe({ sub, coupon });
|
||||||
|
|
||||||
expect(link).to.eql(approvalHerf);
|
expect(link).to.eql(approvalHerf);
|
||||||
expect(paypalBillingAgreementCreateStub).to.be.calledOnce;
|
expect(paypalBillingAgreementCreateStub).to.be.calledOnce;
|
||||||
let billingPlanTitle = `Habitica Subscription ($${sub.price} every ${sub.months} months, recurring)`;
|
const billingPlanTitle = `Habitica Subscription ($${sub.price} every ${sub.months} months, recurring)`;
|
||||||
expect(paypalBillingAgreementCreateStub).to.be.calledWith({
|
expect(paypalBillingAgreementCreateStub).to.be.calledWith({
|
||||||
name: billingPlanTitle,
|
name: billingPlanTitle,
|
||||||
description: billingPlanTitle,
|
description: billingPlanTitle,
|
||||||
@@ -92,11 +93,11 @@ describe('subscribe', () => {
|
|||||||
it('creates a link for a subscription', async () => {
|
it('creates a link for a subscription', async () => {
|
||||||
delete sub.discount;
|
delete sub.discount;
|
||||||
|
|
||||||
let link = await paypalPayments.subscribe({sub, coupon});
|
const link = await paypalPayments.subscribe({ sub, coupon });
|
||||||
|
|
||||||
expect(link).to.eql(approvalHerf);
|
expect(link).to.eql(approvalHerf);
|
||||||
expect(paypalBillingAgreementCreateStub).to.be.calledOnce;
|
expect(paypalBillingAgreementCreateStub).to.be.calledOnce;
|
||||||
let billingPlanTitle = `Habitica Subscription ($${sub.price} every ${sub.months} months, recurring)`;
|
const billingPlanTitle = `Habitica Subscription ($${sub.price} every ${sub.months} months, recurring)`;
|
||||||
expect(paypalBillingAgreementCreateStub).to.be.calledWith({
|
expect(paypalBillingAgreementCreateStub).to.be.calledWith({
|
||||||
name: billingPlanTitle,
|
name: billingPlanTitle,
|
||||||
description: billingPlanTitle,
|
description: billingPlanTitle,
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('cancel subscription', () => {
|
describe('cancel subscription', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
let user, groupId, group;
|
let user; let groupId; let
|
||||||
|
group;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -62,7 +63,7 @@ describe('cancel subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws an error if user is not the group leader', async () => {
|
it('throws an error if user is not the group leader', async () => {
|
||||||
let nonLeader = new User();
|
const nonLeader = new User();
|
||||||
nonLeader.guilds.push(groupId);
|
nonLeader.guilds.push(groupId);
|
||||||
await nonLeader.save();
|
await nonLeader.save();
|
||||||
|
|
||||||
@@ -78,7 +79,9 @@ describe('cancel subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('success', () => {
|
describe('success', () => {
|
||||||
let stripeDeleteCustomerStub, paymentsCancelSubStub, stripeRetrieveStub, subscriptionId, currentPeriodEndTimeStamp;
|
let stripeDeleteCustomerStub; let paymentsCancelSubStub;
|
||||||
|
let stripeRetrieveStub; let subscriptionId; let
|
||||||
|
currentPeriodEndTimeStamp;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
subscriptionId = 'subId';
|
subscriptionId = 'subId';
|
||||||
@@ -89,7 +92,10 @@ describe('cancel subscription', () => {
|
|||||||
stripeRetrieveStub = sinon.stub(stripe.customers, 'retrieve')
|
stripeRetrieveStub = sinon.stub(stripe.customers, 'retrieve')
|
||||||
.resolves({
|
.resolves({
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
data: [{id: subscriptionId, current_period_end: currentPeriodEndTimeStamp}], // eslint-disable-line camelcase
|
data: [{
|
||||||
|
id: subscriptionId,
|
||||||
|
current_period_end: currentPeriodEndTimeStamp,
|
||||||
|
}], // eslint-disable-line camelcase
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,19 +3,22 @@ import cc from 'coupon-code';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
import { model as Coupon } from '../../../../../../website/server/models/coupon';
|
||||||
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('checkout with subscription', () => {
|
describe('checkout with subscription', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
let user, group, data, gift, sub, groupId, email, headers, coupon, customerIdResponse, subscriptionId, token;
|
let user; let group; let data; let gift; let sub;
|
||||||
|
let groupId; let email; let headers; let coupon;
|
||||||
|
let customerIdResponse; let subscriptionId; let
|
||||||
|
token;
|
||||||
let spy;
|
let spy;
|
||||||
let stripeCreateCustomerSpy;
|
let stripeCreateCustomerSpy;
|
||||||
let stripePaymentsCreateSubSpy;
|
let stripePaymentsCreateSubSpy;
|
||||||
@@ -57,10 +60,10 @@ describe('checkout with subscription', () => {
|
|||||||
spy.resolves;
|
spy.resolves;
|
||||||
|
|
||||||
stripeCreateCustomerSpy = sinon.stub(stripe.customers, 'create');
|
stripeCreateCustomerSpy = sinon.stub(stripe.customers, 'create');
|
||||||
let stripCustomerResponse = {
|
const stripCustomerResponse = {
|
||||||
id: customerIdResponse,
|
id: customerIdResponse,
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
data: [{id: subscriptionId}],
|
data: [{ id: subscriptionId }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
stripeCreateCustomerSpy.resolves(stripCustomerResponse);
|
stripeCreateCustomerSpy.resolves(stripCustomerResponse);
|
||||||
@@ -72,7 +75,7 @@ describe('checkout with subscription', () => {
|
|||||||
data.sub.quantity = 3;
|
data.sub.quantity = 3;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
stripe.subscriptions.update.restore();
|
stripe.subscriptions.update.restore();
|
||||||
stripe.customers.create.restore();
|
stripe.customers.create.restore();
|
||||||
payments.createSubscription.restore();
|
payments.createSubscription.restore();
|
||||||
@@ -120,7 +123,7 @@ describe('checkout with subscription', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
await couponModel.save();
|
await couponModel.save();
|
||||||
|
|
||||||
@@ -149,9 +152,9 @@ describe('checkout with subscription', () => {
|
|||||||
sub.key = 'google_6mo';
|
sub.key = 'google_6mo';
|
||||||
coupon = 'example-coupon';
|
coupon = 'example-coupon';
|
||||||
|
|
||||||
let couponModel = new Coupon();
|
const couponModel = new Coupon();
|
||||||
couponModel.event = 'google_6mo';
|
couponModel.event = 'google_6mo';
|
||||||
let updatedCouponModel = await couponModel.save();
|
const updatedCouponModel = await couponModel.save();
|
||||||
|
|
||||||
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
sinon.stub(cc, 'validate').returns(updatedCouponModel._id);
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ import stripePayments from '../../../../../../website/server/libs/payments/strip
|
|||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('checkout', () => {
|
describe('checkout', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
let stripeChargeStub, paymentBuyGemsStub, paymentCreateSubscritionStub;
|
let stripeChargeStub; let paymentBuyGemsStub; let
|
||||||
let user, gift, groupId, email, headers, coupon, customerIdResponse, token;
|
paymentCreateSubscritionStub;
|
||||||
|
let user; let gift; let groupId; let email; let headers; let coupon; let customerIdResponse; let
|
||||||
|
token;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -23,7 +25,7 @@ describe('checkout', () => {
|
|||||||
token = 'test-token';
|
token = 'test-token';
|
||||||
|
|
||||||
customerIdResponse = 'example-customerIdResponse';
|
customerIdResponse = 'example-customerIdResponse';
|
||||||
let stripCustomerResponse = {
|
const stripCustomerResponse = {
|
||||||
id: customerIdResponse,
|
id: customerIdResponse,
|
||||||
};
|
};
|
||||||
stripeChargeStub = sinon.stub(stripe.charges, 'create').resolves(stripCustomerResponse);
|
stripeChargeStub = sinon.stub(stripe.charges, 'create').resolves(stripCustomerResponse);
|
||||||
@@ -54,7 +56,7 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error if gem amount is too low', async () => {
|
it('should error if gem amount is too low', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
gift = {
|
gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
@@ -132,7 +134,7 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should gift gems', async () => {
|
it('should gift gems', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
await receivingUser.save();
|
await receivingUser.save();
|
||||||
gift = {
|
gift = {
|
||||||
type: 'gems',
|
type: 'gems',
|
||||||
@@ -169,7 +171,7 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should gift a subscription', async () => {
|
it('should gift a subscription', async () => {
|
||||||
let receivingUser = new User();
|
const receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
gift = {
|
gift = {
|
||||||
type: 'subscription',
|
type: 'subscription',
|
||||||
|
|||||||
@@ -2,17 +2,18 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('edit subscription', () => {
|
describe('edit subscription', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
let user, groupId, group, token;
|
let user; let groupId; let group; let
|
||||||
|
token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -76,7 +77,7 @@ describe('edit subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws an error if user is not the group leader', async () => {
|
it('throws an error if user is not the group leader', async () => {
|
||||||
let nonLeader = new User();
|
const nonLeader = new User();
|
||||||
nonLeader.guilds.push(groupId);
|
nonLeader.guilds.push(groupId);
|
||||||
await nonLeader.save();
|
await nonLeader.save();
|
||||||
|
|
||||||
@@ -93,13 +94,14 @@ describe('edit subscription', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('success', () => {
|
describe('success', () => {
|
||||||
let stripeListSubscriptionStub, stripeUpdateSubscriptionStub, subscriptionId;
|
let stripeListSubscriptionStub; let stripeUpdateSubscriptionStub; let
|
||||||
|
subscriptionId;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
subscriptionId = 'subId';
|
subscriptionId = 'subId';
|
||||||
stripeListSubscriptionStub = sinon.stub(stripe.subscriptions, 'list')
|
stripeListSubscriptionStub = sinon.stub(stripe.subscriptions, 'list')
|
||||||
.resolves({
|
.resolves({
|
||||||
data: [{id: subscriptionId}],
|
data: [{ id: subscriptionId }],
|
||||||
});
|
});
|
||||||
|
|
||||||
stripeUpdateSubscriptionStub = sinon.stub(stripe.subscriptions, 'update').resolves({});
|
stripeUpdateSubscriptionStub = sinon.stub(stripe.subscriptions, 'update').resolves({});
|
||||||
@@ -118,11 +120,13 @@ describe('edit subscription', () => {
|
|||||||
}, stripe);
|
}, stripe);
|
||||||
|
|
||||||
expect(stripeListSubscriptionStub).to.be.calledOnce;
|
expect(stripeListSubscriptionStub).to.be.calledOnce;
|
||||||
expect(stripeListSubscriptionStub).to.be.calledWith({customer: user.purchased.plan.customerId});
|
expect(stripeListSubscriptionStub).to.be.calledWith({
|
||||||
|
customer: user.purchased.plan.customerId,
|
||||||
|
});
|
||||||
expect(stripeUpdateSubscriptionStub).to.be.calledOnce;
|
expect(stripeUpdateSubscriptionStub).to.be.calledOnce;
|
||||||
expect(stripeUpdateSubscriptionStub).to.be.calledWith(
|
expect(stripeUpdateSubscriptionStub).to.be.calledWith(
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
{ card: token }
|
{ card: token },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -134,11 +138,13 @@ describe('edit subscription', () => {
|
|||||||
}, stripe);
|
}, stripe);
|
||||||
|
|
||||||
expect(stripeListSubscriptionStub).to.be.calledOnce;
|
expect(stripeListSubscriptionStub).to.be.calledOnce;
|
||||||
expect(stripeListSubscriptionStub).to.be.calledWith({customer: group.purchased.plan.customerId});
|
expect(stripeListSubscriptionStub).to.be.calledWith({
|
||||||
|
customer: group.purchased.plan.customerId,
|
||||||
|
});
|
||||||
expect(stripeUpdateSubscriptionStub).to.be.calledOnce;
|
expect(stripeUpdateSubscriptionStub).to.be.calledOnce;
|
||||||
expect(stripeUpdateSubscriptionStub).to.be.calledWith(
|
expect(stripeUpdateSubscriptionStub).to.be.calledWith(
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
{ card: token }
|
{ card: token },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
import stripeModule from 'stripe';
|
import stripeModule from 'stripe';
|
||||||
|
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import moment from 'moment';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
import payments from '../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import common from '../../../../../../website/common';
|
import common from '../../../../../../website/common';
|
||||||
import logger from '../../../../../../website/server/libs/logger';
|
import logger from '../../../../../../website/server/libs/logger';
|
||||||
import { v4 as uuid } from 'uuid';
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('Stripe - Webhooks', () => {
|
describe('Stripe - Webhooks', () => {
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
|
|
||||||
describe('all events', () => {
|
describe('all events', () => {
|
||||||
const eventType = 'account.updated';
|
const eventType = 'account.updated';
|
||||||
const event = {id: 123};
|
const event = { id: 123 };
|
||||||
const eventRetrieved = {type: eventType};
|
const eventRetrieved = { type: eventType };
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sinon.stub(stripe.events, 'retrieve').resolves(eventRetrieved);
|
sinon.stub(stripe.events, 'retrieve').resolves(eventRetrieved);
|
||||||
@@ -33,7 +33,7 @@ describe('Stripe - Webhooks', () => {
|
|||||||
|
|
||||||
it('logs an error if an unsupported webhook event is passed', async () => {
|
it('logs an error if an unsupported webhook event is passed', async () => {
|
||||||
const error = new Error(`Missing handler for Stripe webhook ${eventType}`);
|
const error = new Error(`Missing handler for Stripe webhook ${eventType}`);
|
||||||
await stripePayments.handleWebhooks({requestBody: event}, stripe);
|
await stripePayments.handleWebhooks({ requestBody: event }, stripe);
|
||||||
expect(logger.error).to.have.been.calledOnce;
|
expect(logger.error).to.have.been.calledOnce;
|
||||||
|
|
||||||
const calledWith = logger.error.getCall(0).args;
|
const calledWith = logger.error.getCall(0).args;
|
||||||
@@ -42,7 +42,7 @@ describe('Stripe - Webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('retrieves and validates the event from Stripe', async () => {
|
it('retrieves and validates the event from Stripe', async () => {
|
||||||
await stripePayments.handleWebhooks({requestBody: event}, stripe);
|
await stripePayments.handleWebhooks({ requestBody: event }, stripe);
|
||||||
expect(stripe.events.retrieve).to.have.been.calledOnce;
|
expect(stripe.events.retrieve).to.have.been.calledOnce;
|
||||||
expect(stripe.events.retrieve).to.have.been.calledWith(event.id);
|
expect(stripe.events.retrieve).to.have.been.calledWith(event.id);
|
||||||
});
|
});
|
||||||
@@ -68,7 +68,7 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: 123,
|
request: 123,
|
||||||
});
|
});
|
||||||
|
|
||||||
await stripePayments.handleWebhooks({requestBody: {}}, stripe);
|
await stripePayments.handleWebhooks({ requestBody: {} }, stripe);
|
||||||
|
|
||||||
expect(stripe.events.retrieve).to.have.been.calledOnce;
|
expect(stripe.events.retrieve).to.have.been.calledOnce;
|
||||||
expect(stripe.customers.del).to.not.have.been.called;
|
expect(stripe.customers.del).to.not.have.been.called;
|
||||||
@@ -93,11 +93,12 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: null,
|
request: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(stripePayments.handleWebhooks({requestBody: {}}, stripe)).to.eventually.be.rejectedWith({
|
await expect(stripePayments.handleWebhooks({ requestBody: {} }, stripe))
|
||||||
message: i18n.t('userNotFound'),
|
.to.eventually.be.rejectedWith({
|
||||||
httpCode: 404,
|
message: i18n.t('userNotFound'),
|
||||||
name: 'NotFound',
|
httpCode: 404,
|
||||||
});
|
name: 'NotFound',
|
||||||
|
});
|
||||||
|
|
||||||
expect(stripe.customers.del).to.not.have.been.called;
|
expect(stripe.customers.del).to.not.have.been.called;
|
||||||
expect(payments.cancelSubscription).to.not.have.been.called;
|
expect(payments.cancelSubscription).to.not.have.been.called;
|
||||||
@@ -108,7 +109,7 @@ describe('Stripe - Webhooks', () => {
|
|||||||
it('deletes the customer on Stripe and calls payments.cancelSubscription', async () => {
|
it('deletes the customer on Stripe and calls payments.cancelSubscription', async () => {
|
||||||
const customerId = '456';
|
const customerId = '456';
|
||||||
|
|
||||||
let subscriber = new User();
|
const subscriber = new User();
|
||||||
subscriber.purchased.plan.customerId = customerId;
|
subscriber.purchased.plan.customerId = customerId;
|
||||||
subscriber.purchased.plan.paymentMethod = 'Stripe';
|
subscriber.purchased.plan.paymentMethod = 'Stripe';
|
||||||
await subscriber.save();
|
await subscriber.save();
|
||||||
@@ -127,13 +128,13 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: null,
|
request: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await stripePayments.handleWebhooks({requestBody: {}}, stripe);
|
await stripePayments.handleWebhooks({ requestBody: {} }, stripe);
|
||||||
|
|
||||||
expect(stripe.customers.del).to.have.been.calledOnce;
|
expect(stripe.customers.del).to.have.been.calledOnce;
|
||||||
expect(stripe.customers.del).to.have.been.calledWith(customerId);
|
expect(stripe.customers.del).to.have.been.calledWith(customerId);
|
||||||
expect(payments.cancelSubscription).to.have.been.calledOnce;
|
expect(payments.cancelSubscription).to.have.been.calledOnce;
|
||||||
|
|
||||||
let cancelSubscriptionOpts = payments.cancelSubscription.lastCall.args[0];
|
const cancelSubscriptionOpts = payments.cancelSubscription.lastCall.args[0];
|
||||||
expect(cancelSubscriptionOpts.user._id).to.equal(subscriber._id);
|
expect(cancelSubscriptionOpts.user._id).to.equal(subscriber._id);
|
||||||
expect(cancelSubscriptionOpts.paymentMethod).to.equal('Stripe');
|
expect(cancelSubscriptionOpts.paymentMethod).to.equal('Stripe');
|
||||||
expect(Math.round(moment(cancelSubscriptionOpts.nextBill).diff(new Date(), 'days', true))).to.equal(3);
|
expect(Math.round(moment(cancelSubscriptionOpts.nextBill).diff(new Date(), 'days', true))).to.equal(3);
|
||||||
@@ -160,11 +161,12 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: null,
|
request: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(stripePayments.handleWebhooks({requestBody: {}}, stripe)).to.eventually.be.rejectedWith({
|
await expect(stripePayments.handleWebhooks({ requestBody: {} }, stripe))
|
||||||
message: i18n.t('groupNotFound'),
|
.to.eventually.be.rejectedWith({
|
||||||
httpCode: 404,
|
message: i18n.t('groupNotFound'),
|
||||||
name: 'NotFound',
|
httpCode: 404,
|
||||||
});
|
name: 'NotFound',
|
||||||
|
});
|
||||||
|
|
||||||
expect(stripe.customers.del).to.not.have.been.called;
|
expect(stripe.customers.del).to.not.have.been.called;
|
||||||
expect(payments.cancelSubscription).to.not.have.been.called;
|
expect(payments.cancelSubscription).to.not.have.been.called;
|
||||||
@@ -175,7 +177,7 @@ describe('Stripe - Webhooks', () => {
|
|||||||
it('throws an error if the group leader is not found', async () => {
|
it('throws an error if the group leader is not found', async () => {
|
||||||
const customerId = 456;
|
const customerId = 456;
|
||||||
|
|
||||||
let subscriber = generateGroup({
|
const subscriber = generateGroup({
|
||||||
name: 'test group',
|
name: 'test group',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -199,11 +201,12 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: null,
|
request: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(stripePayments.handleWebhooks({requestBody: {}}, stripe)).to.eventually.be.rejectedWith({
|
await expect(stripePayments.handleWebhooks({ requestBody: {} }, stripe))
|
||||||
message: i18n.t('userNotFound'),
|
.to.eventually.be.rejectedWith({
|
||||||
httpCode: 404,
|
message: i18n.t('userNotFound'),
|
||||||
name: 'NotFound',
|
httpCode: 404,
|
||||||
});
|
name: 'NotFound',
|
||||||
|
});
|
||||||
|
|
||||||
expect(stripe.customers.del).to.not.have.been.called;
|
expect(stripe.customers.del).to.not.have.been.called;
|
||||||
expect(payments.cancelSubscription).to.not.have.been.called;
|
expect(payments.cancelSubscription).to.not.have.been.called;
|
||||||
@@ -214,10 +217,10 @@ describe('Stripe - Webhooks', () => {
|
|||||||
it('deletes the customer on Stripe and calls payments.cancelSubscription', async () => {
|
it('deletes the customer on Stripe and calls payments.cancelSubscription', async () => {
|
||||||
const customerId = '456';
|
const customerId = '456';
|
||||||
|
|
||||||
let leader = new User();
|
const leader = new User();
|
||||||
await leader.save();
|
await leader.save();
|
||||||
|
|
||||||
let subscriber = generateGroup({
|
const subscriber = generateGroup({
|
||||||
name: 'test group',
|
name: 'test group',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -241,13 +244,13 @@ describe('Stripe - Webhooks', () => {
|
|||||||
request: null,
|
request: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await stripePayments.handleWebhooks({requestBody: {}}, stripe);
|
await stripePayments.handleWebhooks({ requestBody: {} }, stripe);
|
||||||
|
|
||||||
expect(stripe.customers.del).to.have.been.calledOnce;
|
expect(stripe.customers.del).to.have.been.calledOnce;
|
||||||
expect(stripe.customers.del).to.have.been.calledWith(customerId);
|
expect(stripe.customers.del).to.have.been.calledWith(customerId);
|
||||||
expect(payments.cancelSubscription).to.have.been.calledOnce;
|
expect(payments.cancelSubscription).to.have.been.calledOnce;
|
||||||
|
|
||||||
let cancelSubscriptionOpts = payments.cancelSubscription.lastCall.args[0];
|
const cancelSubscriptionOpts = payments.cancelSubscription.lastCall.args[0];
|
||||||
expect(cancelSubscriptionOpts.user._id).to.equal(leader._id);
|
expect(cancelSubscriptionOpts.user._id).to.equal(leader._id);
|
||||||
expect(cancelSubscriptionOpts.paymentMethod).to.equal('Stripe');
|
expect(cancelSubscriptionOpts.paymentMethod).to.equal('Stripe');
|
||||||
expect(Math.round(moment(cancelSubscriptionOpts.nextBill).diff(new Date(), 'days', true))).to.equal(3);
|
expect(Math.round(moment(cancelSubscriptionOpts.nextBill).diff(new Date(), 'days', true))).to.equal(3);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
import { model as Group } from '../../../../../../website/server/models/group';
|
import { model as Group } from '../../../../../../website/server/models/group';
|
||||||
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
@@ -10,9 +10,10 @@ import payments from '../../../../../../website/server/libs/payments/payments';
|
|||||||
|
|
||||||
describe('Stripe - Upgrade Group Plan', () => {
|
describe('Stripe - Upgrade Group Plan', () => {
|
||||||
const stripe = stripeModule('test');
|
const stripe = stripeModule('test');
|
||||||
let spy, data, user, group;
|
let spy; let data; let user; let
|
||||||
|
group;
|
||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
user.profile.name = 'sender';
|
user.profile.name = 'sender';
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ describe('Stripe - Upgrade Group Plan', () => {
|
|||||||
stripePayments.setStripeApi(stripe);
|
stripePayments.setStripeApi(stripe);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(() => {
|
||||||
stripe.subscriptions.update.restore();
|
stripe.subscriptions.update.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ describe('Stripe - Upgrade Group Plan', () => {
|
|||||||
data.paymentMethod = 'Stripe';
|
data.paymentMethod = 'Stripe';
|
||||||
await payments.createSubscription(data);
|
await payments.createSubscription(data);
|
||||||
|
|
||||||
let updatedGroup = await Group.findById(group._id).exec();
|
const updatedGroup = await Group.findById(group._id).exec();
|
||||||
expect(updatedGroup.purchased.plan.quantity).to.eql(3);
|
expect(updatedGroup.purchased.plan.quantity).to.eql(3);
|
||||||
|
|
||||||
updatedGroup.memberCount += 1;
|
updatedGroup.memberCount += 1;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { preenHistory } from '../../../../website/server/libs/preening';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
||||||
import { generateHistory } from '../../../helpers/api-unit.helper.js';
|
import { preenHistory } from '../../../../website/server/libs/preening';
|
||||||
|
import { generateHistory } from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
describe('preenHistory', () => {
|
describe('preenHistory', () => {
|
||||||
let clock;
|
let clock;
|
||||||
@@ -13,47 +13,47 @@ describe('preenHistory', () => {
|
|||||||
toFake: ['Date'],
|
toFake: ['Date'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => clock.restore());
|
||||||
return clock.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not modify history if all entries are more recent than cutoff (free users)', () => {
|
it('does not modify history if all entries are more recent than cutoff (free users)', () => {
|
||||||
let h = generateHistory(60);
|
const h = generateHistory(60);
|
||||||
expect(preenHistory(_.cloneDeep(h), false, 0)).to.eql(h);
|
expect(preenHistory(_.cloneDeep(h), false, 0)).to.eql(h);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not modify history if all entries are more recent than cutoff (subscribers)', () => {
|
it('does not modify history if all entries are more recent than cutoff (subscribers)', () => {
|
||||||
let h = generateHistory(365);
|
const h = generateHistory(365);
|
||||||
expect(preenHistory(_.cloneDeep(h), true, 0)).to.eql(h);
|
expect(preenHistory(_.cloneDeep(h), true, 0)).to.eql(h);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does aggregate data in monthly entries before cutoff (free users)', () => {
|
it('does aggregate data in monthly entries before cutoff (free users)', () => {
|
||||||
let h = generateHistory(81); // Jumps to July
|
const h = generateHistory(81); // Jumps to July
|
||||||
let preened = preenHistory(_.cloneDeep(h), false, 0);
|
const preened = preenHistory(_.cloneDeep(h), false, 0);
|
||||||
expect(preened.length).to.eql(62); // Keeps 60 days + 2 entries per august and july
|
expect(preened.length).to.eql(62); // Keeps 60 days + 2 entries per august and july
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does aggregate data in monthly entries before cutoff (subscribers)', () => {
|
it('does aggregate data in monthly entries before cutoff (subscribers)', () => {
|
||||||
let h = generateHistory(396); // Jumps to September 2012
|
const h = generateHistory(396); // Jumps to September 2012
|
||||||
let preened = preenHistory(_.cloneDeep(h), true, 0);
|
const preened = preenHistory(_.cloneDeep(h), true, 0);
|
||||||
expect(preened.length).to.eql(367); // Keeps 365 days + 2 entries per october and september
|
expect(preened.length).to.eql(367); // Keeps 365 days + 2 entries per october and september
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does aggregate data in monthly and yearly entries before cutoff (free users)', () => {
|
it('does aggregate data in monthly and yearly entries before cutoff (free users)', () => {
|
||||||
let h = generateHistory(731); // Jumps to October 21 2012
|
const h = generateHistory(731); // Jumps to October 21 2012
|
||||||
let preened = preenHistory(_.cloneDeep(h), false, 0);
|
const preened = preenHistory(_.cloneDeep(h), false, 0);
|
||||||
expect(preened.length).to.eql(73); // Keeps 60 days + 11 montly entries and 2 yearly entry for 2011 and 2012
|
// Keeps 60 days + 11 montly entries and 2 yearly entry for 2011 and 2012
|
||||||
|
expect(preened.length).to.eql(73);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does aggregate data in monthly and yearly entries before cutoff (subscribers)', () => {
|
it('does aggregate data in monthly and yearly entries before cutoff (subscribers)', () => {
|
||||||
let h = generateHistory(1031); // Jumps to October 21 2012
|
const h = generateHistory(1031); // Jumps to October 21 2012
|
||||||
let preened = preenHistory(_.cloneDeep(h), true, 0);
|
const preened = preenHistory(_.cloneDeep(h), true, 0);
|
||||||
expect(preened.length).to.eql(380); // Keeps 365 days + 13 montly entries and 2 yearly entries for 2011 and 2010
|
// Keeps 365 days + 13 montly entries and 2 yearly entries for 2011 and 2010
|
||||||
|
expect(preened.length).to.eql(380);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly aggregates values', () => {
|
it('correctly aggregates values', () => {
|
||||||
let h = generateHistory(63); // Compress last 3 days
|
const h = generateHistory(63); // Compress last 3 days
|
||||||
let preened = preenHistory(_.cloneDeep(h), false, 0);
|
const preened = preenHistory(_.cloneDeep(h), false, 0);
|
||||||
expect(preened[0].value).to.eql((61 + 62 + 63) / 3);
|
expect(preened[0].value).to.eql((61 + 62 + 63) / 3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { model as User } from '../../../../website/server/models/user';
|
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
import apn from 'apn/mock';
|
import apn from 'apn/mock';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import gcmLib from 'node-gcm'; // works with FCM notifications too
|
import gcmLib from 'node-gcm'; // works with FCM notifications too
|
||||||
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
|
|
||||||
describe('pushNotifications', () => {
|
describe('pushNotifications', () => {
|
||||||
let user;
|
let user;
|
||||||
let sendPushNotification;
|
let sendPushNotification;
|
||||||
let pathToPushNotifications = '../../../../website/server/libs/pushNotifications';
|
const pathToPushNotifications = '../../../../website/server/libs/pushNotifications';
|
||||||
let fcmSendSpy;
|
let fcmSendSpy;
|
||||||
let apnSendSpy;
|
let apnSendSpy;
|
||||||
|
|
||||||
let identifier = 'identifier';
|
const identifier = 'identifier';
|
||||||
let title = 'title';
|
const title = 'title';
|
||||||
let message = 'message';
|
const message = 'message';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -93,7 +93,7 @@ describe('pushNotifications', () => {
|
|||||||
regId: '123',
|
regId: '123',
|
||||||
});
|
});
|
||||||
|
|
||||||
let details = {
|
const details = {
|
||||||
identifier,
|
identifier,
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import setupNconf from '../../../../website/server/libs/setupNconf';
|
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
|
import setupNconf from '../../../../website/server/libs/setupNconf';
|
||||||
|
|
||||||
describe('setupNconf', () => {
|
describe('setupNconf', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -21,7 +21,7 @@ describe('setupNconf', () => {
|
|||||||
expect(nconf.env).to.be.calledOnce;
|
expect(nconf.env).to.be.calledOnce;
|
||||||
expect(nconf.file).to.be.calledOnce;
|
expect(nconf.file).to.be.calledOnce;
|
||||||
|
|
||||||
let regexString = `\\${path.sep}config.json$`;
|
const regexString = `\\${path.sep}config.json$`;
|
||||||
expect(nconf.file).to.be.calledWithMatch('user', new RegExp(regexString));
|
expect(nconf.file).to.be.calledWithMatch('user', new RegExp(regexString));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import { IncomingWebhook } from '@slack/client';
|
import { IncomingWebhook } from '@slack/client';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
|
import nconf from 'nconf';
|
||||||
|
import moment from 'moment';
|
||||||
import * as slack from '../../../../website/server/libs/slack';
|
import * as slack from '../../../../website/server/libs/slack';
|
||||||
import logger from '../../../../website/server/libs/logger';
|
import logger from '../../../../website/server/libs/logger';
|
||||||
import { TAVERN_ID } from '../../../../website/server/models/group';
|
import { TAVERN_ID } from '../../../../website/server/models/group';
|
||||||
import nconf from 'nconf';
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
describe('slack', () => {
|
describe('slack', () => {
|
||||||
describe('sendFlagNotification', () => {
|
describe('sendFlagNotification', () => {
|
||||||
@@ -113,7 +113,7 @@ describe('slack', () => {
|
|||||||
it('noops if no flagging url is provided', () => {
|
it('noops if no flagging url is provided', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('SLACK_FLAGGING_URL').returns('');
|
sandbox.stub(nconf, 'get').withArgs('SLACK_FLAGGING_URL').returns('');
|
||||||
sandbox.stub(logger, 'error');
|
sandbox.stub(logger, 'error');
|
||||||
let reRequiredSlack = requireAgain('../../../../website/server/libs/slack');
|
const reRequiredSlack = requireAgain('../../../../website/server/libs/slack');
|
||||||
|
|
||||||
expect(logger.error).to.be.calledOnce;
|
expect(logger.error).to.be.calledOnce;
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
} from '../../../helpers/api-unit.helper.js';
|
} from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
describe('taskManager', () => {
|
describe('taskManager', () => {
|
||||||
let user, group, challenge;
|
let user; let group; let
|
||||||
let testHabit = {
|
challenge;
|
||||||
|
const testHabit = {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
up: false,
|
up: false,
|
||||||
@@ -47,8 +48,8 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
let newTasks = await createTasks(req, res, {user});
|
const newTasks = await createTasks(req, res, { user });
|
||||||
let newTask = newTasks[0];
|
const newTask = newTasks[0];
|
||||||
|
|
||||||
expect(newTask.text).to.equal(testHabit.text);
|
expect(newTask.text).to.equal(testHabit.text);
|
||||||
expect(newTask.type).to.equal(testHabit.type);
|
expect(newTask.type).to.equal(testHabit.type);
|
||||||
@@ -61,15 +62,15 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
await createTasks(req, res, {user});
|
await createTasks(req, res, { user });
|
||||||
|
|
||||||
req.body = {};
|
req.body = {};
|
||||||
req.query = {
|
req.query = {
|
||||||
type: 'habits',
|
type: 'habits',
|
||||||
};
|
};
|
||||||
|
|
||||||
let tasks = await getTasks(req, res, {user});
|
const tasks = await getTasks(req, res, { user });
|
||||||
let task = tasks[0];
|
const task = tasks[0];
|
||||||
|
|
||||||
expect(task.text).to.equal(testHabit.text);
|
expect(task.text).to.equal(testHabit.text);
|
||||||
expect(task.type).to.equal(testHabit.type);
|
expect(task.type).to.equal(testHabit.type);
|
||||||
@@ -82,8 +83,8 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
let newTasks = await createTasks(req, res, {user, group});
|
const newTasks = await createTasks(req, res, { user, group });
|
||||||
let newTask = newTasks[0];
|
const newTask = newTasks[0];
|
||||||
|
|
||||||
expect(newTask.text).to.equal(testHabit.text);
|
expect(newTask.text).to.equal(testHabit.text);
|
||||||
expect(newTask.type).to.equal(testHabit.type);
|
expect(newTask.type).to.equal(testHabit.type);
|
||||||
@@ -97,15 +98,15 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
await createTasks(req, res, {user, group});
|
await createTasks(req, res, { user, group });
|
||||||
|
|
||||||
req.body = {};
|
req.body = {};
|
||||||
req.query = {
|
req.query = {
|
||||||
type: 'habits',
|
type: 'habits',
|
||||||
};
|
};
|
||||||
|
|
||||||
let tasks = await getTasks(req, res, {user, group});
|
const tasks = await getTasks(req, res, { user, group });
|
||||||
let task = tasks[0];
|
const task = tasks[0];
|
||||||
|
|
||||||
expect(task.text).to.equal(testHabit.text);
|
expect(task.text).to.equal(testHabit.text);
|
||||||
expect(task.type).to.equal(testHabit.type);
|
expect(task.type).to.equal(testHabit.type);
|
||||||
@@ -119,8 +120,8 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
let newTasks = await createTasks(req, res, {user, challenge});
|
const newTasks = await createTasks(req, res, { user, challenge });
|
||||||
let newTask = newTasks[0];
|
const newTask = newTasks[0];
|
||||||
|
|
||||||
expect(newTask.text).to.equal(testHabit.text);
|
expect(newTask.text).to.equal(testHabit.text);
|
||||||
expect(newTask.type).to.equal(testHabit.type);
|
expect(newTask.type).to.equal(testHabit.type);
|
||||||
@@ -134,15 +135,15 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
await createTasks(req, res, {user, challenge});
|
await createTasks(req, res, { user, challenge });
|
||||||
|
|
||||||
req.body = {};
|
req.body = {};
|
||||||
req.query = {
|
req.query = {
|
||||||
type: 'habits',
|
type: 'habits',
|
||||||
};
|
};
|
||||||
|
|
||||||
let tasks = await getTasks(req, res, {user, challenge});
|
const tasks = await getTasks(req, res, { user, challenge });
|
||||||
let task = tasks[0];
|
const task = tasks[0];
|
||||||
|
|
||||||
expect(task.text).to.equal(testHabit.text);
|
expect(task.text).to.equal(testHabit.text);
|
||||||
expect(task.type).to.equal(testHabit.type);
|
expect(task.type).to.equal(testHabit.type);
|
||||||
@@ -156,9 +157,9 @@ describe('taskManager', () => {
|
|||||||
req.body = testHabit;
|
req.body = testHabit;
|
||||||
res.t = i18n.t;
|
res.t = i18n.t;
|
||||||
|
|
||||||
let tasks = await createTasks(req, res, {user, challenge});
|
const tasks = await createTasks(req, res, { user, challenge });
|
||||||
|
|
||||||
let syncableTask = syncableAttrs(tasks[0]);
|
const syncableTask = syncableAttrs(tasks[0]);
|
||||||
|
|
||||||
expect(syncableTask._id).to.not.exist;
|
expect(syncableTask._id).to.not.exist;
|
||||||
expect(syncableTask.userId).to.not.exist;
|
expect(syncableTask.userId).to.not.exist;
|
||||||
@@ -172,7 +173,7 @@ describe('taskManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('moves tasks to a specified position', async () => {
|
it('moves tasks to a specified position', async () => {
|
||||||
let order = ['task-id-1', 'task-id-2'];
|
const order = ['task-id-1', 'task-id-2'];
|
||||||
|
|
||||||
moveTask(order, 'task-id-2', 0);
|
moveTask(order, 'task-id-2', 0);
|
||||||
|
|
||||||
@@ -180,7 +181,7 @@ describe('taskManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('moves tasks to a specified position out of length', async () => {
|
it('moves tasks to a specified position out of length', async () => {
|
||||||
let order = ['task-id-1'];
|
const order = ['task-id-1'];
|
||||||
|
|
||||||
moveTask(order, 'task-id-2', 2);
|
moveTask(order, 'task-id-2', 2);
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import {
|
|||||||
} from '../../../../website/server/models/user';
|
} from '../../../../website/server/models/user';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../helpers/api-unit.helper.js';
|
defer,
|
||||||
import { defer } from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
|
|
||||||
describe('webhooks', () => {
|
describe('webhooks', () => {
|
||||||
let webhooks, user;
|
let webhooks; let
|
||||||
|
user;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sandbox.stub(got, 'post').returns(defer().promise);
|
sandbox.stub(got, 'post').returns(defer().promise);
|
||||||
@@ -72,7 +74,7 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
describe('WebhookSender', () => {
|
describe('WebhookSender', () => {
|
||||||
it('creates a new WebhookSender object', () => {
|
it('creates a new WebhookSender object', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,13 +84,15 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
it('provides default function for data transformation', () => {
|
it('provides default function for data transformation', () => {
|
||||||
sandbox.spy(WebhookSender, 'defaultTransformData');
|
sandbox.spy(WebhookSender, 'defaultTransformData');
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(WebhookSender.defaultTransformData).to.be.calledOnce;
|
expect(WebhookSender.defaultTransformData).to.be.calledOnce;
|
||||||
@@ -100,14 +104,16 @@ describe('webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds default data (user and webhookType) to the body', () => {
|
it('adds default data (user and webhookType) to the body', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
sandbox.spy(sendWebhook, 'attachDefaultData');
|
sandbox.spy(sendWebhook, 'attachDefaultData');
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(sendWebhook.attachDefaultData).to.be.calledOnce;
|
expect(sendWebhook.attachDefaultData).to.be.calledOnce;
|
||||||
@@ -118,25 +124,27 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
expect(body).to.eql({
|
expect(body).to.eql({
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
user: {_id: user._id},
|
user: { _id: user._id },
|
||||||
webhookType: 'custom',
|
webhookType: 'custom',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can pass in a data transformation function', () => {
|
it('can pass in a data transformation function', () => {
|
||||||
sandbox.spy(WebhookSender, 'defaultTransformData');
|
sandbox.spy(WebhookSender, 'defaultTransformData');
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
transformData (data) {
|
transformData (data) {
|
||||||
let dataToSend = Object.assign({baz: 'biz'}, data);
|
const dataToSend = { baz: 'biz', ...data };
|
||||||
|
|
||||||
return dataToSend;
|
return dataToSend;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(WebhookSender.defaultTransformData).to.not.be.called;
|
expect(WebhookSender.defaultTransformData).to.not.be.called;
|
||||||
@@ -152,13 +160,15 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
it('provides a default filter function', () => {
|
it('provides a default filter function', () => {
|
||||||
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(WebhookSender.defaultWebhookFilter).to.be.calledOnce;
|
expect(WebhookSender.defaultWebhookFilter).to.be.calledOnce;
|
||||||
@@ -166,16 +176,18 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
it('can pass in a webhook filter function', () => {
|
it('can pass in a webhook filter function', () => {
|
||||||
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
webhookFilter (hook) {
|
webhookFilter (hook) {
|
||||||
return hook.url !== 'http://custom-url.com';
|
return hook.url !== 'http://custom-url.com';
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(WebhookSender.defaultWebhookFilter).to.not.be.called;
|
expect(WebhookSender.defaultWebhookFilter).to.not.be.called;
|
||||||
@@ -184,18 +196,22 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
it('can pass in a webhook filter function that filters on data', () => {
|
it('can pass in a webhook filter function that filters on data', () => {
|
||||||
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
sandbox.spy(WebhookSender, 'defaultWebhookFilter');
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
webhookFilter (hook, data) {
|
webhookFilter (hook, data) {
|
||||||
return hook.options.foo === data.foo;
|
return hook.options.foo === data.foo;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [
|
user.webhooks = [
|
||||||
{ id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom', options: { foo: 'bar' }},
|
{
|
||||||
{ id: 'other-custom-webhook', url: 'http://other-custom-url.com', enabled: true, type: 'custom', options: { foo: 'foo' }},
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom', options: { foo: 'bar' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'other-custom-webhook', url: 'http://other-custom-url.com', enabled: true, type: 'custom', options: { foo: 'foo' },
|
||||||
|
},
|
||||||
];
|
];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
@@ -204,41 +220,49 @@ describe('webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('ignores disabled webhooks', () => {
|
it('ignores disabled webhooks', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'http://custom-url.com', enabled: false, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: false, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(got.post).to.not.be.called;
|
expect(got.post).to.not.be.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ignores webhooks with invalid urls', () => {
|
it('ignores webhooks with invalid urls', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [{id: 'custom-webhook', url: 'httxp://custom-url!!!', enabled: true, type: 'custom'}];
|
user.webhooks = [{
|
||||||
|
id: 'custom-webhook', url: 'httxp://custom-url!!!', enabled: true, type: 'custom',
|
||||||
|
}];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
expect(got.post).to.not.be.called;
|
expect(got.post).to.not.be.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ignores webhooks of other types', () => {
|
it('ignores webhooks of other types', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [
|
user.webhooks = [
|
||||||
{ id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'},
|
{
|
||||||
{ id: 'other-webhook', url: 'http://other-url.com', enabled: true, type: 'other'},
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'other-webhook', url: 'http://other-url.com', enabled: true, type: 'other',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
@@ -250,14 +274,16 @@ describe('webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends every type of activity to global webhooks', () => {
|
it('sends every type of activity to global webhooks', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [
|
user.webhooks = [
|
||||||
{ id: 'global-webhook', url: 'http://custom-url.com', enabled: true, type: 'globalActivity'},
|
{
|
||||||
|
id: 'global-webhook', url: 'http://custom-url.com', enabled: true, type: 'globalActivity',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
@@ -269,15 +295,19 @@ describe('webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends multiple webhooks of the same type', () => {
|
it('sends multiple webhooks of the same type', () => {
|
||||||
let sendWebhook = new WebhookSender({
|
const sendWebhook = new WebhookSender({
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = { foo: 'bar' };
|
const body = { foo: 'bar' };
|
||||||
|
|
||||||
user.webhooks = [
|
user.webhooks = [
|
||||||
{ id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom'},
|
{
|
||||||
{ id: 'other-custom-webhook', url: 'http://other-url.com', enabled: true, type: 'custom'},
|
id: 'custom-webhook', url: 'http://custom-url.com', enabled: true, type: 'custom',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'other-custom-webhook', url: 'http://other-url.com', enabled: true, type: 'custom',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
sendWebhook.send(user, body);
|
sendWebhook.send(user, body);
|
||||||
|
|
||||||
@@ -299,7 +329,7 @@ describe('webhooks', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
data = {
|
data = {
|
||||||
user: {
|
user: {
|
||||||
_tmp: {foo: 'bar'},
|
_tmp: { foo: 'bar' },
|
||||||
stats: {
|
stats: {
|
||||||
lvl: 5,
|
lvl: 5,
|
||||||
int: 10,
|
int: 10,
|
||||||
@@ -317,11 +347,12 @@ describe('webhooks', () => {
|
|||||||
delta: 176,
|
delta: 176,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockStats = Object.assign({
|
const mockStats = {
|
||||||
maxHealth: 50,
|
maxHealth: 50,
|
||||||
maxMP: 103,
|
maxMP: 103,
|
||||||
toNextLevel: 40,
|
toNextLevel: 40,
|
||||||
}, data.user.stats);
|
...data.user.stats,
|
||||||
|
};
|
||||||
delete mockStats.toJSON;
|
delete mockStats.toJSON;
|
||||||
|
|
||||||
sandbox.stub(User, 'addComputedStatsToJSONObj').returns(mockStats);
|
sandbox.stub(User, 'addComputedStatsToJSONObj').returns(mockStats);
|
||||||
@@ -338,7 +369,7 @@ describe('webhooks', () => {
|
|||||||
webhookType: 'taskActivity',
|
webhookType: 'taskActivity',
|
||||||
user: {
|
user: {
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
_tmp: {foo: 'bar'},
|
_tmp: { foo: 'bar' },
|
||||||
stats: {
|
stats: {
|
||||||
lvl: 5,
|
lvl: 5,
|
||||||
int: 10,
|
int: 10,
|
||||||
@@ -376,7 +407,7 @@ describe('webhooks', () => {
|
|||||||
webhookType: 'taskActivity',
|
webhookType: 'taskActivity',
|
||||||
user: {
|
user: {
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
_tmp: {foo: 'bar'},
|
_tmp: { foo: 'bar' },
|
||||||
stats: {
|
stats: {
|
||||||
lvl: 5,
|
lvl: 5,
|
||||||
int: 10,
|
int: 10,
|
||||||
@@ -416,7 +447,7 @@ describe('webhooks', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
['created', 'updated', 'deleted'].forEach((type) => {
|
['created', 'updated', 'deleted'].forEach(type => {
|
||||||
it(`sends ${type} tasks`, () => {
|
it(`sends ${type} tasks`, () => {
|
||||||
data.type = type;
|
data.type = type;
|
||||||
|
|
||||||
@@ -498,7 +529,7 @@ describe('webhooks', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
['petHatched', 'mountRaised', 'leveledUp'].forEach((type) => {
|
['petHatched', 'mountRaised', 'leveledUp'].forEach(type => {
|
||||||
it(`sends ${type} webhooks`, () => {
|
it(`sends ${type} webhooks`, () => {
|
||||||
data.type = type;
|
data.type = type;
|
||||||
|
|
||||||
@@ -545,7 +576,7 @@ describe('webhooks', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
['questStarted', 'questFinised'].forEach((type) => {
|
['questStarted', 'questFinised'].forEach(type => {
|
||||||
it(`sends ${type} webhooks`, () => {
|
it(`sends ${type} webhooks`, () => {
|
||||||
data.type = type;
|
data.type = type;
|
||||||
|
|
||||||
@@ -584,7 +615,7 @@ describe('webhooks', () => {
|
|||||||
|
|
||||||
describe('groupChatReceivedWebhook', () => {
|
describe('groupChatReceivedWebhook', () => {
|
||||||
it('sends chat data', () => {
|
it('sends chat data', () => {
|
||||||
let data = {
|
const data = {
|
||||||
group: {
|
group: {
|
||||||
id: 'group-id',
|
id: 'group-id',
|
||||||
name: 'some group',
|
name: 'some group',
|
||||||
@@ -619,7 +650,7 @@ describe('webhooks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not send chat data for group if not selected', () => {
|
it('does not send chat data for group if not selected', () => {
|
||||||
let data = {
|
const data = {
|
||||||
group: {
|
group: {
|
||||||
id: 'not-group-id',
|
id: 'not-group-id',
|
||||||
name: 'some group',
|
name: 'some group',
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
/* eslint-disable global-require */
|
/* eslint-disable global-require */
|
||||||
|
import nconf from 'nconf';
|
||||||
|
import requireAgain from 'require-again';
|
||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
||||||
import nconf from 'nconf';
|
|
||||||
import requireAgain from 'require-again';
|
|
||||||
|
|
||||||
describe('analytics middleware', () => {
|
describe('analytics middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
let pathToAnalyticsMiddleware = '../../../../website/server/middlewares/analytics';
|
next;
|
||||||
|
const pathToAnalyticsMiddleware = '../../../../website/server/middlewares/analytics';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -19,7 +20,7 @@ describe('analytics middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('attaches analytics object res.locals', () => {
|
it('attaches analytics object res.locals', () => {
|
||||||
let attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
const attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
||||||
|
|
||||||
attachAnalytics(req, res, next);
|
attachAnalytics(req, res, next);
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ describe('analytics middleware', () => {
|
|||||||
|
|
||||||
it('attaches stubbed methods for non-prod environments', () => {
|
it('attaches stubbed methods for non-prod environments', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(false);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(false);
|
||||||
let attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
const attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
||||||
|
|
||||||
attachAnalytics(req, res, next);
|
attachAnalytics(req, res, next);
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ describe('analytics middleware', () => {
|
|||||||
it('attaches real methods for prod environments', () => {
|
it('attaches real methods for prod environments', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
||||||
|
|
||||||
let attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
const attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
|
||||||
|
|
||||||
attachAnalytics(req, res, next);
|
attachAnalytics(req, res, next);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import {
|
|||||||
import { authWithHeaders as authWithHeadersFactory } from '../../../../website/server/middlewares/auth';
|
import { authWithHeaders as authWithHeadersFactory } from '../../../../website/server/middlewares/auth';
|
||||||
|
|
||||||
describe('auth middleware', () => {
|
describe('auth middleware', () => {
|
||||||
let res, req, user;
|
let res; let req; let
|
||||||
|
user;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -14,7 +15,7 @@ describe('auth middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('auth with headers', () => {
|
describe('auth with headers', () => {
|
||||||
it('allows to specify a list of user field that we do not want to load', (done) => {
|
it('allows to specify a list of user field that we do not want to load', done => {
|
||||||
const authWithHeaders = authWithHeadersFactory({
|
const authWithHeaders = authWithHeadersFactory({
|
||||||
userFieldsToExclude: ['items'],
|
userFieldsToExclude: ['items'],
|
||||||
});
|
});
|
||||||
@@ -22,18 +23,18 @@ describe('auth middleware', () => {
|
|||||||
req.headers['x-api-user'] = user._id;
|
req.headers['x-api-user'] = user._id;
|
||||||
req.headers['x-api-key'] = user.apiToken;
|
req.headers['x-api-key'] = user.apiToken;
|
||||||
|
|
||||||
authWithHeaders(req, res, (err) => {
|
authWithHeaders(req, res, err => {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
const userToJSON = res.locals.user.toJSON();
|
const userToJSON = res.locals.user.toJSON();
|
||||||
expect(userToJSON.items).to.not.exist;
|
expect(userToJSON.items).to.not.exist;
|
||||||
expect(userToJSON.auth).to.exist;
|
expect(userToJSON.auth).to.exist;
|
||||||
|
|
||||||
done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('makes sure some fields are always included', (done) => {
|
it('makes sure some fields are always included', done => {
|
||||||
const authWithHeaders = authWithHeadersFactory({
|
const authWithHeaders = authWithHeadersFactory({
|
||||||
userFieldsToExclude: [
|
userFieldsToExclude: [
|
||||||
'items', 'auth.timestamps',
|
'items', 'auth.timestamps',
|
||||||
@@ -44,7 +45,7 @@ describe('auth middleware', () => {
|
|||||||
req.headers['x-api-user'] = user._id;
|
req.headers['x-api-user'] = user._id;
|
||||||
req.headers['x-api-key'] = user.apiToken;
|
req.headers['x-api-key'] = user.apiToken;
|
||||||
|
|
||||||
authWithHeaders(req, res, (err) => {
|
authWithHeaders(req, res, err => {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
const userToJSON = res.locals.user.toJSON();
|
const userToJSON = res.locals.user.toJSON();
|
||||||
@@ -56,7 +57,7 @@ describe('auth middleware', () => {
|
|||||||
expect(userToJSON._id).to.exist;
|
expect(userToJSON._id).to.exist;
|
||||||
expect(userToJSON.flags).to.exist;
|
expect(userToJSON.flags).to.exist;
|
||||||
|
|
||||||
done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import {
|
|||||||
import cors from '../../../../website/server/middlewares/cors';
|
import cors from '../../../../website/server/middlewares/cors';
|
||||||
|
|
||||||
describe('cors middleware', () => {
|
describe('cors middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
req = generateReq();
|
req = generateReq();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
@@ -5,22 +7,21 @@ import {
|
|||||||
generateDaily,
|
generateDaily,
|
||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import cronMiddleware from '../../../../website/server/middlewares/cron';
|
import cronMiddleware from '../../../../website/server/middlewares/cron';
|
||||||
import moment from 'moment';
|
|
||||||
import { model as User } from '../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
import { model as Group } from '../../../../website/server/models/group';
|
import { model as Group } from '../../../../website/server/models/group';
|
||||||
import * as Tasks from '../../../../website/server/models/task';
|
import * as Tasks from '../../../../website/server/models/task';
|
||||||
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
import * as analyticsService from '../../../../website/server/libs/analyticsService';
|
||||||
import * as cronLib from '../../../../website/server/libs/cron';
|
import * as cronLib from '../../../../website/server/libs/cron';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
const CRON_TIMEOUT_WAIT = new Date(60 * 60 * 1000).getTime();
|
const CRON_TIMEOUT_WAIT = new Date(60 * 60 * 1000).getTime();
|
||||||
const CRON_TIMEOUT_UNIT = new Date(60 * 1000).getTime();
|
const CRON_TIMEOUT_UNIT = new Date(60 * 1000).getTime();
|
||||||
|
|
||||||
describe('cron middleware', () => {
|
describe('cron middleware', () => {
|
||||||
let res, req;
|
let res; let
|
||||||
|
req;
|
||||||
let user;
|
let user;
|
||||||
|
|
||||||
beforeEach((done) => {
|
beforeEach(done => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
req = generateReq();
|
req = generateReq();
|
||||||
user = new User({
|
user = new User({
|
||||||
@@ -48,33 +49,35 @@ describe('cron middleware', () => {
|
|||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls next when user is not attached', (done) => {
|
it('calls next when user is not attached', done => {
|
||||||
res.locals.user = null;
|
res.locals.user = null;
|
||||||
cronMiddleware(req, res, done);
|
cronMiddleware(req, res, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls next when days have not been missed', (done) => {
|
it('calls next when days have not been missed', done => {
|
||||||
cronMiddleware(req, res, done);
|
cronMiddleware(req, res, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should clear todos older than 30 days for free users', async () => {
|
it('should clear todos older than 30 days for free users', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let task = generateTodo(user);
|
const task = generateTodo(user);
|
||||||
task.dateCompleted = moment(new Date()).subtract({days: 31});
|
task.dateCompleted = moment(new Date()).subtract({ days: 31 });
|
||||||
task.completed = true;
|
task.completed = true;
|
||||||
await task.save();
|
await task.save();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
|
|
||||||
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
|
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
|
||||||
if (secondErr) return reject(err);
|
if (secondErr) return reject(err);
|
||||||
expect(secondErr).to.not.exist;
|
expect(secondErr).to.not.exist;
|
||||||
expect(taskFound).to.not.exist;
|
expect(taskFound).to.not.exist;
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -82,22 +85,23 @@ describe('cron middleware', () => {
|
|||||||
it('should not clear todos older than 30 days for subscribed users', async () => {
|
it('should not clear todos older than 30 days for subscribed users', async () => {
|
||||||
user.purchased.plan.customerId = 'subscribedId';
|
user.purchased.plan.customerId = 'subscribedId';
|
||||||
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
|
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let task = generateTodo(user);
|
const task = generateTodo(user);
|
||||||
task.dateCompleted = moment(new Date()).subtract({days: 31});
|
task.dateCompleted = moment(new Date()).subtract({ days: 31 });
|
||||||
task.completed = true;
|
task.completed = true;
|
||||||
await task.save();
|
await task.save();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
|
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
|
||||||
if (secondErr) return reject(secondErr);
|
if (secondErr) return reject(secondErr);
|
||||||
expect(secondErr).to.not.exist;
|
expect(secondErr).to.not.exist;
|
||||||
expect(taskFound).to.exist;
|
expect(taskFound).to.exist;
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -105,105 +109,106 @@ describe('cron middleware', () => {
|
|||||||
it('should clear todos older than 90 days for subscribed users', async () => {
|
it('should clear todos older than 90 days for subscribed users', async () => {
|
||||||
user.purchased.plan.customerId = 'subscribedId';
|
user.purchased.plan.customerId = 'subscribedId';
|
||||||
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
|
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
|
|
||||||
let task = generateTodo(user);
|
const task = generateTodo(user);
|
||||||
task.dateCompleted = moment(new Date()).subtract({days: 91});
|
task.dateCompleted = moment(new Date()).subtract({ days: 91 });
|
||||||
task.completed = true;
|
task.completed = true;
|
||||||
await task.save();
|
await task.save();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
|
Tasks.Task.findOne({ _id: task }, (secondErr, taskFound) => {
|
||||||
if (secondErr) return reject(secondErr);
|
if (secondErr) return reject(secondErr);
|
||||||
expect(secondErr).to.not.exist;
|
expect(secondErr).to.not.exist;
|
||||||
expect(taskFound).to.not.exist;
|
expect(taskFound).to.not.exist;
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call next if user was not modified after cron', async () => {
|
it('should call next if user was not modified after cron', async () => {
|
||||||
let hpBefore = user.stats.hp;
|
const hpBefore = user.stats.hp;
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
expect(hpBefore).to.equal(user.stats.hp);
|
expect(hpBefore).to.equal(user.stats.hp);
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates user.auth.timestamps.loggedin and lastCron', async () => {
|
it('updates user.auth.timestamps.loggedin and lastCron', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
expect(moment(now).isSame(user.lastCron, 'day'));
|
expect(moment(now).isSame(user.lastCron, 'day'));
|
||||||
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
|
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does damage for missing dailies', async () => {
|
it('does damage for missing dailies', async () => {
|
||||||
let hpBefore = user.stats.hp;
|
const hpBefore = user.stats.hp;
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let daily = generateDaily(user);
|
const daily = generateDaily(user);
|
||||||
daily.startDate = moment(new Date()).subtract({days: 2});
|
daily.startDate = moment(new Date()).subtract({ days: 2 });
|
||||||
await daily.save();
|
await daily.save();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
User.findOne({_id: user._id}, function (secondErr, updatedUser) {
|
return User.findOne({ _id: user._id }, (secondErr, updatedUser) => {
|
||||||
if (secondErr) return reject(secondErr);
|
if (secondErr) return reject(secondErr);
|
||||||
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates tasks', async () => {
|
it('updates tasks', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let todo = generateTodo(user);
|
const todo = generateTodo(user);
|
||||||
let todoValueBefore = todo.value;
|
const todoValueBefore = todo.value;
|
||||||
await Promise.all([todo.save(), user.save()]);
|
await Promise.all([todo.save(), user.save()]);
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
Tasks.Task.findOne({_id: todo._id}, function (secondErr, todoFound) {
|
return Tasks.Task.findOne({ _id: todo._id }, (secondErr, todoFound) => {
|
||||||
if (secondErr) return reject(secondErr);
|
if (secondErr) return reject(secondErr);
|
||||||
expect(todoFound.value).to.be.lessThan(todoValueBefore);
|
expect(todoFound.value).to.be.lessThan(todoValueBefore);
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies quest progress', async () => {
|
it('applies quest progress', async () => {
|
||||||
let hpBefore = user.stats.hp;
|
const hpBefore = user.stats.hp;
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let daily = generateDaily(user);
|
const daily = generateDaily(user);
|
||||||
daily.startDate = moment(new Date()).subtract({days: 2});
|
daily.startDate = moment(new Date()).subtract({ days: 2 });
|
||||||
await daily.save();
|
await daily.save();
|
||||||
|
|
||||||
let questKey = 'dilatory';
|
const questKey = 'dilatory';
|
||||||
user.party.quest.key = questKey;
|
user.party.quest.key = questKey;
|
||||||
|
|
||||||
let party = new Group({
|
const party = new Group({
|
||||||
type: 'party',
|
type: 'party',
|
||||||
name: generateUUID(),
|
name: generateUUID(),
|
||||||
leader: user._id,
|
leader: user._id,
|
||||||
@@ -218,22 +223,22 @@ describe('cron middleware', () => {
|
|||||||
party.startQuest(user);
|
party.startQuest(user);
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
User.findOne({_id: user._id}, function (secondErr, updatedUser) {
|
return User.findOne({ _id: user._id }, (secondErr, updatedUser) => {
|
||||||
if (secondErr) return reject(secondErr);
|
if (secondErr) return reject(secondErr);
|
||||||
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('recovers from failed cron and does not error when user is already cronning', async () => {
|
it('recovers from failed cron and does not error when user is already cronning', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
let updatedUser = user.toObject();
|
const updatedUser = user.toObject();
|
||||||
updatedUser.nMatched = 0;
|
updatedUser.nMatched = 0;
|
||||||
|
|
||||||
sandbox.spy(cronLib, 'recoverCron');
|
sandbox.spy(cronLib, 'recoverCron');
|
||||||
@@ -242,8 +247,8 @@ describe('cron middleware', () => {
|
|||||||
.withArgs({
|
.withArgs({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
$or: [
|
$or: [
|
||||||
{_cronSignature: 'NOT_RUNNING'},
|
{ _cronSignature: 'NOT_RUNNING' },
|
||||||
{_cronSignature: {$lt: sinon.match.number}},
|
{ _cronSignature: { $lt: sinon.match.number } },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
.returns({
|
.returns({
|
||||||
@@ -253,18 +258,18 @@ describe('cron middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
expect(cronLib.recoverCron).to.be.calledOnce;
|
expect(cronLib.recoverCron).to.be.calledOnce;
|
||||||
|
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cronSignature less than an hour ago should error', async () => {
|
it('cronSignature less than an hour ago should error', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
await User.update({
|
await User.update({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
}, {
|
}, {
|
||||||
@@ -273,20 +278,20 @@ describe('cron middleware', () => {
|
|||||||
},
|
},
|
||||||
}).exec();
|
}).exec();
|
||||||
await user.save();
|
await user.save();
|
||||||
let expectedErrMessage = `Impossible to recover from cron for user ${user._id}.`;
|
const expectedErrMessage = `Impossible to recover from cron for user ${user._id}.`;
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (!err) return reject(new Error('Cron should have failed.'));
|
if (!err) return reject(new Error('Cron should have failed.'));
|
||||||
expect(err.message).to.be.equal(expectedErrMessage);
|
expect(err.message).to.be.equal(expectedErrMessage);
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cronSignature longer than an hour ago should allow cron', async () => {
|
it('cronSignature longer than an hour ago should allow cron', async () => {
|
||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||||
let now = new Date();
|
const now = new Date();
|
||||||
await User.update({
|
await User.update({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
}, {
|
}, {
|
||||||
@@ -297,11 +302,11 @@ describe('cron middleware', () => {
|
|||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
cronMiddleware(req, res, (err) => {
|
cronMiddleware(req, res, err => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
|
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
|
||||||
expect(user._cronSignature).to.be.equal('NOT_RUNNING');
|
expect(user._cronSignature).to.be.equal('NOT_RUNNING');
|
||||||
resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import { NotAuthorized } from '../../../../website/server/libs/errors';
|
|||||||
import apiError from '../../../../website/server/libs/apiError';
|
import apiError from '../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('ensure access middlewares', () => {
|
describe('ensure access middlewares', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -20,7 +21,7 @@ describe('ensure access middlewares', () => {
|
|||||||
|
|
||||||
context('ensure admin', () => {
|
context('ensure admin', () => {
|
||||||
it('returns not authorized when user is not an admin', () => {
|
it('returns not authorized when user is not an admin', () => {
|
||||||
res.locals = {user: {contributor: {admin: false}}};
|
res.locals = { user: { contributor: { admin: false } } };
|
||||||
|
|
||||||
ensureAdmin(req, res, next);
|
ensureAdmin(req, res, next);
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ describe('ensure access middlewares', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('passes when user is an admin', () => {
|
it('passes when user is an admin', () => {
|
||||||
res.locals = {user: {contributor: {admin: true}}};
|
res.locals = { user: { contributor: { admin: true } } };
|
||||||
|
|
||||||
ensureAdmin(req, res, next);
|
ensureAdmin(req, res, next);
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ describe('ensure access middlewares', () => {
|
|||||||
|
|
||||||
context('ensure sudo', () => {
|
context('ensure sudo', () => {
|
||||||
it('returns not authorized when user is not a sudo user', () => {
|
it('returns not authorized when user is not a sudo user', () => {
|
||||||
res.locals = {user: {contributor: {sudo: false}}};
|
res.locals = { user: { contributor: { sudo: false } } };
|
||||||
|
|
||||||
ensureSudo(req, res, next);
|
ensureSudo(req, res, next);
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ describe('ensure access middlewares', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('passes when user is a sudo user', () => {
|
it('passes when user is a sudo user', () => {
|
||||||
res.locals = {user: {contributor: {sudo: true}}};
|
res.locals = { user: { contributor: { sudo: true } } };
|
||||||
|
|
||||||
ensureSudo(req, res, next);
|
ensureSudo(req, res, next);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable global-require */
|
/* eslint-disable global-require */
|
||||||
|
import nconf from 'nconf';
|
||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
@@ -6,10 +7,10 @@ import {
|
|||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import ensureDevelpmentMode from '../../../../website/server/middlewares/ensureDevelpmentMode';
|
import ensureDevelpmentMode from '../../../../website/server/middlewares/ensureDevelpmentMode';
|
||||||
import { NotFound } from '../../../../website/server/libs/errors';
|
import { NotFound } from '../../../../website/server/libs/errors';
|
||||||
import nconf from 'nconf';
|
|
||||||
|
|
||||||
describe('developmentMode middleware', () => {
|
describe('developmentMode middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { BadRequest } from '../../../../website/server/libs/errors';
|
|||||||
import logger from '../../../../website/server/libs/logger';
|
import logger from '../../../../website/server/libs/logger';
|
||||||
|
|
||||||
describe('errorHandler', () => {
|
describe('errorHandler', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -29,7 +30,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends internal server error if error is not a CustomError and is not identified', () => {
|
it('sends internal server error if error is not a CustomError and is not identified', () => {
|
||||||
let error = new Error();
|
const error = new Error();
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('identifies errors with statusCode property and format them correctly', () => {
|
it('identifies errors with statusCode property and format them correctly', () => {
|
||||||
let error = new Error('Error message');
|
const error = new Error('Error message');
|
||||||
error.statusCode = 400;
|
error.statusCode = 400;
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
@@ -62,7 +63,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t leak info about 500 errors', () => {
|
it('doesn\'t leak info about 500 errors', () => {
|
||||||
let error = new Error('Some secret error message');
|
const error = new Error('Some secret error message');
|
||||||
error.statusCode = 500;
|
error.statusCode = 500;
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
@@ -79,7 +80,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends CustomError', () => {
|
it('sends CustomError', () => {
|
||||||
let error = new BadRequest();
|
const error = new BadRequest();
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handle http-errors errors', () => {
|
it('handle http-errors errors', () => {
|
||||||
let error = new Error('custom message');
|
const error = new Error('custom message');
|
||||||
error.statusCode = 422;
|
error.statusCode = 422;
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
@@ -112,7 +113,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handle express-validator errors', () => {
|
it('handle express-validator errors', () => {
|
||||||
let error = [{param: 'param', msg: 'invalid param', value: 123}];
|
const error = [{ param: 'param', msg: 'invalid param', value: 123 }];
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handle Mongoose Validation errors', () => {
|
it('handle Mongoose Validation errors', () => {
|
||||||
let error = new Error('User validation failed');
|
const error = new Error('User validation failed');
|
||||||
error.name = 'ValidationError';
|
error.name = 'ValidationError';
|
||||||
|
|
||||||
error.errors = {
|
error.errors = {
|
||||||
@@ -159,7 +160,7 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('logs error', () => {
|
it('logs error', () => {
|
||||||
let error = new BadRequest();
|
const error = new BadRequest();
|
||||||
|
|
||||||
errorHandler(error, req, res, next);
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ import {
|
|||||||
import common from '../../../../website/common';
|
import common from '../../../../website/common';
|
||||||
import { model as User } from '../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const { i18n } = common;
|
||||||
|
|
||||||
describe('language middleware', () => {
|
describe('language middleware', () => {
|
||||||
describe('res.t', () => {
|
describe('res.t', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -46,9 +47,10 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getUserLanguage', () => {
|
describe('getUserLanguage', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
let checkResT = (resToCheck) => {
|
const checkResT = resToCheck => {
|
||||||
expect(resToCheck.t).to.be.a('function');
|
expect(resToCheck.t).to.be.a('function');
|
||||||
expect(resToCheck.t('help')).to.equal(i18n.t('help', req.language));
|
expect(resToCheck.t('help')).to.equal(i18n.t('help', req.language));
|
||||||
};
|
};
|
||||||
@@ -119,7 +121,7 @@ describe('language middleware', () => {
|
|||||||
checkResT(res);
|
checkResT(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to english if the user preferred language is not avalaible', (done) => {
|
it('falls back to english if the user preferred language is not avalaible', done => {
|
||||||
req.locals = {
|
req.locals = {
|
||||||
user: {
|
user: {
|
||||||
preferences: {
|
preferences: {
|
||||||
@@ -155,7 +157,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('request with session', () => {
|
context('request with session', () => {
|
||||||
it('uses the user preferred language if avalaible', (done) => {
|
it('uses the user preferred language if avalaible', done => {
|
||||||
sandbox.stub(User, 'findOne').returns({
|
sandbox.stub(User, 'findOne').returns({
|
||||||
lean () {
|
lean () {
|
||||||
return this;
|
return this;
|
||||||
@@ -182,7 +184,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('browser fallback', () => {
|
context('browser fallback', () => {
|
||||||
it('uses browser specificed language', (done) => {
|
it('uses browser specificed language', done => {
|
||||||
req.headers['accept-language'] = 'pt';
|
req.headers['accept-language'] = 'pt';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -192,7 +194,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses first language in series if browser specifies multiple', (done) => {
|
it('uses first language in series if browser specifies multiple', done => {
|
||||||
req.headers['accept-language'] = 'he, pt, it';
|
req.headers['accept-language'] = 'he, pt, it';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -202,7 +204,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', (done) => {
|
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', done => {
|
||||||
req.headers['accept-language'] = 'blah, he, pt, it';
|
req.headers['accept-language'] = 'blah, he, pt, it';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -212,7 +214,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses normal version of language if specialized locale is passed in', (done) => {
|
it('uses normal version of language if specialized locale is passed in', done => {
|
||||||
req.headers['accept-language'] = 'fr-CA';
|
req.headers['accept-language'] = 'fr-CA';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -222,7 +224,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses normal version of language if specialized locale is passed in', (done) => {
|
it('uses normal version of language if specialized locale is passed in', done => {
|
||||||
req.headers['accept-language'] = 'fr-CA';
|
req.headers['accept-language'] = 'fr-CA';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -232,7 +234,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses es if es is passed in', (done) => {
|
it('uses es if es is passed in', done => {
|
||||||
req.headers['accept-language'] = 'es';
|
req.headers['accept-language'] = 'es';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -242,7 +244,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses es_419 if applicable es-languages are passed in', (done) => {
|
it('uses es_419 if applicable es-languages are passed in', done => {
|
||||||
req.headers['accept-language'] = 'es-mx';
|
req.headers['accept-language'] = 'es-mx';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -252,7 +254,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses es_419 if multiple es languages are passed in', (done) => {
|
it('uses es_419 if multiple es languages are passed in', done => {
|
||||||
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
|
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -262,7 +264,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('zh', (done) => {
|
it('zh', done => {
|
||||||
req.headers['accept-language'] = 'zh-TW';
|
req.headers['accept-language'] = 'zh-TW';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -272,7 +274,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses english if browser specified language is not compatible', (done) => {
|
it('uses english if browser specified language is not compatible', done => {
|
||||||
req.headers['accept-language'] = 'blah';
|
req.headers['accept-language'] = 'blah';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -282,7 +284,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses english if browser does not specify', (done) => {
|
it('uses english if browser does not specify', done => {
|
||||||
req.headers['accept-language'] = '';
|
req.headers['accept-language'] = '';
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
@@ -292,7 +294,7 @@ describe('language middleware', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses english if browser does not supply an accept-language header', (done) => {
|
it('uses english if browser does not supply an accept-language header', done => {
|
||||||
delete req.headers['accept-language'];
|
delete req.headers['accept-language'];
|
||||||
|
|
||||||
getUserLanguage(req, res, () => {
|
getUserLanguage(req, res, () => {
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
|
import nconf from 'nconf';
|
||||||
|
import requireAgain from 'require-again';
|
||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import nconf from 'nconf';
|
|
||||||
import requireAgain from 'require-again';
|
|
||||||
|
|
||||||
describe('maintenance mode middleware', () => {
|
describe('maintenance mode middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
let pathToMaintenanceModeMiddleware = '../../../../website/server/middlewares/maintenanceMode';
|
next;
|
||||||
|
const pathToMaintenanceModeMiddleware = '../../../../website/server/middlewares/maintenanceMode';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -18,7 +19,7 @@ describe('maintenance mode middleware', () => {
|
|||||||
it('does not return 503 error when maintenance mode is off', () => {
|
it('does not return 503 error when maintenance mode is off', () => {
|
||||||
req = generateReq();
|
req = generateReq();
|
||||||
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('false');
|
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('false');
|
||||||
let attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
const attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
||||||
|
|
||||||
attachMaintenanceMode(req, res, next);
|
attachMaintenanceMode(req, res, next);
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ describe('maintenance mode middleware', () => {
|
|||||||
it('returns 503 error when maintenance mode is on', () => {
|
it('returns 503 error when maintenance mode is on', () => {
|
||||||
req = generateReq();
|
req = generateReq();
|
||||||
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
||||||
let attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
const attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
||||||
|
|
||||||
attachMaintenanceMode(req, res, next);
|
attachMaintenanceMode(req, res, next);
|
||||||
|
|
||||||
@@ -39,18 +40,18 @@ describe('maintenance mode middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders maintenance page when request type is HTML', () => {
|
it('renders maintenance page when request type is HTML', () => {
|
||||||
req = generateReq({headers: {accept: 'text/html'}});
|
req = generateReq({ headers: { accept: 'text/html' } });
|
||||||
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
||||||
let attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
const attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
||||||
|
|
||||||
attachMaintenanceMode(req, res, next);
|
attachMaintenanceMode(req, res, next);
|
||||||
expect(res.render).to.have.been.calledOnce;
|
expect(res.render).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends error message when request type is JSON', () => {
|
it('sends error message when request type is JSON', () => {
|
||||||
req = generateReq({headers: {accept: 'application/json'}});
|
req = generateReq({ headers: { accept: 'application/json' } });
|
||||||
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
sandbox.stub(nconf, 'get').withArgs('MAINTENANCE_MODE').returns('true');
|
||||||
let attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
const attachMaintenanceMode = requireAgain(pathToMaintenanceModeMiddleware).default;
|
||||||
|
|
||||||
attachMaintenanceMode(req, res, next);
|
attachMaintenanceMode(req, res, next);
|
||||||
expect(res.send).to.have.been.calledOnce;
|
expect(res.send).to.have.been.calledOnce;
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
|
import nconf from 'nconf';
|
||||||
|
import requireAgain from 'require-again';
|
||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import nconf from 'nconf';
|
|
||||||
import requireAgain from 'require-again';
|
|
||||||
|
|
||||||
describe('redirects middleware', () => {
|
describe('redirects middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
let pathToRedirectsMiddleware = '../../../../website/server/middlewares/redirects';
|
next;
|
||||||
|
const pathToRedirectsMiddleware = '../../../../website/server/middlewares/redirects';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -18,13 +19,13 @@ describe('redirects middleware', () => {
|
|||||||
|
|
||||||
context('forceSSL', () => {
|
context('forceSSL', () => {
|
||||||
it('sends http requests to https', () => {
|
it('sends http requests to https', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceSSL(req, res, next);
|
attachRedirects.forceSSL(req, res, next);
|
||||||
|
|
||||||
@@ -33,13 +34,13 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect https forwarded requests', () => {
|
it('does not redirect https forwarded requests', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('https');
|
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('https');
|
||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceSSL(req, res, next);
|
attachRedirects.forceSSL(req, res, next);
|
||||||
|
|
||||||
@@ -47,13 +48,13 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect outside of production environments', () => {
|
it('does not redirect outside of production environments', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(false);
|
nconfStub.withArgs('IS_PROD').returns(false);
|
||||||
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceSSL(req, res, next);
|
attachRedirects.forceSSL(req, res, next);
|
||||||
|
|
||||||
@@ -61,13 +62,13 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if base URL is not https', () => {
|
it('does not redirect if base URL is not https', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('http://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('http://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
req.header = sandbox.stub().withArgs('x-forwarded-proto').returns('http');
|
||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceSSL(req, res, next);
|
attachRedirects.forceSSL(req, res, next);
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if passed skip ssl request param is passed with corrrect key', () => {
|
it('does not redirect if passed skip ssl request param is passed with corrrect key', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
|
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
|
||||||
@@ -91,7 +92,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does redirect if skip ssl request param is passed with incorrrect key', () => {
|
it('does redirect if skip ssl request param is passed with incorrrect key', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
|
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
|
||||||
@@ -108,7 +109,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does redirect if skip ssl check key is not set', () => {
|
it('does redirect if skip ssl check key is not set', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns(null);
|
nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns(null);
|
||||||
@@ -127,7 +128,7 @@ describe('redirects middleware', () => {
|
|||||||
|
|
||||||
context('forceHabitica', () => {
|
context('forceHabitica', () => {
|
||||||
it('sends requests with differing hostname to base URL host', () => {
|
it('sends requests with differing hostname to base URL host', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
@@ -136,7 +137,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
req.url = '/static/front';
|
req.url = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
@@ -145,7 +146,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect outside of production environments', () => {
|
it('does not redirect outside of production environments', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
||||||
nconfStub.withArgs('IS_PROD').returns(false);
|
nconfStub.withArgs('IS_PROD').returns(false);
|
||||||
@@ -154,7 +155,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
req.url = '/static/front';
|
req.url = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if env is set to ignore redirection', () => {
|
it('does not redirect if env is set to ignore redirection', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('true');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('true');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
@@ -171,7 +172,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
req.url = '/static/front';
|
req.url = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
@@ -179,7 +180,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if request hostname matches base URL host', () => {
|
it('does not redirect if request hostname matches base URL host', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
@@ -188,7 +189,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
req.url = '/static/front';
|
req.url = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if request is an API URL', () => {
|
it('does not redirect if request is an API URL', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
@@ -205,7 +206,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/api/v3/challenges';
|
req.originalUrl = '/api/v3/challenges';
|
||||||
req.url = '/api/v3/challenges';
|
req.url = '/api/v3/challenges';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
@@ -213,7 +214,7 @@ describe('redirects middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not redirect if request method is not GET', () => {
|
it('does not redirect if request method is not GET', () => {
|
||||||
let nconfStub = sandbox.stub(nconf, 'get');
|
const nconfStub = sandbox.stub(nconf, 'get');
|
||||||
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
|
||||||
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
nconfStub.withArgs('IGNORE_REDIRECT').returns('false');
|
||||||
nconfStub.withArgs('IS_PROD').returns(true);
|
nconfStub.withArgs('IS_PROD').returns(true);
|
||||||
@@ -222,7 +223,7 @@ describe('redirects middleware', () => {
|
|||||||
req.originalUrl = '/static/front';
|
req.originalUrl = '/static/front';
|
||||||
req.url = '/static/front';
|
req.url = '/static/front';
|
||||||
|
|
||||||
let attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
const attachRedirects = requireAgain(pathToRedirectsMiddleware);
|
||||||
|
|
||||||
attachRedirects.forceHabitica(req, res, next);
|
attachRedirects.forceHabitica(req, res, next);
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import responseMiddleware from '../../../../website/server/middlewares/response'
|
|||||||
import packageInfo from '../../../../package.json';
|
import packageInfo from '../../../../package.json';
|
||||||
|
|
||||||
describe('response middleware', () => {
|
describe('response middleware', () => {
|
||||||
let res, req, next;
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -24,7 +25,7 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
it('can be used to respond to requests', () => {
|
it('can be used to respond to requests', () => {
|
||||||
responseMiddleware(req, res, next);
|
responseMiddleware(req, res, next);
|
||||||
res.respond(200, {field: 1});
|
res.respond(200, { field: 1 });
|
||||||
|
|
||||||
expect(res.status).to.be.calledOnce;
|
expect(res.status).to.be.calledOnce;
|
||||||
expect(res.json).to.be.calledOnce;
|
expect(res.json).to.be.calledOnce;
|
||||||
@@ -32,7 +33,7 @@ describe('response middleware', () => {
|
|||||||
expect(res.status).to.be.calledWith(200);
|
expect(res.status).to.be.calledWith(200);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
success: true,
|
success: true,
|
||||||
data: {field: 1},
|
data: { field: 1 },
|
||||||
notifications: [],
|
notifications: [],
|
||||||
userV: res.locals.user._v,
|
userV: res.locals.user._v,
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
@@ -41,7 +42,7 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
it('can be passed a third parameter to be used as optional message', () => {
|
it('can be passed a third parameter to be used as optional message', () => {
|
||||||
responseMiddleware(req, res, next);
|
responseMiddleware(req, res, next);
|
||||||
res.respond(200, {field: 1}, 'hello');
|
res.respond(200, { field: 1 }, 'hello');
|
||||||
|
|
||||||
expect(res.status).to.be.calledOnce;
|
expect(res.status).to.be.calledOnce;
|
||||||
expect(res.json).to.be.calledOnce;
|
expect(res.json).to.be.calledOnce;
|
||||||
@@ -49,7 +50,7 @@ describe('response middleware', () => {
|
|||||||
expect(res.status).to.be.calledWith(200);
|
expect(res.status).to.be.calledWith(200);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
success: true,
|
success: true,
|
||||||
data: {field: 1},
|
data: { field: 1 },
|
||||||
message: 'hello',
|
message: 'hello',
|
||||||
notifications: [],
|
notifications: [],
|
||||||
userV: res.locals.user._v,
|
userV: res.locals.user._v,
|
||||||
@@ -59,7 +60,7 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
it('treats status >= 400 as failures', () => {
|
it('treats status >= 400 as failures', () => {
|
||||||
responseMiddleware(req, res, next);
|
responseMiddleware(req, res, next);
|
||||||
res.respond(403, {field: 1});
|
res.respond(403, { field: 1 });
|
||||||
|
|
||||||
expect(res.status).to.be.calledOnce;
|
expect(res.status).to.be.calledOnce;
|
||||||
expect(res.json).to.be.calledOnce;
|
expect(res.json).to.be.calledOnce;
|
||||||
@@ -67,7 +68,7 @@ describe('response middleware', () => {
|
|||||||
expect(res.status).to.be.calledWith(403);
|
expect(res.status).to.be.calledWith(403);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
success: false,
|
success: false,
|
||||||
data: {field: 1},
|
data: { field: 1 },
|
||||||
notifications: [],
|
notifications: [],
|
||||||
userV: res.locals.user._v,
|
userV: res.locals.user._v,
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
@@ -76,13 +77,13 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
it('returns userV if a user is authenticated', () => {
|
it('returns userV if a user is authenticated', () => {
|
||||||
responseMiddleware(req, res, next);
|
responseMiddleware(req, res, next);
|
||||||
res.respond(200, {field: 1});
|
res.respond(200, { field: 1 });
|
||||||
|
|
||||||
expect(res.json).to.be.calledOnce;
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
success: true,
|
success: true,
|
||||||
data: {field: 1},
|
data: { field: 1 },
|
||||||
notifications: [],
|
notifications: [],
|
||||||
userV: 0,
|
userV: 0,
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
@@ -90,24 +91,25 @@ describe('response middleware', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns notifications if a user is authenticated', () => {
|
it('returns notifications if a user is authenticated', () => {
|
||||||
const user = res.locals.user;
|
const { user } = res.locals;
|
||||||
|
|
||||||
user.notifications = [
|
user.notifications = [
|
||||||
null, // invalid, not an object
|
null, // invalid, not an object
|
||||||
{seen: true}, // invalid, no type or id
|
{ seen: true }, // invalid, no type or id
|
||||||
{id: 123}, // invalid, no type
|
{ id: 123 }, // invalid, no type
|
||||||
// {type: 'ABC'}, // invalid, no id, not included here because the id would be added automatically
|
// invalid, no id, not included here because the id would be added automatically
|
||||||
{type: 'ABC', id: '123'}, // valid
|
// {type: 'ABC'},
|
||||||
|
{ type: 'ABC', id: '123' }, // valid
|
||||||
];
|
];
|
||||||
|
|
||||||
responseMiddleware(req, res, next);
|
responseMiddleware(req, res, next);
|
||||||
res.respond(200, {field: 1});
|
res.respond(200, { field: 1 });
|
||||||
|
|
||||||
expect(res.json).to.be.calledOnce;
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
success: true,
|
success: true,
|
||||||
data: {field: 1},
|
data: { field: 1 },
|
||||||
notifications: [
|
notifications: [
|
||||||
{
|
{
|
||||||
type: 'ABC',
|
type: 'ABC',
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
import { each, find } from 'lodash';
|
||||||
import { model as Challenge } from '../../../../website/server/models/challenge';
|
import { model as Challenge } from '../../../../website/server/models/challenge';
|
||||||
import { model as Group } from '../../../../website/server/models/group';
|
import { model as Group } from '../../../../website/server/models/group';
|
||||||
import { model as User } from '../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
import * as Tasks from '../../../../website/server/models/task';
|
import * as Tasks from '../../../../website/server/models/task';
|
||||||
import common from '../../../../website/common/';
|
import common from '../../../../website/common';
|
||||||
import { each, find } from 'lodash';
|
|
||||||
|
|
||||||
describe('Challenge Model', () => {
|
describe('Challenge Model', () => {
|
||||||
let guild, leader, challenge, task;
|
let guild; let leader; let challenge; let
|
||||||
let tasksToTest = {
|
task;
|
||||||
|
const tasksToTest = {
|
||||||
habit: {
|
habit: {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
@@ -74,11 +75,15 @@ describe('Challenge Model', () => {
|
|||||||
it('adds tasks to challenge and challenge members', async () => {
|
it('adds tasks to challenge and challenge members', async () => {
|
||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
|
|
||||||
const updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
const updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
const syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) {
|
const syncedTask = find(
|
||||||
return updatedLeadersTask.type === taskValue.type && updatedLeadersTask.text === taskValue.text;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => (
|
||||||
|
updatedLeadersTask.type === taskValue.type
|
||||||
|
&& updatedLeadersTask.text === taskValue.text
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
expect(syncedTask).to.exist;
|
expect(syncedTask).to.exist;
|
||||||
expect(syncedTask.notes).to.eql(task.notes);
|
expect(syncedTask.notes).to.eql(task.notes);
|
||||||
@@ -88,18 +93,22 @@ describe('Challenge Model', () => {
|
|||||||
it('syncs a challenge to a user', async () => {
|
it('syncs a challenge to a user', async () => {
|
||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
|
|
||||||
let newMember = new User({
|
const newMember = new User({
|
||||||
guilds: [guild._id],
|
guilds: [guild._id],
|
||||||
});
|
});
|
||||||
await newMember.save();
|
await newMember.save();
|
||||||
|
|
||||||
await challenge.syncToUser(newMember);
|
await challenge.syncToUser(newMember);
|
||||||
|
|
||||||
let updatedNewMember = await User.findById(newMember._id);
|
const updatedNewMember = await User.findById(newMember._id);
|
||||||
let updatedNewMemberTasks = await Tasks.Task.find({_id: { $in: updatedNewMember.tasksOrder[`${taskType}s`]}});
|
const updatedNewMemberTasks = await Tasks.Task.find({ _id: { $in: updatedNewMember.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedNewMemberTasks, function findNewTask (updatedNewMemberTask) {
|
const syncedTask = find(
|
||||||
return updatedNewMemberTask.type === taskValue.type && updatedNewMemberTask.text === taskValue.text;
|
updatedNewMemberTasks,
|
||||||
});
|
updatedNewMemberTask => (
|
||||||
|
updatedNewMemberTask.type === taskValue.type
|
||||||
|
&& updatedNewMemberTask.text === taskValue.text
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
expect(updatedNewMember.challenges).to.contain(challenge._id);
|
expect(updatedNewMember.challenges).to.contain(challenge._id);
|
||||||
expect(updatedNewMember.tags[7].id).to.equal(challenge._id);
|
expect(updatedNewMember.tags[7].id).to.equal(challenge._id);
|
||||||
@@ -111,30 +120,32 @@ describe('Challenge Model', () => {
|
|||||||
it('syncs a challenge to a user with the existing task', async () => {
|
it('syncs a challenge to a user with the existing task', async () => {
|
||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
let updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
let updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) {
|
let syncedTask = find(
|
||||||
return updatedLeadersTask.challenge.taskId === task._id;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => updatedLeadersTask.challenge.taskId === task._id,
|
||||||
|
);
|
||||||
|
|
||||||
let createdAtBefore = syncedTask.createdAt;
|
const createdAtBefore = syncedTask.createdAt;
|
||||||
let attributeBefore = syncedTask.attribute;
|
const attributeBefore = syncedTask.attribute;
|
||||||
|
|
||||||
let newTitle = 'newName';
|
const newTitle = 'newName';
|
||||||
task.text = newTitle;
|
task.text = newTitle;
|
||||||
task.attribute = 'int';
|
task.attribute = 'int';
|
||||||
await task.save();
|
await task.save();
|
||||||
await challenge.syncToUser(leader);
|
await challenge.syncToUser(leader);
|
||||||
|
|
||||||
updatedLeader = await User.findOne({_id: leader._id});
|
updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
|
|
||||||
syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) {
|
syncedTask = find(
|
||||||
return updatedLeadersTask.challenge.taskId === task._id;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => updatedLeadersTask.challenge.taskId === task._id,
|
||||||
|
);
|
||||||
|
|
||||||
let createdAtAfter = syncedTask.createdAt;
|
const createdAtAfter = syncedTask.createdAt;
|
||||||
let attributeAfter = syncedTask.attribute;
|
const attributeAfter = syncedTask.attribute;
|
||||||
|
|
||||||
expect(createdAtBefore).to.eql(createdAtAfter);
|
expect(createdAtBefore).to.eql(createdAtAfter);
|
||||||
expect(attributeBefore).to.eql(attributeAfter);
|
expect(attributeBefore).to.eql(attributeAfter);
|
||||||
@@ -142,10 +153,10 @@ describe('Challenge Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('updates tasks to challenge and challenge members', async () => {
|
it('updates tasks to challenge and challenge members', async () => {
|
||||||
let updatedTaskName = 'Updated Test Habit';
|
const updatedTaskName = 'Updated Test Habit';
|
||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
|
|
||||||
let req = {
|
const req = {
|
||||||
body: { text: updatedTaskName },
|
body: { text: updatedTaskName },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,8 +165,8 @@ describe('Challenge Model', () => {
|
|||||||
|
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder[`${taskType}s`][0]);
|
const updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder[`${taskType}s`][0]);
|
||||||
|
|
||||||
expect(updatedUserTask.text).to.equal(updatedTaskName);
|
expect(updatedUserTask.text).to.equal(updatedTaskName);
|
||||||
});
|
});
|
||||||
@@ -164,8 +175,8 @@ describe('Challenge Model', () => {
|
|||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
await challenge.removeTask(task);
|
await challenge.removeTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findOne({_id: updatedLeader.tasksOrder[`${taskType}s`][0]}).exec();
|
const updatedUserTask = await Tasks.Task.findOne({ _id: updatedLeader.tasksOrder[`${taskType}s`][0] }).exec();
|
||||||
|
|
||||||
expect(updatedUserTask.challenge.broken).to.equal('TASK_DELETED');
|
expect(updatedUserTask.challenge.broken).to.equal('TASK_DELETED');
|
||||||
});
|
});
|
||||||
@@ -174,11 +185,15 @@ describe('Challenge Model', () => {
|
|||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
await challenge.unlinkTasks(leader, 'remove-all');
|
await challenge.unlinkTasks(leader, 'remove-all');
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) {
|
const syncedTask = find(
|
||||||
return updatedLeadersTask.type === taskValue.type && updatedLeadersTask.text === taskValue.text;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => (
|
||||||
|
updatedLeadersTask.type === taskValue.type
|
||||||
|
&& updatedLeadersTask.text === taskValue.text
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
expect(syncedTask).to.not.exist;
|
expect(syncedTask).to.not.exist;
|
||||||
});
|
});
|
||||||
@@ -187,11 +202,15 @@ describe('Challenge Model', () => {
|
|||||||
await challenge.addTasks([task]);
|
await challenge.addTasks([task]);
|
||||||
await challenge.unlinkTasks(leader, 'keep-all');
|
await challenge.unlinkTasks(leader, 'keep-all');
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) {
|
const syncedTask = find(
|
||||||
return updatedLeadersTask.type === taskValue.type && updatedLeadersTask.text === taskValue.text;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => (
|
||||||
|
updatedLeadersTask.type === taskValue.type
|
||||||
|
&& updatedLeadersTask.text === taskValue.text
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
expect(syncedTask).to.exist;
|
expect(syncedTask).to.exist;
|
||||||
expect(syncedTask.challenge._id).to.be.undefined;
|
expect(syncedTask.challenge._id).to.be.undefined;
|
||||||
@@ -212,8 +231,8 @@ describe('Challenge Model', () => {
|
|||||||
|
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.habits[0]);
|
const updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.habits[0]);
|
||||||
|
|
||||||
expect(updatedUserTask.up).to.equal(true);
|
expect(updatedUserTask.up).to.equal(true);
|
||||||
expect(updatedUserTask.down).to.equal(false);
|
expect(updatedUserTask.down).to.equal(false);
|
||||||
@@ -229,8 +248,8 @@ describe('Challenge Model', () => {
|
|||||||
task.date = new Date();
|
task.date = new Date();
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.todos[0]);
|
const updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.todos[0]);
|
||||||
|
|
||||||
expect(updatedUserTask.date).to.exist;
|
expect(updatedUserTask.date).to.exist;
|
||||||
});
|
});
|
||||||
@@ -247,8 +266,8 @@ describe('Challenge Model', () => {
|
|||||||
});
|
});
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.todos[0]);
|
const updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.todos[0]);
|
||||||
|
|
||||||
expect(updatedUserTask.checklist.toObject()).to.deep.equal([]);
|
expect(updatedUserTask.checklist.toObject()).to.deep.equal([]);
|
||||||
});
|
});
|
||||||
@@ -263,8 +282,8 @@ describe('Challenge Model', () => {
|
|||||||
task.everyX = 2;
|
task.everyX = 2;
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.dailys[0]);
|
const updatedUserTask = await Tasks.Task.findById(updatedLeader.tasksOrder.dailys[0]);
|
||||||
|
|
||||||
expect(updatedUserTask.everyX).to.eql(2);
|
expect(updatedUserTask.everyX).to.eql(2);
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,13 @@
|
|||||||
|
import { each, find, findIndex } from 'lodash';
|
||||||
import { model as Challenge } from '../../../../website/server/models/challenge';
|
import { model as Challenge } from '../../../../website/server/models/challenge';
|
||||||
import { model as Group } from '../../../../website/server/models/group';
|
import { model as Group } from '../../../../website/server/models/group';
|
||||||
import { model as User } from '../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
import * as Tasks from '../../../../website/server/models/task';
|
import * as Tasks from '../../../../website/server/models/task';
|
||||||
import { each, find, findIndex } from 'lodash';
|
|
||||||
|
|
||||||
describe('Group Task Methods', () => {
|
describe('Group Task Methods', () => {
|
||||||
let guild, leader, challenge, task;
|
let guild; let leader; let challenge; let
|
||||||
let tasksToTest = {
|
task;
|
||||||
|
const tasksToTest = {
|
||||||
habit: {
|
habit: {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
@@ -79,9 +80,9 @@ describe('Group Task Methods', () => {
|
|||||||
it('syncs an assigned task to a user', async () => {
|
it('syncs an assigned task to a user', async () => {
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let tagIndex = findIndex(updatedLeader.tags, {id: guild._id});
|
const tagIndex = findIndex(updatedLeader.tags, { id: guild._id });
|
||||||
let newTag = updatedLeader.tags[tagIndex];
|
const newTag = updatedLeader.tags[tagIndex];
|
||||||
|
|
||||||
expect(newTag.id).to.equal(guild._id);
|
expect(newTag.id).to.equal(guild._id);
|
||||||
expect(newTag.name).to.equal(guild.name);
|
expect(newTag.name).to.equal(guild.name);
|
||||||
@@ -91,9 +92,9 @@ describe('Group Task Methods', () => {
|
|||||||
it('create tags for a user when task is synced', async () => {
|
it('create tags for a user when task is synced', async () => {
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(task.group.assignedUsers).to.contain(leader._id);
|
expect(task.group.assignedUsers).to.contain(leader._id);
|
||||||
expect(syncedTask).to.exist;
|
expect(syncedTask).to.exist;
|
||||||
@@ -101,13 +102,13 @@ describe('Group Task Methods', () => {
|
|||||||
|
|
||||||
it('syncs updated info for assigned task to a user', async () => {
|
it('syncs updated info for assigned task to a user', async () => {
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
let updatedTaskName = 'Update Task name';
|
const updatedTaskName = 'Update Task name';
|
||||||
task.text = updatedTaskName;
|
task.text = updatedTaskName;
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(task.group.assignedUsers).to.contain(leader._id);
|
expect(task.group.assignedUsers).to.contain(leader._id);
|
||||||
expect(syncedTask).to.exist;
|
expect(syncedTask).to.exist;
|
||||||
@@ -117,9 +118,9 @@ describe('Group Task Methods', () => {
|
|||||||
it('syncs checklist items to an assigned user', async () => {
|
it('syncs checklist items to an assigned user', async () => {
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
if (task.type !== 'daily' && task.type !== 'todo') return;
|
if (task.type !== 'daily' && task.type !== 'todo') return;
|
||||||
|
|
||||||
@@ -141,19 +142,19 @@ describe('Group Task Methods', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('syncs updated info for assigned task to all users', async () => {
|
it('syncs updated info for assigned task to all users', async () => {
|
||||||
let updatedTaskName = 'Update Task name';
|
const updatedTaskName = 'Update Task name';
|
||||||
task.text = updatedTaskName;
|
task.text = updatedTaskName;
|
||||||
task.group.approval.required = true;
|
task.group.approval.required = true;
|
||||||
|
|
||||||
await guild.updateTask(task);
|
await guild.updateTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
let updatedMember = await User.findOne({_id: newMember._id});
|
const updatedMember = await User.findOne({ _id: newMember._id });
|
||||||
let updatedMemberTasks = await Tasks.Task.find({_id: { $in: updatedMember.tasksOrder[`${taskType}s`]}});
|
const updatedMemberTasks = await Tasks.Task.find({ _id: { $in: updatedMember.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
const syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(task.group.assignedUsers).to.contain(leader._id);
|
expect(task.group.assignedUsers).to.contain(leader._id);
|
||||||
expect(syncedTask).to.exist;
|
expect(syncedTask).to.exist;
|
||||||
@@ -169,22 +170,22 @@ describe('Group Task Methods', () => {
|
|||||||
it('syncs a new checklist item to all assigned users', async () => {
|
it('syncs a new checklist item to all assigned users', async () => {
|
||||||
if (task.type !== 'daily' && task.type !== 'todo') return;
|
if (task.type !== 'daily' && task.type !== 'todo') return;
|
||||||
|
|
||||||
let newCheckListItem = {
|
const newCheckListItem = {
|
||||||
text: 'Checklist Item 1',
|
text: 'Checklist Item 1',
|
||||||
completed: false,
|
completed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
task.checklist.push(newCheckListItem);
|
task.checklist.push(newCheckListItem);
|
||||||
|
|
||||||
await guild.updateTask(task, {newCheckListItem});
|
await guild.updateTask(task, { newCheckListItem });
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
let updatedMember = await User.findOne({_id: newMember._id});
|
const updatedMember = await User.findOne({ _id: newMember._id });
|
||||||
let updatedMemberTasks = await Tasks.Task.find({_id: { $in: updatedMember.tasksOrder[`${taskType}s`]}});
|
const updatedMemberTasks = await Tasks.Task.find({ _id: { $in: updatedMember.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
const syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(syncedTask.checklist.length).to.equal(task.checklist.length);
|
expect(syncedTask.checklist.length).to.equal(task.checklist.length);
|
||||||
expect(syncedTask.checklist[1].text).to.equal(task.checklist[1].text);
|
expect(syncedTask.checklist[1].text).to.equal(task.checklist[1].text);
|
||||||
@@ -195,20 +196,20 @@ describe('Group Task Methods', () => {
|
|||||||
it('syncs updated info for checklist in assigned task to all users when flag is passed', async () => {
|
it('syncs updated info for checklist in assigned task to all users when flag is passed', async () => {
|
||||||
if (task.type !== 'daily' && task.type !== 'todo') return;
|
if (task.type !== 'daily' && task.type !== 'todo') return;
|
||||||
|
|
||||||
let updateCheckListText = 'Updated checklist item';
|
const updateCheckListText = 'Updated checklist item';
|
||||||
if (task.checklist) {
|
if (task.checklist) {
|
||||||
task.checklist[0].text = updateCheckListText;
|
task.checklist[0].text = updateCheckListText;
|
||||||
}
|
}
|
||||||
|
|
||||||
await guild.updateTask(task, {updateCheckListItems: [task.checklist[0]]});
|
await guild.updateTask(task, { updateCheckListItems: [task.checklist[0]] });
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
let updatedMember = await User.findOne({_id: newMember._id});
|
const updatedMember = await User.findOne({ _id: newMember._id });
|
||||||
let updatedMemberTasks = await Tasks.Task.find({_id: { $in: updatedMember.tasksOrder[`${taskType}s`]}});
|
const updatedMemberTasks = await Tasks.Task.find({ _id: { $in: updatedMember.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
const syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(syncedTask.checklist.length).to.equal(task.checklist.length);
|
expect(syncedTask.checklist.length).to.equal(task.checklist.length);
|
||||||
expect(syncedTask.checklist[0].text).to.equal(updateCheckListText);
|
expect(syncedTask.checklist[0].text).to.equal(updateCheckListText);
|
||||||
@@ -219,15 +220,15 @@ describe('Group Task Methods', () => {
|
|||||||
it('removes a checklist item in assigned task to all users when flag is passed with checklist id', async () => {
|
it('removes a checklist item in assigned task to all users when flag is passed with checklist id', async () => {
|
||||||
if (task.type !== 'daily' && task.type !== 'todo') return;
|
if (task.type !== 'daily' && task.type !== 'todo') return;
|
||||||
|
|
||||||
await guild.updateTask(task, {removedCheckListItemId: task.checklist[0].id});
|
await guild.updateTask(task, { removedCheckListItemId: task.checklist[0].id });
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
let updatedMember = await User.findOne({_id: newMember._id});
|
const updatedMember = await User.findOne({ _id: newMember._id });
|
||||||
let updatedMemberTasks = await Tasks.Task.find({_id: { $in: updatedMember.tasksOrder[`${taskType}s`]}});
|
const updatedMemberTasks = await Tasks.Task.find({ _id: { $in: updatedMember.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
const syncedMemberTask = find(updatedMemberTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(syncedTask.checklist.length).to.equal(0);
|
expect(syncedTask.checklist.length).to.equal(0);
|
||||||
expect(syncedMemberTask.checklist.length).to.equal(0);
|
expect(syncedMemberTask.checklist.length).to.equal(0);
|
||||||
@@ -238,9 +239,9 @@ describe('Group Task Methods', () => {
|
|||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
await guild.removeTask(task);
|
await guild.removeTask(task);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(syncedTask.group.broken).to.equal('TASK_DELETED');
|
expect(syncedTask.group.broken).to.equal('TASK_DELETED');
|
||||||
});
|
});
|
||||||
@@ -249,9 +250,9 @@ describe('Group Task Methods', () => {
|
|||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
await guild.unlinkTask(task, leader, 'remove-all');
|
await guild.unlinkTask(task, leader, 'remove-all');
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
const updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
const updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
expect(task.group.assignedUsers).to.not.contain(leader._id);
|
expect(task.group.assignedUsers).to.not.contain(leader._id);
|
||||||
expect(syncedTask).to.not.exist;
|
expect(syncedTask).to.not.exist;
|
||||||
@@ -260,17 +261,18 @@ describe('Group Task Methods', () => {
|
|||||||
it('unlinks and keeps group tasks for a user when keep-all is specified', async () => {
|
it('unlinks and keeps group tasks for a user when keep-all is specified', async () => {
|
||||||
await guild.syncTask(task, leader);
|
await guild.syncTask(task, leader);
|
||||||
|
|
||||||
let updatedLeader = await User.findOne({_id: leader._id});
|
let updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
let updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
const syncedTask = find(updatedLeadersTasks, findLinkedTask);
|
||||||
|
|
||||||
await guild.unlinkTask(task, leader, 'keep-all');
|
await guild.unlinkTask(task, leader, 'keep-all');
|
||||||
|
|
||||||
updatedLeader = await User.findOne({_id: leader._id});
|
updatedLeader = await User.findOne({ _id: leader._id });
|
||||||
updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}});
|
updatedLeadersTasks = await Tasks.Task.find({ _id: { $in: updatedLeader.tasksOrder[`${taskType}s`] } });
|
||||||
let updatedSyncedTask = find(updatedLeadersTasks, function findUpdatedLinkedTask (updatedLeadersTask) {
|
const updatedSyncedTask = find(
|
||||||
return updatedLeadersTask._id === syncedTask._id;
|
updatedLeadersTasks,
|
||||||
});
|
updatedLeadersTask => updatedLeadersTask._id === syncedTask._id,
|
||||||
|
);
|
||||||
|
|
||||||
expect(task.group.assignedUsers).to.not.contain(leader._id);
|
expect(task.group.assignedUsers).to.not.contain(leader._id);
|
||||||
expect(updatedSyncedTask).to.exist;
|
expect(updatedSyncedTask).to.exist;
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
|
import { each } from 'lodash';
|
||||||
import { model as Challenge } from '../../../../website/server/models/challenge';
|
import { model as Challenge } from '../../../../website/server/models/challenge';
|
||||||
import { model as Group } from '../../../../website/server/models/group';
|
import { model as Group } from '../../../../website/server/models/group';
|
||||||
import { model as User } from '../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
import * as Tasks from '../../../../website/server/models/task';
|
import * as Tasks from '../../../../website/server/models/task';
|
||||||
import { InternalServerError } from '../../../../website/server/libs/errors';
|
import { InternalServerError } from '../../../../website/server/libs/errors';
|
||||||
import { each } from 'lodash';
|
import { generateHistory } from '../../../helpers/api-unit.helper';
|
||||||
import { generateHistory } from '../../../helpers/api-unit.helper.js';
|
|
||||||
|
|
||||||
describe('Task Model', () => {
|
describe('Task Model', () => {
|
||||||
let guild, leader, challenge, task;
|
let guild; let leader; let challenge; let
|
||||||
let tasksToTest = {
|
task;
|
||||||
|
const tasksToTest = {
|
||||||
habit: {
|
habit: {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
@@ -62,11 +63,11 @@ describe('Task Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('preens challenge tasks history when scored', async () => {
|
it('preens challenge tasks history when scored', async () => {
|
||||||
let historyLengthBeforePreen = task.history.length;
|
const historyLengthBeforePreen = task.history.length;
|
||||||
|
|
||||||
await task.scoreChallengeTask(1.2);
|
await task.scoreChallengeTask(1.2);
|
||||||
|
|
||||||
let updatedTask = await Tasks.Task.findOne({_id: task._id});
|
const updatedTask = await Tasks.Task.findOne({ _id: task._id });
|
||||||
|
|
||||||
expect(historyLengthBeforePreen).to.be.greaterThan(updatedTask.history.length);
|
expect(historyLengthBeforePreen).to.be.greaterThan(updatedTask.history.length);
|
||||||
});
|
});
|
||||||
@@ -75,7 +76,8 @@ describe('Task Model', () => {
|
|||||||
|
|
||||||
describe('Static Methods', () => {
|
describe('Static Methods', () => {
|
||||||
describe('findByIdOrAlias', () => {
|
describe('findByIdOrAlias', () => {
|
||||||
let taskWithAlias, user;
|
let taskWithAlias; let
|
||||||
|
user;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = new User();
|
user = new User();
|
||||||
@@ -112,13 +114,13 @@ describe('Task Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns task by id', async () => {
|
it('returns task by id', async () => {
|
||||||
let foundTodo = await Tasks.Task.findByIdOrAlias(taskWithAlias._id, user._id);
|
const foundTodo = await Tasks.Task.findByIdOrAlias(taskWithAlias._id, user._id);
|
||||||
|
|
||||||
expect(foundTodo.text).to.eql(taskWithAlias.text);
|
expect(foundTodo.text).to.eql(taskWithAlias.text);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns task by alias', async () => {
|
it('returns task by alias', async () => {
|
||||||
let foundTodo = await Tasks.Task.findByIdOrAlias(taskWithAlias.alias, user._id);
|
const foundTodo = await Tasks.Task.findByIdOrAlias(taskWithAlias.alias, user._id);
|
||||||
|
|
||||||
expect(foundTodo.text).to.eql(taskWithAlias.text);
|
expect(foundTodo.text).to.eql(taskWithAlias.text);
|
||||||
});
|
});
|
||||||
@@ -134,7 +136,7 @@ describe('Task Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns null if task cannot be found', async () => {
|
it('returns null if task cannot be found', async () => {
|
||||||
let foundTask = await Tasks.Task.findByIdOrAlias('not-found', user._id);
|
const foundTask = await Tasks.Task.findByIdOrAlias('not-found', user._id);
|
||||||
|
|
||||||
expect(foundTask).to.eql(null);
|
expect(foundTask).to.eql(null);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import common from '../../../../website/common';
|
|||||||
|
|
||||||
describe('User Model', () => {
|
describe('User Model', () => {
|
||||||
it('keeps user._tmp when calling .toJSON', () => {
|
it('keeps user._tmp when calling .toJSON', () => {
|
||||||
let user = new User({
|
const user = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: 'username',
|
username: 'username',
|
||||||
@@ -17,26 +17,26 @@ describe('User Model', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
user._tmp = {ok: true};
|
user._tmp = { ok: true };
|
||||||
user._nonTmp = {ok: true};
|
user._nonTmp = { ok: true };
|
||||||
|
|
||||||
expect(user._tmp).to.eql({ok: true});
|
expect(user._tmp).to.eql({ ok: true });
|
||||||
expect(user._nonTmp).to.eql({ok: true});
|
expect(user._nonTmp).to.eql({ ok: true });
|
||||||
|
|
||||||
let toObject = user.toObject();
|
const toObject = user.toObject();
|
||||||
let toJSON = user.toJSON();
|
const toJSON = user.toJSON();
|
||||||
|
|
||||||
expect(toObject).to.not.have.keys('_tmp');
|
expect(toObject).to.not.have.keys('_tmp');
|
||||||
expect(toObject).to.not.have.keys('_nonTmp');
|
expect(toObject).to.not.have.keys('_nonTmp');
|
||||||
|
|
||||||
expect(toJSON).to.have.any.key('_tmp');
|
expect(toJSON).to.have.any.key('_tmp');
|
||||||
expect(toJSON._tmp).to.eql({ok: true});
|
expect(toJSON._tmp).to.eql({ ok: true });
|
||||||
expect(toJSON).to.not.have.keys('_nonTmp');
|
expect(toJSON).to.not.have.keys('_nonTmp');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add computed stats to a JSONified user object', () => {
|
it('can add computed stats to a JSONified user object', () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
let userToJSON = user.toJSON();
|
const userToJSON = user.toJSON();
|
||||||
|
|
||||||
expect(userToJSON.stats.maxMP).to.not.exist;
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
expect(userToJSON.stats.maxHealth).to.not.exist;
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
@@ -50,9 +50,9 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can transform user object without mongoose helpers', async () => {
|
it('can transform user object without mongoose helpers', async () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
await user.save();
|
await user.save();
|
||||||
let userToJSON = await User.findById(user._id).lean().exec();
|
const userToJSON = await User.findById(user._id).lean().exec();
|
||||||
|
|
||||||
expect(userToJSON.stats.maxMP).to.not.exist;
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
expect(userToJSON.stats.maxHealth).to.not.exist;
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
@@ -68,9 +68,9 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can transform user object without mongoose helpers (including computed stats)', async () => {
|
it('can transform user object without mongoose helpers (including computed stats)', async () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
await user.save();
|
await user.save();
|
||||||
let userToJSON = await User.findById(user._id).lean().exec();
|
const userToJSON = await User.findById(user._id).lean().exec();
|
||||||
|
|
||||||
expect(userToJSON.stats.maxMP).to.not.exist;
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
expect(userToJSON.stats.maxHealth).to.not.exist;
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
@@ -86,11 +86,11 @@ describe('User Model', () => {
|
|||||||
|
|
||||||
context('notifications', () => {
|
context('notifications', () => {
|
||||||
it('can add notifications without data', () => {
|
it('can add notifications without data', () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
|
|
||||||
user.addNotification('CRON');
|
user.addNotification('CRON');
|
||||||
|
|
||||||
let userToJSON = user.toJSON();
|
const userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
||||||
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
||||||
@@ -99,14 +99,15 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('removes invalid notifications when calling toJSON', () => {
|
it('removes invalid notifications when calling toJSON', () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
|
|
||||||
user.notifications = [
|
user.notifications = [
|
||||||
null, // invalid, not an object
|
null, // invalid, not an object
|
||||||
{seen: true}, // invalid, no type or id
|
{ seen: true }, // invalid, no type or id
|
||||||
{id: 123}, // invalid, no type
|
{ id: 123 }, // invalid, no type
|
||||||
// {type: 'ABC'}, // invalid, no id, not included here because the id would be added automatically
|
// invalid, no id, not included here because the id would be added automatically
|
||||||
{type: 'ABC', id: '123'}, // valid
|
// {type: 'ABC'},
|
||||||
|
{ type: 'ABC', id: '123' }, // valid
|
||||||
];
|
];
|
||||||
|
|
||||||
const userToJSON = user.toJSON();
|
const userToJSON = user.toJSON();
|
||||||
@@ -118,15 +119,15 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can add notifications with data and already marked as seen', () => {
|
it('can add notifications with data and already marked as seen', () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
|
|
||||||
user.addNotification('CRON', {field: 1}, true);
|
user.addNotification('CRON', { field: 1 }, true);
|
||||||
|
|
||||||
let userToJSON = user.toJSON();
|
const userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
||||||
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
||||||
expect(userToJSON.notifications[0].data).to.eql({field: 1});
|
expect(userToJSON.notifications[0].data).to.eql({ field: 1 });
|
||||||
expect(userToJSON.notifications[0].seen).to.eql(true);
|
expect(userToJSON.notifications[0].seen).to.eql(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,11 +136,11 @@ describe('User Model', () => {
|
|||||||
let user = new User();
|
let user = new User();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
await User.pushNotification({_id: user._id}, 'CRON');
|
await User.pushNotification({ _id: user._id }, 'CRON');
|
||||||
|
|
||||||
user = await User.findOne({_id: user._id}).exec();
|
user = await User.findOne({ _id: user._id }).exec();
|
||||||
|
|
||||||
let userToJSON = user.toJSON();
|
const userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
||||||
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
||||||
@@ -147,21 +148,21 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('validates notifications via static method', async () => {
|
it('validates notifications via static method', async () => {
|
||||||
let user = new User();
|
const user = new User();
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
expect(User.pushNotification({_id: user._id}, 'BAD_TYPE')).to.eventually.be.rejected;
|
expect(User.pushNotification({ _id: user._id }, 'BAD_TYPE')).to.eventually.be.rejected;
|
||||||
expect(User.pushNotification({_id: user._id}, 'CRON', null, 'INVALID_SEEN')).to.eventually.be.rejected;
|
expect(User.pushNotification({ _id: user._id }, 'CRON', null, 'INVALID_SEEN')).to.eventually.be.rejected;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds notifications without data for all given users via static method', async () => {
|
it('adds notifications without data for all given users via static method', async () => {
|
||||||
let user = new User();
|
let user = new User();
|
||||||
let otherUser = new User();
|
const otherUser = new User();
|
||||||
await Promise.all([user.save(), otherUser.save()]);
|
await Promise.all([user.save(), otherUser.save()]);
|
||||||
|
|
||||||
await User.pushNotification({_id: {$in: [user._id, otherUser._id]}}, 'CRON');
|
await User.pushNotification({ _id: { $in: [user._id, otherUser._id] } }, 'CRON');
|
||||||
|
|
||||||
user = await User.findOne({_id: user._id}).exec();
|
user = await User.findOne({ _id: user._id }).exec();
|
||||||
|
|
||||||
let userToJSON = user.toJSON();
|
let userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
@@ -170,7 +171,7 @@ describe('User Model', () => {
|
|||||||
expect(userToJSON.notifications[0].data).to.eql({});
|
expect(userToJSON.notifications[0].data).to.eql({});
|
||||||
expect(userToJSON.notifications[0].seen).to.eql(false);
|
expect(userToJSON.notifications[0].seen).to.eql(false);
|
||||||
|
|
||||||
user = await User.findOne({_id: otherUser._id}).exec();
|
user = await User.findOne({ _id: otherUser._id }).exec();
|
||||||
|
|
||||||
userToJSON = user.toJSON();
|
userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
@@ -182,27 +183,27 @@ describe('User Model', () => {
|
|||||||
|
|
||||||
it('adds notifications with data and seen status for all given users via static method', async () => {
|
it('adds notifications with data and seen status for all given users via static method', async () => {
|
||||||
let user = new User();
|
let user = new User();
|
||||||
let otherUser = new User();
|
const otherUser = new User();
|
||||||
await Promise.all([user.save(), otherUser.save()]);
|
await Promise.all([user.save(), otherUser.save()]);
|
||||||
|
|
||||||
await User.pushNotification({_id: {$in: [user._id, otherUser._id]}}, 'CRON', {field: 1}, true);
|
await User.pushNotification({ _id: { $in: [user._id, otherUser._id] } }, 'CRON', { field: 1 }, true);
|
||||||
|
|
||||||
user = await User.findOne({_id: user._id}).exec();
|
user = await User.findOne({ _id: user._id }).exec();
|
||||||
|
|
||||||
let userToJSON = user.toJSON();
|
let userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
||||||
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
||||||
expect(userToJSON.notifications[0].data).to.eql({field: 1});
|
expect(userToJSON.notifications[0].data).to.eql({ field: 1 });
|
||||||
expect(userToJSON.notifications[0].seen).to.eql(true);
|
expect(userToJSON.notifications[0].seen).to.eql(true);
|
||||||
|
|
||||||
user = await User.findOne({_id: otherUser._id}).exec();
|
user = await User.findOne({ _id: otherUser._id }).exec();
|
||||||
|
|
||||||
userToJSON = user.toJSON();
|
userToJSON = user.toJSON();
|
||||||
expect(user.notifications.length).to.equal(1);
|
expect(user.notifications.length).to.equal(1);
|
||||||
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
expect(userToJSON.notifications[0]).to.have.all.keys(['data', 'id', 'type', 'seen']);
|
||||||
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
expect(userToJSON.notifications[0].type).to.equal('CRON');
|
||||||
expect(userToJSON.notifications[0].data).to.eql({field: 1});
|
expect(userToJSON.notifications[0].data).to.eql({ field: 1 });
|
||||||
expect(userToJSON.notifications[0].seen).to.eql(true);
|
expect(userToJSON.notifications[0].seen).to.eql(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -245,7 +246,7 @@ describe('User Model', () => {
|
|||||||
let group;
|
let group;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = new User();
|
user = new User();
|
||||||
let leader = new User();
|
const leader = new User();
|
||||||
group = new Group({
|
group = new Group({
|
||||||
name: 'test',
|
name: 'test',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -379,7 +380,8 @@ describe('User Model', () => {
|
|||||||
|
|
||||||
// Create conditions for the Beast Master achievement to be awarded
|
// Create conditions for the Beast Master achievement to be awarded
|
||||||
user.achievements.beastMasterCount = 3;
|
user.achievements.beastMasterCount = 3;
|
||||||
expect(user.achievements.beastMaster).to.not.equal(true); // verify that it was not awarded initially
|
// verify that it was not awarded initially
|
||||||
|
expect(user.achievements.beastMaster).to.not.equal(true);
|
||||||
|
|
||||||
user = await user.save();
|
user = await user.save();
|
||||||
// verify that it's been awarded
|
// verify that it's been awarded
|
||||||
@@ -397,7 +399,8 @@ describe('User Model', () => {
|
|||||||
user = await User.findById(user._id).select('-items').exec();
|
user = await User.findById(user._id).select('-items').exec();
|
||||||
expect(user.isSelected('items')).to.equal(false);
|
expect(user.isSelected('items')).to.equal(false);
|
||||||
|
|
||||||
// create the conditions for the beast master achievement but this time it should not be awarded
|
// create the conditions for the beast master achievement
|
||||||
|
// but this time it should not be awarded
|
||||||
user.achievements.beastMasterCount = 3;
|
user.achievements.beastMasterCount = 3;
|
||||||
user = await user.save();
|
user = await user.save();
|
||||||
expect(user.achievements.beastMaster).to.equal(false);
|
expect(user.achievements.beastMaster).to.equal(false);
|
||||||
@@ -536,11 +539,9 @@ describe('User Model', () => {
|
|||||||
|
|
||||||
const today = moment('2017-12-06T00:00:00.000-06:00'); // 11 pm on 4 Texas
|
const today = moment('2017-12-06T00:00:00.000-06:00'); // 11 pm on 4 Texas
|
||||||
const req = {};
|
const req = {};
|
||||||
req.header = () => {
|
req.header = () => timezoneOffset + 60;
|
||||||
return timezoneOffset + 60;
|
|
||||||
};
|
|
||||||
|
|
||||||
const {daysMissed} = user.daysUserHasMissed(today, req);
|
const { daysMissed } = user.daysUserHasMissed(today, req);
|
||||||
|
|
||||||
expect(daysMissed).to.eql(0);
|
expect(daysMissed).to.eql(0);
|
||||||
});
|
});
|
||||||
@@ -554,11 +555,9 @@ describe('User Model', () => {
|
|||||||
|
|
||||||
const today = moment('2017-12-06T02:00:00.000-08:00');
|
const today = moment('2017-12-06T02:00:00.000-08:00');
|
||||||
const req = {};
|
const req = {};
|
||||||
req.header = () => {
|
req.header = () => timezoneOffset + 60;
|
||||||
return timezoneOffset + 60;
|
|
||||||
};
|
|
||||||
|
|
||||||
const {daysMissed} = user.daysUserHasMissed(today, req);
|
const { daysMissed } = user.daysUserHasMissed(today, req);
|
||||||
|
|
||||||
expect(daysMissed).to.eql(0);
|
expect(daysMissed).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ describe('UserNotification Model', () => {
|
|||||||
it('converts an array of notifications to a safe version', () => {
|
it('converts an array of notifications to a safe version', () => {
|
||||||
const notifications = [
|
const notifications = [
|
||||||
null, // invalid, not an object
|
null, // invalid, not an object
|
||||||
{seen: true}, // invalid, no type or id
|
{ seen: true }, // invalid, no type or id
|
||||||
{id: 123}, // invalid, no type
|
{ id: 123 }, // invalid, no type
|
||||||
{type: 'ABC'}, // invalid, no id
|
{ type: 'ABC' }, // invalid, no id
|
||||||
new UserNotification({type: 'ABC', id: 123}), // valid
|
new UserNotification({ type: 'ABC', id: 123 }), // valid
|
||||||
];
|
];
|
||||||
|
|
||||||
const notificationsToJSON = UserNotification.convertNotificationsToSafeJson(notifications);
|
const notificationsToJSON = UserNotification.convertNotificationsToSafeJson(notifications);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import { model as Webhook } from '../../../../website/server/models/webhook';
|
import { model as Webhook } from '../../../../website/server/models/webhook';
|
||||||
import { BadRequest } from '../../../../website/server/libs/errors';
|
import { BadRequest } from '../../../../website/server/libs/errors';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
import apiError from '../../../../website/server/libs/apiError';
|
import apiError from '../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('Webhook Model', () => {
|
describe('Webhook Model', () => {
|
||||||
@@ -33,7 +33,7 @@ describe('Webhook Model', () => {
|
|||||||
it('it provides default values for options', () => {
|
it('it provides default values for options', () => {
|
||||||
delete config.options;
|
delete config.options;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ describe('Webhook Model', () => {
|
|||||||
it('provides missing task options', () => {
|
it('provides missing task options', () => {
|
||||||
delete config.options.created;
|
delete config.options.created;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ describe('Webhook Model', () => {
|
|||||||
it('discards additional options', () => {
|
it('discards additional options', () => {
|
||||||
config.options.foo = 'another option';
|
config.options.foo = 'another option';
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -79,12 +79,12 @@ describe('Webhook Model', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
['created', 'updated', 'deleted', 'scored', 'checklistScored'].forEach((option) => {
|
['created', 'updated', 'deleted', 'scored', 'checklistScored'].forEach(option => {
|
||||||
it(`validates that ${option} is a boolean`, (done) => {
|
it(`validates that ${option} is a boolean`, done => {
|
||||||
config.options[option] = 'not a boolean';
|
config.options[option] = 'not a boolean';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -115,7 +115,7 @@ describe('Webhook Model', () => {
|
|||||||
it('it provides default values for options', () => {
|
it('it provides default values for options', () => {
|
||||||
delete config.options;
|
delete config.options;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ describe('Webhook Model', () => {
|
|||||||
it('provides missing user options', () => {
|
it('provides missing user options', () => {
|
||||||
delete config.options.petHatched;
|
delete config.options.petHatched;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ describe('Webhook Model', () => {
|
|||||||
it('discards additional options', () => {
|
it('discards additional options', () => {
|
||||||
config.options.foo = 'another option';
|
config.options.foo = 'another option';
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -155,12 +155,12 @@ describe('Webhook Model', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
['petHatched', 'petHatched', 'leveledUp'].forEach((option) => {
|
['petHatched', 'petHatched', 'leveledUp'].forEach(option => {
|
||||||
it(`validates that ${option} is a boolean`, (done) => {
|
it(`validates that ${option} is a boolean`, done => {
|
||||||
config.options[option] = 'not a boolean';
|
config.options[option] = 'not a boolean';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -190,7 +190,7 @@ describe('Webhook Model', () => {
|
|||||||
it('it provides default values for options', () => {
|
it('it provides default values for options', () => {
|
||||||
delete config.options;
|
delete config.options;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ describe('Webhook Model', () => {
|
|||||||
it('provides missing user options', () => {
|
it('provides missing user options', () => {
|
||||||
delete config.options.questStarted;
|
delete config.options.questStarted;
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ describe('Webhook Model', () => {
|
|||||||
it('discards additional options', () => {
|
it('discards additional options', () => {
|
||||||
config.options.foo = 'another option';
|
config.options.foo = 'another option';
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -227,12 +227,12 @@ describe('Webhook Model', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
['questStarted', 'questFinished'].forEach((option) => {
|
['questStarted', 'questFinished'].forEach(option => {
|
||||||
it(`validates that ${option} is a boolean`, (done) => {
|
it(`validates that ${option} is a boolean`, done => {
|
||||||
config.options[option] = 'not a boolean';
|
config.options[option] = 'not a boolean';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -259,7 +259,7 @@ describe('Webhook Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates options', () => {
|
it('creates options', () => {
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ describe('Webhook Model', () => {
|
|||||||
it('discards additional objects', () => {
|
it('discards additional objects', () => {
|
||||||
config.options.foo = 'another thing';
|
config.options.foo = 'another thing';
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
@@ -279,11 +279,11 @@ describe('Webhook Model', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('requires groupId option to be a uuid', (done) => {
|
it('requires groupId option to be a uuid', done => {
|
||||||
config.options.groupId = 'not a uuid';
|
config.options.groupId = 'not a uuid';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -310,7 +310,7 @@ describe('Webhook Model', () => {
|
|||||||
it('discards additional objects', () => {
|
it('discards additional objects', () => {
|
||||||
config.options.foo = 'another thing';
|
config.options.foo = 'another thing';
|
||||||
|
|
||||||
let wh = new Webhook(config);
|
const wh = new Webhook(config);
|
||||||
|
|
||||||
wh.formatOptions(res);
|
wh.formatOptions(res);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
@@ -6,11 +7,10 @@ import {
|
|||||||
checkExistence,
|
checkExistence,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('DELETE /challenges/:challengeId', () => {
|
describe('DELETE /challenges/:challengeId', () => {
|
||||||
it('returns error when challengeId is not a valid UUID', async () => {
|
it('returns error when challengeId is not a valid UUID', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
await expect(user.del('/challenges/test')).to.eventually.be.rejected.and.eql({
|
await expect(user.del('/challenges/test')).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -19,7 +19,7 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when challengeId is not for a valid challenge', async () => {
|
it('returns error when challengeId is not for a valid challenge', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.del(`/challenges/${generateUUID()}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.del(`/challenges/${generateUUID()}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -32,10 +32,10 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
let groupLeader;
|
let groupLeader;
|
||||||
let group;
|
let group;
|
||||||
let challenge;
|
let challenge;
|
||||||
let taskText = 'A challenge task text';
|
const taskText = 'A challenge task text';
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup();
|
const populatedGroup = await createAndPopulateGroup();
|
||||||
|
|
||||||
groupLeader = populatedGroup.groupLeader;
|
groupLeader = populatedGroup.groupLeader;
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
@@ -44,14 +44,14 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
||||||
{type: 'habit', text: taskText},
|
{ type: 'habit', text: taskText },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await challenge.sync();
|
await challenge.sync();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when user doesn\'t have permissions to delete the challenge', async () => {
|
it('returns an error when user doesn\'t have permissions to delete the challenge', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.del(`/challenges/${challenge._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.del(`/challenges/${challenge._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
@@ -69,7 +69,7 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('refunds gems to group leader', async () => {
|
it('refunds gems to group leader', async () => {
|
||||||
let oldBalance = (await groupLeader.sync()).balance;
|
const oldBalance = (await groupLeader.sync()).balance;
|
||||||
|
|
||||||
await groupLeader.del(`/challenges/${challenge._id}`);
|
await groupLeader.del(`/challenges/${challenge._id}`);
|
||||||
|
|
||||||
@@ -83,10 +83,8 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
|
|
||||||
await sleep(0.5);
|
await sleep(0.5);
|
||||||
|
|
||||||
let tasks = await groupLeader.get('/tasks/user');
|
const tasks = await groupLeader.get('/tasks/user');
|
||||||
let testTask = _.find(tasks, (task) => {
|
const testTask = _.find(tasks, task => task.text === taskText);
|
||||||
return task.text === taskText;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(testTask.challenge.broken).to.eql('CHALLENGE_DELETED');
|
expect(testTask.challenge.broken).to.eql('CHALLENGE_DELETED');
|
||||||
expect(testTask.challenge.winner).to.be.null;
|
expect(testTask.challenge.winner).to.be.null;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId', () => {
|
describe('GET /challenges/:challengeId', () => {
|
||||||
it('fails if challenge doesn\'t exists', async () => {
|
it('fails if challenge doesn\'t exists', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
await expect(user.get(`/challenges/${generateUUID()}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(`/challenges/${generateUUID()}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -25,8 +25,8 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = await generateUser();
|
user = await generateUser();
|
||||||
|
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
groupDetails: {type: 'guild', privacy: 'public'},
|
groupDetails: { type: 'guild', privacy: 'public' },
|
||||||
});
|
});
|
||||||
|
|
||||||
groupLeader = populatedGroup.groupLeader;
|
groupLeader = populatedGroup.groupLeader;
|
||||||
@@ -38,7 +38,7 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
|
|
||||||
it('should return challenge data', async () => {
|
it('should return challenge data', async () => {
|
||||||
await challenge.sync();
|
await challenge.sync();
|
||||||
let chal = await user.get(`/challenges/${challenge._id}`);
|
const chal = await user.get(`/challenges/${challenge._id}`);
|
||||||
expect(chal.memberCount).to.equal(challenge.memberCount);
|
expect(chal.memberCount).to.equal(challenge.memberCount);
|
||||||
expect(chal.name).to.equal(challenge.name);
|
expect(chal.name).to.equal(challenge.name);
|
||||||
expect(chal._id).to.equal(challenge._id);
|
expect(chal._id).to.equal(challenge._id);
|
||||||
@@ -46,7 +46,7 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: groupLeader._id,
|
_id: groupLeader._id,
|
||||||
id: groupLeader._id,
|
id: groupLeader._id,
|
||||||
profile: {name: groupLeader.profile.name},
|
profile: { name: groupLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: groupLeader.auth.local.username,
|
username: groupLeader.auth.local.username,
|
||||||
@@ -81,8 +81,8 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
groupDetails: {type: 'guild', privacy: 'private'},
|
groupDetails: { type: 'guild', privacy: 'private' },
|
||||||
members: 2,
|
members: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,8 +90,8 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
members = populatedGroup.members;
|
members = populatedGroup.members;
|
||||||
|
|
||||||
challengeLeader = members[0];
|
challengeLeader = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
otherMember = members[1];
|
otherMember = members[1]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(challengeLeader, group);
|
challenge = await generateChallenge(challengeLeader, group);
|
||||||
});
|
});
|
||||||
@@ -105,14 +105,14 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns challenge data for any user in the guild', async () => {
|
it('returns challenge data for any user in the guild', async () => {
|
||||||
let chal = await otherMember.get(`/challenges/${challenge._id}`);
|
const chal = await otherMember.get(`/challenges/${challenge._id}`);
|
||||||
expect(chal.name).to.equal(challenge.name);
|
expect(chal.name).to.equal(challenge.name);
|
||||||
expect(chal._id).to.equal(challenge._id);
|
expect(chal._id).to.equal(challenge._id);
|
||||||
|
|
||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: challengeLeader._id,
|
_id: challengeLeader._id,
|
||||||
id: challengeLeader._id,
|
id: challengeLeader._id,
|
||||||
profile: {name: challengeLeader.profile.name},
|
profile: { name: challengeLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: challengeLeader.auth.local.username,
|
username: challengeLeader.auth.local.username,
|
||||||
@@ -139,14 +139,14 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
await challengeLeader.sync();
|
await challengeLeader.sync();
|
||||||
expect(challengeLeader.guilds).to.be.empty; // check that leaving worked
|
expect(challengeLeader.guilds).to.be.empty; // check that leaving worked
|
||||||
|
|
||||||
let chal = await challengeLeader.get(`/challenges/${challenge._id}`);
|
const chal = await challengeLeader.get(`/challenges/${challenge._id}`);
|
||||||
expect(chal.name).to.equal(challenge.name);
|
expect(chal.name).to.equal(challenge.name);
|
||||||
expect(chal._id).to.equal(challenge._id);
|
expect(chal._id).to.equal(challenge._id);
|
||||||
|
|
||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: challengeLeader._id,
|
_id: challengeLeader._id,
|
||||||
id: challengeLeader._id,
|
id: challengeLeader._id,
|
||||||
profile: {name: challengeLeader.profile.name},
|
profile: { name: challengeLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: challengeLeader.auth.local.username,
|
username: challengeLeader.auth.local.username,
|
||||||
@@ -171,8 +171,8 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
groupDetails: {type: 'party', privacy: 'private'},
|
groupDetails: { type: 'party', privacy: 'private' },
|
||||||
members: 2,
|
members: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -180,8 +180,8 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
members = populatedGroup.members;
|
members = populatedGroup.members;
|
||||||
|
|
||||||
challengeLeader = members[0];
|
challengeLeader = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
otherMember = members[1];
|
otherMember = members[1]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(challengeLeader, group);
|
challenge = await generateChallenge(challengeLeader, group);
|
||||||
});
|
});
|
||||||
@@ -195,14 +195,14 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns challenge data for any user in the party', async () => {
|
it('returns challenge data for any user in the party', async () => {
|
||||||
let chal = await otherMember.get(`/challenges/${challenge._id}`);
|
const chal = await otherMember.get(`/challenges/${challenge._id}`);
|
||||||
expect(chal.name).to.equal(challenge.name);
|
expect(chal.name).to.equal(challenge.name);
|
||||||
expect(chal._id).to.equal(challenge._id);
|
expect(chal._id).to.equal(challenge._id);
|
||||||
|
|
||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: challengeLeader._id,
|
_id: challengeLeader._id,
|
||||||
id: challengeLeader._id,
|
id: challengeLeader._id,
|
||||||
profile: {name: challengeLeader.profile.name},
|
profile: { name: challengeLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: challengeLeader.auth.local.username,
|
username: challengeLeader.auth.local.username,
|
||||||
@@ -229,14 +229,14 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
await challengeLeader.sync();
|
await challengeLeader.sync();
|
||||||
expect(challengeLeader.party._id).to.be.undefined; // check that leaving worked
|
expect(challengeLeader.party._id).to.be.undefined; // check that leaving worked
|
||||||
|
|
||||||
let chal = await challengeLeader.get(`/challenges/${challenge._id}`);
|
const chal = await challengeLeader.get(`/challenges/${challenge._id}`);
|
||||||
expect(chal.name).to.equal(challenge.name);
|
expect(chal.name).to.equal(challenge.name);
|
||||||
expect(chal._id).to.equal(challenge._id);
|
expect(chal._id).to.equal(challenge._id);
|
||||||
|
|
||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: challengeLeader._id,
|
_id: challengeLeader._id,
|
||||||
id: challengeLeader._id,
|
id: challengeLeader._id,
|
||||||
profile: {name: challengeLeader.profile.name},
|
profile: { name: challengeLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: challengeLeader.auth.local.username,
|
username: challengeLeader.auth.local.username,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
@@ -5,7 +6,6 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
sleep,
|
sleep,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/export/csv', () => {
|
describe('GET /challenges/:challengeId/export/csv', () => {
|
||||||
let groupLeader;
|
let groupLeader;
|
||||||
@@ -15,7 +15,7 @@ describe('GET /challenges/:challengeId/export/csv', () => {
|
|||||||
let user;
|
let user;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 3,
|
members: 3,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ describe('GET /challenges/:challengeId/export/csv', () => {
|
|||||||
await members[2].post(`/challenges/${challenge._id}/join`);
|
await members[2].post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
||||||
{type: 'habit', text: 'Task 1'},
|
{ type: 'habit', text: 'Task 1' },
|
||||||
{type: 'todo', text: 'Task 2'},
|
{ type: 'todo', text: 'Task 2' },
|
||||||
]);
|
]);
|
||||||
await sleep(0.5); // Make sure tasks are synced to the users
|
await sleep(0.5); // Make sure tasks are synced to the users
|
||||||
await members[0].sync();
|
await members[0].sync();
|
||||||
@@ -74,7 +74,7 @@ describe('GET /challenges/:challengeId/export/csv', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should successfully return when it contains erroneous residue user data', async () => {
|
it('should successfully return when it contains erroneous residue user data', async () => {
|
||||||
await members[0].update({challenges: []});
|
await members[0].update({ challenges: [] });
|
||||||
const res = await members[1].get(`/challenges/${challenge._id}/export/csv`);
|
const res = await members[1].get(`/challenges/${challenge._id}/export/csv`);
|
||||||
const sortedMembers = _.sortBy([members[1], members[2], groupLeader], '_id');
|
const sortedMembers = _.sortBy([members[1], members[2], groupLeader], '_id');
|
||||||
const splitRes = res.split('\n');
|
const splitRes = res.split('\n');
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
@@ -5,7 +6,6 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/members', () => {
|
describe('GET /challenges/:challengeId/members', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -31,9 +31,9 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user isn\'t in the private group and isn\'t challenge leader', async () => {
|
it('fails if user isn\'t in the private group and isn\'t challenge leader', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', privacy: 'private'});
|
const group = await generateGroup(user, { type: 'party', privacy: 'private' });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
let anotherUser = await generateUser();
|
const anotherUser = await generateUser();
|
||||||
|
|
||||||
await expect(anotherUser.get(`/challenges/${challenge._id}/members`)).to.eventually.be.rejected.and.eql({
|
await expect(anotherUser.get(`/challenges/${challenge._id}/members`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -43,23 +43,23 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works if user isn\'t in the private group but is challenge leader', async () => {
|
it('works if user isn\'t in the private group but is challenge leader', async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
groupDetails: {type: 'party', privacy: 'private'},
|
groupDetails: { type: 'party', privacy: 'private' },
|
||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
let groupLeader = populatedGroup.groupLeader;
|
const { groupLeader } = populatedGroup;
|
||||||
let challengeLeader = populatedGroup.members[0];
|
const challengeLeader = populatedGroup.members[0];
|
||||||
let challenge = await generateChallenge(challengeLeader, populatedGroup.group);
|
const challenge = await generateChallenge(challengeLeader, populatedGroup.group);
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
await challengeLeader.post('/groups/party/leave');
|
await challengeLeader.post('/groups/party/leave');
|
||||||
await challengeLeader.sync();
|
await challengeLeader.sync();
|
||||||
expect(challengeLeader.party._id).to.be.undefined; // check that leaving worked
|
expect(challengeLeader.party._id).to.be.undefined; // check that leaving worked
|
||||||
|
|
||||||
let res = await challengeLeader.get(`/challenges/${challenge._id}/members`);
|
const res = await challengeLeader.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: groupLeader._id,
|
_id: groupLeader._id,
|
||||||
id: groupLeader._id,
|
id: groupLeader._id,
|
||||||
profile: {name: groupLeader.profile.name},
|
profile: { name: groupLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: groupLeader.auth.local.username,
|
username: groupLeader.auth.local.username,
|
||||||
@@ -72,15 +72,15 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works with challenges belonging to public guild', async () => {
|
it('works with challenges belonging to public guild', async () => {
|
||||||
let leader = await generateUser({balance: 4});
|
const leader = await generateUser({ balance: 4 });
|
||||||
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(leader, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(leader, group);
|
const challenge = await generateChallenge(leader, group);
|
||||||
await leader.post(`/challenges/${challenge._id}/join`);
|
await leader.post(`/challenges/${challenge._id}/join`);
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
const res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: leader._id,
|
_id: leader._id,
|
||||||
id: leader._id,
|
id: leader._id,
|
||||||
profile: {name: leader.profile.name},
|
profile: { name: leader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: leader.auth.local.username,
|
username: leader.auth.local.username,
|
||||||
@@ -95,15 +95,15 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('populates only some fields', async () => {
|
it('populates only some fields', async () => {
|
||||||
let anotherUser = await generateUser({balance: 3});
|
const anotherUser = await generateUser({ balance: 3 });
|
||||||
let group = await generateGroup(anotherUser, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(anotherUser, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(anotherUser, group);
|
const challenge = await generateChallenge(anotherUser, group);
|
||||||
await anotherUser.post(`/challenges/${challenge._id}/join`);
|
await anotherUser.post(`/challenges/${challenge._id}/join`);
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
const res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: anotherUser._id,
|
_id: anotherUser._id,
|
||||||
id: anotherUser._id,
|
id: anotherUser._id,
|
||||||
profile: {name: anotherUser.profile.name},
|
profile: { name: anotherUser.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: anotherUser.auth.local.username,
|
username: anotherUser.auth.local.username,
|
||||||
@@ -118,17 +118,17 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns only first 30 members if req.query.includeAllMembers is not true', async () => {
|
it('returns only first 30 members if req.query.includeAllMembers is not true', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
|
usersToGenerate.push(generateUser({ challenges: [challenge._id] }));
|
||||||
}
|
}
|
||||||
await Promise.all(usersToGenerate);
|
await Promise.all(usersToGenerate);
|
||||||
|
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members?includeAllMembers=not-true`);
|
const res = await user.get(`/challenges/${challenge._id}/members?includeAllMembers=not-true`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -137,17 +137,17 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns only first 30 members if req.query.includeAllMembers is not defined', async () => {
|
it('returns only first 30 members if req.query.includeAllMembers is not defined', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
|
usersToGenerate.push(generateUser({ challenges: [challenge._id] }));
|
||||||
}
|
}
|
||||||
await Promise.all(usersToGenerate);
|
await Promise.all(usersToGenerate);
|
||||||
|
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
const res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -156,17 +156,17 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns all members if req.query.includeAllMembers is true', async () => {
|
it('returns all members if req.query.includeAllMembers is true', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
|
usersToGenerate.push(generateUser({ challenges: [challenge._id] }));
|
||||||
}
|
}
|
||||||
await Promise.all(usersToGenerate);
|
await Promise.all(usersToGenerate);
|
||||||
|
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members?includeAllMembers=true`);
|
const res = await user.get(`/challenges/${challenge._id}/members?includeAllMembers=true`);
|
||||||
expect(res.length).to.equal(32);
|
expect(res.length).to.equal(32);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -174,47 +174,48 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports using req.query.lastId to get more members', async function () {
|
it('supports using req.query.lastId to get more members', async function test () {
|
||||||
this.timeout(30000); // @TODO: times out after 8 seconds
|
this.timeout(30000); // @TODO: times out after 8 seconds
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 57; i++) {
|
for (let i = 0; i < 57; i += 1) {
|
||||||
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
|
usersToGenerate.push(generateUser({ challenges: [challenge._id] }));
|
||||||
}
|
}
|
||||||
let generatedUsers = await Promise.all(usersToGenerate); // Group has 59 members (1 is the leader)
|
// Group has 59 members (1 is the leader)
|
||||||
let expectedIds = [user._id].concat(generatedUsers.map(generatedUser => generatedUser._id));
|
const generatedUsers = await Promise.all(usersToGenerate);
|
||||||
|
const expectedIds = [user._id].concat(generatedUsers.map(generatedUser => generatedUser._id));
|
||||||
|
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
const res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
let res2 = await user.get(`/challenges/${challenge._id}/members?lastId=${res[res.length - 1]._id}`);
|
const res2 = await user.get(`/challenges/${challenge._id}/members?lastId=${res[res.length - 1]._id}`);
|
||||||
expect(res2.length).to.equal(28);
|
expect(res2.length).to.equal(28);
|
||||||
|
|
||||||
let resIds = res.concat(res2).map(member => member._id);
|
const resIds = res.concat(res2).map(member => member._id);
|
||||||
expect(resIds).to.eql(expectedIds.sort());
|
expect(resIds).to.eql(expectedIds.sort());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports using req.query.search to get search members', async () => {
|
it('supports using req.query.search to get search members', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i += 1) {
|
||||||
usersToGenerate.push(generateUser({
|
usersToGenerate.push(generateUser({
|
||||||
challenges: [challenge._id],
|
challenges: [challenge._id],
|
||||||
'profile.name': `${i}profilename`,
|
'profile.name': `${i}profilename`,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let generatedUsers = await Promise.all(usersToGenerate);
|
const generatedUsers = await Promise.all(usersToGenerate);
|
||||||
let profileNames = generatedUsers.map(generatedUser => generatedUser.profile.name);
|
const profileNames = generatedUsers.map(generatedUser => generatedUser.profile.name);
|
||||||
|
|
||||||
let firstProfileName = profileNames[0];
|
const firstProfileName = profileNames[0];
|
||||||
let nameToSearch = firstProfileName.substring(0, 4);
|
const nameToSearch = firstProfileName.substring(0, 4);
|
||||||
|
|
||||||
let response = await user.get(`/challenges/${challenge._id}/members?search=${nameToSearch}`);
|
const response = await user.get(`/challenges/${challenge._id}/members?search=${nameToSearch}`);
|
||||||
expect(response[0].profile.name).to.eql(firstProfileName);
|
expect(response[0].profile.name).to.eql(firstProfileName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/members/:memberId', () => {
|
describe('GET /challenges/:challengeId/members/:memberId', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -30,16 +30,16 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if member doesn\'t exists', async () => {
|
it('fails if member doesn\'t exists', async () => {
|
||||||
let userId = generateUUID();
|
const userId = generateUUID();
|
||||||
await expect(user.get(`/challenges/${generateUUID()}/members/${userId}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(`/challenges/${generateUUID()}/members/${userId}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('userWithIDNotFound', {userId}),
|
message: t('userWithIDNotFound', { userId }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if challenge doesn\'t exists', async () => {
|
it('fails if challenge doesn\'t exists', async () => {
|
||||||
let member = await generateUser();
|
const member = await generateUser();
|
||||||
await expect(user.get(`/challenges/${generateUUID()}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(`/challenges/${generateUUID()}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -48,11 +48,11 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user doesn\'t have access to the challenge', async () => {
|
it('fails if user doesn\'t have access to the challenge', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let anotherUser = await generateUser();
|
const anotherUser = await generateUser();
|
||||||
let member = await generateUser();
|
const member = await generateUser();
|
||||||
await expect(anotherUser.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(anotherUser.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -61,10 +61,10 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if member is not part of the challenge', async () => {
|
it('fails if member is not part of the challenge', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let member = await generateUser();
|
const member = await generateUser();
|
||||||
await expect(user.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -73,37 +73,37 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works with challenges belonging to a public guild', async () => {
|
it('works with challenges belonging to a public guild', async () => {
|
||||||
let groupLeader = await generateUser({balance: 4});
|
const groupLeader = await generateUser({ balance: 4 });
|
||||||
let group = await generateGroup(groupLeader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(groupLeader, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(groupLeader, group);
|
const challenge = await generateChallenge(groupLeader, group);
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
let taskText = 'Test Text';
|
const taskText = 'Test Text';
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: taskText}]);
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [{ type: 'habit', text: taskText }]);
|
||||||
|
|
||||||
let memberProgress = await user.get(`/challenges/${challenge._id}/members/${groupLeader._id}`);
|
const memberProgress = await user.get(`/challenges/${challenge._id}/members/${groupLeader._id}`);
|
||||||
expect(memberProgress).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile', 'tasks']);
|
expect(memberProgress).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile', 'tasks']);
|
||||||
expect(memberProgress.profile).to.have.all.keys(['name']);
|
expect(memberProgress.profile).to.have.all.keys(['name']);
|
||||||
expect(memberProgress.tasks.length).to.equal(1);
|
expect(memberProgress.tasks.length).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the member tasks for the challenges', async () => {
|
it('returns the member tasks for the challenges', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
await user.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: 'Test Text'}]);
|
await user.post(`/tasks/challenge/${challenge._id}`, [{ type: 'habit', text: 'Test Text' }]);
|
||||||
|
|
||||||
let memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
|
const memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
|
||||||
let chalTasks = await user.get(`/tasks/challenge/${challenge._id}`);
|
const chalTasks = await user.get(`/tasks/challenge/${challenge._id}`);
|
||||||
expect(memberProgress.tasks.length).to.equal(chalTasks.length);
|
expect(memberProgress.tasks.length).to.equal(chalTasks.length);
|
||||||
expect(memberProgress.tasks[0].challenge.id).to.equal(challenge._id);
|
expect(memberProgress.tasks[0].challenge.id).to.equal(challenge._id);
|
||||||
expect(memberProgress.tasks[0].challenge.taskId).to.equal(chalTasks[0]._id);
|
expect(memberProgress.tasks[0].challenge.taskId).to.equal(chalTasks[0]._id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the tasks without the tags and checklist', async () => {
|
it('returns the tasks without the tags and checklist', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let challenge = await generateChallenge(user, group);
|
const challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let taskText = 'Test Text';
|
const taskText = 'Test Text';
|
||||||
await user.post(`/tasks/challenge/${challenge._id}`, [{
|
await user.post(`/tasks/challenge/${challenge._id}`, [{
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
text: taskText,
|
text: taskText,
|
||||||
@@ -115,7 +115,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
],
|
],
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
let memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
|
const memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
|
||||||
expect(memberProgress.tasks[0]).not.to.have.key('tags');
|
expect(memberProgress.tasks[0]).not.to.have.key('tags');
|
||||||
expect(memberProgress.tasks[0].checklist).to.eql([]);
|
expect(memberProgress.tasks[0].checklist).to.eql([]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import { TAVERN_ID } from '../../../../../website/common/script/constants';
|
|||||||
|
|
||||||
describe('GET challenges/groups/:groupId', () => {
|
describe('GET challenges/groups/:groupId', () => {
|
||||||
context('Public Guild', () => {
|
context('Public Guild', () => {
|
||||||
let publicGuild, user, nonMember, challenge, challenge2;
|
let publicGuild; let user; let nonMember; let challenge; let
|
||||||
|
challenge2;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestGuild',
|
name: 'TestGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -31,14 +32,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for non member with populated leader', async () => {
|
it('should return group challenges for non member with populated leader', async () => {
|
||||||
let challenges = await nonMember.get(`/challenges/groups/${publicGuild._id}`);
|
const challenges = await nonMember.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -48,12 +49,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -66,14 +67,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for member with populated leader', async () => {
|
it('should return group challenges for member with populated leader', async () => {
|
||||||
let challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
const challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -83,12 +84,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -106,7 +107,7 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
const newChallenge = await generateChallenge(user, publicGuild);
|
||||||
await user.post(`/challenges/${newChallenge._id}/join`);
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
@@ -117,10 +118,11 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Private Guild', () => {
|
context('Private Guild', () => {
|
||||||
let privateGuild, user, nonMember, challenge, challenge2;
|
let privateGuild; let user; let nonMember; let challenge; let
|
||||||
|
challenge2;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestPrivateGuild',
|
name: 'TestPrivateGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -149,14 +151,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for member with populated leader', async () => {
|
it('should return group challenges for member with populated leader', async () => {
|
||||||
let challenges = await user.get(`/challenges/groups/${privateGuild._id}`);
|
const challenges = await user.get(`/challenges/groups/${privateGuild._id}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: privateGuild.leader._id,
|
_id: privateGuild.leader._id,
|
||||||
id: privateGuild.leader._id,
|
id: privateGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -166,12 +168,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: privateGuild.leader._id,
|
_id: privateGuild.leader._id,
|
||||||
id: privateGuild.leader._id,
|
id: privateGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -185,10 +187,11 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('official challenge is present', () => {
|
context('official challenge is present', () => {
|
||||||
let publicGuild, user, officialChallenge, challenge, challenge2;
|
let publicGuild; let user; let officialChallenge; let challenge; let
|
||||||
|
challenge2;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestGuild',
|
name: 'TestGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -218,9 +221,9 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return official challenges first', async () => {
|
it('should return official challenges first', async () => {
|
||||||
let challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
const challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
|
|
||||||
let foundChallengeIndex = _.findIndex(challenges, { _id: officialChallenge._id });
|
const foundChallengeIndex = _.findIndex(challenges, { _id: officialChallenge._id });
|
||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -233,7 +236,7 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallengeIndex).to.eql(1);
|
expect(foundChallengeIndex).to.eql(1);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
const newChallenge = await generateChallenge(user, publicGuild);
|
||||||
await user.post(`/challenges/${newChallenge._id}/join`);
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
@@ -244,10 +247,11 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Party', () => {
|
context('Party', () => {
|
||||||
let party, user, nonMember, challenge, challenge2;
|
let party; let user; let nonMember; let challenge; let
|
||||||
|
challenge2;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestParty',
|
name: 'TestParty',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
@@ -275,14 +279,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for member with populated leader', async () => {
|
it('should return group challenges for member with populated leader', async () => {
|
||||||
let challenges = await user.get(`/challenges/groups/${party._id}`);
|
const challenges = await user.get(`/challenges/groups/${party._id}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: party.leader._id,
|
_id: party.leader._id,
|
||||||
id: party.leader._id,
|
id: party.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -292,12 +296,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: party.leader._id,
|
_id: party.leader._id,
|
||||||
id: party.leader._id,
|
id: party.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -310,14 +314,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for member using ID "party"', async () => {
|
it('should return group challenges for member using ID "party"', async () => {
|
||||||
let challenges = await user.get('/challenges/groups/party');
|
const challenges = await user.get('/challenges/groups/party');
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: party.leader._id,
|
_id: party.leader._id,
|
||||||
id: party.leader._id,
|
id: party.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -327,12 +331,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: party.leader._id,
|
_id: party.leader._id,
|
||||||
id: party.leader._id,
|
id: party.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -346,28 +350,29 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Tavern', () => {
|
context('Tavern', () => {
|
||||||
let tavern, user, challenge, challenge2;
|
let tavern; let user; let challenge; let
|
||||||
|
challenge2;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
user = await generateUser();
|
user = await generateUser();
|
||||||
await user.update({balance: 0.5});
|
await user.update({ balance: 0.5 });
|
||||||
tavern = await user.get(`/groups/${TAVERN_ID}`);
|
tavern = await user.get(`/groups/${TAVERN_ID}`);
|
||||||
|
|
||||||
challenge = await generateChallenge(user, tavern, {prize: 1});
|
challenge = await generateChallenge(user, tavern, { prize: 1 });
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, tavern, {prize: 1});
|
challenge2 = await generateChallenge(user, tavern, { prize: 1 });
|
||||||
await user.post(`/challenges/${challenge2._id}/join`);
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return tavern challenges with populated leader', async () => {
|
it('should return tavern challenges with populated leader', async () => {
|
||||||
let challenges = await user.get(`/challenges/groups/${TAVERN_ID}`);
|
const challenges = await user.get(`/challenges/groups/${TAVERN_ID}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -377,12 +382,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -395,14 +400,14 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return tavern challenges using ID "habitrpg', async () => {
|
it('should return tavern challenges using ID "habitrpg', async () => {
|
||||||
let challenges = await user.get('/challenges/groups/habitrpg');
|
const challenges = await user.get('/challenges/groups/habitrpg');
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -412,12 +417,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
verifiedUsername: true,
|
verifiedUsername: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import {
|
|||||||
|
|
||||||
describe('GET challenges/user', () => {
|
describe('GET challenges/user', () => {
|
||||||
context('no official challenges', () => {
|
context('no official challenges', () => {
|
||||||
let user, member, nonMember, challenge, challenge2, publicGuild;
|
let user; let member; let nonMember; let challenge; let challenge2; let
|
||||||
|
publicGuild;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestGuild',
|
name: 'TestGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -20,7 +21,7 @@ describe('GET challenges/user', () => {
|
|||||||
|
|
||||||
user = groupLeader;
|
user = groupLeader;
|
||||||
publicGuild = group;
|
publicGuild = group;
|
||||||
member = members[0];
|
member = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
@@ -32,14 +33,14 @@ describe('GET challenges/user', () => {
|
|||||||
it('should return challenges user has joined', async () => {
|
it('should return challenges user has joined', async () => {
|
||||||
await nonMember.post(`/challenges/${challenge._id}/join`);
|
await nonMember.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let challenges = await nonMember.get('/challenges/user');
|
const challenges = await nonMember.get('/challenges/user');
|
||||||
|
|
||||||
let foundChallenge = _.find(challenges, { _id: challenge._id });
|
const foundChallenge = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge).to.exist;
|
expect(foundChallenge).to.exist;
|
||||||
expect(foundChallenge.leader).to.eql({
|
expect(foundChallenge.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -62,14 +63,14 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return challenges user has created', async () => {
|
it('should return challenges user has created', async () => {
|
||||||
let challenges = await user.get('/challenges/user');
|
const challenges = await user.get('/challenges/user');
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -89,12 +90,12 @@ describe('GET challenges/user', () => {
|
|||||||
summary: publicGuild.name,
|
summary: publicGuild.name,
|
||||||
leader: publicGuild.leader._id,
|
leader: publicGuild.leader._id,
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -117,14 +118,14 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return challenges in user\'s group', async () => {
|
it('should return challenges in user\'s group', async () => {
|
||||||
let challenges = await member.get('/challenges/user');
|
const challenges = await member.get('/challenges/user');
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.exist;
|
expect(foundChallenge1).to.exist;
|
||||||
expect(foundChallenge1.leader).to.eql({
|
expect(foundChallenge1.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -144,12 +145,12 @@ describe('GET challenges/user', () => {
|
|||||||
summary: publicGuild.name,
|
summary: publicGuild.name,
|
||||||
leader: publicGuild.leader._id,
|
leader: publicGuild.leader._id,
|
||||||
});
|
});
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.exist;
|
expect(foundChallenge2).to.exist;
|
||||||
expect(foundChallenge2.leader).to.eql({
|
expect(foundChallenge2.leader).to.eql({
|
||||||
_id: publicGuild.leader._id,
|
_id: publicGuild.leader._id,
|
||||||
id: publicGuild.leader._id,
|
id: publicGuild.leader._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -172,12 +173,12 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not return challenges in user groups if we send member true param', async () => {
|
it('should not return challenges in user groups if we send member true param', async () => {
|
||||||
let challenges = await member.get(`/challenges/user?member=${true}`);
|
const challenges = await member.get(`/challenges/user?member=${true}`);
|
||||||
|
|
||||||
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
|
||||||
expect(foundChallenge1).to.not.exist;
|
expect(foundChallenge1).to.not.exist;
|
||||||
|
|
||||||
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallenge2).to.not.exist;
|
expect(foundChallenge2).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,7 +188,7 @@ describe('GET challenges/user', () => {
|
|||||||
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
const newChallenge = await generateChallenge(user, publicGuild);
|
||||||
await user.post(`/challenges/${newChallenge._id}/join`);
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get('/challenges/user');
|
challenges = await user.get('/challenges/user');
|
||||||
@@ -197,7 +198,7 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not return challenges user doesn\'t have access to', async () => {
|
it('should not return challenges user doesn\'t have access to', async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestPrivateGuild',
|
name: 'TestPrivateGuild',
|
||||||
summary: 'summary for TestPrivateGuild',
|
summary: 'summary for TestPrivateGuild',
|
||||||
@@ -206,17 +207,17 @@ describe('GET challenges/user', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let privateChallenge = await generateChallenge(groupLeader, group);
|
const privateChallenge = await generateChallenge(groupLeader, group);
|
||||||
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
|
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
|
||||||
|
|
||||||
let challenges = await nonMember.get('/challenges/user');
|
const challenges = await nonMember.get('/challenges/user');
|
||||||
|
|
||||||
let foundChallenge = _.find(challenges, { _id: privateChallenge._id });
|
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
|
||||||
expect(foundChallenge).to.not.exist;
|
expect(foundChallenge).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not return challenges user doesn\'t have access to, even with query parameters', async () => {
|
it('should not return challenges user doesn\'t have access to, even with query parameters', async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestPrivateGuild',
|
name: 'TestPrivateGuild',
|
||||||
summary: 'summary for TestPrivateGuild',
|
summary: 'summary for TestPrivateGuild',
|
||||||
@@ -225,24 +226,27 @@ describe('GET challenges/user', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let privateChallenge = await generateChallenge(groupLeader, group, {categories: [{
|
const privateChallenge = await generateChallenge(groupLeader, group, {
|
||||||
name: 'academics',
|
categories: [{
|
||||||
slug: 'academics',
|
name: 'academics',
|
||||||
}]});
|
slug: 'academics',
|
||||||
|
}],
|
||||||
|
});
|
||||||
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
|
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
|
||||||
|
|
||||||
let challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned');
|
const challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned');
|
||||||
|
|
||||||
let foundChallenge = _.find(challenges, { _id: privateChallenge._id });
|
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
|
||||||
expect(foundChallenge).to.not.exist;
|
expect(foundChallenge).to.not.exist;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('official challenge is present', () => {
|
context('official challenge is present', () => {
|
||||||
let user, officialChallenge, challenge, challenge2, publicGuild;
|
let user; let officialChallenge; let challenge; let challenge2; let
|
||||||
|
publicGuild;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestGuild',
|
name: 'TestGuild',
|
||||||
summary: 'summary for TestGuild',
|
summary: 'summary for TestGuild',
|
||||||
@@ -273,9 +277,9 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return official challenges first', async () => {
|
it('should return official challenges first', async () => {
|
||||||
let challenges = await user.get('/challenges/user');
|
const challenges = await user.get('/challenges/user');
|
||||||
|
|
||||||
let foundChallengeIndex = _.findIndex(challenges, { _id: officialChallenge._id });
|
const foundChallengeIndex = _.findIndex(challenges, { _id: officialChallenge._id });
|
||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -288,7 +292,7 @@ describe('GET challenges/user', () => {
|
|||||||
foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
|
||||||
expect(foundChallengeIndex).to.eql(1);
|
expect(foundChallengeIndex).to.eql(1);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
const newChallenge = await generateChallenge(user, publicGuild);
|
||||||
await user.post(`/challenges/${newChallenge._id}/join`);
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get('/challenges/user');
|
challenges = await user.get('/challenges/user');
|
||||||
@@ -299,14 +303,15 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('filters and paging', () => {
|
context('filters and paging', () => {
|
||||||
let user, guild, member;
|
let user; let guild; let
|
||||||
|
member;
|
||||||
const categories = [{
|
const categories = [{
|
||||||
slug: 'newCat',
|
slug: 'newCat',
|
||||||
name: 'New Category',
|
name: 'New Category',
|
||||||
}];
|
}];
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestGuild',
|
name: 'TestGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -317,9 +322,9 @@ describe('GET challenges/user', () => {
|
|||||||
|
|
||||||
user = groupLeader;
|
user = groupLeader;
|
||||||
guild = group;
|
guild = group;
|
||||||
member = members[0];
|
member = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
await user.update({balance: 20});
|
await user.update({ balance: 20 });
|
||||||
|
|
||||||
for (let i = 0; i < 11; i += 1) {
|
for (let i = 0; i < 11; i += 1) {
|
||||||
let challenge = await generateChallenge(user, group); // eslint-disable-line
|
let challenge = await generateChallenge(user, group); // eslint-disable-line
|
||||||
@@ -328,7 +333,7 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns public guilds filtered by category', async () => {
|
it('returns public guilds filtered by category', async () => {
|
||||||
const categoryChallenge = await generateChallenge(user, guild, {categories});
|
const categoryChallenge = await generateChallenge(user, guild, { categories });
|
||||||
await user.post(`/challenges/${categoryChallenge._id}/join`);
|
await user.post(`/challenges/${categoryChallenge._id}/join`);
|
||||||
const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`);
|
const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`);
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('POST /challenges', () => {
|
describe('POST /challenges', () => {
|
||||||
it('returns error when group is empty', async () => {
|
it('returns error when group is empty', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post('/challenges')).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/challenges')).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -17,7 +17,7 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when groupId is not for a valid group', async () => {
|
it('returns error when groupId is not for a valid group', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post('/challenges', {
|
await expect(user.post('/challenges', {
|
||||||
group: generateUUID(),
|
group: generateUUID(),
|
||||||
@@ -29,7 +29,7 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when creating a challenge in the tavern with no prize', async () => {
|
it('returns error when creating a challenge in the tavern with no prize', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post('/challenges', {
|
await expect(user.post('/challenges', {
|
||||||
group: 'habitrpg',
|
group: 'habitrpg',
|
||||||
@@ -42,8 +42,8 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when creating a challenge in a public guild and you are not a member of it', async () => {
|
it('returns error when creating a challenge in a public guild and you are not a member of it', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
let { group } = await createAndPopulateGroup({
|
const { group } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -66,7 +66,7 @@ describe('POST /challenges', () => {
|
|||||||
let groupMember;
|
let groupMember;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 1,
|
members: 1,
|
||||||
leaderDetails: {
|
leaderDetails: {
|
||||||
balance: 3,
|
balance: 3,
|
||||||
@@ -81,7 +81,7 @@ describe('POST /challenges', () => {
|
|||||||
|
|
||||||
groupLeader = await populatedGroup.groupLeader.sync();
|
groupLeader = await populatedGroup.groupLeader.sync();
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
groupMember = populatedGroup.members[0];
|
groupMember = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when non-leader member creates a challenge in leaderOnly group', async () => {
|
it('returns an error when non-leader member creates a challenge in leaderOnly group', async () => {
|
||||||
@@ -95,14 +95,14 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('allows non-leader member to create a challenge', async () => {
|
it('allows non-leader member to create a challenge', async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
groupMember = populatedGroup.members[0];
|
groupMember = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
let chal = await groupMember.post('/challenges', {
|
const chal = await groupMember.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name: 'Test Challenge',
|
name: 'Test Challenge',
|
||||||
shortName: 'TC Label',
|
shortName: 'TC Label',
|
||||||
@@ -110,13 +110,13 @@ describe('POST /challenges', () => {
|
|||||||
|
|
||||||
expect(chal.leader).to.eql({
|
expect(chal.leader).to.eql({
|
||||||
_id: groupMember._id,
|
_id: groupMember._id,
|
||||||
profile: {name: groupMember.profile.name},
|
profile: { name: groupMember.profile.name },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t take gems from user or group when challenge has no prize', async () => {
|
it('doesn\'t take gems from user or group when challenge has no prize', async () => {
|
||||||
let oldUserBalance = groupLeader.balance;
|
const oldUserBalance = groupLeader.balance;
|
||||||
let oldGroupBalance = group.balance;
|
const oldGroupBalance = group.balance;
|
||||||
|
|
||||||
await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
@@ -143,9 +143,9 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('takes prize out of group if it has sufficient funds', async () => {
|
it('takes prize out of group if it has sufficient funds', async () => {
|
||||||
let oldUserBalance = groupLeader.balance;
|
const oldUserBalance = groupLeader.balance;
|
||||||
let oldGroupBalance = group.balance;
|
const oldGroupBalance = group.balance;
|
||||||
let prize = 4;
|
const prize = 4;
|
||||||
|
|
||||||
await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
@@ -159,8 +159,8 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('takes prize out of both group and user if group doesn\'t have enough', async () => {
|
it('takes prize out of both group and user if group doesn\'t have enough', async () => {
|
||||||
let oldUserBalance = groupLeader.balance;
|
const oldUserBalance = groupLeader.balance;
|
||||||
let prize = 8;
|
const prize = 8;
|
||||||
|
|
||||||
await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
@@ -170,14 +170,14 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await expect(group.sync()).to.eventually.have.property('balance', 0);
|
await expect(group.sync()).to.eventually.have.property('balance', 0);
|
||||||
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance - (prize / 4 - 1));
|
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance - (prize / 4 - 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('takes prize out of user if group has no balance', async () => {
|
it('takes prize out of user if group has no balance', async () => {
|
||||||
let oldUserBalance = groupLeader.balance;
|
const oldUserBalance = groupLeader.balance;
|
||||||
let prize = 8;
|
const prize = 8;
|
||||||
|
|
||||||
await group.update({ balance: 0});
|
await group.update({ balance: 0 });
|
||||||
await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name: 'Test Challenge',
|
name: 'Test Challenge',
|
||||||
@@ -190,7 +190,7 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('increases challenge count of group', async () => {
|
it('increases challenge count of group', async () => {
|
||||||
let oldChallengeCount = group.challengeCount;
|
const oldChallengeCount = group.challengeCount;
|
||||||
|
|
||||||
await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
@@ -208,7 +208,7 @@ describe('POST /challenges', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let challenge = await groupLeader.post('/challenges', {
|
const challenge = await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name: 'Test Challenge',
|
name: 'Test Challenge',
|
||||||
shortName: 'TC Label',
|
shortName: 'TC Label',
|
||||||
@@ -219,7 +219,7 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t set challenge as official if official flag is set by non-admin', async () => {
|
it('doesn\'t set challenge as official if official flag is set by non-admin', async () => {
|
||||||
let challenge = await groupLeader.post('/challenges', {
|
const challenge = await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name: 'Test Challenge',
|
name: 'Test Challenge',
|
||||||
shortName: 'TC Label',
|
shortName: 'TC Label',
|
||||||
@@ -230,9 +230,9 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when challenge validation fails; doesn\'s save user or group', async () => {
|
it('returns an error when challenge validation fails; doesn\'s save user or group', async () => {
|
||||||
let oldChallengeCount = group.challengeCount;
|
const oldChallengeCount = group.challengeCount;
|
||||||
let oldUserBalance = groupLeader.balance;
|
const oldUserBalance = groupLeader.balance;
|
||||||
let oldGroupBalance = group.balance;
|
const oldGroupBalance = group.balance;
|
||||||
|
|
||||||
await expect(groupLeader.post('/challenges', {
|
await expect(groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
@@ -252,12 +252,12 @@ describe('POST /challenges', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets all properites of the challenge as passed', async () => {
|
it('sets all properites of the challenge as passed', async () => {
|
||||||
let name = 'Test Challenge';
|
const name = 'Test Challenge';
|
||||||
let shortName = 'TC Label';
|
const shortName = 'TC Label';
|
||||||
let description = 'Test Description';
|
const description = 'Test Description';
|
||||||
let prize = 4;
|
const prize = 4;
|
||||||
|
|
||||||
let challenge = await groupLeader.post('/challenges', {
|
const challenge = await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name,
|
name,
|
||||||
shortName,
|
shortName,
|
||||||
@@ -267,7 +267,7 @@ describe('POST /challenges', () => {
|
|||||||
|
|
||||||
expect(challenge.leader).to.eql({
|
expect(challenge.leader).to.eql({
|
||||||
_id: groupLeader._id,
|
_id: groupLeader._id,
|
||||||
profile: {name: groupLeader.profile.name},
|
profile: { name: groupLeader.profile.name },
|
||||||
});
|
});
|
||||||
expect(challenge.name).to.eql(name);
|
expect(challenge.name).to.eql(name);
|
||||||
expect(challenge.shortName).to.eql(shortName);
|
expect(challenge.shortName).to.eql(shortName);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/join', () => {
|
describe('POST /challenges/:challengeId/join', () => {
|
||||||
it('returns error when challengeId is not a valid UUID', async () => {
|
it('returns error when challengeId is not a valid UUID', async () => {
|
||||||
let user = await generateUser({ balance: 1});
|
const user = await generateUser({ balance: 1 });
|
||||||
|
|
||||||
await expect(user.post('/challenges/test/join')).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/challenges/test/join')).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -18,7 +18,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when challengeId is not for a valid challenge', async () => {
|
it('returns error when challengeId is not for a valid challenge', async () => {
|
||||||
let user = await generateUser({ balance: 1});
|
const user = await generateUser({ balance: 1 });
|
||||||
|
|
||||||
await expect(user.post(`/challenges/${generateUUID()}/join`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/challenges/${generateUUID()}/join`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -34,20 +34,20 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
let authorizedUser;
|
let authorizedUser;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
groupLeader = populatedGroup.groupLeader;
|
groupLeader = populatedGroup.groupLeader;
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
authorizedUser = populatedGroup.members[0];
|
authorizedUser = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when user isn\'t in the private group and isn\'t challenge leader', async () => {
|
it('returns an error when user isn\'t in the private group and isn\'t challenge leader', async () => {
|
||||||
let unauthorizedUser = await generateUser();
|
const unauthorizedUser = await generateUser();
|
||||||
|
|
||||||
await expect(unauthorizedUser.post(`/challenges/${challenge._id}/join`)).to.eventually.be.rejected.and.eql({
|
await expect(unauthorizedUser.post(`/challenges/${challenge._id}/join`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -62,12 +62,12 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
await groupLeader.sync();
|
await groupLeader.sync();
|
||||||
expect(groupLeader.guilds).to.be.empty; // check that leaving worked
|
expect(groupLeader.guilds).to.be.empty; // check that leaving worked
|
||||||
|
|
||||||
let res = await groupLeader.post(`/challenges/${challenge._id}/join`);
|
const res = await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
expect(res.name).to.equal(challenge.name);
|
expect(res.name).to.equal(challenge.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns challenge data', async () => {
|
it('returns challenge data', async () => {
|
||||||
let res = await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
const res = await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
expect(res.group).to.eql({
|
expect(res.group).to.eql({
|
||||||
_id: group._id,
|
_id: group._id,
|
||||||
@@ -78,7 +78,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
expect(res.leader).to.eql({
|
expect(res.leader).to.eql({
|
||||||
_id: groupLeader._id,
|
_id: groupLeader._id,
|
||||||
id: groupLeader._id,
|
id: groupLeader._id,
|
||||||
profile: {name: groupLeader.profile.name},
|
profile: { name: groupLeader.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: groupLeader.auth.local.username,
|
username: groupLeader.auth.local.username,
|
||||||
@@ -111,7 +111,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
|
|
||||||
it('increases memberCount of challenge', async () => {
|
it('increases memberCount of challenge', async () => {
|
||||||
await challenge.sync();
|
await challenge.sync();
|
||||||
let oldMemberCount = challenge.memberCount;
|
const oldMemberCount = challenge.memberCount;
|
||||||
|
|
||||||
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
@@ -123,15 +123,13 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
it('syncs challenge tasks to joining user', async () => {
|
it('syncs challenge tasks to joining user', async () => {
|
||||||
const taskText = 'A challenge task text';
|
const taskText = 'A challenge task text';
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
||||||
{type: 'daily', text: taskText},
|
{ type: 'daily', text: taskText },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
const tasks = await authorizedUser.get('/tasks/user');
|
const tasks = await authorizedUser.get('/tasks/user');
|
||||||
const syncedTask = tasks.find((task) => {
|
const syncedTask = tasks.find(task => task.text === taskText);
|
||||||
return task.text === taskText;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(syncedTask.text).to.eql(taskText);
|
expect(syncedTask.text).to.eql(taskText);
|
||||||
expect(syncedTask.isDue).to.exist;
|
expect(syncedTask.isDue).to.exist;
|
||||||
@@ -139,7 +137,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds challenge tag to user tags', async () => {
|
it('adds challenge tag to user tags', async () => {
|
||||||
let userTagsLength = (await authorizedUser.get('/tags')).length;
|
const userTagsLength = (await authorizedUser.get('/tags')).length;
|
||||||
|
|
||||||
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/leave', () => {
|
describe('POST /challenges/:challengeId/leave', () => {
|
||||||
it('returns error when challengeId is not a valid UUID', async () => {
|
it('returns error when challengeId is not a valid UUID', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post('/challenges/test/leave')).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/challenges/test/leave')).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -18,7 +18,7 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when challengeId is not for a valid challenge', async () => {
|
it('returns error when challengeId is not for a valid challenge', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post(`/challenges/${generateUUID()}/leave`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/challenges/${generateUUID()}/leave`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -37,15 +37,15 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
let taskText;
|
let taskText;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 3,
|
members: 3,
|
||||||
});
|
});
|
||||||
|
|
||||||
groupLeader = populatedGroup.groupLeader;
|
groupLeader = populatedGroup.groupLeader;
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
leavingUser = populatedGroup.members[0];
|
leavingUser = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
|
||||||
notInChallengeUser = populatedGroup.members[1];
|
notInChallengeUser = populatedGroup.members[1]; // eslint-disable-line prefer-destructuring
|
||||||
notInGroupLeavingUser = populatedGroup.members[2];
|
notInGroupLeavingUser = populatedGroup.members[2]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
@@ -53,7 +53,7 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
taskText = 'A challenge task text';
|
taskText = 'A challenge task text';
|
||||||
|
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
||||||
{type: 'habit', text: taskText},
|
{ type: 'habit', text: taskText },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await leavingUser.post(`/challenges/${challenge._id}/join`);
|
await leavingUser.post(`/challenges/${challenge._id}/join`);
|
||||||
@@ -87,7 +87,7 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('decreases memberCount of challenge', async () => {
|
it('decreases memberCount of challenge', async () => {
|
||||||
let oldMemberCount = challenge.memberCount;
|
const oldMemberCount = challenge.memberCount;
|
||||||
|
|
||||||
await leavingUser.post(`/challenges/${challenge._id}/leave`);
|
await leavingUser.post(`/challenges/${challenge._id}/leave`);
|
||||||
|
|
||||||
@@ -100,10 +100,8 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
await leavingUser.post(`/challenges/${challenge._id}/leave`, {
|
await leavingUser.post(`/challenges/${challenge._id}/leave`, {
|
||||||
keep: 'remove-all',
|
keep: 'remove-all',
|
||||||
});
|
});
|
||||||
let tasks = await leavingUser.get('/tasks/user');
|
const tasks = await leavingUser.get('/tasks/user');
|
||||||
let tasksTexts = tasks.map((task) => {
|
const tasksTexts = tasks.map(task => task.text);
|
||||||
return task.text;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(tasksTexts).to.not.include(taskText);
|
expect(tasksTexts).to.not.include(taskText);
|
||||||
});
|
});
|
||||||
@@ -113,10 +111,8 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
keep: 'test',
|
keep: 'test',
|
||||||
});
|
});
|
||||||
|
|
||||||
let tasks = await leavingUser.get('/tasks/user');
|
const tasks = await leavingUser.get('/tasks/user');
|
||||||
let testTask = _.find(tasks, (task) => {
|
const testTask = _.find(tasks, task => task.text === taskText);
|
||||||
return task.text === taskText;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(testTask).to.not.be.undefined;
|
expect(testTask).to.not.be.undefined;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
@@ -6,11 +7,10 @@ import {
|
|||||||
checkExistence,
|
checkExistence,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
||||||
it('returns error when challengeId is not a valid UUID', async () => {
|
it('returns error when challengeId is not a valid UUID', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post(`/challenges/test/selectWinner/${user._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/challenges/test/selectWinner/${user._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -20,7 +20,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when winnerId is not a valid UUID', async () => {
|
it('returns error when winnerId is not a valid UUID', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post(`/challenges/${generateUUID()}/selectWinner/test`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/challenges/${generateUUID()}/selectWinner/test`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -30,7 +30,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when challengeId is not for a valid challenge', async () => {
|
it('returns error when challengeId is not for a valid challenge', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
|
|
||||||
await expect(user.post(`/challenges/${generateUUID()}/selectWinner/${user._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/challenges/${generateUUID()}/selectWinner/${user._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
@@ -44,16 +44,16 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
let group;
|
let group;
|
||||||
let challenge;
|
let challenge;
|
||||||
let winningUser;
|
let winningUser;
|
||||||
let taskText = 'A challenge task text';
|
const taskText = 'A challenge task text';
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let populatedGroup = await createAndPopulateGroup({
|
const populatedGroup = await createAndPopulateGroup({
|
||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
groupLeader = populatedGroup.groupLeader;
|
groupLeader = populatedGroup.groupLeader;
|
||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
winningUser = populatedGroup.members[0];
|
winningUser = populatedGroup.members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group, {
|
challenge = await generateChallenge(groupLeader, group, {
|
||||||
prize: 1,
|
prize: 1,
|
||||||
@@ -61,7 +61,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
|
||||||
{type: 'habit', text: taskText},
|
{ type: 'habit', text: taskText },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await winningUser.post(`/challenges/${challenge._id}/join`);
|
await winningUser.post(`/challenges/${challenge._id}/join`);
|
||||||
@@ -78,12 +78,12 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when winning user isn\'t part of the challenge', async () => {
|
it('returns an error when winning user isn\'t part of the challenge', async () => {
|
||||||
let notInChallengeUser = await generateUser();
|
const notInChallengeUser = await generateUser();
|
||||||
|
|
||||||
await expect(groupLeader.post(`/challenges/${challenge._id}/selectWinner/${notInChallengeUser._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(groupLeader.post(`/challenges/${challenge._id}/selectWinner/${notInChallengeUser._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('winnerNotFound', {userId: notInChallengeUser._id}),
|
message: t('winnerNotFound', { userId: notInChallengeUser._id }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -101,12 +101,13 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
await sleep(0.5);
|
await sleep(0.5);
|
||||||
|
|
||||||
await expect(winningUser.sync()).to.eventually.have.nested.property('achievements.challenges').to.include(challenge.name);
|
await expect(winningUser.sync()).to.eventually.have.nested.property('achievements.challenges').to.include(challenge.name);
|
||||||
expect(winningUser.notifications.length).to.equal(2); // 2 because winningUser just joined the challenge, which now awards an achievement
|
// 2 because winningUser just joined the challenge, which now awards an achievement
|
||||||
|
expect(winningUser.notifications.length).to.equal(2);
|
||||||
expect(winningUser.notifications[1].type).to.equal('WON_CHALLENGE');
|
expect(winningUser.notifications[1].type).to.equal('WON_CHALLENGE');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gives winner gems as reward', async () => {
|
it('gives winner gems as reward', async () => {
|
||||||
let oldBalance = winningUser.balance;
|
const oldBalance = winningUser.balance;
|
||||||
|
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/selectWinner/${winningUser._id}`);
|
await groupLeader.post(`/challenges/${challenge._id}/selectWinner/${winningUser._id}`);
|
||||||
|
|
||||||
@@ -116,8 +117,8 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t gives winner gems if group policy prevents it', async () => {
|
it('doesn\'t gives winner gems if group policy prevents it', async () => {
|
||||||
let oldBalance = winningUser.balance;
|
const oldBalance = winningUser.balance;
|
||||||
let oldLeaderBalance = (await groupLeader.sync()).balance;
|
const oldLeaderBalance = (await groupLeader.sync()).balance;
|
||||||
|
|
||||||
await winningUser.update({
|
await winningUser.update({
|
||||||
'purchased.plan.customerId': 'group-plan',
|
'purchased.plan.customerId': 'group-plan',
|
||||||
@@ -136,7 +137,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('doesn\'t refund gems to group leader', async () => {
|
it('doesn\'t refund gems to group leader', async () => {
|
||||||
let oldBalance = (await groupLeader.sync()).balance;
|
const oldBalance = (await groupLeader.sync()).balance;
|
||||||
|
|
||||||
await groupLeader.post(`/challenges/${challenge._id}/selectWinner/${winningUser._id}`);
|
await groupLeader.post(`/challenges/${challenge._id}/selectWinner/${winningUser._id}`);
|
||||||
|
|
||||||
@@ -151,14 +152,10 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
await sleep(0.5);
|
await sleep(0.5);
|
||||||
|
|
||||||
const tasks = await winningUser.get('/tasks/user');
|
const tasks = await winningUser.get('/tasks/user');
|
||||||
const testTask = _.find(tasks, (task) => {
|
const testTask = _.find(tasks, task => task.text === taskText);
|
||||||
return task.text === taskText;
|
|
||||||
});
|
|
||||||
|
|
||||||
const updatedUser = await winningUser.sync();
|
const updatedUser = await winningUser.sync();
|
||||||
const challengeTag = updatedUser.tags.find(tags => {
|
const challengeTag = updatedUser.tags.find(tags => tags.id === challenge._id);
|
||||||
return tags.id === challenge._id;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(testTask.challenge.broken).to.eql('CHALLENGE_CLOSED');
|
expect(testTask.challenge.broken).to.eql('CHALLENGE_CLOSED');
|
||||||
expect(testTask.challenge.winner).to.eql(winningUser.profile.name);
|
expect(testTask.challenge.winner).to.eql(winningUser.profile.name);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
|
|
||||||
describe('POST /challenges/:challengeId/clone', () => {
|
describe('POST /challenges/:challengeId/clone', () => {
|
||||||
it('clones a challenge', async () => {
|
it('clones a challenge', async () => {
|
||||||
const user = await generateUser({balance: 10});
|
const user = await generateUser({ balance: 10 });
|
||||||
const group = await generateGroup(user);
|
const group = await generateGroup(user);
|
||||||
|
|
||||||
const name = 'Test Challenge';
|
const name = 'Test Challenge';
|
||||||
@@ -38,6 +38,7 @@ describe('POST /challenges/:challengeId/clone', () => {
|
|||||||
|
|
||||||
expect(cloneChallengeResponse.clonedTasks[0].text).to.eql(challengeTask.text);
|
expect(cloneChallengeResponse.clonedTasks[0].text).to.eql(challengeTask.text);
|
||||||
expect(cloneChallengeResponse.clonedTasks[0]._id).to.not.eql(challengeTask._id);
|
expect(cloneChallengeResponse.clonedTasks[0]._id).to.not.eql(challengeTask._id);
|
||||||
expect(cloneChallengeResponse.clonedTasks[0].challenge.id).to.eql(cloneChallengeResponse.clonedChallenge._id);
|
expect(cloneChallengeResponse.clonedTasks[0].challenge.id)
|
||||||
|
.to.eql(cloneChallengeResponse.clonedChallenge._id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import {
|
|||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('PUT /challenges/:challengeId', () => {
|
describe('PUT /challenges/:challengeId', () => {
|
||||||
let privateGuild, user, nonMember, challenge, member;
|
let privateGuild; let user; let nonMember; let challenge; let
|
||||||
|
member;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'TestPrivateGuild',
|
name: 'TestPrivateGuild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -22,7 +23,7 @@ describe('PUT /challenges/:challengeId', () => {
|
|||||||
user = groupLeader;
|
user = groupLeader;
|
||||||
|
|
||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
member = members[0];
|
member = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
await user.post(`/challenges/${challenge._id}/join`);
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
@@ -48,7 +49,7 @@ describe('PUT /challenges/:challengeId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('only updates allowed fields', async () => {
|
it('only updates allowed fields', async () => {
|
||||||
let res = await user.put(`/challenges/${challenge._id}`, {
|
const res = await user.put(`/challenges/${challenge._id}`, {
|
||||||
// ignored
|
// ignored
|
||||||
prize: 33,
|
prize: 33,
|
||||||
group: 'blabla',
|
group: 'blabla',
|
||||||
@@ -78,7 +79,7 @@ describe('PUT /challenges/:challengeId', () => {
|
|||||||
expect(res.leader).to.eql({
|
expect(res.leader).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
||||||
let groupWithChat, message, user, userThatDidNotCreateChat, admin;
|
let groupWithChat; let message; let user; let userThatDidNotCreateChat; let
|
||||||
|
admin;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -21,12 +22,12 @@ describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
|||||||
message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message' });
|
message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message' });
|
||||||
message = message.message;
|
message = message.message;
|
||||||
userThatDidNotCreateChat = await generateUser();
|
userThatDidNotCreateChat = await generateUser();
|
||||||
admin = await generateUser({'contributor.admin': true});
|
admin = await generateUser({ 'contributor.admin': true });
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Chat errors', () => {
|
context('Chat errors', () => {
|
||||||
it('returns an error is message does not exist', async () => {
|
it('returns an error is message does not exist', async () => {
|
||||||
let fakeChatId = generateUUID();
|
const fakeChatId = generateUUID();
|
||||||
await expect(user.del(`/groups/${groupWithChat._id}/chat/${fakeChatId}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.del(`/groups/${groupWithChat._id}/chat/${fakeChatId}`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -55,9 +56,9 @@ describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
|||||||
await user.del(`/groups/${groupWithChat._id}/chat/${nextMessage.id}`);
|
await user.del(`/groups/${groupWithChat._id}/chat/${nextMessage.id}`);
|
||||||
|
|
||||||
const returnedMessages = await user.get(`/groups/${groupWithChat._id}/chat/`);
|
const returnedMessages = await user.get(`/groups/${groupWithChat._id}/chat/`);
|
||||||
const messageFromUser = returnedMessages.find(returnedMessage => {
|
const messageFromUser = returnedMessages.find(
|
||||||
return returnedMessage.id === nextMessage.id;
|
returnedMessage => returnedMessage.id === nextMessage.id,
|
||||||
});
|
);
|
||||||
|
|
||||||
expect(returnedMessages).is.an('array');
|
expect(returnedMessages).is.an('array');
|
||||||
expect(messageFromUser).to.not.exist;
|
expect(messageFromUser).to.not.exist;
|
||||||
@@ -67,9 +68,9 @@ describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
|||||||
await admin.del(`/groups/${groupWithChat._id}/chat/${nextMessage.id}`);
|
await admin.del(`/groups/${groupWithChat._id}/chat/${nextMessage.id}`);
|
||||||
|
|
||||||
const returnedMessages = await user.get(`/groups/${groupWithChat._id}/chat/`);
|
const returnedMessages = await user.get(`/groups/${groupWithChat._id}/chat/`);
|
||||||
const messageFromUser = returnedMessages.find(returnedMessage => {
|
const messageFromUser = returnedMessages.find(
|
||||||
return returnedMessage.id === nextMessage.id;
|
returnedMessage => returnedMessage.id === nextMessage.id,
|
||||||
});
|
);
|
||||||
|
|
||||||
expect(returnedMessages).is.an('array');
|
expect(returnedMessages).is.an('array');
|
||||||
expect(messageFromUser).to.not.exist;
|
expect(messageFromUser).to.not.exist;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('GET /groups/:groupId/chat', () => {
|
|||||||
let group;
|
let group;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let leader = await generateUser({balance: 2});
|
const leader = await generateUser({ balance: 2 });
|
||||||
|
|
||||||
group = await generateGroup(leader, {
|
group = await generateGroup(leader, {
|
||||||
name: 'test group',
|
name: 'test group',
|
||||||
@@ -23,8 +23,8 @@ describe('GET /groups/:groupId/chat', () => {
|
|||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
}, {
|
}, {
|
||||||
chat: [
|
chat: [
|
||||||
{text: 'Hello', flags: {}, id: 1},
|
{ text: 'Hello', flags: {}, id: 1 },
|
||||||
{text: 'Welcome to the Guild', flags: {}, id: 2},
|
{ text: 'Welcome to the Guild', flags: {}, id: 2 },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -41,7 +41,7 @@ describe('GET /groups/:groupId/chat', () => {
|
|||||||
let group;
|
let group;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let leader = await generateUser({balance: 2});
|
const leader = await generateUser({ balance: 2 });
|
||||||
|
|
||||||
group = await generateGroup(leader, {
|
group = await generateGroup(leader, {
|
||||||
name: 'test group',
|
name: 'test group',
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
import {
|
|
||||||
generateUser,
|
|
||||||
translate as t,
|
|
||||||
} from '../../../../helpers/api-integration/v3';
|
|
||||||
import { find } from 'lodash';
|
import { find } from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import { IncomingWebhook } from '@slack/client';
|
import { IncomingWebhook } from '@slack/client';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
translate as t,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
const BASE_URL = nconf.get('BASE_URL');
|
const BASE_URL = nconf.get('BASE_URL');
|
||||||
|
|
||||||
describe('POST /chat/:chatId/flag', () => {
|
describe('POST /chat/:chatId/flag', () => {
|
||||||
let user, admin, anotherUser, newUser, group;
|
let user; let admin; let anotherUser; let newUser; let
|
||||||
|
group;
|
||||||
const TEST_MESSAGE = 'Test Message';
|
const TEST_MESSAGE = 'Test Message';
|
||||||
const USER_AGE_FOR_FLAGGING = 3;
|
const USER_AGE_FOR_FLAGGING = 3;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = await generateUser({balance: 1, 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate()});
|
user = await generateUser({ balance: 1, 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
|
||||||
admin = await generateUser({balance: 1, 'contributor.admin': true});
|
admin = await generateUser({ balance: 1, 'contributor.admin': true });
|
||||||
anotherUser = await generateUser({'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate()});
|
anotherUser = await generateUser({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
|
||||||
newUser = await generateUser({'auth.timestamps.created': moment().subtract(1, 'days').toDate()});
|
newUser = await generateUser({ 'auth.timestamps.created': moment().subtract(1, 'days').toDate() });
|
||||||
sandbox.stub(IncomingWebhook.prototype, 'send');
|
sandbox.stub(IncomingWebhook.prototype, 'send');
|
||||||
|
|
||||||
group = await user.post('/groups', {
|
group = await user.post('/groups', {
|
||||||
@@ -42,20 +43,20 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Allows players to flag their own message', async () => {
|
it('Allows players to flag their own message', async () => {
|
||||||
let message = await user.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const message = await user.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
await expect(user.post(`/groups/${group._id}/chat/${message.message.id}/flag`)).to.eventually.be.ok;
|
await expect(user.post(`/groups/${group._id}/chat/${message.message.id}/flag`)).to.eventually.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Flags a chat and sends normal message to moderator Slack when user is not new', async () => {
|
it('Flags a chat and sends normal message to moderator Slack when user is not new', async () => {
|
||||||
let { message } = await anotherUser.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await anotherUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
let flagResult = await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
const flagResult = await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
expect(flagResult.flags[user._id]).to.equal(true);
|
expect(flagResult.flags[user._id]).to.equal(true);
|
||||||
expect(flagResult.flagCount).to.equal(1);
|
expect(flagResult.flagCount).to.equal(1);
|
||||||
|
|
||||||
let groupWithFlags = await admin.get(`/groups/${group._id}`);
|
const groupWithFlags = await admin.get(`/groups/${group._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
expect(messageToCheck.flags[user._id]).to.equal(true);
|
expect(messageToCheck.flags[user._id]).to.equal(true);
|
||||||
|
|
||||||
// Slack message to mods
|
// Slack message to mods
|
||||||
@@ -81,16 +82,16 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Does not increment message flag count and sends different message to moderator Slack when user is new', async () => {
|
it('Does not increment message flag count and sends different message to moderator Slack when user is new', async () => {
|
||||||
let automatedComment = `The post's flag count has not been increased because the flagger's account is less than ${USER_AGE_FOR_FLAGGING} days old.`;
|
const automatedComment = `The post's flag count has not been increased because the flagger's account is less than ${USER_AGE_FOR_FLAGGING} days old.`;
|
||||||
let { message } = await newUser.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await newUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
let flagResult = await newUser.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
const flagResult = await newUser.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
expect(flagResult.flags[newUser._id]).to.equal(true);
|
expect(flagResult.flags[newUser._id]).to.equal(true);
|
||||||
expect(flagResult.flagCount).to.equal(0);
|
expect(flagResult.flagCount).to.equal(0);
|
||||||
|
|
||||||
let groupWithFlags = await admin.get(`/groups/${group._id}`);
|
const groupWithFlags = await admin.get(`/groups/${group._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
expect(messageToCheck.flags[newUser._id]).to.equal(true);
|
expect(messageToCheck.flags[newUser._id]).to.equal(true);
|
||||||
|
|
||||||
// Slack message to mods
|
// Slack message to mods
|
||||||
@@ -116,38 +117,38 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Flags a chat when the author\'s account was deleted', async () => {
|
it('Flags a chat when the author\'s account was deleted', async () => {
|
||||||
let deletedUser = await generateUser();
|
const deletedUser = await generateUser();
|
||||||
let { message } = await deletedUser.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await deletedUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
await deletedUser.del('/user', {
|
await deletedUser.del('/user', {
|
||||||
password: 'password',
|
password: 'password',
|
||||||
});
|
});
|
||||||
|
|
||||||
let flagResult = await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
const flagResult = await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
expect(flagResult.flags[user._id]).to.equal(true);
|
expect(flagResult.flags[user._id]).to.equal(true);
|
||||||
expect(flagResult.flagCount).to.equal(1);
|
expect(flagResult.flagCount).to.equal(1);
|
||||||
|
|
||||||
let groupWithFlags = await admin.get(`/groups/${group._id}`);
|
const groupWithFlags = await admin.get(`/groups/${group._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
expect(messageToCheck.flags[user._id]).to.equal(true);
|
expect(messageToCheck.flags[user._id]).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Flags a chat with a higher flag acount when an admin flags the message', async () => {
|
it('Flags a chat with a higher flag acount when an admin flags the message', async () => {
|
||||||
let { message } = await user.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await user.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
let flagResult = await admin.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
const flagResult = await admin.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
expect(flagResult.flags[admin._id]).to.equal(true);
|
expect(flagResult.flags[admin._id]).to.equal(true);
|
||||||
expect(flagResult.flagCount).to.equal(5);
|
expect(flagResult.flagCount).to.equal(5);
|
||||||
|
|
||||||
let groupWithFlags = await admin.get(`/groups/${group._id}`);
|
const groupWithFlags = await admin.get(`/groups/${group._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
expect(messageToCheck.flags[admin._id]).to.equal(true);
|
expect(messageToCheck.flags[admin._id]).to.equal(true);
|
||||||
expect(messageToCheck.flagCount).to.equal(5);
|
expect(messageToCheck.flagCount).to.equal(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows admin to flag a message in a private group', async () => {
|
it('allows admin to flag a message in a private group', async () => {
|
||||||
let privateGroup = await user.post('/groups', {
|
const privateGroup = await user.post('/groups', {
|
||||||
name: 'Test party',
|
name: 'Test party',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
@@ -156,26 +157,26 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
uuids: [anotherUser._id],
|
uuids: [anotherUser._id],
|
||||||
});
|
});
|
||||||
await anotherUser.post(`/groups/${privateGroup._id}/join`);
|
await anotherUser.post(`/groups/${privateGroup._id}/join`);
|
||||||
let { message } = await user.post(`/groups/${privateGroup._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await user.post(`/groups/${privateGroup._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
let flagResult = await admin.post(`/groups/${privateGroup._id}/chat/${message.id}/flag`);
|
const flagResult = await admin.post(`/groups/${privateGroup._id}/chat/${message.id}/flag`);
|
||||||
|
|
||||||
expect(flagResult.flags[admin._id]).to.equal(true);
|
expect(flagResult.flags[admin._id]).to.equal(true);
|
||||||
expect(flagResult.flagCount).to.equal(5);
|
expect(flagResult.flagCount).to.equal(5);
|
||||||
|
|
||||||
let groupWithFlags = await anotherUser.get(`/groups/${privateGroup._id}`);
|
const groupWithFlags = await anotherUser.get(`/groups/${privateGroup._id}`);
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
|
|
||||||
expect(messageToCheck).to.not.exist;
|
expect(messageToCheck).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not allow non member to flag message in private group', async () => {
|
it('does not allow non member to flag message in private group', async () => {
|
||||||
let privateGroup = await user.post('/groups', {
|
const privateGroup = await user.post('/groups', {
|
||||||
name: 'Test party',
|
name: 'Test party',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
});
|
});
|
||||||
let { message } = await user.post(`/groups/${privateGroup._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await user.post(`/groups/${privateGroup._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
await expect(anotherUser.post(`/groups/${privateGroup._id}/chat/${message.id}/flag`))
|
await expect(anotherUser.post(`/groups/${privateGroup._id}/chat/${message.id}/flag`))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
@@ -186,7 +187,7 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when user tries to flag a message that they already flagged', async () => {
|
it('Returns an error when user tries to flag a message that they already flagged', async () => {
|
||||||
let { message } = await anotherUser.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await anotherUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
await user.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
|
|
||||||
@@ -199,17 +200,17 @@ describe('POST /chat/:chatId/flag', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('shows a hidden message to the original poster', async () => {
|
it('shows a hidden message to the original poster', async () => {
|
||||||
let { message } = await user.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
|
const { message } = await user.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
|
||||||
|
|
||||||
await admin.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
await admin.post(`/groups/${group._id}/chat/${message.id}/flag`);
|
||||||
|
|
||||||
let groupWithFlags = await user.get(`/groups/${group._id}`);
|
const groupWithFlags = await user.get(`/groups/${group._id}`);
|
||||||
let messageToCheck = find(groupWithFlags.chat, {id: message.id});
|
const messageToCheck = find(groupWithFlags.chat, { id: message.id });
|
||||||
|
|
||||||
expect(messageToCheck).to.exist;
|
expect(messageToCheck).to.exist;
|
||||||
|
|
||||||
let auGroupWithFlags = await anotherUser.get(`/groups/${group._id}`);
|
const auGroupWithFlags = await anotherUser.get(`/groups/${group._id}`);
|
||||||
let auMessageToCheck = find(auGroupWithFlags.chat, {id: message.id});
|
const auMessageToCheck = find(auGroupWithFlags.chat, { id: message.id });
|
||||||
|
|
||||||
expect(auMessageToCheck).to.not.exist;
|
expect(auMessageToCheck).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
|
import { find } from 'lodash';
|
||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { find } from 'lodash';
|
|
||||||
|
|
||||||
describe('POST /chat/:chatId/like', () => {
|
describe('POST /chat/:chatId/like', () => {
|
||||||
let user;
|
let user;
|
||||||
let groupWithChat;
|
let groupWithChat;
|
||||||
let testMessage = 'Test Message';
|
const testMessage = 'Test Message';
|
||||||
let anotherUser;
|
let anotherUser;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'Test Guild',
|
name: 'Test Guild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -22,7 +22,7 @@ describe('POST /chat/:chatId/like', () => {
|
|||||||
|
|
||||||
user = groupLeader;
|
user = groupLeader;
|
||||||
groupWithChat = group;
|
groupWithChat = group;
|
||||||
anotherUser = members[0];
|
anotherUser = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when chat message is not found', async () => {
|
it('Returns an error when chat message is not found', async () => {
|
||||||
@@ -35,7 +35,7 @@ describe('POST /chat/:chatId/like', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when user tries to like their own message', async () => {
|
it('Returns an error when user tries to like their own message', async () => {
|
||||||
let message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`))
|
await expect(user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
@@ -46,30 +46,30 @@ describe('POST /chat/:chatId/like', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Likes a chat', async () => {
|
it('Likes a chat', async () => {
|
||||||
let message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
let likeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
const likeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
||||||
|
|
||||||
expect(likeResult.likes[user._id]).to.equal(true);
|
expect(likeResult.likes[user._id]).to.equal(true);
|
||||||
|
|
||||||
let groupWithChatLikes = await user.get(`/groups/${groupWithChat._id}`);
|
const groupWithChatLikes = await user.get(`/groups/${groupWithChat._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithChatLikes.chat, {id: message.message.id});
|
const messageToCheck = find(groupWithChatLikes.chat, { id: message.message.id });
|
||||||
expect(messageToCheck.likes[user._id]).to.equal(true);
|
expect(messageToCheck.likes[user._id]).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Unlikes a chat', async () => {
|
it('Unlikes a chat', async () => {
|
||||||
let message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
let likeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
const likeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
||||||
expect(likeResult.likes[user._id]).to.equal(true);
|
expect(likeResult.likes[user._id]).to.equal(true);
|
||||||
|
|
||||||
let unlikeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
const unlikeResult = await user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`);
|
||||||
expect(unlikeResult.likes[user._id]).to.equal(false);
|
expect(unlikeResult.likes[user._id]).to.equal(false);
|
||||||
|
|
||||||
let groupWithoutChatLikes = await user.get(`/groups/${groupWithChat._id}`);
|
const groupWithoutChatLikes = await user.get(`/groups/${groupWithChat._id}`);
|
||||||
|
|
||||||
let messageToCheck = find(groupWithoutChatLikes.chat, {id: message.message.id});
|
const messageToCheck = find(groupWithoutChatLikes.chat, { id: message.message.id });
|
||||||
expect(messageToCheck.likes[user._id]).to.equal(false);
|
expect(messageToCheck.likes[user._id]).to.equal(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { IncomingWebhook } from '@slack/client';
|
import { IncomingWebhook } from '@slack/client';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateUser,
|
generateUser,
|
||||||
@@ -13,7 +14,6 @@ import {
|
|||||||
TAVERN_ID,
|
TAVERN_ID,
|
||||||
} from '../../../../../website/server/models/group';
|
} from '../../../../../website/server/models/group';
|
||||||
import { CHAT_FLAG_FROM_SHADOW_MUTE } from '../../../../../website/common/script/constants';
|
import { CHAT_FLAG_FROM_SHADOW_MUTE } from '../../../../../website/common/script/constants';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
import { getMatchesByWordArray } from '../../../../../website/server/libs/stringUtils';
|
import { getMatchesByWordArray } from '../../../../../website/server/libs/stringUtils';
|
||||||
import bannedWords from '../../../../../website/server/libs/bannedWords';
|
import bannedWords from '../../../../../website/server/libs/bannedWords';
|
||||||
import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
|
import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
|
||||||
@@ -22,16 +22,17 @@ import * as email from '../../../../../website/server/libs/email';
|
|||||||
const BASE_URL = nconf.get('BASE_URL');
|
const BASE_URL = nconf.get('BASE_URL');
|
||||||
|
|
||||||
describe('POST /chat', () => {
|
describe('POST /chat', () => {
|
||||||
let user, groupWithChat, member, additionalMember;
|
let user; let groupWithChat; let member; let
|
||||||
let testMessage = 'Test Message';
|
additionalMember;
|
||||||
let testBannedWordMessage = 'TESTPLACEHOLDERSWEARWORDHERE';
|
const testMessage = 'Test Message';
|
||||||
let testBannedWordMessage1 = 'TESTPLACEHOLDERSWEARWORDHERE1';
|
const testBannedWordMessage = 'TESTPLACEHOLDERSWEARWORDHERE';
|
||||||
let testSlurMessage = 'message with TESTPLACEHOLDERSLURWORDHERE';
|
const testBannedWordMessage1 = 'TESTPLACEHOLDERSWEARWORDHERE1';
|
||||||
let testSlurMessage1 = 'TESTPLACEHOLDERSLURWORDHERE1';
|
const testSlurMessage = 'message with TESTPLACEHOLDERSLURWORDHERE';
|
||||||
let bannedWordErrorMessage = t('bannedWordUsed', {swearWordsUsed: testBannedWordMessage});
|
const testSlurMessage1 = 'TESTPLACEHOLDERSLURWORDHERE1';
|
||||||
|
const bannedWordErrorMessage = t('bannedWordUsed', { swearWordsUsed: testBannedWordMessage });
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'Test Guild',
|
name: 'Test Guild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -40,14 +41,14 @@ describe('POST /chat', () => {
|
|||||||
members: 2,
|
members: 2,
|
||||||
});
|
});
|
||||||
user = groupLeader;
|
user = groupLeader;
|
||||||
await user.update({'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL}); // prevent tests accidentally throwing messageGroupChatSpam
|
await user.update({ 'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL }); // prevent tests accidentally throwing messageGroupChatSpam
|
||||||
groupWithChat = group;
|
groupWithChat = group;
|
||||||
member = members[0];
|
member = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
additionalMember = members[1];
|
additionalMember = members[1]; // eslint-disable-line prefer-destructuring
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when no message is provided', async () => {
|
it('Returns an error when no message is provided', async () => {
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: ''}))
|
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: '' }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -56,7 +57,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when an empty message is provided', async () => {
|
it('Returns an error when an empty message is provided', async () => {
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: ' '}))
|
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: ' ' }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -65,7 +66,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when an message containing only newlines is provided', async () => {
|
it('Returns an error when an message containing only newlines is provided', async () => {
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: '\n\n'}))
|
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: '\n\n' }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -74,7 +75,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Returns an error when group is not found', async () => {
|
it('Returns an error when group is not found', async () => {
|
||||||
await expect(user.post('/groups/invalidID/chat', { message: testMessage})).to.eventually.be.rejected.and.eql({
|
await expect(user.post('/groups/invalidID/chat', { message: testMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('groupNotFound'),
|
message: t('groupNotFound'),
|
||||||
@@ -83,12 +84,12 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
describe('mute user', () => {
|
describe('mute user', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
member.update({'flags.chatRevoked': false});
|
member.update({ 'flags.chatRevoked': false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when chat privileges are revoked when sending a message to a public guild', async () => {
|
it('returns an error when chat privileges are revoked when sending a message to a public guild', async () => {
|
||||||
const userWithChatRevoked = await member.update({'flags.chatRevoked': true});
|
const userWithChatRevoked = await member.update({ 'flags.chatRevoked': true });
|
||||||
await expect(userWithChatRevoked.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
|
await expect(userWithChatRevoked.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
error: 'NotAuthorized',
|
error: 'NotAuthorized',
|
||||||
message: t('chatPrivilegesRevoked'),
|
message: t('chatPrivilegesRevoked'),
|
||||||
@@ -106,9 +107,9 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const privateGuildMemberWithChatsRevoked = members[0];
|
const privateGuildMemberWithChatsRevoked = members[0];
|
||||||
await privateGuildMemberWithChatsRevoked.update({'flags.chatRevoked': true});
|
await privateGuildMemberWithChatsRevoked.update({ 'flags.chatRevoked': true });
|
||||||
|
|
||||||
const message = await privateGuildMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage});
|
const message = await privateGuildMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
@@ -124,9 +125,9 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const privatePartyMemberWithChatsRevoked = members[0];
|
const privatePartyMemberWithChatsRevoked = members[0];
|
||||||
await privatePartyMemberWithChatsRevoked.update({'flags.chatRevoked': true});
|
await privatePartyMemberWithChatsRevoked.update({ 'flags.chatRevoked': true });
|
||||||
|
|
||||||
const message = await privatePartyMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage});
|
const message = await privatePartyMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
@@ -140,12 +141,12 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
member.update({'flags.chatShadowMuted': false});
|
member.update({ 'flags.chatShadowMuted': false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates a chat with flagCount already set and notifies mods when sending a message to a public guild', async () => {
|
it('creates a chat with flagCount already set and notifies mods when sending a message to a public guild', async () => {
|
||||||
const userWithChatShadowMuted = await member.update({'flags.chatShadowMuted': true});
|
const userWithChatShadowMuted = await member.update({ 'flags.chatShadowMuted': true });
|
||||||
const message = await userWithChatShadowMuted.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await userWithChatShadowMuted.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(message.message.flagCount).to.eql(CHAT_FLAG_FROM_SHADOW_MUTE);
|
expect(message.message.flagCount).to.eql(CHAT_FLAG_FROM_SHADOW_MUTE);
|
||||||
|
|
||||||
@@ -185,9 +186,9 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const userWithChatShadowMuted = members[0];
|
const userWithChatShadowMuted = members[0];
|
||||||
await userWithChatShadowMuted.update({'flags.chatShadowMuted': true});
|
await userWithChatShadowMuted.update({ 'flags.chatShadowMuted': true });
|
||||||
|
|
||||||
const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage});
|
const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(message.message.flagCount).to.eql(0);
|
expect(message.message.flagCount).to.eql(0);
|
||||||
@@ -204,16 +205,16 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const userWithChatShadowMuted = members[0];
|
const userWithChatShadowMuted = members[0];
|
||||||
await userWithChatShadowMuted.update({'flags.chatShadowMuted': true});
|
await userWithChatShadowMuted.update({ 'flags.chatShadowMuted': true });
|
||||||
|
|
||||||
const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage});
|
const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(message.message.flagCount).to.eql(0);
|
expect(message.message.flagCount).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates a chat with zero flagCount when non-shadow-muted user sends a message to a public guild', async () => {
|
it('creates a chat with zero flagCount when non-shadow-muted user sends a message to a public guild', async () => {
|
||||||
const message = await member.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await member.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(message.message.flagCount).to.eql(0);
|
expect(message.message.flagCount).to.eql(0);
|
||||||
});
|
});
|
||||||
@@ -221,7 +222,7 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
context('banned word', () => {
|
context('banned word', () => {
|
||||||
it('returns an error when chat message contains a banned word in tavern', async () => {
|
it('returns an error when chat message contains a banned word in tavern', async () => {
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: testBannedWordMessage}))
|
await expect(user.post('/groups/habitrpg/chat', { message: testBannedWordMessage }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -230,7 +231,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when chat message contains a banned word in a public guild', async () => {
|
it('returns an error when chat message contains a banned word in a public guild', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'public guild',
|
name: 'public guild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -239,7 +240,7 @@ describe('POST /chat', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage}))
|
await expect(members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -248,8 +249,8 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors when word is part of a phrase', async () => {
|
it('errors when word is part of a phrase', async () => {
|
||||||
let wordInPhrase = `phrase ${testBannedWordMessage} end`;
|
const wordInPhrase = `phrase ${testBannedWordMessage} end`;
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase}))
|
await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -258,8 +259,8 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors when word is surrounded by non alphabet characters', async () => {
|
it('errors when word is surrounded by non alphabet characters', async () => {
|
||||||
let wordInPhrase = `_!${testBannedWordMessage}@_`;
|
const wordInPhrase = `_!${testBannedWordMessage}@_`;
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase}))
|
await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
@@ -268,47 +269,51 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors when word is typed in mixed case', async () => {
|
it('errors when word is typed in mixed case', async () => {
|
||||||
let substrLength = Math.floor(testBannedWordMessage.length / 2);
|
const substrLength = Math.floor(testBannedWordMessage.length / 2);
|
||||||
let chatMessage = testBannedWordMessage.substring(0, substrLength).toLowerCase() + testBannedWordMessage.substring(substrLength).toUpperCase();
|
const chatMessage = testBannedWordMessage.substring(0, substrLength).toLowerCase()
|
||||||
|
+ testBannedWordMessage.substring(substrLength).toUpperCase();
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
|
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('bannedWordUsed', {swearWordsUsed: chatMessage}),
|
message: t('bannedWordUsed', { swearWordsUsed: chatMessage }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checks error message has all the banned words used, regardless of case', async () => {
|
it('checks error message has all the banned words used, regardless of case', async () => {
|
||||||
let testBannedWords = [testBannedWordMessage.toUpperCase(), testBannedWordMessage1.toLowerCase()];
|
const testBannedWords = [
|
||||||
let chatMessage = `Mixing ${testBannedWords[0]} and ${testBannedWords[1]} is bad for you.`;
|
testBannedWordMessage.toUpperCase(),
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage}))
|
testBannedWordMessage1.toLowerCase(),
|
||||||
|
];
|
||||||
|
const chatMessage = `Mixing ${testBannedWords[0]} and ${testBannedWords[1]} is bad for you.`;
|
||||||
|
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
|
||||||
.to.eventually.be.rejected
|
.to.eventually.be.rejected
|
||||||
.and.have.property('message')
|
.and.have.property('message')
|
||||||
.that.includes(testBannedWords.join(', '));
|
.that.includes(testBannedWords.join(', '));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('check all banned words are matched', async () => {
|
it('check all banned words are matched', async () => {
|
||||||
let message = bannedWords.join(',').replace(/\\/g, '');
|
const message = bannedWords.join(',').replace(/\\/g, '');
|
||||||
let matches = getMatchesByWordArray(message, bannedWords);
|
const matches = getMatchesByWordArray(message, bannedWords);
|
||||||
expect(matches.length).to.equal(bannedWords.length);
|
expect(matches.length).to.equal(bannedWords.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not error when bad word is suffix of a word', async () => {
|
it('does not error when bad word is suffix of a word', async () => {
|
||||||
let wordAsSuffix = `prefix${testBannedWordMessage}`;
|
const wordAsSuffix = `prefix${testBannedWordMessage}`;
|
||||||
let message = await user.post('/groups/habitrpg/chat', { message: wordAsSuffix});
|
const message = await user.post('/groups/habitrpg/chat', { message: wordAsSuffix });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not error when bad word is prefix of a word', async () => {
|
it('does not error when bad word is prefix of a word', async () => {
|
||||||
let wordAsPrefix = `${testBannedWordMessage}suffix`;
|
const wordAsPrefix = `${testBannedWordMessage}suffix`;
|
||||||
let message = await user.post('/groups/habitrpg/chat', { message: wordAsPrefix});
|
const message = await user.post('/groups/habitrpg/chat', { message: wordAsPrefix });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not error when sending a chat message containing a banned word to a party', async () => {
|
it('does not error when sending a chat message containing a banned word to a party', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'Party',
|
name: 'Party',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
@@ -317,13 +322,13 @@ describe('POST /chat', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
|
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not error when sending a chat message containing a banned word to a public guild in which banned words are allowed', async () => {
|
it('does not error when sending a chat message containing a banned word to a public guild in which banned words are allowed', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'public guild',
|
name: 'public guild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -334,13 +339,13 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
guildsAllowingBannedWords[group._id] = true;
|
guildsAllowingBannedWords[group._id] = true;
|
||||||
|
|
||||||
let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
|
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not error when sending a chat message containing a banned word to a private guild', async () => {
|
it('does not error when sending a chat message containing a banned word to a private guild', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'private guild',
|
name: 'private guild',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
@@ -349,7 +354,7 @@ describe('POST /chat', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
|
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
});
|
});
|
||||||
@@ -363,11 +368,11 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
user.update({'flags.chatRevoked': false});
|
user.update({ 'flags.chatRevoked': false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('errors and revokes privileges when chat message contains a banned slur', async () => {
|
it('errors and revokes privileges when chat message contains a banned slur', async () => {
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testSlurMessage})).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testSlurMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('bannedSlurUsed'),
|
message: t('bannedSlurUsed'),
|
||||||
@@ -398,7 +403,7 @@ describe('POST /chat', () => {
|
|||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
// Chat privileges are revoked
|
// Chat privileges are revoked
|
||||||
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
error: 'NotAuthorized',
|
error: 'NotAuthorized',
|
||||||
message: t('chatPrivilegesRevoked'),
|
message: t('chatPrivilegesRevoked'),
|
||||||
@@ -406,7 +411,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not allow slurs in private groups', async () => {
|
it('does not allow slurs in private groups', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'Party',
|
name: 'Party',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
@@ -415,7 +420,7 @@ describe('POST /chat', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage})).to.eventually.be.rejected.and.eql({
|
await expect(members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('bannedSlurUsed'),
|
message: t('bannedSlurUsed'),
|
||||||
@@ -446,7 +451,7 @@ describe('POST /chat', () => {
|
|||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
// Chat privileges are revoked
|
// Chat privileges are revoked
|
||||||
await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
|
await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
|
||||||
code: 401,
|
code: 401,
|
||||||
error: 'NotAuthorized',
|
error: 'NotAuthorized',
|
||||||
message: t('chatPrivilegesRevoked'),
|
message: t('chatPrivilegesRevoked'),
|
||||||
@@ -454,8 +459,9 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors when slur is typed in mixed case', async () => {
|
it('errors when slur is typed in mixed case', async () => {
|
||||||
let substrLength = Math.floor(testSlurMessage1.length / 2);
|
const substrLength = Math.floor(testSlurMessage1.length / 2);
|
||||||
let chatMessage = testSlurMessage1.substring(0, substrLength).toLowerCase() + testSlurMessage1.substring(substrLength).toUpperCase();
|
const chatMessage = testSlurMessage1.substring(0, substrLength).toLowerCase()
|
||||||
|
+ testSlurMessage1.substring(substrLength).toUpperCase();
|
||||||
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
|
await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -466,7 +472,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a chat', async () => {
|
it('creates a chat', async () => {
|
||||||
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
|
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
|
||||||
|
|
||||||
expect(newMessage.message.id).to.exist;
|
expect(newMessage.message.id).to.exist;
|
||||||
@@ -479,7 +485,7 @@ describe('POST /chat', () => {
|
|||||||
THIS PART WON'T BE IN THE MESSAGE (over 3000)
|
THIS PART WON'T BE IN THE MESSAGE (over 3000)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: veryLongMessage});
|
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: veryLongMessage });
|
||||||
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
|
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
|
||||||
|
|
||||||
expect(newMessage.message.id).to.exist;
|
expect(newMessage.message.id).to.exist;
|
||||||
@@ -501,7 +507,7 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
await userWithStyle.sync();
|
await userWithStyle.sync();
|
||||||
|
|
||||||
const message = await userWithStyle.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await userWithStyle.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(message.message.userStyles.items.currentMount).to.eql(userWithStyle.items.currentMount);
|
expect(message.message.userStyles.items.currentMount).to.eql(userWithStyle.items.currentMount);
|
||||||
@@ -511,7 +517,8 @@ describe('POST /chat', () => {
|
|||||||
expect(message.message.userStyles.preferences.skin).to.eql(userWithStyle.preferences.skin);
|
expect(message.message.userStyles.preferences.skin).to.eql(userWithStyle.preferences.skin);
|
||||||
expect(message.message.userStyles.preferences.shirt).to.eql(userWithStyle.preferences.shirt);
|
expect(message.message.userStyles.preferences.shirt).to.eql(userWithStyle.preferences.shirt);
|
||||||
expect(message.message.userStyles.preferences.chair).to.eql(userWithStyle.preferences.chair);
|
expect(message.message.userStyles.preferences.chair).to.eql(userWithStyle.preferences.chair);
|
||||||
expect(message.message.userStyles.preferences.background).to.eql(userWithStyle.preferences.background);
|
expect(message.message.userStyles.preferences.background)
|
||||||
|
.to.eql(userWithStyle.preferences.background);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds backer info to chat', async () => {
|
it('adds backer info to chat', async () => {
|
||||||
@@ -524,7 +531,7 @@ describe('POST /chat', () => {
|
|||||||
backer: backerInfo,
|
backer: backerInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
const message = await backer.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
|
const message = await backer.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
const messageBackerInfo = message.message.backer;
|
const messageBackerInfo = message.message.backer;
|
||||||
|
|
||||||
expect(messageBackerInfo.npc).to.equal(backerInfo.npc);
|
expect(messageBackerInfo.npc).to.equal(backerInfo.npc);
|
||||||
@@ -533,8 +540,8 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sends group chat received webhooks', async () => {
|
it('sends group chat received webhooks', async () => {
|
||||||
let userUuid = generateUUID();
|
const userUuid = generateUUID();
|
||||||
let memberUuid = generateUUID();
|
const memberUuid = generateUUID();
|
||||||
await server.start();
|
await server.start();
|
||||||
|
|
||||||
await user.post('/user/webhook', {
|
await user.post('/user/webhook', {
|
||||||
@@ -554,16 +561,16 @@ describe('POST /chat', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
|
|
||||||
await sleep();
|
await sleep();
|
||||||
|
|
||||||
await server.close();
|
await server.close();
|
||||||
|
|
||||||
let userBody = server.getWebhookData(userUuid);
|
const userBody = server.getWebhookData(userUuid);
|
||||||
let memberBody = server.getWebhookData(memberUuid);
|
const memberBody = server.getWebhookData(memberUuid);
|
||||||
|
|
||||||
[userBody, memberBody].forEach((body) => {
|
[userBody, memberBody].forEach(body => {
|
||||||
expect(body.group.id).to.eql(groupWithChat._id);
|
expect(body.group.id).to.eql(groupWithChat._id);
|
||||||
expect(body.group.name).to.eql(groupWithChat.name);
|
expect(body.group.name).to.eql(groupWithChat.name);
|
||||||
expect(body.chat).to.eql(message.message);
|
expect(body.chat).to.eql(message.message);
|
||||||
@@ -572,22 +579,20 @@ describe('POST /chat', () => {
|
|||||||
|
|
||||||
context('chat notifications', () => {
|
context('chat notifications', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
member.update({newMessages: {}, notifications: []});
|
member.update({ newMessages: {}, notifications: [] });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies other users of new messages for a guild', async () => {
|
it('notifies other users of new messages for a guild', async () => {
|
||||||
let message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
let memberWithNotification = await member.get('/user');
|
const memberWithNotification = await member.get('/user');
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(memberWithNotification.newMessages[`${groupWithChat._id}`]).to.exist;
|
expect(memberWithNotification.newMessages[`${groupWithChat._id}`]).to.exist;
|
||||||
expect(memberWithNotification.notifications.find(n => {
|
expect(memberWithNotification.notifications.find(n => n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === groupWithChat._id)).to.exist;
|
||||||
return n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === groupWithChat._id;
|
|
||||||
})).to.exist;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies other users of new messages for a party', async () => {
|
it('notifies other users of new messages for a party', async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
name: 'Test Party',
|
name: 'Test Party',
|
||||||
type: 'party',
|
type: 'party',
|
||||||
@@ -596,36 +601,32 @@ describe('POST /chat', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
let message = await groupLeader.post(`/groups/${group._id}/chat`, { message: testMessage });
|
const message = await groupLeader.post(`/groups/${group._id}/chat`, { message: testMessage });
|
||||||
let memberWithNotification = await members[0].get('/user');
|
const memberWithNotification = await members[0].get('/user');
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(memberWithNotification.newMessages[`${group._id}`]).to.exist;
|
expect(memberWithNotification.newMessages[`${group._id}`]).to.exist;
|
||||||
expect(memberWithNotification.notifications.find(n => {
|
expect(memberWithNotification.notifications.find(n => n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === group._id)).to.exist;
|
||||||
return n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === group._id;
|
|
||||||
})).to.exist;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not notify other users of a new message that is already hidden from shadow-muting', async () => {
|
it('does not notify other users of a new message that is already hidden from shadow-muting', async () => {
|
||||||
await user.update({'flags.chatShadowMuted': true});
|
await user.update({ 'flags.chatShadowMuted': true });
|
||||||
let message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
const message = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
|
||||||
let memberWithNotification = await member.get('/user');
|
const memberWithNotification = await member.get('/user');
|
||||||
|
|
||||||
await user.update({'flags.chatShadowMuted': false});
|
await user.update({ 'flags.chatShadowMuted': false });
|
||||||
|
|
||||||
expect(message.message.id).to.exist;
|
expect(message.message.id).to.exist;
|
||||||
expect(memberWithNotification.newMessages[`${groupWithChat._id}`]).to.not.exist;
|
expect(memberWithNotification.newMessages[`${groupWithChat._id}`]).to.not.exist;
|
||||||
expect(memberWithNotification.notifications.find(n => {
|
expect(memberWithNotification.notifications.find(n => n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === groupWithChat._id)).to.not.exist;
|
||||||
return n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === groupWithChat._id;
|
|
||||||
})).to.not.exist;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Spam prevention', () => {
|
context('Spam prevention', () => {
|
||||||
it('Returns an error when the user has been posting too many messages', async () => {
|
it('Returns an error when the user has been posting too many messages', async () => {
|
||||||
// Post as many messages are needed to reach the spam limit
|
// Post as many messages are needed to reach the spam limit
|
||||||
for (let i = 0; i < SPAM_MESSAGE_LIMIT; i++) {
|
for (let i = 0; i < SPAM_MESSAGE_LIMIT; i += 1) {
|
||||||
let result = await additionalMember.post(`/groups/${TAVERN_ID}/chat`, { message: testMessage }); // eslint-disable-line no-await-in-loop
|
const result = await additionalMember.post(`/groups/${TAVERN_ID}/chat`, { message: testMessage }); // eslint-disable-line no-await-in-loop
|
||||||
expect(result.message.id).to.exist;
|
expect(result.message.id).to.exist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,11 +638,11 @@ describe('POST /chat', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('contributor should not receive spam alert', async () => {
|
it('contributor should not receive spam alert', async () => {
|
||||||
let userSocialite = await member.update({'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL});
|
const userSocialite = await member.update({ 'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL });
|
||||||
|
|
||||||
// Post 1 more message than the spam limit to ensure they do not reach the limit
|
// Post 1 more message than the spam limit to ensure they do not reach the limit
|
||||||
for (let i = 0; i < SPAM_MESSAGE_LIMIT + 1; i++) {
|
for (let i = 0; i < SPAM_MESSAGE_LIMIT + 1; i += 1) {
|
||||||
let result = await userSocialite.post(`/groups/${TAVERN_ID}/chat`, { message: testMessage }); // eslint-disable-line no-await-in-loop
|
const result = await userSocialite.post(`/groups/${TAVERN_ID}/chat`, { message: testMessage }); // eslint-disable-line no-await-in-loop
|
||||||
expect(result.message.id).to.exist;
|
expect(result.message.id).to.exist;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import {
|
|||||||
|
|
||||||
describe('POST /groups/:id/chat/seen', () => {
|
describe('POST /groups/:id/chat/seen', () => {
|
||||||
context('Guild', () => {
|
context('Guild', () => {
|
||||||
let guild, guildLeader, guildMember, guildMessage;
|
let guild; let guildLeader; let guildMember; let
|
||||||
|
guildMessage;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -18,7 +19,7 @@ describe('POST /groups/:id/chat/seen', () => {
|
|||||||
|
|
||||||
guild = group;
|
guild = group;
|
||||||
guildLeader = groupLeader;
|
guildLeader = groupLeader;
|
||||||
guildMember = members[0];
|
guildMember = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
guildMessage = await guildLeader.post(`/groups/${guild._id}/chat`, { message: 'Some guild message' });
|
guildMessage = await guildLeader.post(`/groups/${guild._id}/chat`, { message: 'Some guild message' });
|
||||||
guildMessage = guildMessage.message;
|
guildMessage = guildMessage.message;
|
||||||
@@ -32,7 +33,7 @@ describe('POST /groups/:id/chat/seen', () => {
|
|||||||
|
|
||||||
await sleep(1);
|
await sleep(1);
|
||||||
|
|
||||||
let guildThatHasSeenChat = await guildMember.get('/user');
|
const guildThatHasSeenChat = await guildMember.get('/user');
|
||||||
|
|
||||||
expect(guildThatHasSeenChat.notifications.length).to.equal(initialNotifications - 1);
|
expect(guildThatHasSeenChat.notifications.length).to.equal(initialNotifications - 1);
|
||||||
expect(guildThatHasSeenChat.newMessages).to.be.empty;
|
expect(guildThatHasSeenChat.newMessages).to.be.empty;
|
||||||
@@ -40,10 +41,11 @@ describe('POST /groups/:id/chat/seen', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Party', () => {
|
context('Party', () => {
|
||||||
let party, partyLeader, partyMember, partyMessage;
|
let party; let partyLeader; let partyMember; let
|
||||||
|
partyMessage;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'party',
|
type: 'party',
|
||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
@@ -53,7 +55,7 @@ describe('POST /groups/:id/chat/seen', () => {
|
|||||||
|
|
||||||
party = group;
|
party = group;
|
||||||
partyLeader = groupLeader;
|
partyLeader = groupLeader;
|
||||||
partyMember = members[0];
|
partyMember = members[0]; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
partyMessage = await partyLeader.post(`/groups/${party._id}/chat`, { message: 'Some party message' });
|
partyMessage = await partyLeader.post(`/groups/${party._id}/chat`, { message: 'Some party message' });
|
||||||
partyMessage = partyMessage.message;
|
partyMessage = partyMessage.message;
|
||||||
@@ -67,7 +69,7 @@ describe('POST /groups/:id/chat/seen', () => {
|
|||||||
|
|
||||||
await sleep(1);
|
await sleep(1);
|
||||||
|
|
||||||
let partyMemberThatHasSeenChat = await partyMember.get('/user');
|
const partyMemberThatHasSeenChat = await partyMember.get('/user');
|
||||||
|
|
||||||
expect(partyMemberThatHasSeenChat.notifications.length).to.equal(initialNotifications - 1);
|
expect(partyMemberThatHasSeenChat.notifications.length).to.equal(initialNotifications - 1);
|
||||||
expect(partyMemberThatHasSeenChat.newMessages).to.be.empty;
|
expect(partyMemberThatHasSeenChat.newMessages).to.be.empty;
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import config from '../../../../../config.json';
|
import config from '../../../../../config.json';
|
||||||
import moment from 'moment';
|
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('POST /groups/:id/chat/:id/clearflags', () => {
|
describe('POST /groups/:id/chat/:id/clearflags', () => {
|
||||||
const USER_AGE_FOR_FLAGGING = 3;
|
const USER_AGE_FOR_FLAGGING = 3;
|
||||||
let groupWithChat, message, author, nonAdmin, admin;
|
let groupWithChat; let message; let author; let nonAdmin; let
|
||||||
|
admin;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let { group, groupLeader } = await createAndPopulateGroup({
|
const { group, groupLeader } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
@@ -21,8 +22,8 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
|
|
||||||
groupWithChat = group;
|
groupWithChat = group;
|
||||||
author = groupLeader;
|
author = groupLeader;
|
||||||
nonAdmin = await generateUser({'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate()});
|
nonAdmin = await generateUser({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
|
||||||
admin = await generateUser({'contributor.admin': true});
|
admin = await generateUser({ 'contributor.admin': true });
|
||||||
|
|
||||||
message = await author.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message' });
|
message = await author.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message' });
|
||||||
message = message.message;
|
message = message.message;
|
||||||
@@ -30,17 +31,15 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Single Message', () => {
|
context('Single Message', () => {
|
||||||
it('returns error when non-admin attempts to clear flags', async () => {
|
it('returns error when non-admin attempts to clear flags', async () => expect(nonAdmin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`))
|
||||||
return expect(nonAdmin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`))
|
.to.eventually.be.rejected.and.eql({
|
||||||
.to.eventually.be.rejected.and.eql({
|
code: 401,
|
||||||
code: 401,
|
error: 'NotAuthorized',
|
||||||
error: 'NotAuthorized',
|
message: t('messageGroupChatAdminClearFlagCount'),
|
||||||
message: t('messageGroupChatAdminClearFlagCount'),
|
}));
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns error if message does not exist', async () => {
|
it('returns error if message does not exist', async () => {
|
||||||
let fakeMessageID = generateUUID();
|
const fakeMessageID = generateUUID();
|
||||||
|
|
||||||
await expect(admin.post(`/groups/${groupWithChat._id}/chat/${fakeMessageID}/clearflags`))
|
await expect(admin.post(`/groups/${groupWithChat._id}/chat/${fakeMessageID}/clearflags`))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
@@ -52,13 +51,13 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
|
|
||||||
it('clears flags and leaves old flags on the flag object', async () => {
|
it('clears flags and leaves old flags on the flag object', async () => {
|
||||||
await admin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`);
|
await admin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`);
|
||||||
let messages = await admin.get(`/groups/${groupWithChat._id}/chat`);
|
const messages = await admin.get(`/groups/${groupWithChat._id}/chat`);
|
||||||
expect(messages[0].flagCount).to.eql(0);
|
expect(messages[0].flagCount).to.eql(0);
|
||||||
expect(messages[0].flags).to.have.property(admin._id, true);
|
expect(messages[0].flags).to.have.property(admin._id, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clears flags in a private group', async () => {
|
it('clears flags in a private group', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'party',
|
type: 'party',
|
||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
@@ -82,7 +81,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can\'t flag a system message', async () => {
|
it('can\'t flag a system message', async () => {
|
||||||
let { group, members } = await createAndPopulateGroup({
|
const { group, members } = await createAndPopulateGroup({
|
||||||
groupDetails: {
|
groupDetails: {
|
||||||
type: 'party',
|
type: 'party',
|
||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
@@ -90,7 +89,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
members: 1,
|
members: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
let member = members[0];
|
const member = members[0];
|
||||||
|
|
||||||
// make member that can use skills
|
// make member that can use skills
|
||||||
await member.update({
|
await member.update({
|
||||||
@@ -101,12 +100,12 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
|
|
||||||
await member.post('/user/class/cast/mpheal');
|
await member.post('/user/class/cast/mpheal');
|
||||||
|
|
||||||
let [skillMsg] = await member.get(`/groups/${group.id}/chat`);
|
const [skillMsg] = await member.get(`/groups/${group.id}/chat`);
|
||||||
await expect(member.post(`/groups/${group._id}/chat/${skillMsg.id}/flag`))
|
await expect(member.post(`/groups/${group._id}/chat/${skillMsg.id}/flag`))
|
||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('messageCannotFlagSystemMessages', {communityManagerEmail: config.EMAILS_COMMUNITY_MANAGER_EMAIL}),
|
message: t('messageCannotFlagSystemMessages', { communityManagerEmail: config.EMAILS_COMMUNITY_MANAGER_EMAIL }),
|
||||||
});
|
});
|
||||||
// let messages = await members[0].get(`/groups/${group._id}/chat`);
|
// let messages = await members[0].get(`/groups/${group._id}/chat`);
|
||||||
// expect(messages[0].id).to.eql(skillMsg.id);
|
// expect(messages[0].id).to.eql(skillMsg.id);
|
||||||
@@ -115,7 +114,8 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('admin user, group with multiple messages', () => {
|
context('admin user, group with multiple messages', () => {
|
||||||
let message2, message3, message4;
|
let message2; let message3; let
|
||||||
|
message4;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
message2 = await author.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message 2' });
|
message2 = await author.post(`/groups/${groupWithChat._id}/chat`, { message: 'Some message 2' });
|
||||||
@@ -133,14 +133,14 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
|
|||||||
|
|
||||||
it('changes only the message that is flagged', async () => {
|
it('changes only the message that is flagged', async () => {
|
||||||
await admin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`);
|
await admin.post(`/groups/${groupWithChat._id}/chat/${message.id}/clearflags`);
|
||||||
let messages = await admin.get(`/groups/${groupWithChat._id}/chat`);
|
const messages = await admin.get(`/groups/${groupWithChat._id}/chat`);
|
||||||
|
|
||||||
expect(messages).to.have.lengthOf(4);
|
expect(messages).to.have.lengthOf(4);
|
||||||
|
|
||||||
let messageThatWasUnflagged = messages[3];
|
const messageThatWasUnflagged = messages[3];
|
||||||
let messageWith1Flag = messages[2];
|
const messageWith1Flag = messages[2];
|
||||||
let messageWith2Flag = messages[1];
|
const messageWith2Flag = messages[1];
|
||||||
let messageWithoutFlags = messages[0];
|
const messageWithoutFlags = messages[0];
|
||||||
|
|
||||||
expect(messageThatWasUnflagged.flagCount).to.eql(0);
|
expect(messageThatWasUnflagged.flagCount).to.eql(0);
|
||||||
expect(messageThatWasUnflagged.flags).to.have.property(admin._id, true);
|
expect(messageThatWasUnflagged.flags).to.have.property(admin._id, true);
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ import i18n from '../../../../../website/common/script/i18n';
|
|||||||
|
|
||||||
describe('GET /content', () => {
|
describe('GET /content', () => {
|
||||||
it('returns content (and does not require authentication)', async () => {
|
it('returns content (and does not require authentication)', async () => {
|
||||||
let res = await requester().get('/content');
|
const res = await requester().get('/content');
|
||||||
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
||||||
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(t('backgroundBeachText'));
|
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(t('backgroundBeachText'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns content not in English', async () => {
|
it('returns content not in English', async () => {
|
||||||
let res = await requester().get('/content?language=de');
|
const res = await requester().get('/content?language=de');
|
||||||
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
||||||
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(i18n.t('backgroundBeachText', 'de'));
|
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(i18n.t('backgroundBeachText', 'de'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to English if the desired language is not found', async () => {
|
it('falls back to English if the desired language is not found', async () => {
|
||||||
let res = await requester().get('/content?language=wrong');
|
const res = await requester().get('/content?language=wrong');
|
||||||
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
expect(res).to.have.nested.property('backgrounds.backgrounds062014.beach');
|
||||||
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(t('backgroundBeachText'));
|
expect(res.backgrounds.backgrounds062014.beach.text).to.equal(t('backgroundBeachText'));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ describe('GET /coupons/', () => {
|
|||||||
'contributor.sudo': true,
|
'contributor.sudo': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let coupons = await user.post('/coupons/generate/wondercon?count=11');
|
const coupons = await user.post('/coupons/generate/wondercon?count=11');
|
||||||
let res = await user.get('/coupons');
|
const res = await user.get('/coupons');
|
||||||
let splitRes = res.split('\n');
|
const splitRes = res.split('\n');
|
||||||
|
|
||||||
expect(splitRes.length).to.equal(13);
|
expect(splitRes.length).to.equal(13);
|
||||||
expect(splitRes[0]).to.equal('code,event,date,user');
|
expect(splitRes[0]).to.equal('code,event,date,user');
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ describe('POST /coupons/enter/:code', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error if coupon has been used', async () => {
|
it('returns an error if coupon has been used', async () => {
|
||||||
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
const [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
||||||
await user.post(`/coupons/enter/${coupon._id}`); // use coupon
|
await user.post(`/coupons/enter/${coupon._id}`); // use coupon
|
||||||
|
|
||||||
await expect(user.post(`/coupons/enter/${coupon._id}`)).to.eventually.be.rejected.and.eql({
|
await expect(user.post(`/coupons/enter/${coupon._id}`)).to.eventually.be.rejected.and.eql({
|
||||||
@@ -47,8 +47,8 @@ describe('POST /coupons/enter/:code', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should apply the coupon to the user', async () => {
|
it('should apply the coupon to the user', async () => {
|
||||||
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
const [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
||||||
let userRes = await user.post(`/coupons/enter/${coupon._id}`);
|
const userRes = await user.post(`/coupons/enter/${coupon._id}`);
|
||||||
expect(userRes._id).to.equal(user._id);
|
expect(userRes._id).to.equal(user._id);
|
||||||
expect(userRes.items.gear.owned.eyewear_special_wondercon_red).to.be.true;
|
expect(userRes.items.gear.owned.eyewear_special_wondercon_red).to.be.true;
|
||||||
expect(userRes.items.gear.owned.eyewear_special_wondercon_black).to.be.true;
|
expect(userRes.items.gear.owned.eyewear_special_wondercon_black).to.be.true;
|
||||||
@@ -57,6 +57,6 @@ describe('POST /coupons/enter/:code', () => {
|
|||||||
expect(userRes.items.gear.owned.body_special_wondercon_red).to.be.true;
|
expect(userRes.items.gear.owned.body_special_wondercon_red).to.be.true;
|
||||||
expect(userRes.items.gear.owned.body_special_wondercon_black).to.be.true;
|
expect(userRes.items.gear.owned.body_special_wondercon_black).to.be.true;
|
||||||
expect(userRes.items.gear.owned.body_special_wondercon_gold).to.be.true;
|
expect(userRes.items.gear.owned.body_special_wondercon_gold).to.be.true;
|
||||||
expect(userRes.extra).to.eql({signupEvent: 'wondercon'});
|
expect(userRes.extra).to.eql({ signupEvent: 'wondercon' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import couponCode from 'coupon-code';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import couponCode from 'coupon-code';
|
|
||||||
import apiError from '../../../../../website/server/libs/apiError';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('POST /coupons/generate/:event', () => {
|
describe('POST /coupons/generate/:event', () => {
|
||||||
@@ -51,7 +51,7 @@ describe('POST /coupons/generate/:event', () => {
|
|||||||
'contributor.sudo': true,
|
'contributor.sudo': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let coupons = await user.post('/coupons/generate/wondercon?count=2');
|
const coupons = await user.post('/coupons/generate/wondercon?count=2');
|
||||||
expect(coupons.length).to.equal(2);
|
expect(coupons.length).to.equal(2);
|
||||||
expect(coupons[0].event).to.equal('wondercon');
|
expect(coupons[0].event).to.equal('wondercon');
|
||||||
expect(couponCode.validate(coupons[1]._id)).to.not.equal(''); // '' means invalid
|
expect(couponCode.validate(coupons[1]._id)).to.not.equal(''); // '' means invalid
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /coupons/validate/:code', () => {
|
describe('POST /coupons/validate/:code', () => {
|
||||||
let api = requester();
|
const api = requester();
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await resetHabiticaDB();
|
await resetHabiticaDB();
|
||||||
@@ -20,17 +20,17 @@ describe('POST /coupons/validate/:code', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if coupon code is valid', async () => {
|
it('returns true if coupon code is valid', async () => {
|
||||||
let sudoUser = await generateUser({
|
const sudoUser = await generateUser({
|
||||||
'contributor.sudo': true,
|
'contributor.sudo': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
const [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
|
||||||
let res = await api.post(`/coupons/validate/${coupon._id}`);
|
const res = await api.post(`/coupons/validate/${coupon._id}`);
|
||||||
expect(res).to.eql({valid: true});
|
expect(res).to.eql({ valid: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if coupon code is valid', async () => {
|
it('returns false if coupon code is valid', async () => {
|
||||||
let res = await api.post('/coupons/validate/notValid');
|
const res = await api.post('/coupons/validate/notValid');
|
||||||
expect(res).to.eql({valid: false});
|
expect(res).to.eql({ valid: false });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
xdescribe('GET /export/avatar-:memberId.html', () => {
|
xdescribe('GET /export/avatar-:memberId.html', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -20,16 +20,16 @@ xdescribe('GET /export/avatar-:memberId.html', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles non-existing members', async () => {
|
it('handles non-existing members', async () => {
|
||||||
let dummyId = generateUUID();
|
const dummyId = generateUUID();
|
||||||
await expect(user.get(`/export/avatar-${dummyId}.html`)).to.eventually.be.rejected.and.eql({
|
await expect(user.get(`/export/avatar-${dummyId}.html`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
message: t('userWithIDNotFound', {userId: dummyId}),
|
message: t('userWithIDNotFound', { userId: dummyId }),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an html page', async () => {
|
it('returns an html page', async () => {
|
||||||
let res = await user.get(`/export/avatar-${user._id}.html`);
|
const res = await user.get(`/export/avatar-${user._id}.html`);
|
||||||
expect(res.substring(0, 100).indexOf('<!DOCTYPE html>')).to.equal(0);
|
expect(res.substring(0, 100).indexOf('<!DOCTYPE html>')).to.equal(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
|
import moment from 'moment';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
updateDocument,
|
updateDocument,
|
||||||
} from '../../../../helpers/mongo';
|
} from '../../../../helpers/mongo';
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
describe('GET /export/history.csv', () => {
|
describe('GET /export/history.csv', () => {
|
||||||
// TODO disabled because it randomly causes the build to fail
|
// TODO disabled because it randomly causes the build to fail
|
||||||
xit('should return a valid CSV file with tasks history data', async () => {
|
xit('should return a valid CSV file with tasks history data', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
let tasks = await user.post('/tasks/user', [
|
let tasks = await user.post('/tasks/user', [
|
||||||
{type: 'daily', text: 'daily 1'},
|
{ type: 'daily', text: 'daily 1' },
|
||||||
{type: 'habit', text: 'habit 1'},
|
{ type: 'habit', text: 'habit 1' },
|
||||||
{type: 'habit', text: 'habit 2'},
|
{ type: 'habit', text: 'habit 2' },
|
||||||
{type: 'todo', text: 'todo 1'},
|
{ type: 'todo', text: 'todo 1' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// to handle occasional inconsistency in task creation order
|
// to handle occasional inconsistency in task creation order
|
||||||
tasks.sort(function (a, b) {
|
tasks.sort((a, b) => a.text.localeCompare(b.text));
|
||||||
return a.text.localeCompare(b.text);
|
|
||||||
});
|
|
||||||
|
|
||||||
// score all the tasks twice
|
// score all the tasks twice
|
||||||
await user.post(`/tasks/${tasks[0]._id}/score/up`);
|
await user.post(`/tasks/${tasks[0]._id}/score/up`);
|
||||||
@@ -35,16 +33,14 @@ describe('GET /export/history.csv', () => {
|
|||||||
|
|
||||||
// adding an history entry to daily 1 manually because cron didn't run yet
|
// adding an history entry to daily 1 manually because cron didn't run yet
|
||||||
await updateDocument('tasks', tasks[0], {
|
await updateDocument('tasks', tasks[0], {
|
||||||
history: [{value: 3.2, date: Number(new Date())}],
|
history: [{ value: 3.2, date: Number(new Date()) }],
|
||||||
});
|
});
|
||||||
|
|
||||||
// get updated tasks
|
// get updated tasks
|
||||||
tasks = await Promise.all(tasks.map(task => {
|
tasks = await Promise.all(tasks.map(task => user.get(`/tasks/${task._id}`)));
|
||||||
return user.get(`/tasks/${task._id}`);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let res = await user.get('/export/history.csv');
|
const res = await user.get('/export/history.csv');
|
||||||
let splitRes = res.split('\n');
|
const splitRes = res.split('\n');
|
||||||
|
|
||||||
expect(splitRes[0]).to.equal('Task Name,Task ID,Task Type,Date,Value');
|
expect(splitRes[0]).to.equal('Task Name,Task ID,Task Type,Date,Value');
|
||||||
expect(splitRes[1]).to.equal(`daily 1,${tasks[0]._id},daily,${moment(tasks[0].history[0].date).format('YYYY-MM-DD HH:mm:ss')},${tasks[0].history[0].value}`);
|
expect(splitRes[1]).to.equal(`daily 1,${tasks[0]._id},daily,${moment(tasks[0].history[0].date).format('YYYY-MM-DD HH:mm:ss')},${tasks[0].history[0].value}`);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ describe('GET /export/inbox.html', () => {
|
|||||||
let user;
|
let user;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
let otherUser = await generateUser({
|
const otherUser = await generateUser({
|
||||||
'profile.name': 'Other User',
|
'profile.name': 'Other User',
|
||||||
});
|
});
|
||||||
user = await generateUser({
|
user = await generateUser({
|
||||||
@@ -30,13 +30,13 @@ describe('GET /export/inbox.html', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an html page', async () => {
|
it('returns an html page', async () => {
|
||||||
let res = await user.get('/export/inbox.html');
|
const res = await user.get('/export/inbox.html');
|
||||||
|
|
||||||
expect(res.substring(0, 100).indexOf('<!DOCTYPE html>')).to.equal(0);
|
expect(res.substring(0, 100).indexOf('<!DOCTYPE html>')).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the markdown messages as html', async () => {
|
it('renders the markdown messages as html', async () => {
|
||||||
let res = await user.get('/export/inbox.html');
|
const res = await user.get('/export/inbox.html');
|
||||||
|
|
||||||
expect(res).to.include('img class="habitica-emoji"');
|
expect(res).to.include('img class="habitica-emoji"');
|
||||||
expect(res).to.include('<h1>Hello!</h1>');
|
expect(res).to.include('<h1>Hello!</h1>');
|
||||||
@@ -44,11 +44,11 @@ describe('GET /export/inbox.html', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sorts messages from newest to oldest', async () => {
|
it('sorts messages from newest to oldest', async () => {
|
||||||
let res = await user.get('/export/inbox.html');
|
const res = await user.get('/export/inbox.html');
|
||||||
|
|
||||||
let emojiPosition = res.indexOf('img class="habitica-emoji"');
|
const emojiPosition = res.indexOf('img class="habitica-emoji"');
|
||||||
let headingPosition = res.indexOf('<h1>Hello!</h1>');
|
const headingPosition = res.indexOf('<h1>Hello!</h1>');
|
||||||
let listPosition = res.indexOf('<li>list 1</li>');
|
const listPosition = res.indexOf('<li>list 1</li>');
|
||||||
|
|
||||||
expect(emojiPosition).to.be.greaterThan(headingPosition);
|
expect(emojiPosition).to.be.greaterThan(headingPosition);
|
||||||
expect(headingPosition).to.be.greaterThan(listPosition);
|
expect(headingPosition).to.be.greaterThan(listPosition);
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import {
|
|||||||
|
|
||||||
describe('GET /export/userdata.json', () => {
|
describe('GET /export/userdata.json', () => {
|
||||||
it('should return a valid JSON file with user data', async () => {
|
it('should return a valid JSON file with user data', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
let tasks = await user.post('/tasks/user', [
|
const tasks = await user.post('/tasks/user', [
|
||||||
{type: 'habit', text: 'habit 1'},
|
{ type: 'habit', text: 'habit 1' },
|
||||||
{type: 'daily', text: 'daily 1'},
|
{ type: 'daily', text: 'daily 1' },
|
||||||
{type: 'reward', text: 'reward 1'},
|
{ type: 'reward', text: 'reward 1' },
|
||||||
{type: 'todo', text: 'todo 1'},
|
{ type: 'todo', text: 'todo 1' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let res = await user.get('/export/userdata.json');
|
const res = await user.get('/export/userdata.json');
|
||||||
expect(res._id).to.equal(user._id);
|
expect(res._id).to.equal(user._id);
|
||||||
expect(res).to.contain.all.keys(['tasks', 'flags', 'tasksOrder', 'auth']);
|
expect(res).to.contain.all.keys(['tasks', 'flags', 'tasksOrder', 'auth']);
|
||||||
expect(res.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
expect(res.auth.local).not.to.have.keys(['salt', 'hashed_password']);
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
|
import xml2js from 'xml2js';
|
||||||
|
import util from 'util';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import xml2js from 'xml2js';
|
|
||||||
import util from 'util';
|
|
||||||
|
|
||||||
let parseStringAsync = util.promisify(xml2js.parseString).bind(xml2js);
|
const parseStringAsync = util.promisify(xml2js.parseString).bind(xml2js);
|
||||||
|
|
||||||
describe('GET /export/userdata.xml', () => {
|
describe('GET /export/userdata.xml', () => {
|
||||||
it('should return a valid XML file with user data', async () => {
|
it('should return a valid XML file with user data', async () => {
|
||||||
let user = await generateUser();
|
const user = await generateUser();
|
||||||
let tasks = await user.post('/tasks/user', [
|
const tasks = await user.post('/tasks/user', [
|
||||||
{type: 'habit', text: 'habit 1'},
|
{ type: 'habit', text: 'habit 1' },
|
||||||
{type: 'daily', text: 'daily 1'},
|
{ type: 'daily', text: 'daily 1' },
|
||||||
{type: 'reward', text: 'reward 1'},
|
{ type: 'reward', text: 'reward 1' },
|
||||||
{type: 'todo', text: 'todo 1'},
|
{ type: 'todo', text: 'todo 1' },
|
||||||
// due to how the xml parser works an array is returned only if there's more than one children
|
// due to how the xml parser works an array is returned only if there's more than one children
|
||||||
// so we create two tasks for each type
|
// so we create two tasks for each type
|
||||||
{type: 'habit', text: 'habit 2'},
|
{ type: 'habit', text: 'habit 2' },
|
||||||
{type: 'daily', text: 'daily 2'},
|
{ type: 'daily', text: 'daily 2' },
|
||||||
{type: 'reward', text: 'reward 2'},
|
{ type: 'reward', text: 'reward 2' },
|
||||||
{type: 'todo', text: 'todo 2'},
|
{ type: 'todo', text: 'todo 2' },
|
||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -27,15 +27,15 @@ describe('GET /export/userdata.xml', () => {
|
|||||||
await user.get('/user/toggle-pinned-item/marketGear/gear.flat.shield_rogue_5');
|
await user.get('/user/toggle-pinned-item/marketGear/gear.flat.shield_rogue_5');
|
||||||
|
|
||||||
// add a private message
|
// add a private message
|
||||||
let receiver = await generateUser();
|
const receiver = await generateUser();
|
||||||
|
|
||||||
user.post('/members/send-private-message', {
|
user.post('/members/send-private-message', {
|
||||||
message: 'Your first message, hi!',
|
message: 'Your first message, hi!',
|
||||||
toUserId: receiver._id,
|
toUserId: receiver._id,
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = await user.get('/export/userdata.xml');
|
const response = await user.get('/export/userdata.xml');
|
||||||
let {user: res} = await parseStringAsync(response, {explicitArray: false});
|
const { user: res } = await parseStringAsync(response, { explicitArray: false });
|
||||||
|
|
||||||
expect(res._id).to.equal(user._id);
|
expect(res._id).to.equal(user._id);
|
||||||
expect(res).to.contain.all.keys(['tasks', 'flags', 'tasksOrder', 'auth']);
|
expect(res).to.contain.all.keys(['tasks', 'flags', 'tasksOrder', 'auth']);
|
||||||
@@ -43,19 +43,19 @@ describe('GET /export/userdata.xml', () => {
|
|||||||
expect(res.tasks).to.have.all.keys(['dailys', 'habits', 'todos', 'rewards']);
|
expect(res.tasks).to.have.all.keys(['dailys', 'habits', 'todos', 'rewards']);
|
||||||
|
|
||||||
expect(res.tasks.habits.length).to.equal(2);
|
expect(res.tasks.habits.length).to.equal(2);
|
||||||
let habitIds = _.map(res.tasks.habits, '_id');
|
const habitIds = _.map(res.tasks.habits, '_id');
|
||||||
expect(habitIds).to.have.deep.members([tasks[0]._id, tasks[4]._id]);
|
expect(habitIds).to.have.deep.members([tasks[0]._id, tasks[4]._id]);
|
||||||
|
|
||||||
expect(res.tasks.dailys.length).to.equal(2);
|
expect(res.tasks.dailys.length).to.equal(2);
|
||||||
let dailyIds = _.map(res.tasks.dailys, '_id');
|
const dailyIds = _.map(res.tasks.dailys, '_id');
|
||||||
expect(dailyIds).to.have.deep.members([tasks[1]._id, tasks[5]._id]);
|
expect(dailyIds).to.have.deep.members([tasks[1]._id, tasks[5]._id]);
|
||||||
|
|
||||||
expect(res.tasks.rewards.length).to.equal(2);
|
expect(res.tasks.rewards.length).to.equal(2);
|
||||||
let rewardIds = _.map(res.tasks.rewards, '_id');
|
const rewardIds = _.map(res.tasks.rewards, '_id');
|
||||||
expect(rewardIds).to.have.deep.members([tasks[2]._id, tasks[6]._id]);
|
expect(rewardIds).to.have.deep.members([tasks[2]._id, tasks[6]._id]);
|
||||||
|
|
||||||
expect(res.tasks.todos.length).to.equal(3);
|
expect(res.tasks.todos.length).to.equal(3);
|
||||||
let todoIds = _.map(res.tasks.todos, '_id');
|
const todoIds = _.map(res.tasks.todos, '_id');
|
||||||
expect(todoIds).to.deep.include.members([tasks[3]._id, tasks[7]._id]);
|
expect(todoIds).to.deep.include.members([tasks[3]._id, tasks[7]._id]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('POST /debug/add-hourglass', () => {
|
|||||||
it('adds Hourglass to the current user', async () => {
|
it('adds Hourglass to the current user', async () => {
|
||||||
await userToGetHourGlass.post('/debug/add-hourglass');
|
await userToGetHourGlass.post('/debug/add-hourglass');
|
||||||
|
|
||||||
let userWithHourGlass = await userToGetHourGlass.get('/user');
|
const userWithHourGlass = await userToGetHourGlass.get('/user');
|
||||||
|
|
||||||
expect(userWithHourGlass.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(userWithHourGlass.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('POST /debug/add-ten-gems', () => {
|
|||||||
it('adds ten gems to the current user', async () => {
|
it('adds ten gems to the current user', async () => {
|
||||||
await userToGainTenGems.post('/debug/add-ten-gems');
|
await userToGainTenGems.post('/debug/add-ten-gems');
|
||||||
|
|
||||||
let userWithTenGems = await userToGainTenGems.get('/user');
|
const userWithTenGems = await userToGainTenGems.get('/user');
|
||||||
|
|
||||||
expect(userWithTenGems.balance).to.equal(2.5);
|
expect(userWithTenGems.balance).to.equal(2.5);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import {
|
|||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /debug/modify-inventory', () => {
|
describe('POST /debug/modify-inventory', () => {
|
||||||
let user, originalItems;
|
let user; let
|
||||||
|
originalItems;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
originalItems = {
|
originalItems = {
|
||||||
@@ -43,7 +44,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets equipment', async () => {
|
it('sets equipment', async () => {
|
||||||
let gear = {
|
const gear = {
|
||||||
weapon_healer_2: true,
|
weapon_healer_2: true,
|
||||||
weapon_wizard_1: true,
|
weapon_wizard_1: true,
|
||||||
weapon_special_critical: true,
|
weapon_special_critical: true,
|
||||||
@@ -59,7 +60,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets special spells', async () => {
|
it('sets special spells', async () => {
|
||||||
let special = {
|
const special = {
|
||||||
shinySeed: 3,
|
shinySeed: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets mounts', async () => {
|
it('sets mounts', async () => {
|
||||||
let mounts = {
|
const mounts = {
|
||||||
'Orca-Base': true,
|
'Orca-Base': true,
|
||||||
'Mammoth-Base': true,
|
'Mammoth-Base': true,
|
||||||
};
|
};
|
||||||
@@ -88,7 +89,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets eggs', async () => {
|
it('sets eggs', async () => {
|
||||||
let eggs = {
|
const eggs = {
|
||||||
Gryphon: 3,
|
Gryphon: 3,
|
||||||
Hedgehog: 7,
|
Hedgehog: 7,
|
||||||
};
|
};
|
||||||
@@ -103,7 +104,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets hatching potions', async () => {
|
it('sets hatching potions', async () => {
|
||||||
let hatchingPotions = {
|
const hatchingPotions = {
|
||||||
White: 7,
|
White: 7,
|
||||||
Spooky: 2,
|
Spooky: 2,
|
||||||
};
|
};
|
||||||
@@ -118,7 +119,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets food', async () => {
|
it('sets food', async () => {
|
||||||
let food = {
|
const food = {
|
||||||
Meat: 5,
|
Meat: 5,
|
||||||
Candy_Red: 7,
|
Candy_Red: 7,
|
||||||
};
|
};
|
||||||
@@ -133,7 +134,7 @@ describe('POST /debug/modify-inventory', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets quests', async () => {
|
it('sets quests', async () => {
|
||||||
let quests = {
|
const quests = {
|
||||||
whale: 5,
|
whale: 5,
|
||||||
cheetah: 10,
|
cheetah: 10,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('POST /debug/set-cron', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets last cron', async () => {
|
it('sets last cron', async () => {
|
||||||
let newCron = new Date(2015, 11, 20);
|
const newCron = new Date(2015, 11, 20);
|
||||||
|
|
||||||
await user.post('/debug/set-cron', {
|
await user.post('/debug/set-cron', {
|
||||||
lastCron: newCron,
|
lastCron: newCron,
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { encrypt } from '../../../../../website/server/libs/encryption';
|
import { encrypt } from '../../../../../website/server/libs/encryption';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /email/unsubscribe', () => {
|
describe('GET /email/unsubscribe', () => {
|
||||||
let user;
|
let user;
|
||||||
let testEmail = 'test@habitica.com';
|
const testEmail = 'test@habitica.com';
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = await generateUser();
|
user = await generateUser();
|
||||||
@@ -22,7 +22,7 @@ describe('GET /email/unsubscribe', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('return error when user is not found', async () => {
|
it('return error when user is not found', async () => {
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
_id: generateUUID(),
|
_id: generateUUID(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -34,34 +34,34 @@ describe('GET /email/unsubscribe', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('unsubscribes a user from email notifications', async () => {
|
it('unsubscribes a user from email notifications', async () => {
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.get(`/email/unsubscribe?code=${code}`);
|
await user.get(`/email/unsubscribe?code=${code}`);
|
||||||
|
|
||||||
let unsubscribedUser = await user.get('/user');
|
const unsubscribedUser = await user.get('/user');
|
||||||
|
|
||||||
expect(unsubscribedUser.preferences.emailNotifications.unsubscribeFromAll).to.be.true;
|
expect(unsubscribedUser.preferences.emailNotifications.unsubscribeFromAll).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unsubscribes an email from notifications', async () => {
|
it('unsubscribes an email from notifications', async () => {
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
email: testEmail,
|
email: testEmail,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let unsubscribedMessage = await user.get(`/email/unsubscribe?code=${code}`);
|
const unsubscribedMessage = await user.get(`/email/unsubscribe?code=${code}`);
|
||||||
|
|
||||||
expect(unsubscribedMessage).to.equal('<h1>Unsubscribed successfully!</h1> You won\'t receive any other email from Habitica.');
|
expect(unsubscribedMessage).to.equal('<h1>Unsubscribed successfully!</h1> You won\'t receive any other email from Habitica.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns okay when email is already unsubscribed', async () => {
|
it('returns okay when email is already unsubscribed', async () => {
|
||||||
let code = encrypt(JSON.stringify({
|
const code = encrypt(JSON.stringify({
|
||||||
email: testEmail,
|
email: testEmail,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let unsubscribedMessage = await user.get(`/email/unsubscribe?code=${code}`);
|
const unsubscribedMessage = await user.get(`/email/unsubscribe?code=${code}`);
|
||||||
|
|
||||||
expect(unsubscribedMessage).to.equal('<h1>Unsubscribed successfully!</h1> You won\'t receive any other email from Habitica.');
|
expect(unsubscribedMessage).to.equal('<h1>Unsubscribed successfully!</h1> You won\'t receive any other email from Habitica.');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ describe('GET /group-plans', () => {
|
|||||||
let groupPlan;
|
let groupPlan;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
user = await generateUser({balance: 4});
|
user = await generateUser({ balance: 4 });
|
||||||
groupPlan = await generateGroup(user,
|
groupPlan = await generateGroup(user,
|
||||||
{
|
{
|
||||||
name: 'public guild - is member',
|
name: 'public guild - is member',
|
||||||
@@ -25,7 +25,7 @@ describe('GET /group-plans', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns group plans for the user', async () => {
|
it('returns group plans for the user', async () => {
|
||||||
let groupPlans = await user.get('/group-plans');
|
const groupPlans = await user.get('/group-plans');
|
||||||
|
|
||||||
expect(groupPlans[0]._id).to.eql(groupPlan._id);
|
expect(groupPlans[0]._id).to.eql(groupPlan._id);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('GET /groups', () => {
|
|||||||
const NUMBER_OF_USERS_PRIVATE_GUILDS = 1;
|
const NUMBER_OF_USERS_PRIVATE_GUILDS = 1;
|
||||||
const NUMBER_OF_GROUPS_USER_CAN_VIEW = 5;
|
const NUMBER_OF_GROUPS_USER_CAN_VIEW = 5;
|
||||||
const GUILD_PER_PAGE = 30;
|
const GUILD_PER_PAGE = 30;
|
||||||
let categories = [{
|
const categories = [{
|
||||||
slug: 'newCat',
|
slug: 'newCat',
|
||||||
name: 'New Category',
|
name: 'New Category',
|
||||||
}];
|
}];
|
||||||
@@ -26,15 +26,15 @@ describe('GET /groups', () => {
|
|||||||
before(async () => {
|
before(async () => {
|
||||||
await resetHabiticaDB();
|
await resetHabiticaDB();
|
||||||
|
|
||||||
let leader = await generateUser({ balance: 10 });
|
const leader = await generateUser({ balance: 10 });
|
||||||
user = await generateUser({balance: 4});
|
user = await generateUser({ balance: 4 });
|
||||||
|
|
||||||
let publicGuildUserIsMemberOf = await generateGroup(leader, {
|
const publicGuildUserIsMemberOf = await generateGroup(leader, {
|
||||||
name: 'public guild - is member',
|
name: 'public guild - is member',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
});
|
});
|
||||||
await leader.post(`/groups/${publicGuildUserIsMemberOf._id}/invite`, { uuids: [user._id]});
|
await leader.post(`/groups/${publicGuildUserIsMemberOf._id}/invite`, { uuids: [user._id] });
|
||||||
await user.post(`/groups/${publicGuildUserIsMemberOf._id}/join`);
|
await user.post(`/groups/${publicGuildUserIsMemberOf._id}/join`);
|
||||||
|
|
||||||
publicGuildNotMember = await generateGroup(leader, {
|
publicGuildNotMember = await generateGroup(leader, {
|
||||||
@@ -50,7 +50,7 @@ describe('GET /groups', () => {
|
|||||||
privacy: 'private',
|
privacy: 'private',
|
||||||
categories,
|
categories,
|
||||||
});
|
});
|
||||||
await leader.post(`/groups/${privateGuildUserIsMemberOf._id}/invite`, { uuids: [user._id]});
|
await leader.post(`/groups/${privateGuildUserIsMemberOf._id}/invite`, { uuids: [user._id] });
|
||||||
await user.post(`/groups/${privateGuildUserIsMemberOf._id}/join`);
|
await user.post(`/groups/${privateGuildUserIsMemberOf._id}/join`);
|
||||||
|
|
||||||
await generateGroup(leader, {
|
await generateGroup(leader, {
|
||||||
@@ -110,13 +110,13 @@ describe('GET /groups', () => {
|
|||||||
|
|
||||||
describe('filters', () => {
|
describe('filters', () => {
|
||||||
it('returns public guilds filtered by category', async () => {
|
it('returns public guilds filtered by category', async () => {
|
||||||
let guilds = await user.get(`/groups?type=publicGuilds&categories=${categories[0].slug}`);
|
const guilds = await user.get(`/groups?type=publicGuilds&categories=${categories[0].slug}`);
|
||||||
|
|
||||||
expect(guilds[0]._id).to.equal(publicGuildNotMember._id);
|
expect(guilds[0]._id).to.equal(publicGuildNotMember._id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns private guilds filtered by category', async () => {
|
it('returns private guilds filtered by category', async () => {
|
||||||
let guilds = await user.get(`/groups?type=privateGuilds&categories=${categories[0].slug}`);
|
const guilds = await user.get(`/groups?type=privateGuilds&categories=${categories[0].slug}`);
|
||||||
|
|
||||||
expect(guilds[0]._id).to.equal(privateGuildUserIsMemberOf._id);
|
expect(guilds[0]._id).to.equal(privateGuildUserIsMemberOf._id);
|
||||||
});
|
});
|
||||||
@@ -131,7 +131,7 @@ describe('GET /groups', () => {
|
|||||||
|
|
||||||
// @TODO: anyway to set higher memberCount in tests right now?
|
// @TODO: anyway to set higher memberCount in tests right now?
|
||||||
|
|
||||||
let guilds = await user.get('/groups?type=publicGuilds&minMemberCount=3');
|
const guilds = await user.get('/groups?type=publicGuilds&minMemberCount=3');
|
||||||
|
|
||||||
expect(guilds.length).to.equal(0);
|
expect(guilds.length).to.equal(0);
|
||||||
});
|
});
|
||||||
@@ -146,7 +146,7 @@ describe('GET /groups', () => {
|
|||||||
|
|
||||||
// @TODO: anyway to set higher memberCount in tests right now?
|
// @TODO: anyway to set higher memberCount in tests right now?
|
||||||
|
|
||||||
let guilds = await user.get('/groups?type=privateGuilds&minMemberCount=3');
|
const guilds = await user.get('/groups?type=privateGuilds&minMemberCount=3');
|
||||||
|
|
||||||
expect(guilds.length).to.equal(0);
|
expect(guilds.length).to.equal(0);
|
||||||
});
|
});
|
||||||
@@ -181,26 +181,24 @@ describe('GET /groups', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 30 guilds per page ordered by number of members', async () => {
|
it('returns 30 guilds per page ordered by number of members', async () => {
|
||||||
await user.update({balance: 9000});
|
await user.update({ balance: 9000 });
|
||||||
let groups = await Promise.all(_.times(60, (i) => {
|
const groups = await Promise.all(_.times(60, i => generateGroup(user, {
|
||||||
return generateGroup(user, {
|
name: `public guild ${i} - is member`,
|
||||||
name: `public guild ${i} - is member`,
|
type: 'guild',
|
||||||
type: 'guild',
|
privacy: 'public',
|
||||||
privacy: 'public',
|
})));
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
// update group number 32 and not the first to make sure sorting works
|
// update group number 32 and not the first to make sure sorting works
|
||||||
await groups[32].update({name: 'guild with most members', memberCount: 199});
|
await groups[32].update({ name: 'guild with most members', memberCount: 199 });
|
||||||
await groups[33].update({name: 'guild with less members', memberCount: -100});
|
await groups[33].update({ name: 'guild with less members', memberCount: -100 });
|
||||||
|
|
||||||
let page0 = await expect(user.get('/groups?type=publicGuilds&paginate=true'))
|
const page0 = await expect(user.get('/groups?type=publicGuilds&paginate=true'))
|
||||||
.to.eventually.have.a.lengthOf(GUILD_PER_PAGE);
|
.to.eventually.have.a.lengthOf(GUILD_PER_PAGE);
|
||||||
expect(page0[0].name).to.equal('guild with most members');
|
expect(page0[0].name).to.equal('guild with most members');
|
||||||
|
|
||||||
await expect(user.get('/groups?type=publicGuilds&paginate=true&page=1'))
|
await expect(user.get('/groups?type=publicGuilds&paginate=true&page=1'))
|
||||||
.to.eventually.have.a.lengthOf(GUILD_PER_PAGE);
|
.to.eventually.have.a.lengthOf(GUILD_PER_PAGE);
|
||||||
let page2 = await expect(user.get('/groups?type=publicGuilds&paginate=true&page=2'))
|
const page2 = await expect(user.get('/groups?type=publicGuilds&paginate=true&page=2'))
|
||||||
.to.eventually.have.a.lengthOf(1 + 4); // 1 created now, 4 by other tests
|
.to.eventually.have.a.lengthOf(1 + 4); // 1 created now, 4 by other tests
|
||||||
expect(page2[4].name).to.equal('guild with less members');
|
expect(page2[4].name).to.equal('guild with less members');
|
||||||
}).timeout(10000);
|
}).timeout(10000);
|
||||||
@@ -208,7 +206,8 @@ describe('GET /groups', () => {
|
|||||||
|
|
||||||
it('returns all the user\'s guilds when guilds passed in as query', async () => {
|
it('returns all the user\'s guilds when guilds passed in as query', async () => {
|
||||||
await expect(user.get('/groups?type=guilds'))
|
await expect(user.get('/groups?type=guilds'))
|
||||||
.to.eventually.have.a.lengthOf(NUMBER_OF_PUBLIC_GUILDS_USER_IS_MEMBER + NUMBER_OF_USERS_PRIVATE_GUILDS);
|
.to.eventually.have.a
|
||||||
|
.lengthOf(NUMBER_OF_PUBLIC_GUILDS_USER_IS_MEMBER + NUMBER_OF_USERS_PRIVATE_GUILDS);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns all private guilds user is a part of when privateGuilds passed in as query', async () => {
|
it('returns all private guilds user is a part of when privateGuilds passed in as query', async () => {
|
||||||
@@ -222,7 +221,7 @@ describe('GET /groups', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns a list of groups user has access to', async () => {
|
it('returns a list of groups user has access to', async () => {
|
||||||
let group = await generateGroup(user, {
|
const group = await generateGroup(user, {
|
||||||
name: 'c++ coders',
|
name: 'c++ coders',
|
||||||
type: 'guild',
|
type: 'guild',
|
||||||
privacy: 'public',
|
privacy: 'public',
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
|
|
||||||
describe('GET /groups/:groupId/invites', () => {
|
describe('GET /groups/:groupId/invites', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -29,8 +29,8 @@ describe('GET /groups/:groupId/invites', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user doesn\'t have access to the group', async () => {
|
it('fails if user doesn\'t have access to the group', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let anotherUser = await generateUser();
|
const anotherUser = await generateUser();
|
||||||
await expect(anotherUser.get(`/groups/${group._id}/invites`)).to.eventually.be.rejected.and.eql({
|
await expect(anotherUser.get(`/groups/${group._id}/invites`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -39,17 +39,17 @@ describe('GET /groups/:groupId/invites', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works when passing party as req.params.groupId', async () => {
|
it('works when passing party as req.params.groupId', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let invited = await generateUser();
|
const invited = await generateUser();
|
||||||
await user.post(`/groups/${group._id}/invite`, {uuids: [invited._id]});
|
await user.post(`/groups/${group._id}/invite`, { uuids: [invited._id] });
|
||||||
let res = await user.get('/groups/party/invites');
|
const res = await user.get('/groups/party/invites');
|
||||||
|
|
||||||
expect(res).to.be.an('array');
|
expect(res).to.be.an('array');
|
||||||
expect(res.length).to.equal(1);
|
expect(res.length).to.equal(1);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: invited._id,
|
_id: invited._id,
|
||||||
id: invited._id,
|
id: invited._id,
|
||||||
profile: {name: invited.profile.name},
|
profile: { name: invited.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: invited.auth.local.username,
|
username: invited.auth.local.username,
|
||||||
@@ -62,26 +62,26 @@ describe('GET /groups/:groupId/invites', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('populates only some fields', async () => {
|
it('populates only some fields', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let invited = await generateUser();
|
const invited = await generateUser();
|
||||||
await user.post(`/groups/${group._id}/invite`, {uuids: [invited._id]});
|
await user.post(`/groups/${group._id}/invite`, { uuids: [invited._id] });
|
||||||
let res = await user.get('/groups/party/invites');
|
const res = await user.get('/groups/party/invites');
|
||||||
expect(res[0]).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(res[0]).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
expect(res[0].profile).to.have.all.keys(['name']);
|
expect(res[0].profile).to.have.all.keys(['name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns only first 30 invites', async () => {
|
it('returns only first 30 invites', async () => {
|
||||||
let leader = await generateUser({balance: 4});
|
const leader = await generateUser({ balance: 4 });
|
||||||
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(leader, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
|
|
||||||
let invitesToGenerate = [];
|
const invitesToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
invitesToGenerate.push(generateUser());
|
invitesToGenerate.push(generateUser());
|
||||||
}
|
}
|
||||||
let generatedInvites = await Promise.all(invitesToGenerate);
|
const generatedInvites = await Promise.all(invitesToGenerate);
|
||||||
await leader.post(`/groups/${group._id}/invite`, {uuids: generatedInvites.map(invite => invite._id)});
|
await leader.post(`/groups/${group._id}/invite`, { uuids: generatedInvites.map(invite => invite._id) });
|
||||||
|
|
||||||
let res = await leader.get(`/groups/${group._id}/invites`);
|
const res = await leader.get(`/groups/${group._id}/invites`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -89,25 +89,25 @@ describe('GET /groups/:groupId/invites', () => {
|
|||||||
});
|
});
|
||||||
}).timeout(10000);
|
}).timeout(10000);
|
||||||
|
|
||||||
it('supports using req.query.lastId to get more invites', async function () {
|
it('supports using req.query.lastId to get more invites', async function test () {
|
||||||
this.timeout(30000); // @TODO: times out after 8 seconds
|
this.timeout(30000); // @TODO: times out after 8 seconds
|
||||||
let leader = await generateUser({balance: 4});
|
const leader = await generateUser({ balance: 4 });
|
||||||
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(leader, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
|
|
||||||
let invitesToGenerate = [];
|
const invitesToGenerate = [];
|
||||||
for (let i = 0; i < 32; i++) {
|
for (let i = 0; i < 32; i += 1) {
|
||||||
invitesToGenerate.push(generateUser());
|
invitesToGenerate.push(generateUser());
|
||||||
}
|
}
|
||||||
let generatedInvites = await Promise.all(invitesToGenerate); // Group has 32 invites
|
const generatedInvites = await Promise.all(invitesToGenerate); // Group has 32 invites
|
||||||
let expectedIds = generatedInvites.map(generatedInvite => generatedInvite._id);
|
const expectedIds = generatedInvites.map(generatedInvite => generatedInvite._id);
|
||||||
await user.post(`/groups/${group._id}/invite`, {uuids: expectedIds});
|
await user.post(`/groups/${group._id}/invite`, { uuids: expectedIds });
|
||||||
|
|
||||||
let res = await user.get(`/groups/${group._id}/invites`);
|
const res = await user.get(`/groups/${group._id}/invites`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
let res2 = await user.get(`/groups/${group._id}/invites?lastId=${res[res.length - 1]._id}`);
|
const res2 = await user.get(`/groups/${group._id}/invites?lastId=${res[res.length - 1]._id}`);
|
||||||
expect(res2.length).to.equal(2);
|
expect(res2.length).to.equal(2);
|
||||||
|
|
||||||
let resIds = res.concat(res2).map(invite => invite._id);
|
const resIds = res.concat(res2).map(invite => invite._id);
|
||||||
expect(resIds).to.eql(expectedIds.sort());
|
expect(resIds).to.eql(expectedIds.sort());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
|
||||||
import common from '../../../../../website/common';
|
import common from '../../../../../website/common';
|
||||||
|
|
||||||
describe('GET /groups/:groupId/members', () => {
|
describe('GET /groups/:groupId/members', () => {
|
||||||
@@ -12,8 +12,8 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = await generateUser({
|
user = await generateUser({
|
||||||
balance: 10,
|
balance: 10,
|
||||||
contributor: {level: 1},
|
contributor: { level: 1 },
|
||||||
backer: {tier: 3},
|
backer: { tier: 3 },
|
||||||
preferences: {
|
preferences: {
|
||||||
costume: false,
|
costume: false,
|
||||||
background: 'volcano',
|
background: 'volcano',
|
||||||
@@ -38,8 +38,8 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user doesn\'t have access to the group', async () => {
|
it('fails if user doesn\'t have access to the group', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let anotherUser = await generateUser();
|
const anotherUser = await generateUser();
|
||||||
await expect(anotherUser.get(`/groups/${group._id}/members`)).to.eventually.be.rejected.and.eql({
|
await expect(anotherUser.get(`/groups/${group._id}/members`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 404,
|
code: 404,
|
||||||
error: 'NotFound',
|
error: 'NotFound',
|
||||||
@@ -48,14 +48,14 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works when passing party as req.params.groupId', async () => {
|
it('works when passing party as req.params.groupId', async () => {
|
||||||
await generateGroup(user, {type: 'party', name: generateUUID()});
|
await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let res = await user.get('/groups/party/members');
|
const res = await user.get('/groups/party/members');
|
||||||
expect(res).to.be.an('array');
|
expect(res).to.be.an('array');
|
||||||
expect(res.length).to.equal(1);
|
expect(res.length).to.equal(1);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
id: user._id,
|
id: user._id,
|
||||||
profile: {name: user.profile.name},
|
profile: { name: user.profile.name },
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
username: user.auth.local.username,
|
username: user.auth.local.username,
|
||||||
@@ -68,15 +68,15 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('populates only some fields', async () => {
|
it('populates only some fields', async () => {
|
||||||
await generateGroup(user, {type: 'party', name: generateUUID()});
|
await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let res = await user.get('/groups/party/members');
|
const res = await user.get('/groups/party/members');
|
||||||
expect(res[0]).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(res[0]).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
expect(res[0].profile).to.have.all.keys(['name']);
|
expect(res[0].profile).to.have.all.keys(['name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('req.query.includeAllPublicFields === true works with guilds', async () => {
|
it('req.query.includeAllPublicFields === true works with guilds', async () => {
|
||||||
let group = await generateGroup(user, {type: 'guild', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'guild', name: generateUUID() });
|
||||||
let [memberRes] = await user.get(`/groups/${group._id}/members?includeAllPublicFields=true`);
|
const [memberRes] = await user.get(`/groups/${group._id}/members?includeAllPublicFields=true`);
|
||||||
|
|
||||||
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
|
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||||
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
|
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
|
||||||
@@ -96,8 +96,8 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('populates all public fields if req.query.includeAllPublicFields === true and it is a party', async () => {
|
it('populates all public fields if req.query.includeAllPublicFields === true and it is a party', async () => {
|
||||||
await generateGroup(user, {type: 'party', name: generateUUID()});
|
await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
let [memberRes] = await user.get('/groups/party/members?includeAllPublicFields=true');
|
const [memberRes] = await user.get('/groups/party/members?includeAllPublicFields=true');
|
||||||
|
|
||||||
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
|
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
|
||||||
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
|
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
|
||||||
@@ -117,15 +117,15 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns only first 30 members', async () => {
|
it('returns only first 30 members', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
usersToGenerate.push(generateUser({party: {_id: group._id}}));
|
usersToGenerate.push(generateUser({ party: { _id: group._id } }));
|
||||||
}
|
}
|
||||||
await Promise.all(usersToGenerate);
|
await Promise.all(usersToGenerate);
|
||||||
|
|
||||||
let res = await user.get('/groups/party/members');
|
const res = await user.get('/groups/party/members');
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -134,15 +134,15 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns only first 30 members even when ?includeAllMembers=true', async () => {
|
it('returns only first 30 members even when ?includeAllMembers=true', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i += 1) {
|
||||||
usersToGenerate.push(generateUser({party: {_id: group._id}}));
|
usersToGenerate.push(generateUser({ party: { _id: group._id } }));
|
||||||
}
|
}
|
||||||
await Promise.all(usersToGenerate);
|
await Promise.all(usersToGenerate);
|
||||||
|
|
||||||
let res = await user.get('/groups/party/members?includeAllMembers=true');
|
const res = await user.get('/groups/party/members?includeAllMembers=true');
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
res.forEach(member => {
|
res.forEach(member => {
|
||||||
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
expect(member).to.have.all.keys(['_id', 'auth', 'flags', 'id', 'profile']);
|
||||||
@@ -150,38 +150,39 @@ describe('GET /groups/:groupId/members', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports using req.query.lastId to get more members', async function () {
|
it('supports using req.query.lastId to get more members', async function test () {
|
||||||
this.timeout(30000); // @TODO: times out after 8 seconds
|
this.timeout(30000); // @TODO: times out after 8 seconds
|
||||||
let leader = await generateUser({balance: 4});
|
const leader = await generateUser({ balance: 4 });
|
||||||
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
const group = await generateGroup(leader, { type: 'guild', privacy: 'public', name: generateUUID() });
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 57; i++) {
|
for (let i = 0; i < 57; i += 1) {
|
||||||
usersToGenerate.push(generateUser({guilds: [group._id]}));
|
usersToGenerate.push(generateUser({ guilds: [group._id] }));
|
||||||
}
|
}
|
||||||
let generatedUsers = await Promise.all(usersToGenerate); // Group has 59 members (1 is the leader)
|
// Group has 59 members (1 is the leader)
|
||||||
let expectedIds = [leader._id].concat(generatedUsers.map(generatedUser => generatedUser._id));
|
const generatedUsers = await Promise.all(usersToGenerate);
|
||||||
|
const expectedIds = [leader._id].concat(generatedUsers.map(generatedUser => generatedUser._id));
|
||||||
|
|
||||||
let res = await user.get(`/groups/${group._id}/members`);
|
const res = await user.get(`/groups/${group._id}/members`);
|
||||||
expect(res.length).to.equal(30);
|
expect(res.length).to.equal(30);
|
||||||
let res2 = await user.get(`/groups/${group._id}/members?lastId=${res[res.length - 1]._id}`);
|
const res2 = await user.get(`/groups/${group._id}/members?lastId=${res[res.length - 1]._id}`);
|
||||||
expect(res2.length).to.equal(28);
|
expect(res2.length).to.equal(28);
|
||||||
|
|
||||||
let resIds = res.concat(res2).map(member => member._id);
|
const resIds = res.concat(res2).map(member => member._id);
|
||||||
expect(resIds).to.eql(expectedIds.sort());
|
expect(resIds).to.eql(expectedIds.sort());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('searches members', async () => {
|
it('searches members', async () => {
|
||||||
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
const group = await generateGroup(user, { type: 'party', name: generateUUID() });
|
||||||
|
|
||||||
let usersToGenerate = [];
|
const usersToGenerate = [];
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i += 1) {
|
||||||
usersToGenerate.push(generateUser({party: {_id: group._id}}));
|
usersToGenerate.push(generateUser({ party: { _id: group._id } }));
|
||||||
}
|
}
|
||||||
const usersCreated = await Promise.all(usersToGenerate);
|
const usersCreated = await Promise.all(usersToGenerate);
|
||||||
const userToSearch = usersCreated[0].profile.name;
|
const userToSearch = usersCreated[0].profile.name;
|
||||||
|
|
||||||
let res = await user.get(`/groups/party/members?search=${userToSearch}`);
|
const res = await user.get(`/groups/party/members?search=${userToSearch}`);
|
||||||
expect(res.length).to.equal(1);
|
expect(res.length).to.equal(1);
|
||||||
expect(res[0].profile.name).to.equal(userToSearch);
|
expect(res[0].profile.name).to.equal(userToSearch);
|
||||||
});
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user