This commit is contained in:
2026-10-18 04:59:27 +07:00
parent 7a97b9b506
commit f5e645ec00
7 changed files with 267 additions and 51 deletions
+61 -4
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { ApiError, SessionChangedError } from './request-error.js'
import { buildScreenPackage, prepareScreenPackage } from './screen-package.js'
import { buildScreenPackage, prepareScreenPackage, parseScreenPackage } from './screen-package.js'
const server = 'https://example.test'
function fixture() {
@@ -151,7 +151,7 @@ test('неполные или некорректные ответы не ста
assert.throws(() => build(data))
}
assert.throws(() => buildScreenPackage(server, 7, { game: {}, plan: {}, music: {} }))
assert.throws(() =>
assert.doesNotThrow(() =>
buildScreenPackage(server, 7, { game: { game: { ID: 7, scenario: {} } }, plan: {}, music: {} }),
)
})
@@ -306,8 +306,6 @@ test('таймаут и отмена подготовки различаются
test('ошибка структуры описания называет запрос, поле и тип, не раскрывая значения', async () => {
for (const [badValue, expectedType] of [
[null, 'null'],
[undefined, 'поле отсутствует'],
[[], 'массив'],
['SECRET', 'string'],
] as const) {
@@ -366,3 +364,62 @@ test('ошибки элементов плана и треков сохраня
)
}
})
test('scenario и story могут отсутствовать или быть null; неверные типы остаются ошибкой', () => {
for (const scenario of [undefined, null, {}, { story: null }, { story: undefined }]) {
const pkg = buildScreenPackage(server, 7, {
game: { game: { ID: 7, scenario } },
plan: {
plan: {
steps: [
{ mode: 8, text: 'Текст' },
{ mode: 7, timerDurationSeconds: 60 },
],
},
},
music: {},
})
assert.deepEqual(pkg.assets, [])
assert.deepEqual(pkg.media, { cover: null, background: null, intro: null, conclusion: null })
assert.equal(pkg.steps.length, 2)
}
for (const scenario of [[], 'SECRET', { story: [] }, { story: 'SECRET' }]) {
assert.throws(
() =>
buildScreenPackage(server, 7, { game: { game: { ID: 7, scenario } }, plan: {}, music: {} }),
/game.scenario/,
)
}
})
test('ссылки состояния экрана определяют медиа без истории, включая явное отсутствие файла', () => {
const resources = {
cover: 'cover.png',
background: 'background.png',
intro: 'intro.wav',
conclusion: 'end.mp4',
}
const minimal = { game: { game: { ID: 7 } }, plan: {}, music: {} }
const pkg = buildScreenPackage(server, 7, minimal, resources)
assert.equal(pkg.assets.length, 4)
for (const [name, ref] of Object.entries(resources)) {
const id = pkg.media[name as keyof typeof pkg.media]
assert.equal(pkg.assets.find((a) => a.id === id)?.url, `${server}/api/files/${ref}`)
}
const cleared = buildScreenPackage(server, 7, fixture(), {
cover: '',
background: '',
intro: '',
conclusion: '',
})
assert.deepEqual(cleared.media, { cover: null, background: null, intro: null, conclusion: null })
assert.ok(!cleared.assets.some((a) => a.url.endsWith('final.mp4')))
const coverOnly = buildScreenPackage(server, 7, minimal, {
cover: 'cover.png',
background: '',
intro: '',
conclusion: '',
})
assert.equal(coverOnly.media.background, null)
for (const value of [pkg, cleared, coverOnly]) assert.deepEqual(parseScreenPackage(value), value)
})