mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 13:47:33 +01:00
Merge branch 'develop' into party-chat-translations
# Conflicts: # test/api/unit/models/group.test.js
This commit is contained in:
@@ -20,8 +20,9 @@ env:
|
|||||||
- DISABLE_REQUEST_LOGGING=true
|
- DISABLE_REQUEST_LOGGING=true
|
||||||
matrix:
|
matrix:
|
||||||
- TEST="lint"
|
- TEST="lint"
|
||||||
- TEST="test:api-v3:unit" REQUIRES_SERVER=true COVERAGE=true
|
- TEST="test:api:unit" REQUIRES_SERVER=true COVERAGE=true
|
||||||
- TEST="test:api-v3:integration" REQUIRES_SERVER=true COVERAGE=true
|
- TEST="test:api-v3:integration" REQUIRES_SERVER=true COVERAGE=true
|
||||||
|
- TEST="test:api-v4:integration" REQUIRES_SERVER=true COVERAGE=true
|
||||||
- TEST="test:sanity"
|
- TEST="test:sanity"
|
||||||
- TEST="test:content" COVERAGE=true
|
- TEST="test:content" COVERAGE=true
|
||||||
- TEST="test:common" COVERAGE=true
|
- TEST="test:common" COVERAGE=true
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ RUN npm install -g gulp-cli mocha
|
|||||||
# Clone Habitica repo and install dependencies
|
# Clone Habitica repo and install dependencies
|
||||||
RUN mkdir -p /usr/src/habitrpg
|
RUN mkdir -p /usr/src/habitrpg
|
||||||
WORKDIR /usr/src/habitrpg
|
WORKDIR /usr/src/habitrpg
|
||||||
RUN git clone --branch v4.42.4 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
RUN git clone --branch v4.46.2 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||||
RUN npm install
|
RUN npm install
|
||||||
RUN gulp build:prod --force
|
RUN gulp build:prod --force
|
||||||
|
|
||||||
|
|||||||
@@ -112,5 +112,6 @@
|
|||||||
"CLOUDKARAFKA_USERNAME": "",
|
"CLOUDKARAFKA_USERNAME": "",
|
||||||
"CLOUDKARAFKA_PASSWORD": "",
|
"CLOUDKARAFKA_PASSWORD": "",
|
||||||
"CLOUDKARAFKA_TOPIC_PREFIX": ""
|
"CLOUDKARAFKA_TOPIC_PREFIX": ""
|
||||||
}
|
},
|
||||||
|
"MIGRATION_CONNECT_STRING": "mongodb://localhost:27017/habitrpg?auto_reconnect=true"
|
||||||
}
|
}
|
||||||
|
|||||||
100
database_reports/20180607_subscriber_histories.js
Normal file
100
database_reports/20180607_subscriber_histories.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import max from 'lodash/max';
|
||||||
|
import mean from 'lodash/mean';
|
||||||
|
import monk from 'monk';
|
||||||
|
import round from 'lodash/round';
|
||||||
|
import sum from 'lodash/sum';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Output data on subscribers' task histories, formatted for CSV.
|
||||||
|
* User ID,Count of Dailies,Count of Habits,Total History Size,Max History Size,Mean History Size,Median History Size
|
||||||
|
*/
|
||||||
|
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||||
|
|
||||||
|
let dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||||
|
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||||
|
|
||||||
|
function usersReport () {
|
||||||
|
let allHistoryLengths = [];
|
||||||
|
|
||||||
|
console.info('User ID,Count of Dailies,Count of Habits,Total History Size,Max History Size,Mean History Size,Median History Size');
|
||||||
|
|
||||||
|
dbUsers.find(
|
||||||
|
{
|
||||||
|
$and:
|
||||||
|
[
|
||||||
|
{'purchased.plan.planId': {$ne:null}},
|
||||||
|
{'purchased.plan.planId': {$ne:''}},
|
||||||
|
],
|
||||||
|
$or:
|
||||||
|
[
|
||||||
|
{'purchased.plan.dateTerminated': null},
|
||||||
|
{'purchased.plan.dateTerminated': ''},
|
||||||
|
{'purchased.plan.dateTerminated': {$gt:new Date()}},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: {_id: 1},
|
||||||
|
}
|
||||||
|
).each((user, {close, pause, resume}) => {
|
||||||
|
let historyLengths = [];
|
||||||
|
let habitCount = 0;
|
||||||
|
let dailyCount = 0;
|
||||||
|
|
||||||
|
pause();
|
||||||
|
return dbTasks.find(
|
||||||
|
{
|
||||||
|
userId: user._id,
|
||||||
|
$or:
|
||||||
|
[
|
||||||
|
{type: 'habit'},
|
||||||
|
{type: 'daily'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: {
|
||||||
|
type: 1,
|
||||||
|
history: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
).each((task) => {
|
||||||
|
if (task.type === 'habit') {
|
||||||
|
habitCount++;
|
||||||
|
}
|
||||||
|
if (task.type === 'daily') {
|
||||||
|
dailyCount++;
|
||||||
|
}
|
||||||
|
if (task.history.length > 0) {
|
||||||
|
allHistoryLengths.push(task.history.length);
|
||||||
|
historyLengths.push(task.history.length);
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
const totalHistory = sum(historyLengths);
|
||||||
|
const maxHistory = historyLengths.length > 0 ? max(historyLengths) : 0;
|
||||||
|
const meanHistory = historyLengths.length > 0 ? round(mean(historyLengths)) : 0;
|
||||||
|
const medianHistory = historyLengths.length > 0 ? median(historyLengths) : 0;
|
||||||
|
console.info(`${user._id},${dailyCount},${habitCount},${totalHistory},${maxHistory},${meanHistory},${medianHistory}`);
|
||||||
|
resume();
|
||||||
|
});
|
||||||
|
}).then(() => {
|
||||||
|
console.info(`Total Subscriber History Entries: ${sum(allHistoryLengths)}`);
|
||||||
|
console.info(`Largest History Size: ${max(allHistoryLengths)}`);
|
||||||
|
console.info(`Mean History Size: ${round(mean(allHistoryLengths))}`);
|
||||||
|
console.info(`Median History Size: ${median(allHistoryLengths)}`);
|
||||||
|
return process.exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function median(values) { // https://gist.github.com/caseyjustus/1166258
|
||||||
|
values.sort( function(a,b) {return a - b;} );
|
||||||
|
|
||||||
|
var half = Math.floor(values.length/2);
|
||||||
|
|
||||||
|
if (values.length % 2) {
|
||||||
|
return values[half];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (values[half-1] + values[half]) / 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = usersReport;
|
||||||
@@ -165,9 +165,9 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
|
|||||||
pipe(runner);
|
pipe(runner);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
gulp.task('test:api-v3:unit', (done) => {
|
gulp.task('test:api:unit', (done) => {
|
||||||
let runner = exec(
|
let runner = exec(
|
||||||
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-unit node_modules/mocha/bin/_mocha -- test/api/v3/unit --recursive --require ./test/helpers/start-server'),
|
testBin('node_modules/.bin/istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@@ -179,8 +179,8 @@ gulp.task('test:api-v3:unit', (done) => {
|
|||||||
pipe(runner);
|
pipe(runner);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test:api-v3:unit:watch', () => {
|
gulp.task('test:api:unit:watch', () => {
|
||||||
return gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api-v3:unit', done => done()));
|
return gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done()));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test:api-v3:integration', (done) => {
|
gulp.task('test:api-v3:integration', (done) => {
|
||||||
@@ -215,17 +215,43 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
|
|||||||
pipe(runner);
|
pipe(runner);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('test:api-v4:integration', (done) => {
|
||||||
|
let runner = exec(
|
||||||
|
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
|
||||||
|
{maxBuffer: 500 * 1024},
|
||||||
|
(err) => {
|
||||||
|
if (err) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
pipe(runner);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('test:api-v4:integration:separate-server', (done) => {
|
||||||
|
let runner = exec(
|
||||||
|
testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
|
||||||
|
{maxBuffer: 500 * 1024},
|
||||||
|
(err) => done(err)
|
||||||
|
);
|
||||||
|
|
||||||
|
pipe(runner);
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('test', gulp.series(
|
gulp.task('test', gulp.series(
|
||||||
'test:sanity',
|
'test:sanity',
|
||||||
'test:content',
|
'test:content',
|
||||||
'test:common',
|
'test:common',
|
||||||
'test:api-v3:unit',
|
'test:api:unit',
|
||||||
'test:api-v3:integration',
|
'test:api-v3:integration',
|
||||||
|
'test:api-v4:integration',
|
||||||
done => done()
|
done => done()
|
||||||
));
|
));
|
||||||
|
|
||||||
gulp.task('test:api-v3', gulp.series(
|
gulp.task('test:api-v3', gulp.series(
|
||||||
'test:api-v3:unit',
|
'test:api:unit',
|
||||||
'test:api-v3:integration',
|
'test:api-v3:integration',
|
||||||
done => done()
|
done => done()
|
||||||
));
|
));
|
||||||
107
migrations/groups/reconcile-group-plan-members.js
Normal file
107
migrations/groups/reconcile-group-plan-members.js
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import monk from 'monk';
|
||||||
|
import nconf from 'nconf';
|
||||||
|
import stripePayments from '../../website/server/libs/payments/stripe';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that group plan billing is accurate by doing the following:
|
||||||
|
* 1. Correct the memberCount in all paid groups whose counts are wrong
|
||||||
|
* 2. Where the above uses Stripe, update their subscription counts in Stripe
|
||||||
|
*
|
||||||
|
* Provides output on what groups were fixed, which can be piped to CSV.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||||
|
|
||||||
|
let dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
|
||||||
|
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
|
||||||
|
|
||||||
|
async function fixGroupPlanMembers () {
|
||||||
|
console.info('Group ID, Customer ID, Plan ID, Quantity, Recorded Member Count, Actual Member Count');
|
||||||
|
let groupPlanCount = 0;
|
||||||
|
let fixedGroupCount = 0;
|
||||||
|
|
||||||
|
dbGroups.find(
|
||||||
|
{
|
||||||
|
$and:
|
||||||
|
[
|
||||||
|
{'purchased.plan.planId': {$ne: null}},
|
||||||
|
{'purchased.plan.planId': {$ne: ''}},
|
||||||
|
{'purchased.plan.customerId': {$ne: 'cus_9f0DV4g7WHRzpM'}}, // Demo groups
|
||||||
|
{'purchased.plan.customerId': {$ne: 'cus_9maalqDOFTrvqx'}},
|
||||||
|
],
|
||||||
|
$or:
|
||||||
|
[
|
||||||
|
{'purchased.plan.dateTerminated': null},
|
||||||
|
{'purchased.plan.dateTerminated': ''},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: {
|
||||||
|
memberCount: 1,
|
||||||
|
'purchased.plan': 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
).each(async (group, {close, pause, resume}) => { // eslint-disable-line no-unused-vars
|
||||||
|
pause();
|
||||||
|
groupPlanCount++;
|
||||||
|
|
||||||
|
const canonicalMemberCount = await dbUsers.count(
|
||||||
|
{
|
||||||
|
$or:
|
||||||
|
[
|
||||||
|
{'party._id': group._id},
|
||||||
|
{guilds: group._id},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const incorrectMemberCount = group.memberCount !== canonicalMemberCount;
|
||||||
|
|
||||||
|
const isMonthlyPlan = group.purchased.plan.planId === 'group_monthly';
|
||||||
|
const quantityMismatch = group.purchased.plan.quantity !== group.memberCount + 2;
|
||||||
|
const incorrectQuantity = isMonthlyPlan && quantityMismatch;
|
||||||
|
|
||||||
|
if (!incorrectMemberCount && !incorrectQuantity) {
|
||||||
|
resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(`${group._id}, ${group.purchased.plan.customerId}, ${group.purchased.plan.planId}, ${group.purchased.plan.quantity}, ${group.memberCount}, ${canonicalMemberCount}`);
|
||||||
|
|
||||||
|
const groupUpdate = await dbGroups.update(
|
||||||
|
{ _id: group._id },
|
||||||
|
{
|
||||||
|
$set: {
|
||||||
|
memberCount: canonicalMemberCount,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!groupUpdate) return;
|
||||||
|
|
||||||
|
fixedGroupCount++;
|
||||||
|
if (group.purchased.plan.paymentMethod === 'Stripe') {
|
||||||
|
await stripePayments.chargeForAdditionalGroupMember(group);
|
||||||
|
await dbGroups.update(
|
||||||
|
{_id: group._id},
|
||||||
|
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incorrectQuantity) {
|
||||||
|
await dbGroups.update(
|
||||||
|
{_id: group._id},
|
||||||
|
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
resume();
|
||||||
|
}).then(() => {
|
||||||
|
console.info(`Fixed ${fixedGroupCount} out of ${groupPlanCount} active Group Plans`);
|
||||||
|
return process.exit(0);
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
return process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fixGroupPlanMembers;
|
||||||
@@ -17,5 +17,5 @@ function setUpServer () {
|
|||||||
setUpServer();
|
setUpServer();
|
||||||
|
|
||||||
// Replace this with your migration
|
// Replace this with your migration
|
||||||
const processUsers = require('./groups/migrate-chat.js');
|
const processUsers = require('./users/mystery-items.js');
|
||||||
processUsers();
|
processUsers();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let monk = require('monk');
|
let monk = require('monk');
|
||||||
let connectionString = 'mongodb://sabrecat:z8e8jyRA8CTofMQ@ds013393-a0.mlab.com:13393/habitica?auto_reconnect=true';
|
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
|
||||||
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
|
||||||
|
|
||||||
function processTasks (lastId) {
|
function processTasks (lastId) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const migrationName = 'mystery-items-201802.js'; // Update per month
|
const migrationName = 'mystery-items-201805.js'; // Update per month
|
||||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Award this month's mystery items to subscribers
|
* Award this month's mystery items to subscribers
|
||||||
*/
|
*/
|
||||||
const MYSTERY_ITEMS = ['back_mystery_201804', 'headAccessory_mystery_201804'];
|
const MYSTERY_ITEMS = ['back_mystery_201805', 'head_mystery_201805'];
|
||||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||||
|
|
||||||
let monk = require('monk');
|
let monk = require('monk');
|
||||||
|
|||||||
109
migrations/users/remove-social-users-extra-data.js
Normal file
109
migrations/users/remove-social-users-extra-data.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
const migrationName = 'remove-social-users-extra-data.js';
|
||||||
|
const authorName = 'paglias'; // in case script author needs to know when their ...
|
||||||
|
const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is done
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove not needed data from social profiles
|
||||||
|
*/
|
||||||
|
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||||
|
|
||||||
|
const monk = require('monk');
|
||||||
|
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||||
|
|
||||||
|
function processUsers (lastId) {
|
||||||
|
// specify a query to limit the affected users (empty for all users):
|
||||||
|
let query = {
|
||||||
|
migration: {$ne: migrationName},
|
||||||
|
$or: [
|
||||||
|
{ 'auth.facebook.id': { $exists: true } },
|
||||||
|
{ 'auth.google.id': { $exists: true } },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (lastId) {
|
||||||
|
query._id = {
|
||||||
|
$gt: lastId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dbUsers.find(query, {
|
||||||
|
sort: {_id: 1},
|
||||||
|
limit: 250,
|
||||||
|
})
|
||||||
|
.then(updateUsers)
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
return exiting(1, `ERROR! ${ err}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let progressCount = 1000;
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
function updateUsers (users) {
|
||||||
|
if (!users || users.length === 0) {
|
||||||
|
console.warn('All appropriate users found and modified.');
|
||||||
|
displayData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let userPromises = users.map(updateUser);
|
||||||
|
let lastUser = users[users.length - 1];
|
||||||
|
|
||||||
|
return Promise.all(userPromises)
|
||||||
|
.then(() => {
|
||||||
|
processUsers(lastUser._id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateUser (user) {
|
||||||
|
count++;
|
||||||
|
|
||||||
|
const isFacebook = user.auth.facebook && user.auth.facebook.id;
|
||||||
|
const isGoogle = user.auth.google && user.auth.google.id;
|
||||||
|
|
||||||
|
const update = { $set: {} };
|
||||||
|
|
||||||
|
if (isFacebook) {
|
||||||
|
update.$set['auth.facebook'] = {
|
||||||
|
id: user.auth.facebook.id,
|
||||||
|
emails: user.auth.facebook.emails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGoogle) {
|
||||||
|
update.$set['auth.google'] = {
|
||||||
|
id: user.auth.google.id,
|
||||||
|
emails: user.auth.google.emails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dbUsers.update({
|
||||||
|
_id: user._id,
|
||||||
|
}, update);
|
||||||
|
|
||||||
|
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||||
|
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayData () {
|
||||||
|
console.warn(`\n${ count } users processed\n`);
|
||||||
|
return exiting(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function exiting (code, msg) {
|
||||||
|
code = code || 0; // 0 = success
|
||||||
|
if (code && !msg) {
|
||||||
|
msg = 'ERROR!';
|
||||||
|
}
|
||||||
|
if (msg) {
|
||||||
|
if (code) {
|
||||||
|
console.error(msg);
|
||||||
|
} else {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process.exit(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = processUsers;
|
||||||
11098
package-lock.json
generated
11098
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "habitica",
|
"name": "habitica",
|
||||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||||
"version": "4.42.6",
|
"version": "4.47.0",
|
||||||
"main": "./website/server/index.js",
|
"main": "./website/server/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@slack/client": "^3.8.1",
|
"@slack/client": "^3.8.1",
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"method-override": "^2.3.5",
|
"method-override": "^2.3.5",
|
||||||
"moment": "^2.22.1",
|
"moment": "^2.22.1",
|
||||||
"moment-recur": "^1.0.7",
|
"moment-recur": "^1.0.7",
|
||||||
"mongoose": "^5.1.1",
|
"mongoose": "^5.1.2",
|
||||||
"morgan": "^1.7.0",
|
"morgan": "^1.7.0",
|
||||||
"nconf": "^0.10.0",
|
"nconf": "^0.10.0",
|
||||||
"node-gcm": "^0.14.4",
|
"node-gcm": "^0.14.4",
|
||||||
@@ -90,6 +90,8 @@
|
|||||||
"svgo": "^1.0.5",
|
"svgo": "^1.0.5",
|
||||||
"svgo-loader": "^2.1.0",
|
"svgo-loader": "^2.1.0",
|
||||||
"universal-analytics": "^0.4.16",
|
"universal-analytics": "^0.4.16",
|
||||||
|
"update": "^0.7.4",
|
||||||
|
"upgrade": "^1.1.0",
|
||||||
"url-loader": "^1.0.0",
|
"url-loader": "^1.0.0",
|
||||||
"useragent": "^2.1.9",
|
"useragent": "^2.1.9",
|
||||||
"uuid": "^3.0.1",
|
"uuid": "^3.0.1",
|
||||||
@@ -119,9 +121,11 @@
|
|||||||
"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",
|
||||||
"test:api-v3:unit": "gulp test:api-v3:unit",
|
"test:api:unit": "gulp test:api:unit",
|
||||||
"test:api-v3:integration": "gulp test:api-v3:integration",
|
"test:api-v3:integration": "gulp test:api-v3:integration",
|
||||||
"test:api-v3:integration:separate-server": "NODE_ENV=test gulp test:api-v3:integration:separate-server",
|
"test:api-v3:integration:separate-server": "NODE_ENV=test gulp test:api-v3:integration:separate-server",
|
||||||
|
"test:api-v4:integration": "gulp test:api-v4:integration",
|
||||||
|
"test:api-v4:integration:separate-server": "NODE_ENV=test gulp test:api-v4:integration:separate-server",
|
||||||
"test:sanity": "istanbul cover --dir coverage/sanity --report lcovonly node_modules/mocha/bin/_mocha -- test/sanity --recursive",
|
"test:sanity": "istanbul cover --dir coverage/sanity --report lcovonly node_modules/mocha/bin/_mocha -- test/sanity --recursive",
|
||||||
"test:common": "istanbul cover --dir coverage/common --report lcovonly node_modules/mocha/bin/_mocha -- test/common --recursive",
|
"test:common": "istanbul cover --dir coverage/common --report lcovonly node_modules/mocha/bin/_mocha -- test/common --recursive",
|
||||||
"test:content": "istanbul cover --dir coverage/content --report lcovonly node_modules/mocha/bin/_mocha -- test/content --recursive",
|
"test:content": "istanbul cover --dir coverage/content --report lcovonly node_modules/mocha/bin/_mocha -- test/content --recursive",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import analyticsService from '../../../../../website/server/libs/analyticsService';
|
import analyticsService from '../../../../website/server/libs/analyticsService';
|
||||||
import Amplitude from 'amplitude';
|
import Amplitude from 'amplitude';
|
||||||
import { Visitor } from 'universal-analytics';
|
import { Visitor } from 'universal-analytics';
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import apiError from '../../../../../website/server/libs/apiError';
|
import apiError from '../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('API Messages', () => {
|
describe('API Messages', () => {
|
||||||
const message = 'Only public guilds support pagination.';
|
const message = 'Only public guilds support pagination.';
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import baseModel from '../../../../../website/server/libs/baseModel';
|
import baseModel from '../../../../website/server/libs/baseModel';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
describe('Base model plugin', () => {
|
describe('Base model plugin', () => {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import {
|
import {
|
||||||
removeFromArray,
|
removeFromArray,
|
||||||
} from '../../../../../website/server/libs/collectionManipulators';
|
} from '../../../../website/server/libs/collectionManipulators';
|
||||||
|
|
||||||
describe('Collection Manipulators', () => {
|
describe('Collection Manipulators', () => {
|
||||||
describe('removeFromArray', () => {
|
describe('removeFromArray', () => {
|
||||||
@@ -2,17 +2,18 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
import { recoverCron, cron } from '../../../../../website/server/libs/cron';
|
import { recoverCron, cron } from '../../../../website/server/libs/cron';
|
||||||
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 analytics from '../../../../../website/server/libs/analyticsService';
|
import analytics from '../../../../website/server/libs/analyticsService';
|
||||||
|
|
||||||
// const scoreTask = common.ops.scoreTask;
|
// const scoreTask = common.ops.scoreTask;
|
||||||
|
|
||||||
let pathToCronLib = '../../../../../website/server/libs/cron';
|
let pathToCronLib = '../../../../website/server/libs/cron';
|
||||||
|
|
||||||
describe('cron', () => {
|
describe('cron', () => {
|
||||||
|
let clock = null;
|
||||||
let user;
|
let user;
|
||||||
let tasksByType = {habits: [], dailys: [], todos: [], rewards: []};
|
let tasksByType = {habits: [], dailys: [], todos: [], rewards: []};
|
||||||
let daysMissed = 0;
|
let daysMissed = 0;
|
||||||
@@ -34,6 +35,8 @@ describe('cron', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
if (clock !== null)
|
||||||
|
clock.restore();
|
||||||
analytics.track.restore();
|
analytics.track.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,14 +85,12 @@ describe('cron', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not reset plan.gemsBought within the month', () => {
|
it('does not reset plan.gemsBought within the month', () => {
|
||||||
let clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').toDate());
|
clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').toDate());
|
||||||
user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
|
user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
|
||||||
|
|
||||||
user.purchased.plan.gemsBought = 10;
|
user.purchased.plan.gemsBought = 10;
|
||||||
cron({user, tasksByType, daysMissed, analytics});
|
cron({user, tasksByType, daysMissed, analytics});
|
||||||
expect(user.purchased.plan.gemsBought).to.equal(10);
|
expect(user.purchased.plan.gemsBought).to.equal(10);
|
||||||
|
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resets plan.dateUpdated on a new month', () => {
|
it('resets plan.dateUpdated on a new month', () => {
|
||||||
@@ -156,7 +157,6 @@ describe('cron', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 1-month recurring subscription', () => {
|
describe('for a 1-month recurring subscription', () => {
|
||||||
let clock;
|
|
||||||
// create a user that will be used for all of these tests without a reset before each
|
// create a user that will be used for all of these tests without a reset before each
|
||||||
let user1 = new User({
|
let user1 = new User({
|
||||||
auth: {
|
auth: {
|
||||||
@@ -187,7 +187,6 @@ describe('cron', () => {
|
|||||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits after the second month', () => {
|
it('does not increment consecutive benefits after the second month', () => {
|
||||||
@@ -199,7 +198,6 @@ describe('cron', () => {
|
|||||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(0);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits after the third month', () => {
|
it('increments consecutive benefits after the third month', () => {
|
||||||
@@ -211,7 +209,6 @@ describe('cron', () => {
|
|||||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits after the fourth month', () => {
|
it('does not increment consecutive benefits after the fourth month', () => {
|
||||||
@@ -223,7 +220,6 @@ describe('cron', () => {
|
|||||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||||
@@ -233,12 +229,10 @@ describe('cron', () => {
|
|||||||
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user1.purchased.plan.consecutive.trinkets).to.equal(3);
|
expect(user1.purchased.plan.consecutive.trinkets).to.equal(3);
|
||||||
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
expect(user1.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 3-month recurring subscription', () => {
|
describe('for a 3-month recurring subscription', () => {
|
||||||
let clock;
|
|
||||||
let user3 = new User({
|
let user3 = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
@@ -266,7 +260,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the middle of the period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the middle of the period that they already have benefits for', () => {
|
||||||
@@ -276,7 +269,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||||
@@ -286,7 +278,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||||
@@ -296,7 +287,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the second month of the second period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the second month of the second period that they already have benefits for', () => {
|
||||||
@@ -306,7 +296,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the final month of the second period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the final month of the second period that they already have benefits for', () => {
|
||||||
@@ -316,7 +305,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||||
@@ -326,7 +314,6 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(3);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(3);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(15);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||||
@@ -336,12 +323,10 @@ describe('cron', () => {
|
|||||||
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
|
||||||
expect(user3.purchased.plan.consecutive.trinkets).to.equal(4);
|
expect(user3.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||||
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
expect(user3.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 6-month recurring subscription', () => {
|
describe('for a 6-month recurring subscription', () => {
|
||||||
let clock;
|
|
||||||
let user6 = new User({
|
let user6 = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
@@ -369,7 +354,6 @@ describe('cron', () => {
|
|||||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||||
@@ -379,7 +363,6 @@ describe('cron', () => {
|
|||||||
expect(user6.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user6.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
|
||||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(10);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||||
@@ -389,7 +372,6 @@ describe('cron', () => {
|
|||||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(4);
|
expect(user6.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||||
@@ -399,7 +381,6 @@ describe('cron', () => {
|
|||||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(6);
|
expect(user6.purchased.plan.consecutive.trinkets).to.equal(6);
|
||||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||||
@@ -409,13 +390,10 @@ describe('cron', () => {
|
|||||||
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6.purchased.plan.consecutive.trinkets).to.equal(8);
|
expect(user6.purchased.plan.consecutive.trinkets).to.equal(8);
|
||||||
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 12-month recurring subscription', () => {
|
describe('for a 12-month recurring subscription', () => {
|
||||||
let clock;
|
|
||||||
|
|
||||||
let user12 = new User({
|
let user12 = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
@@ -443,7 +421,6 @@ describe('cron', () => {
|
|||||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
|
||||||
@@ -453,7 +430,6 @@ describe('cron', () => {
|
|||||||
expect(user12.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user12.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
|
||||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(20);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the second paid period has started', () => {
|
it('increments consecutive benefits the month after the second paid period has started', () => {
|
||||||
@@ -463,7 +439,6 @@ describe('cron', () => {
|
|||||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(8);
|
expect(user12.purchased.plan.consecutive.trinkets).to.equal(8);
|
||||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits the month after the third paid period has started', () => {
|
it('increments consecutive benefits the month after the third paid period has started', () => {
|
||||||
@@ -473,7 +448,6 @@ describe('cron', () => {
|
|||||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(12);
|
expect(user12.purchased.plan.consecutive.trinkets).to.equal(12);
|
||||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
|
||||||
@@ -483,12 +457,10 @@ describe('cron', () => {
|
|||||||
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
|
||||||
expect(user12.purchased.plan.consecutive.trinkets).to.equal(16);
|
expect(user12.purchased.plan.consecutive.trinkets).to.equal(16);
|
||||||
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user12.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 3-month gift subscription (non-recurring)', () => {
|
describe('for a 3-month gift subscription (non-recurring)', () => {
|
||||||
let clock;
|
|
||||||
let user3g = new User({
|
let user3g = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
@@ -503,7 +475,7 @@ describe('cron', () => {
|
|||||||
// user3g has a 3-month gift subscription starting today
|
// user3g has a 3-month gift subscription starting today
|
||||||
user3g.purchased.plan.customerId = 'Gift';
|
user3g.purchased.plan.customerId = 'Gift';
|
||||||
user3g.purchased.plan.dateUpdated = moment().toDate();
|
user3g.purchased.plan.dateUpdated = moment().toDate();
|
||||||
user3g.purchased.plan.dateTerminated = moment().add(3, 'months').toDate();
|
user3g.purchased.plan.dateTerminated = moment().startOf('month').add(3, 'months').add(15, 'days').toDate();
|
||||||
user3g.purchased.plan.planId = null;
|
user3g.purchased.plan.planId = null;
|
||||||
user3g.purchased.plan.consecutive.count = 0;
|
user3g.purchased.plan.consecutive.count = 0;
|
||||||
user3g.purchased.plan.consecutive.offset = 3;
|
user3g.purchased.plan.consecutive.offset = 3;
|
||||||
@@ -517,7 +489,6 @@ describe('cron', () => {
|
|||||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(2);
|
expect(user3g.purchased.plan.consecutive.offset).to.equal(2);
|
||||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the second month of the gift subscription', () => {
|
it('does not increment consecutive benefits in the second month of the gift subscription', () => {
|
||||||
@@ -527,7 +498,6 @@ describe('cron', () => {
|
|||||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(1);
|
expect(user3g.purchased.plan.consecutive.offset).to.equal(1);
|
||||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the third month of the gift subscription', () => {
|
it('does not increment consecutive benefits in the third month of the gift subscription', () => {
|
||||||
@@ -537,7 +507,6 @@ describe('cron', () => {
|
|||||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(5);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the month after the gift subscription has ended', () => {
|
it('does not increment consecutive benefits in the month after the gift subscription has ended', () => {
|
||||||
@@ -547,12 +516,10 @@ describe('cron', () => {
|
|||||||
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
|
||||||
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
|
||||||
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(0); // erased
|
expect(user3g.purchased.plan.consecutive.gemCapExtra).to.equal(0); // erased
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for a 6-month recurring subscription where the user has incorrect consecutive month data from prior bugs', () => {
|
describe('for a 6-month recurring subscription where the user has incorrect consecutive month data from prior bugs', () => {
|
||||||
let clock;
|
|
||||||
let user6x = new User({
|
let user6x = new User({
|
||||||
auth: {
|
auth: {
|
||||||
local: {
|
local: {
|
||||||
@@ -580,7 +547,6 @@ describe('cron', () => {
|
|||||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the second month after the fix goes live', () => {
|
it('does not increment consecutive benefits in the second month after the fix goes live', () => {
|
||||||
@@ -590,7 +556,6 @@ describe('cron', () => {
|
|||||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(4);
|
expect(user6x.purchased.plan.consecutive.offset).to.equal(4);
|
||||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increment consecutive benefits in the third month after the fix goes live', () => {
|
it('does not increment consecutive benefits in the third month after the fix goes live', () => {
|
||||||
@@ -600,7 +565,6 @@ describe('cron', () => {
|
|||||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(3);
|
expect(user6x.purchased.plan.consecutive.offset).to.equal(3);
|
||||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
|
||||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increments consecutive benefits in the seventh month after the fix goes live', () => {
|
it('increments consecutive benefits in the seventh month after the fix goes live', () => {
|
||||||
@@ -610,7 +574,6 @@ describe('cron', () => {
|
|||||||
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
|
||||||
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(7);
|
expect(user6x.purchased.plan.consecutive.trinkets).to.equal(7);
|
||||||
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
expect(user6x.purchased.plan.consecutive.gemCapExtra).to.equal(25);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -627,14 +590,12 @@ describe('cron', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not reset plan.gemsBought within the month', () => {
|
it('does not reset plan.gemsBought within the month', () => {
|
||||||
let clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').unix());
|
clock = sinon.useFakeTimers(moment().startOf('month').add(2, 'days').unix());
|
||||||
user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
|
user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
|
||||||
|
|
||||||
user.purchased.plan.gemsBought = 10;
|
user.purchased.plan.gemsBought = 10;
|
||||||
cron({user, tasksByType, daysMissed, analytics});
|
cron({user, tasksByType, daysMissed, analytics});
|
||||||
expect(user.purchased.plan.gemsBought).to.equal(10);
|
expect(user.purchased.plan.gemsBought).to.equal(10);
|
||||||
|
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not reset plan.dateUpdated on a new month', () => {
|
it('does not reset plan.dateUpdated on a new month', () => {
|
||||||
@@ -1040,15 +1001,11 @@ describe('cron', () => {
|
|||||||
|
|
||||||
describe('counters', () => {
|
describe('counters', () => {
|
||||||
let notStartOfWeekOrMonth = new Date(2016, 9, 28).getTime(); // a Friday
|
let notStartOfWeekOrMonth = new Date(2016, 9, 28).getTime(); // a Friday
|
||||||
let clock;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Replace system clocks so we can get predictable results
|
// Replace system clocks so we can get predictable results
|
||||||
clock = sinon.useFakeTimers(notStartOfWeekOrMonth);
|
clock = sinon.useFakeTimers(notStartOfWeekOrMonth);
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
|
||||||
return clock.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reset a daily habit counter each day', () => {
|
it('should reset a daily habit counter each day', () => {
|
||||||
tasksByType.habits[0].counterUp = 1;
|
tasksByType.habits[0].counterUp = 1;
|
||||||
@@ -3,9 +3,9 @@ import got from 'got';
|
|||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import nodemailer from 'nodemailer';
|
import nodemailer from 'nodemailer';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
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 { defer } from '../../../../helpers/api-unit.helper';
|
import { defer } from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
function getUser () {
|
function getUser () {
|
||||||
return {
|
return {
|
||||||
@@ -19,7 +19,6 @@ function getUser () {
|
|||||||
emails: [{
|
emails: [{
|
||||||
value: 'email@facebook',
|
value: 'email@facebook',
|
||||||
}],
|
}],
|
||||||
displayName: 'fb display name',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
@@ -34,7 +33,7 @@ function getUser () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('emails', () => {
|
describe('emails', () => {
|
||||||
let pathToEmailLib = '../../../../../website/server/libs/email';
|
let pathToEmailLib = '../../../../website/server/libs/email';
|
||||||
|
|
||||||
describe('sendEmail', () => {
|
describe('sendEmail', () => {
|
||||||
let sendMailSpy;
|
let sendMailSpy;
|
||||||
@@ -100,7 +99,7 @@ describe('emails', () => {
|
|||||||
|
|
||||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||||
|
|
||||||
expect(data).to.have.property('name', user.auth.facebook.displayName);
|
expect(data).to.have.property('name', user.profile.name);
|
||||||
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
||||||
expect(data).to.have.property('_id', user._id);
|
expect(data).to.have.property('_id', user._id);
|
||||||
expect(data).to.have.property('canSend', true);
|
expect(data).to.have.property('canSend', true);
|
||||||
@@ -110,13 +109,12 @@ describe('emails', () => {
|
|||||||
let attachEmail = requireAgain(pathToEmailLib);
|
let attachEmail = requireAgain(pathToEmailLib);
|
||||||
let getUserInfo = attachEmail.getUserInfo;
|
let getUserInfo = attachEmail.getUserInfo;
|
||||||
let user = getUser();
|
let user = getUser();
|
||||||
delete user.profile.name;
|
|
||||||
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']);
|
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||||
|
|
||||||
expect(data).to.have.property('name', user.auth.local.username);
|
expect(data).to.have.property('name', user.profile.name);
|
||||||
expect(data).not.to.have.property('email');
|
expect(data).not.to.have.property('email');
|
||||||
expect(data).to.have.property('_id', user._id);
|
expect(data).to.have.property('_id', user._id);
|
||||||
expect(data).to.have.property('canSend', true);
|
expect(data).to.have.property('canSend', true);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
encrypt,
|
encrypt,
|
||||||
decrypt,
|
decrypt,
|
||||||
} from '../../../../../website/server/libs/encryption';
|
} from '../../../../website/server/libs/encryption';
|
||||||
|
|
||||||
describe('encryption', () => {
|
describe('encryption', () => {
|
||||||
it('can encrypt and decrypt', () => {
|
it('can encrypt and decrypt', () => {
|
||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
BadRequest,
|
BadRequest,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
NotFound,
|
NotFound,
|
||||||
} from '../../../../../website/server/libs/errors';
|
} from '../../../../website/server/libs/errors';
|
||||||
|
|
||||||
describe('Custom Errors', () => {
|
describe('Custom Errors', () => {
|
||||||
describe('CustomError', () => {
|
describe('CustomError', () => {
|
||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
translations,
|
translations,
|
||||||
localePath,
|
localePath,
|
||||||
langCodes,
|
langCodes,
|
||||||
} from '../../../../../website/server/libs/i18n';
|
} from '../../../../website/server/libs/i18n';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import winston from 'winston';
|
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;
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
encrypt,
|
encrypt,
|
||||||
} from '../../../../../website/server/libs/encryption';
|
} from '../../../../website/server/libs/encryption';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
sha1Encrypt as sha1EncryptPassword,
|
sha1Encrypt as sha1EncryptPassword,
|
||||||
sha1MakeSalt,
|
sha1MakeSalt,
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
compare,
|
compare,
|
||||||
convertToBcrypt,
|
convertToBcrypt,
|
||||||
validatePasswordResetCodeAndFindUser,
|
validatePasswordResetCodeAndFindUser,
|
||||||
} from '../../../../../website/server/libs/password';
|
} from '../../../../website/server/libs/password';
|
||||||
|
|
||||||
describe('Password Utilities', () => {
|
describe('Password Utilities', () => {
|
||||||
describe('compare', () => {
|
describe('compare', () => {
|
||||||
@@ -2,11 +2,11 @@ import moment from 'moment';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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.i18n;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
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';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const i18n = common.i18n;
|
||||||
|
|
||||||
@@ -2,12 +2,12 @@ import cc from 'coupon-code';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -2,11 +2,11 @@ import uuid from 'uuid';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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, data, user, group, uuidString;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import iapModule from '../../../../../../website/server/libs/inAppPurchases';
|
import iapModule from '../../../../../website/server/libs/inAppPurchases';
|
||||||
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 moment from 'moment';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const i18n = common.i18n;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import iapModule from '../../../../../../website/server/libs/inAppPurchases';
|
import iapModule from '../../../../../website/server/libs/inAppPurchases';
|
||||||
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 moment from 'moment';
|
||||||
|
|
||||||
const i18n = common.i18n;
|
const i18n = common.i18n;
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import * as sender from '../../../../../../../website/server/libs/email';
|
import * as sender from '../../../../../../website/server/libs/email';
|
||||||
import * as api from '../../../../../../../website/server/libs/payments/payments';
|
import * as api from '../../../../../../website/server/libs/payments/payments';
|
||||||
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 {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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, group, user, data;
|
||||||
@@ -2,16 +2,16 @@ import moment from 'moment';
|
|||||||
import stripeModule from 'stripe';
|
import stripeModule from 'stripe';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
|
|
||||||
import * as sender from '../../../../../../../website/server/libs/email';
|
import * as sender from '../../../../../../website/server/libs/email';
|
||||||
import * as api from '../../../../../../../website/server/libs/payments/payments';
|
import * as api from '../../../../../../website/server/libs/payments/payments';
|
||||||
import amzLib from '../../../../../../../website/server/libs/payments/amazon';
|
import amzLib from '../../../../../../website/server/libs/payments/amazon';
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
import stripePayments from '../../../../../../../website/server/libs/payments/stripe';
|
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
|
||||||
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 {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
|
|
||||||
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';
|
||||||
@@ -443,8 +443,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);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
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) {
|
||||||
let nonLeader = new User();
|
let nonLeader = new User();
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import * as sender from '../../../../../../website/server/libs/email';
|
import * as sender from '../../../../../website/server/libs/email';
|
||||||
import * as api from '../../../../../../website/server/libs/payments/payments';
|
import * as api from '../../../../../website/server/libs/payments/payments';
|
||||||
import analytics from '../../../../../../website/server/libs/analyticsService';
|
import analytics from '../../../../../website/server/libs/analyticsService';
|
||||||
import notifications from '../../../../../../website/server/libs/pushNotifications';
|
import notifications from '../../../../../website/server/libs/pushNotifications';
|
||||||
import { model as User } from '../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../website/server/models/user';
|
||||||
import { translate as t } from '../../../../../helpers/api-v3-integration.helper';
|
import { translate as t } from '../../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../helpers/api-unit.helper.js';
|
} from '../../../../helpers/api-unit.helper.js';
|
||||||
|
|
||||||
describe('payments/index', () => {
|
describe('payments/index', () => {
|
||||||
let user, group, data, plan;
|
let user, group, data, plan;
|
||||||
@@ -210,7 +210,7 @@ describe('payments/index', () => {
|
|||||||
let msg = '\`Hello recipient, sender has sent you 3 months of subscription!\`';
|
let 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 });
|
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 () => {
|
||||||
@@ -629,7 +629,7 @@ describe('payments/index', () => {
|
|||||||
await api.buyGems(data);
|
await api.buyGems(data);
|
||||||
let msg = '\`Hello recipient, sender has sent you 4 gems!\`';
|
let msg = '\`Hello recipient, sender has sent you 4 gems!\`';
|
||||||
|
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg });
|
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 () => {
|
||||||
@@ -638,7 +638,7 @@ 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 });
|
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 () => {
|
||||||
@@ -667,7 +667,7 @@ describe('payments/index', () => {
|
|||||||
return `\`${messageContent}\``;
|
return `\`${messageContent}\``;
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: recipientsMessageContent, senderMsg: sendersMessageContent });
|
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: recipientsMessageContent, senderMsg: sendersMessageContent, save: false });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
import payments from '../../../../../../../website/server/libs/payments/payments';
|
import payments from '../../../../../../website/server/libs/payments/payments';
|
||||||
import { model as User } from '../../../../../../../website/server/models/user';
|
import { model as User } from '../../../../../../website/server/models/user';
|
||||||
|
|
||||||
describe('checkout success', () => {
|
describe('checkout success', () => {
|
||||||
const subKey = 'basic_3mo';
|
const subKey = 'basic_3mo';
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
|
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
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';
|
||||||
|
|
||||||
const BASE_URL = nconf.get('BASE_URL');
|
const BASE_URL = nconf.get('BASE_URL');
|
||||||
const i18n = common.i18n;
|
const i18n = common.i18n;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
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.js';
|
||||||
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';
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
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.js';
|
||||||
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.i18n;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
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.js';
|
||||||
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';
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import cc from 'coupon-code';
|
import cc from 'coupon-code';
|
||||||
|
|
||||||
import paypalPayments from '../../../../../../../website/server/libs/payments/paypal';
|
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -2,11 +2,11 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -3,12 +3,12 @@ import cc from 'coupon-code';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import stripeModule from 'stripe';
|
import stripeModule from 'stripe';
|
||||||
|
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -37,6 +37,22 @@ describe('checkout', () => {
|
|||||||
payments.createSubscription.restore();
|
payments.createSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if there is no token', async () => {
|
||||||
|
await expect(stripePayments.checkout({
|
||||||
|
user,
|
||||||
|
gift,
|
||||||
|
groupId,
|
||||||
|
email,
|
||||||
|
headers,
|
||||||
|
coupon,
|
||||||
|
}, stripe))
|
||||||
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
|
httpCode: 400,
|
||||||
|
message: 'Missing req.body.id',
|
||||||
|
name: 'BadRequest',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should error if gem amount is too low', async () => {
|
it('should error if gem amount is too low', async () => {
|
||||||
let receivingUser = new User();
|
let receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
@@ -64,7 +80,6 @@ describe('checkout', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should error if user cannot get gems', async () => {
|
it('should error if user cannot get gems', async () => {
|
||||||
gift = undefined;
|
gift = undefined;
|
||||||
sinon.stub(user, 'canGetGems').returnsPromise().resolves(false);
|
sinon.stub(user, 'canGetGems').returnsPromise().resolves(false);
|
||||||
@@ -2,10 +2,10 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -2,12 +2,12 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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 { v4 as uuid } from 'uuid';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
@@ -2,11 +2,11 @@ import stripeModule from 'stripe';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../../../helpers/api-unit.helper.js';
|
} from '../../../../../helpers/api-unit.helper.js';
|
||||||
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';
|
||||||
import payments from '../../../../../../../website/server/libs/payments/payments';
|
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');
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { preenHistory } from '../../../../../website/server/libs/preening';
|
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 { generateHistory } from '../../../helpers/api-unit.helper.js';
|
||||||
|
|
||||||
describe('preenHistory', () => {
|
describe('preenHistory', () => {
|
||||||
let clock;
|
let clock;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { model as User } from '../../../../../website/server/models/user';
|
import { model as User } from '../../../../website/server/models/user';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
import pushNotify from 'push-notify';
|
import pushNotify from 'push-notify';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
@@ -7,7 +7,7 @@ import gcmLib from 'node-gcm'; // works with FCM notifications too
|
|||||||
describe('pushNotifications', () => {
|
describe('pushNotifications', () => {
|
||||||
let user;
|
let user;
|
||||||
let sendPushNotification;
|
let sendPushNotification;
|
||||||
let pathToPushNotifications = '../../../../../website/server/libs/pushNotifications';
|
let pathToPushNotifications = '../../../../website/server/libs/pushNotifications';
|
||||||
let fcmSendSpy;
|
let fcmSendSpy;
|
||||||
let apnSendSpy;
|
let apnSendSpy;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import setupNconf from '../../../../../website/server/libs/setupNconf';
|
import setupNconf from '../../../../website/server/libs/setupNconf';
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
@@ -1,10 +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 slack from '../../../../../website/server/libs/slack';
|
import 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 nconf from 'nconf';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
describe('slack', () => {
|
describe('slack', () => {
|
||||||
describe('sendFlagNotification', () => {
|
describe('sendFlagNotification', () => {
|
||||||
@@ -45,13 +46,15 @@ describe('slack', () => {
|
|||||||
it('sends a slack webhook', () => {
|
it('sends a slack webhook', () => {
|
||||||
slack.sendFlagNotification(data);
|
slack.sendFlagNotification(data);
|
||||||
|
|
||||||
|
const timestamp = `${moment(data.message.timestamp).utc().format('YYYY-MM-DD HH:mm')} UTC`;
|
||||||
|
|
||||||
expect(IncomingWebhook.prototype.send).to.be.calledOnce;
|
expect(IncomingWebhook.prototype.send).to.be.calledOnce;
|
||||||
expect(IncomingWebhook.prototype.send).to.be.calledWith({
|
expect(IncomingWebhook.prototype.send).to.be.calledWith({
|
||||||
text: 'flagger (flagger-id; language: flagger-lang) flagged a message',
|
text: 'flagger (flagger-id; language: flagger-lang) flagged a message',
|
||||||
attachments: [{
|
attachments: [{
|
||||||
fallback: 'Flag Message',
|
fallback: 'Flag Message',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
author_name: 'Author - author@example.com - author-id',
|
author_name: `Author - author@example.com - author-id\n${timestamp}`,
|
||||||
title: 'Flag in Some group - (private guild)',
|
title: 'Flag in Some group - (private guild)',
|
||||||
title_link: undefined,
|
title_link: undefined,
|
||||||
text: 'some text',
|
text: 'some text',
|
||||||
@@ -97,9 +100,11 @@ describe('slack', () => {
|
|||||||
|
|
||||||
slack.sendFlagNotification(data);
|
slack.sendFlagNotification(data);
|
||||||
|
|
||||||
|
const timestamp = `${moment(data.message.timestamp).utc().format('YYYY-MM-DD HH:mm')} UTC`;
|
||||||
|
|
||||||
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
|
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
|
||||||
attachments: [sandbox.match({
|
attachments: [sandbox.match({
|
||||||
author_name: 'System Message',
|
author_name: `System Message\n${timestamp}`,
|
||||||
})],
|
})],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -107,7 +112,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');
|
let reRequiredSlack = requireAgain('../../../../website/server/libs/slack');
|
||||||
|
|
||||||
expect(logger.error).to.be.calledOnce;
|
expect(logger.error).to.be.calledOnce;
|
||||||
|
|
||||||
@@ -3,13 +3,13 @@ import {
|
|||||||
getTasks,
|
getTasks,
|
||||||
syncableAttrs,
|
syncableAttrs,
|
||||||
moveTask,
|
moveTask,
|
||||||
} from '../../../../../website/server/libs/taskManager';
|
} from '../../../../website/server/libs/taskManager';
|
||||||
import i18n from '../../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
} from '../../../../helpers/api-unit.helper.js';
|
} from '../../../helpers/api-unit.helper.js';
|
||||||
|
|
||||||
describe('taskManager', () => {
|
describe('taskManager', () => {
|
||||||
let user, group, challenge;
|
let user, group, challenge;
|
||||||
@@ -6,11 +6,14 @@ import {
|
|||||||
taskActivityWebhook,
|
taskActivityWebhook,
|
||||||
questActivityWebhook,
|
questActivityWebhook,
|
||||||
userActivityWebhook,
|
userActivityWebhook,
|
||||||
} from '../../../../../website/server/libs/webhook';
|
} from '../../../../website/server/libs/webhook';
|
||||||
|
import {
|
||||||
|
model as User,
|
||||||
|
} from '../../../../website/server/models/user';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-unit.helper.js';
|
} from '../../../helpers/api-unit.helper.js';
|
||||||
import { defer } from '../../../../helpers/api-unit.helper';
|
import { defer } from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
describe('webhooks', () => {
|
describe('webhooks', () => {
|
||||||
let webhooks, user;
|
let webhooks, user;
|
||||||
@@ -306,17 +309,6 @@ describe('webhooks', () => {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
addComputedStatsToJSONObj () {
|
|
||||||
let mockStats = Object.assign({
|
|
||||||
maxHealth: 50,
|
|
||||||
maxMP: 103,
|
|
||||||
toNextLevel: 40,
|
|
||||||
}, this.stats);
|
|
||||||
|
|
||||||
delete mockStats.toJSON;
|
|
||||||
|
|
||||||
return mockStats;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
task: {
|
task: {
|
||||||
text: 'text',
|
text: 'text',
|
||||||
@@ -324,6 +316,15 @@ describe('webhooks', () => {
|
|||||||
direction: 'up',
|
direction: 'up',
|
||||||
delta: 176,
|
delta: 176,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mockStats = Object.assign({
|
||||||
|
maxHealth: 50,
|
||||||
|
maxMP: 103,
|
||||||
|
toNextLevel: 40,
|
||||||
|
}, data.user.stats);
|
||||||
|
delete mockStats.toJSON;
|
||||||
|
|
||||||
|
sandbox.stub(User, 'addComputedStatsToJSONObj').returns(mockStats);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends task and stats data', () => {
|
it('sends task and stats data', () => {
|
||||||
@@ -3,14 +3,14 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import analyticsService from '../../../../../website/server/libs/analyticsService';
|
import analyticsService from '../../../../website/server/libs/analyticsService';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
|
|
||||||
describe('analytics middleware', () => {
|
describe('analytics middleware', () => {
|
||||||
let res, req, next;
|
let res, req, next;
|
||||||
let pathToAnalyticsMiddleware = '../../../../../website/server/middlewares/analytics';
|
let pathToAnalyticsMiddleware = '../../../../website/server/middlewares/analytics';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
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, req, user;
|
||||||
@@ -3,8 +3,8 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
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, req, next;
|
||||||
@@ -3,14 +3,14 @@ import {
|
|||||||
generateReq,
|
generateReq,
|
||||||
generateTodo,
|
generateTodo,
|
||||||
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 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 analyticsService from '../../../../../website/server/libs/analyticsService';
|
import 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';
|
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();
|
||||||
@@ -166,8 +166,11 @@ 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(user.stats.hp).to.be.lessThan(hpBefore);
|
User.findOne({_id: user._id}, function (secondErr, updatedUser) {
|
||||||
resolve();
|
if (secondErr) return reject(secondErr);
|
||||||
|
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -176,7 +179,7 @@ describe('cron middleware', () => {
|
|||||||
user.lastCron = moment(new Date()).subtract({days: 2});
|
user.lastCron = moment(new Date()).subtract({days: 2});
|
||||||
let todo = generateTodo(user);
|
let todo = generateTodo(user);
|
||||||
let todoValueBefore = todo.value;
|
let todoValueBefore = todo.value;
|
||||||
await 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) => {
|
||||||
@@ -217,8 +220,11 @@ 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(user.stats.hp).to.be.lessThan(hpBefore);
|
User.findOne({_id: user._id}, function (secondErr, updatedUser) {
|
||||||
resolve();
|
if (secondErr) return reject(secondErr);
|
||||||
|
expect(updatedUser.stats.hp).to.be.lessThan(hpBefore);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -3,11 +3,11 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import i18n from '../../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
import { ensureAdmin, ensureSudo } from '../../../../../website/server/middlewares/ensureAccessRight';
|
import { ensureAdmin, ensureSudo } from '../../../../website/server/middlewares/ensureAccessRight';
|
||||||
import { NotAuthorized } from '../../../../../website/server/libs/errors';
|
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, req, next;
|
||||||
@@ -3,9 +3,9 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} 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';
|
import nconf from 'nconf';
|
||||||
|
|
||||||
describe('developmentMode middleware', () => {
|
describe('developmentMode middleware', () => {
|
||||||
@@ -2,17 +2,17 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
|
|
||||||
import errorHandler from '../../../../../website/server/middlewares/errorHandler';
|
import errorHandler from '../../../../website/server/middlewares/errorHandler';
|
||||||
import responseMiddleware from '../../../../../website/server/middlewares/response';
|
import responseMiddleware from '../../../../website/server/middlewares/response';
|
||||||
import {
|
import {
|
||||||
getUserLanguage,
|
getUserLanguage,
|
||||||
attachTranslateFunction,
|
attachTranslateFunction,
|
||||||
} from '../../../../../website/server/middlewares/language';
|
} from '../../../../website/server/middlewares/language';
|
||||||
|
|
||||||
import { BadRequest } from '../../../../../website/server/libs/errors';
|
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, req, next;
|
||||||
@@ -2,13 +2,13 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import {
|
import {
|
||||||
getUserLanguage,
|
getUserLanguage,
|
||||||
attachTranslateFunction,
|
attachTranslateFunction,
|
||||||
} from '../../../../../website/server/middlewares/language';
|
} from '../../../../website/server/middlewares/language';
|
||||||
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.i18n;
|
||||||
|
|
||||||
@@ -2,13 +2,13 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
|
|
||||||
describe('maintenance mode middleware', () => {
|
describe('maintenance mode middleware', () => {
|
||||||
let res, req, next;
|
let res, req, next;
|
||||||
let pathToMaintenanceModeMiddleware = '../../../../../website/server/middlewares/maintenanceMode';
|
let pathToMaintenanceModeMiddleware = '../../../../website/server/middlewares/maintenanceMode';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -2,13 +2,13 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import requireAgain from 'require-again';
|
import requireAgain from 'require-again';
|
||||||
|
|
||||||
describe('redirects middleware', () => {
|
describe('redirects middleware', () => {
|
||||||
let res, req, next;
|
let res, req, next;
|
||||||
let pathToRedirectsMiddleware = '../../../../../website/server/middlewares/redirects';
|
let pathToRedirectsMiddleware = '../../../../website/server/middlewares/redirects';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
res = generateRes();
|
res = generateRes();
|
||||||
@@ -2,9 +2,9 @@ import {
|
|||||||
generateRes,
|
generateRes,
|
||||||
generateReq,
|
generateReq,
|
||||||
generateNext,
|
generateNext,
|
||||||
} from '../../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import responseMiddleware from '../../../../../website/server/middlewares/response';
|
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, req, next;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
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';
|
import { each, find } from 'lodash';
|
||||||
|
|
||||||
describe('Challenge Model', () => {
|
describe('Challenge Model', () => {
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
import { sleep, translationCheck } from '../../../../helpers/api-unit.helper';
|
import { sleep, translationCheck } from '../../../helpers/api-unit.helper';
|
||||||
import {
|
import {
|
||||||
SPAM_MESSAGE_LIMIT,
|
SPAM_MESSAGE_LIMIT,
|
||||||
SPAM_MIN_EXEMPT_CONTRIB_LEVEL,
|
SPAM_MIN_EXEMPT_CONTRIB_LEVEL,
|
||||||
SPAM_WINDOW_LENGTH,
|
SPAM_WINDOW_LENGTH,
|
||||||
INVITES_LIMIT,
|
INVITES_LIMIT,
|
||||||
model as Group,
|
model as Group,
|
||||||
} from '../../../../../website/server/models/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 { quests as questScrolls } from '../../../../../website/common/script/content';
|
import { quests as questScrolls } from '../../../../website/common/script/content';
|
||||||
import {
|
import {
|
||||||
groupChatReceivedWebhook,
|
groupChatReceivedWebhook,
|
||||||
questActivityWebhook,
|
questActivityWebhook,
|
||||||
} from '../../../../../website/server/libs/webhook';
|
} from '../../../../website/server/libs/webhook';
|
||||||
import * as email from '../../../../../website/server/libs/email';
|
import * as email from '../../../../website/server/libs/email';
|
||||||
import { TAVERN_ID } from '../../../../../website/common/script/';
|
import { TAVERN_ID } from '../../../../website/common/script/';
|
||||||
import shared from '../../../../../website/common';
|
import shared from '../../../../website/common';
|
||||||
|
|
||||||
describe('Group Model', () => {
|
describe('Group Model', () => {
|
||||||
let party, questLeader, participatingMember, nonParticipatingMember, undecidedMember;
|
let party, questLeader, participatingMember, nonParticipatingMember, undecidedMember;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
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';
|
import { each, find, findIndex } from 'lodash';
|
||||||
|
|
||||||
describe('Group Task Methods', () => {
|
describe('Group Task Methods', () => {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
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 { each } from 'lodash';
|
||||||
import { generateHistory } from '../../../../helpers/api-unit.helper.js';
|
import { generateHistory } from '../../../helpers/api-unit.helper.js';
|
||||||
|
|
||||||
describe('Task Model', () => {
|
describe('Task Model', () => {
|
||||||
let guild, leader, challenge, task;
|
let guild, leader, challenge, task;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import moment from 'moment';
|
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 common from '../../../../../website/common';
|
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', () => {
|
||||||
@@ -42,13 +42,48 @@ describe('User Model', () => {
|
|||||||
expect(userToJSON.stats.maxHealth).to.not.exist;
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
expect(userToJSON.stats.toNextLevel).to.not.exist;
|
expect(userToJSON.stats.toNextLevel).to.not.exist;
|
||||||
|
|
||||||
user.addComputedStatsToJSONObj(userToJSON.stats);
|
User.addComputedStatsToJSONObj(userToJSON.stats, userToJSON);
|
||||||
|
|
||||||
expect(userToJSON.stats.maxMP).to.exist;
|
expect(userToJSON.stats.maxMP).to.exist;
|
||||||
expect(userToJSON.stats.maxHealth).to.equal(common.maxHealth);
|
expect(userToJSON.stats.maxHealth).to.equal(common.maxHealth);
|
||||||
expect(userToJSON.stats.toNextLevel).to.equal(common.tnl(user.stats.lvl));
|
expect(userToJSON.stats.toNextLevel).to.equal(common.tnl(user.stats.lvl));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can transform user object without mongoose helpers', async () => {
|
||||||
|
let user = new User();
|
||||||
|
await user.save();
|
||||||
|
let userToJSON = await User.findById(user._id).lean().exec();
|
||||||
|
|
||||||
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
|
expect(userToJSON.stats.toNextLevel).to.not.exist;
|
||||||
|
expect(userToJSON.id).to.not.exist;
|
||||||
|
|
||||||
|
User.transformJSONUser(userToJSON);
|
||||||
|
|
||||||
|
expect(userToJSON.id).to.equal(userToJSON._id);
|
||||||
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
|
expect(userToJSON.stats.toNextLevel).to.not.exist;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can transform user object without mongoose helpers (including computed stats)', async () => {
|
||||||
|
let user = new User();
|
||||||
|
await user.save();
|
||||||
|
let userToJSON = await User.findById(user._id).lean().exec();
|
||||||
|
|
||||||
|
expect(userToJSON.stats.maxMP).to.not.exist;
|
||||||
|
expect(userToJSON.stats.maxHealth).to.not.exist;
|
||||||
|
expect(userToJSON.stats.toNextLevel).to.not.exist;
|
||||||
|
|
||||||
|
User.transformJSONUser(userToJSON, true);
|
||||||
|
|
||||||
|
expect(userToJSON.id).to.equal(userToJSON._id);
|
||||||
|
expect(userToJSON.stats.maxMP).to.exist;
|
||||||
|
expect(userToJSON.stats.maxHealth).to.equal(common.maxHealth);
|
||||||
|
expect(userToJSON.stats.toNextLevel).to.equal(common.tnl(user.stats.lvl));
|
||||||
|
});
|
||||||
|
|
||||||
context('notifications', () => {
|
context('notifications', () => {
|
||||||
it('can add notifications without data', () => {
|
it('can add notifications without data', () => {
|
||||||
let user = new User();
|
let user = new User();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { model as UserNotification } from '../../../../../website/server/models/userNotification';
|
import { model as UserNotification } from '../../../../website/server/models/userNotification';
|
||||||
|
|
||||||
describe('UserNotification Model', () => {
|
describe('UserNotification Model', () => {
|
||||||
context('convertNotificationsToSafeJson', () => {
|
context('convertNotificationsToSafeJson', () => {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
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 { 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', () => {
|
||||||
context('Instance Methods', () => {
|
context('Instance Methods', () => {
|
||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
sleep,
|
sleep,
|
||||||
checkExistence,
|
checkExistence,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('DELETE /challenges/:challengeId', () => {
|
describe('DELETE /challenges/:challengeId', () => {
|
||||||
@@ -41,6 +41,7 @@ describe('DELETE /challenges/:challengeId', () => {
|
|||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
|
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},
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId', () => {
|
describe('GET /challenges/:challengeId', () => {
|
||||||
@@ -33,9 +33,11 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
group = populatedGroup.group;
|
group = populatedGroup.group;
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return challenge data', async () => {
|
it('should return challenge data', async () => {
|
||||||
|
await challenge.sync();
|
||||||
let chal = await user.get(`/challenges/${challenge._id}`);
|
let 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);
|
||||||
@@ -80,6 +82,7 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
await members[0].post(`/challenges/${challenge._id}/join`);
|
await members[0].post(`/challenges/${challenge._id}/join`);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user doesn\'t have access to the challenge', async () => {
|
it('fails if user doesn\'t have access to the challenge', async () => {
|
||||||
@@ -134,6 +137,7 @@ describe('GET /challenges/:challengeId', () => {
|
|||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
await members[0].post(`/challenges/${challenge._id}/join`);
|
await members[0].post(`/challenges/${challenge._id}/join`);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails if user doesn\'t have access to the challenge', async () => {
|
it('fails if user doesn\'t have access to the challenge', async () => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
translate as t,
|
translate as t,
|
||||||
sleep,
|
sleep,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/export/csv', () => {
|
describe('GET /challenges/:challengeId/export/csv', () => {
|
||||||
@@ -24,6 +24,7 @@ describe('GET /challenges/:challengeId/export/csv', () => {
|
|||||||
members = populatedGroup.members;
|
members = populatedGroup.members;
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
await members[0].post(`/challenges/${challenge._id}/join`);
|
await members[0].post(`/challenges/${challenge._id}/join`);
|
||||||
await members[1].post(`/challenges/${challenge._id}/join`);
|
await members[1].post(`/challenges/${challenge._id}/join`);
|
||||||
await members[2].post(`/challenges/${challenge._id}/join`);
|
await members[2].post(`/challenges/${challenge._id}/join`);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateGroup,
|
generateGroup,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/members', () => {
|
describe('GET /challenges/:challengeId/members', () => {
|
||||||
@@ -45,6 +45,7 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
let leader = await generateUser({balance: 4});
|
let leader = await generateUser({balance: 4});
|
||||||
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(leader, group);
|
let challenge = await generateChallenge(leader, group);
|
||||||
|
await leader.post(`/challenges/${challenge._id}/join`);
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
let res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: leader._id,
|
_id: leader._id,
|
||||||
@@ -59,6 +60,7 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
let anotherUser = await generateUser({balance: 3});
|
let anotherUser = await generateUser({balance: 3});
|
||||||
let group = await generateGroup(anotherUser, {type: 'guild', privacy: 'public', name: generateUUID()});
|
let group = await generateGroup(anotherUser, {type: 'guild', privacy: 'public', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(anotherUser, group);
|
let challenge = await generateChallenge(anotherUser, group);
|
||||||
|
await anotherUser.post(`/challenges/${challenge._id}/join`);
|
||||||
let res = await user.get(`/challenges/${challenge._id}/members`);
|
let res = await user.get(`/challenges/${challenge._id}/members`);
|
||||||
expect(res[0]).to.eql({
|
expect(res[0]).to.eql({
|
||||||
_id: anotherUser._id,
|
_id: anotherUser._id,
|
||||||
@@ -72,6 +74,7 @@ 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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
let usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i++) {
|
||||||
@@ -90,6 +93,7 @@ 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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
let usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i++) {
|
||||||
@@ -108,6 +112,7 @@ 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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
let usersToGenerate = [];
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i = 0; i < 31; i++) {
|
||||||
@@ -127,6 +132,7 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
let usersToGenerate = [];
|
||||||
for (let i = 0; i < 57; i++) {
|
for (let i = 0; i < 57; i++) {
|
||||||
@@ -147,6 +153,7 @@ describe('GET /challenges/:challengeId/members', () => {
|
|||||||
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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
let usersToGenerate = [];
|
let usersToGenerate = [];
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('GET /challenges/:challengeId/members/:memberId', () => {
|
describe('GET /challenges/:challengeId/members/:memberId', () => {
|
||||||
@@ -50,6 +50,7 @@ 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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let anotherUser = await generateUser();
|
let anotherUser = await generateUser();
|
||||||
let member = await generateUser();
|
let 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({
|
||||||
@@ -62,6 +63,7 @@ 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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let member = await generateUser();
|
let 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,
|
||||||
@@ -74,6 +76,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
let groupLeader = await generateUser({balance: 4});
|
let groupLeader = await generateUser({balance: 4});
|
||||||
let group = await generateGroup(groupLeader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
let group = await generateGroup(groupLeader, {type: 'guild', privacy: 'public', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(groupLeader, group);
|
let challenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
let taskText = 'Test Text';
|
let 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}]);
|
||||||
|
|
||||||
@@ -86,6 +89,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
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}`);
|
let memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
|
||||||
@@ -98,6 +102,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
|
|||||||
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()});
|
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
|
||||||
let challenge = await generateChallenge(user, group);
|
let challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
let taskText = 'Test Text';
|
let taskText = 'Test Text';
|
||||||
await user.post(`/tasks/challenge/${challenge._id}`, [{
|
await user.post(`/tasks/challenge/${challenge._id}`, [{
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { TAVERN_ID } from '../../../../../website/common/script/constants';
|
import { TAVERN_ID } from '../../../../../website/common/script/constants';
|
||||||
|
|
||||||
describe('GET challenges/groups/:groupId', () => {
|
describe('GET challenges/groups/:groupId', () => {
|
||||||
@@ -25,7 +25,9 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return group challenges for non member with populated leader', async () => {
|
it('should return group challenges for non member with populated leader', async () => {
|
||||||
@@ -73,6 +75,7 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
let newChallenge = await generateChallenge(user, publicGuild);
|
||||||
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
|
|
||||||
@@ -99,7 +102,9 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prevent non-member from seeing challenges', async () => {
|
it('should prevent non-member from seeing challenges', async () => {
|
||||||
@@ -156,9 +161,12 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
slug: 'habitica_official',
|
slug: 'habitica_official',
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
await user.post(`/challenges/${officialChallenge._id}/join`);
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return official challenges first', async () => {
|
it('should return official challenges first', async () => {
|
||||||
@@ -178,6 +186,7 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
expect(foundChallengeIndex).to.eql(1);
|
expect(foundChallengeIndex).to.eql(1);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
let newChallenge = await generateChallenge(user, publicGuild);
|
||||||
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
|
||||||
|
|
||||||
@@ -203,7 +212,9 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prevent non-member from seeing challenges', async () => {
|
it('should prevent non-member from seeing challenges', async () => {
|
||||||
@@ -263,7 +274,9 @@ describe('GET challenges/groups/:groupId', () => {
|
|||||||
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`);
|
||||||
challenge2 = await generateChallenge(user, tavern, {prize: 1});
|
challenge2 = await generateChallenge(user, tavern, {prize: 1});
|
||||||
|
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 () => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('GET challenges/user', () => {
|
describe('GET challenges/user', () => {
|
||||||
context('no official challenges', () => {
|
context('no official challenges', () => {
|
||||||
@@ -24,7 +24,9 @@ describe('GET challenges/user', () => {
|
|||||||
nonMember = await generateUser();
|
nonMember = await generateUser();
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return challenges user has joined', async () => {
|
it('should return challenges user has joined', async () => {
|
||||||
@@ -146,6 +148,7 @@ describe('GET challenges/user', () => {
|
|||||||
expect(foundChallengeIndex).to.eql(0);
|
expect(foundChallengeIndex).to.eql(0);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
let newChallenge = await generateChallenge(user, publicGuild);
|
||||||
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get('/challenges/user');
|
challenges = await user.get('/challenges/user');
|
||||||
|
|
||||||
@@ -164,6 +167,7 @@ describe('GET challenges/user', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let privateChallenge = await generateChallenge(groupLeader, group);
|
let privateChallenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
|
||||||
|
|
||||||
let challenges = await nonMember.get('/challenges/user');
|
let challenges = await nonMember.get('/challenges/user');
|
||||||
|
|
||||||
@@ -198,9 +202,12 @@ describe('GET challenges/user', () => {
|
|||||||
slug: 'habitica_official',
|
slug: 'habitica_official',
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
await user.post(`/challenges/${officialChallenge._id}/join`);
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
challenge2 = await generateChallenge(user, group);
|
challenge2 = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge2._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return official challenges first', async () => {
|
it('should return official challenges first', async () => {
|
||||||
@@ -220,6 +227,7 @@ describe('GET challenges/user', () => {
|
|||||||
expect(foundChallengeIndex).to.eql(1);
|
expect(foundChallengeIndex).to.eql(1);
|
||||||
|
|
||||||
let newChallenge = await generateChallenge(user, publicGuild);
|
let newChallenge = await generateChallenge(user, publicGuild);
|
||||||
|
await user.post(`/challenges/${newChallenge._id}/join`);
|
||||||
|
|
||||||
challenges = await user.get('/challenges/user');
|
challenges = await user.get('/challenges/user');
|
||||||
|
|
||||||
@@ -252,12 +260,14 @@ describe('GET challenges/user', () => {
|
|||||||
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) {
|
||||||
await generateChallenge(user, group); // eslint-disable-line
|
let challenge = await generateChallenge(user, group); // eslint-disable-line
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`); // eslint-disable-line
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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`);
|
||||||
const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`);
|
const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`);
|
||||||
|
|
||||||
expect(challenges[0]._id).to.eql(categoryChallenge._id);
|
expect(challenges[0]._id).to.eql(categoryChallenge._id);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('POST /challenges', () => {
|
describe('POST /challenges', () => {
|
||||||
@@ -242,7 +242,6 @@ 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;
|
let oldChallengeCount = group.challengeCount;
|
||||||
let oldUserBalance = groupLeader.balance;
|
let oldUserBalance = groupLeader.balance;
|
||||||
let oldUserChallenges = groupLeader.challenges;
|
|
||||||
let oldGroupBalance = group.balance;
|
let oldGroupBalance = group.balance;
|
||||||
|
|
||||||
await expect(groupLeader.post('/challenges', {
|
await expect(groupLeader.post('/challenges', {
|
||||||
@@ -260,7 +259,6 @@ describe('POST /challenges', () => {
|
|||||||
expect(group.challengeCount).to.eql(oldChallengeCount);
|
expect(group.challengeCount).to.eql(oldChallengeCount);
|
||||||
expect(group.balance).to.eql(oldGroupBalance);
|
expect(group.balance).to.eql(oldGroupBalance);
|
||||||
expect(groupLeader.balance).to.eql(oldUserBalance);
|
expect(groupLeader.balance).to.eql(oldUserBalance);
|
||||||
expect(groupLeader.challenges).to.eql(oldUserChallenges);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets all properites of the challenge as passed', async () => {
|
it('sets all properites of the challenge as passed', async () => {
|
||||||
@@ -291,18 +289,19 @@ describe('POST /challenges', () => {
|
|||||||
name: group.name,
|
name: group.name,
|
||||||
type: group.type,
|
type: group.type,
|
||||||
});
|
});
|
||||||
expect(challenge.memberCount).to.eql(1);
|
expect(challenge.memberCount).to.eql(0);
|
||||||
expect(challenge.prize).to.eql(prize);
|
expect(challenge.prize).to.eql(prize);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds challenge to creator\'s challenges', async () => {
|
it('does not add challenge to creator\'s challenges', async () => {
|
||||||
let challenge = await groupLeader.post('/challenges', {
|
await groupLeader.post('/challenges', {
|
||||||
group: group._id,
|
group: group._id,
|
||||||
name: 'Test Challenge',
|
name: 'Test Challenge',
|
||||||
shortName: 'TC Label',
|
shortName: 'TC Label',
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(groupLeader.sync()).to.eventually.have.property('challenges').to.include(challenge._id);
|
await groupLeader.sync();
|
||||||
|
expect(groupLeader.challenges.length).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('awards achievement if this is creator\'s first challenge', async () => {
|
it('awards achievement if this is creator\'s first challenge', async () => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/join', () => {
|
describe('POST /challenges/:challengeId/join', () => {
|
||||||
@@ -43,6 +43,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
authorizedUser = populatedGroup.members[0];
|
authorizedUser = populatedGroup.members[0];
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when user doesn\'t have permissions to access the challenge', async () => {
|
it('returns an error when user doesn\'t have permissions to access the challenge', async () => {
|
||||||
@@ -91,6 +92,7 @@ describe('POST /challenges/:challengeId/join', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('increases memberCount of challenge', async () => {
|
it('increases memberCount of challenge', async () => {
|
||||||
|
await challenge.sync();
|
||||||
let oldMemberCount = challenge.memberCount;
|
let oldMemberCount = challenge.memberCount;
|
||||||
|
|
||||||
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
await authorizedUser.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/leave', () => {
|
describe('POST /challenges/:challengeId/leave', () => {
|
||||||
@@ -48,6 +48,7 @@ describe('POST /challenges/:challengeId/leave', () => {
|
|||||||
notInGroupLeavingUser = populatedGroup.members[2];
|
notInGroupLeavingUser = populatedGroup.members[2];
|
||||||
|
|
||||||
challenge = await generateChallenge(groupLeader, group);
|
challenge = await generateChallenge(groupLeader, group);
|
||||||
|
await groupLeader.post(`/challenges/${challenge._id}/join`);
|
||||||
|
|
||||||
taskText = 'A challenge task text';
|
taskText = 'A challenge task text';
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
sleep,
|
sleep,
|
||||||
checkExistence,
|
checkExistence,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
||||||
@@ -58,6 +58,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
|
|||||||
challenge = await generateChallenge(groupLeader, group, {
|
challenge = await generateChallenge(groupLeader, group, {
|
||||||
prize: 1,
|
prize: 1,
|
||||||
});
|
});
|
||||||
|
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},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /challenges/:challengeId/clone', () => {
|
describe('POST /challenges/:challengeId/clone', () => {
|
||||||
it('clones a challenge', async () => {
|
it('clones a challenge', async () => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateChallenge,
|
generateChallenge,
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('PUT /challenges/:challengeId', () => {
|
describe('PUT /challenges/:challengeId', () => {
|
||||||
let privateGuild, user, nonMember, challenge, member;
|
let privateGuild, user, nonMember, challenge, member;
|
||||||
@@ -25,6 +25,7 @@ describe('PUT /challenges/:challengeId', () => {
|
|||||||
member = members[0];
|
member = members[0];
|
||||||
|
|
||||||
challenge = await generateChallenge(user, group);
|
challenge = await generateChallenge(user, group);
|
||||||
|
await user.post(`/challenges/${challenge._id}/join`);
|
||||||
await member.post(`/challenges/${challenge._id}/join`);
|
await member.post(`/challenges/${challenge._id}/join`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
describe('DELETE /groups/:groupId/chat/:chatId', () => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
generateGroup,
|
generateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('GET /groups/:groupId/chat', () => {
|
describe('GET /groups/:groupId/chat', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { find } from 'lodash';
|
import { find } from 'lodash';
|
||||||
|
|
||||||
describe('POST /chat/:chatId/flag', () => {
|
describe('POST /chat/:chatId/flag', () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { find } from 'lodash';
|
import { find } from 'lodash';
|
||||||
|
|
||||||
describe('POST /chat/:chatId/like', () => {
|
describe('POST /chat/:chatId/like', () => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
translate as t,
|
translate as t,
|
||||||
sleep,
|
sleep,
|
||||||
server,
|
server,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
SPAM_MESSAGE_LIMIT,
|
SPAM_MESSAGE_LIMIT,
|
||||||
SPAM_MIN_EXEMPT_CONTRIB_LEVEL,
|
SPAM_MIN_EXEMPT_CONTRIB_LEVEL,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
sleep,
|
sleep,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /groups/:id/chat/seen', () => {
|
describe('POST /groups/:id/chat/seen', () => {
|
||||||
context('Guild', () => {
|
context('Guild', () => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
createAndPopulateGroup,
|
createAndPopulateGroup,
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import config from '../../../../../config.json';
|
import config from '../../../../../config.json';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
requester,
|
requester,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import i18n from '../../../../../website/common/script/i18n';
|
import i18n from '../../../../../website/common/script/i18n';
|
||||||
|
|
||||||
describe('GET /content', () => {
|
describe('GET /content', () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import apiError from '../../../../../website/server/libs/apiError';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
describe('GET /coupons/', () => {
|
describe('GET /coupons/', () => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /coupons/enter/:code', () => {
|
describe('POST /coupons/enter/:code', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import couponCode from 'coupon-code';
|
import couponCode from 'coupon-code';
|
||||||
import apiError from '../../../../../website/server/libs/apiError';
|
import apiError from '../../../../../website/server/libs/apiError';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
requester,
|
requester,
|
||||||
resetHabiticaDB,
|
resetHabiticaDB,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /coupons/validate/:code', () => {
|
describe('POST /coupons/validate/:code', () => {
|
||||||
let api = requester();
|
let api = requester();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
xdescribe('GET /export/avatar-:memberId.html', () => {
|
xdescribe('GET /export/avatar-:memberId.html', () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import {
|
import {
|
||||||
updateDocument,
|
updateDocument,
|
||||||
} from '../../../../helpers/mongo';
|
} from '../../../../helpers/mongo';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('GET /export/inbox.html', () => {
|
describe('GET /export/inbox.html', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
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 () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
import xml2js from 'xml2js';
|
import xml2js from 'xml2js';
|
||||||
import util from 'util';
|
import util from 'util';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-v3-integration.helper';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('POST /debug/add-hourglass', () => {
|
describe('POST /debug/add-hourglass', () => {
|
||||||
let userToGetHourGlass;
|
let userToGetHourGlass;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user