Move from deprecated moment#zone to moment#utcOffset (#12207)

* Issue 10209 - Remove read usages of zone

* Issue 10209 - Add coverage on daysSince and startOfDay cron utility functions

* Issue 10209 - Add unit test for daysUserHasMissed method

* Issue 10209 - Remove usages of deprecated `moment.js#zone` method.

* Issue 10209 - Add helper function to centralise logic

Also simplify timezoneOffsetToUtc function in site.vue

* Issue 10209 - Also add getUtcOffset as method on user

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
This commit is contained in:
Bart Enkelaar
2020-07-25 13:22:41 +02:00
committed by GitHub
parent c10b9b7993
commit 234258b41e
25 changed files with 413 additions and 141 deletions
+25
View File
@@ -0,0 +1,25 @@
import getUtcOffset from '../../../website/common/script/fns/getUtcOffset';
describe('getUtcOffset', () => {
let user;
beforeEach(() => {
user = { preferences: {} };
});
it('returns 0 when user.timezoneOffset is not set', () => {
expect(getUtcOffset(user)).to.equal(0);
});
it('returns 0 when user.timezoneOffset is zero', () => {
user.preferences.timezoneOffset = 0;
expect(getUtcOffset(user)).to.equal(0);
});
it('returns the opposite of user.timezoneOffset', () => {
user.preferences.timezoneOffset = -10;
expect(getUtcOffset(user)).to.eql(10);
});
});
+184
View File
@@ -0,0 +1,184 @@
import moment from 'moment';
import { startOfDay, daysSince } 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);
});
});
});
+2 -1
View File
@@ -1,6 +1,7 @@
import moment from 'moment';
import taskDefaults from '../../../website/common/script/libs/taskDefaults';
import getUtcOffset from '../../../website/common/script/fns/getUtcOffset';
import { generateUser } from '../../helpers/common.helper';
describe('taskDefaults', () => {
@@ -72,7 +73,7 @@ describe('taskDefaults', () => {
expect(task.startDate).to.eql(
moment()
.zone(user.preferences.timezoneOffset, 'hour')
.utcOffset(getUtcOffset(user))
.startOf('day')
.subtract(1, 'day')
.toDate(),
+8 -6
View File
@@ -5,6 +5,8 @@ import 'moment-recur';
describe('shouldDo', () => {
let day; let
dailyTask;
// Options is a mapping of user.preferences, therefor `timezoneOffset` still holds old zone
// values instead of utcOffset values.
let options = {};
let nextDue = [];
@@ -80,17 +82,17 @@ describe('shouldDo', () => {
it('returns true if the user\'s current time is after start date and Custom Day Start', () => {
options.dayStart = 4;
day = moment().zone(options.timezoneOffset).startOf('day').add(6, 'hours')
day = moment().utcOffset(-options.timezoneOffset).startOf('day').add(6, 'hours')
.toDate();
dailyTask.startDate = moment().zone(options.timezoneOffset).startOf('day').toDate();
dailyTask.startDate = moment().utcOffset(-options.timezoneOffset).startOf('day').toDate();
expect(shouldDo(day, dailyTask, options)).to.equal(true);
});
it('returns false if the user\'s current time is before Custom Day Start', () => {
options.dayStart = 8;
day = moment().zone(options.timezoneOffset).startOf('day').add(2, 'hours')
day = moment().utcOffset(-options.timezoneOffset).startOf('day').add(2, 'hours')
.toDate();
dailyTask.startDate = moment().zone(options.timezoneOffset).startOf('day').toDate();
dailyTask.startDate = moment().utcOffset(-options.timezoneOffset).startOf('day').toDate();
expect(shouldDo(day, dailyTask, options)).to.equal(false);
});
});
@@ -112,14 +114,14 @@ describe('shouldDo', () => {
it('returns true if the user\'s current time is after Custom Day Start', () => {
options.dayStart = 4;
day = moment().zone(options.timezoneOffset).startOf('day').add(6, 'hours')
day = moment().utcOffset(-options.timezoneOffset).startOf('day').add(6, 'hours')
.toDate();
expect(shouldDo(day, dailyTask, options)).to.equal(true);
});
it('returns false if the user\'s current time is before Custom Day Start', () => {
options.dayStart = 8;
day = moment().zone(options.timezoneOffset).startOf('day').add(2, 'hours')
day = moment().utcOffset(-options.timezoneOffset).startOf('day').add(2, 'hours')
.toDate();
expect(shouldDo(day, dailyTask, options)).to.equal(false);
});