feat: added test cases for hooks and api call functions

This commit is contained in:
SagarRajput-7 2025-05-14 02:58:54 +05:30
parent dbbd7c24ac
commit 314059204a
3 changed files with 547 additions and 0 deletions

View File

@ -0,0 +1,114 @@
/* eslint-disable sonarjs/no-duplicate-string */
import { ApiBaseInstance } from 'api';
import { getFieldKeys } from '../getFieldKeys';
// Mock the API instance
jest.mock('api', () => ({
ApiBaseInstance: {
get: jest.fn(),
},
}));
describe('getFieldKeys API', () => {
beforeEach(() => {
jest.clearAllMocks();
});
const mockSuccessResponse = {
data: {
status: 'success',
data: {
keys: {
'service.name': [],
'http.status_code': [],
},
complete: true,
},
},
};
it('should call API with correct parameters when no args provided', async () => {
// Mock successful API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce(mockSuccessResponse);
// Call function with no parameters
await getFieldKeys();
// Verify API was called correctly with empty params object
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/keys', {
params: {},
});
});
it('should call API with signal parameter when provided', async () => {
// Mock successful API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce(mockSuccessResponse);
// Call function with signal parameter
await getFieldKeys('traces');
// Verify API was called with signal parameter
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/keys', {
params: { signal: 'traces' },
});
});
it('should call API with name parameter when provided', async () => {
// Mock successful API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
keys: { service: [] },
complete: false,
},
},
});
// Call function with name parameter
await getFieldKeys(undefined, 'service');
// Verify API was called with name parameter
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/keys', {
params: { name: 'service' },
});
});
it('should call API with both signal and name when provided', async () => {
// Mock successful API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
keys: { service: [] },
complete: false,
},
},
});
// Call function with both parameters
await getFieldKeys('logs', 'service');
// Verify API was called with both parameters
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/keys', {
params: { signal: 'logs', name: 'service' },
});
});
it('should return properly formatted response', async () => {
// Mock API to return our response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce(mockSuccessResponse);
// Call the function
const result = await getFieldKeys('traces');
// Verify the returned structure matches our expected format
expect(result).toEqual({
statusCode: 200,
error: null,
message: 'success',
payload: mockSuccessResponse.data.data,
});
});
});

View File

@ -0,0 +1,209 @@
/* eslint-disable sonarjs/no-duplicate-string */
import { ApiBaseInstance } from 'api';
import { getFieldValues } from '../getFieldValues';
// Mock the API instance
jest.mock('api', () => ({
ApiBaseInstance: {
get: jest.fn(),
},
}));
describe('getFieldValues API', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should call the API with correct parameters (no options)', async () => {
// Mock API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
},
complete: true,
},
},
});
// Call function without parameters
await getFieldValues();
// Verify API was called correctly with empty params
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/values', {
params: {},
});
});
it('should call the API with signal parameter', async () => {
// Mock API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
},
complete: true,
},
},
});
// Call function with signal parameter
await getFieldValues('traces');
// Verify API was called with signal parameter
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/values', {
params: { signal: 'traces' },
});
});
it('should call the API with name parameter', async () => {
// Mock API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
},
complete: true,
},
},
});
// Call function with name parameter
await getFieldValues(undefined, 'service.name');
// Verify API was called with name parameter
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/values', {
params: { name: 'service.name' },
});
});
it('should call the API with value parameter', async () => {
// Mock API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend'],
},
complete: false,
},
},
});
// Call function with value parameter
await getFieldValues(undefined, 'service.name', 'front');
// Verify API was called with value parameter
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/values', {
params: { name: 'service.name', value: 'front' },
});
});
it('should call the API with time range parameters', async () => {
// Mock API response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce({
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
},
complete: true,
},
},
});
// Call function with time range parameters
const startUnixMilli = 1625097600000000; // Note: nanoseconds
const endUnixMilli = 1625184000000000;
await getFieldValues(
'logs',
'service.name',
undefined,
startUnixMilli,
endUnixMilli,
);
// Verify API was called with time range parameters (converted to milliseconds)
expect(ApiBaseInstance.get).toHaveBeenCalledWith('/fields/values', {
params: {
signal: 'logs',
name: 'service.name',
startUnixMilli: '1625097600', // Should be converted to seconds (divided by 1000000)
endUnixMilli: '1625184000', // Should be converted to seconds (divided by 1000000)
},
});
});
it('should normalize the response values', async () => {
// Mock API response with multiple value types
const mockResponse = {
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
numberValues: [200, 404],
boolValues: [true, false],
},
complete: true,
},
},
};
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce(mockResponse);
// Call the function
const result = await getFieldValues('traces', 'mixed.values');
// Verify the response has normalized values array
expect(result.payload?.normalizedValues).toContain('frontend');
expect(result.payload?.normalizedValues).toContain('backend');
expect(result.payload?.normalizedValues).toContain('200');
expect(result.payload?.normalizedValues).toContain('404');
expect(result.payload?.normalizedValues).toContain('true');
expect(result.payload?.normalizedValues).toContain('false');
expect(result.payload?.normalizedValues?.length).toBe(6);
});
it('should return a properly formatted success response', async () => {
// Create mock response
const mockApiResponse = {
data: {
status: 'success',
data: {
values: {
stringValues: ['frontend', 'backend'],
},
complete: true,
},
},
};
// Mock API to return our response
(ApiBaseInstance.get as jest.Mock).mockResolvedValueOnce(mockApiResponse);
// Call the function
const result = await getFieldValues('traces', 'service.name');
// Verify the returned structure
expect(result).toEqual({
statusCode: 200,
error: null,
message: 'success',
payload: expect.objectContaining({
values: expect.any(Object),
normalizedValues: expect.any(Array),
complete: true,
}),
});
});
});

