Files
prop-ai-hr/mobile-uni/tests/personal-assistant.test.mjs
T

150 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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');
const idHelpers = await import('../src/services/personal-assistant-id.ts');
test('Snowflake ID 全程保留字符串精度并安全生成详情路径', () => {
const hugeId = '1990000000000000000';
assert.equal(idHelpers.normalizeBackendId(hugeId), hugeId);
assert.equal(idHelpers.personalItemRoute(hugeId), `/pages/user/assistant/item?id=${hugeId}`);
assert.equal(idHelpers.personalItemApiPath(hugeId), `/api/aihr/personal-assistant/items/${hugeId}`);
assert.equal(idHelpers.personalSessionApiPath(hugeId), `/api/aihr/personal-assistant/sessions/${hugeId}`);
});
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.match(client, /sessionId\?: string/);
assert.match(client, /itemIds\?: string\[\]/);
assert.match(client, /loadPersonalItem = \(id: string\)/);
assert.match(client, /loadPersonalSession = \(id: string\)/);
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<KnowledgeScope\[\]>\(\['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, /:disabled="asking"/);
assert.match(page, /if \(asking\.value\) return/);
assert.match(page, /scopeSnapshot/);
assert.match(page, /scopeKey\(scopes\.value\)/);
assert.match(page, /收藏资料/);
assert.doesNotMatch(page, /ownerUserId|tenantId/);
});
test('个人助理先生成可编辑大纲并在确认后冻结来源', async () => {
const [page, client] = await Promise.all([
source('../src/pages/user/assistant/index.vue'),
source('../src/services/personal-assistant.ts')
]);
assert.match(client, /createPersonalOutline/);
assert.match(client, /updatePersonalOutline/);
assert.match(client, /confirmPersonalOutline/);
assert.match(client, /enqueuePersonalPpt/);
assert.match(client, /loadPersonalExport/);
assert.match(client, /downloadPersonalExport/);
assert.match(page, /生成 PPT/);
assert.match(page, /下载 PPT/);
assert.match(page, /生成汇报提纲/);
assert.match(page, /确认大纲/);
assert.match(page, /资料来源不可编辑/);
assert.match(page, /answer\.citations\?\.length/);
});
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, /dateFrom/);
assert.match(library, /dateTo/);
assert.match(library, /mode="date"/);
assert.match(library, /dateFrom: dateFrom\.value/);
assert.match(library, /dateTo: dateTo\.value/);
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, /附件、解析正文和搜索索引/);
assert.match(page, /normalizeBackendId\(String\(options\?\.id/);
assert.doesNotMatch(page, /Number\(options\?\.id|parseInt\(options\?\.id|Number\.isSafeInteger/);
});
test('扫描 PDF 详情展示识别进度、部分失败和失败页重试', async () => {
const ocr = await import('../src/services/personal-assistant-ocr.ts');
const page = await source('../src/pages/user/assistant/item.vue');
assert.equal(ocr.ocrProgressText({ required: true, status: 'RUNNING', totalPages: 86, processedPages: 20, successPages: 20, failedPages: 0, failedPageNumbers: [] }), '正在识别扫描 PDF:20/86 页');
assert.equal(ocr.ocrProgressText({ required: true, status: 'PARTIAL', totalPages: 8, processedPages: 8, successPages: 6, failedPages: 2, failedPageNumbers: [3, 7] }), '已收录,2 页识别失败');
assert.match(page, /retryPersonalOcrPages/);
assert.match(page, /识别失败页/);
assert.match(page, /ocrProgressPercent/);
assert.match(page, /setTimeout/);
});
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/);
});