mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 23:19:09 +00:00
fix: restore process sets currentDay
This commit is contained in:
committed by
Carlos Valente
parent
1b55254834
commit
f8cde5d627
@@ -13,6 +13,7 @@ describe('isRestorePoint()', () => {
|
|||||||
pausedAt: 3,
|
pausedAt: 3,
|
||||||
firstStart: 1,
|
firstStart: 1,
|
||||||
startEpoch: 1,
|
startEpoch: 1,
|
||||||
|
currentDay: 0,
|
||||||
};
|
};
|
||||||
expect(isRestorePoint(restorePoint)).toBe(true);
|
expect(isRestorePoint(restorePoint)).toBe(true);
|
||||||
|
|
||||||
@@ -24,6 +25,21 @@ describe('isRestorePoint()', () => {
|
|||||||
pausedAt: null,
|
pausedAt: null,
|
||||||
firstStart: 1,
|
firstStart: 1,
|
||||||
startEpoch: 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);
|
expect(isRestorePoint(restorePoint)).toBe(true);
|
||||||
});
|
});
|
||||||
@@ -63,5 +79,39 @@ describe('isRestorePoint()', () => {
|
|||||||
};
|
};
|
||||||
expect(isRestorePoint(restorePoint)).toBe(false);
|
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,
|
pausedAt: 9087,
|
||||||
firstStart: 1234,
|
firstStart: 1234,
|
||||||
startEpoch: 1234,
|
startEpoch: 1234,
|
||||||
|
currentDay: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockRead = vi.fn().mockResolvedValue(expected);
|
const mockRead = vi.fn().mockResolvedValue(expected);
|
||||||
@@ -35,6 +36,7 @@ describe('restoreService', () => {
|
|||||||
pausedAt: null,
|
pausedAt: null,
|
||||||
firstStart: 1234,
|
firstStart: 1234,
|
||||||
startEpoch: 1234,
|
startEpoch: 1234,
|
||||||
|
currentDay: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockRead = vi.fn().mockResolvedValue(expected);
|
const mockRead = vi.fn().mockResolvedValue(expected);
|
||||||
@@ -82,6 +84,7 @@ describe('restoreService', () => {
|
|||||||
pausedAt: 1234,
|
pausedAt: 1234,
|
||||||
firstStart: 1234,
|
firstStart: 1234,
|
||||||
startEpoch: 1234,
|
startEpoch: 1234,
|
||||||
|
currentDay: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockWrite = vi.fn().mockResolvedValue(undefined);
|
const mockWrite = vi.fn().mockResolvedValue(undefined);
|
||||||
@@ -90,6 +93,39 @@ describe('restoreService', () => {
|
|||||||
expect(mockWrite).toHaveBeenCalledWith(testData);
|
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 () => {
|
it('handles write failures gracefully', async () => {
|
||||||
const testData: RestorePoint = {
|
const testData: RestorePoint = {
|
||||||
playback: Playback.Pause,
|
playback: Playback.Pause,
|
||||||
@@ -99,6 +135,7 @@ describe('restoreService', () => {
|
|||||||
pausedAt: 5678,
|
pausedAt: 5678,
|
||||||
firstStart: 5678,
|
firstStart: 5678,
|
||||||
startEpoch: 5678,
|
startEpoch: 5678,
|
||||||
|
currentDay: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockWrite = vi.fn().mockRejectedValue(new Error('Write failed'));
|
const mockWrite = vi.fn().mockRejectedValue(new Error('Write failed'));
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
|
|||||||
'pausedAt',
|
'pausedAt',
|
||||||
'firstStart',
|
'firstStart',
|
||||||
'startEpoch',
|
'startEpoch',
|
||||||
|
'currentDay',
|
||||||
])
|
])
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -54,5 +55,9 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is.number(restorePoint.currentDay) && restorePoint.currentDay !== null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ export type RestorePoint = {
|
|||||||
pausedAt: MaybeNumber;
|
pausedAt: MaybeNumber;
|
||||||
firstStart: MaybeNumber;
|
firstStart: MaybeNumber;
|
||||||
startEpoch: MaybeNumber;
|
startEpoch: MaybeNumber;
|
||||||
|
currentDay: MaybeNumber;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -759,6 +759,7 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
|
|||||||
pausedAt: state._timer.pausedAt,
|
pausedAt: state._timer.pausedAt,
|
||||||
firstStart: state.rundown.actualStart,
|
firstStart: state.rundown.actualStart,
|
||||||
startEpoch: state._startEpoch,
|
startEpoch: state._startEpoch,
|
||||||
|
currentDay: state.rundown.currentDay,
|
||||||
})
|
})
|
||||||
.catch((_e) => {
|
.catch((_e) => {
|
||||||
//we don't do anything with the error here
|
//we don't do anything with the error here
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import {
|
|||||||
load,
|
load,
|
||||||
loadGroupFlagAndEnd,
|
loadGroupFlagAndEnd,
|
||||||
pause,
|
pause,
|
||||||
|
resume,
|
||||||
roll,
|
roll,
|
||||||
start,
|
start,
|
||||||
stop,
|
stop,
|
||||||
|
update,
|
||||||
} from '../runtimeState.js';
|
} from '../runtimeState.js';
|
||||||
import { rundownCache } from '../../api-data/rundown/rundown.dao.js';
|
import { rundownCache } from '../../api-data/rundown/rundown.dao.js';
|
||||||
import { RundownMetadata } from '../../api-data/rundown/rundown.types.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.absolute).toBe(0);
|
||||||
expect(newState.offset.expectedRundownEnd).toBeNull();
|
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', () => {
|
describe('roll mode', () => {
|
||||||
|
|||||||
@@ -246,12 +246,19 @@ export function load(
|
|||||||
patchTimer(initialData);
|
patchTimer(initialData);
|
||||||
const startEpoch = initialData?.startEpoch;
|
const startEpoch = initialData?.startEpoch;
|
||||||
const firstStart = initialData?.firstStart;
|
const firstStart = initialData?.firstStart;
|
||||||
|
const currentDay = initialData?.currentDay;
|
||||||
if (
|
if (
|
||||||
(firstStart === null || typeof firstStart === 'number') &&
|
(firstStart === null || typeof firstStart === 'number') &&
|
||||||
(startEpoch === null || typeof startEpoch === 'number')
|
(startEpoch === null || typeof startEpoch === 'number')
|
||||||
) {
|
) {
|
||||||
runtimeState.rundown.actualStart = firstStart;
|
runtimeState.rundown.actualStart = firstStart;
|
||||||
runtimeState._startEpoch = startEpoch;
|
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);
|
const { absolute, relative } = getRuntimeOffset(runtimeState);
|
||||||
runtimeState.offset.absolute = absolute;
|
runtimeState.offset.absolute = absolute;
|
||||||
runtimeState.offset.relative = relative;
|
runtimeState.offset.relative = relative;
|
||||||
|
|||||||
Reference in New Issue
Block a user