From 7fa0004ab993110760212f0bb66bf286dbe83932 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Mon, 19 Oct 2026 00:57:56 +0700 Subject: [PATCH] fix --- electron/diagnostics.test.ts | 2 +- electron/diagnostics.ts | 2 +- electron/online.test.ts | 2 +- electron/request-error.ts | 2 +- electron/screen-package.test.ts | 14 ++++++++------ electron/screen-package.ts | 8 ++++---- scripts/materials-prepare-smoke.cjs | 5 ++++- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/electron/diagnostics.test.ts b/electron/diagnostics.test.ts index af9d216..1328d48 100644 --- a/electron/diagnostics.test.ts +++ b/electron/diagnostics.test.ts @@ -27,7 +27,7 @@ test('журнал сохраняет только разрешённые пол }) log.record('request-error', { path: '/api/games/7?token=SECRET', reason: 'ENOTFOUND' }) log.record('request-error', { path: '/api/games/{id}', reason: 'SECRET' }) - log.record('request-error', { path: '/api/scenarios/{id}', reason: 'AUTH', token: 'SECRET' }) + log.record('request-error', { path: '/api/scenarios/{id}/full', reason: 'AUTH', token: 'SECRET' }) const content = await readFile(join(dir, 'diagnostic.jsonl'), 'utf8') assert.equal(content.includes('SECRET'), false) const lines = content diff --git a/electron/diagnostics.ts b/electron/diagnostics.ts index fdf9584..f3f67a5 100644 --- a/electron/diagnostics.ts +++ b/electron/diagnostics.ts @@ -28,7 +28,7 @@ const fields: Partial>> = { ], }, 'request-error': { - path: ['/api/games/{id}', '/api/games/{id}/screen-plan', '/api/games/{id}/music', '/api/scenarios/{id}'], + path: ['/api/games/{id}', '/api/games/{id}/screen-plan', '/api/games/{id}/music', '/api/scenarios/{id}/full'], reason: [...NETWORK_ERROR_CODES, 'AUTH', 'HTTP', 'INVALID_JSON', 'SESSION_CHANGED'], }, 'media-error': { channel: ['main', 'music', 'scene'] }, diff --git a/electron/online.test.ts b/electron/online.test.ts index 083d87b..8b7b538 100644 --- a/electron/online.test.ts +++ b/electron/online.test.ts @@ -163,7 +163,7 @@ async function fixture(t: TestContext, secure = true) { return json({}, 401) if (model.refreshExpired) return json({}, 401) if (path === '/api/users/me') return json({ user: { roles: model.roles } }) - if (path === '/api/scenarios/23') return model.scenarioError ? json({}, model.scenarioError) : json({ scenario: { ID: 23, image: 'https://media.test/cover.png', story: { background: 'https://media.test/background.png', introduction: { audio: model.introURL }, questions: [{ answer: 'PRIVATE-ANSWER' }] } } }) + if (path === '/api/scenarios/23/full') return model.scenarioError ? json({}, model.scenarioError) : json({ scenario: { ID: 23, image: 'https://media.test/cover.png', story: { background: 'https://media.test/background.png', introduction: { audio: model.introURL }, questions: [{ answer: 'PRIVATE-ANSWER' }] } } }) if (path === '/api/games') return json({ games: [ diff --git a/electron/request-error.ts b/electron/request-error.ts index e8aefb7..e73b6f0 100644 --- a/electron/request-error.ts +++ b/electron/request-error.ts @@ -136,7 +136,7 @@ export function requestErrorContext( if (contextualErrors.has(result)) return result const names: Record = { GetGame: 'Описание игры', - GetScenario: 'Сценарий игры', + GetFullScenario: 'Сценарий игры', GetGameMusic: 'Музыка игры', GetScreenPlan: 'План экранов', SaveScreenPlan: 'Сохранение плана', diff --git a/electron/screen-package.test.ts b/electron/screen-package.test.ts index 2b821e5..a6d0190 100644 --- a/electron/screen-package.test.ts +++ b/electron/screen-package.test.ts @@ -195,11 +195,13 @@ test('полный сценарий добавляет фон и введени 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) + if (url.endsWith('/scenarios/23')) return Response.json({ scenario: { ID: 23, image: 'cover.png' } }) + return Response.json(url.endsWith('/scenarios/23/full') ? 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.ok(calls.includes(`${server}/api/scenarios/23/full`)) + 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) @@ -212,17 +214,17 @@ test('недоступный или неполный сценарий преду 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 : {}) + return url.endsWith('/scenarios/23/full') ? 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' }]) + if (status !== 200) assert.deepEqual(failures, [{ path: '/api/scenarios/{id}/full', 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 : {})), + Response.json(String(input).endsWith('/scenarios/23/full') ? { 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 : {})), + Response.json(String(input).endsWith('/scenarios/23/full') ? null : String(input).endsWith('/games/7') ? game : {})), /Сценарий игры.*scenarioResponse/) }) diff --git a/electron/screen-package.ts b/electron/screen-package.ts index 1aa3222..e4e9e13 100644 --- a/electron/screen-package.ts +++ b/electron/screen-package.ts @@ -329,7 +329,7 @@ export async function prepareScreenPackage( : meta.method === 'GetScreenPlan' ? '/screen-plan' : '' - const safePath = meta.method === 'GetScenario' ? '/api/scenarios/{id}' : `/api/games/{id}${suffix}` + const safePath = meta.method === 'GetFullScenario' ? '/api/scenarios/{id}/full' : `/api/games/{id}${suffix}` let response: Response try { response = await fetchAPI(`${server}/${requestData.path}`, { @@ -397,7 +397,7 @@ export async function prepareScreenPackage( let response let received = false try { - response = await client.GetScenario({ ID: scenarioId }) + response = await client.GetFullScenario({ ID: scenarioId }) received = true } catch (error) { if (signal.aborted || error instanceof SessionChangedError || (error instanceof ApiError && error.status === 401)) throw error @@ -413,7 +413,7 @@ export async function prepareScreenPackage( gameData.scenario = { ...scenario, ...full, story: full.story } if (full.story == null) request.onIncomplete?.() } catch (error) { - throw requestErrorContext(error, 'GetScenario', 'GET', `/api/scenarios/${scenarioId}`) + throw requestErrorContext(error, 'GetFullScenario', 'GET', `/api/scenarios/${scenarioId}/full`) } } } else if (scenario.story == null) request.onIncomplete?.() @@ -422,7 +422,7 @@ export async function prepareScreenPackage( } catch (error) { const field = error instanceof ResponseFieldError ? error.field : 'game' if (fullScenarioId !== null && field.startsWith('game.scenario.')) - throw requestErrorContext(error, 'GetScenario', 'GET', `/api/scenarios/${fullScenarioId}`) + throw requestErrorContext(error, 'GetFullScenario', 'GET', `/api/scenarios/${fullScenarioId}/full`) const state = field.startsWith('state.') const suffix = field.startsWith('plan') ? '/screen-plan' diff --git a/scripts/materials-prepare-smoke.cjs b/scripts/materials-prepare-smoke.cjs index 3c94d60..709c0cd 100644 --- a/scripts/materials-prepare-smoke.cjs +++ b/scripts/materials-prepare-smoke.cjs @@ -24,7 +24,8 @@ module.exports = async ({ evaluate, poll }) => { if (request.url === '/api/games/7/music') return send({ gamePlaylistId: 1, playlists: [{ ID: 1, name: 'Музыка', tracks: Array.from({ length: 13 }, (_, index) => ({ ID: index + 1, name: `Трек ${index}`, filename: `track-${index}.wav` })), }] }) - if (request.url === '/api/scenarios/23') return send({ scenario: { ID: 23, image: 'cover.png', story: { background: 'background.png', introduction: { audio: 'intro.wav' } } } }, scenarioError ? 403 : 200) + if (request.url === '/api/scenarios/23') return send({ scenario: { ID: 23, image: 'cover.png' } }) + if (request.url === '/api/scenarios/23/full') return send({ scenario: { ID: 23, image: 'cover.png', story: { background: 'background.png', introduction: { audio: 'intro.wav' } } } }, scenarioError ? 403 : 200) if (request.url.startsWith('/api/files/')) { response.writeHead(200, { 'Content-Type': request.url.endsWith('.png') ? 'image/png' : 'audio/wav' }) response.end(request.url.endsWith('.png') ? image : soundCheckWav) @@ -42,6 +43,8 @@ module.exports = async ({ evaluate, poll }) => { await evaluate('window.screenBridge.onlineAction({ action: "select-game", gameId: 7 })') const result = await evaluate('window.screenBridge.onlineState()') assert.equal(result.materials.length, 16) + assert.ok(requests.includes('/api/scenarios/23/full')) + assert.ok(!requests.includes('/api/scenarios/23')) assert.ok(result.materials.every((m) => m.status === 'ready')) assert.ok(result.materials.some((m) => m.usages.some((u) => u.name === 'Фон'))) assert.ok(result.materials.some((m) => m.usages.some((u) => u.name === 'Вступление')))