mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
make content releases use a given offset to the time.
This commit is contained in:
@@ -89,5 +89,6 @@
|
||||
"REDIS_PASSWORD": "12345678",
|
||||
"TRUSTED_DOMAINS": "localhost,https://habitica.com",
|
||||
"TIME_TRAVEL_ENABLED": "false",
|
||||
"DEBUG_ENABLED": "false"
|
||||
"DEBUG_ENABLED": "false",
|
||||
"CONTENT_SWITCHOVER_TIME_OFFSET": 8
|
||||
}
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
"chalk": "^5.3.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"mocha": "^5.1.1",
|
||||
"nyc": "^15.1.0",
|
||||
"monk": "^7.3.4",
|
||||
"nyc": "^15.1.0",
|
||||
"require-again": "^2.0.0",
|
||||
"run-rs": "^0.7.7",
|
||||
"sinon-chai": "^3.7.0",
|
||||
|
||||
67
test/common/fns/datedMemoize.test.js
Normal file
67
test/common/fns/datedMemoize.test.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/* eslint-disable global-require */
|
||||
import { expect } from 'chai';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
|
||||
describe('datedMemoize', () => {
|
||||
it('should return a function that returns a function', () => {
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(() => {});
|
||||
expect(memoized).to.be.a('function');
|
||||
});
|
||||
|
||||
it('should not call multiple times', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized(1, 2);
|
||||
memoized(1, 3);
|
||||
expect(stub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('call multiple times for different identifiers', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized({ identifier: 'a', memoizeConfig: true }, 1, 2);
|
||||
memoized({ identifier: 'b', memoizeConfig: true }), 1, 2;
|
||||
expect(stub).to.have.been.calledTwice;
|
||||
});
|
||||
|
||||
it('call once for the same identifier', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized({ identifier: 'a', memoizeConfig: true }, 1, 2);
|
||||
memoized({ identifier: 'a', memoizeConfig: true }, 1, 2);
|
||||
expect(stub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('call once on the same day', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized({ date: new Date('2024-01-01'), memoizeConfig: true }, 1, 2);
|
||||
memoized({ date: new Date('2024-01-01'), memoizeConfig: true }, 1, 2);
|
||||
expect(stub).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('call multiple times on different days', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized({ date: new Date('2024-01-01'), memoizeConfig: true }, 1, 2);
|
||||
memoized({ date: new Date('2024-01-02'), memoizeConfig: true }, 1, 2);
|
||||
expect(stub).to.have.been.calledTwice;
|
||||
});
|
||||
|
||||
it('respects switchover time', () => {
|
||||
const stub = sandbox.stub().returns({});
|
||||
const datedMemoize = require('../../../website/common/script/fns/datedMemoize').default;
|
||||
const memoized = datedMemoize(stub);
|
||||
memoized({ date: new Date('2024-01-01T00:00:00.000Z'), memoizeConfig: true }, 1, 2);
|
||||
memoized({ date: new Date(`2024-01-01T${String(SWITCHOVER_TIME).padStart(2, '0')}`), memoizeConfig: true }, 1, 2);
|
||||
expect(stub).to.have.been.calledTwice;
|
||||
});
|
||||
});
|
||||
@@ -26,7 +26,7 @@ describe('armoire', () => {
|
||||
clock.restore();
|
||||
});
|
||||
it('does not return unreleased gear', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-01-01'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-01-02'));
|
||||
const items = makeArmoireIitemList();
|
||||
expect(items.length).to.equal(377);
|
||||
expect(items.filter(item => item.set === 'pottersSet' || item.set === 'optimistSet' || item.set === 'schoolUniform')).to.be.an('array').that.is.empty;
|
||||
@@ -47,7 +47,7 @@ describe('armoire', () => {
|
||||
});
|
||||
|
||||
it('releases gear when appropriate', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-01-01'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-01-01T00:00:00.000Z'));
|
||||
const items = makeArmoireIitemList();
|
||||
expect(items.length).to.equal(377);
|
||||
clock.restore();
|
||||
@@ -57,8 +57,13 @@ describe('armoire', () => {
|
||||
expect(januaryItems.length).to.equal(381);
|
||||
clock.restore();
|
||||
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
|
||||
clock = sinon.useFakeTimers(new Date('2024-02-20'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-02-07'));
|
||||
const januaryItems2 = makeArmoireIitemList();
|
||||
expect(januaryItems2.length).to.equal(381);
|
||||
clock.restore();
|
||||
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
|
||||
clock = sinon.useFakeTimers(new Date('2024-02-07T09:00:00.000Z'));
|
||||
const febuaryItems = makeArmoireIitemList();
|
||||
expect(febuaryItems.length).to.equal(384);
|
||||
expect(febuaryItems.length).to.equal(381);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// eslint-disable-next-line max-len
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
import {
|
||||
getAllScheduleMatchingGroups, clearCachedMatchers, MONTHLY_SCHEDULE, GALA_SCHEDULE,
|
||||
} from '../../website/common/script/content/constants/schedule';
|
||||
@@ -16,7 +17,10 @@ function validateMatcher (matcher, checkedDate) {
|
||||
}
|
||||
|
||||
describe('Content Schedule', () => {
|
||||
let switchoverTime;
|
||||
|
||||
beforeEach(() => {
|
||||
switchoverTime = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
clearCachedMatchers();
|
||||
});
|
||||
|
||||
@@ -50,8 +54,8 @@ describe('Content Schedule', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('assembles scheduled items on march 21st', () => {
|
||||
const date = new Date('2024-03-21');
|
||||
it('assembles scheduled items on march 22st', () => {
|
||||
const date = new Date('2024-03-22');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
for (const key in matchers) {
|
||||
if (matchers[key]) {
|
||||
@@ -92,31 +96,31 @@ describe('Content Schedule', () => {
|
||||
it('sets the end date if its in the same month', () => {
|
||||
const date = new Date('2024-04-03');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc('2024-04-07').toDate());
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-04-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date if its in the next day', () => {
|
||||
const date = new Date('2024-05-06T14:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc('2024-05-07').toDate());
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-05-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date if its on the release day', () => {
|
||||
const date = new Date('2024-05-07');
|
||||
const date = new Date('2024-05-07T07:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc('2024-06-07').toDate());
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-06-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date if its next month', () => {
|
||||
const date = new Date('2024-05-20T01:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc('2024-06-07').toDate());
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-06-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('sets the end date for a gala', () => {
|
||||
const date = new Date('2024-05-20');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.seasonalGear.end).to.eql(moment.utc('2024-06-21').toDate());
|
||||
expect(matchers.seasonalGear.end).to.eql(moment.utc(`2024-06-21T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('contains content for repeating events', () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
import SEASONAL_SETS from './seasonalSets';
|
||||
import { getRepeatingEvents } from './events';
|
||||
|
||||
@@ -773,6 +774,8 @@ export const GALA_SCHEDULE = {
|
||||
},
|
||||
};
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
|
||||
export const TYPE_SCHEDULE = {
|
||||
timeTravelers: FIRST_RELEASE_DAY,
|
||||
backgrounds: SECOND_RELEASE_DAY,
|
||||
@@ -790,7 +793,9 @@ function getDay (date) {
|
||||
if (date === undefined) {
|
||||
return 0;
|
||||
}
|
||||
return date instanceof moment ? date.date() : date.getDate();
|
||||
const checkDate = new Date(date.getTime());
|
||||
checkDate.setHours(checkDate.getHours() - SWITCHOVER_TIME);
|
||||
return checkDate.getDate();
|
||||
}
|
||||
|
||||
function getMonth (date) {
|
||||
@@ -871,7 +876,7 @@ function makeMatcherClass (date) {
|
||||
function makeEndDate (checkedDate, matcher) {
|
||||
let end = moment.utc(checkedDate);
|
||||
end.date(TYPE_SCHEDULE[matcher.type]);
|
||||
end.hour(0);
|
||||
end.hour(SWITCHOVER_TIME);
|
||||
end.minute(0);
|
||||
end.second(0);
|
||||
if (matcher.endMonth !== undefined) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import defaults from 'lodash/defaults';
|
||||
import find from 'lodash/find';
|
||||
import forEach from 'lodash/forEach';
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import { ownsItem } from '../gear-helper';
|
||||
import { ATTRIBUTES } from '../../../constants';
|
||||
@@ -1832,6 +1833,7 @@ const weapon = {
|
||||
},
|
||||
};
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
const releaseDay = 7;
|
||||
const releaseDates = {
|
||||
somethingSpooky: { year: 2023, month: 10 },
|
||||
@@ -1888,7 +1890,7 @@ forEach({
|
||||
|
||||
function updateReleased (type) {
|
||||
const today = moment();
|
||||
const releaseDateEndPart = `${String(releaseDay).padStart(2, '0')}T08:00-0500`;
|
||||
const releaseDateEndPart = `${String(releaseDay).padStart(2, '0')}T${String(SWITCHOVER_TIME).padStart(2, '0')}:00-0500`;
|
||||
const returnType = {};
|
||||
forEach(type, (gearItem, gearKey) => {
|
||||
let released;
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
|
||||
function getDay (date) {
|
||||
if (date === undefined) {
|
||||
return 0;
|
||||
}
|
||||
return date instanceof moment ? date.date() : date.getDate();
|
||||
const checkDate = new Date(date.getTime());
|
||||
checkDate.setHours(checkDate.getHours() - SWITCHOVER_TIME);
|
||||
return checkDate.getDate();
|
||||
}
|
||||
|
||||
function getMonth (date) {
|
||||
|
||||
Reference in New Issue
Block a user