Files
signoz/frontend/src/components/ErrorModal/ErrorModal.test.tsx
Aditya Singh bced4774bb feat: frontend unit test suite setup (#9027)
* feat: update context link modal form init

* feat: add double way sync on urls and param

* feat: minor refactor

* feat: minor refactor

* feat: change contextlinks data structure

* feat: context menu changes init

* feat: context menu hook refactor

* feat: context links processors

* feat: context variables hook added

* feat: add support for field variables

* feat: minor refactor

* feat: minor refactor

* feat: minor refactor

* feat: handle on save

* feat: minor refactor

* feat: snapshot update

* feat: revert qbv5

* feat: aggregation header val

* feat: fix header color

* feat: minor refactor

* feat: minor refactor

* feat: fix breaking changes from qb v5

* feat: change api for breakout opitons

* feat: minor refactor

* feat: minor refactor

* fix: added fix for extractquerypararms when value is string in multivalue operator

* feat: minor refactor

* feat: add back in breakout

* feat: minor refactor

* feat: add substitute var api call to decode vars

* feat: minor fix

* feat: optimize query value comparison in QueryBuilderV2

* feat: minor fix

* feat: minor fix

* feat: test fix

* feat: added dynamic variables creation flow (#7541)

* feat: added dynamic variables creation flow

* feat: added keys and value apis and hooks

* feat: added api and select component changes

* feat: added keys fetching and preview values

* feat: added dynamic variable to variable items

* feat: handled value persistence and tab switches

* feat: added default value and formed a schema for dyn-variables

* feat: added client and server side searches

* feat: corrected the initial load getfieldKey api

* feat: removed fetch on mount restriction

* feat: added dynamic variable to the dashboard details (#7755)

* feat: added dynamic variable to the dashboard details

* feat: added new component to existing variables

* feat: added enhancement to multiselect and select for dyn-variables

* feat: added refetch method between all dynamic-variables

* feat: correct error handling

* feat: correct error handling

* feat: enforced non-empty selectedvalues and default value

* feat: added client and server side searches

* feat: retry on error

* feat: correct error handling

* feat: handle defautl value in existing variables

* feat: lowercase the source for payload

* feat: fixed the incorrect assignment of active indices

* feat: improved handling of all option

* feat: improved the ALL option visuals

* feat: handled default value enforcement in existing variables

* feat: added unix time to values call

* feat: added incomplete data message and info to search

* feat: changed dashboard panel call handling with existing variables

* feat: adjusted the response type and data with the new API schema for values

* feat: code refactor

* feat: made dyn-variable option as the default

* feat: added test cases for dyn variable creation and completion

* feat: updated test cases

* feat: added variable in url and made dashboard sync around that and sharable (#7944)

* feat: added dynamic variable to the dashboard details

* feat: added new component to existing variables

* feat: added enhancement to multiselect and select for dyn-variables

* feat: added refetch method between all dynamic-variables

* feat: correct error handling

* feat: correct error handling

* feat: enforced non-empty selectedvalues and default value

* feat: added client and server side searches

* feat: retry on error

* feat: correct error handling

* feat: handle defautl value in existing variables

* feat: lowercase the source for payload

* feat: fixed the incorrect assignment of active indices

* feat: improved handling of all option

* feat: improved the ALL option visuals

* feat: handled default value enforcement in existing variables

* feat: added unix time to values call

* feat: added incomplete data message and info to search

* feat: changed dashboard panel call handling with existing variables

* feat: adjusted the response type and data with the new API schema for values

* feat: code refactor

* feat: made dyn-variable option as the default

* feat: added test cases for dyn variable creation and completion

* feat: updated test cases

* feat: added variable in url and made dashboard sync around that and sharable

* feat: added test cases

* feat: added safety check

* feat: enabled url setting on first load itself

* feat: code refactor

* feat: cleared options query param when on dashboard list page

* feat: resolved conflicts

* feat: added dynamic variable suggestion in where clause

* feat: added test cases for hooks and api call functions

* feat: added test case for querybuildersearchv2 suggestion changes

* feat: code refactor

* feat: updated test case

* feat: corrected the regex matcher for resolved titles

* feat: added ability to add/remove variable filter to one or more existing panels

* feat: added widgetselector on variable creation

* feat: show labels in widget selector

* feat: added apply to all and variable removal logical

* feat: refectch only related and affected panels in case of dynamic variables

* feat: added button loader for apply-all

* feat: light-mode styles

* feat: minor refactor

* feat: added test cases

* feat: refactor

* feat: remove consoles

* feat: pass panel types to substitutevars

* feat: cross filtering init

* fix: added fix for query builder filters

* feat: cross filtering add set/unset/create functionality

* feat: test update

* fix: added migration to filter expression for crud operations of variable

* feat: format legend name according to existing format

* feat: breakout test init

* feat: breakout test match query

* feat: context links tests

* feat: minor refactor

* feat: show edit only if user has access

* feat: added dynamic variables creation flow (#7541)

* feat: added dynamic variables creation flow

* feat: added keys and value apis and hooks

* feat: added api and select component changes

* feat: added keys fetching and preview values

* feat: added dynamic variable to variable items

* feat: handled value persistence and tab switches

* feat: added default value and formed a schema for dyn-variables

* feat: added client and server side searches

* feat: corrected the initial load getfieldKey api

* feat: removed fetch on mount restriction

* feat: added dynamic variable to the dashboard details (#7755)

* feat: added dynamic variable to the dashboard details

* feat: added new component to existing variables

* feat: added enhancement to multiselect and select for dyn-variables

* feat: added refetch method between all dynamic-variables

* feat: correct error handling

* feat: correct error handling

* feat: enforced non-empty selectedvalues and default value

* feat: added client and server side searches

* feat: retry on error

* feat: correct error handling

* feat: handle defautl value in existing variables

* feat: lowercase the source for payload

* feat: fixed the incorrect assignment of active indices

* feat: improved handling of all option

* feat: improved the ALL option visuals

* feat: handled default value enforcement in existing variables

* feat: added unix time to values call

* feat: added incomplete data message and info to search

* feat: changed dashboard panel call handling with existing variables

* feat: adjusted the response type and data with the new API schema for values

* feat: code refactor

* feat: made dyn-variable option as the default

* feat: added test cases for dyn variable creation and completion

* feat: updated test cases

* feat: added dynamic variable suggestion in where clause

* feat: added test cases for hooks and api call functions

* feat: added test case for querybuildersearchv2 suggestion changes

* feat: code refactor

* feat: updated test case

* feat: corrected the regex matcher for resolved titles

* feat: added ability to add/remove variable filter to one or more existing panels

* feat: added widgetselector on variable creation

* feat: show labels in widget selector

* feat: added apply to all and variable removal logical

* feat: refectch only related and affected panels in case of dynamic variables

* feat: added button loader for apply-all

* feat: light-mode styles

* fix: added migration to filter expression for crud operations of variable

* feat: reverted dynamic variable url config changes (#8877)

* Revert "feat: changed query param name"

This reverts commit 62bee5f003.

* Revert "feat: added user-friendly format to dashboard variable url"

This reverts commit 6de8b1c2e8.

* feat: reverted url var changes

* feat: reverted url changed from usedashboardvarupdate hook

* feat: send empty array for widgetId

* feat: added type in the variables in query_range payload for dynamic

* feat: minor fixes

* fix: added fix for multivalue operator without brackets

* feat: minor fix

* feat: fix failing test

* feat: change revert

* test: added tests for querycontextUtils + querybuilderv2 utils

* fix: added fix for replacing filter with the new value

* fix: added fix for replacing filters + datetimepicker composite query

* test: fixed querybuilderv2 utils test

* feat: handle number dataType in filters

* feat: correct the variable addition to panel format for new qb expression

* feat: remove other queries in breakout

* feat: add metric to traces mapping

* feat: pass proper time range

* feat: update time range logic

* feat: value panel drilldown init

* feat: value panel drilldown init

* feat: enable context links in value panel

* feat: minor fix

* feat: update snapshot

* feat: hide breakout in value panel

* feat: add panel type to view mode

* feat: add support to change panel in breakouts

* feat: panel change for breakout logic added

* chore: fix style

* chore: show variables suggestion while creating context links

* chore: add timestamp to graphs

* chore: add timestamp to table panel

* chore: fix failing tests

* chore: fix infinite re-rendering due to queryRange

* chore: send appropriate time range when signal is metrics

* chore: show variables suggestion while creating context links

* chore: minor refactor

* chore: show trace details link if filter has trace_id

* chore: fix infinite render of table component

* chore: added tests for v2

* fix: context links set from dropdown

* chore: minor refactor

* chore: minor refactor

* chore: fix test

* chore: fix timerange for apm metrics

* fix: get correct timestamp for clicked data

* chore: comment out change to histogram on breakout by number

* chore: change panel type on panel type change in url

* chore: remove consoles

* feat: added dynamic variables creation flow (#7541)

* feat: added dynamic variables creation flow

* feat: added keys and value apis and hooks

* feat: added api and select component changes

* feat: added keys fetching and preview values

* feat: added dynamic variable to variable items

* feat: handled value persistence and tab switches

* feat: added default value and formed a schema for dyn-variables

* feat: added client and server side searches

* feat: corrected the initial load getfieldKey api

* feat: removed fetch on mount restriction

* feat: added dynamic variable to the dashboard details (#7755)

* feat: added dynamic variable to the dashboard details

* feat: added new component to existing variables

* feat: added enhancement to multiselect and select for dyn-variables

* feat: added refetch method between all dynamic-variables

* feat: correct error handling

* feat: correct error handling

* feat: enforced non-empty selectedvalues and default value

* feat: added client and server side searches

* feat: retry on error

* feat: correct error handling

* feat: handle defautl value in existing variables

* feat: lowercase the source for payload

* feat: fixed the incorrect assignment of active indices

* feat: improved handling of all option

* feat: improved the ALL option visuals

* feat: handled default value enforcement in existing variables

* feat: added unix time to values call

* feat: added incomplete data message and info to search

* feat: changed dashboard panel call handling with existing variables

* feat: adjusted the response type and data with the new API schema for values

* feat: code refactor

* feat: made dyn-variable option as the default

* feat: added test cases for dyn variable creation and completion

* feat: updated test cases

* feat: fix lint and test cases

* feat: fix typo

* feat: fixed test case

* feat: added dynamic variable suggestion in where clause

* feat: added test cases for hooks and api call functions

* feat: added test case for querybuildersearchv2 suggestion changes

* feat: code refactor

* feat: corrected the regex matcher for resolved titles

* feat: fixed test cases

* feat: added ability to add/remove variable filter to one or more existing panels

* feat: added widgetselector on variable creation

* feat: show labels in widget selector

* feat: added apply to all and variable removal logical

* feat: refectch only related and affected panels in case of dynamic variables

* feat: added button loader for apply-all

* feat: light-mode styles

* fix: added migration to filter expression for crud operations of variable

* feat: added type in the variables in query_range payload for dynamic

* feat: correct the variable addition to panel format for new qb expression

* feat: added test cases for dynamic variable and add/remove panel feat

* feat: implemented where clause suggestion in new qb v5

* feat: added retries for dyn variable and fixed on-enter selection issue

* feat: added relatedValues and existing query in param related changes

* feat: sanitized data storage and removed duplicates

* fix: fixed typechecks

* feat: updated panel wait and refetch logic and ALL option selection

* feat: fixed variable tabel reordering issue

* feat: added empty name validation in variable creation

* feat: change value to searchtext in values API

* feat: added option for regex in the component, disabled for now

* feat: added beta and not rec. tag in variable tabs

* feat: added check to prevent api and updates calls with same payload

* feat: optimized localstorage for all selection in dynamic variable and updated __all__ case

* feat: resolved variable tables infinite loop update error

* feat: aded variable name auto-update based on attribute name entered for dynamic variables

* feat: modified only/all click behaviour and set all selection always true for dynamic variable

* feat: fix dropdown closing doesn't reset us back to our all available values when we have a search

* feat: handled all state distinction and carry forward in existing variables

* feat: trucate + n more tooltip content to 10

* feat: fixed infinite loop because of dependency of frequently changing object ref in var table

* feat: fixed inconsist search implementations

* feat: reverted only - all updated area implementation

* feat: added more space for search in multiselect component

* feat: checked for variable id instead of variable key for refetch

* feat: improved performance around multiselect component and added confirm modal for apply to all

* feat: rewrite functionality around add and remove panels

* feat: changed color for apply to all modal

* feat: added changes under flag to handle variable specific removal for removeKeysFromExpression func

* feat: added validation in variable edit panel

* chore: fix dynamic variable update in context menu to latest logic

* chore: minor fix

* chore: type fix

* fix: remove unwanted code

* fix: remove unwanted code

* fix: resolved pr comments

* fix: minor fix

* fix: fix tests

* fix: style fix

* fix: hide drilldown options in view mode for non-builder panels

* chore: add global uplot mock

* chore: query builder context update to all provider

* chore: add cursor rules init

* chore: useSafeNavigate mock added

* chore: more cleanups

* chore: remove react-router-v5 mock from setup

* chore: update cursorrules

* chore: add tests readme init

* chore: minor refactor

---------

Co-authored-by: Aditya Singh <adityasingh@Adityas-MacBook-Pro.local>
Co-authored-by: Abhi Kumar <ahrefabhi@gmail.com>
Co-authored-by: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com>
Co-authored-by: SagarRajput-7 <sagar@signoz.io>
2025-09-18 12:19:57 +05:30

191 lines
6.2 KiB
TypeScript

import { render, screen, userEvent, waitFor } from 'tests/test-utils';
import APIError from 'types/api/error';
import ErrorModal from './ErrorModal';
// Mock the query client to return version data
const mockVersionData = {
payload: {
ee: 'Y',
version: '1.0.0',
},
};
jest.mock('react-query', () => ({
...jest.requireActual('react-query'),
useQueryClient: (): { getQueryData: () => typeof mockVersionData } => ({
getQueryData: jest.fn(() => mockVersionData),
}),
}));
const mockError: APIError = new APIError({
httpStatusCode: 400,
error: {
// eslint-disable-next-line sonarjs/no-duplicate-string
message: 'Something went wrong while processing your request.',
// eslint-disable-next-line sonarjs/no-duplicate-string
code: 'An error occurred',
// eslint-disable-next-line sonarjs/no-duplicate-string
url: 'https://example.com/docs',
errors: [
{ message: 'First error detail' },
{ message: 'Second error detail' },
{ message: 'Third error detail' },
],
},
});
describe('ErrorModal Component', () => {
it('should render the modal when open is true', () => {
render(<ErrorModal error={mockError} open onClose={jest.fn()} />);
// Check if the error message is displayed
expect(screen.getByText('An error occurred')).toBeInTheDocument();
expect(
screen.getByText('Something went wrong while processing your request.'),
).toBeInTheDocument();
});
it('should not render the modal when open is false', () => {
render(<ErrorModal error={mockError} open={false} onClose={jest.fn()} />);
// Check that the modal content is not in the document
expect(screen.queryByText('An error occurred')).not.toBeInTheDocument();
});
it('should call onClose when the close button is clicked', async () => {
const onCloseMock = jest.fn();
render(<ErrorModal error={mockError} open onClose={onCloseMock} />);
// Click the close button
const closeButton = screen.getByTestId('close-button');
const user = userEvent.setup({ pointerEventsCheck: 0 });
await user.click(closeButton);
// Check if onClose was called
expect(onCloseMock).toHaveBeenCalledTimes(1);
});
it('should display version data if available', async () => {
render(<ErrorModal error={mockError} open onClose={jest.fn()} />);
// Check if the version data is displayed
expect(screen.getByText('ENTERPRISE')).toBeInTheDocument();
expect(screen.getByText('1.0.0')).toBeInTheDocument();
});
it('should render the messages count badge when there are multiple errors', () => {
render(<ErrorModal error={mockError} open onClose={jest.fn()} />);
// Check if the messages count badge is displayed
expect(screen.getByText('MESSAGES')).toBeInTheDocument();
expect(screen.getByText('3')).toBeInTheDocument();
// Check if the individual error messages are displayed
expect(screen.getByText('First error detail')).toBeInTheDocument();
expect(screen.getByText('Second error detail')).toBeInTheDocument();
expect(screen.getByText('Third error detail')).toBeInTheDocument();
});
it('should render the open docs button when URL is provided', async () => {
render(<ErrorModal error={mockError} open onClose={jest.fn()} />);
// Check if the open docs button is displayed
const openDocsButton = screen.getByTestId('error-docs-button');
expect(openDocsButton).toBeInTheDocument();
expect(openDocsButton).toHaveAttribute('href', 'https://example.com/docs');
expect(openDocsButton).toHaveAttribute('target', '_blank');
});
it('should not display scroll for more if there are less than 10 messages', () => {
render(<ErrorModal error={mockError} open onClose={jest.fn()} />);
expect(screen.queryByText('Scroll for more')).not.toBeInTheDocument();
});
it('should display scroll for more if there are more than 10 messages', async () => {
const longError = new APIError({
httpStatusCode: 400,
error: {
...mockError.error,
code: 'An error occurred',
message: 'Something went wrong while processing your request.',
url: 'https://example.com/docs',
errors: Array.from({ length: 15 }, (_, i) => ({
message: `Error detail ${i + 1}`,
})),
},
});
render(<ErrorModal error={longError} open onClose={jest.fn()} />);
// Check if the scroll hint is displayed
expect(screen.getByText('Scroll for more')).toBeInTheDocument();
});
});
it('should render the trigger component if provided', () => {
const mockTrigger = <button type="button">Open Error Modal</button>;
render(
<ErrorModal
error={mockError}
triggerComponent={mockTrigger}
onClose={jest.fn()}
/>,
);
// Check if the trigger component is rendered
expect(screen.getByText('Open Error Modal')).toBeInTheDocument();
});
it('should open the modal when the trigger component is clicked', async () => {
const mockTrigger = <button type="button">Open Error Modal</button>;
render(
<ErrorModal
error={mockError}
triggerComponent={mockTrigger}
onClose={jest.fn()}
/>,
);
// Click the trigger component
const triggerButton = screen.getByText('Open Error Modal');
const user = userEvent.setup({ pointerEventsCheck: 0 });
await user.click(triggerButton);
// Check if the modal is displayed
expect(screen.getByText('An error occurred')).toBeInTheDocument();
});
it('should render the default trigger tag if no trigger component is provided', () => {
render(<ErrorModal error={mockError} onClose={jest.fn()} />);
// Check if the default trigger tag is rendered
expect(screen.getByText('error')).toBeInTheDocument();
});
it('should close the modal when the onCancel event is triggered', async () => {
const onCloseMock = jest.fn();
render(<ErrorModal error={mockError} onClose={onCloseMock} />);
// Click the trigger component
const triggerButton = screen.getByText('error');
const user = userEvent.setup({ pointerEventsCheck: 0 });
await user.click(triggerButton);
await waitFor(() => {
expect(screen.getByText('An error occurred')).toBeInTheDocument();
});
// Trigger the onCancel event
await user.click(screen.getByTestId('close-button'));
// Check if the modal is closed
expect(onCloseMock).toHaveBeenCalledTimes(1);
await waitFor(() => {
// check if the modal is not visible
const modal = document.getElementsByClassName('ant-modal');
const style = window.getComputedStyle(modal[0]);
expect(style.display).toBe('none');
});
});