From 03ddcdd20ed68365c003f58169e98c9c5e914b19 Mon Sep 17 00:00:00 2001 From: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com> Date: Wed, 1 May 2024 18:49:04 +0530 Subject: [PATCH] feat: added test cases for pipeline pages (#4872) * feat: added test cases for pipeline pages * feat: added test cases for changeHistory * chore: change history table test case added * chore: added create pipeline button test cases * chore: updated useAnalytics mocking --- .../tests/ChangeHistory.test.tsx | 87 +++++++ .../Layouts/ChangeHistory/tests/testUtils.ts | 240 ++++++++++++++++++ .../tests/CreatePipelineButton.test.tsx | 66 ++++- .../tests/PipelinesSearchSection.test.tsx | 42 ++- 4 files changed, 433 insertions(+), 2 deletions(-) create mode 100644 frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/ChangeHistory.test.tsx create mode 100644 frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/testUtils.ts diff --git a/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/ChangeHistory.test.tsx b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/ChangeHistory.test.tsx new file mode 100644 index 0000000000..194acbea0a --- /dev/null +++ b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/ChangeHistory.test.tsx @@ -0,0 +1,87 @@ +import { render } from '@testing-library/react'; +import { I18nextProvider } from 'react-i18next'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { Provider } from 'react-redux'; +import { MemoryRouter } from 'react-router-dom'; +import i18n from 'ReactI18'; +import store from 'store'; + +import ChangeHistory from '../index'; +import { pipelineData, pipelineDataHistory } from './testUtils'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + }, + }, +}); + +describe('ChangeHistory test', () => { + it('should render changeHistory correctly', () => { + const { getAllByText, getByText } = render( + + + + + + + + + , + ); + + // change History table headers + [ + 'Version', + 'Deployment Stage', + 'Last Deploy Message', + 'Last Deployed Time', + 'Edited by', + ].forEach((text) => expect(getByText(text)).toBeInTheDocument()); + + // table content + expect(getAllByText('test-user').length).toBe(2); + expect(getAllByText('Deployment was successful').length).toBe(2); + }); + + it('test deployment stage and icon based on history data', () => { + const { getByText, container } = render( + + + + + + + + + , + ); + + // assertion for different deployment stages + expect(container.querySelector('[data-icon="loading"]')).toBeInTheDocument(); + expect(getByText('In Progress')).toBeInTheDocument(); + + expect( + container.querySelector('[data-icon="exclamation-circle"]'), + ).toBeInTheDocument(); + expect(getByText('Dirty')).toBeInTheDocument(); + + expect( + container.querySelector('[data-icon="close-circle"]'), + ).toBeInTheDocument(); + expect(getByText('Failed')).toBeInTheDocument(); + + expect( + container.querySelector('[data-icon="minus-circle"]'), + ).toBeInTheDocument(); + expect(getByText('Unknown')).toBeInTheDocument(); + + expect(container.querySelectorAll('.ant-table-row').length).toBe(5); + }); +}); diff --git a/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/testUtils.ts b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/testUtils.ts new file mode 100644 index 0000000000..900cb4f12d --- /dev/null +++ b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/tests/testUtils.ts @@ -0,0 +1,240 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { Pipeline } from 'types/api/pipeline/def'; +import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; + +export const pipelineData: Pipeline = { + id: 'test-id-1', + version: 24, + elementType: 'log_pipelines', + active: false, + is_valid: false, + disabled: false, + deployStatus: 'DEPLOYED', + deployResult: 'Deployment was successful', + lastHash: 'log_pipelines:24', + lastConf: 'oiwernveroi', + createdBy: 'test-created-by', + pipelines: [ + { + id: 'test-id-2', + orderId: 1, + name: 'hotrod logs parser', + alias: 'hotrodlogsparser', + description: 'Trying to test Logs Pipeline feature', + enabled: true, + filter: { + op: 'AND', + items: [ + { + key: { + key: 'container_name', + dataType: DataTypes.String, + type: 'tag', + isColumn: false, + isJSON: false, + }, + id: 'sampleid', + value: 'hotrod', + op: '=', + }, + ], + }, + config: [ + { + type: 'regex_parser', + id: 'parsetext(regex)', + output: 'parseattribsjson', + on_error: 'send', + orderId: 1, + enabled: true, + name: 'parse text (regex)', + parse_to: 'attributes', + regex: + '.+\\t+(?P.+)\\t+(?P.+)\\t+(?P.+)\\t+(?P.+)', + parse_from: 'body', + }, + { + type: 'json_parser', + id: 'parseattribsjson', + output: 'removetempattribs_json', + orderId: 2, + enabled: true, + name: 'parse attribs json', + parse_to: 'attributes', + parse_from: 'attributes.attribs_json', + }, + { + type: 'remove', + id: 'removetempattribs_json', + output: 'c2062723-895e-4614-ba38-29c5d5ee5927', + orderId: 3, + enabled: true, + name: 'remove temp attribs_json', + field: 'attributes.attribs_json', + }, + { + type: 'add', + id: 'c2062723-895e-4614-ba38-29c5d5ee5927', + orderId: 4, + enabled: true, + name: 'test add ', + field: 'resource["container.name"]', + value: 'hotrod', + }, + ], + createdBy: 'test@email', + createdAt: '2024-01-02T13:56:02.858300964Z', + }, + { + id: 'tes-id-1', + orderId: 2, + name: 'Logs Parser - test - Customer Service', + alias: 'LogsParser-test-CustomerService', + description: 'Trying to test Logs Pipeline feature', + enabled: true, + filter: { + op: 'AND', + items: [ + { + key: { + key: 'service', + dataType: DataTypes.String, + type: 'tag', + isColumn: false, + isJSON: false, + }, + id: 'sample-test-1', + value: 'customer', + op: '=', + }, + ], + }, + config: [ + { + type: 'grok_parser', + id: 'Testtest', + on_error: 'send', + orderId: 1, + enabled: true, + name: 'Test test', + parse_to: 'attributes', + pattern: + '^%{DATE:date}Z INFO customer/database.go:73 Loading customer {"service": "customer", "component": "mysql", "trace_id": "test-id", "span_id": "1427a3fcad8b1514", "customer_id": "567"}', + parse_from: 'body', + }, + ], + createdBy: 'test@email', + createdAt: '2024-01-02T13:56:02.863764227Z', + }, + ], + history: [ + { + id: 'test-id-4', + version: 24, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'DEPLOYED', + deployResult: 'Deployment was successful', + lastHash: 'log_pipelines:24', + lastConf: 'eovineroiv', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2024-01-02T13:56:02Z', + }, + { + id: 'test-4', + version: 23, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'DEPLOYED', + deployResult: 'Deployment was successful', + lastHash: 'log_pipelines:23', + lastConf: 'eivrounreovi', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2023-12-29T12:59:20Z', + }, + ], +}; + +export const pipelineDataHistory: Pipeline['history'] = [ + { + id: 'test-id-4', + version: 24, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'DEPLOYED', + deployResult: 'Deployment was successful', + lastHash: 'log_pipelines:24', + lastConf: 'eovineroiv', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2024-01-02T13:56:02Z', + }, + { + id: 'test-4', + version: 23, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'IN_PROGRESS', + deployResult: 'Deployment is in progress', + lastHash: 'log_pipelines:23', + lastConf: 'eivrounreovi', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2023-12-29T12:59:20Z', + }, + { + id: 'test-4-1', + version: 25, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'DIRTY', + deployResult: 'Deployment is dirty', + lastHash: 'log_pipelines:23', + lastConf: 'eivrounreovi', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2023-12-29T12:59:20Z', + }, + { + id: 'test-4-2', + version: 26, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'FAILED', + deployResult: 'Deployment failed', + lastHash: 'log_pipelines:23', + lastConf: 'eivrounreovi', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2023-12-29T12:59:20Z', + }, + { + id: 'test-4-3', + version: 27, + elementType: 'log_pipelines', + active: false, + isValid: false, + disabled: false, + deployStatus: 'UNKNOWN', + deployResult: '', + lastHash: 'log_pipelines:23', + lastConf: 'eivrounreovi', + createdBy: 'test-created-by', + createdByName: 'test-user', + createdAt: '2023-12-29T12:59:20Z', + }, +]; diff --git a/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx b/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx index fd9d546db7..49d0a132ea 100644 --- a/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx +++ b/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx @@ -1,4 +1,5 @@ import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { I18nextProvider } from 'react-i18next'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; @@ -8,8 +9,17 @@ import store from 'store'; import CreatePipelineButton from '../Layouts/Pipeline/CreatePipelineButton'; import { pipelineApiResponseMockData } from '../mocks/pipeline'; +const trackEventVar = jest.fn(); +jest.mock('hooks/analytics/useAnalytics', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + trackEvent: trackEventVar, + trackPageView: jest.fn(), + })), +})); + describe('PipelinePage container test', () => { - it('should render CreatePipelineButton section', () => { + it('should render CreatePipelineButton section', async () => { const { asFragment } = render( @@ -26,4 +36,58 @@ describe('PipelinePage container test', () => { ); expect(asFragment()).toMatchSnapshot(); }); + + it('CreatePipelineButton - edit mode & tracking', async () => { + const { getByText } = render( + + + + + + + , + ); + + // enter_edit_mode click and track event data + const editButton = getByText('enter_edit_mode'); + expect(editButton).toBeInTheDocument(); + await userEvent.click(editButton); + + expect(trackEventVar).toBeCalledWith('Logs: Pipelines: Entered Edit Mode', { + source: 'signoz-ui', + }); + }); + + it('CreatePipelineButton - add new mode & tracking', async () => { + const { getByText } = render( + + + + + + + , + ); + // new_pipeline click and track event data + const editButton = getByText('new_pipeline'); + expect(editButton).toBeInTheDocument(); + await userEvent.click(editButton); + + expect(trackEventVar).toBeCalledWith( + 'Logs: Pipelines: Clicked Add New Pipeline', + { + source: 'signoz-ui', + }, + ); + }); }); diff --git a/frontend/src/container/PipelinePage/tests/PipelinesSearchSection.test.tsx b/frontend/src/container/PipelinePage/tests/PipelinesSearchSection.test.tsx index 10627e3a18..bfe69adcd1 100644 --- a/frontend/src/container/PipelinePage/tests/PipelinesSearchSection.test.tsx +++ b/frontend/src/container/PipelinePage/tests/PipelinesSearchSection.test.tsx @@ -1,4 +1,5 @@ -import { render } from '@testing-library/react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { I18nextProvider } from 'react-i18next'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; @@ -20,4 +21,43 @@ describe('PipelinePage container test', () => { ); expect(asFragment()).toMatchSnapshot(); }); + + it('should handle search', async () => { + const setPipelineValue = jest.fn(); + const { getByPlaceholderText, container } = render( + + + + + + + , + ); + + const searchInput = getByPlaceholderText('search_pipeline_placeholder'); + + // Type into the search input + userEvent.type(searchInput, 'sample_pipeline'); + + jest.advanceTimersByTime(299); + expect(setPipelineValue).not.toHaveBeenCalled(); + + // Wait for the debounce delay to pass + await waitFor(() => { + // Expect the callback to be called after debounce delay + expect(setPipelineValue).toHaveBeenCalledWith('sample_pipeline'); + }); + + // clear button + fireEvent.click( + container.querySelector( + 'span[class*="ant-input-clear-icon"]', + ) as HTMLElement, + ); + + // Wait for the debounce delay to pass + await waitFor(() => { + expect(setPipelineValue).toHaveBeenCalledWith(''); + }); + }); });