import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; const source = (path) => readFile(new URL(path, import.meta.url), 'utf8'); test('个人助理 API 固定使用登录态且不接收 owner 参数', async () => { const [client, api] = await Promise.all([ source('../src/services/personal-assistant.ts'), source('../src/services/api.ts') ]); assert.match(client, /apiRequest/); assert.match(client, /\/api\/aihr\/personal-assistant\/ask/); assert.match(client, /\/api\/aihr\/personal-assistant\/items\/file/); assert.match(client, /uni\.uploadFile/); assert.doesNotMatch(client, /ownerUserId|tenantId/); assert.doesNotMatch(client, /clearAuthOnUnauthorized:\s*false/); assert.doesNotMatch(api, /statusCode === 401 \|\| statusCode === 403/); assert.match(api, /statusCode === 401 \|\| code === 401/); }); test('问答首页默认只查询个人资料并展示真实引用域', async () => { const page = await source('../src/pages/user/assistant/index.vue'); assert.match(page, /ref\(\['PERSONAL'\]\)/); assert.match(page, /我的资料/); assert.match(page, /企业知识按岗位权限/); assert.match(page, /企业 SOP/); assert.match(page, /外部网页/); assert.match(page, /citation\.domain/); assert.match(page, /citation\.itemId/); assert.match(page, /citation\.sourceType/); assert.doesNotMatch(page, /loadPersonalItem/); assert.match(page, /answer\.value = undefined/); assert.match(page, /requestGeneration/); assert.match(page, /收藏资料/); assert.doesNotMatch(page, /ownerUserId|tenantId/); }); test('资料库和收藏页覆盖分页筛选以及三种真实收藏方式', async () => { const [library, capture] = await Promise.all([ source('../src/pages/user/assistant/library.vue'), source('../src/pages/user/assistant/capture.vue') ]); assert.match(library, /pageNum/); assert.match(library, /sourceType/); assert.match(library, /status/); assert.match(library, /loadPersonalItems/); assert.match(library, /requestGeneration/); assert.match(library, /pageSnapshot/); assert.match(library, /mergePersonalRows/); assert.match(library, /pageNum\.value = Math\.max/); assert.match(capture, /TEXT/); assert.match(capture, /FILE/); assert.match(capture, /URL/); assert.match(capture, /createTextItem/); assert.match(capture, /uploadPersonalFile/); assert.match(capture, /createUrlItem/); }); test('个人资料详情包含全部状态、重试、下载和明确删除提示', async () => { const page = await source('../src/pages/user/assistant/item.vue'); assert.match(page, /QUEUED/); assert.match(page, /PARSING/); assert.match(page, /READY/); assert.match(page, /FAILED/); assert.match(page, /DELETING/); assert.match(page, /DELETED/); assert.match(page, /retryPersonalItem/); assert.match(page, /deletePersonalItem/); assert.match(page, /downloadPersonalItem/); assert.match(page, /附件、解析正文和搜索索引/); }); test('会话页覆盖列表、详情和删除且不伪造会话', async () => { const page = await source('../src/pages/user/assistant/sessions.vue'); assert.match(page, /loadPersonalSessions/); assert.match(page, /loadPersonalSession/); assert.match(page, /deletePersonalSession/); assert.match(page, /暂无历史会话/); assert.match(page, /chat\.role\.toLowerCase\(\) === 'user'/); }); test('个人助理路由已注册且企业 SOP 问答保留独立入口', async () => { const [pages, sop] = await Promise.all([ source('../src/pages.json'), source('../src/pages/user/sop/index.vue') ]); for (const route of ['index', 'library', 'capture', 'item', 'sessions']) { assert.match(pages, new RegExp(`pages/user/assistant/${route}`)); } assert.match(sop, /个人助理/); assert.match(sop, /我的资料/); assert.match(sop, /企业 SOP/); assert.match(sop, /\/pages\/user\/assistant\/index/); });