diff --git a/web/jest.setup.js b/web/jest.setup.js index a84e24f24..c752f45ba 100644 --- a/web/jest.setup.js +++ b/web/jest.setup.js @@ -48,3 +48,13 @@ jest.mock('next/navigation', () => ({ jest.mock('react-hotkeys-hook', () => ({ useHotkeys: jest.fn() })); + +jest.mock('react-markdown', () => ({ + __esModule: true, + default: jest.fn() +})); + +jest.mock('remark-gfm', () => ({ + __esModule: true, + default: jest.fn() +})); diff --git a/web/src/api/buster_rest/chats/requests.test.ts b/web/src/api/buster_rest/chats/requests.test.ts new file mode 100644 index 000000000..1b0626aad --- /dev/null +++ b/web/src/api/buster_rest/chats/requests.test.ts @@ -0,0 +1,54 @@ +import { mainApi } from '../instances'; +import { BusterChatListItem } from '@/api/asset_interfaces/chat/chatInterfaces'; + +// Mock the mainApi +jest.mock('../instances', () => ({ + mainApi: { + get: jest.fn() + } +})); + +describe('Chat API Requests', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getListChats', () => { + it('should fetch list of chats with default pagination parameters', async () => { + // Mock data + const mockChats: BusterChatListItem[] = [ + { + id: 'test-chat-1', + title: 'Test Chat 1', + created_at: '2024-03-20T00:00:00Z', + updated_at: '2024-03-20T00:00:00Z', + is_favorited: false, + created_by: 'test-user', + created_by_id: 'test-user-id', + created_by_name: 'Test User', + created_by_avatar: 'avatar-url', + last_edited: '2024-03-20T00:00:00Z', + latest_file_id: 'file-1', + latest_file_type: 'dashboard' + } + ]; + + // Setup mock response + (mainApi.get as jest.Mock).mockResolvedValueOnce({ data: mockChats }); + + // Import the function we want to test + const { getListChats } = await import('./requests'); + + // Execute the function + const result = await getListChats(); + + // Verify the API was called with correct parameters + expect(mainApi.get).toHaveBeenCalledWith('/chats', { + params: { page_token: 0, page_size: 3000 } + }); + + // Verify the result matches the mock data + expect(result).toEqual(mockChats); + }); + }); +}); diff --git a/web/src/api/buster_rest/dashboards/helpers/addMetricToDashboard.ts b/web/src/api/buster_rest/dashboards/helpers/addMetricToDashboard.ts index f46be2959..6a2576850 100644 --- a/web/src/api/buster_rest/dashboards/helpers/addMetricToDashboard.ts +++ b/web/src/api/buster_rest/dashboards/helpers/addMetricToDashboard.ts @@ -1,5 +1,5 @@ import type { BusterDashboard } from '@/api/asset_interfaces/dashboard'; -import { MAX_NUMBER_OF_ITEMS, NUMBER_OF_COLUMNS } from '@/components/ui/grid/helpers'; +import { MAX_NUMBER_OF_ITEMS, NUMBER_OF_COLUMNS } from '../../../../components/ui/grid/helpers'; import { v4 as uuidv4 } from 'uuid'; export const addMetricToDashboardConfig = ( diff --git a/web/src/api/buster_rest/dashboards/helpers/removeMetricFromDashboard.ts b/web/src/api/buster_rest/dashboards/helpers/removeMetricFromDashboard.ts index 4527dd8d5..9a516b0eb 100644 --- a/web/src/api/buster_rest/dashboards/helpers/removeMetricFromDashboard.ts +++ b/web/src/api/buster_rest/dashboards/helpers/removeMetricFromDashboard.ts @@ -1,5 +1,5 @@ import type { BusterDashboard } from '@/api/asset_interfaces/dashboard'; -import { NUMBER_OF_COLUMNS } from '@/components/ui/grid/helpers'; +import { NUMBER_OF_COLUMNS } from '../../../../components/ui/grid/helpers'; export const removeMetricFromDashboardConfig = ( metricIds: string[], diff --git a/web/src/api/buster_rest/metrics/getMetricQueryRequests.test.ts b/web/src/api/buster_rest/metrics/getMetricQueryRequests.test.ts new file mode 100644 index 000000000..7b1877351 --- /dev/null +++ b/web/src/api/buster_rest/metrics/getMetricQueryRequests.test.ts @@ -0,0 +1,44 @@ +import { QueryClient } from '@tanstack/react-query'; +import { prefetchGetMetricDataClient } from './getMetricQueryRequests'; +import { metricsQueryKeys } from '@/api/query_keys/metric'; +import { getMetricData } from './requests'; + +// Mock the requests module +jest.mock('./requests', () => ({ + getMetricData: jest.fn() +})); + +describe('prefetchGetMetricDataClient', () => { + let queryClient: QueryClient; + + beforeEach(() => { + queryClient = new QueryClient(); + jest.clearAllMocks(); + }); + + it('should prefetch metric data when no existing data is found', async () => { + // Setup + const mockId = 'test-metric-id'; + const mockVersionNumber = 1; + const mockMetricData = { id: mockId, data: 'test-data' }; + + // Mock the getMetricData function + (getMetricData as jest.Mock).mockResolvedValue(mockMetricData); + + // Execute + await prefetchGetMetricDataClient( + { id: mockId, version_number: mockVersionNumber }, + queryClient + ); + + // Get the query key + const queryKey = metricsQueryKeys.metricsGetData(mockId, mockVersionNumber).queryKey; + + // Verify + expect(getMetricData).toHaveBeenCalledWith({ + id: mockId, + version_number: mockVersionNumber + }); + expect(queryClient.getQueryData(queryKey)).toEqual(mockMetricData); + }); +}); diff --git a/web/src/api/query_keys/chat.test.ts b/web/src/api/query_keys/chat.test.ts new file mode 100644 index 000000000..a42eaf75e --- /dev/null +++ b/web/src/api/query_keys/chat.test.ts @@ -0,0 +1,14 @@ +import { chatQueryKeys } from './chat'; + +describe('chatQueryKeys', () => { + describe('chatsGetChat', () => { + it('should return correct query options configuration', () => { + const chatId = 'test-chat-123'; + const result = chatQueryKeys.chatsGetChat(chatId); + + expect(result.queryKey).toEqual(['chats', 'get', chatId]); + expect(result.enabled).toBe(true); + expect(result.staleTime).toBe(60 * 1000); // 1 minute in milliseconds + }); + }); +}); diff --git a/web/src/context/Metrics/useOriginalMetricStore.test.tsx b/web/src/context/Metrics/useOriginalMetricStore.test.tsx new file mode 100644 index 000000000..1733cb8a7 --- /dev/null +++ b/web/src/context/Metrics/useOriginalMetricStore.test.tsx @@ -0,0 +1,61 @@ +import { renderHook, act } from '@testing-library/react'; +import { useOriginalMetricStore } from './useOriginalMetricStore'; +import { VerificationStatus } from '@/api/asset_interfaces/share'; +import { ShareRole } from '@/api/asset_interfaces/share/shareInterfaces'; +import { DEFAULT_CHART_CONFIG } from '@/api/asset_interfaces/metric/defaults'; +import { IBusterMetric } from '@/api/asset_interfaces/metric'; + +describe('useOriginalMetricStore', () => { + beforeEach(() => { + // Clear the store before each test + useOriginalMetricStore.setState({ originalMetrics: {} }); + }); + + it('should correctly set and get a metric', () => { + const mockMetric: IBusterMetric = { + id: 'test-metric-1', + type: 'metric' as const, + name: 'Test Metric', + version_number: 1, + description: '', + time_frame: '', + sql: null, + dataset_id: 'test-dataset', + dataset_name: null, + error: null, + data_metadata: null, + status: VerificationStatus.NOT_REQUESTED, + evaluation_score: 'Moderate', + evaluation_summary: '', + file_name: 'test.yaml', + file: '', + data_source_id: 'test-source', + created_at: '2024-01-01T00:00:00Z', + updated_at: '2024-01-01T00:00:00Z', + sent_by_id: 'user-1', + sent_by_name: 'Test User', + permission: ShareRole.CAN_VIEW, + sent_by_avatar_url: null, + dashboards: [], + collections: [], + chart_config: DEFAULT_CHART_CONFIG, + individual_permissions: null, + public_expiry_date: null, + public_enabled_by: null, + publicly_accessible: false, + public_password: null, + versions: [] + }; + + // Use the hook + const { result } = renderHook(() => useOriginalMetricStore()); + + // Add a metric + act(() => { + result.current.setOriginalMetric(mockMetric); + }); + + // Verify the metric was added correctly + expect(result.current.getOriginalMetric('test-metric-1')).toEqual(mockMetric); + }); +});