89c06b58c3
live 验收(8/8, api.aishufu.top admin):登录可达、未登录 401、历史记录(时间范围 避免生产 sort buffer 报错)、软件版本列表、数字人版本列表、字段/信封契约。 EOF
115 lines
4.8 KiB
TypeScript
115 lines
4.8 KiB
TypeScript
import test from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { parseHistoryPage } from '../../src/pages/records/history-model.ts'
|
||
import { parseSoftwareVersionList } from '../../src/pages/records/version-model.ts'
|
||
import { parseDigitalHumanVersions } from '../../src/pages/records/digitalhuman-model.ts'
|
||
|
||
const BASE = process.env.AIIMAGE_LIVE_BASE || 'http://127.0.0.1:18080'
|
||
const USER = process.env.AIIMAGE_LIVE_USER || ''
|
||
const PASS = process.env.AIIMAGE_LIVE_PASS || ''
|
||
const HAS_CREDS = Boolean(USER && PASS)
|
||
const DEVICE = 'claude-task140-records-acceptance'
|
||
|
||
let sessionCookie = ''
|
||
let bearerToken = ''
|
||
|
||
async function ensureSession(): Promise<void> {
|
||
if (sessionCookie || bearerToken) return
|
||
const res = await fetch(`${BASE}/login`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username: USER, password: PASS, deviceId: DEVICE }),
|
||
})
|
||
const body = (await res.json()) as { success?: boolean; message?: string; data?: { token?: string } }
|
||
assert.equal(body.success, true, `登录应成功: ${body.message || ''}`)
|
||
if (body.data?.token) bearerToken = body.data.token
|
||
const cookies = typeof res.headers.getSetCookie === 'function' ? res.headers.getSetCookie() : []
|
||
const setCookie = cookies[0] || res.headers.get('set-cookie') || ''
|
||
const match = /aiimage_token=([^;]+)/.exec(setCookie)
|
||
if (match) sessionCookie = `aiimage_token=${match[1]}`
|
||
assert.ok(sessionCookie || bearerToken, '登录应下发会话 cookie 或 token')
|
||
}
|
||
|
||
async function authedFetch(path: string, init: RequestInit = {}): Promise<Response> {
|
||
const headers: Record<string, string> = { ...(init.headers as Record<string, string>) }
|
||
if (sessionCookie) headers.Cookie = sessionCookie
|
||
else if (bearerToken) headers.Authorization = `Bearer ${bearerToken}`
|
||
return fetch(`${BASE}${path}`, { ...init, headers })
|
||
}
|
||
|
||
test('test_task_140_records_live_reachability', async () => {
|
||
// 真实服务在线。
|
||
const res = await fetch(`${BASE}/login`)
|
||
assert.equal(res.status, 200)
|
||
})
|
||
|
||
test('test_task_140_records_live_unauth', async () => {
|
||
// 未登录访问后台记录/版本 → 401。
|
||
for (const path of ['/api/admin/history?page=1&page_size=5&time_start=2026-08-01 00:00:00&time_end=2026-09-05 23:59:59', '/api/admin/versions']) {
|
||
const res = await fetch(`${BASE}${path}`)
|
||
const body = (await res.json()) as { success?: boolean; code?: number }
|
||
assert.equal(body.success, false, path)
|
||
assert.equal(body.code, 401, path)
|
||
}
|
||
})
|
||
|
||
test('test_task_140_records_live_history', { skip: !HAS_CREDS }, async () => {
|
||
// 真实历史记录分页。
|
||
await ensureSession()
|
||
const res = await authedFetch('/api/admin/history?page=1&page_size=5&time_start=2026-08-01 00:00:00&time_end=2026-09-05 23:59:59')
|
||
const page = parseHistoryPage(await res.json())
|
||
assert.equal(res.status, 200)
|
||
assert.ok(Array.isArray(page.items))
|
||
assert.equal(typeof page.total, 'number')
|
||
})
|
||
|
||
test('test_task_140_records_live_versions', { skip: !HAS_CREDS }, async () => {
|
||
// 真实客户端软件版本列表。
|
||
await ensureSession()
|
||
const res = await authedFetch('/api/admin/versions')
|
||
const list = parseSoftwareVersionList(await res.json())
|
||
assert.equal(res.status, 200)
|
||
assert.ok(Array.isArray(list.items))
|
||
})
|
||
|
||
test('test_task_140_records_live_digital_human', { skip: !HAS_CREDS }, async () => {
|
||
// 真实数字人版本列表。
|
||
await ensureSession()
|
||
const res = await authedFetch('/api/digital-human/versions')
|
||
const list = parseDigitalHumanVersions(await res.json())
|
||
assert.equal(res.status, 200)
|
||
assert.ok(Array.isArray(list.items))
|
||
})
|
||
|
||
test('test_task_140_records_live_contract', { skip: !HAS_CREDS }, async () => {
|
||
// 统一信封覆盖后台列表。
|
||
await ensureSession()
|
||
for (const path of ['/api/admin/versions']) {
|
||
const res = await authedFetch(path)
|
||
const body = (await res.json()) as { success?: boolean; data?: unknown }
|
||
assert.equal(body.success, true, path)
|
||
assert.ok(body.data && typeof body.data === 'object', path)
|
||
}
|
||
})
|
||
|
||
test('test_task_140_records_live_history_items', { skip: !HAS_CREDS }, async () => {
|
||
// 历史行字段契约(若有数据):username/panel_type 均为 string。
|
||
await ensureSession()
|
||
const res = await authedFetch('/api/admin/history?page=1&page_size=5&time_start=2026-08-01 00:00:00&time_end=2026-09-05 23:59:59')
|
||
const page = parseHistoryPage(await res.json())
|
||
if (page.items.length) {
|
||
assert.equal(typeof page.items[0].username, 'string')
|
||
assert.equal(typeof page.items[0].panelType, 'string')
|
||
}
|
||
})
|
||
|
||
test('test_task_140_records_live_versions_items', { skip: !HAS_CREDS }, async () => {
|
||
// 软件版本行字段契约(若有数据):version 为 string。
|
||
await ensureSession()
|
||
const res = await authedFetch('/api/admin/versions')
|
||
const list = parseSoftwareVersionList(await res.json())
|
||
if (list.items.length) {
|
||
assert.equal(typeof list.items[0].version, 'string')
|
||
}
|
||
})
|