Files
Arcrun/cypher-executor/tests/console-library-map-page.test.ts
T
Claude 10dda9e6f5 feat(console): library-map M5 — 總庫搜尋頁藏書地圖首頁區塊(R4)
library-map SDD M5(Arcrun#39):console 首頁從空白搜尋框變全館地圖。

落點裁定:console 是 hash-routing 單頁殼,home 隨 profile(full=駕駛艙、
rag=總庫搜尋)——地圖放總庫搜尋頁搜尋框上方:rag profile 該頁即首頁;
full profile 它是全館入口,「點庫卡片→進該庫搜尋」動線同頁最短,一份實作
兩 profile 全吃。

- console.ts:藏書地圖區塊(lm-section)——每庫一張卡(庫名+narrative+
  top entities 前 5 帶 degree+triplet_count+commit_hash/updated 更新時間感)、
  跨庫 bridges 有資料才列一小區;兩段式渲染(全館列表先出卡,逐庫詳圖補
  degree/bridges,詳圖失敗維持名字版不擋);點庫卡片=設 library filter
  (/kbdb/search 既有 library 參數,不新造)進庫搜尋,附清除鈕搜回全館;
  /map 空陣列或錯誤=誠實空狀態(指引 POST /map/recompute backfill),
  不擋搜尋等其他功能。品牌沿 CONSOLE_BRAND 變數(#21),零外部庫。
- kbdb-proxy.ts:GET /kbdb/map+/kbdb/map/:library 純轉發(rule 07,聚合真身
  在 kbdb base M2)。owner_id 不強制注入只選擇性透傳(同 M4 MCP kbdb_get_map
  語意;現行 backfill map block owner=NULL,強制注入租戶=首頁永遠假空狀態);
  仍要求 X-Arcrun-API-Key 同閘;KBDB 不可達誠實 502。
- 測試:kbdb-map-proxy.test.ts 9 測(租戶閘/轉發/owner 透傳/空陣列/404/502)+
  console-library-map-page.test.ts 6 測(route 200/區塊在搜尋框上方/資料源接線/
  library 參數/誠實空狀態文案/品牌變數)——15/15 過。
- 誠實回報:tsc 16 行 ExecutionContext.tracing 錯誤與 executor.test 1 失敗=
  main 基線既有(git stash 對照實證),非本分支引入。

merge 後需 gated redeploy cypher-executor(leo 閘)。關聯 #39。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUmjwkHLVBHM3ydhT1WSW3
2026-07-19 09:34:36 +00:00

58 lines
2.5 KiB
TypeScript
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.
/**
* GET /console 頁面測試 — 藏書地圖首頁區塊(library-map SDD M5/R4
*
* console 是單檔 HTML 薄殼(server 端零資料請求,client JS 打 /kbdb/map),所以頁面測試
* 驗的是「殼有沒有長對」:route 200、地圖區塊在搜尋框上方、進庫搜尋接的是既有 library
* 參數、空狀態/錯誤誠實文案在(不擋其他功能)。轉發行為真身在 kbdb-map-proxy.test.ts。
*/
import { SELF } from 'cloudflare:test';
import { describe, it, expect } from 'vitest';
async function page(): Promise<{ status: number; html: string }> {
const res = await SELF.fetch('http://localhost/console');
return { status: res.status, html: await res.text() };
}
describe('GET /console — 藏書地圖區塊', () => {
it('route 200、HTML 含地圖區塊(lm-section/lm-cards/lm-bridges', async () => {
const { status, html } = await page();
expect(status).toBe(200);
expect(html).toContain('藏書地圖');
expect(html).toContain('id="lm-section"');
expect(html).toContain('id="lm-cards"');
expect(html).toContain('id="lm-bridges"');
});
it('地圖區塊在搜尋框上方(DOM 順序:lm-section 先於 se-q', async () => {
const { html } = await page();
expect(html.indexOf('id="lm-section"')).toBeGreaterThan(-1);
expect(html.indexOf('id="lm-section"')).toBeLessThan(html.indexOf('id="se-q"'));
});
it('資料源接 /kbdb/mapcypher 代轉慣例)+逐庫詳圖 /kbdb/map/', async () => {
const { html } = await page();
expect(html).toContain("fetch('/kbdb/map'");
expect(html).toContain("'/kbdb/map/' + encodeURIComponent");
});
it('點庫卡片=既有搜尋 library 參數進庫(不新造參數)', async () => {
const { html } = await page();
expect(html).toContain("'&library=' + encodeURIComponent(S.library)");
expect(html).toContain('data-lib');
});
it('空狀態/錯誤分支=誠實文案(recompute backfill 指引)且不擋搜尋', async () => {
const { html } = await page();
expect(html).toContain('還沒有藏書地圖');
expect(html).toContain('/map/recompute');
expect(html).toContain('不影響下方搜尋');
expect(html).toContain('地圖服務不可達');
});
it('品牌字樣走 CONSOLE_BRAND 變數(未設=預設 Arcrun),地圖區塊沒硬編品牌', async () => {
const { html } = await page();
// 測試環境未設 CONSOLE_BRAND → 預設 Arcrun#21 rebrand:字樣由變數注入,非硬編 Mira)
expect(html).toContain('<title>Arcrun Console</title>');
});
});