test: prove TechLog UI migration parity

This commit is contained in:
DongHyeonka
2026-08-16 02:48:26 +09:00
parent c5c8b9423c
commit 6c2780b7a7
176 changed files with 2393 additions and 616 deletions
@@ -190,6 +190,7 @@ jobs:
scripts/lib/secret-scan.ts \\
scripts/lib/supply-chain.ts \\
scripts/lib/validated-json-artifact.ts \\
scripts/lib/vite-route-chunks.ts \\
src/contracts/release-artifacts.ts \\
src/features/installed-contract-contributions.ts \\
src/features/installed-feature-contracts.ts \\
+46
View File
@@ -121,6 +121,29 @@ describe("bounded body reader", () => {
});
});
it("abandons and cancels a bounded read when its lifetime aborts", async () => {
const controller = new AbortController();
const reader = {
read: vi.fn(() => new Promise<never>(() => {})),
cancel: vi.fn().mockRejectedValue(new Error("abandoned cancel failed")),
releaseLock: vi.fn(),
};
const response = {
headers: new Headers(),
body: { getReader: () => reader },
} as unknown as Response;
const outcome = readBoundedBytes(response, 3, controller.signal);
controller.abort();
await expect(outcome).resolves.toEqual({
ok: false,
code: "RESPONSE_STREAM_FAILURE",
});
expect(reader.cancel).toHaveBeenCalledOnce();
expect(reader.releaseLock).toHaveBeenCalledOnce();
});
it("detects a forbidden body from declared length without reading it", async () => {
const cancel = vi.fn();
const response = {
@@ -200,6 +223,29 @@ describe("bounded body reader", () => {
});
});
it("abandons and cancels a forbidden-body probe when its lifetime aborts", async () => {
const controller = new AbortController();
const reader = {
read: vi.fn(() => new Promise<never>(() => {})),
cancel: vi.fn().mockRejectedValue(new Error("abandoned cancel failed")),
releaseLock: vi.fn(),
};
const response = {
headers: new Headers(),
body: { getReader: () => reader },
} as unknown as Response;
const outcome = probeForbiddenBody(response, controller.signal);
controller.abort();
await expect(outcome).resolves.toEqual({
ok: false,
code: "RESPONSE_STREAM_FAILURE",
});
expect(reader.cancel).toHaveBeenCalledOnce();
expect(reader.releaseLock).toHaveBeenCalledOnce();
});
it("decodes valid JSON and distinguishes UTF-8 from JSON failures", () => {
expect(decodeJsonBytes(new TextEncoder().encode('{"ok":true}'))).toEqual({
ok: true,
+15
View File
@@ -0,0 +1,15 @@
import { describe, expect, it } from "vitest";
import { containsRawPaletteValue } from "../../scripts/lib/design-system-source.ts";
describe("design-system source palette detection", () => {
it("rejects palette literals without treating URL fragments as colors", () => {
expect(containsRawPaletteValue('style={{ color: "#ff0000" }}')).toBe(true);
expect(containsRawPaletteValue('const css = "color: rgb(255 0 0)"')).toBe(true);
expect(
containsRawPaletteValue(
'path: "/projects/backend-skeleton/decisions#feed-pagination-boundary"',
),
).toBe(false);
});
});
+2 -2
View File
@@ -335,9 +335,9 @@ describe("registry governance manifest", () => {
});
expect(versions?.rows).toBeDefined();
expect(approval).toMatchObject({
owner: "frontend-platform",
owner: "tech-log-frontend",
reason:
"Baseline canonical invalidation graph and topic-version contracts after FE-REG-QUERY retirement",
"Install approved TechLog Public and Studio route contract",
});
});
+2
View File
@@ -1770,6 +1770,7 @@ async function createArchivedAssessmentFixture(): Promise<{
"scripts/lib/secret-scan.ts",
"scripts/lib/supply-chain.ts",
"scripts/lib/validated-json-artifact.ts",
"scripts/lib/vite-route-chunks.ts",
"src/contracts/release-artifacts.ts",
"src/features/installed-contract-contributions.ts",
"src/features/installed-feature-contracts.ts",
@@ -1799,6 +1800,7 @@ async function createArchivedAssessmentFixture(): Promise<{
"scripts/lib/secret-scan.ts",
"scripts/lib/supply-chain.ts",
"scripts/lib/validated-json-artifact.ts",
"scripts/lib/vite-route-chunks.ts",
"src/contracts/release-artifacts.ts",
"src/features/installed-contract-contributions.ts",
"src/features/installed-feature-contracts.ts",
+55
View File
@@ -0,0 +1,55 @@
import { describe, expect, it } from "vitest";
import { findViteDynamicRouteChunk } from "../../scripts/lib/vite-route-chunks.ts";
describe("Vite route chunk identity", () => {
it("recognizes a governed manual chunk referenced by an entry dynamic import", () => {
const manifest = {
"_route-tech-log-home-abc.js": {
file: "assets/route-tech-log-home-abc.js",
name: "route-tech-log-home",
},
"index.html": {
file: "assets/index.js",
name: "index",
isEntry: true,
dynamicImports: ["_route-tech-log-home-abc.js"],
},
};
expect(findViteDynamicRouteChunk(manifest, "route-tech-log-home")).toEqual({
file: "assets/route-tech-log-home-abc.js",
name: "route-tech-log-home",
});
});
it("retains Vite native dynamic-entry support", () => {
const manifest = {
"src/page.tsx": {
file: "assets/page.js",
name: "route-page",
isDynamicEntry: true,
},
};
expect(findViteDynamicRouteChunk(manifest, "route-page")?.file).toBe(
"assets/page.js",
);
});
it("rejects a named chunk that is not dynamically reachable", () => {
const manifest = {
"_route-tech-log-home-abc.js": {
file: "assets/route-tech-log-home-abc.js",
name: "route-tech-log-home",
},
"index.html": {
file: "assets/index.js",
name: "index",
isEntry: true,
},
};
expect(findViteDynamicRouteChunk(manifest, "route-tech-log-home")).toBeUndefined();
});
});