fix(t130 🔴🔴): PORTAL_TEMPLATE_SEEDS 補 triplet——新實例總圖不再永遠空
真兇(總管探針定罪):seeds 只有 portal_user/portal_library,寫三元組回 400 'template not found: triplet' ⇒ 每個新用戶(含封測者)總圖必空。 geek6688 有是舊實例早期流程建過=拿它驗會假綠(已記 mistakes)。 呼叫路徑已驗:daemon/libraries、admin/libraries、init/seed 皆會 ensurePortalTemplates(冪等)。 vitest 24/24 綠(總管親跑)。(實作=子 CC;驗證+commit=總管)
This commit is contained in:
@@ -66,7 +66,7 @@ function mockListByTemplate(template: string, records: { record_id: string; valu
|
||||
}
|
||||
|
||||
function mockTemplatesExist() {
|
||||
for (const name of ['portal_user', 'portal_library']) {
|
||||
for (const name of ['portal_user', 'portal_library', 'triplet']) {
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: `/templates/${name}`, method: 'GET' })
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import { SELF, env, fetchMock } from 'cloudflare:test';
|
||||
import { beforeAll, beforeEach, afterEach, describe, it, expect } from 'vitest';
|
||||
import { hashPassword, verifyPassword, PBKDF2_ITERATIONS } from '../src/lib/portal-auth';
|
||||
import { PORTAL_TEMPLATE_SEEDS } from '../src/lib/portal-seeds';
|
||||
|
||||
const KBDB = 'https://kbdb.test';
|
||||
const NS = 'leo::portal'; // wrangler.test.toml CONSOLE_TENANT=leo → 子 namespace
|
||||
@@ -73,7 +74,7 @@ function mockListByTemplate(template: string, records: { record_id: string; valu
|
||||
}
|
||||
|
||||
function mockTemplatesExist() {
|
||||
for (const name of ['portal_user', 'portal_library']) {
|
||||
for (const name of ['portal_user', 'portal_library', 'triplet']) {
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: `/templates/${name}`, method: 'GET' })
|
||||
@@ -414,3 +415,52 @@ describe('admin 端點 role 閘', () => {
|
||||
expect(res.status).toBe(404);
|
||||
});
|
||||
});
|
||||
|
||||
// ═══════════════ t130 — triplet template seed ═══════════════
|
||||
|
||||
describe('t130 — triplet template seed(PORTAL_TEMPLATE_SEEDS 補 triplet,ensurePortalTemplates 冪等)', () => {
|
||||
it('PORTAL_TEMPLATE_SEEDS 含 triplet 且必要 slots 齊備(pure data)', () => {
|
||||
const seed = PORTAL_TEMPLATE_SEEDS.find((s) => s.name === 'triplet');
|
||||
expect(seed).toBeDefined();
|
||||
for (const slot of ['subject', 'predicate', 'object', 'source_uri', 'status', 'library']) {
|
||||
expect(seed!.slots).toContain(slot);
|
||||
}
|
||||
});
|
||||
|
||||
it('POST /init/seed — triplet 已存 → existing(冪等,不重建)', async () => {
|
||||
for (const name of ['portal_user', 'portal_library', 'triplet']) {
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: `/templates/${name}`, method: 'GET' })
|
||||
.reply(200, { success: true, template: { id: `tpl-${name}`, name } });
|
||||
}
|
||||
const res = await SELF.fetch('http://localhost/init/seed', { method: 'POST' });
|
||||
expect(res.status).toBe(200);
|
||||
const data = (await res.json()) as { portal_templates: { created: string[]; existing: string[] } };
|
||||
expect(data.portal_templates.existing).toContain('triplet');
|
||||
expect(data.portal_templates.created).not.toContain('triplet');
|
||||
});
|
||||
|
||||
it('POST /init/seed — triplet 缺 → 自動補建(新實例首次 seed)', async () => {
|
||||
for (const name of ['portal_user', 'portal_library']) {
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: `/templates/${name}`, method: 'GET' })
|
||||
.reply(200, { success: true, template: { id: `tpl-${name}`, name } });
|
||||
}
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: '/templates/triplet', method: 'GET' })
|
||||
.reply(404, { success: false, error: 'template not found: triplet' });
|
||||
fetchMock
|
||||
.get(KBDB)
|
||||
.intercept({ path: '/templates', method: 'POST' })
|
||||
.reply(200, { success: true, template: { id: 'tpl-triplet-new', name: 'triplet' } });
|
||||
|
||||
const res = await SELF.fetch('http://localhost/init/seed', { method: 'POST' });
|
||||
expect(res.status).toBe(200);
|
||||
const data = (await res.json()) as { portal_templates: { created: string[]; existing: string[] } };
|
||||
expect(data.portal_templates.created).toContain('triplet');
|
||||
expect(data.portal_templates.existing).not.toContain('triplet');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user