Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0
This commit is contained in:
1 parent
7082ab955a
commit
848f0d8f8a
434 files changed
+67298
-4315
No files matched your search
@@ -1,22 +1,190 @@
|
||||
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { MigrationWorkspace } from "./MigrationWorkspace";
|
||||
import { clearOperatorCredential, setOperatorCredential } from "../lib/api";
|
||||
|
||||
function mockMigration(): void {
|
||||
vi.stubGlobal("fetch", vi.fn((input: RequestInfo | URL) => {
|
||||
const url = String(input); let payload: unknown = [];
|
||||
if (url.endsWith("/plans")) payload = [{ id: "plan-1", project_id: "project-1", project_binding_id: "binding-1", capability_contract_id: "contract-1", migration_class: "REQUIRES_REINDEX", environment: "LAB", state: "BACKFILL_PAUSED", version: 7, generation: 1, adapter: { key: "examplerag.qdrant-reindex", version: "1", fingerprint: "a".repeat(64), operations: [] }, source_identity: {}, target_identity: {}, source_data_target: "rag_source_v1", target_shadow_target: "rag_shadow_v2", source_space_ref: "space-v1", target_space_id: "space-2", corpus_revision: "corpus-1", migration_policy_revision: "m13-1", validation_policy_revision_id: "policy-1", lifecycle_approval_id: "approval-1", rollback_target_ref: "rag_source_v1", total_expected_items: 597, completed_items: 256, failed_items: 0, retryable_items: 0, permanent_failed_items: 0, batch_size: 32, priority: "BACKGROUND", rollback_retention_days: 30, plan_fingerprint: "b".repeat(64), approval_fingerprint: "c".repeat(64), failure_details: {}, last_cursor: "256", cancel_requested: false, immutable_at: "2026-08-26T10:00:00Z", created_at: "2026-08-26T10:00:00Z", updated_at: "2026-08-26T10:01:00Z" }];
|
||||
if (url.includes("/validation")) payload = [{ id: "validation-1", migration_plan_id: "plan-1", generation: 1, expected_count: 597, actual_count: 597, missing_count: 0, duplicate_count: 0, malformed_count: 0, non_finite_count: 0, wrong_dimension_count: 0, content_hash_mismatch_count: 0, wrong_space_count: 0, comparable: true, critical_regressions: 0, passed: true, technical_cutover_eligible: true, project_promotion_eligible: false, blockers: ["EXTERNAL_VALIDATION_NOT_SATISFIED"], target_fingerprint: "d".repeat(64), snapshot_fingerprint: "e".repeat(64), evidence: {}, created_at: "2026-08-26T10:02:00Z" }];
|
||||
if (url.includes("/cutovers")) payload = [{ id: "cutover-1", migration_plan_id: "plan-1", stage: "ROLLED_BACK", generation: 1, source_before: "rag_source_v1", target_after: "rag_shadow_v2", external_state_fingerprint: "f".repeat(64), health_evidence: {}, failure_details: {}, switch_duration_ms: 3.2, rollback_duration_ms: 2.1, started_at: "2026-08-26T10:03:00Z", finished_at: "2026-08-26T10:04:00Z" }];
|
||||
if (url.includes("/events")) payload = [{ id: "event-1", migration_plan_id: "plan-1", event_type: "BACKFILL_PAUSED", before_state: "BACKFILLING", after_state: "BACKFILL_PAUSED", actor: "operator", reason: "interruption rehearsal", policy_revision: "m13-1", evidence_refs: [], source_identity: {}, target_identity: {}, generation: 1, change_id: "change-1", details: {}, occurred_at: "2026-08-26T10:01:00Z" }];
|
||||
const activePlan = (overrides: Record<string, unknown> = {}) => ({
|
||||
id: "plan-1", project_id: "project-1", project_binding_id: "binding-1", capability_contract_id: "contract-1",
|
||||
migration_class: "REQUIRES_REINDEX", environment: "LAB", state: "BACKFILL_PAUSED", version: 7, generation: 1,
|
||||
adapter: { key: "examplerag.qdrant-reindex", version: "1", fingerprint: "a".repeat(64), operations: [] },
|
||||
source_identity: {}, target_identity: {}, source_data_target: "rag_source_v1", target_shadow_target: "rag_shadow_v2",
|
||||
source_space_ref: "space-v1", target_space_id: "space-2", corpus_revision: "corpus-1", migration_policy_revision: "m13-1",
|
||||
validation_policy_revision_id: "policy-1", lifecycle_approval_id: "approval-1", rollback_target_ref: "rag_source_v1",
|
||||
total_expected_items: 597, completed_items: 256, failed_items: 0, retryable_items: 0, permanent_failed_items: 0,
|
||||
batch_size: 32, priority: "BACKGROUND", rollback_retention_days: 30, plan_fingerprint: "b".repeat(64),
|
||||
approval_fingerprint: "c".repeat(64), failure_details: {}, last_cursor: "256", cancel_requested: false,
|
||||
immutable_at: "2026-08-26T10:00:00Z", created_at: "2026-08-26T10:00:00Z", updated_at: "2026-08-26T10:01:00Z",
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const validation = (planId = "plan-1", overrides: Record<string, unknown> = {}) => ({
|
||||
id: `validation-${planId}`, migration_plan_id: planId, generation: 1, expected_count: 597, actual_count: 597,
|
||||
missing_count: 0, duplicate_count: 0, malformed_count: 0, non_finite_count: 0, wrong_dimension_count: 0,
|
||||
content_hash_mismatch_count: 0, wrong_space_count: 0, comparable: true, critical_regressions: 0, passed: true,
|
||||
technical_cutover_eligible: true, project_promotion_eligible: false, blockers: ["EXTERNAL_VALIDATION_NOT_SATISFIED"],
|
||||
target_fingerprint: "d".repeat(64), snapshot_fingerprint: "e".repeat(64), evidence: {}, created_at: "2026-08-26T10:02:00Z",
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const cutover = (planId = "plan-1", overrides: Record<string, unknown> = {}) => ({
|
||||
id: `cutover-${planId}`, migration_plan_id: planId, stage: "ROLLED_BACK", generation: 1,
|
||||
source_before: "rag_source_v1", target_after: "rag_shadow_v2", external_state_fingerprint: "f".repeat(64),
|
||||
health_evidence: {}, failure_details: {}, switch_duration_ms: 3.2, rollback_duration_ms: 2.1,
|
||||
started_at: "2026-08-26T10:03:00Z", finished_at: "2026-08-26T10:04:00Z", ...overrides,
|
||||
});
|
||||
|
||||
const auditEvent = {
|
||||
id: "event-1", migration_plan_id: "plan-1", event_type: "BACKFILL_PAUSED", before_state: "BACKFILLING",
|
||||
after_state: "BACKFILL_PAUSED", actor: "operator", reason: "interruption rehearsal", policy_revision: "m13-1",
|
||||
evidence_refs: [], source_identity: {}, target_identity: {}, generation: 1, change_id: "change-1", details: {},
|
||||
occurred_at: "2026-08-26T10:01:00Z",
|
||||
};
|
||||
|
||||
function mockMigration(options: {
|
||||
plans?: Record<string, unknown>[];
|
||||
validations?: Record<string, unknown>[];
|
||||
cutovers?: Record<string, unknown>[];
|
||||
events?: Record<string, unknown>[];
|
||||
} = {}) {
|
||||
const plans = options.plans ?? [activePlan()];
|
||||
const validations = options.validations ?? [validation()];
|
||||
const cutovers = options.cutovers ?? [cutover()];
|
||||
const events = options.events ?? [auditEvent];
|
||||
const requests: { url: string; method: string }[] = [];
|
||||
const fetchMock = vi.fn((input: RequestInfo | URL, init?: RequestInit) => {
|
||||
const url = String(input);
|
||||
requests.push({ url, method: init?.method ?? "GET" });
|
||||
let payload: unknown = [];
|
||||
if (url.endsWith("/plans")) payload = plans;
|
||||
if (url.includes("/validation")) {
|
||||
const planId = decodeURIComponent(url.split("/plans/")[1]?.split("/validation")[0] ?? "");
|
||||
payload = validations.filter((item) => item.migration_plan_id === planId);
|
||||
}
|
||||
if (url.includes("/cutovers")) payload = cutovers;
|
||||
if (url.includes("/events")) payload = events;
|
||||
if (url.includes("/backfill/start")) payload = plans.find((item) => item.id === "plan-1") ?? activePlan();
|
||||
return Promise.resolve(new Response(JSON.stringify(payload), { status: 200 }));
|
||||
}));
|
||||
});
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
return { fetchMock, requests };
|
||||
}
|
||||
|
||||
afterEach(() => { cleanup(); vi.unstubAllGlobals(); });
|
||||
afterEach(() => { clearOperatorCredential(); cleanup(); vi.unstubAllGlobals(); });
|
||||
|
||||
describe("M13 migration operator workspace", () => {
|
||||
it("separates current work from terminal history and counts only current evidence", async () => {
|
||||
mockMigration({
|
||||
plans: [activePlan(), activePlan({
|
||||
id: "plan-old", state: "ROLLED_BACK", source_data_target: "archive_source", target_shadow_target: "archive_target",
|
||||
total_expected_items: 100, completed_items: 100, rollback_target_ref: "archive_source",
|
||||
}), activePlan({
|
||||
id: "plan-committed", state: "CUTOVER_COMMITTED", source_data_target: "committed_source",
|
||||
target_shadow_target: "committed_target", total_expected_items: 10, completed_items: 10,
|
||||
rollback_target_ref: "committed_source",
|
||||
})],
|
||||
validations: [validation(), validation("plan-old", { project_promotion_eligible: true })],
|
||||
cutovers: [cutover(), cutover("plan-committed", {
|
||||
stage: "COMMITTED", source_before: "committed_source", target_after: "committed_target", rollback_duration_ms: null,
|
||||
})],
|
||||
});
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace />);
|
||||
|
||||
await screen.findByText("266 / 607");
|
||||
expect(screen.getByText("Current item progress").closest(".migration-fact")).toHaveTextContent("266 / 607");
|
||||
expect(screen.getByText("Current migrations").closest(".migration-fact")).toHaveTextContent("2");
|
||||
expect(screen.getByText("Current project-promotion eligible").closest(".migration-fact")).toHaveTextContent("0");
|
||||
fireEvent.click(screen.getByRole("tab", { name: "plans" }));
|
||||
|
||||
expect(await screen.findByRole("heading", { name: "Current migrations (2)" })).toBeInTheDocument();
|
||||
expect(screen.getByText("Historical migrations (1)")).toBeInTheDocument();
|
||||
const current = screen.getByRole("heading", { name: "rag_source_v1 → rag_shadow_v2" }).closest("article");
|
||||
const history = screen.getByText("archive_source → archive_target").closest("article");
|
||||
const committed = screen.getByRole("heading", { name: "committed_source → committed_target" }).closest("article");
|
||||
expect(current).toHaveTextContent("Current migration");
|
||||
expect(current).toHaveTextContent("Validation snapshot");
|
||||
expect(history).toHaveTextContent("Historical record");
|
||||
expect(history).toHaveTextContent("Read-only history");
|
||||
expect(history).not.toHaveTextContent("Start/resume");
|
||||
expect(history).not.toHaveTextContent("Cancel");
|
||||
expect(committed).toHaveTextContent("Current migration");
|
||||
expect(committed).toHaveTextContent("Rollback targetcommitted_source");
|
||||
expect(committed).toHaveTextContent("30-day retention policy");
|
||||
expect(committed).not.toHaveTextContent("Cancel");
|
||||
});
|
||||
|
||||
it("keeps a selected historical plan visible and read-only for Quick Jump", async () => {
|
||||
mockMigration({ plans: [activePlan({ id: "plan-old", state: "ROLLED_BACK" })] });
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace targetPlanId="plan-old" />);
|
||||
|
||||
const target = await screen.findByText("QUICK JUMP TARGET");
|
||||
expect(screen.getByRole("tab", { name: "plans" })).toHaveAttribute("aria-selected", "true");
|
||||
expect(target.closest("article")).toHaveTextContent("Historical record");
|
||||
expect(target.closest("article")).toHaveTextContent("rag_source_v1 → rag_shadow_v2");
|
||||
expect(target.closest("article")).not.toHaveTextContent("Start/resume");
|
||||
});
|
||||
|
||||
it("surfaces missing validation and cutover evidence on plans requiring reconciliation", async () => {
|
||||
mockMigration({
|
||||
plans: [activePlan({ state: "MANUAL_INTERVENTION_REQUIRED" })],
|
||||
validations: [],
|
||||
cutovers: [],
|
||||
});
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace />);
|
||||
fireEvent.click(screen.getByRole("tab", { name: "plans" }));
|
||||
|
||||
const card = (await screen.findByText("rag_source_v1 → rag_shadow_v2")).closest("article");
|
||||
expect(card).toHaveTextContent("Reconciliation required");
|
||||
expect(card).toHaveTextContent("Validation evidence not recorded");
|
||||
expect(card).toHaveTextContent("Cutover journal not recorded");
|
||||
expect(card).toHaveTextContent(/Rollback target\s*rag_source_v1/);
|
||||
expect(card).not.toHaveTextContent("Start/resume");
|
||||
expect(card).not.toHaveTextContent("Pause");
|
||||
expect(card).not.toHaveTextContent("Cancel");
|
||||
});
|
||||
|
||||
it("does not present prior-generation evidence as current reconciliation context", async () => {
|
||||
mockMigration({
|
||||
plans: [activePlan({ generation: 2, state: "MANUAL_INTERVENTION_REQUIRED" })],
|
||||
validations: [validation("plan-1", { generation: 1, project_promotion_eligible: true })],
|
||||
cutovers: [cutover("plan-1", { generation: 1, stage: "COMMITTED" })],
|
||||
});
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace />);
|
||||
fireEvent.click(screen.getByRole("tab", { name: "plans" }));
|
||||
const card = (await screen.findByRole("heading", { name: "rag_source_v1 → rag_shadow_v2" })).closest("article");
|
||||
|
||||
expect(card).toHaveTextContent("stale generation");
|
||||
expect(card).toHaveTextContent("current plan generation is 2");
|
||||
expect(card).toHaveTextContent("Latest cutover journal is from generation 1");
|
||||
expect(card).toHaveTextContent("not proven pending reconciliation");
|
||||
expect(card).toHaveTextContent("not currently eligible");
|
||||
expect(card).not.toHaveTextContent("snapshot eligible");
|
||||
expect(screen.getByRole("heading", { name: "Needs operator attention (1)" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("waits for an explicit current-plan action and never mutates history", async () => {
|
||||
const { requests } = mockMigration({
|
||||
plans: [activePlan(), activePlan({ id: "plan-old", state: "ROLLED_BACK" })],
|
||||
});
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace />);
|
||||
await screen.findByText("256 / 597");
|
||||
expect(requests.every((request) => request.method === "GET")).toBe(true);
|
||||
|
||||
fireEvent.click(screen.getByRole("tab", { name: "plans" }));
|
||||
expect(await screen.findByRole("heading", { name: "Current migrations (1)" })).toBeInTheDocument();
|
||||
expect(requests.every((request) => request.method === "GET")).toBe(true);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Start/resume" }));
|
||||
await screen.findByText("Background backfill explicitly started or resumed.");
|
||||
await waitFor(() => expect(requests.some((request) => request.method === "POST" && request.url.endsWith("/plan-1/backfill/start"))).toBe(true));
|
||||
expect(requests.some((request) => request.method !== "GET" && request.url.includes("plan-old"))).toBe(false);
|
||||
});
|
||||
|
||||
it("separates technical cutover from project-promotion eligibility", async () => {
|
||||
mockMigration(); render(<MigrationWorkspace />);
|
||||
fireEvent.change(screen.getByLabelText("Operator API key"), { target: { value: "operator-test" } });
|
||||
@@ -39,4 +207,13 @@ describe("M13 migration operator workspace", () => {
|
||||
fireEvent.click(screen.getByRole("tab", { name: "history" }));
|
||||
expect(screen.getByText("interruption rehearsal")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not select another plan when a Quick Jump target is absent", async () => {
|
||||
mockMigration();
|
||||
setOperatorCredential("operator-test");
|
||||
render(<MigrationWorkspace targetPlanId="missing-plan" />);
|
||||
|
||||
expect(await screen.findByRole("status")).toHaveTextContent(/selected migration plan is not in the loaded index/i);
|
||||
expect(screen.queryByText("QUICK JUMP TARGET")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user