fix: restore process sets currentDay

This commit is contained in:
Carlos Valente
2026-01-10 09:42:16 +01:00
committed by Carlos Valente
parent 1b55254834
commit f8cde5d627
7 changed files with 141 additions and 0 deletions
@@ -13,6 +13,7 @@ describe('isRestorePoint()', () => {
pausedAt: 3,
firstStart: 1,
startEpoch: 1,
currentDay: 0,
};
expect(isRestorePoint(restorePoint)).toBe(true);
@@ -24,6 +25,21 @@ describe('isRestorePoint()', () => {
pausedAt: null,
firstStart: 1,
startEpoch: 1,
currentDay: 2,
};
expect(isRestorePoint(restorePoint)).toBe(true);
});
it('accepts null start fields', () => {
const restorePoint: RestorePoint = {
playback: Playback.Stop,
selectedEventId: null,
startedAt: null,
addedTime: 0,
pausedAt: null,
firstStart: null,
startEpoch: null,
currentDay: null,
};
expect(isRestorePoint(restorePoint)).toBe(true);
});
@@ -63,5 +79,39 @@ describe('isRestorePoint()', () => {
};
expect(isRestorePoint(restorePoint)).toBe(false);
});
it('with missing firstStart', () => {
const restorePoint = {
playback: Playback.Roll,
selectedEventId: '123',
startedAt: null,
addedTime: 0,
pausedAt: null,
startEpoch: 1,
};
expect(isRestorePoint(restorePoint)).toBe(false);
});
it('with missing startEpoch', () => {
const restorePoint = {
playback: Playback.Roll,
selectedEventId: '123',
startedAt: null,
addedTime: 0,
pausedAt: null,
firstStart: 1,
};
expect(isRestorePoint(restorePoint)).toBe(false);
});
it('with missing currentDay', () => {
const restorePoint = {
playback: Playback.Roll,
selectedEventId: '123',
startedAt: null,
addedTime: 0,
pausedAt: null,
firstStart: 1,
startEpoch: 1,
};
expect(isRestorePoint(restorePoint)).toBe(false);
});
});
});
@@ -17,6 +17,7 @@ describe('restoreService', () => {
pausedAt: 9087,
firstStart: 1234,
startEpoch: 1234,
currentDay: 0,
};
const mockRead = vi.fn().mockResolvedValue(expected);
@@ -35,6 +36,7 @@ describe('restoreService', () => {
pausedAt: null,
firstStart: 1234,
startEpoch: 1234,
currentDay: null,
};
const mockRead = vi.fn().mockResolvedValue(expected);
@@ -82,6 +84,7 @@ describe('restoreService', () => {
pausedAt: 1234,
firstStart: 1234,
startEpoch: 1234,
currentDay: 0,
};
const mockWrite = vi.fn().mockResolvedValue(undefined);
@@ -90,6 +93,39 @@ describe('restoreService', () => {
expect(mockWrite).toHaveBeenCalledWith(testData);
});
it('writes updated data when values change', async () => {
const firstData: RestorePoint = {
playback: Playback.Play,
selectedEventId: '2345',
startedAt: 2345,
addedTime: 2345,
pausedAt: 2345,
firstStart: 2345,
startEpoch: 2345,
currentDay: 0,
};
const updatedData: RestorePoint = {
playback: Playback.Pause,
selectedEventId: '3456',
startedAt: 3456,
addedTime: 3456,
pausedAt: 3456,
firstStart: 3456,
startEpoch: 3456,
currentDay: 1,
};
const mockWrite = vi.fn().mockResolvedValue(undefined);
await restoreService.save(firstData, mockWrite);
await restoreService.save(updatedData, mockWrite);
expect(mockWrite).toHaveBeenCalledTimes(2);
expect(mockWrite).toHaveBeenNthCalledWith(1, firstData);
expect(mockWrite).toHaveBeenNthCalledWith(2, updatedData);
});
it('handles write failures gracefully', async () => {
const testData: RestorePoint = {
playback: Playback.Pause,
@@ -99,6 +135,7 @@ describe('restoreService', () => {
pausedAt: 5678,
firstStart: 5678,
startEpoch: 5678,
currentDay: 0,
};
const mockWrite = vi.fn().mockRejectedValue(new Error('Write failed'));
@@ -21,6 +21,7 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
'pausedAt',
'firstStart',
'startEpoch',
'currentDay',
])
) {
return false;
@@ -54,5 +55,9 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
return false;
}
if (!is.number(restorePoint.currentDay) && restorePoint.currentDay !== null) {
return false;
}
return true;
}
@@ -8,4 +8,5 @@ export type RestorePoint = {
pausedAt: MaybeNumber;
firstStart: MaybeNumber;
startEpoch: MaybeNumber;
currentDay: MaybeNumber;
};
@@ -759,6 +759,7 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
pausedAt: state._timer.pausedAt,
firstStart: state.rundown.actualStart,
startEpoch: state._startEpoch,
currentDay: state.rundown.currentDay,
})
.catch((_e) => {
//we don't do anything with the error here
@@ -11,9 +11,11 @@ import {
load,
loadGroupFlagAndEnd,
pause,
resume,
roll,
start,
stop,
update,
} from '../runtimeState.js';
import { rundownCache } from '../../api-data/rundown/rundown.dao.js';
import { RundownMetadata } from '../../api-data/rundown/rundown.types.js';
@@ -244,6 +246,44 @@ describe('mutation on runtimeState', () => {
expect(newState.offset.absolute).toBe(0);
expect(newState.offset.expectedRundownEnd).toBeNull();
});
test('resume restores currentDay from restore point', async () => {
clearState();
const mockRundown = makeRundown({
entries: {
event1: { ...mockEvent, id: 'event1', timeStart: 0, timeEnd: 1000, duration: 1000, dayOffset: 0 },
},
order: ['event1'],
});
const startEpoch = new Date('2024-01-01T00:00:00Z').getTime();
vi.setSystemTime(new Date('2024-01-03T00:00:00Z'));
await initRundown(mockRundown, {});
vi.runAllTimers();
const { rundown, metadata } = rundownCache.get();
const restorePoint = {
playback: Playback.Play,
selectedEventId: 'event1',
startedAt: 0,
addedTime: 0,
pausedAt: null,
firstStart: 60 * 1000,
startEpoch,
currentDay: 2,
};
resume(restorePoint, mockRundown.entries.event1 as PlayableEvent, rundown, metadata);
const newState = getState();
expect(newState.rundown.actualStart).toBe(60 * 1000);
expect(newState.rundown.currentDay).toBe(2);
vi.setSystemTime(new Date('2024-01-04T00:00:00Z'));
update();
expect(getState().rundown.currentDay).toBe(3);
});
});
describe('roll mode', () => {
+7
View File
@@ -246,12 +246,19 @@ export function load(
patchTimer(initialData);
const startEpoch = initialData?.startEpoch;
const firstStart = initialData?.firstStart;
const currentDay = initialData?.currentDay;
if (
(firstStart === null || typeof firstStart === 'number') &&
(startEpoch === null || typeof startEpoch === 'number')
) {
runtimeState.rundown.actualStart = firstStart;
runtimeState._startEpoch = startEpoch;
if (firstStart !== null && runtimeState.rundown.plannedStart !== null) {
runtimeState._startDayOffset = findDayOffset(runtimeState.rundown.plannedStart, firstStart);
}
if (currentDay !== undefined) {
runtimeState.rundown.currentDay = currentDay;
}
const { absolute, relative } = getRuntimeOffset(runtimeState);
runtimeState.offset.absolute = absolute;
runtimeState.offset.relative = relative;