mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
Fix schedule using wrong month at the beginning hours of month (#15290)
* Fix schedule using wrong month at the beginning hours of month * fix broken test * fix switchover for time based matchers * Fix scheduling issue related to timezones * Fix end date creating issues
This commit is contained in:
@@ -47,9 +47,9 @@ describe('shops', () => {
|
||||
|
||||
describe('premium hatching potions', () => {
|
||||
it('contains current scheduled premium hatching potions', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01T09:00:00.000Z'));
|
||||
const potions = shared.shops.getMarketCategories(user).find(x => x.identifier === 'premiumHatchingPotions');
|
||||
expect(potions.items.length).to.eql(2);
|
||||
expect(potions.items.length).to.eql(3);
|
||||
});
|
||||
|
||||
it('does not contain past scheduled premium hatching potions', async () => {
|
||||
@@ -73,9 +73,9 @@ describe('shops', () => {
|
||||
});
|
||||
|
||||
it('does not contain locked quest premium hatching potions', async () => {
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01'));
|
||||
clock = sinon.useFakeTimers(new Date('2024-04-01T09:00:00.000Z'));
|
||||
const potions = shared.shops.getMarketCategories(user).find(x => x.identifier === 'premiumHatchingPotions');
|
||||
expect(potions.items.length).to.eql(2);
|
||||
expect(potions.items.length).to.eql(3);
|
||||
expect(potions.items.filter(x => x.key === 'Bronze' || x.key === 'BlackPearl').length).to.eql(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -18,12 +18,19 @@ function validateMatcher (matcher, checkedDate) {
|
||||
|
||||
describe('Content Schedule', () => {
|
||||
let switchoverTime;
|
||||
let clock;
|
||||
|
||||
beforeEach(() => {
|
||||
switchoverTime = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
clearCachedMatchers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (clock) {
|
||||
clock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it('assembles scheduled items on january 15th', () => {
|
||||
const date = new Date('2024-01-15');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
@@ -105,8 +112,14 @@ describe('Content Schedule', () => {
|
||||
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-07T07:00:00.000Z');
|
||||
it('sets the end date if its on the release day before switchover', () => {
|
||||
const date = new Date('2024-05-07T07:00:00.000+00:00');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
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 after switchover', () => {
|
||||
const date = new Date('2024-05-07T09:00:00.000+00:00');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.backgrounds.end).to.eql(moment.utc(`2024-06-07T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
@@ -129,6 +142,42 @@ describe('Content Schedule', () => {
|
||||
expect(matchers.seasonalGear.end).to.eql(moment.utc(`2025-03-21T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
|
||||
});
|
||||
|
||||
it('uses correct date for first hours of the month', () => {
|
||||
// if the date is checked before CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the previous month
|
||||
const date = new Date('2024-05-01T02:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202404'), '202404').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.false;
|
||||
});
|
||||
|
||||
it('uses correct date after switchover time', () => {
|
||||
// if the date is checked after CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the current
|
||||
const date = new Date('2024-05-01T09:00:00.000Z');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202405'), '202405').to.be.false;
|
||||
});
|
||||
|
||||
it('uses UTC timezone', () => {
|
||||
// if the date is checked after CONTENT_SWITCHOVER_TIME_OFFSET,
|
||||
// it should be considered the current
|
||||
clock = sinon.useFakeTimers(new Date('2024-05-01T05:00:00.000-04:00'));
|
||||
const matchers = getAllScheduleMatchingGroups();
|
||||
expect(matchers.petQuests.items).to.contain('snake');
|
||||
expect(matchers.petQuests.items).to.not.contain('horse');
|
||||
expect(matchers.timeTravelers.match('202304'), '202304').to.be.false;
|
||||
expect(matchers.timeTravelers.match('202305'), '202305').to.be.true;
|
||||
expect(matchers.timeTravelers.match('202405'), '202405').to.be.false;
|
||||
});
|
||||
|
||||
it('contains content for repeating events', () => {
|
||||
const date = new Date('2024-04-15');
|
||||
const matchers = getAllScheduleMatchingGroups(date);
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('time-travelers store', () => {
|
||||
|
||||
describe('on may 1st', () => {
|
||||
beforeEach(() => {
|
||||
date = new Date('2024-05-01');
|
||||
date = new Date('2024-05-01T09:00:00.000Z');
|
||||
});
|
||||
it('returns the correct gear', () => {
|
||||
const items = timeTravelers.timeTravelerStore(user, date);
|
||||
|
||||
@@ -809,7 +809,9 @@ function getMonth (date) {
|
||||
if (date === undefined) {
|
||||
return 0;
|
||||
}
|
||||
return date instanceof moment ? date.month() : date.getMonth();
|
||||
const checkDate = new Date(date.getTime());
|
||||
checkDate.setHours(checkDate.getHours() - SWITCHOVER_TIME);
|
||||
return checkDate.getMonth();
|
||||
}
|
||||
|
||||
function getGalaIndex (date) {
|
||||
@@ -892,7 +894,7 @@ function makeEndDate (checkedDate, matcher) {
|
||||
end.year(checkedDate.getFullYear() + 1);
|
||||
}
|
||||
end.month(matcher.endMonth);
|
||||
} else if (end.date() <= checkedDate.getDate()) {
|
||||
} else if (end.valueOf() <= checkedDate.getTime()) {
|
||||
end = moment(end).add(1, 'months');
|
||||
}
|
||||
return end.toDate();
|
||||
@@ -904,7 +906,7 @@ export function clearCachedMatchers () {
|
||||
}
|
||||
|
||||
export function getAllScheduleMatchingGroups (date) {
|
||||
const checkedDate = date || new Date();
|
||||
const checkedDate = date || moment.utc().toDate();
|
||||
if (cacheDate !== null && (getDay(checkedDate) !== getDay(cacheDate)
|
||||
|| getMonth(checkedDate) !== getMonth(cacheDate))) {
|
||||
// Clear cached matchers, since they are old
|
||||
@@ -914,9 +916,14 @@ export function getAllScheduleMatchingGroups (date) {
|
||||
// No matchers exist, make new ones
|
||||
cacheDate = new Date();
|
||||
cachedScheduleMatchers = {};
|
||||
// subtract switchover time for the matcher classes, but
|
||||
// NOT to decide which matchers to assemble.
|
||||
// assembly uses getDate and getMonth which already adjust for switchover time
|
||||
const adjustedDate = new Date(checkedDate.getTime());
|
||||
adjustedDate.setHours(adjustedDate.getHours() - SWITCHOVER_TIME);
|
||||
assembleScheduledMatchers(checkedDate).forEach(matcher => {
|
||||
if (!cachedScheduleMatchers[matcher.type]) {
|
||||
cachedScheduleMatchers[matcher.type] = makeMatcherClass(checkedDate);
|
||||
cachedScheduleMatchers[matcher.type] = makeMatcherClass(adjustedDate);
|
||||
}
|
||||
cachedScheduleMatchers[matcher.type].end = makeEndDate(checkedDate, matcher);
|
||||
if (matcher.matcher instanceof Function) {
|
||||
|
||||
Reference in New Issue
Block a user