149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import type { AuthInfo, QuickAccessResult } from "../src/types";
|
|
import {
|
|
createQuickAccessLaunchContext,
|
|
isQuickAccessResultAllowed,
|
|
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: [],
|
|
presentation: {
|
|
quickAccessRecommendedToolIds: ["mail.messages"],
|
|
quickAccessFocusedToolIds: ["mail.messages", "files.recent"]
|
|
}
|
|
}
|
|
});
|
|
|
|
assert(context.contractVersion === "2", "launch context must be explicitly versioned");
|
|
assert(context.referenceContractVersion === "1", "reference payloads must be independently 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(context.viewContext?.recommendedToolIds[0] === "mail.messages", "View recommendations must survive launch without becoming authority");
|
|
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: "3" } }) === 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");
|
|
|
|
const selectedFileResult = {
|
|
contractVersion: "1",
|
|
outcome: "completed",
|
|
action: "selected",
|
|
reference: {
|
|
ownerModule: "files",
|
|
kind: "file-version",
|
|
objectId: "version-1",
|
|
tenantId: "tenant-1",
|
|
label: "Permit evidence.pdf",
|
|
path: "/files?version=version-1"
|
|
}
|
|
} as const;
|
|
assert(
|
|
isQuickAccessResultAllowed(selectedFileResult, context, ["files.file-version"]),
|
|
"a declared same-tenant result reference is accepted"
|
|
);
|
|
assert(
|
|
!isQuickAccessResultAllowed(
|
|
{ ...selectedFileResult, reference: { ...selectedFileResult.reference, tenantId: "tenant-2" } },
|
|
context,
|
|
["files.file-version"]
|
|
),
|
|
"cross-tenant result references fail closed"
|
|
);
|
|
assert(
|
|
!isQuickAccessResultAllowed(selectedFileResult, context, ["records.record"]),
|
|
"undeclared result-reference kinds fail closed"
|
|
);
|
|
assert(
|
|
isQuickAccessResultAllowed({ contractVersion: "1", outcome: "cancelled", reason: "user" }, context),
|
|
"explicit cancellation is a valid terminal result"
|
|
);
|
|
assert(
|
|
!isQuickAccessResultAllowed(
|
|
{ ...selectedFileResult, outcome: "unknown" } as unknown as QuickAccessResult,
|
|
context,
|
|
["files.file-version"]
|
|
),
|
|
"unknown result outcomes fail closed"
|
|
);
|
|
assert(
|
|
!isQuickAccessResultAllowed(
|
|
{
|
|
...selectedFileResult,
|
|
reference: { ...selectedFileResult.reference, path: "//outside.example/files/version-1" }
|
|
},
|
|
context,
|
|
["files.file-version"]
|
|
),
|
|
"protocol-relative result paths fail closed"
|
|
);
|