View File

@ -0,0 +1,224 @@
import { renderHook, waitFor } from '@testing-library/react';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { ReactNode } from 'react';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
import { useGetDynamicVariables } from '../useGetDynamicVariables';
// Mock the dependencies
jest.mock('react-query', () => ({
...jest.requireActual('react-query'),
useQuery: jest.fn(),
}));
jest.mock('providers/Dashboard/Dashboard', () => ({
useDashboard: jest.fn(),
}));
// Sample dashboard data with variables
const mockDashboardData = {
data: {
title: 'Test Dashboard',
variables: {
var1: {
id: 'var1',
name: 'service',
type: 'DYNAMIC',
dynamicVariablesAttribute: 'service.name',
dynamicVariablesSource: 'Traces',
selectedValue: 'frontend',
multiSelect: false,
showALLOption: false,
allSelected: false,
description: '',
sort: 'DISABLED',
},
var2: {
id: 'var2',
name: 'status',
type: 'DYNAMIC',
dynamicVariablesAttribute: 'http.status_code',
dynamicVariablesSource: 'Traces',
selectedValue: '200',
multiSelect: false,
showALLOption: false,
allSelected: false,
description: '',
sort: 'DISABLED',
},
var3: {
id: 'var3',
name: 'interval',
type: 'CUSTOM', // Not DYNAMIC - should be filtered out
customValue: '5m',
multiSelect: false,
showALLOption: false,
allSelected: false,
description: '',
sort: 'DISABLED',
},
},
},
uuid: 'dashboard-123',
loading: false,
error: null,
};
// Mock refetch function
const mockRefetch = jest.fn();
// Constants
const DASHBOARD_ID = 'dashboard-123';
// Create a wrapper for the renderHook function with the QueryClientProvider
const createWrapper = (): React.FC<{ children: ReactNode }> => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});
// Define as function declaration to fix linter error
function Wrapper({ children }: { children: ReactNode }): JSX.Element {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
return Wrapper;
};
describe('useGetDynamicVariables', () => {
beforeEach(() => {
jest.clearAllMocks();
// Mock the useDashboard hook
(useDashboard as jest.Mock).mockReturnValue({
dashboardId: DASHBOARD_ID,
});
// Mock the useQuery hook for successful response
(useQuery as jest.Mock).mockReturnValue({
data: mockDashboardData,
isLoading: false,
isError: false,
refetch: mockRefetch,
});
});
it('should return dynamic variables from the dashboard', async () => {
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
await waitFor(() => {
expect(result.current.dynamicVariables).toHaveLength(2); // Only DYNAMIC type variables
expect(result.current.dynamicVariables[0].name).toBe('service');
expect(result.current.dynamicVariables[1].name).toBe('status');
expect(result.current.isLoading).toBe(false);
expect(result.current.isError).toBe(false);
});
// Verify each dynamic variable has dashboard info
expect(result.current.dynamicVariables[0].dashboardName).toBe(
'Test Dashboard',
);
expect(result.current.dynamicVariables[0].dashboardId).toBe(DASHBOARD_ID);
});
it('should use dashboardId from props if provided', async () => {
const customDashboardId = 'custom-dashboard-id';
renderHook(() => useGetDynamicVariables({ dashboardId: customDashboardId }), {
wrapper: createWrapper(),
});
// Check that useQuery was called with the custom dashboardId
expect(useQuery).toHaveBeenCalledWith(
expect.objectContaining({
queryKey: expect.arrayContaining(['DASHBOARD_BY_ID', customDashboardId]),
}),
);
});
it('should return empty array when dashboard has no variables', async () => {
// Mock no variables in dashboard
(useQuery as jest.Mock).mockReturnValue({
data: {
data: { title: 'Empty Dashboard' },
uuid: 'dashboard-empty',
loading: false,
error: null,
},
isLoading: false,
isError: false,
refetch: mockRefetch,
});
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
expect(result.current.dynamicVariables).toHaveLength(0);
});
it('should return empty array when dashboard is null', async () => {
// Mock null dashboard data
(useQuery as jest.Mock).mockReturnValue({
data: null,
isLoading: false,
isError: false,
refetch: mockRefetch,
});
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
expect(result.current.dynamicVariables).toHaveLength(0);
});
it('should handle loading state', async () => {
// Mock loading state
(useQuery as jest.Mock).mockReturnValue({
data: null,
isLoading: true,
isError: false,
refetch: mockRefetch,
});
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
expect(result.current.isLoading).toBe(true);
expect(result.current.dynamicVariables).toHaveLength(0);
});
it('should handle error state', async () => {
// Mock error state
(useQuery as jest.Mock).mockReturnValue({
data: null,
isLoading: false,
isError: true,
refetch: mockRefetch,
});
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
expect(result.current.isError).toBe(true);
expect(result.current.dynamicVariables).toHaveLength(0);
});
it('should call refetch when returned function is called', async () => {
const { result } = renderHook(() => useGetDynamicVariables(), {
wrapper: createWrapper(),
});
result.current.refetch();
expect(mockRefetch).toHaveBeenCalledTimes(1);
});
});