import { afterAll, beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
import { GlobalRegistrator } from "@happy-dom/global-registrator";
import { OpenGeniApiError, type Session } from "@opengeni/sdk";
import type { OpenGeniBrowserClient } from "@opengeni/sdk/browser";
import { act, type ReactNode } from "react";
import { createRoot } from "react-dom/client";
import * as SonnerPackage from "sonner";
import {
SessionTenancyOperationController,
type SessionTenancyOperationScope,
} from "../../lib/session-tenancy-operation-controller";
const toastSuccess = mock((_message: string) => undefined);
const toastInfo = mock((_message: string) => undefined);
mock.module("sonner", () => ({
...SonnerPackage,
toast: Object.assign(
mock((_message: string) => undefined),
{
error: mock((_message: string) => undefined),
info: toastInfo,
success: toastSuccess,
},
),
}));
mock.module("../../../ui/confirm-dialog", () => ({
ConfirmDialog: ({
confirmLabel,
description,
children,
onConfirm,
open,
title,
}: {
confirmLabel: string;
description?: ReactNode | undefined;
children?: ReactNode | undefined;
onConfirm: () => unknown;
open: boolean;
title: ReactNode;
}) => {
return open ? (
{title}
{description}
{children}
) : null;
},
}));
// Keep mutation/reconciliation tests independent of Radix portal geometry.
// The production module remains Radix-backed; this semantic stand-in exposes
// the same trigger/menuitem interaction in the test document.
mock.module("../../../ui/dropdown-menu", () => ({
DropdownMenu: ({ children }: { children: ReactNode }) => <>{children}>,
DropdownMenuTrigger: ({ children }: { children: ReactNode }) => <>{children}>,
DropdownMenuContent: ({ children }: { children: ReactNode }) => {children}
,
DropdownMenuItem: ({
children,
onSelect,
"aria-label": ariaLabel,
}: {
children: ReactNode;
onSelect?: (() => void) | undefined;
"aria-label"?: string | undefined;
}) => (
),
DropdownMenuSeparator: () =>
,
}));
const { SessionTenancyControl } = await import("./session-tenancy-control");
const baseSession = {
id: "session-a",
workspaceId: "workspace-a",
accountId: "organization-a",
status: "idle",
initialMessage: "Inspect the tenancy boundary",
title: "Tenancy audit",
titleSource: "user",
tenancy: {
visibility: "workspace",
authorityEpoch: 4,
ownedByCurrentUser: true,
fork: null,
},
} as Session;
function deferred() {
let resolve!: (value: Value) => void;
let reject!: (error: unknown) => void;
const promise = new Promise((resolvePromise, rejectPromise) => {
resolve = resolvePromise;
reject = rejectPromise;
});
return { promise, reject, resolve };
}
function operationAuthority(
controller = new SessionTenancyOperationController(),
scope: Partial = {},
) {
return {
operationController: controller,
operationScope: {
principalId: "principal-a",
workspaceId: "workspace-a",
sessionId: "session-a",
workspaceTransitionRevision: 1,
...scope,
},
};
}
function apiError(input: {
status: number;
code: string;
reason?: string | undefined;
blocker?: string | undefined;
details?: Record | undefined;
outcomeUnknown?: boolean | undefined;
retryable?: boolean | undefined;
}) {
return new OpenGeniApiError(
input.status,
JSON.stringify({
error: {
code: input.code,
message: "tenancy failure",
retryable: input.retryable ?? false,
...(input.outcomeUnknown ? { outcomeUnknown: true } : {}),
...(input.reason
? {
details: {
reason: input.reason,
...(input.blocker ? { blocker: input.blocker } : {}),
...input.details,
},
}
: {}),
},
}),
{ mutation: true },
);
}
function button(container: HTMLElement, label: string): HTMLButtonElement {
const found = Array.from(container.querySelectorAll("button")).find(
(candidate) => candidate.textContent?.trim() === label,
);
if (!(found instanceof HTMLButtonElement)) throw new Error(`Missing button: ${label}`);
return found;
}
function dialogButton(container: HTMLElement, label: string): HTMLButtonElement {
const dialog = container.querySelector('[role="dialog"]');
if (!(dialog instanceof HTMLElement)) throw new Error("Missing confirmation dialog");
return button(dialog, label);
}
async function chooseAccessAction(container: HTMLElement, label: string): Promise {
const trigger = container.querySelector(
'button[aria-label$="Manage session access"]',
);
if (!trigger) throw new Error("Missing session access menu trigger");
await act(async () => trigger.click());
const item = Array.from(container.querySelectorAll('[role="menuitem"]')).find(
(candidate) =>
candidate.getAttribute("aria-label") === label || candidate.textContent?.trim() === label,
);
if (!item) throw new Error(`Missing session access action: ${label}`);
await act(async () => item.click());
}
async function flush() {
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
}
beforeAll(() => {
GlobalRegistrator.register();
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
});
afterAll(() => {
mock.restore();
GlobalRegistrator.unregister();
});
beforeEach(() => {
toastInfo.mockClear();
toastSuccess.mockClear();
});
describe("SessionTenancyControl", () => {
test("renders only activated tenancy and lets shared-session members fork without managing visibility", async () => {
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
const common = {
client: {} as OpenGeniBrowserClient,
managedSession: true,
canForkPrivately: true,
scopeLabel: "Engineering",
captureWorkspaceInvocation: () => ({ workspaceId: "workspace-a", revision: 1 }),
ownsWorkspaceInvocation: () => true,
...operationAuthority(),
onRefreshSession: async () => undefined,
onOpenSession: () => undefined,
};
await act(async () => {
root.render(
,
);
});
expect(container.textContent).toBe("");
await act(async () => {
root.render(
,
);
});
expect(container.textContent).toContain("Workspace");
expect(container.querySelector('[aria-label^="Workspace session access"]')).not.toBeNull();
expect(container.querySelector('[aria-label$="Manage session access"]')).toBeNull();
const memberActions = container.querySelector(
'button[aria-label$="Session actions"]',
);
expect(memberActions).not.toBeNull();
await act(async () => memberActions!.click());
expect(container.textContent).not.toContain("Limit this session to me");
expect(container.textContent).toContain("Fork session");
await act(async () => root.unmount());
container.remove();
});
test("names the read-only access mark with a role screen readers accept", async () => {
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
session={baseSession}
/>,
);
});
// Without a managed session there is nothing to change or fork: a focusable mark only.
expect(container.querySelector('button[aria-label*="session access"]')).toBeNull();
const mark = container.querySelector('[aria-label^="Workspace session access."]');
expect(mark).not.toBeNull();
expect(mark!.tabIndex).toBe(0);
// ARIA prohibits aria-label on a role-less span, so assistive technology may skip it.
expect(mark!.getAttribute("role")).toBe("img");
await act(async () => root.unmount());
container.remove();
});
test("retains one key across a blocker retry and reconciles the replay", async () => {
const keys: string[] = [];
let updateCalls = 0;
let reads = 0;
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
keys.push(request.idempotencyKey);
updateCalls += 1;
if (updateCalls === 1) {
throw apiError({
status: 409,
code: "conflict",
reason: "not_quiescent",
blocker: "active_sandbox_access",
});
}
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 8,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: true,
revokedGrantCount: 0,
};
});
const getSession = mock(async () => {
reads += 1;
return reads === 1
? baseSession
: {
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "private" as const, authorityEpoch: 5 },
};
});
const client = { updateSessionVisibility, getSession } as unknown as OpenGeniBrowserClient;
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(container.textContent).toContain(
"Close active Files, Terminal, Desktop, and viewer access first.",
);
expect(container.textContent).toContain("Retry limit to me");
await act(async () => dialogButton(container, "Retry limit to me").click());
await flush();
expect(keys).toHaveLength(2);
expect(keys[1]).toBe(keys[0]);
expect(getSession).toHaveBeenCalledTimes(2);
expect(container.textContent).toContain("Private");
await act(async () => root.unmount());
container.remove();
});
test("forks with an explicit destination and durable private-to-workspace acknowledgement", async () => {
const privateSession = {
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "private" as const, authorityEpoch: 5 },
};
const requests: unknown[] = [];
const forkSession = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 1,
sessionId: "session-fork",
workspaceId: "workspace-a",
visibility: "workspace" as const,
authorityEpoch: 1 as const,
copiedHistoryItemCount: 3,
replay: false,
};
});
const getSession = mock(async () => ({
...baseSession,
id: "session-fork",
tenancy: {
...baseSession.tenancy!,
visibility: "workspace" as const,
authorityEpoch: 1,
},
}));
const onOpenSession = mock((_workspaceId: string, _sessionId: string) => undefined);
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onOpenSession={onOpenSession}
/>,
);
});
await chooseAccessAction(container, "Fork session");
await act(async () => dialogButton(container, "Workspace").click());
expect(container.textContent).toContain(
"This private session's complete conversation will be copied",
);
await act(async () => dialogButton(container, "Fork for workspace").click());
await flush();
expect(requests).toEqual([
{
visibility: "workspace",
workspaceSharedAcknowledged: true,
idempotencyKey: expect.any(String),
},
]);
expect(getSession).toHaveBeenCalledWith("workspace-a", "session-fork", { fresh: true });
expect(onOpenSession).toHaveBeenCalledWith("workspace-a", "session-fork");
await act(async () => root.unmount());
container.remove();
});
test("forks from the selected message through the existing visibility confirmation", async () => {
const privateSession = {
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "private" as const, authorityEpoch: 5 },
};
const requests: unknown[] = [];
const forkSession = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 1,
sessionId: "session-fork",
workspaceId: "workspace-a",
visibility: "workspace" as const,
authorityEpoch: 1 as const,
copiedHistoryItemCount: 3,
replay: false,
};
});
const getSession = mock(async () => ({
...baseSession,
id: "session-fork",
tenancy: {
...baseSession.tenancy!,
visibility: "workspace" as const,
authorityEpoch: 1,
},
}));
const onOpenSession = mock((_workspaceId: string, _sessionId: string) => undefined);
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onOpenSession={onOpenSession}
/>,
);
});
await act(async () => dialogButton(container, "Workspace").click());
expect(container.textContent).toContain("selected message");
await act(async () => dialogButton(container, "Fork for workspace").click());
await flush();
expect(requests).toEqual([
{
sourceEventId: "selected-message-event",
visibility: "workspace",
workspaceSharedAcknowledged: true,
idempotencyKey: expect.any(String),
},
]);
expect(getSession).toHaveBeenCalledWith("workspace-a", "session-fork", { fresh: true });
expect(onOpenSession).toHaveBeenCalledWith("workspace-a", "session-fork");
await act(async () => root.unmount());
container.remove();
});
test("offers no private fork destination when the organization has not enabled private sessions", async () => {
// Migration 0336 fails a private fork into a shared workspace closed with
// SQLSTATE 55000 when the organization has not enabled private sessions, so
// the dialog must not present a choice the database refuses. The same
// `canForkPrivately={false}` state also covers "not answered yet".
const requests: unknown[] = [];
const forkSession = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 1,
sessionId: "session-fork",
workspaceId: "workspace-a",
visibility: "workspace" as const,
authorityEpoch: 1 as const,
copiedHistoryItemCount: 1,
replay: false,
};
});
const getSession = mock(async () => ({
...baseSession,
id: "session-fork",
tenancy: { ...baseSession.tenancy!, visibility: "workspace" as const, authorityEpoch: 1 },
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Fork session");
const dialog = container.querySelector('[role="dialog"]');
if (!(dialog instanceof HTMLElement)) throw new Error("Missing confirmation dialog");
expect(
Array.from(dialog.querySelectorAll('[role="radio"]')).map((node) => node.textContent?.trim()),
).toEqual(["Workspace"]);
// A private source would otherwise default the fork to private.
expect(dialog.textContent).toContain("Fork a workspace-visible copy?");
await act(async () => dialogButton(container, "Fork for workspace").click());
await flush();
expect(requests).toEqual([
{
visibility: "workspace",
workspaceSharedAcknowledged: true,
idempotencyKey: expect.any(String),
},
]);
await act(async () => root.unmount());
container.remove();
});
test("reuses the exact fork key when destination reconciliation is retryable", async () => {
const keys: string[] = [];
let forkCalls = 0;
const forkSession = mock(async (_workspaceId, _sessionId, request) => {
keys.push(request.idempotencyKey);
forkCalls += 1;
return {
operationId: "operation-fork",
eventId: "event-fork",
eventSequence: 1,
sessionId: "session-fork",
workspaceId: "workspace-a",
visibility: "workspace" as const,
authorityEpoch: 1 as const,
copiedHistoryItemCount: 1,
replay: forkCalls > 1,
};
});
let reads = 0;
const getSession = mock(async () => {
reads += 1;
if (reads === 1) {
throw apiError({ status: 503, code: "unavailable", retryable: true });
}
return {
...baseSession,
id: "session-fork",
tenancy: { ...baseSession.tenancy!, authorityEpoch: 1 },
};
});
const onOpenSession = mock((_workspaceId: string, _sessionId: string) => undefined);
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onOpenSession={onOpenSession}
/>,
);
});
await chooseAccessAction(container, "Fork session");
await act(async () => dialogButton(container, "Fork for workspace").click());
await flush();
expect(container.textContent).toContain("Retry fork");
await act(async () => dialogButton(container, "Retry fork").click());
await flush();
expect(keys).toHaveLength(2);
expect(keys[1]).toBe(keys[0]);
expect(onOpenSession).toHaveBeenCalledWith("workspace-a", "session-fork");
await act(async () => root.unmount());
container.remove();
});
test("summarizes the work a private change stops and sends one consented request", async () => {
const requests: Array> = [];
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 9,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: false,
revokedGrantCount: 0,
};
});
const previewSessionVisibilityChange = mock(async () => ({
visibility: "workspace" as const,
targetVisibility: "private" as const,
authorityEpoch: 4,
work: {
runningTurnCount: 1,
queuedTurnCount: 2,
activeGoal: true,
liveVoice: false,
otherPeoplePendingUpdateCount: 1,
otherPeopleAccountChoiceCount: 0,
},
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await flush();
expect(previewSessionVisibilityChange).toHaveBeenCalledWith(
"workspace-a",
"session-a",
"private",
);
expect(container.textContent).toContain("This will also");
expect(container.textContent).toContain("Stop the response that is in progress");
expect(container.textContent).toContain("Cancel 2 queued messages");
expect(container.textContent).toContain("Pause the active goal");
expect(container.textContent).toContain(
"Drop a pending update that uses someone else's access",
);
expect(container.textContent).not.toContain("waits for all current work");
await act(async () => dialogButton(container, "Stop work and limit to me").click());
await flush();
expect(requests).toHaveLength(1);
expect(requests[0]).toMatchObject({ visibility: "private", stopActiveWork: true });
expect(toastSuccess).toHaveBeenCalledWith("Session access updated", {
description: "Session is private to you.",
});
await act(async () => root.unmount());
container.remove();
});
test("asks again when work starts after the preview, then retries a settling stop with one key", async () => {
const requests: Array> = [];
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
if (requests.length === 1) {
throw apiError({
status: 409,
code: "conflict",
reason: "active_work",
details: { runningTurnCount: 1, queuedTurnCount: 0, activeGoal: false },
});
}
if (requests.length === 2) {
throw apiError({
status: 409,
code: "conflict",
reason: "stopping_active_work",
retryable: true,
details: { runningTurnCount: 1, queuedTurnCount: 0, activeGoal: false },
});
}
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 9,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: false,
revokedGrantCount: 0,
};
});
const previewSessionVisibilityChange = mock(async () => ({
visibility: "workspace" as const,
targetVisibility: "private" as const,
authorityEpoch: 4,
work: {
runningTurnCount: 0,
queuedTurnCount: 0,
activeGoal: false,
liveVoice: false,
otherPeoplePendingUpdateCount: 0,
otherPeopleAccountChoiceCount: 0,
},
}));
const getSession = mock(async () => baseSession);
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
// Nothing in the way: the change is sent without a dialog.
await chooseAccessAction(container, "Limit this session to me");
await flush();
expect(requests).toHaveLength(1);
expect(requests[0]?.stopActiveWork).toBeUndefined();
expect(container.textContent).toContain("This will also");
expect(container.textContent).toContain("Stop the response that is in progress");
expect(getSession).not.toHaveBeenCalled();
await act(async () => dialogButton(container, "Stop work and limit to me").click());
await flush();
expect(requests).toHaveLength(3);
expect(requests[1]).toMatchObject({ stopActiveWork: true });
expect(requests[2]).toMatchObject({ stopActiveWork: true });
expect(new Set(requests.map((request) => request.idempotencyKey)).size).toBe(1);
expect(toastSuccess).toHaveBeenCalledWith("Session access updated", {
description: "Session is private to you.",
});
await act(async () => root.unmount());
container.remove();
});
test("drops other people's access with one confirmation that stops nothing", async () => {
const requests: Array> = [];
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
requests.push(request);
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 9,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: false,
revokedGrantCount: 0,
};
});
const previewSessionVisibilityChange = mock(async () => ({
visibility: "workspace" as const,
targetVisibility: "private" as const,
authorityEpoch: 4,
work: {
runningTurnCount: 0,
queuedTurnCount: 0,
activeGoal: false,
liveVoice: false,
otherPeoplePendingUpdateCount: 2,
otherPeopleAccountChoiceCount: 1,
},
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await flush();
expect(requests).toHaveLength(0);
expect(container.textContent).toContain(
"Drop 2 pending updates that use other people's access",
);
expect(container.textContent).toContain("Stop using another person's account in this session");
expect(container.textContent).not.toContain("Stop work and limit to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(requests).toHaveLength(1);
expect(requests[0]).toMatchObject({ visibility: "private", stopActiveWork: true });
await act(async () => root.unmount());
container.remove();
});
test("reconciles an unknown visibility outcome before offering another operation", async () => {
const updateSessionVisibility = mock(async () => {
throw apiError({ status: 503, code: "upstream_unavailable", outcomeUnknown: true });
});
const getSession = mock(async () => ({
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "private" as const, authorityEpoch: 5 },
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(getSession).toHaveBeenCalledTimes(1);
expect(container.textContent).toContain("Only you can open this session.");
expect(toastInfo).toHaveBeenCalledWith("Session access refreshed", {
description: "Session is private to you.",
});
await act(async () => root.unmount());
container.remove();
});
test("renders the fresh workspace state when a visibility replay was superseded", async () => {
const controller = new SessionTenancyOperationController();
const authority = operationAuthority(controller);
const updateSessionVisibility = mock(async () => ({
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 8,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: true,
revokedGrantCount: 0,
}));
const getSession = mock(async () => ({
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "workspace" as const, authorityEpoch: 6 },
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...authority}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(container.textContent).toContain("Visible to people in Engineering.");
expect(container.textContent).not.toContain("Only you can open this session.");
expect(toastInfo).toHaveBeenCalledWith("Session access refreshed", {
description: "Session is visible to Engineering.",
});
expect(controller.snapshot(authority.operationScope).visibility).toBeNull();
await act(async () => root.unmount());
container.remove();
});
test("retires a visibility replay when the fresh projection is no longer present", async () => {
const controller = new SessionTenancyOperationController();
const authority = operationAuthority(controller);
const updateSessionVisibility = mock(async () => ({
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 8,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: true,
revokedGrantCount: 0,
}));
const getSession = mock(async () => ({ ...baseSession, tenancy: undefined }));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...authority}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(container.textContent).toBe("");
expect(toastSuccess).not.toHaveBeenCalled();
expect(toastInfo).toHaveBeenCalledWith("Session access refreshed", {
description: "Session access controls are no longer available.",
});
expect(controller.snapshot(authority.operationScope).visibility).toBeNull();
await act(async () => root.unmount());
container.remove();
});
test("reuses an outcome-unknown visibility key after an actual unmount and remount", async () => {
const keys: string[] = [];
const controller = new SessionTenancyOperationController();
const authority = operationAuthority(controller);
let calls = 0;
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
keys.push(request.idempotencyKey);
calls += 1;
if (calls === 1) {
throw apiError({ status: 503, code: "upstream_unavailable", outcomeUnknown: true });
}
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 8,
visibility: "private" as const,
authorityEpoch: 5,
changed: true,
replay: true,
revokedGrantCount: 0,
};
});
let reads = 0;
const getSession = mock(async () => {
reads += 1;
return reads === 1
? baseSession
: {
...baseSession,
tenancy: { ...baseSession.tenancy!, visibility: "private" as const, authorityEpoch: 5 },
};
});
const props = {
session: baseSession,
client: { updateSessionVisibility, getSession } as unknown as OpenGeniBrowserClient,
managedSession: true,
canForkPrivately: true,
scopeLabel: "Engineering",
captureWorkspaceInvocation: () => ({ workspaceId: "workspace-a", revision: 1 }),
ownsWorkspaceInvocation: () => true,
...authority,
onRefreshSession: async () => undefined,
onOpenSession: () => undefined,
};
const container = document.createElement("div");
document.body.append(container);
let root = createRoot(container);
await act(async () => root.render());
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
await act(async () => root.unmount());
root = createRoot(container);
await act(async () => root.render());
await chooseAccessAction(container, "Retry: Limit this session to me");
expect(container.textContent).toContain("Retry limit to me");
await act(async () => dialogButton(container, "Retry limit to me").click());
await flush();
expect(keys).toHaveLength(2);
expect(keys[1]).toBe(keys[0]);
expect(container.textContent).toContain("Only you can open this session.");
await act(async () => root.unmount());
container.remove();
});
test("refetches an authority-epoch conflict and starts the next intent with fresh input", async () => {
const keys: string[] = [];
const epochs: number[] = [];
let calls = 0;
const updateSessionVisibility = mock(async (_workspaceId, _sessionId, request) => {
keys.push(request.idempotencyKey);
epochs.push(request.expectedAuthorityEpoch);
calls += 1;
if (calls === 1) {
throw apiError({ status: 409, code: "conflict", reason: "authority_epoch" });
}
return {
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 10,
visibility: "private" as const,
authorityEpoch: 6,
changed: true,
replay: false,
revokedGrantCount: 0,
};
});
const getSession = mock(async () => ({
...baseSession,
tenancy: { ...baseSession.tenancy!, authorityEpoch: 5 },
}));
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => true}
{...operationAuthority()}
onRefreshSession={async () => undefined}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(container.textContent).toContain(
"Session access changed in another tab. The latest state has been loaded.",
);
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
await flush();
expect(epochs).toEqual([4, 5]);
expect(keys[1]).not.toBe(keys[0]);
await act(async () => root.unmount());
container.remove();
});
for (const transition of ["principal", "workspace"] as const) {
test(`makes a delayed mutation inert after a ${transition} transition`, async () => {
const pending = deferred<{
operationId: string;
eventId: string;
eventSequence: number;
visibility: "private";
authorityEpoch: number;
changed: true;
replay: false;
revokedGrantCount: number;
}>();
let current = true;
const refresh = mock(async () => undefined);
const updateSessionVisibility = mock(async () => await pending.promise);
const container = document.createElement("div");
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
({ workspaceId: "workspace-a", revision: 1 })}
ownsWorkspaceInvocation={() => current}
{...operationAuthority()}
onRefreshSession={refresh}
onOpenSession={() => undefined}
/>,
);
});
await chooseAccessAction(container, "Limit this session to me");
await act(async () => dialogButton(container, "Limit to me").click());
current = false;
pending.resolve({
operationId: crypto.randomUUID(),
eventId: crypto.randomUUID(),
eventSequence: 8,
visibility: "private",
authorityEpoch: 5,
changed: true,
replay: false,
revokedGrantCount: 0,
});
await flush();
expect(refresh).not.toHaveBeenCalled();
expect(toastSuccess).not.toHaveBeenCalled();
expect(container.textContent).toContain("Workspace");
await act(async () => root.unmount());
container.remove();
});
}
});