Skip to content

Commit 9bea15f

Browse files
authored
Merge pull request #1275 from nrkno/fix/sofie-3501/playoutModel-rundownsInOrder
fix: playout model rundowns not in order (SOFIE-3501)
2 parents 0320ffd + 913f988 commit 9bea15f

File tree

3 files changed

+119
-1
lines changed

3 files changed

+119
-1
lines changed

packages/corelib/src/playout/playlist.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { DBRundown } from '../dataModel/Rundown'
12
import { DBSegment } from '../dataModel/Segment'
23
import { DBPart } from '../dataModel/Part'
34
import { DBPartInstance } from '../dataModel/PartInstance'
@@ -89,3 +90,22 @@ export function sortRundownIDsInPlaylist(
8990

9091
return [...sortedVerifiedExisting, ...missingIds]
9192
}
93+
94+
export function sortRundownsWithinPlaylist(
95+
sortedPossibleIds: ReadonlyDeep<RundownId[]>,
96+
unsortedRundowns: DBRundown[]
97+
): DBRundown[] {
98+
return unsortedRundowns.slice().sort((a, b) => {
99+
const indexA = sortedPossibleIds.indexOf(a._id)
100+
const indexB = sortedPossibleIds.indexOf(b._id)
101+
if (indexA === -1 && indexB === -1) {
102+
return a._id.toString().localeCompare(b._id.toString())
103+
} else if (indexA === -1) {
104+
return 1
105+
} else if (indexB === -1) {
106+
return -1
107+
}
108+
109+
return indexA - indexB
110+
})
111+
}

packages/job-worker/src/playout/model/implementation/LoadPlayoutModel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { PeripheralDevice } from '@sofie-automation/corelib/dist/dataModel/Perip
2222
import { PlayoutModel, PlayoutModelPreInit } from '../PlayoutModel'
2323
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
2424
import { RundownBaselineObj } from '@sofie-automation/corelib/dist/dataModel/RundownBaselineObj'
25+
import { sortRundownsWithinPlaylist } from '@sofie-automation/corelib/dist/playout/playlist'
2526

2627
/**
2728
* Load a PlayoutModelPreInit for the given RundownPlaylist
@@ -59,7 +60,7 @@ export async function loadPlayoutModelPreInit(
5960
peripheralDevices: PeripheralDevices,
6061

6162
playlist: Playlist,
62-
rundowns: Rundowns,
63+
rundowns: sortRundownsWithinPlaylist(Playlist.rundownIdsInOrder, Rundowns),
6364

6465
getRundown: (id: RundownId) => Rundowns.find((rd) => rd._id === id),
6566
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import {
2+
setupDefaultRundown,
3+
setupDefaultRundownPlaylist,
4+
setupMockShowStyleCompound,
5+
} from '../../../../__mocks__/presetCollections'
6+
import { MockJobContext, setupDefaultJobEnvironment } from '../../../../__mocks__/context'
7+
import { ProcessedShowStyleCompound } from '../../../../jobs'
8+
import { ReadonlyDeep } from 'type-fest'
9+
import { protectString } from '@sofie-automation/corelib/dist/protectedString'
10+
import { loadPlayoutModelPreInit } from '../LoadPlayoutModel'
11+
import { runWithPlaylistLock } from '../../../../playout/lock'
12+
13+
describe('LoadPlayoutModel', () => {
14+
let context: MockJobContext
15+
let showStyleCompound: ReadonlyDeep<ProcessedShowStyleCompound>
16+
17+
beforeAll(async () => {
18+
context = setupDefaultJobEnvironment()
19+
20+
showStyleCompound = await setupMockShowStyleCompound(context)
21+
})
22+
23+
describe('loadPlayoutModelPreInit', () => {
24+
afterEach(async () =>
25+
Promise.all([
26+
context.mockCollections.RundownBaselineAdLibPieces.remove({}),
27+
context.mockCollections.RundownBaselineAdLibActions.remove({}),
28+
context.mockCollections.RundownBaselineObjects.remove({}),
29+
context.mockCollections.AdLibActions.remove({}),
30+
context.mockCollections.AdLibPieces.remove({}),
31+
context.mockCollections.Pieces.remove({}),
32+
context.mockCollections.Parts.remove({}),
33+
context.mockCollections.Segments.remove({}),
34+
context.mockCollections.Rundowns.remove({}),
35+
context.mockCollections.RundownPlaylists.remove({}),
36+
])
37+
)
38+
39+
test('Rundowns are in order specified in RundownPlaylist', async () => {
40+
// Set up a playlist:
41+
const { rundownId: rundownId00, playlistId: playlistId0 } = await setupDefaultRundownPlaylist(
42+
context,
43+
showStyleCompound,
44+
protectString('rundown00')
45+
)
46+
const rundownId01 = protectString('rundown01')
47+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId01)
48+
const rundownId02 = protectString('rundown02')
49+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId02)
50+
51+
const playlist0 = await context.mockCollections.RundownPlaylists.findOne(playlistId0)
52+
expect(playlist0).toBeTruthy()
53+
54+
if (!playlist0) throw new Error(`Playlist "${playlistId0}" not found!`)
55+
56+
const rundownIdsInOrder = [rundownId01, rundownId02, rundownId00]
57+
58+
await context.mockCollections.RundownPlaylists.update(playlistId0, {
59+
rundownIdsInOrder,
60+
})
61+
62+
await runWithPlaylistLock(context, playlistId0, async (lock) => {
63+
const model = await loadPlayoutModelPreInit(context, lock, playlist0)
64+
expect(model.rundowns.map((r) => r._id)).toMatchObject([rundownId01, rundownId02, rundownId00])
65+
})
66+
})
67+
68+
test('Rundowns not ordered in RundownPlaylist are at the end', async () => {
69+
// Set up a playlist:
70+
const { rundownId: rundownId00, playlistId: playlistId0 } = await setupDefaultRundownPlaylist(
71+
context,
72+
showStyleCompound,
73+
protectString('rundown00')
74+
)
75+
const rundownId01 = protectString('rundown01')
76+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId01)
77+
const rundownId02 = protectString('rundown02')
78+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId02)
79+
80+
const playlist0 = await context.mockCollections.RundownPlaylists.findOne(playlistId0)
81+
expect(playlist0).toBeTruthy()
82+
83+
if (!playlist0) throw new Error(`Playlist "${playlistId0}" not found!`)
84+
85+
const rundownIdsInOrder = [rundownId01]
86+
87+
await context.mockCollections.RundownPlaylists.update(playlistId0, {
88+
rundownIdsInOrder,
89+
})
90+
91+
await runWithPlaylistLock(context, playlistId0, async (lock) => {
92+
const model = await loadPlayoutModelPreInit(context, lock, playlist0)
93+
expect(model.rundowns.map((r) => r._id)).toMatchObject([rundownId01, rundownId00, rundownId02])
94+
})
95+
})
96+
})
97+
})

0 commit comments

Comments
 (0)