Files
habitica/test/common/libs/cron.test.js
negue 8cb8411cc6 Show "Next Hourglass" Month (#13860)
* Show "Next Hourglass" Month

* fix lint

* lint,

* lint

* lint..

* linting bad

* ui fixes

* remove additional margin

* show next hourglass date to debug further

* WIP tests - maybe broken logic

* flex:1 doesn't work - so stats columns now at 33% width

* fix(cron): lint and short circuit

* refactor logic

* update test dates using timezone

* also check for the timezone date

* fix timezone for tests

* fixing the test dates?

* fixing the test dates?

* change nextHourglass logic + update gem cap label / value

* fix lint

* dont add gemsBought to it

* remove tooltip

Co-authored-by: SabreCat <sabe@habitica.com>
2022-04-06 16:30:13 -05:00

244 lines
7.0 KiB
JavaScript

import moment from 'moment';
import { startOfDay, daysSince, getPlanContext } from '../../../website/common/script/cron';
function localMoment (timeString, utcOffset) {
return moment(timeString).utcOffset(utcOffset, true);
}
describe('cron utility functions', () => {
describe('startOfDay', () => {
it('is zero when no daystart configured', () => {
const options = { now: moment('2020-02-02 09:30:00Z'), timezoneOffset: 0 };
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 00:00:00Z');
});
it('is zero when negative daystart configured', () => {
const options = {
now: moment('2020-02-02 09:30:00Z'),
timezoneOffset: 0,
daystart: -5,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 00:00:00Z');
});
it('is zero when daystart over 24 is configured', () => {
const options = {
now: moment('2020-02-02 09:30:00Z'),
timezoneOffset: 0,
daystart: 25,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 00:00:00Z');
});
it('is equal to daystart o\'clock when daystart configured', () => {
const options = {
now: moment('2020-02-02 09:30:00Z'),
timezoneOffset: 0,
dayStart: 5,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 05:00:00Z');
});
it('is previous day daystart o\'clock when daystart is after current time', () => {
const options = {
now: moment('2020-02-02 04:30:00Z'),
timezoneOffset: 0,
dayStart: 5,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-01 05:00:00Z');
});
it('is daystart o\'clock when daystart is after current time due to timezone', () => {
const options = {
now: moment('2020-02-02 04:30:00Z'),
timezoneOffset: -120,
dayStart: 5,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 05:00:00+02:00');
});
it('returns in default timezone if no timezone defined', () => {
const utcOffset = moment().utcOffset();
const now = localMoment('2020-02-02 04:30:00', utcOffset).utc();
const result = startOfDay({ now });
expect(result).to.be.sameMoment(localMoment('2020-02-02', utcOffset));
});
it('returns in default timezone if timezone lower than -12:00', () => {
const utcOffset = moment().utcOffset();
const options = {
now: localMoment('2020-02-02 17:30:00', utcOffset).utc(),
timezoneOffset: 721,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment(localMoment('2020-02-02', utcOffset));
});
it('returns in default timezone if timezone higher than +14:00', () => {
const utcOffset = moment().utcOffset();
const options = {
now: localMoment('2020-02-02 07:32:25.376', utcOffset).utc(),
timezoneOffset: -841,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment(localMoment('2020-02-02', utcOffset));
});
it('returns in overridden timezone if override present', () => {
const options = {
now: moment('2020-02-02 13:30:27Z'),
timezoneOffset: 0,
timezoneUtcOffsetOverride: -240,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment('2020-02-02 00:00:00-04:00');
});
it('returns start of yesterday if timezone difference carries it over datelines', () => {
const offset = 300;
const options = {
now: moment('2020-02-02 04:30:00Z'),
timezoneOffset: offset,
};
const result = startOfDay(options);
expect(result).to.be.sameMoment(localMoment('2020-02-01', -offset));
});
});
describe('daysSince', () => {
it('correctly calculates days between two dates', () => {
const now = moment();
const dayBeforeYesterday = moment(now).subtract({ days: 2 });
expect(daysSince(dayBeforeYesterday, { now })).to.equal(2);
});
it('is one lower if current time is before dayStart', () => {
const oneWeekAgoAtOnePm = moment().hour(13).subtract({ days: 7 });
const thisMorningThreeAm = moment().hour(3);
const options = {
now: thisMorningThreeAm,
dayStart: 6,
};
const result = daysSince(oneWeekAgoAtOnePm, options);
expect(result).to.equal(6);
});
it('is one higher if reference time is before dayStart and current time after dayStart', () => {
const oneWeekAgoAtEightAm = moment().hour(8).subtract({ days: 7 });
const todayAtFivePm = moment().hour(17);
const options = {
now: todayAtFivePm,
dayStart: 11,
};
const result = daysSince(oneWeekAgoAtEightAm, options);
expect(result).to.equal(8);
});
// Variations in timezone configuration options are already covered by startOfDay tests.
it('uses now in user timezone as configured in options', () => {
const timezoneOffset = 120;
const options = {
now: moment('1989-11-09 02:53:00+01:00'),
timezoneOffset,
};
const result = daysSince(localMoment('1989-11-08', -timezoneOffset), options);
expect(result).to.equal(0);
});
});
describe('getPlanContext', () => {
const now = new Date(2022, 5, 1);
function baseUserData (count, offset, planId) {
return {
purchased: {
plan: {
consecutive: {
count,
offset,
gemCapExtra: 25,
trinkets: 19,
},
quantity: 1,
extraMonths: 0,
gemsBought: 0,
owner: '116b4133-8fb7-43f2-b0de-706621a8c9d8',
nextBillingDate: null,
nextPaymentProcessing: null,
planId,
customerId: 'group-plan',
dateUpdated: '2022-05-10T03:00:00.144+01:00',
paymentMethod: 'Group Plan',
dateTerminated: null,
lastBillingDate: null,
dateCreated: '2017-02-10T19:00:00.355+01:00',
},
},
};
}
it('offset 0, next date in 3 months', () => {
const user = baseUserData(60, 0, 'group_plan_auto');
const planContext = getPlanContext(user, now);
expect(planContext.nextHourglassDate)
.to.be.sameMoment('2022-08-10T02:00:00.144Z');
});
it('offset 1, next date in 1 months', () => {
const user = baseUserData(60, 1, 'group_plan_auto');
const planContext = getPlanContext(user, now);
expect(planContext.nextHourglassDate)
.to.be.sameMoment('2022-06-10T02:00:00.144Z');
});
it('offset 2, next date in 2 months - with any plan', () => {
const user = baseUserData(60, 2, 'basic_3mo');
const planContext = getPlanContext(user, now);
expect(planContext.nextHourglassDate)
.to.be.sameMoment('2022-07-10T02:00:00.144Z');
});
});
});