feat: add UI conformance and launch context
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import type { AuthInfo } from "../src/types";
|
||||
import {
|
||||
createQuickAccessLaunchContext,
|
||||
quickAccessLaunchContextFromState,
|
||||
quickAccessLaunchState,
|
||||
quickAccessReturnPath
|
||||
} from "../src/platform/launchContext";
|
||||
|
||||
|
||||
function assert(condition: unknown, message: string): void {
|
||||
if (!condition) throw new Error(message);
|
||||
}
|
||||
|
||||
const auth = {
|
||||
user: { id: "user-1", account_id: "account-1", email: "case@example.test" },
|
||||
tenant: { id: "tenant-1", slug: "test", name: "Test" },
|
||||
scopes: [],
|
||||
roles: [],
|
||||
groups: [],
|
||||
principal: {
|
||||
account_id: "account-1",
|
||||
tenant_id: "tenant-1",
|
||||
scopes: [],
|
||||
group_ids: [],
|
||||
auth_method: "session",
|
||||
acting_assignment_id: "assignment-1"
|
||||
},
|
||||
profile_loaded: true,
|
||||
roles_loaded: true,
|
||||
groups_loaded: true
|
||||
} satisfies AuthInfo;
|
||||
|
||||
const context = createQuickAccessLaunchContext({
|
||||
pathname: "/cases/case-1",
|
||||
search: "?tab=history",
|
||||
hash: "#revision-4",
|
||||
historyIndex: 7,
|
||||
auth,
|
||||
activeObject: {
|
||||
ownerModule: "cases",
|
||||
kind: "case",
|
||||
objectId: "case-1",
|
||||
tenantId: "tenant-1",
|
||||
label: "V-2026-0042 · Resident parking permit",
|
||||
version: "4"
|
||||
},
|
||||
temporalContext: {
|
||||
validityMode: "at",
|
||||
validAt: "2026-08-01T10:00:00.000Z",
|
||||
recordedAt: "2026-08-02T10:00:00.000Z"
|
||||
},
|
||||
viewContext: {
|
||||
activeViewId: "case-worker",
|
||||
activeRevisionId: "view-revision-3",
|
||||
activeViewName: "Case worker",
|
||||
visibleSurfaceIds: [],
|
||||
locked: false,
|
||||
availableViews: [],
|
||||
provenance: [],
|
||||
diagnostics: []
|
||||
}
|
||||
});
|
||||
|
||||
assert(context.contractVersion === "1", "launch context must be explicitly versioned");
|
||||
assert(context.activeObject?.objectId === "case-1", "active object reference must survive launch");
|
||||
assert(context.actingContext?.assignmentId === "assignment-1", "acting assignment must survive launch");
|
||||
assert(context.temporalContext.validityMode === "at", "temporal selection must survive launch");
|
||||
assert(context.viewContext?.revisionId === "view-revision-3", "exact View revision must survive launch");
|
||||
assert(
|
||||
quickAccessReturnPath(context) === "/cases/case-1?tab=history#revision-4",
|
||||
"return path must preserve route, query and fragment"
|
||||
);
|
||||
assert(
|
||||
quickAccessLaunchContextFromState(quickAccessLaunchState(context))?.accountId === "account-1",
|
||||
"router state must decode a valid launch context"
|
||||
);
|
||||
assert(
|
||||
quickAccessLaunchContextFromState({ govoplanQuickAccessLaunch: { contractVersion: "2" } }) === null,
|
||||
"unknown launch context versions must fail closed"
|
||||
);
|
||||
|
||||
const crossTenant = createQuickAccessLaunchContext({
|
||||
pathname: "/cases/case-1",
|
||||
auth,
|
||||
activeObject: { ...context.activeObject!, tenantId: "tenant-2" },
|
||||
temporalContext: { validityMode: "current", validAt: null, recordedAt: null }
|
||||
});
|
||||
assert(crossTenant.activeObject === null, "cross-tenant object references must be discarded");
|
||||
Reference in New Issue
Block a user