mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-29 16:14:42 +00:00
feat: added test cases for hooks and api call functions
This commit is contained in:
parent
dbbd7c24ac
commit
314059204a
114
frontend/src/api/dynamicVariables/__tests__/getFieldKeys.test.ts
Normal file
114
frontend/src/api/dynamicVariables/__tests__/getFieldKeys.test.ts
Normal 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,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -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,
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user