import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; import { createServer } from 'vite'; const source = (path) => readFile(new URL(path, import.meta.url), 'utf8'); test('引用详情使用不透明 ref,并覆盖文本、图片和视频状态', async () => { const [types, service, page, detail] = await Promise.all([ source('../src/types/api.ts'), source('../src/services/knowledge.ts'), source('../src/pages/user/sop/index.vue'), source('../src/pages/user/sop/citation-detail.vue') ]); assert.match(types, /detailRef\?: string \| null/); assert.match(types, /KnowledgeCitationDetail/); assert.match(service, /\/api\/knowledge\/citations/); assert.match(page, /openCitationDetail/); assert.match(page, /snippet\.detailRef/); assert.doesNotMatch(page, /attachmentId.*navigateTo|navigateTo.*attachmentId/); assert.match(detail, /state === 'forbidden'|state === 'not-found'/); assert.match(detail, /authenticatedFileUrl/); assert.match(detail, /loaded\.locator/); assert.match(detail, /currentTime/); }); test('引用详情页释放媒体临时 URL', async () => { const detail = await source('../src/pages/user/sop/citation-detail.vue'); assert.match(detail, /onUnmounted\(releaseMedia\)/); assert.match(detail, /releaseAuthenticatedFileUrl/); }); test('H5 video media URLs stay rooted at the dev API instead of the /h5 app base', async () => { globalThis.window = { location: { origin: 'https://wygj-mobile-uni.localhost' } }; globalThis.uni = { getStorageSync: () => '', removeStorageSync: () => {} }; const vite = await createServer({ root: fileURLToPath(new URL('..', import.meta.url)), configFile: false, optimizeDeps: { noDiscovery: true }, server: { middlewareMode: true, hmr: false }, appType: 'custom' }); try { const { apiMediaUrl } = await vite.ssrLoadModule('/src/services/api.ts'); assert.equal( apiMediaUrl('/api/knowledge/resources/2069/download?ticket=opaque'), 'https://wygj-mobile-uni.localhost/dev-api/api/knowledge/resources/2069/download?ticket=opaque' ); } finally { await vite.close(); delete globalThis.window; delete globalThis.uni; } });