{"version":3,"file":"feature-test-utils.mjs","sources":["../../../../src/lib/feature/testing/feature-test-utils.ts"],"sourcesContent":["/**\n * @file Feature Testing Utilities\n * @description Isolated testing utilities for feature modules\n */\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport React, { type ReactElement, type ReactNode } from 'react';\nimport type { FeatureAccess, FeatureConfig, FeatureRegistryEntry } from '../types';\nimport { FeatureDIContainer, FeatureDIProvider } from '../featureDI';\nimport { expect, type Mock, vi } from 'vitest';\n\n/**\n * Simple render result type\n */\nexport interface RenderResult {\n  element: ReactElement;\n  queryClient: QueryClient;\n  diContainer: FeatureDIContainer;\n}\n\n// ============================================================================\n// Test Query Client\n// ============================================================================\n\n/**\n * Create a test query client with sensible defaults\n */\nexport function createTestQueryClient(\n  options: {\n    defaultOptions?: {\n      queries?: {\n        retry?: number | boolean;\n        gcTime?: number;\n        staleTime?: number;\n      };\n      mutations?: {\n        retry?: number | boolean;\n      };\n    };\n  } = {}\n): QueryClient {\n  return new QueryClient({\n    defaultOptions: {\n      queries: {\n        retry: false,\n        gcTime: 0,\n        staleTime: 0,\n        ...options.defaultOptions?.queries,\n      },\n      mutations: {\n        retry: false,\n        ...options.defaultOptions?.mutations,\n      },\n    },\n  });\n}\n\n// ============================================================================\n// Feature Test Wrapper\n// ============================================================================\n\n/**\n * Props for FeatureTestWrapper\n */\nexport interface FeatureTestWrapperProps {\n  children: ReactNode;\n  queryClient?: QueryClient;\n  diContainer?: FeatureDIContainer;\n  initialRouterEntries?: string[];\n}\n\n/**\n * Comprehensive test wrapper for feature testing\n */\nexport function FeatureTestWrapper({\n  children,\n  queryClient = createTestQueryClient(),\n  diContainer = new FeatureDIContainer(),\n}: FeatureTestWrapperProps): ReactElement {\n  return React.createElement(\n    QueryClientProvider,\n    { client: queryClient },\n    React.createElement(FeatureDIProvider, { container: diContainer, children })\n  );\n}\n\n/**\n * Create a custom render function for a feature\n */\nexport function createFeatureRenderer(\n  defaultOptions: Partial<FeatureTestWrapperProps> = {}\n): (ui: ReactElement, options?: Partial<FeatureTestWrapperProps>) => RenderResult {\n  return function renderFeature(\n    ui: ReactElement,\n    options: Partial<FeatureTestWrapperProps> = {}\n  ): RenderResult {\n    const mergedOptions = { ...defaultOptions, ...options };\n    const queryClient = mergedOptions.queryClient ?? createTestQueryClient();\n    const diContainer = mergedOptions.diContainer ?? new FeatureDIContainer();\n\n    return {\n      element: React.createElement(FeatureTestWrapper, {\n        ...mergedOptions,\n        queryClient,\n        diContainer,\n        children: ui,\n      }),\n      queryClient,\n      diContainer,\n    };\n  };\n}\n\n// ============================================================================\n// Mock Feature Factory\n// ============================================================================\n\n/**\n * Options for creating a mock feature\n */\nexport interface MockFeatureOptions {\n  id?: string;\n  name?: string;\n  description?: string;\n  category?: string;\n  order?: number;\n  access?: Partial<FeatureAccess>;\n  config?: Partial<FeatureConfig>;\n}\n\n/**\n * Create a mock feature for testing\n */\nexport function createMockFeature(overrides: MockFeatureOptions = {}): FeatureRegistryEntry {\n  const {\n    id = 'mock-feature',\n    name = 'Mock Feature',\n    description = 'Mock feature for testing',\n    category = 'test',\n    order = 999,\n    access: accessOverrides = {},\n    config: configOverrides = {},\n  } = overrides;\n\n  const mockConfig: FeatureConfig = {\n    metadata: {\n      id,\n      name,\n      description,\n      category,\n      order,\n    },\n    access: {\n      requiredRoles: [],\n      featureFlag: `${id}_enabled`,\n      ...accessOverrides,\n    },\n    ...configOverrides,\n  };\n\n  const MockComponent = (): React.ReactElement =>\n    React.createElement('div', { 'data-testid': id }, name);\n\n  return {\n    config: mockConfig,\n    component: React.lazy(async () => Promise.resolve({ default: MockComponent })),\n  };\n}\n\n/**\n * Create multiple mock features\n */\nexport function createMockFeatures(\n  count: number,\n  baseOptions: MockFeatureOptions = {}\n): FeatureRegistryEntry[] {\n  return Array.from({ length: count }, (_, index) =>\n    createMockFeature({\n      ...baseOptions,\n      id: `${baseOptions.id ?? 'mock-feature'}-${index + 1}`,\n      name: `${baseOptions.name ?? 'Mock Feature'} ${index + 1}`,\n      order: (baseOptions.order ?? 0) + index,\n    })\n  );\n}\n\n// ============================================================================\n// Mock Entity Factory\n// ============================================================================\n\n/**\n * Base entity interface for mocking\n */\nexport interface MockEntityBase {\n  id: string;\n  createdAt: string;\n  updatedAt: string;\n}\n\n/**\n * Create a mock entity with common fields\n */\nexport function createMockEntity<T extends Partial<MockEntityBase>>(\n  overrides: T & { id?: string } = {} as T\n): MockEntityBase & T {\n  const now = new Date().toISOString();\n  return {\n    id: overrides.id ?? `mock-${Math.random().toString(36).substr(2, 9)}`,\n    createdAt: now,\n    updatedAt: now,\n    ...overrides,\n  } as MockEntityBase & T;\n}\n\n/**\n * Create multiple mock entities\n */\nexport function createMockEntities<T extends Partial<MockEntityBase>>(\n  count: number,\n  factory: (index: number) => T\n): Array<MockEntityBase & T> {\n  return Array.from({ length: count }, (_, index) => createMockEntity(factory(index)));\n}\n\n// ============================================================================\n// API Mocking Utilities\n// ============================================================================\n\n/**\n * Mock API response wrapper\n */\nexport interface MockApiResponse<T> {\n  data: T;\n  status: number;\n  headers?: Record<string, string>;\n}\n\n/**\n * Create a mock API response\n */\nexport function createMockApiResponse<T>(\n  data: T,\n  options: { status?: number; headers?: Record<string, string> } = {}\n): MockApiResponse<T> {\n  return {\n    data,\n    status: options.status ?? 200,\n    headers: options.headers,\n  };\n}\n\n/**\n * Mock service method type\n */\ntype MockFn = Mock | ((...args: unknown[]) => unknown);\n\n/**\n * Create a mock service with typed methods\n */\nexport function createMockService<T extends Record<string, (...args: unknown[]) => unknown>>(\n  implementations: Partial<{\n    [K in keyof T]: MockFn;\n  }>\n): { [K in keyof T]: Mock } {\n  const service = {} as { [K in keyof T]: Mock };\n\n  for (const [key, impl] of Object.entries(implementations)) {\n    const typedKey = key as keyof T;\n    if (typeof impl === 'function' && 'mockImplementation' in impl) {\n      service[typedKey] = impl as unknown as Mock;\n    } else {\n      service[typedKey] = vi.fn().mockImplementation(impl as MockFn) as unknown as Mock;\n    }\n  }\n\n  return service;\n}\n\n/**\n * Create mock query data for testing\n */\nexport function createMockQueryData<T>(\n  data: T,\n  options: {\n    isLoading?: boolean;\n    isFetching?: boolean;\n    error?: Error | null;\n    isError?: boolean;\n    isSuccess?: boolean;\n  } = {}\n): {\n  data: T | undefined;\n  isLoading: boolean;\n  isFetching: boolean;\n  error: Error | null;\n  isError: boolean;\n  isSuccess: boolean;\n  refetch: Mock;\n} {\n  const isLoading = options.isLoading ?? false;\n  const isError = options.isError ?? !!options.error;\n  const isSuccess = options.isSuccess ?? (!isLoading && !isError);\n\n  return {\n    data: isLoading ? undefined : data,\n    isLoading,\n    isFetching: options.isFetching ?? isLoading,\n    error: options.error ?? null,\n    isError,\n    isSuccess,\n    refetch: vi.fn().mockResolvedValue({ data }),\n  };\n}\n\n/**\n * Create mock mutation result\n */\nexport function createMockMutationResult<TData, _TVariables>(\n  options: {\n    isLoading?: boolean;\n    isSuccess?: boolean;\n    isError?: boolean;\n    error?: Error | null;\n    data?: TData;\n  } = {}\n): {\n  mutate: Mock;\n  mutateAsync: Mock;\n  isLoading: boolean;\n  isPending: boolean;\n  isSuccess: boolean;\n  isError: boolean;\n  error: Error | null;\n  data: TData | undefined;\n  reset: Mock;\n} {\n  return {\n    mutate: vi.fn(),\n    mutateAsync: vi.fn().mockResolvedValue(options.data),\n    isLoading: options.isLoading ?? false,\n    isPending: options.isLoading ?? false,\n    isSuccess: options.isSuccess ?? false,\n    isError: options.isError ?? false,\n    error: options.error ?? null,\n    data: options.data,\n    reset: vi.fn(),\n  };\n}\n\n// ============================================================================\n// Feature Integration Test Helpers\n// ============================================================================\n\n/**\n * Test fixture for feature integration tests\n */\nexport interface FeatureTestFixture<TData> {\n  featureId: string;\n  initialData: TData;\n  mockApi: Record<string, Mock>;\n  queryClient: QueryClient;\n  diContainer: FeatureDIContainer;\n}\n\n/**\n * Create a complete test fixture for a feature\n */\nexport function createFeatureTestFixture<TData>(\n  featureId: string,\n  options: {\n    initialData: TData;\n    apiMethods?: string[];\n  }\n): FeatureTestFixture<TData> {\n  const queryClient = createTestQueryClient();\n  const diContainer = new FeatureDIContainer();\n\n  const mockApi: Record<string, Mock> = {};\n\n  const methods = options.apiMethods ?? ['getAll', 'getById', 'create', 'update', 'delete'];\n\n  methods.forEach((method) => {\n    mockApi[method] = vi.fn();\n  });\n\n  // Setup default implementations\n  if (mockApi.getAll) {\n    mockApi.getAll.mockResolvedValue({\n      items: Array.isArray(options.initialData) ? options.initialData : [options.initialData],\n      total: Array.isArray(options.initialData) ? options.initialData.length : 1,\n      page: 1,\n      pageSize: 20,\n    });\n  }\n\n  if (mockApi.getById) {\n    mockApi.getById.mockImplementation(async (id: string) => {\n      const items = Array.isArray(options.initialData)\n        ? options.initialData\n        : [options.initialData];\n      const item = (items as Array<{ id: string }>).find((i) => i.id === id);\n      return Promise.resolve(item);\n    });\n  }\n\n  return {\n    featureId,\n    initialData: options.initialData,\n    mockApi,\n    queryClient,\n    diContainer,\n  };\n}\n\n/**\n * Seed query cache with initial data\n */\nexport function seedQueryCache<T>(\n  queryClient: QueryClient,\n  queryKey: readonly unknown[],\n  data: T\n): void {\n  queryClient.setQueryData(queryKey, data);\n}\n\n/**\n * Assert query cache contains expected data\n */\nexport function assertQueryCache<T>(\n  queryClient: QueryClient,\n  queryKey: readonly unknown[],\n  expectedData: T\n): void {\n  const cachedData = queryClient.getQueryData<T>(queryKey);\n  expect(cachedData).toEqual(expectedData);\n}\n\n/**\n * Clear specific query from cache\n */\nexport function clearQueryCache(queryClient: QueryClient, queryKey: readonly unknown[]): void {\n  queryClient.removeQueries({ queryKey });\n}\n\n/**\n * Wait for queries to settle\n */\nexport async function waitForQueries(queryClient: QueryClient): Promise<void> {\n  while (queryClient.isFetching()) {\n    await new Promise((resolve) => setTimeout(resolve, 50));\n  }\n}\n\n// ============================================================================\n// Snapshot Testing Helpers\n// ============================================================================\n\n/**\n * Create a serializable snapshot of feature state\n */\nexport function createFeatureSnapshot(\n  queryClient: QueryClient,\n  queryKeys: readonly (readonly unknown[])[]\n): Record<string, unknown> {\n  const snapshot: Record<string, unknown> = {};\n\n  queryKeys.forEach((key) => {\n    snapshot[JSON.stringify(key)] = queryClient.getQueryData(key);\n  });\n\n  return snapshot;\n}\n\n/**\n * Compare two feature snapshots\n */\nexport function compareSnapshots(\n  snapshot1: Record<string, unknown>,\n  snapshot2: Record<string, unknown>\n): {\n  added: string[];\n  removed: string[];\n  changed: string[];\n} {\n  const keys1 = new Set(Object.keys(snapshot1));\n  const keys2 = new Set(Object.keys(snapshot2));\n\n  const added = Array.from(keys2).filter((k) => !keys1.has(k));\n  const removed = Array.from(keys1).filter((k) => !keys2.has(k));\n  const changed = Array.from(keys1)\n    .filter((k) => keys2.has(k))\n    .filter((k) => JSON.stringify(snapshot1[k]) !== JSON.stringify(snapshot2[k]));\n\n  return { added, removed, changed };\n}\n\n// ============================================================================\n// Timing Utilities\n// ============================================================================\n\n/**\n * Wait for a condition to be true\n */\nexport async function waitFor(\n  condition: () => boolean | Promise<boolean>,\n  options: { timeout?: number; interval?: number } = {}\n): Promise<void> {\n  const { timeout = 5000, interval = 50 } = options;\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    if (await condition()) {\n      return;\n    }\n    await new Promise((resolve) => setTimeout(resolve, interval));\n  }\n\n  throw new Error(`waitFor timed out after ${timeout}ms`);\n}\n\n/**\n * Delay execution for testing async behavior\n */\nexport async function delay(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Test Data Generators\n// ============================================================================\n\n/**\n * Generate a random ID\n */\nexport function generateId(prefix = ''): string {\n  const random = Math.random().toString(36).substr(2, 9);\n  return prefix ? `${prefix}-${random}` : random;\n}\n\n/**\n * Generate a random date within a range\n */\nexport function generateDate(options: { min?: Date; max?: Date } = {}): string {\n  const min = options.min?.getTime() ?? Date.now() - 30 * 24 * 60 * 60 * 1000;\n  const max = options.max?.getTime() ?? Date.now();\n  const timestamp = min + Math.random() * (max - min);\n  return new Date(timestamp).toISOString();\n}\n\n/**\n * Generate test data with faker-like utilities\n */\nexport const testData = {\n  id: generateId,\n  date: generateDate,\n\n  string: (length = 10): string => {\n    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n    return Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join('');\n  },\n\n  number: (min = 0, max = 100): number => {\n    return Math.floor(Math.random() * (max - min + 1)) + min;\n  },\n\n  boolean: (): boolean => Math.random() > 0.5,\n\n  email: (): string => `test-${generateId()}@example.com`,\n\n  name: (): string => {\n    const firstNames = ['John', 'Jane', 'Bob', 'Alice', 'Charlie'];\n    const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones'];\n    return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${lastNames[Math.floor(Math.random() * lastNames.length)]}`;\n  },\n\n  pick: <T>(array: T[]): T => {\n    if (array.length === 0) {\n      throw new Error('Cannot pick from empty array');\n    }\n    const index = Math.floor(Math.random() * array.length);\n    const item = array[index];\n    if (item === undefined) {\n      throw new Error('Unexpected undefined value in array');\n    }\n    return item;\n  },\n\n  array: <T>(length: number, factory: (index: number) => T): T[] =>\n    Array.from({ length }, (_, i) => factory(i)),\n};\n"],"names":["createTestQueryClient","options","QueryClient","FeatureTestWrapper","children","queryClient","diContainer","FeatureDIContainer","React","QueryClientProvider","FeatureDIProvider","createFeatureRenderer","defaultOptions","ui","mergedOptions","createMockFeature","overrides","id","name","description","category","order","accessOverrides","configOverrides","mockConfig","MockComponent","createMockFeatures","count","baseOptions","_","index","createMockEntity","now","createMockEntities","factory","createMockApiResponse","data","createMockService","implementations","service","key","impl","typedKey","vi","createMockQueryData","isLoading","isError","isSuccess","createMockMutationResult","createFeatureTestFixture","featureId","mockApi","method","item","i","seedQueryCache","queryKey","assertQueryCache","expectedData","cachedData","expect","clearQueryCache","waitForQueries","resolve","createFeatureSnapshot","queryKeys","snapshot","compareSnapshots","snapshot1","snapshot2","keys1","keys2","added","k","removed","changed","waitFor","condition","timeout","interval","startTime","delay","ms","generateId","prefix","random","generateDate","min","max","timestamp","testData","length","chars","firstNames","lastNames","array"],"mappings":"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"}