mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 13:17:24 +01:00
Fix various tests
This commit is contained in:
committed by
Sabe Jones
parent
3540a274b3
commit
fb56f7df20
38
test/api/unit/middlewares/ensureTimeTravelMode.js
Normal file
38
test/api/unit/middlewares/ensureTimeTravelMode.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* eslint-disable global-require */
|
||||||
|
import nconf from 'nconf';
|
||||||
|
import {
|
||||||
|
generateRes,
|
||||||
|
generateReq,
|
||||||
|
generateNext,
|
||||||
|
} from '../../../helpers/api-unit.helper';
|
||||||
|
import ensureDevelpmentMode from '../../../../website/server/middlewares/ensureDevelpmentMode';
|
||||||
|
import { NotFound } from '../../../../website/server/libs/errors';
|
||||||
|
|
||||||
|
describe('timetravelMode middleware', () => {
|
||||||
|
let res; let req; let
|
||||||
|
next;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
res = generateRes();
|
||||||
|
req = generateReq();
|
||||||
|
next = generateNext();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns not found when not in time travel mode', () => {
|
||||||
|
sandbox.stub(nconf, 'get').withArgs('ENABLE_TIME_TRAVEL').returns(true);
|
||||||
|
|
||||||
|
ensureDevelpmentMode(req, res, next);
|
||||||
|
|
||||||
|
const calledWith = next.getCall(0).args;
|
||||||
|
expect(calledWith[0] instanceof NotFound).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes when in time travel mode', () => {
|
||||||
|
sandbox.stub(nconf, 'get').withArgs('ENABLE_TIME_TRAVEL').returns(false);
|
||||||
|
|
||||||
|
ensureDevelpmentMode(req, res, next);
|
||||||
|
|
||||||
|
expect(next).to.be.calledOnce;
|
||||||
|
expect(next.args[0]).to.be.empty;
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import nconf from 'nconf';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
|
describe('GET /debug/time-travel-time', () => {
|
||||||
|
let user;
|
||||||
|
before(async () => {
|
||||||
|
user = await generateUser({ permissions: { fullAccess: true } });
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the shifted time', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const result = await user.get('/debug/time-travel-time');
|
||||||
|
expect(result.time).to.exist;
|
||||||
|
await user.post('/debug/jump-time', { disable: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when the user is not an admin', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const regularUser = await generateUser();
|
||||||
|
await expect(regularUser.get('/debug/time-travel-time'))
|
||||||
|
.eventually.be.rejected.and.to.deep.equal({
|
||||||
|
code: 400,
|
||||||
|
error: 'BadRequest',
|
||||||
|
message: 'You do not have permission to time travel.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when not in time travel mode', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', false);
|
||||||
|
|
||||||
|
await expect(user.get('/debug/time-travel-time'))
|
||||||
|
.eventually.be.rejected.and.to.deep.equal({
|
||||||
|
code: 404,
|
||||||
|
error: 'NotFound',
|
||||||
|
message: 'Not found.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
75
test/api/v3/integration/debug/POST-debug_jumpTime.test.js
Normal file
75
test/api/v3/integration/debug/POST-debug_jumpTime.test.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import nconf from 'nconf';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
|
describe('POST /debug/jump-time', () => {
|
||||||
|
let user;
|
||||||
|
let today;
|
||||||
|
before(async () => {
|
||||||
|
user = await generateUser({ permissions: { fullAccess: true } });
|
||||||
|
today = new Date();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
await user.post('/debug/jump-time', { disable: true });
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Jumps forward', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const resultDate = new Date((await user.post('/debug/jump-time', { reset: true })).time);
|
||||||
|
expect(resultDate.getDate()).to.eql(today.getDate());
|
||||||
|
expect(resultDate.getMonth()).to.eql(today.getMonth());
|
||||||
|
expect(resultDate.getFullYear()).to.eql(today.getFullYear());
|
||||||
|
const newResultDate = new Date((await user.post('/debug/jump-time', { offsetDays: 1 })).time);
|
||||||
|
expect(newResultDate.getDate()).to.eql(today.getDate() + 1);
|
||||||
|
expect(newResultDate.getMonth()).to.eql(today.getMonth());
|
||||||
|
expect(newResultDate.getFullYear()).to.eql(today.getFullYear());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('jumps back', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const resultDate = new Date((await user.post('/debug/jump-time', { reset: true })).time);
|
||||||
|
expect(resultDate.getDate()).to.eql(today.getDate());
|
||||||
|
expect(resultDate.getMonth()).to.eql(today.getMonth());
|
||||||
|
expect(resultDate.getFullYear()).to.eql(today.getFullYear());
|
||||||
|
const newResultDate = new Date((await user.post('/debug/jump-time', { offsetDays: -1 })).time);
|
||||||
|
expect(newResultDate.getDate()).to.eql(today.getDate() - 1);
|
||||||
|
expect(newResultDate.getMonth()).to.eql(today.getMonth());
|
||||||
|
expect(newResultDate.getFullYear()).to.eql(today.getFullYear());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can jump a lot', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const resultDate = new Date((await user.post('/debug/jump-time', { reset: true })).time);
|
||||||
|
expect(resultDate.getDate()).to.eql(today.getDate());
|
||||||
|
expect(resultDate.getMonth()).to.eql(today.getMonth());
|
||||||
|
expect(resultDate.getFullYear()).to.eql(today.getFullYear());
|
||||||
|
const newResultDate = new Date((await user.post('/debug/jump-time', { offsetDays: 355 })).time);
|
||||||
|
expect(newResultDate.getFullYear()).to.eql(today.getFullYear() + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when the user is not an admin', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', true);
|
||||||
|
const regularUser = await generateUser();
|
||||||
|
await expect(regularUser.post('/debug/jump-time', { offsetDays: 1 }))
|
||||||
|
.eventually.be.rejected.and.to.deep.equal({
|
||||||
|
code: 400,
|
||||||
|
error: 'BadRequest',
|
||||||
|
message: 'You do not have permission to time travel.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when not in time travel mode', async () => {
|
||||||
|
nconf.set('ENABLE_TIME_TRAVEL', false);
|
||||||
|
|
||||||
|
await expect(user.post('/debug/jump-time', { offsetDays: 1 }))
|
||||||
|
.eventually.be.rejected.and.to.deep.equal({
|
||||||
|
code: 404,
|
||||||
|
error: 'NotFound',
|
||||||
|
message: 'Not found.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -10,6 +10,7 @@ import { BuyQuestWithGemOperation } from '../../../../website/common/script/ops/
|
|||||||
|
|
||||||
describe('shared.ops.buyQuestGems', () => {
|
describe('shared.ops.buyQuestGems', () => {
|
||||||
let user;
|
let user;
|
||||||
|
let clock;
|
||||||
const goldPoints = 40;
|
const goldPoints = 40;
|
||||||
const analytics = { track () {} };
|
const analytics = { track () {} };
|
||||||
|
|
||||||
@@ -26,11 +27,13 @@ describe('shared.ops.buyQuestGems', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sinon.stub(analytics, 'track');
|
sinon.stub(analytics, 'track');
|
||||||
sinon.spy(pinnedGearUtils, 'removeItemByPath');
|
sinon.spy(pinnedGearUtils, 'removeItemByPath');
|
||||||
|
clock = sinon.useFakeTimers(new Date('2024-01-16'));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
analytics.track.restore();
|
analytics.track.restore();
|
||||||
pinnedGearUtils.removeItemByPath.restore();
|
pinnedGearUtils.removeItemByPath.restore();
|
||||||
|
clock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
context('single purchase', () => {
|
context('single purchase', () => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
describe('shared.ops.purchase', () => {
|
describe('shared.ops.purchase', () => {
|
||||||
const SEASONAL_FOOD = moment().isBefore('2021-11-02T20:00-04:00') ? 'Candy_Base' : 'Meat';
|
const SEASONAL_FOOD = moment().isBefore('2021-11-02T20:00-04:00') ? 'Candy_Base' : 'Meat';
|
||||||
let user;
|
let user;
|
||||||
|
let clock;
|
||||||
const goldPoints = 40;
|
const goldPoints = 40;
|
||||||
const analytics = { track () {} };
|
const analytics = { track () {} };
|
||||||
|
|
||||||
@@ -25,11 +26,13 @@ describe('shared.ops.purchase', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sinon.stub(analytics, 'track');
|
sinon.stub(analytics, 'track');
|
||||||
sinon.spy(pinnedGearUtils, 'removeItemByPath');
|
sinon.spy(pinnedGearUtils, 'removeItemByPath');
|
||||||
|
clock = sandbox.useFakeTimers(new Date('2024-01-10'));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
analytics.track.restore();
|
analytics.track.restore();
|
||||||
pinnedGearUtils.removeItemByPath.restore();
|
pinnedGearUtils.removeItemByPath.restore();
|
||||||
|
clock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
context('failure conditions', () => {
|
context('failure conditions', () => {
|
||||||
@@ -62,7 +65,7 @@ describe('shared.ops.purchase', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns error when unknown item is requested', async () => {
|
it.only('returns error when unknown item is requested', async () => {
|
||||||
try {
|
try {
|
||||||
await purchase(user, { params: { type: 'gear', key: 'randomKey' } });
|
await purchase(user, { params: { type: 'gear', key: 'randomKey' } });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -82,7 +85,7 @@ describe('shared.ops.purchase', () => {
|
|||||||
|
|
||||||
it('returns error when user does not have enough gems to buy an item', async () => {
|
it('returns error when user does not have enough gems to buy an item', async () => {
|
||||||
try {
|
try {
|
||||||
await purchase(user, { params: { type: 'gear', key: 'headAccessory_special_wolfEars' } });
|
await purchase(user, { params: { type: 'gear', key: 'shield_special_winter2019Healer' } });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
expect(err.message).to.equal(i18n.t('notEnoughGems'));
|
expect(err.message).to.equal(i18n.t('notEnoughGems'));
|
||||||
@@ -150,7 +153,7 @@ describe('shared.ops.purchase', () => {
|
|||||||
user.pinnedItems.push({ type: 'eggs', key: 'Wolf' });
|
user.pinnedItems.push({ type: 'eggs', key: 'Wolf' });
|
||||||
user.pinnedItems.push({ type: 'hatchingPotions', key: 'Base' });
|
user.pinnedItems.push({ type: 'hatchingPotions', key: 'Base' });
|
||||||
user.pinnedItems.push({ type: 'food', key: SEASONAL_FOOD });
|
user.pinnedItems.push({ type: 'food', key: SEASONAL_FOOD });
|
||||||
user.pinnedItems.push({ type: 'gear', key: 'headAccessory_special_tigerEars' });
|
user.pinnedItems.push({ type: 'gear', key: 'shield_special_winter2019Healer' });
|
||||||
user.pinnedItems.push({ type: 'bundles', key: 'featheredFriends' });
|
user.pinnedItems.push({ type: 'bundles', key: 'featheredFriends' });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,7 +190,7 @@ describe('shared.ops.purchase', () => {
|
|||||||
|
|
||||||
it('purchases gear', async () => {
|
it('purchases gear', async () => {
|
||||||
const type = 'gear';
|
const type = 'gear';
|
||||||
const key = 'headAccessory_special_tigerEars';
|
const key = 'shield_special_winter2019Healer';
|
||||||
|
|
||||||
await purchase(user, { params: { type, key } });
|
await purchase(user, { params: { type, key } });
|
||||||
|
|
||||||
@@ -197,7 +200,8 @@ describe('shared.ops.purchase', () => {
|
|||||||
|
|
||||||
it('purchases quest bundles', async () => {
|
it('purchases quest bundles', async () => {
|
||||||
const startingBalance = user.balance;
|
const startingBalance = user.balance;
|
||||||
const clock = sandbox.useFakeTimers(moment('2024-03-20').valueOf());
|
clock.restore();
|
||||||
|
clock = sandbox.useFakeTimers(moment('2022-03-10').valueOf());
|
||||||
const type = 'bundles';
|
const type = 'bundles';
|
||||||
const key = 'cuddleBuddies';
|
const key = 'cuddleBuddies';
|
||||||
const price = 1.75;
|
const price = 1.75;
|
||||||
@@ -216,7 +220,6 @@ describe('shared.ops.purchase', () => {
|
|||||||
expect(user.balance).to.equal(startingBalance - price);
|
expect(user.balance).to.equal(startingBalance - price);
|
||||||
|
|
||||||
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
|
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
|
||||||
clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ import get from 'lodash/get';
|
|||||||
import unlock from '../../../website/common/script/ops/unlock';
|
import unlock from '../../../website/common/script/ops/unlock';
|
||||||
import i18n from '../../../website/common/script/i18n';
|
import i18n from '../../../website/common/script/i18n';
|
||||||
import { generateUser } from '../../helpers/common.helper';
|
import { generateUser } from '../../helpers/common.helper';
|
||||||
import { NotAuthorized, BadRequest } from '../../../website/common/script/libs/errors';
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
BadRequest,
|
||||||
|
} from '../../../website/common/script/libs/errors';
|
||||||
|
|
||||||
describe('shared.ops.unlock', () => {
|
describe('shared.ops.unlock', () => {
|
||||||
let user;
|
let user;
|
||||||
|
let clock;
|
||||||
const unlockPath = 'shirt.convict,shirt.cross,shirt.fire,shirt.horizon,shirt.ocean,shirt.purple,shirt.rainbow,shirt.redblue,shirt.thunder,shirt.tropical,shirt.zombie';
|
const unlockPath = 'shirt.convict,shirt.cross,shirt.fire,shirt.horizon,shirt.ocean,shirt.purple,shirt.rainbow,shirt.redblue,shirt.thunder,shirt.tropical,shirt.zombie';
|
||||||
const unlockGearSetPath = 'items.gear.owned.headAccessory_special_bearEars,items.gear.owned.headAccessory_special_cactusEars,items.gear.owned.headAccessory_special_foxEars,items.gear.owned.headAccessory_special_lionEars,items.gear.owned.headAccessory_special_pandaEars,items.gear.owned.headAccessory_special_pigEars,items.gear.owned.headAccessory_special_tigerEars,items.gear.owned.headAccessory_special_wolfEars';
|
const unlockGearSetPath = 'items.gear.owned.headAccessory_special_bearEars,items.gear.owned.headAccessory_special_cactusEars,items.gear.owned.headAccessory_special_foxEars,items.gear.owned.headAccessory_special_lionEars,items.gear.owned.headAccessory_special_pandaEars,items.gear.owned.headAccessory_special_pigEars,items.gear.owned.headAccessory_special_tigerEars,items.gear.owned.headAccessory_special_wolfEars';
|
||||||
const backgroundUnlockPath = 'background.giant_florals';
|
const backgroundUnlockPath = 'background.giant_florals';
|
||||||
const backgroundSetUnlockPath = 'background.archery_range,background.giant_florals,background.rainbows_end';
|
|
||||||
const hairUnlockPath = 'hair.color.rainbow,hair.color.yellow,hair.color.green,hair.color.purple,hair.color.blue,hair.color.TRUred';
|
const hairUnlockPath = 'hair.color.rainbow,hair.color.yellow,hair.color.green,hair.color.purple,hair.color.blue,hair.color.TRUred';
|
||||||
const facialHairUnlockPath = 'hair.mustache.1,hair.mustache.2,hair.beard.1,hair.beard.2,hair.beard.3';
|
const facialHairUnlockPath = 'hair.mustache.1,hair.mustache.2,hair.beard.1,hair.beard.2,hair.beard.3';
|
||||||
const usersStartingGems = 50 / 4;
|
const usersStartingGems = 50 / 4;
|
||||||
@@ -17,6 +20,11 @@ describe('shared.ops.unlock', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = generateUser();
|
user = generateUser();
|
||||||
user.balance = usersStartingGems;
|
user.balance = usersStartingGems;
|
||||||
|
clock = sandbox.useFakeTimers(new Date('2024-04-10'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
clock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when path is not provided', async () => {
|
it('returns an error when path is not provided', async () => {
|
||||||
@@ -31,7 +39,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
it('does not unlock lost gear', async () => {
|
it('does not unlock lost gear', async () => {
|
||||||
user.items.gear.owned.headAccessory_special_bearEars = false;
|
user.items.gear.owned.headAccessory_special_bearEars = false;
|
||||||
|
|
||||||
await unlock(user, { query: { path: 'items.gear.owned.headAccessory_special_bearEars' } });
|
await unlock(user, {
|
||||||
|
query: { path: 'items.gear.owned.headAccessory_special_bearEars' },
|
||||||
|
});
|
||||||
|
|
||||||
expect(user.balance).to.equal(usersStartingGems);
|
expect(user.balance).to.equal(usersStartingGems);
|
||||||
});
|
});
|
||||||
@@ -95,7 +105,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
|
|
||||||
it('returns an error if gear is not from the animal set', async () => {
|
it('returns an error if gear is not from the animal set', async () => {
|
||||||
try {
|
try {
|
||||||
await unlock(user, { query: { path: 'items.gear.owned.back_mystery_202004' } });
|
await unlock(user, {
|
||||||
|
query: { path: 'items.gear.owned.back_mystery_202004' },
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).to.be.an.instanceof(BadRequest);
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||||
@@ -163,7 +175,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
|
|
||||||
await unlock(user, { query: { path: backgroundUnlockPath } });
|
await unlock(user, { query: { path: backgroundUnlockPath } });
|
||||||
const afterBalance = user.balance;
|
const afterBalance = user.balance;
|
||||||
const response = await unlock(user, { query: { path: backgroundUnlockPath } });
|
const response = await unlock(user, {
|
||||||
|
query: { path: backgroundUnlockPath },
|
||||||
|
});
|
||||||
expect(user.balance).to.equal(afterBalance); // do not bill twice
|
expect(user.balance).to.equal(afterBalance); // do not bill twice
|
||||||
|
|
||||||
expect(response.message).to.not.exist;
|
expect(response.message).to.not.exist;
|
||||||
@@ -176,7 +190,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
await unlock(user, { query: { path: backgroundUnlockPath } }); // unlock
|
await unlock(user, { query: { path: backgroundUnlockPath } }); // unlock
|
||||||
const afterBalance = user.balance;
|
const afterBalance = user.balance;
|
||||||
await unlock(user, { query: { path: backgroundUnlockPath } }); // equip
|
await unlock(user, { query: { path: backgroundUnlockPath } }); // equip
|
||||||
const response = await unlock(user, { query: { path: backgroundUnlockPath } });
|
const response = await unlock(user, {
|
||||||
|
query: { path: backgroundUnlockPath },
|
||||||
|
});
|
||||||
expect(user.balance).to.equal(afterBalance); // do not bill twice
|
expect(user.balance).to.equal(afterBalance); // do not bill twice
|
||||||
|
|
||||||
expect(response.message).to.not.exist;
|
expect(response.message).to.not.exist;
|
||||||
@@ -192,8 +208,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
individualPaths.forEach(path => {
|
individualPaths.forEach(path => {
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
});
|
});
|
||||||
expect(Object.keys(user.purchased.shirt).length)
|
expect(Object.keys(user.purchased.shirt).length).to.equal(
|
||||||
.to.equal(initialShirts + individualPaths.length);
|
initialShirts + individualPaths.length,
|
||||||
|
);
|
||||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -208,8 +225,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
individualPaths.forEach(path => {
|
individualPaths.forEach(path => {
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
});
|
});
|
||||||
expect(Object.keys(user.purchased.hair.color).length)
|
expect(Object.keys(user.purchased.hair.color).length).to.equal(
|
||||||
.to.equal(initialHairColors + individualPaths.length);
|
initialHairColors + individualPaths.length,
|
||||||
|
);
|
||||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -219,21 +237,28 @@ describe('shared.ops.unlock', () => {
|
|||||||
|
|
||||||
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
|
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
|
||||||
const initialBeard = Object.keys(user.purchased.hair.mustache).length;
|
const initialBeard = Object.keys(user.purchased.hair.mustache).length;
|
||||||
const [, message] = await unlock(user, { query: { path: facialHairUnlockPath } });
|
const [, message] = await unlock(user, {
|
||||||
|
query: { path: facialHairUnlockPath },
|
||||||
|
});
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
const individualPaths = facialHairUnlockPath.split(',');
|
const individualPaths = facialHairUnlockPath.split(',');
|
||||||
individualPaths.forEach(path => {
|
individualPaths.forEach(path => {
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
});
|
});
|
||||||
expect(Object.keys(user.purchased.hair.mustache).length + Object.keys(user.purchased.hair.beard).length) // eslint-disable-line max-len
|
expect(
|
||||||
|
Object.keys(user.purchased.hair.mustache).length
|
||||||
|
+ Object.keys(user.purchased.hair.beard).length,
|
||||||
|
) // eslint-disable-line max-len
|
||||||
.to.equal(initialMustache + initialBeard + individualPaths.length);
|
.to.equal(initialMustache + initialBeard + individualPaths.length);
|
||||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unlocks a full set of gear', async () => {
|
it('unlocks a full set of gear', async () => {
|
||||||
const initialGear = Object.keys(user.items.gear.owned).length;
|
const initialGear = Object.keys(user.items.gear.owned).length;
|
||||||
const [, message] = await unlock(user, { query: { path: unlockGearSetPath } });
|
const [, message] = await unlock(user, {
|
||||||
|
query: { path: unlockGearSetPath },
|
||||||
|
});
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
|
|
||||||
@@ -241,32 +266,21 @@ describe('shared.ops.unlock', () => {
|
|||||||
individualPaths.forEach(path => {
|
individualPaths.forEach(path => {
|
||||||
expect(get(user, path)).to.be.true;
|
expect(get(user, path)).to.be.true;
|
||||||
});
|
});
|
||||||
expect(Object.keys(user.items.gear.owned).length)
|
expect(Object.keys(user.items.gear.owned).length).to.equal(
|
||||||
.to.equal(initialGear + individualPaths.length);
|
initialGear + individualPaths.length,
|
||||||
|
);
|
||||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unlocks a full set of backgrounds', async () => {
|
|
||||||
const initialBackgrounds = Object.keys(user.purchased.background).length;
|
|
||||||
const [, message] = await unlock(user, { query: { path: backgroundSetUnlockPath } });
|
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
|
||||||
const individualPaths = backgroundSetUnlockPath.split(',');
|
|
||||||
individualPaths.forEach(path => {
|
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
|
||||||
});
|
|
||||||
expect(Object.keys(user.purchased.background).length)
|
|
||||||
.to.equal(initialBackgrounds + individualPaths.length);
|
|
||||||
expect(user.balance).to.equal(usersStartingGems - 3.75);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('unlocks an item (appearance)', async () => {
|
it('unlocks an item (appearance)', async () => {
|
||||||
const path = unlockPath.split(',')[0];
|
const path = unlockPath.split(',')[0];
|
||||||
const initialShirts = Object.keys(user.purchased.shirt).length;
|
const initialShirts = Object.keys(user.purchased.shirt).length;
|
||||||
const [, message] = await unlock(user, { query: { path } });
|
const [, message] = await unlock(user, { query: { path } });
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
expect(Object.keys(user.purchased.shirt).length).to.equal(initialShirts + 1);
|
expect(Object.keys(user.purchased.shirt).length).to.equal(
|
||||||
|
initialShirts + 1,
|
||||||
|
);
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||||
});
|
});
|
||||||
@@ -279,7 +293,9 @@ describe('shared.ops.unlock', () => {
|
|||||||
const [, message] = await unlock(user, { query: { path } });
|
const [, message] = await unlock(user, { query: { path } });
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
expect(Object.keys(user.purchased.hair.color).length).to.equal(initialColorHair + 1);
|
expect(Object.keys(user.purchased.hair.color).length).to.equal(
|
||||||
|
initialColorHair + 1,
|
||||||
|
);
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||||
});
|
});
|
||||||
@@ -295,8 +311,12 @@ describe('shared.ops.unlock', () => {
|
|||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
|
|
||||||
expect(Object.keys(user.purchased.hair.mustache).length).to.equal(initialMustache + 1);
|
expect(Object.keys(user.purchased.hair.mustache).length).to.equal(
|
||||||
expect(Object.keys(user.purchased.hair.beard).length).to.equal(initialBeard);
|
initialMustache + 1,
|
||||||
|
);
|
||||||
|
expect(Object.keys(user.purchased.hair.beard).length).to.equal(
|
||||||
|
initialBeard,
|
||||||
|
);
|
||||||
|
|
||||||
expect(get(user.purchased, path)).to.be.true;
|
expect(get(user.purchased, path)).to.be.true;
|
||||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||||
@@ -315,10 +335,14 @@ describe('shared.ops.unlock', () => {
|
|||||||
|
|
||||||
it('unlocks an item (background)', async () => {
|
it('unlocks an item (background)', async () => {
|
||||||
const initialBackgrounds = Object.keys(user.purchased.background).length;
|
const initialBackgrounds = Object.keys(user.purchased.background).length;
|
||||||
const [, message] = await unlock(user, { query: { path: backgroundUnlockPath } });
|
const [, message] = await unlock(user, {
|
||||||
|
query: { path: backgroundUnlockPath },
|
||||||
|
});
|
||||||
|
|
||||||
expect(message).to.equal(i18n.t('unlocked'));
|
expect(message).to.equal(i18n.t('unlocked'));
|
||||||
expect(Object.keys(user.purchased.background).length).to.equal(initialBackgrounds + 1);
|
expect(Object.keys(user.purchased.background).length).to.equal(
|
||||||
|
initialBackgrounds + 1,
|
||||||
|
);
|
||||||
expect(get(user.purchased, backgroundUnlockPath)).to.be.true;
|
expect(get(user.purchased, backgroundUnlockPath)).to.be.true;
|
||||||
expect(user.balance).to.equal(usersStartingGems - 1.75);
|
expect(user.balance).to.equal(usersStartingGems - 1.75);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -292,28 +292,35 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="ENABLE_TIME_TRAVEL && user.permissions.fullAccess"
|
v-if="ENABLE_TIME_TRAVEL && user.permissions.fullAccess"
|
||||||
:key="lastTimeJump">
|
:key="lastTimeJump"
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(-1)">-1 Day</a>
|
@click="jumpTime(-1)"
|
||||||
|
>-1 Day</a>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(-7)">-7 Days</a>
|
@click="jumpTime(-7)"
|
||||||
|
>-7 Days</a>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(-30)">-30 Days</a>
|
@click="jumpTime(-30)"
|
||||||
|
>-30 Days</a>
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
Time Traveling! It is {{ new Date().toLocaleDateString() }}
|
Time Traveling! It is {{ new Date().toLocaleDateString() }}
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(1)">+1 Day</a>
|
@click="jumpTime(1)"
|
||||||
|
>+1 Day</a>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(7)">+7 Days</a>
|
@click="jumpTime(7)"
|
||||||
|
>+7 Days</a>
|
||||||
<a
|
<a
|
||||||
class="btn btn-secondary mr-1"
|
class="btn btn-secondary mr-1"
|
||||||
@click="jumpTime(30)">+30 Days</a>
|
@click="jumpTime(30)"
|
||||||
|
>+30 Days</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ import gemsBlock from './gems';
|
|||||||
import faq from './faq';
|
import faq from './faq';
|
||||||
import timeTravelers from './time-travelers';
|
import timeTravelers from './time-travelers';
|
||||||
|
|
||||||
import { getScheduleMatchingGroup } from './constants/schedule';
|
import { REPEATING_EVENTS, getRepeatingEvents } from './constants/events';
|
||||||
import { getRepeatingEvents } from './constants/events';
|
|
||||||
|
|
||||||
import loginIncentives from './loginIncentives';
|
import loginIncentives from './loginIncentives';
|
||||||
|
|
||||||
@@ -116,6 +115,7 @@ api.armoire = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
api.events = EVENTS;
|
api.events = EVENTS;
|
||||||
|
api.repeatingEvents = REPEATING_EVENTS;
|
||||||
|
|
||||||
api.classes = CLASSES;
|
api.classes = CLASSES;
|
||||||
|
|
||||||
@@ -269,6 +269,7 @@ api.food = {
|
|||||||
text: t('foodSaddleText'),
|
text: t('foodSaddleText'),
|
||||||
value: 5,
|
value: 5,
|
||||||
notes: t('foodSaddleNotes'),
|
notes: t('foodSaddleNotes'),
|
||||||
|
canDrop: false,
|
||||||
},
|
},
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
Cake_Skeleton: {
|
Cake_Skeleton: {
|
||||||
@@ -577,6 +578,4 @@ api.faq = faq;
|
|||||||
|
|
||||||
api.loginIncentives = loginIncentives(api);
|
api.loginIncentives = loginIncentives(api);
|
||||||
|
|
||||||
api.getScheduleMatchingGroup = getScheduleMatchingGroup;
|
|
||||||
|
|
||||||
export default api;
|
export default api;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
MAX_GIFT_MESSAGE_LENGTH,
|
MAX_GIFT_MESSAGE_LENGTH,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import content from './content/index';
|
import content from './content/index';
|
||||||
|
import { getCurrentGalaEvent, getScheduleMatchingGroup } from './content/constants/schedule';
|
||||||
import * as count from './count';
|
import * as count from './count';
|
||||||
// TODO under api.libs.cron?
|
// TODO under api.libs.cron?
|
||||||
import {
|
import {
|
||||||
@@ -106,6 +107,10 @@ const api = {
|
|||||||
getPlanMonths,
|
getPlanMonths,
|
||||||
daysSince,
|
daysSince,
|
||||||
DAY_MAPPING,
|
DAY_MAPPING,
|
||||||
|
schedule: {
|
||||||
|
getCurrentGalaEvent,
|
||||||
|
getScheduleMatchingGroup,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
api.constants = {
|
api.constants = {
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
|
|||||||
if (this.analytics) {
|
if (this.analytics) {
|
||||||
this._trackDropAnalytics(user._id, drop.key);
|
this._trackDropAnalytics(user._id, drop.key);
|
||||||
}
|
}
|
||||||
|
console.log(drop);
|
||||||
return {
|
return {
|
||||||
message: this.i18n('armoireFood', {
|
message: this.i18n('armoireFood', {
|
||||||
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import nconf from 'nconf';
|
import sinon from 'sinon';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { authWithHeaders } from '../../middlewares/auth';
|
import { authWithHeaders } from '../../middlewares/auth';
|
||||||
import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode';
|
import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode';
|
||||||
|
import ensureTimeTravelMode from '../../middlewares/ensureTimeTravelMode';
|
||||||
import { BadRequest } from '../../libs/errors';
|
import { BadRequest } from '../../libs/errors';
|
||||||
import common from '../../../common';
|
import common from '../../../common';
|
||||||
|
|
||||||
@@ -204,56 +205,68 @@ api.questProgress = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let clock;
|
let clock;
|
||||||
if (nconf.get('ENABLE_TIME_TRAVEL')) {
|
|
||||||
(async () => {
|
|
||||||
const sinon = await import('sinon');
|
|
||||||
const time = new Date();
|
|
||||||
clock = sinon.useFakeTimers({
|
|
||||||
now: time,
|
|
||||||
shouldAdvanceTime: true,
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
api.timeTravelTime = {
|
function fakeClock () {
|
||||||
method: 'GET',
|
if (clock) clock.restore();
|
||||||
url: '/debug/time-travel-time',
|
const time = new Date();
|
||||||
middlewares: [authWithHeaders()],
|
clock = sinon.useFakeTimers({
|
||||||
async handler (req, res) {
|
now: time,
|
||||||
const { user } = res.locals;
|
shouldAdvanceTime: true,
|
||||||
|
});
|
||||||
if (!user.permissions.fullAccess) {
|
|
||||||
throw new BadRequest('You do not have permission to time travel.');
|
|
||||||
}
|
|
||||||
|
|
||||||
res.respond(200, {
|
|
||||||
time: new Date(),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
api.timeTravelAdjust = {
|
|
||||||
method: 'POST',
|
|
||||||
url: '/debug/jump-time',
|
|
||||||
middlewares: [authWithHeaders()],
|
|
||||||
async handler (req, res) {
|
|
||||||
const { user } = res.locals;
|
|
||||||
|
|
||||||
if (!user.permissions.fullAccess) {
|
|
||||||
throw new BadRequest('You do not have permission to time travel.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { offsetDays } = req.body;
|
|
||||||
if (offsetDays > 0) {
|
|
||||||
clock.jump(offsetDays * 24 * 60 * 60 * 1000)
|
|
||||||
} else {
|
|
||||||
clock.setSystemTime(moment().add(offsetDays, 'days').toDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
res.respond(200, {
|
|
||||||
time: new Date(),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.timeTravelTime = {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/debug/time-travel-time',
|
||||||
|
middlewares: [ensureTimeTravelMode, authWithHeaders()],
|
||||||
|
async handler (req, res) {
|
||||||
|
if (clock === undefined) {
|
||||||
|
fakeClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
const { user } = res.locals;
|
||||||
|
|
||||||
|
if (!user.permissions.fullAccess) {
|
||||||
|
throw new BadRequest('You do not have permission to time travel.');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.respond(200, {
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
api.timeTravelAdjust = {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/debug/jump-time',
|
||||||
|
middlewares: [ensureTimeTravelMode, authWithHeaders()],
|
||||||
|
async handler (req, res) {
|
||||||
|
const { user } = res.locals;
|
||||||
|
|
||||||
|
if (!user.permissions.fullAccess) {
|
||||||
|
throw new BadRequest('You do not have permission to time travel.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { offsetDays, reset, disable } = req.body;
|
||||||
|
if (reset) {
|
||||||
|
fakeClock();
|
||||||
|
} else if (disable) {
|
||||||
|
clock.restore();
|
||||||
|
clock = undefined;
|
||||||
|
} else if (clock !== undefined) {
|
||||||
|
try {
|
||||||
|
clock.setSystemTime(moment().add(offsetDays, 'days').toDate());
|
||||||
|
} catch (e) {
|
||||||
|
throw new BadRequest('Error adjusting time');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BadRequest('Invalid command');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.respond(200, {
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default api;
|
export default api;
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ import { // eslint-disable-line import/no-cycle
|
|||||||
model as Group,
|
model as Group,
|
||||||
TAVERN_ID as tavernId,
|
TAVERN_ID as tavernId,
|
||||||
} from '../models/group';
|
} from '../models/group';
|
||||||
import { REPEATING_EVENTS } from '../../common/script/content/constants';
|
import common from '../../common';
|
||||||
import { getCurrentGalaEvent } from '../../common/script/content/constants/schedule';
|
|
||||||
|
|
||||||
export async function getWorldBoss () {
|
export async function getWorldBoss () {
|
||||||
const tavern = await Group
|
const tavern = await Group.findById(tavernId)
|
||||||
.findById(tavernId)
|
|
||||||
.select('quest.progress quest.key quest.active quest.extra')
|
.select('quest.progress quest.key quest.active quest.extra')
|
||||||
.exec();
|
.exec();
|
||||||
if (tavern && tavern.quest && tavern.quest.active) {
|
if (tavern && tavern.quest && tavern.quest.active) {
|
||||||
@@ -20,42 +18,46 @@ export async function getWorldBoss () {
|
|||||||
|
|
||||||
export function getCurrentEvent () {
|
export function getCurrentEvent () {
|
||||||
const now = moment();
|
const now = moment();
|
||||||
const currEvtKey = Object.keys(REPEATING_EVENTS).find(evtKey => {
|
const currEvtKey = Object.keys(common.content.repeatingEvents).find(
|
||||||
const event = REPEATING_EVENTS[evtKey];
|
evtKey => {
|
||||||
const startDate = event.start.replace('1970', now.year());
|
const event = common.content.repeatingEventsS[evtKey];
|
||||||
const endDate = event.end.replace('1970', now.year());
|
const startDate = event.start.replace('1970', now.year());
|
||||||
|
const endDate = event.end.replace('1970', now.year());
|
||||||
|
|
||||||
return now.isBetween(startDate, endDate);
|
return now.isBetween(startDate, endDate);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (!currEvtKey) {
|
if (!currEvtKey) {
|
||||||
return getCurrentGalaEvent()
|
return common.schedule.getCurrentGalaEvent();
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
event: currEvtKey,
|
event: currEvtKey,
|
||||||
...REPEATING_EVENTS[currEvtKey],
|
...common.content.repeatingEvents[currEvtKey],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentEventList () {
|
export function getCurrentEventList () {
|
||||||
const now = moment();
|
const now = moment();
|
||||||
const currentEventKeys = filter(Object.keys(REPEATING_EVENTS), eventKey => {
|
const currentEventKeys = filter(
|
||||||
const eventData = REPEATING_EVENTS[eventKey];
|
Object.keys(common.content.repeatingEvents),
|
||||||
const startDate = eventData.start.replace('1970', now.year());
|
eventKey => {
|
||||||
const endDate = eventData.end.replace('1970', now.year());
|
const eventData = common.content.repeatingEvents[eventKey];
|
||||||
|
const startDate = eventData.start.replace('1970', now.year());
|
||||||
|
const endDate = eventData.end.replace('1970', now.year());
|
||||||
|
|
||||||
return now.isBetween(startDate, endDate);
|
return now.isBetween(startDate, endDate);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const currentEventList = [];
|
const currentEventList = [];
|
||||||
|
|
||||||
currentEventKeys.forEach(key => {
|
currentEventKeys.forEach(key => {
|
||||||
currentEventList.push({
|
currentEventList.push({
|
||||||
event: key,
|
event: key,
|
||||||
...REPEATING_EVENTS[key],
|
...common.content.repeatingEvents[key],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
currentEventList.push(common.schedule.getCurrentGalaEvent());
|
||||||
currentEventList.push(getCurrentGalaEvent());
|
|
||||||
return currentEventList;
|
return currentEventList;
|
||||||
}
|
}
|
||||||
|
|||||||
12
website/server/middlewares/ensureTimeTravelMode.js
Normal file
12
website/server/middlewares/ensureTimeTravelMode.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import nconf from 'nconf';
|
||||||
|
import {
|
||||||
|
NotFound,
|
||||||
|
} from '../libs/errors';
|
||||||
|
|
||||||
|
export default function ensureTimeTravelMode (req, res, next) {
|
||||||
|
if (nconf.get('ENABLE_TIME_TRAVEL')) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next(new NotFound());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user