mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-11 07:59:01 +08:00
test: dashboard variable is updated (#2640)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
parent
fe314a8ddd
commit
37ff9480e1
@ -0,0 +1,168 @@
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { IDashboardVariable } from 'types/api/dashboard/getAll';
|
||||
|
||||
import VariableItem from './VariableItem';
|
||||
|
||||
const mockVariableData: IDashboardVariable = {
|
||||
description: 'Test Variable',
|
||||
type: 'TEXTBOX',
|
||||
textboxValue: 'defaultValue',
|
||||
sort: 'DISABLED',
|
||||
multiSelect: false,
|
||||
showALLOption: false,
|
||||
name: 'testVariable',
|
||||
};
|
||||
|
||||
// New mock data for a custom variable
|
||||
const mockCustomVariableData: IDashboardVariable = {
|
||||
...mockVariableData,
|
||||
name: 'customVariable',
|
||||
type: 'CUSTOM',
|
||||
customValue: 'option1,option2,option3',
|
||||
};
|
||||
|
||||
const mockOnValueUpdate = jest.fn();
|
||||
const mockOnAllSelectedUpdate = jest.fn();
|
||||
|
||||
describe('VariableItem', () => {
|
||||
let useEffectSpy: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
useEffectSpy = jest.spyOn(React, 'useEffect');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
useEffectSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('renders component with default props', () => {
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={mockVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('$testVariable')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders Input when the variable type is TEXTBOX', () => {
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={mockVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByPlaceholderText('Enter value')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls onChange event handler when Input value changes', () => {
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={mockVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
const inputElement = screen.getByPlaceholderText('Enter value');
|
||||
fireEvent.change(inputElement, { target: { value: 'newValue' } });
|
||||
|
||||
expect(mockOnValueUpdate).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnValueUpdate).toHaveBeenCalledWith('testVariable', 'newValue');
|
||||
expect(mockOnAllSelectedUpdate).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnAllSelectedUpdate).toHaveBeenCalledWith('testVariable', false);
|
||||
});
|
||||
|
||||
test('renders a Select element when variable type is CUSTOM', () => {
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={mockCustomVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('$customVariable')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('variable-select')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders a Select element with all selected', async () => {
|
||||
const customVariableData = {
|
||||
...mockCustomVariableData,
|
||||
allSelected: true,
|
||||
};
|
||||
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={customVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByTitle('ALL')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls useEffect when the component mounts', () => {
|
||||
render(
|
||||
<VariableItem
|
||||
variableData={mockCustomVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(React.useEffect).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('calls useEffect only once when the component mounts', () => {
|
||||
// Render the component
|
||||
const { rerender } = render(
|
||||
<VariableItem
|
||||
variableData={mockCustomVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
// Create an updated version of the mock data
|
||||
const updatedMockCustomVariableData = {
|
||||
...mockCustomVariableData,
|
||||
selectedValue: 'option1',
|
||||
};
|
||||
|
||||
// Re-render the component with the updated data
|
||||
rerender(
|
||||
<VariableItem
|
||||
variableData={updatedMockCustomVariableData}
|
||||
existingVariables={{}}
|
||||
onValueUpdate={mockOnValueUpdate}
|
||||
onAllSelectedUpdate={mockOnAllSelectedUpdate}
|
||||
lastUpdatedVar=""
|
||||
/>,
|
||||
);
|
||||
|
||||
// Check if the useEffect is called with the correct arguments
|
||||
expect(useEffectSpy).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
});
|
@ -4,7 +4,7 @@ import { Input, Popover, Select, Typography } from 'antd';
|
||||
import query from 'api/dashboard/variables/query';
|
||||
import { commaValuesParser } from 'lib/dashbaordVariables/customCommaValuesParser';
|
||||
import sortValues from 'lib/dashbaordVariables/sortVariableValues';
|
||||
import { map } from 'lodash-es';
|
||||
import map from 'lodash-es/map';
|
||||
import React, { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { IDashboardVariable } from 'types/api/dashboard/getAll';
|
||||
|
||||
@ -12,24 +12,16 @@ import { variablePropsToPayloadVariables } from '../utils';
|
||||
import { SelectItemStyle, VariableContainer, VariableName } from './styles';
|
||||
import { areArraysEqual } from './util';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
const ALL_SELECT_VALUE = '__ALL__';
|
||||
|
||||
interface VariableItemProps {
|
||||
variableData: IDashboardVariable;
|
||||
existingVariables: Record<string, IDashboardVariable>;
|
||||
onValueUpdate: (
|
||||
name: string | undefined,
|
||||
arg1:
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| (string | number | boolean)[]
|
||||
| null
|
||||
| undefined,
|
||||
name: string,
|
||||
arg1: IDashboardVariable['selectedValue'],
|
||||
) => void;
|
||||
onAllSelectedUpdate: (name: string | undefined, arg1: boolean) => void;
|
||||
onAllSelectedUpdate: (name: string, arg1: boolean) => void;
|
||||
lastUpdatedVar: string;
|
||||
}
|
||||
function VariableItem({
|
||||
@ -101,8 +93,10 @@ function VariableItem({
|
||||
} else {
|
||||
[value] = newOptionsData;
|
||||
}
|
||||
onValueUpdate(variableData.name, value);
|
||||
onAllSelectedUpdate(variableData.name, allSelected);
|
||||
if (variableData.name) {
|
||||
onValueUpdate(variableData.name, value);
|
||||
onAllSelectedUpdate(variableData.name, allSelected);
|
||||
}
|
||||
}
|
||||
setOptionsData(newOptionsData);
|
||||
}
|
||||
@ -133,17 +127,18 @@ function VariableItem({
|
||||
}, [variableData, existingVariables]);
|
||||
|
||||
const handleChange = (value: string | string[]): void => {
|
||||
if (
|
||||
value === ALL_SELECT_VALUE ||
|
||||
(Array.isArray(value) && value.includes(ALL_SELECT_VALUE)) ||
|
||||
(Array.isArray(value) && value.length === 0)
|
||||
) {
|
||||
onValueUpdate(variableData.name, optionsData);
|
||||
onAllSelectedUpdate(variableData.name, true);
|
||||
} else {
|
||||
onValueUpdate(variableData.name, value);
|
||||
onAllSelectedUpdate(variableData.name, false);
|
||||
}
|
||||
if (variableData.name)
|
||||
if (
|
||||
value === ALL_SELECT_VALUE ||
|
||||
(Array.isArray(value) && value.includes(ALL_SELECT_VALUE)) ||
|
||||
(Array.isArray(value) && value.length === 0)
|
||||
) {
|
||||
onValueUpdate(variableData.name, optionsData);
|
||||
onAllSelectedUpdate(variableData.name, true);
|
||||
} else {
|
||||
onValueUpdate(variableData.name, value);
|
||||
onAllSelectedUpdate(variableData.name, false);
|
||||
}
|
||||
};
|
||||
|
||||
const selectValue = variableData.allSelected
|
||||
@ -182,10 +177,21 @@ function VariableItem({
|
||||
style={SelectItemStyle}
|
||||
loading={isLoading}
|
||||
showArrow
|
||||
data-testid="variable-select"
|
||||
>
|
||||
{enableSelectAll && <Option value={ALL_SELECT_VALUE}>ALL</Option>}
|
||||
{enableSelectAll && (
|
||||
<Select.Option data-testid="option-ALL" value={ALL_SELECT_VALUE}>
|
||||
ALL
|
||||
</Select.Option>
|
||||
)}
|
||||
{map(optionsData, (option) => (
|
||||
<Option value={option}>{option.toString()}</Option>
|
||||
<Select.Option
|
||||
data-testid={`option-${option}`}
|
||||
key={option.toString()}
|
||||
value={option}
|
||||
>
|
||||
{option.toString()}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
)
|
||||
|
@ -0,0 +1,33 @@
|
||||
import { areArraysEqual } from './util';
|
||||
|
||||
describe('areArraysEqual', () => {
|
||||
it('should return true for equal arrays with same order', () => {
|
||||
const array1 = [1, 'a', true, 5, 'hello'];
|
||||
const array2 = [1, 'a', true, 5, 'hello'];
|
||||
expect(areArraysEqual(array1, array2)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for equal arrays with different order', () => {
|
||||
const array1 = [1, 'a', true, 5, 'hello'];
|
||||
const array2 = ['hello', 1, true, 'a', 5];
|
||||
expect(areArraysEqual(array1, array2)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for arrays with different lengths', () => {
|
||||
const array1 = [1, 'a', true, 5, 'hello'];
|
||||
const array2 = [1, 'a', true, 5];
|
||||
expect(areArraysEqual(array1, array2)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for arrays with different elements', () => {
|
||||
const array1 = [1, 'a', true, 5, 'hello'];
|
||||
const array2 = [1, 'a', true, 5, 'world'];
|
||||
expect(areArraysEqual(array1, array2)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true for empty arrays', () => {
|
||||
const array1: string[] = [];
|
||||
const array2: string[] = [];
|
||||
expect(areArraysEqual(array1, array2)).toBe(true);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user