Files
evening_detective_screen/electron/api-client.test.ts
T
2026-10-18 04:40:55 +07:00

81 lines
3.2 KiB
TypeScript

import assert from 'node:assert/strict'
import { test } from 'node:test'
import { createEveningDetectiveServerClient } from './api/generated/crabs/evening_detective_server/index.js'
import { apiPlan, apiScreenMode, apiScreenCommand } from './api-values.js'
import { parsePlan } from './screen-plan.js'
import { parseRemote } from './remote-state.js'
test('клиент proto задаёт маршруты, методы и JSON enum существующего gateway', async () => {
const calls: { path: string; method: string; body: string | null }[] = []
const client = createEveningDetectiveServerClient(async (request) => {
calls.push(request)
return {}
})
await client.Login({ email: 'dev@example.test', password: 'SECRET' })
await client.Refresh({ refreshToken: 'SECRET' })
await client.GetMe({})
await client.GetGames({})
await client.GetGame({ ID: 7 })
await client.GetScreenPlan({ gameID: 7 })
await client.GetGameMusic({ gameID: 7 })
const plan = parsePlan({
steps: [
{ mode: 8, text: 'Улика' },
{ mode: 7, timerDurationSeconds: 60 },
],
})
await client.SaveScreenPlan({ gameID: 7, ...apiPlan(plan) })
await client.SetScreenMode({ gameID: 7, mode: apiScreenMode(2) })
await client.SendScreenCommand({
gameID: 7,
command: apiScreenCommand(6),
positionMs: 1500,
volume: 50,
})
assert.deepEqual(
calls.map((c) => [c.method, c.path]),
[
['POST', 'api/auth/login'],
['POST', 'api/auth/refresh'],
['GET', 'api/users/me'],
['GET', 'api/games'],
['GET', 'api/games/7'],
['GET', 'api/games/7/screen-plan'],
['GET', 'api/games/7/music'],
['PUT', 'api/games/7/screen-plan'],
['POST', 'api/games/7/screens/mode'],
['POST', 'api/games/7/screens/command'],
],
)
assert.deepEqual(parsePlan(JSON.parse(calls[7]!.body!)), plan)
assert.equal(JSON.parse(calls[7]!.body!).steps[0].mode, 'SCREEN_MODE_TEXT')
assert.equal(JSON.parse(calls[8]!.body!).mode, 'SCREEN_MODE_INTRO')
assert.equal(JSON.parse(calls[9]!.body!).command, 'SCREEN_COMMAND_SEEK')
assert.throws(() => apiScreenMode(99), /режим/)
assert.throws(() => apiScreenCommand(99), /команда/)
})
test('ответ proto сохраняет строковый int64, enum и отсутствующие поля для проверки границы', async () => {
const client = createEveningDetectiveServerClient(async () =>
JSON.parse(
'{"state":{"stateVersion":"9007199254740993","mode":"SCREEN_MODE_TEXT","text":"Текст","positionMs":"1500"}}',
),
)
const next = parseRemote(
(await client.GetScreenState({ screenID: '12', accessToken: 'SECRET' })).state,
)
assert.equal(next.version, 9007199254740993n)
assert.equal(next.mode, 8)
assert.equal(next.position, 1.5)
assert.equal(next.music, null)
const invalid = createEveningDetectiveServerClient(async () => ({
state: { stateVersion: 9007199254740992 },
}))
assert.throws(() => parseRemote({ stateVersion: 9007199254740992 }), /версия/)
await assert.rejects(
async () =>
parseRemote((await invalid.GetScreenState({ screenID: '12', accessToken: 'SECRET' })).state),
/версия/,
)
})