refactor: create transaction system and apply to adding entry (#1620)

* refactor: create transaction system and apply to adding entry

* refactor: migrate edit mutations to transaction

* refactor: migrate delete mutation to transaction

* refactor: migrate reorder mutation to transaction

* refactor: migrate apply delay to transaction

* refactor: migrate swapEvents to transaction

* refactor: migrate clone to transaction

* refactor: migrate group/ungroup transactions

* refactor: simplify mutations

* refactor: migrate getters

* chore: add tests to processRundown()
This commit is contained in:
Carlos Valente
2025-06-05 06:14:29 +02:00
committed by arc-alex
parent 33ac05ebee
commit aebf949883
37 changed files with 3204 additions and 2704 deletions
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
import { SupportedEntry, OntimeEvent, OntimeBlock, Rundown } from 'ontime-types';
import { defaultRundown } from '../../../models/dataModel.js';
import { makeOntimeBlock, makeOntimeEvent } from '../../../services/rundown-service/__mocks__/rundown.mocks.js';
import { makeOntimeBlock, makeOntimeEvent } from '../__mocks__/rundown.mocks.js';
import { parseRundowns, parseRundown } from '../rundown.parser.js';
@@ -1,6 +1,8 @@
import { TimeStrategy, EndAction, TimerType, OntimeEvent } from 'ontime-types';
import { assertType } from 'vitest';
import { createEvent } from '../rundown.utils.js';
import { createEvent, deleteById, doesInvalidateMetadata, hasChanges } from '../rundown.utils.js';
describe('test event validator', () => {
it('validates a good object', () => {
@@ -78,3 +80,79 @@ describe('test event validator', () => {
expect(typeof validated.title).toEqual('string');
});
});
describe('doesInvalidateMetadata()', () => {
it('is stale if data contains timers', () => {
const needsRecompute = [
{ timeStart: 10 },
{ timeEnd: 10 },
{ duration: 10 },
{ linkStart: true },
{ timerStrategy: TimeStrategy.LockDuration },
];
for (const testCase of needsRecompute) {
expect(doesInvalidateMetadata(testCase)).toBe(true);
}
expect.assertions(needsRecompute.length);
});
it('is not stale if data contains auxiliary dataset', () => {
expect(
doesInvalidateMetadata({
cue: 'cue',
title: 'title',
note: 'note',
endAction: EndAction.LoadNext,
timerType: TimerType.Clock,
isPublic: false,
colour: 'colour',
timeWarning: 1,
timeDanger: 2,
custom: {
lighting: '3',
},
}),
).toBe(false);
});
});
describe('hasChanges()', () => {
it('identifies objects with new values', () => {
const newEvent = { id: '1', title: 'new-title' } as OntimeEvent;
const existing = { id: '1', cue: 'cue', title: 'title' } as OntimeEvent;
expect(hasChanges(existing, newEvent)).toBe(true);
});
it('identifies objects with all same values', () => {
const newEvent = { id: '1', title: 'title' } as OntimeEvent;
const existing = { id: '1', cue: 'cue', title: 'title' } as OntimeEvent;
expect(hasChanges(existing, newEvent)).toBe(false);
});
});
describe('deleteById', () => {
it('should delete the first instance of the specified ID from the array', () => {
const array = ['id1', 'id2', 'id3', 'id4'];
const result = deleteById(array, 'id2');
expect(result).toStrictEqual(['id1', 'id3', 'id4']);
expect(result).not.toBe(array); // Ensure a new array is returned
});
it('should not modify the array if the specified ID does not exist', () => {
const array = ['id1', 'id2', 'id3', 'id4'];
const result = deleteById(array, 'id5');
expect(result).toStrictEqual(['id1', 'id2', 'id3', 'id4']);
});
it('should return the same array if it is empty', () => {
const array: string[] = [];
const result = deleteById(array, 'id1');
expect(result).toStrictEqual([]);
});
it('should handle scenarios where the delete id is not found', () => {
const array = ['id1', 'id2', 'id3'];
const result = deleteById(array, 'id4');
expect(result).toStrictEqual(['id1', 'id2', 'id3']);
});
});