UNPKG

@dbs-portal/core-api

Version:

HTTP client and API utilities for DBS Portal

279 lines 9.17 kB
/** * MSW integration with TanStack Query */ import { createQueryClient as originalCreateQueryClient } from '../../query/query-client'; import { setupMocks, isMswSetup } from '../setup'; import { getMockConfig } from '../config'; /** * Create query client with MSW integration */ export async function createMockAwareQueryClient(config = {}) { // Initialize MSW if configured if (config.autoSetupMocks && config.mocking?.enabled) { await setupMocks({ config: config.mocking, handlers: config.mockHandlers || [], start: true, }); } // Create query client with mock-aware defaults const queryClientConfig = { ...config, defaultOptions: { ...config.defaultOptions, queries: { ...config.defaultOptions?.queries, // Adjust retry behavior for mocked responses retry: config.mocking?.enabled ? 1 : (config.defaultOptions?.queries?.retry ?? 3), // Reduce stale time for development with mocks staleTime: config.mocking?.enabled && config.mocking.mode === 'development' ? 0 : (config.defaultOptions?.queries?.staleTime ?? 5 * 60 * 1000), }, mutations: { ...config.defaultOptions?.mutations, // Reduce retry for mutations with mocks retry: config.mocking?.enabled ? 0 : (config.defaultOptions?.mutations?.retry ?? 0), }, }, }; return originalCreateQueryClient(queryClientConfig); } /** * Query client wrapper with MSW utilities */ export class MockAwareQueryClient { queryClient; mockConfig; constructor(queryClient, mockConfig) { this.queryClient = queryClient; this.mockConfig = mockConfig || {}; } /** * Get the underlying query client */ getClient() { return this.queryClient; } /** * Check if mocking is enabled */ isMocking() { return this.mockConfig?.enabled ?? false; } /** * Invalidate queries (useful after adding/removing mock handlers) */ async invalidateAll() { await this.queryClient.invalidateQueries(); } /** * Clear all queries (useful when switching between mock/real APIs) */ clear() { this.queryClient.clear(); } /** * Reset queries to initial state */ async resetQueries() { await this.queryClient.resetQueries(); } /** * Refetch all queries (useful after mock data changes) */ async refetchAll() { await this.queryClient.refetchQueries(); } } /** * Testing utilities for MSW + React Query */ export const mockQueryUtils = { /** * Create a query client optimized for testing */ createTestQueryClient(mockHandlers = []) { return createMockAwareQueryClient({ mocking: { enabled: true, mode: 'testing', logging: false, delay: 0, // No delay in tests }, mockHandlers, autoSetupMocks: true, defaultOptions: { queries: { retry: false, staleTime: 0, gcTime: 0, }, mutations: { retry: false, }, }, }); }, /** * Create a query client for Storybook */ createStorybookQueryClient(mockHandlers = []) { return createMockAwareQueryClient({ mocking: { enabled: true, mode: 'storybook', logging: true, delay: [100, 300], }, mockHandlers, autoSetupMocks: true, defaultOptions: { queries: { retry: 1, staleTime: 5 * 60 * 1000, }, mutations: { retry: 0, }, }, }); }, /** * Wait for queries to settle (useful in tests) */ async waitForQueries(queryClient, timeout = 5000) { const start = Date.now(); while (Date.now() - start < timeout) { const queries = queryClient.getQueryCache().getAll(); const isSettled = queries.every(query => query.state.status === 'success' || query.state.status === 'error' || query.state.status === 'pending'); if (isSettled) { return; } await new Promise(resolve => setTimeout(resolve, 10)); } throw new Error(`Queries did not settle within ${timeout}ms`); }, /** * Mock query data directly in cache */ setQueryData(queryClient, queryKey, data) { queryClient.setQueryData(queryKey, data); }, /** * Get query data from cache */ getQueryData(queryClient, queryKey) { return queryClient.getQueryData(queryKey); }, }; /** * Hook utilities for MSW + React Query integration */ export const mockHookUtils = { /** * Create mock-aware query options */ createMockQueryOptions(queryKey, mockData, options = {}) { const mockConfig = getMockConfig(); return { queryKey, queryFn: async () => { // If mocking is enabled, return mock data if (mockConfig.enabled) { // Simulate network delay if configured if (mockConfig.delay) { const delay = Array.isArray(mockConfig.delay) ? Math.floor(Math.random() * (mockConfig.delay[1] - mockConfig.delay[0] + 1)) + mockConfig.delay[0] : mockConfig.delay; await new Promise(resolve => setTimeout(resolve, delay)); } return mockData; } // This should not be reached if MSW is properly set up throw new Error('Mock data requested but MSW is not enabled'); }, enabled: options.enabled ?? true, staleTime: options.staleTime ?? (mockConfig.enabled ? 0 : 5 * 60 * 1000), gcTime: options.gcTime ?? (mockConfig.enabled ? 0 : 5 * 60 * 1000), }; }, /** * Create mock-aware mutation options */ createMockMutationOptions(mockMutationFn, options = {}) { const mockConfig = getMockConfig(); return { mutationFn: async (variables) => { // If mocking is enabled, use mock function if (mockConfig.enabled) { // Simulate network delay if configured if (mockConfig.delay) { const delay = Array.isArray(mockConfig.delay) ? Math.floor(Math.random() * (mockConfig.delay[1] - mockConfig.delay[0] + 1)) + mockConfig.delay[0] : mockConfig.delay; await new Promise(resolve => setTimeout(resolve, delay)); } return await Promise.resolve(mockMutationFn(variables)); } // This should not be reached if MSW is properly set up throw new Error('Mock mutation requested but MSW is not enabled'); }, onSuccess: options.onSuccess, onError: options.onError, retry: mockConfig.enabled ? 0 : 3, }; }, }; /** * Development utilities for MSW + React Query */ export const mockDevUtils = { /** * Log query cache state (useful for debugging) */ logQueryCache(queryClient) { const queries = queryClient.getQueryCache().getAll(); console.group('Query Cache State'); queries.forEach(query => { console.log({ queryKey: query.queryKey, status: query.state.status, data: query.state.data, error: query.state.error, lastUpdated: query.state.dataUpdatedAt, }); }); console.groupEnd(); }, /** * Log mutation cache state */ logMutationCache(queryClient) { const mutations = queryClient.getMutationCache().getAll(); console.group('Mutation Cache State'); mutations.forEach(mutation => { console.log({ mutationKey: mutation.options.mutationKey, status: mutation.state.status, data: mutation.state.data, error: mutation.state.error, variables: mutation.state.variables, }); }); console.groupEnd(); }, /** * Check if MSW is properly set up for queries */ checkMswSetup() { return { isMswSetup: isMswSetup(), isMockingEnabled: getMockConfig().enabled, mockConfig: getMockConfig(), }; }, }; //# sourceMappingURL=query-integration.js.map