import { describe, expect, mock, test } from 'bun:test'; type ComponentFn

= Record> = (props: P) => unknown; type HookRecord = { values: unknown[]; deps: Array; }; type HookEffect = () => void | (() => void); type HookCallback = (...args: unknown[]) => unknown; type JSXProps = Record & { children?: unknown }; type JSXElementType

= Record> = ComponentFn

| string | symbol; const hookRecords = new Map(); let currentRecord: HookRecord | null = null; let hookIndex = 0; let pendingEffects: Array<() => void> = []; const resetHarness = () => { hookRecords.clear(); currentRecord = null; hookIndex = 0; pendingEffects = []; }; const shallowEqualDeps = (left?: unknown[], right?: unknown[]): boolean => { if (!left || !right) return false; if (left.length !== right.length) return false; return left.every((value, index) => Object.is(value, right[index])); }; const getRecord = (component: unknown): HookRecord => { const existing = hookRecords.get(component); if (existing) return existing; const record: HookRecord = { values: [], deps: [] }; hookRecords.set(component, record); return record; }; const getHookRecord = (): HookRecord => { if (!currentRecord) { throw new Error('Hooks can only run during a render pass'); } return currentRecord; }; const renderComponent =

>(component: ComponentFn

, props: P): unknown => { const previousRecord = currentRecord; const previousHookIndex = hookIndex; currentRecord = getRecord(component); hookIndex = 0; try { return component(props); } finally { currentRecord = previousRecord; hookIndex = previousHookIndex; } }; function useCallback(callback: T, deps?: unknown[]): T { const record = getHookRecord(); const index = hookIndex++; const previousDeps = record.deps[index]; if (!shallowEqualDeps(previousDeps, deps)) { record.values[index] = callback; record.deps[index] = deps; } return record.values[index] as T; } function useEffect(effect: HookEffect, deps?: unknown[]): void { const record = getHookRecord(); const index = hookIndex++; const previousDeps = record.deps[index]; if (!shallowEqualDeps(previousDeps, deps)) { record.deps[index] = deps; pendingEffects.push(() => { effect(); }); } } function useMemo(factory: () => T, deps?: unknown[]): T { const record = getHookRecord(); const index = hookIndex++; const previousDeps = record.deps[index]; if (!shallowEqualDeps(previousDeps, deps)) { record.values[index] = factory(); record.deps[index] = deps; } return record.values[index] as T; } function useRef(initialValue: T): { current: T } { const record = getHookRecord(); const index = hookIndex++; if (record.values[index] === undefined) { record.values[index] = { current: initialValue }; } return record.values[index] as { current: T }; } function useState(initialValue: T | (() => T)): readonly [T, (next: T | ((prev: T) => T)) => void] { const record = getHookRecord(); const index = hookIndex++; if (record.values[index] === undefined) { record.values[index] = typeof initialValue === 'function' ? (initialValue as () => T)() : initialValue; } const setState = (next: T | ((prev: T) => T)) => { record.values[index] = typeof next === 'function' ? (next as (prev: T) => T)(record.values[index] as T) : next; }; return [record.values[index] as T, setState] as const; } function jsx

