知识库工作台(/knowledge/:workId)新增「知识图谱」面板:经 GET /works/{id}/graph 读真实 muse_knowledge_entity/relation,渲染已确认入库的 Canonical 实体(节点)与关系(边)——与「待确认草稿面板」构成双轨主权闭环(候选 Shadow → 人工确认 → 正式图谱可见)。新增 useKnowledgeGraph hook;confirm 成功后失活图谱缓存联动刷新。
活体证(MSW off,chromium 直连 48080):knowledge-graph.spec.ts 绿(GET graph code:0、节点 huotituopusuqing/huotituopuqingzhou + huoti_related 边渲染);curl 实证后端真返节点/边。tsc -b 干净、vitest 47/47 无回归。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
import { expect, test, type Page } from '@playwright/test';
|
|
|
|
/**
|
|
* 知识图谱视图 e2e(先审后入"正式轨"成果,真实后端,MSW off)。
|
|
*
|
|
* 前置:vite 以 VITE_API_MOCK=false 运行、真实 muse-server 在 48080、muse_slice_live 作品 1 下已种子
|
|
* Canonical 实体 + 关系(/tmp/KnowledgeGraphSeed.java)。
|
|
* 目的:rendered studio 的「知识图谱」面板经 GET /works/1/graph 读真实 muse_knowledge_entity/relation,
|
|
* 把确认入库的实体(节点)与关系(边)在 UI 渲染——证"确认草稿 → 正式图谱"双轨闭环的成果可见(打真后端,非 mock)。
|
|
*/
|
|
const TOKEN = 'test1';
|
|
|
|
async function seedToken(page: Page): Promise<void> {
|
|
await page.addInitScript((t) => {
|
|
window.localStorage.setItem('accessToken', t);
|
|
window.localStorage.setItem('tenantId', '1');
|
|
}, TOKEN);
|
|
}
|
|
|
|
test('知识图谱渲染真实实体与关系(Canonical,真实后端)', async ({ page }) => {
|
|
await seedToken(page);
|
|
|
|
// 捕获真实 graph 读响应(打真后端,非 mock)。
|
|
const [resp] = await Promise.all([
|
|
page.waitForResponse(
|
|
(r) => /\/works\/1\/graph(\?|$)/.test(r.url()) && r.request().method() === 'GET',
|
|
{ timeout: 15_000 }
|
|
),
|
|
page.goto('/knowledge/1'),
|
|
]);
|
|
|
|
// Yudao 口径:成功为 HTTP 200 + CommonResult{code:0}。
|
|
expect(resp.status()).toBe(200);
|
|
const body = await resp.json();
|
|
expect(body.code).toBe(0);
|
|
// 真实后端返回种子节点(规范名)与关系。
|
|
const names = (body.data?.nodes ?? []).map((n: { name: string }) => n.name);
|
|
expect(names).toContain('huotituopusuqing');
|
|
expect(names).toContain('huotituopuqingzhou');
|
|
|
|
// UI 渲染:两个实体节点 + 关系语义徽标。
|
|
await expect(page.getByText('huotituopusuqing').first()).toBeVisible({ timeout: 15_000 });
|
|
await expect(page.getByText('huotituopuqingzhou').first()).toBeVisible({ timeout: 15_000 });
|
|
await expect(page.getByText(/huoti_related/).first()).toBeVisible({ timeout: 15_000 });
|
|
});
|