From 73e21d005074b08438fd0fc09dada5e31aaeae0d Mon Sep 17 00:00:00 2001 From: Alan Shum Date: Fri, 28 Aug 2026 05:44:40 -0700 Subject: [PATCH] test(ui): repair current main test baseline (#3191) --- .../auth/SessionAuthGate.behavior.test.tsx | 13 +++++++++++++ .../components/chat/markdown/markdownCore.test.ts | 14 +++++++++++++- packages/ui/src/lib/shortcuts.test.ts | 4 ++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/auth/SessionAuthGate.behavior.test.tsx b/packages/ui/src/components/auth/SessionAuthGate.behavior.test.tsx index 8f8cd7ee..956ec2a1 100644 --- a/packages/ui/src/components/auth/SessionAuthGate.behavior.test.tsx +++ b/packages/ui/src/components/auth/SessionAuthGate.behavior.test.tsx @@ -303,6 +303,19 @@ mock.module('@/lib/passkeys', () => ({ registerCurrentDevicePasskey: mock(() => Promise.resolve(null)), })); +const authSessionStore = { + state: 'ok' as const, + markAuthenticated: mock(() => undefined), +}; + +mock.module('@/lib/runtime-auth-expiry', () => ({ + installAuthSessionFocusWatch: mock(() => undefined), + useAuthSessionStore: Object.assign( + (selector: (store: typeof authSessionStore) => unknown) => selector(authSessionStore), + { getState: () => authSessionStore }, + ), +})); + const { SessionAuthGate } = await import('./SessionAuthGate'); const flushEffects = async () => { diff --git a/packages/ui/src/components/chat/markdown/markdownCore.test.ts b/packages/ui/src/components/chat/markdown/markdownCore.test.ts index 1b76c272..b1366366 100644 --- a/packages/ui/src/components/chat/markdown/markdownCore.test.ts +++ b/packages/ui/src/components/chat/markdown/markdownCore.test.ts @@ -19,6 +19,15 @@ const sanitizeHooks: { afterSanitizeAttributes?: (node: unknown) => void; } = {}; +// Mirrors DOMPurify's default URI policy: approved schemes plus relative URLs. +const DOMPURIFY_ALLOWED_URI_RE = + // Keep this byte-aligned with DOMPurify's default IS_ALLOWED_URI expression. + // eslint-disable-next-line no-useless-escape + /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; +const URI_ATTRIBUTE_WHITESPACE_RE = + // eslint-disable-next-line no-control-regex + /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g; + Object.assign(globalThis, { window: {}, HTMLAnchorElement: TestAnchorElement, @@ -36,7 +45,10 @@ mock.module('dompurify', () => ({ sanitizeHooks.uponSanitizeAttribute?.(anchor, data); sanitizeHooks.afterSanitizeAttributes?.(anchor); - return data.forceKeepAttr || /^(?:https?|mailto|tel):/i.test(href) ? attribute : ''; + const normalizedHref = href.replace(URI_ATTRIBUTE_WHITESPACE_RE, ''); + return data.forceKeepAttr || DOMPURIFY_ALLOWED_URI_RE.test(normalizedHref) + ? attribute + : ''; }), }, })); diff --git a/packages/ui/src/lib/shortcuts.test.ts b/packages/ui/src/lib/shortcuts.test.ts index 593ea714..fd2f2bd1 100644 --- a/packages/ui/src/lib/shortcuts.test.ts +++ b/packages/ui/src/lib/shortcuts.test.ts @@ -8,8 +8,8 @@ import { } from './shortcuts'; describe('getEffectiveShortcutPrefix', () => { - test('falls back to the action default (bare mod) when unset', () => { - expect(getEffectiveShortcutPrefix('switch_context_surface', {})).toBe('mod'); + test('falls back to the action default (bare mod+alt) when unset', () => { + expect(getEffectiveShortcutPrefix('switch_context_surface', {})).toBe('mod+alt'); }); test('honors modifier + key overrides', () => {