>(type: JSXElementType

, props: JSXProps & P): unknown { if (type === reactJsxRuntime.Fragment) { return props.children ?? null; } if (typeof type === 'function') { return renderComponent(type, props as P); } return { type, props }; } const ReactMock = { useCallback, useEffect, useMemo, useRef, useState, }; const reactJsxRuntime = { Fragment: Symbol('Fragment'), jsx, jsxs: jsx, jsxDEV: jsx, }; let desktopShell = false; let runtimeFetchRejects = true; mock.module('react/jsx-runtime', () => reactJsxRuntime); mock.module('react/jsx-dev-runtime', () => reactJsxRuntime); mock.module('react', () => ({ __esModule: true, default: ReactMock, ...ReactMock, })); mock.module('@simplewebauthn/browser', () => ({ browserSupportsWebAuthn: mock(() => false), })); mock.module('@/components/ui/button', () => ({ Button: ({ children }: { children?: unknown }) => children ?? null, })); mock.module('@/components/ui/checkbox', () => ({ Checkbox: () => null, })); mock.module('@/components/ui/input', () => ({ Input: () => null, })); mock.module('@/components/ui', () => ({ toast: { success: mock(() => undefined), error: mock(() => undefined), message: mock(() => undefined), }, })); mock.module('@/components/ui/OpenChamberLogo', () => ({ OpenChamberLogo: () => 'logo', })); mock.module('@/components/icon/Icon', () => ({ Icon: () => null, })); mock.module('@/components/desktop/DesktopHostSwitcher', () => ({ DesktopHostSwitcherInline: () => 'host-switcher', })); mock.module('@/lib/i18n', () => ({ useI18n: () => ({ t: (key: string) => key }), })); mock.module('@/lib/desktop', () => ({ invokeDesktop: mock(() => Promise.resolve(null)), isDesktopShell: mock(() => desktopShell), isVSCodeRuntime: mock(() => false), })); mock.module('@/lib/persistence', () => ({ initializeAppearancePreferences: mock(() => Promise.resolve()), syncDesktopSettings: mock(() => Promise.resolve()), })); mock.module('@/lib/directoryPersistence', () => ({ applyPersistedDirectoryPreferences: mock(() => Promise.resolve()), })); mock.module('@/lib/runtime-fetch', () => ({ runtimeFetch: mock(async () => { if (runtimeFetchRejects) { throw new Error('offline'); } return new Response(JSON.stringify({ authenticated: false }), { status: 401, headers: { 'content-type': 'application/json' }, }); }), })); mock.module('@/lib/runtime-auth', () => ({ getRuntimeExtraHeadersSync: mock(() => ({})), })); mock.module('@/lib/runtime-switch', () => ({ getRuntimeApiBaseUrl: mock(() => ''), subscribeRuntimeEndpointChanged: mock(() => () => {}), switchRuntimeEndpoint: mock(() => undefined), })); mock.module('@/lib/desktopHosts', () => ({ desktopHostsGet: mock(() => Promise.resolve(null)), desktopHostsSet: mock(() => Promise.resolve()), getDesktopHostApiUrl: mock(() => ''), normalizeHostUrl: mock(() => ''), })); mock.module('@/lib/passkeys', () => ({ authenticateWithPasskey: mock(() => Promise.resolve(null)), cancelPasskeyCeremony: mock(() => undefined), defaultPasskeyStatus: { enabled: false, hasPasskeys: false, passkeyCount: 0, rpID: null }, fetchPasskeyStatus: mock(() => Promise.resolve({ enabled: false, hasPasskeys: false, passkeyCount: 0, rpID: null })), isPasskeyCeremonyAbort: mock(() => false), registerCurrentDevicePasskey: mock(() => Promise.resolve(null)), })); const { SessionAuthGate } = await import('./SessionAuthGate'); const flushEffects = async () => { while (pendingEffects.length > 0) { const effects = pendingEffects; pendingEffects = []; for (const effect of effects) { effect(); } await Promise.resolve(); } await Promise.resolve(); await new Promise((resolve) => setTimeout(resolve, 0)); await Promise.resolve(); }; const renderGate = async () => { const firstPass = renderComponent(SessionAuthGate, { children: 'child' }); await flushEffects(); const secondPass = renderComponent(SessionAuthGate, { children: 'child' }); await flushEffects(); return secondPass ?? firstPass; }; const collectText = (node: unknown): string => { if (node === null || node === undefined || typeof node === 'boolean') return ''; if (typeof node === 'string' || typeof node === 'number') return String(node); if (Array.isArray(node)) return node.map((child) => collectText(child)).join(' '); if (typeof node === 'object') { const element = node as { props?: { children?: unknown } }; return collectText(element.props?.children); } return ''; }; describe('SessionAuthGate status-check failure behavior', () => { test('keeps non-desktop status-check rejection on the error screen', async () => { resetHarness(); desktopShell = false; runtimeFetchRejects = true; const tree = await renderGate(); const text = collectText(tree); expect(text).toContain('sessionAuth.error.networkTitle'); expect(text).not.toContain('sessionAuth.locked.unlockTitle'); }); test('keeps desktop-shell status-check rejection on the locked password prompt', async () => { resetHarness(); desktopShell = true; runtimeFetchRejects = true; const tree = await renderGate(); const text = collectText(tree); expect(text).toContain('sessionAuth.locked.unlockTitle'); expect(text).not.toContain('sessionAuth.error.networkTitle'); }); });