This commit is contained in:
2026-10-19 00:48:46 +07:00
parent 0f948b316a
commit 5635b8b5b1
13 changed files with 252 additions and 11 deletions
+76
View File
@@ -180,6 +180,82 @@ test('получает данные через три существующих A
assert.ok(!JSON.stringify(result).includes('SECRET'))
})
test('полный сценарий добавляет фон и введение до подключения: 14 файлов становятся 16', async () => {
const game = { game: { ID: 7, name: 'Игра', scenario: { ID: 23, image: 'cover.png' } } }
const full = { scenario: { ID: 23, image: 'cover.png', story: {
background: 'background.png', introduction: { audio: 'intro.wav' },
questions: [{ answer: 'PRIVATE-ANSWER' }],
} } }
const music = { gamePlaylistId: 1, playlists: [{ ID: 1, name: 'Музыка', tracks:
Array.from({ length: 13 }, (_, index) => ({ ID: index + 1, name: `Трек ${index}`, filename: `track-${index}.wav` })),
}] }
assert.equal(buildScreenPackage(server, 7, { game, plan: {}, music }).assets.length, 14)
const calls: string[] = []
let incomplete = false
const pkg = await prepareScreenPackage({ server, gameId: 7, token: 'SECRET', onIncomplete: () => { incomplete = true } }, async (input) => {
const url = String(input)
calls.push(url)
return Response.json(url.endsWith('/scenarios/23') ? full : url.endsWith('/music') ? music : url.endsWith('/screen-plan') ? {} : game)
})
assert.equal(pkg.assets.length, 16)
assert.ok(pkg.media.background && pkg.media.intro)
assert.ok(calls.includes(`${server}/api/scenarios/23`))
assert.equal(incomplete, false)
assert.equal(JSON.stringify(pkg).includes('PRIVATE-ANSWER'), false)
assert.deepEqual(parseScreenPackage(pkg), pkg)
})
test('недоступный или неполный сценарий предупреждает о неполном списке, чужой ID отклоняется', async () => {
const game = { game: { ID: 7, scenario: { ID: 23, image: 'cover.png' } } }
for (const status of [403, 404, 500, 200]) {
let incomplete = false
const failures: unknown[] = []
const pkg = await prepareScreenPackage({ server, gameId: 7, token: 'SECRET', onIncomplete: () => { incomplete = true }, onRequestFailure: (failure) => failures.push(failure) }, async (input) => {
const url = String(input)
return url.endsWith('/scenarios/23') ? Response.json({ scenario: { ID: 23 } }, { status }) : Response.json(url.endsWith('/games/7') ? game : {})
})
assert.equal(incomplete, true)
assert.equal(pkg.assets.length, 1)
if (status !== 200) assert.deepEqual(failures, [{ path: '/api/scenarios/{id}', reason: status === 403 ? 'AUTH' : 'HTTP' }])
}
await assert.rejects(prepareScreenPackage({ server, gameId: 7, token: 'SECRET' }, async (input) =>
Response.json(String(input).endsWith('/scenarios/23') ? { scenario: { ID: 24 } } : String(input).endsWith('/games/7') ? game : {})),
/Сценарий игры.*GET \/api\/scenarios\/23.*другой сценарий/)
await assert.rejects(prepareScreenPackage({ server, gameId: 7, token: 'SECRET' }, async (input) =>
Response.json(String(input).endsWith('/scenarios/23') ? null : String(input).endsWith('/games/7') ? game : {})),
/Сценарий игры.*scenarioResponse/)
})
test('состояние подключённого экрана имеет приоритет и не требует сценария', async () => {
const data = fixture()
Object.assign(data.game.game.scenario, { ID: 23 })
let calls = 0
const pkg = await prepareScreenPackage({ server, gameId: 7, token: 'SECRET', resources: { cover: 'current.png', background: '', intro: '', conclusion: '' } }, async (input) => {
const url = String(input)
assert.ok(!url.includes('/scenarios/'))
calls++
return Response.json(url.endsWith('/music') ? data.music : url.endsWith('/screen-plan') ? data.plan : data.game)
})
assert.equal(calls, 3)
assert.equal(pkg.media.intro, null)
assert.ok(pkg.assets.some((asset) => asset.url.endsWith('/current.png')))
})
test('отмена запроса полного сценария не выдаёт неполный пакет', async () => {
const abort = new AbortController()
const timer = setTimeout(() => abort.abort(), 20)
let incomplete = false
try {
await assert.rejects(prepareScreenPackage({ server, gameId: 7, token: 'SECRET', signal: abort.signal, onIncomplete: () => { incomplete = true } }, async (input, init) => {
if (String(input).includes('/scenarios/')) return new Promise((_resolve, reject) => {
init!.signal!.addEventListener('abort', () => reject(init!.signal!.reason), { once: true })
})
return Response.json(String(input).endsWith('/games/7') ? { game: { ID: 7, scenario: { ID: 23 } } } : {})
}), /Сценарий игры.*отмен/)
assert.equal(incomplete, false)
} finally { clearTimeout(timer) }
})
test('отказы API и некорректный JSON не выдают частичный пакет или ответ с секретом', async () => {
for (const status of [401, 403, 404, 500]) {
await assert.rejects(