fix: issue where a end time can be overflowing (#761)

This commit is contained in:
Carlos Valente
2024-02-06 11:42:28 +01:00
committed by GitHub
parent 965a7092d9
commit 467b595375
10 changed files with 94 additions and 13 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ontime-ui",
"version": "2.28.12",
"version": "2.28.13",
"private": true,
"dependencies": {
"@chakra-ui/react": "^2.7.0",
@@ -1,7 +1,7 @@
import { memo } from 'react';
import { Select, Switch } from '@chakra-ui/react';
import { EndAction, OntimeEvent, TimerType } from 'ontime-types';
import { calculateDuration, millisToString } from 'ontime-utils';
import { calculateDuration, dayInMs, millisToString } from 'ontime-utils';
import TimeInput from '../../../common/components/input/time-input/TimeInput';
import { useEventAction } from '../../../common/hooks/useEventAction';
@@ -28,14 +28,13 @@ const EventEditorTimes = (props: EventEditorTimesProps) => {
const { eventId, timeStart, timeEnd, duration, delay, isPublic, endAction, timerType } = props;
const { updateEvent } = useEventAction();
const handleSubmit = (field: TimeActions, value: number | string | boolean) => {
const newEventData: Partial<OntimeEvent> = { id: eventId };
switch (field) {
case 'durationOverride': {
// duration defines timeEnd
newEventData.duration = value as number;
newEventData.timeEnd = timeStart + (value as number);
newEventData.timeEnd = timeStart + ((value as number) % dayInMs);
break;
}
case 'timeStart': {
@@ -1,6 +1,6 @@
import { memo } from 'react';
import { OntimeEvent } from 'ontime-types';
import { calculateDuration, millisToString } from 'ontime-utils';
import { calculateDuration, dayInMs, millisToString } from 'ontime-utils';
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
import { useEventAction } from '../../../../common/hooks/useEventAction';
@@ -29,7 +29,7 @@ const EventBlockTimers = (props: EventBlockTimerProps) => {
case 'durationOverride': {
// duration defines timeEnd
newEventData.duration = value;
newEventData.timeEnd = timeStart + value;
newEventData.timeEnd = timeStart + ((value as number) % dayInMs);
break;
}
case 'timeStart': {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ontime",
"version": "2.28.12",
"version": "2.28.13",
"author": "Carlos Valente",
"description": "Time keeping for live events",
"repository": "https://github.com/cpvalente/ontime",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "ontime-server",
"type": "module",
"main": "src/index.ts",
"version": "2.28.12",
"version": "2.28.13",
"exports": "./src/index.js",
"dependencies": {
"@googleapis/sheets": "^5.0.5",
@@ -528,6 +528,76 @@ describe('test that roll behaviour multi day event edge cases', () => {
});
});
// test getRollTimers() on issue #757
describe('it handles timeEnd over day', () => {
it('ignores events with timeEnd larger than a day', () => {
const testRundown = [
{
title: 'Setup',
subtitle: '',
presenter: '',
note: 'BMA, Nebelfluid, Shooter, Akkus, UHF11, Getränke, Kaffee, Strom, ELA, Text für Holger',
endAction: 'play-next',
timerType: 'count-down',
timeStart: 66600000,
timeEnd: 68400000,
duration: 1800000,
isPublic: false,
skip: false,
colour: '#2fa9e5',
user0: '',
user1: '',
user2: '',
user3: '',
user4: '',
user5: '',
user6: '',
user7: '',
user8: '',
user9: '',
type: 'event',
revision: 0,
cue: 'PRE',
id: 'b2f8d',
},
{
title: 'Künstliche Intelligenz',
subtitle: ' -> Vorstellung Maske',
presenter: 'Engel und Teufel',
note: 'Melli Kleben! Sofa',
endAction: 'play-next',
timerType: 'count-down',
timeStart: 86100000,
// timeEnd: 1020000, <--- this would have been equivalent
timeEnd: 87420000,
duration: 1320000,
isPublic: true,
skip: false,
colour: '#a8ec31',
user0: 'UHF1 Melli (Korsett)',
user1: 'UHF2 Reinhold (unter Flügel)',
user2: 'UHF3 Oli (Sport-Unterhose Rechts)',
user3: '',
user4: '',
user5: '',
user6: '',
user7: '',
user8: '',
user9: '',
type: 'event',
revision: 0,
cue: '16',
id: '8b970',
},
];
const timeNow = 64488675; // 17:55-something
const timers = getRollTimers(testRundown as OntimeEvent[], timeNow);
expect(timers.currentEvent).toBeNull();
});
});
// test normaliseEndTime() on issue #58
test('test typical scenarios', () => {
const t1 = {
+2 -1
View File
@@ -79,7 +79,8 @@ export const getRollTimers = (rundown: OntimeEvent[], timeNow: number) => {
const normalEnd = normaliseEndTime(event.timeStart, event.timeEnd);
const hasNotEnded = normalEnd > timeNow;
const isFromDayBefore = normalEnd > dayInMs && timeNow < event.timeEnd;
// TODO: we will likely want a better solution than the modulus here
const isFromDayBefore = normalEnd > dayInMs && timeNow < event.timeEnd % dayInMs;
const hasStarted = isFromDayBefore || timeNow >= event.timeStart;
if (normalEnd <= timeNow) {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ontime",
"version": "2.28.12",
"version": "2.28.13",
"description": "Time keeping for live events",
"keywords": [
"lightdev",
@@ -93,6 +93,17 @@ describe('validateTimes()', () => {
expect(timeEnd).toBe(10);
expect(duration).toBe(10);
});
it('ensures values dont overflow dayMs', () => {
const start = 86100000;
const endOverDay = 87420000;
const durationNormal = 1320000;
const { timeStart, timeEnd, duration } = validateTimes(start, endOverDay, durationNormal);
expect(timeStart).toBe(start);
expect(timeEnd).toBe(1020000);
expect(duration).toBe(durationNormal);
});
});
describe('calculateDuration()', () => {
@@ -52,9 +52,9 @@ function convertToInteger(value: unknown): number {
* @param _duration
*/
export function validateTimes(_start?: unknown, _end?: unknown, _duration?: unknown) {
const timeStart = convertToInteger(_start);
const timeEnd = convertToInteger(_end);
const duration = convertToInteger(_duration);
const timeStart = convertToInteger(_start) % dayInMs;
const timeEnd = convertToInteger(_end) % dayInMs;
const duration = convertToInteger(_duration) % dayInMs;
if (_start != null && _end != null) {
// Case 1. if we have start and end, duration must be derived