diff --git a/features/messaging/frontend-public/src/features/inbox/test-utils/content-flagging-service-only.ts b/features/messaging/frontend-public/src/features/inbox/test-utils/content-flagging-service-only.ts new file mode 100644 index 000000000..ae65d87cb --- /dev/null +++ b/features/messaging/frontend-public/src/features/inbox/test-utils/content-flagging-service-only.ts @@ -0,0 +1,30 @@ +/** + * Test-only re-export of ContentFlaggingService. + * + * The package barrel (@lilith/text-processing-content-flagging) re-exports + * UI components that depend on styled-components + React. In test environments + * this requires either deps.inline (causes OOM with many tests) or vitest + * stub factories for every transitive dep. + * + * This file re-exports ONLY the pure-logic service + types from the package's + * dist, bypassing the barrel and its UI component imports entirely. + * Used via resolve.alias in vite.config.ts test configuration. + */ +export { + ContentFlaggingService, + getContentFlaggingService, + flagContent, +} from '@lilith/text-processing-content-flagging/dist/ContentFlaggingService.js'; + +export { + DEFAULT_FLAGGING_CONFIG, + SEVERITY_SCORES, +} from '@lilith/text-processing-content-flagging/dist/types.js'; + +export type { + ContentFlagResult, + ContentFlag, + FlagCategory, + FlaggingConfig, + ContentFlagSeverity, +} from '@lilith/text-processing-content-flagging/dist/types.js'; diff --git a/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.service.test.ts b/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.service.test.ts index abb6ab6fb..263b00823 100644 --- a/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.service.test.ts +++ b/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.service.test.ts @@ -5,45 +5,12 @@ * These verify the core safety guarantees: threats are caught, normal * messages pass, and adult platform context doesn't produce false positives. * - * The content-flagging package barrel re-exports UI components that depend on - * styled-components + React. We replace those transitive dependencies with - * stubs via vi.mock so the service class (pure logic) can be tested in Node. - * This works because vite.config.ts inlines the package (deps.inline). + * The barrel import is aliased in vite.config.ts (test.resolve.alias) to a + * service-only re-export that skips UI components, avoiding styled-components + * transitive deps entirely. No deps.inline or stub factories needed. */ -import { describe, it, expect, vi } from 'vitest'; - -// vi.hoisted runs BEFORE vi.mock factories (which are hoisted above imports). -// This ensures stub values exist when the mock factories reference them. -const { styledProxy, tagFn, noop } = vi.hoisted(() => { - const noop = () => null; - const tagFn = () => noop; - const styledProxy = new Proxy(tagFn, { - get: (_target, prop) => (prop === '__esModule' ? true : tagFn), - apply: () => noop, - }); - return { styledProxy, tagFn, noop }; -}); - -// Stub styled-components and UI deps used by the package's React component exports. -// Only the ContentFlaggingService class (pure regex logic) is exercised here. -vi.mock('styled-components', () => ({ - default: styledProxy, - keyframes: tagFn, - css: tagFn, - ThemeProvider: noop, -})); - -vi.mock('@lilith/ui-styled-components', () => ({ - default: styledProxy, - keyframes: tagFn, - css: tagFn, - ThemeProvider: noop, - useTheme: () => ({}), -})); - -vi.mock('lucide-react', () => new Proxy({}, { get: () => noop })); - +import { describe, it, expect } from 'vitest'; import { ContentFlaggingService } from '@lilith/text-processing-content-flagging'; /** diff --git a/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.worker.test.ts b/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.worker.test.ts index 46fe44d10..2dd78e6dc 100644 --- a/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.worker.test.ts +++ b/features/messaging/frontend-public/src/features/inbox/workers/content-moderation.worker.test.ts @@ -2,7 +2,10 @@ * Content Moderation Worker Protocol Tests * * Tests the Web Worker message handling by simulating the worker environment. - * We provide a mock postMessage, import the worker module (which registers + * The barrel import is aliased in vite.config.ts (test.resolve.alias) to skip + * UI components, so no styled-components stubs are needed. + * + * We provide a spy postMessage, import the worker module (which registers * its addEventListener handler on the global scope), then dispatch * MessageEvents to exercise the protocol. * @@ -11,35 +14,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -// vi.hoisted runs BEFORE vi.mock factories. -const { styledProxy, tagFn, noop, postMessageSpy } = vi.hoisted(() => { - const noop = () => null; - const tagFn = () => noop; - const styledProxy = new Proxy(tagFn, { - get: (_target, prop) => (prop === '__esModule' ? true : tagFn), - apply: () => noop, - }); - const postMessageSpy = vi.fn(); - return { styledProxy, tagFn, noop, postMessageSpy }; -}); - -// Stub styled-components transitive deps (same pattern as service test) -vi.mock('styled-components', () => ({ - default: styledProxy, - keyframes: tagFn, - css: tagFn, - ThemeProvider: noop, -})); - -vi.mock('@lilith/ui-styled-components', () => ({ - default: styledProxy, - keyframes: tagFn, - css: tagFn, - ThemeProvider: noop, - useTheme: () => ({}), -})); - -vi.mock('lucide-react', () => new Proxy({}, { get: () => noop })); +const postMessageSpy = vi.fn(); // Replace the global postMessage with our spy BEFORE the worker module loads. // The worker calls bare `postMessage()` which resolves to the global scope.