/** * 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/map(cypher 代轉慣例)+逐庫詳圖 /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('