mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-25 02:48:23 +01:00
Introduce infrastructure for Notification Profiles
This commit is contained in:
859
ts/test-node/types/NotificationProfile_test.ts
Normal file
859
ts/test-node/types/NotificationProfile_test.ts
Normal file
@@ -0,0 +1,859 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { DAY, HOUR } from '../../util/durations';
|
||||
|
||||
import {
|
||||
DayOfWeek,
|
||||
findNextProfileEvent,
|
||||
getDayOfWeek,
|
||||
getMidnight,
|
||||
loopThroughWeek,
|
||||
sortProfiles,
|
||||
} from '../../types/NotificationProfile';
|
||||
import { generateNotificationProfileId } from '../../types/NotificationProfile-node';
|
||||
|
||||
import type {
|
||||
NextProfileEvent,
|
||||
NotificationProfileType,
|
||||
} from '../../types/NotificationProfile';
|
||||
|
||||
describe('NotificationProfile', () => {
|
||||
const startingTime = Date.now();
|
||||
const startingTimeDay = getDayOfWeek(startingTime);
|
||||
const delta = startingTimeDay - 1;
|
||||
|
||||
const mondayOfThisWeek = startingTime - DAY * delta;
|
||||
const midnight = getMidnight(mondayOfThisWeek);
|
||||
|
||||
// 10am on Monday of this week, local time
|
||||
const now = midnight + 10 * HOUR;
|
||||
|
||||
const CONVERSATION1 = 'conversation-1';
|
||||
const CONVERSATION2 = 'conversation-2';
|
||||
|
||||
function createBasicProfile(
|
||||
partial?: Partial<NotificationProfileType>
|
||||
): NotificationProfileType {
|
||||
return {
|
||||
id: generateNotificationProfileId(),
|
||||
name: 'After Hours',
|
||||
emoji: '💤 ',
|
||||
color: 0xff111111,
|
||||
|
||||
createdAtMs: now,
|
||||
|
||||
allowAllCalls: true,
|
||||
allowAllMentions: false,
|
||||
|
||||
allowedMembers: new Set([CONVERSATION1, CONVERSATION2]),
|
||||
scheduleEnabled: false,
|
||||
|
||||
scheduleStartTime: undefined,
|
||||
scheduleEndTime: undefined,
|
||||
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: false,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
deletedAtTimestampMs: undefined,
|
||||
storageID: 'storageId-1',
|
||||
storageVersion: 56,
|
||||
storageUnknownFields: undefined,
|
||||
storageNeedsSync: false,
|
||||
|
||||
...partial,
|
||||
};
|
||||
}
|
||||
|
||||
describe('findNextProfileEvent', () => {
|
||||
it('should return noChange with no profiles', () => {
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'noChange',
|
||||
activeProfile: undefined,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return noChange with no profiles with schedules', () => {
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'noChange',
|
||||
activeProfile: undefined,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
createBasicProfile(),
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return noChange if manual enable override w/o end time and profile has no schedule', () => {
|
||||
const defaultProfile = createBasicProfile();
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'noChange',
|
||||
activeProfile: defaultProfile.id,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: defaultProfile.id,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willDisable if manual enable override w/ end time and profile has no schedule', () => {
|
||||
const defaultProfile = createBasicProfile();
|
||||
const disableAt = now + HOUR;
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: defaultProfile.id,
|
||||
willDisableAt: disableAt,
|
||||
clearEnableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: defaultProfile.id,
|
||||
endsAtMs: disableAt,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willDisable if manual enable override w/ end time overlaps with scheduled time', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: defaultProfile.id,
|
||||
willDisableAt: now + HOUR,
|
||||
clearEnableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: defaultProfile.id,
|
||||
endsAtMs: now + HOUR,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
it('should return willDisable if manual enable override w/ end time if different profile enables at end time', () => {
|
||||
const newProfile = createBasicProfile({
|
||||
name: 'new',
|
||||
createdAtMs: now,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
const oldProfile = createBasicProfile({
|
||||
name: 'old',
|
||||
createdAtMs: now - 10,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
const profiles = sortProfiles([oldProfile, newProfile]);
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: oldProfile.id,
|
||||
willDisableAt: now + HOUR,
|
||||
clearEnableOverride: true,
|
||||
};
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: oldProfile.id,
|
||||
endsAtMs: now + HOUR,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willDisable if manual enable override w/o end time refers to profile with schedule, enabled now', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: defaultProfile.id,
|
||||
willDisableAt: now + 2 * HOUR,
|
||||
clearEnableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: defaultProfile.id,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
it('should return willDisable if manual enable override w/o end time refers to profile with schedule, not enabled now', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: false,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: true,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: defaultProfile.id,
|
||||
willDisableAt: now + 2 * DAY + 2 * HOUR,
|
||||
clearEnableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: undefined,
|
||||
enabled: {
|
||||
profileId: defaultProfile.id,
|
||||
},
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willDisable if profile should be active right now', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: defaultProfile.id,
|
||||
willDisableAt: now + 2 * HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
it('should return willDisable with earlier start if two profiles should be active right now', () => {
|
||||
const oldProfile = createBasicProfile({
|
||||
createdAtMs: now - 10,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 800,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
const newProfile = createBasicProfile({
|
||||
createdAtMs: now,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: oldProfile.id,
|
||||
willDisableAt: now + 2 * HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = sortProfiles([
|
||||
oldProfile,
|
||||
newProfile,
|
||||
]);
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
it('should return willDisable with newer profile with same start if two profiles should be active right now', () => {
|
||||
const oldProfile = createBasicProfile({
|
||||
createdAtMs: now - 10,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
const newProfile = createBasicProfile({
|
||||
createdAtMs: now,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1200,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willDisable',
|
||||
activeProfile: newProfile.id,
|
||||
willDisableAt: now + 2 * HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = sortProfiles([
|
||||
oldProfile,
|
||||
newProfile,
|
||||
]);
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable if profile is scheduled to start soon', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: defaultProfile.id,
|
||||
willEnableAt: now + HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable w/ manual disable override if profile will start soon', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: defaultProfile.id,
|
||||
willEnableAt: now + HOUR,
|
||||
clearDisableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: now,
|
||||
enabled: undefined,
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable w/ manual disable override if profile should be active now, another starts tomorrow', () => {
|
||||
const activeProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 900,
|
||||
scheduleEndTime: 1100,
|
||||
});
|
||||
const willStartProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: false,
|
||||
[DayOfWeek.TUESDAY]: true,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: willStartProfile.id,
|
||||
willEnableAt: now + DAY + HOUR,
|
||||
clearDisableOverride: true,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
activeProfile,
|
||||
willStartProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: {
|
||||
disabledAtMs: now,
|
||||
enabled: undefined,
|
||||
},
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable if profile schedule starts in six days', () => {
|
||||
const defaultProfile = createBasicProfile({
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: false,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: true,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: defaultProfile.id,
|
||||
willEnableAt: now + HOUR + 6 * DAY,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = [
|
||||
defaultProfile,
|
||||
createBasicProfile({
|
||||
name: 'Work',
|
||||
}),
|
||||
];
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable for newer profile if there is a conflict', () => {
|
||||
const newProfile = createBasicProfile({
|
||||
name: 'new-profile',
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
const oldProfile = createBasicProfile({
|
||||
name: 'old-profile',
|
||||
createdAtMs: now - HOUR,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: newProfile.id,
|
||||
willEnableAt: now + HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = sortProfiles([
|
||||
oldProfile,
|
||||
newProfile,
|
||||
]);
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
|
||||
it('should return willEnable for older profile if it will activate first', () => {
|
||||
const newProfile = createBasicProfile({
|
||||
name: 'new-profile',
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: false,
|
||||
[DayOfWeek.TUESDAY]: true,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
const oldProfile = createBasicProfile({
|
||||
name: 'old-profile',
|
||||
createdAtMs: now - HOUR,
|
||||
scheduleEnabled: true,
|
||||
scheduleDaysEnabled: {
|
||||
[DayOfWeek.MONDAY]: true,
|
||||
[DayOfWeek.TUESDAY]: false,
|
||||
[DayOfWeek.WEDNESDAY]: false,
|
||||
[DayOfWeek.THURSDAY]: false,
|
||||
[DayOfWeek.FRIDAY]: false,
|
||||
[DayOfWeek.SATURDAY]: false,
|
||||
[DayOfWeek.SUNDAY]: false,
|
||||
},
|
||||
scheduleStartTime: 1100,
|
||||
scheduleEndTime: 1400,
|
||||
});
|
||||
|
||||
const expected: NextProfileEvent = {
|
||||
type: 'willEnable',
|
||||
toEnable: oldProfile.id,
|
||||
willEnableAt: now + HOUR,
|
||||
};
|
||||
const profiles: ReadonlyArray<NotificationProfileType> = sortProfiles([
|
||||
oldProfile,
|
||||
newProfile,
|
||||
]);
|
||||
|
||||
const actual = findNextProfileEvent({
|
||||
override: undefined,
|
||||
profiles,
|
||||
time: now,
|
||||
});
|
||||
assert.deepEqual(expected, actual);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loopThroughWeek', () => {
|
||||
it('finds result on first day checked', () => {
|
||||
let count = 0;
|
||||
const startingDay = getDayOfWeek(now);
|
||||
|
||||
loopThroughWeek({
|
||||
time: now,
|
||||
startingDay,
|
||||
check: _options => {
|
||||
count += 1;
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
it('finds result on second-to-last day checked', () => {
|
||||
let count = 0;
|
||||
const startingDay = getDayOfWeek(now);
|
||||
|
||||
loopThroughWeek({
|
||||
time: now,
|
||||
startingDay,
|
||||
check: ({ day }) => {
|
||||
count += 1;
|
||||
if (day === DayOfWeek.SATURDAY) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(count, 6);
|
||||
});
|
||||
it('loops through entire week if check returns false', () => {
|
||||
let count = 0;
|
||||
const startingDay = getDayOfWeek(now);
|
||||
|
||||
loopThroughWeek({
|
||||
time: now,
|
||||
startingDay,
|
||||
check: _options => {
|
||||
count += 1;
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(count, 7);
|
||||
});
|
||||
it('loops from monday to sunday', () => {
|
||||
let count = 0;
|
||||
const startingDay = getDayOfWeek(now);
|
||||
|
||||
loopThroughWeek({
|
||||
time: now,
|
||||
startingDay,
|
||||
check: ({ day }) => {
|
||||
count += 1;
|
||||
if (day === DayOfWeek.SUNDAY) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(count, 7);
|
||||
});
|
||||
it('loops from sunday to saturday', () => {
|
||||
const sundayAt10 = now + 6 * DAY;
|
||||
let count = 0;
|
||||
const startingDay = getDayOfWeek(sundayAt10);
|
||||
|
||||
loopThroughWeek({
|
||||
time: sundayAt10,
|
||||
startingDay,
|
||||
check: ({ day }) => {
|
||||
count += 1;
|
||||
if (day === DayOfWeek.SATURDAY) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(count, 7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortProfiles', () => {
|
||||
it('sorts profiles in descending by create date', () => {
|
||||
const old = createBasicProfile({ name: 'old', createdAtMs: now - 10 });
|
||||
const middle = createBasicProfile({ name: 'middle', createdAtMs: now });
|
||||
const newest = createBasicProfile({
|
||||
name: 'newest',
|
||||
createdAtMs: now + 10,
|
||||
});
|
||||
|
||||
const starting = [middle, old, newest];
|
||||
const actual = sortProfiles(starting);
|
||||
|
||||
assert.strictEqual(actual[0].name, 'newest');
|
||||
assert.strictEqual(actual[1].name, 'middle');
|
||||
assert.strictEqual(actual[2].name, 'old');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user