mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 20:16:00 +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 query from 'api/dashboard/variables/query';
|
||||||
import { commaValuesParser } from 'lib/dashbaordVariables/customCommaValuesParser';
|
import { commaValuesParser } from 'lib/dashbaordVariables/customCommaValuesParser';
|
||||||
import sortValues from 'lib/dashbaordVariables/sortVariableValues';
|
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 React, { memo, useCallback, useEffect, useState } from 'react';
|
||||||
import { IDashboardVariable } from 'types/api/dashboard/getAll';
|
import { IDashboardVariable } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
@ -12,24 +12,16 @@ import { variablePropsToPayloadVariables } from '../utils';
|
|||||||
import { SelectItemStyle, VariableContainer, VariableName } from './styles';
|
import { SelectItemStyle, VariableContainer, VariableName } from './styles';
|
||||||
import { areArraysEqual } from './util';
|
import { areArraysEqual } from './util';
|
||||||
|
|
||||||
const { Option } = Select;
|
|
||||||
|
|
||||||
const ALL_SELECT_VALUE = '__ALL__';
|
const ALL_SELECT_VALUE = '__ALL__';
|
||||||
|
|
||||||
interface VariableItemProps {
|
interface VariableItemProps {
|
||||||
variableData: IDashboardVariable;
|
variableData: IDashboardVariable;
|
||||||
existingVariables: Record<string, IDashboardVariable>;
|
existingVariables: Record<string, IDashboardVariable>;
|
||||||
onValueUpdate: (
|
onValueUpdate: (
|
||||||
name: string | undefined,
|
name: string,
|
||||||
arg1:
|
arg1: IDashboardVariable['selectedValue'],
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| (string | number | boolean)[]
|
|
||||||
| null
|
|
||||||
| undefined,
|
|
||||||
) => void;
|
) => void;
|
||||||
onAllSelectedUpdate: (name: string | undefined, arg1: boolean) => void;
|
onAllSelectedUpdate: (name: string, arg1: boolean) => void;
|
||||||
lastUpdatedVar: string;
|
lastUpdatedVar: string;
|
||||||
}
|
}
|
||||||
function VariableItem({
|
function VariableItem({
|
||||||
@ -101,8 +93,10 @@ function VariableItem({
|
|||||||
} else {
|
} else {
|
||||||
[value] = newOptionsData;
|
[value] = newOptionsData;
|
||||||
}
|
}
|
||||||
onValueUpdate(variableData.name, value);
|
if (variableData.name) {
|
||||||
onAllSelectedUpdate(variableData.name, allSelected);
|
onValueUpdate(variableData.name, value);
|
||||||
|
onAllSelectedUpdate(variableData.name, allSelected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setOptionsData(newOptionsData);
|
setOptionsData(newOptionsData);
|
||||||
}
|
}
|
||||||
@ -133,17 +127,18 @@ function VariableItem({
|
|||||||
}, [variableData, existingVariables]);
|
}, [variableData, existingVariables]);
|
||||||
|
|
||||||
const handleChange = (value: string | string[]): void => {
|
const handleChange = (value: string | string[]): void => {
|
||||||
if (
|
if (variableData.name)
|
||||||
value === ALL_SELECT_VALUE ||
|
if (
|
||||||
(Array.isArray(value) && value.includes(ALL_SELECT_VALUE)) ||
|
value === ALL_SELECT_VALUE ||
|
||||||
(Array.isArray(value) && value.length === 0)
|
(Array.isArray(value) && value.includes(ALL_SELECT_VALUE)) ||
|
||||||
) {
|
(Array.isArray(value) && value.length === 0)
|
||||||
onValueUpdate(variableData.name, optionsData);
|
) {
|
||||||
onAllSelectedUpdate(variableData.name, true);
|
onValueUpdate(variableData.name, optionsData);
|
||||||
} else {
|
onAllSelectedUpdate(variableData.name, true);
|
||||||
onValueUpdate(variableData.name, value);
|
} else {
|
||||||
onAllSelectedUpdate(variableData.name, false);
|
onValueUpdate(variableData.name, value);
|
||||||
}
|
onAllSelectedUpdate(variableData.name, false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectValue = variableData.allSelected
|
const selectValue = variableData.allSelected
|
||||||
@ -182,10 +177,21 @@ function VariableItem({
|
|||||||
style={SelectItemStyle}
|
style={SelectItemStyle}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
showArrow
|
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) => (
|
{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>
|
</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