test: dashboard variable is updated (#2640)

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
Palash Gupta 2023-05-02 18:51:24 +05:30 committed by GitHub
parent fe314a8ddd
commit 37ff9480e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 234 additions and 27 deletions

View File

@ -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);
});
});

View File

@ -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>
)

View File

@ -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);
});
});