From 6781c29082296f3f4bcc471ee7f905f3fb05c9b6 Mon Sep 17 00:00:00 2001 From: Shaheer Kochai Date: Thu, 8 Aug 2024 08:52:15 +0430 Subject: [PATCH] feat: tests for alert channels settings (#5563) * feat: tests for alert channels settings * chore: overall improvements to alert channel settings tests * chore: improve alerts dummy data --- .../__tests__/AlertChannels.test.tsx | 78 ++++ .../AlertChannelsNormalUser.test.tsx | 72 +++ .../__tests__/CreateAlertChannel.test.tsx | 424 ++++++++++++++++++ .../CreateAlertChannelNormalUser.test.tsx | 348 ++++++++++++++ .../__tests__/EditAlertChannel.test.tsx | 118 +++++ .../AllAlertChannels/__tests__/testUtils.ts | 31 ++ .../FormAlertChannels/Settings/Email.tsx | 1 + .../FormAlertChannels/Settings/MsTeams.tsx | 3 + .../FormAlertChannels/Settings/Opsgenie.tsx | 8 +- .../FormAlertChannels/Settings/Pager.tsx | 8 + .../FormAlertChannels/Settings/Slack.tsx | 4 + .../FormAlertChannels/Settings/Webhook.tsx | 3 + .../src/container/FormAlertChannels/index.tsx | 29 +- .../src/mocks-server/__mockdata__/alerts.ts | 49 ++ frontend/src/mocks-server/handlers.ts | 13 + .../src/pages/GettingStarted/renderConfig.tsx | 2 +- 16 files changed, 1182 insertions(+), 9 deletions(-) create mode 100644 frontend/src/container/AllAlertChannels/__tests__/AlertChannels.test.tsx create mode 100644 frontend/src/container/AllAlertChannels/__tests__/AlertChannelsNormalUser.test.tsx create mode 100644 frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannel.test.tsx create mode 100644 frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannelNormalUser.test.tsx create mode 100644 frontend/src/container/AllAlertChannels/__tests__/EditAlertChannel.test.tsx create mode 100644 frontend/src/container/AllAlertChannels/__tests__/testUtils.ts create mode 100644 frontend/src/mocks-server/__mockdata__/alerts.ts diff --git a/frontend/src/container/AllAlertChannels/__tests__/AlertChannels.test.tsx b/frontend/src/container/AllAlertChannels/__tests__/AlertChannels.test.tsx new file mode 100644 index 0000000000..14dbb70084 --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/AlertChannels.test.tsx @@ -0,0 +1,78 @@ +import AlertChannels from 'container/AllAlertChannels'; +import { allAlertChannels } from 'mocks-server/__mockdata__/alerts'; +import { act, fireEvent, render, screen, waitFor } from 'tests/test-utils'; + +jest.mock('hooks/useFetch', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + payload: allAlertChannels, + })), +})); + +const successNotification = jest.fn(); +jest.mock('hooks/useNotifications', () => ({ + __esModule: true, + useNotifications: jest.fn(() => ({ + notifications: { + success: successNotification, + error: jest.fn(), + }, + })), +})); + +describe('Alert Channels Settings List page', () => { + beforeEach(() => { + render(); + }); + afterEach(() => { + jest.restoreAllMocks(); + }); + describe('Should display the Alert Channels page properly', () => { + it('Should check if "The alerts will be sent to all the configured channels." is visible ', () => { + expect(screen.getByText('sending_channels_note')).toBeInTheDocument(); + }); + it('Should check if "New Alert Channel" Button is visble ', () => { + expect(screen.getByText('button_new_channel')).toBeInTheDocument(); + }); + it('Should check if the help icon is visible and displays "tooltip_notification_channels ', async () => { + const helpIcon = screen.getByLabelText('question-circle'); + + fireEvent.mouseOver(helpIcon); + + await waitFor(() => { + const tooltip = screen.getByText('tooltip_notification_channels'); + expect(tooltip).toBeInTheDocument(); + }); + }); + }); + describe('Should check if the channels table is properly displayed', () => { + it('Should check if the table columns are properly displayed', () => { + expect(screen.getByText('column_channel_name')).toBeInTheDocument(); + expect(screen.getByText('column_channel_type')).toBeInTheDocument(); + expect(screen.getByText('column_channel_action')).toBeInTheDocument(); + }); + + it('Should check if the data in the table is displayed properly', () => { + expect(screen.getByText('Dummy-Channel')).toBeInTheDocument(); + expect(screen.getAllByText('slack')[0]).toBeInTheDocument(); + expect(screen.getAllByText('column_channel_edit')[0]).toBeInTheDocument(); + expect(screen.getAllByText('Delete')[0]).toBeInTheDocument(); + }); + + it('Should check if clicking on Delete displays Success Toast "Channel Deleted Successfully"', async () => { + const deleteButton = screen.getAllByRole('button', { name: 'Delete' })[0]; + expect(deleteButton).toBeInTheDocument(); + + act(() => { + fireEvent.click(deleteButton); + }); + + await waitFor(() => { + expect(successNotification).toBeCalledWith({ + message: 'Success', + description: 'channel_delete_success', + }); + }); + }); + }); +}); diff --git a/frontend/src/container/AllAlertChannels/__tests__/AlertChannelsNormalUser.test.tsx b/frontend/src/container/AllAlertChannels/__tests__/AlertChannelsNormalUser.test.tsx new file mode 100644 index 0000000000..3d957af104 --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/AlertChannelsNormalUser.test.tsx @@ -0,0 +1,72 @@ +import AlertChannels from 'container/AllAlertChannels'; +import { allAlertChannels } from 'mocks-server/__mockdata__/alerts'; +import { fireEvent, render, screen, waitFor } from 'tests/test-utils'; + +jest.mock('hooks/useFetch', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + payload: allAlertChannels, + })), +})); + +const successNotification = jest.fn(); +jest.mock('hooks/useNotifications', () => ({ + __esModule: true, + useNotifications: jest.fn(() => ({ + notifications: { + success: successNotification, + error: jest.fn(), + }, + })), +})); + +jest.mock('hooks/useComponentPermission', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => [false]), +})); + +describe('Alert Channels Settings List page (Normal User)', () => { + beforeEach(() => { + render(); + }); + afterEach(() => { + jest.restoreAllMocks(); + }); + describe('Should display the Alert Channels page properly', () => { + it('Should check if "The alerts will be sent to all the configured channels." is visible ', () => { + expect(screen.getByText('sending_channels_note')).toBeInTheDocument(); + }); + + it('Should check if "New Alert Channel" Button is visble and disabled', () => { + const newAlertButton = screen.getByRole('button', { + name: 'plus button_new_channel', + }); + expect(newAlertButton).toBeInTheDocument(); + expect(newAlertButton).toBeDisabled(); + }); + it('Should check if the help icon is visible and displays "tooltip_notification_channels ', async () => { + const helpIcon = screen.getByLabelText('question-circle'); + + fireEvent.mouseOver(helpIcon); + + await waitFor(() => { + const tooltip = screen.getByText('tooltip_notification_channels'); + expect(tooltip).toBeInTheDocument(); + }); + }); + }); + describe('Should check if the channels table is properly displayed', () => { + it('Should check if the table columns are properly displayed', () => { + expect(screen.getByText('column_channel_name')).toBeInTheDocument(); + expect(screen.getByText('column_channel_type')).toBeInTheDocument(); + expect(screen.queryByText('column_channel_action')).not.toBeInTheDocument(); + }); + + it('Should check if the data in the table is displayed properly', () => { + expect(screen.getByText('Dummy-Channel')).toBeInTheDocument(); + expect(screen.getAllByText('slack')[0]).toBeInTheDocument(); + expect(screen.queryByText('column_channel_edit')).not.toBeInTheDocument(); + expect(screen.queryByText('Delete')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannel.test.tsx b/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannel.test.tsx new file mode 100644 index 0000000000..0406df814f --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannel.test.tsx @@ -0,0 +1,424 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +/* eslint-disable sonarjs/no-identical-functions */ + +import CreateAlertChannels from 'container/CreateAlertChannels'; +import { ChannelType } from 'container/CreateAlertChannels/config'; +import { + opsGenieDescriptionDefaultValue, + opsGenieMessageDefaultValue, + opsGeniePriorityDefaultValue, + pagerDutyAdditionalDetailsDefaultValue, + pagerDutyDescriptionDefaultVaule, + pagerDutySeverityTextDefaultValue, + slackDescriptionDefaultValue, + slackTitleDefaultValue, +} from 'mocks-server/__mockdata__/alerts'; +import { server } from 'mocks-server/server'; +import { rest } from 'msw'; +import { fireEvent, render, screen, waitFor } from 'tests/test-utils'; + +import { testLabelInputAndHelpValue } from './testUtils'; + +const successNotification = jest.fn(); +const errorNotification = jest.fn(); +jest.mock('hooks/useNotifications', () => ({ + __esModule: true, + useNotifications: jest.fn(() => ({ + notifications: { + success: successNotification, + error: errorNotification, + }, + })), +})); + +jest.mock('hooks/useFeatureFlag', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + active: true, + })), +})); + +describe('Create Alert Channel', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel ', () => { + beforeEach(() => { + render(); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('Should check if the title is "New Notification Channels"', () => { + expect(screen.getByText('page_title_create')).toBeInTheDocument(); + }); + it('Should check if the name label and textbox are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_name', + testId: 'channel-name-textbox', + }); + }); + it('Should check if Send resolved alerts label and checkbox are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_send_resolved', + testId: 'field-send-resolved-checkbox', + }); + }); + it('Should check if channel type label and dropdown are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_type', + testId: 'channel-type-select', + }); + }); + // Default Channel type (Slack) fields + it('Should check if the selected item in the type dropdown has text "Slack"', () => { + expect(screen.getByText('Slack')).toBeInTheDocument(); + }); + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + }); + }); + it('Should check if Recepient label, input, and help text are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_recipient', + testId: 'slack-channel-textbox', + helpText: 'slack_channel_help', + }); + }); + + it('Should check if Title label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_title', + testId: 'title-textarea', + }); + }); + it('Should check if Title contains template', () => { + const titleTextArea = screen.getByTestId('title-textarea'); + + expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue); + }); + it('Should check if Description label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_description', + testId: 'description-textarea', + }); + }); + it('Should check if Description contains template', () => { + const descriptionTextArea = screen.getByTestId('description-textarea'); + + expect(descriptionTextArea).toHaveTextContent(slackDescriptionDefaultValue); + }); + it('Should check if the form buttons are displayed properly (Save, Test, Back)', () => { + expect(screen.getByText('button_save_channel')).toBeInTheDocument(); + expect(screen.getByText('button_test_channel')).toBeInTheDocument(); + expect(screen.getByText('button_return')).toBeInTheDocument(); + }); + it('Should check if saving the form without filling the name displays "Something went wrong"', async () => { + const saveButton = screen.getByRole('button', { + name: 'button_save_channel', + }); + + fireEvent.click(saveButton); + + await waitFor(() => + expect(errorNotification).toHaveBeenCalledWith({ + description: 'Something went wrong', + message: 'Error', + }), + ); + }); + it('Should check if clicking on Test button shows "An alert has been sent to this channel" success message if testing passes', async () => { + server.use( + rest.post('http://localhost/api/v1/testChannel', (req, res, ctx) => + res( + ctx.status(200), + ctx.json({ + status: 'success', + data: 'test alert sent', + }), + ), + ), + ); + const testButton = screen.getByRole('button', { + name: 'button_test_channel', + }); + + fireEvent.click(testButton); + + await waitFor(() => + expect(successNotification).toHaveBeenCalledWith({ + message: 'Success', + description: 'channel_test_done', + }), + ); + }); + it('Should check if clicking on Test button shows "Something went wrong" error message if testing fails', async () => { + const testButton = screen.getByRole('button', { + name: 'button_test_channel', + }); + + fireEvent.click(testButton); + + await waitFor(() => + expect(errorNotification).toHaveBeenCalledWith({ + message: 'Error', + description: 'channel_test_failed', + }), + ); + }); + }); + describe('New Alert Channel Cascading Fields Based on Channel Type', () => { + describe('Webhook', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Webhook"', () => { + expect(screen.getByText('Webhook')).toBeInTheDocument(); + }); + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + }); + }); + it('Should check if Webhook User Name label, input, and help text are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_username', + testId: 'webhook-username-textbox', + helpText: 'help_webhook_username', + }); + }); + it('Should check if Password label and textbox, and help text are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'Password (optional)', + testId: 'webhook-password-textbox', + helpText: 'help_webhook_password', + }); + }); + }); + describe('PagerDuty', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Pagerduty"', () => { + expect(screen.getByText('Pagerduty')).toBeInTheDocument(); + }); + it('Should check if Routing key label, required, and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_routing_key', + testId: 'pager-routing-key-textbox', + }); + }); + it('Should check if Description label, required, info (Shows up as description in pagerduty), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_description', + testId: 'pager-description-textarea', + helpText: 'help_pager_description', + }); + }); + it('Should check if the description contains default template', () => { + const descriptionTextArea = screen.getByTestId( + 'pager-description-textarea', + ); + + expect(descriptionTextArea).toHaveTextContent( + pagerDutyDescriptionDefaultVaule, + ); + }); + it('Should check if Severity label, info (help_pager_severity), and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_severity', + testId: 'pager-severity-textbox', + helpText: 'help_pager_severity', + }); + }); + it('Should check if Severity contains the default template', () => { + const severityTextbox = screen.getByTestId('pager-severity-textbox'); + + expect(severityTextbox).toHaveValue(pagerDutySeverityTextDefaultValue); + }); + it('Should check if Additional Information label, text area, and help text (help_pager_details) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_details', + testId: 'pager-additional-details-textarea', + helpText: 'help_pager_details', + }); + }); + it('Should check if Additional Information contains the default template', () => { + const detailsTextArea = screen.getByTestId( + 'pager-additional-details-textarea', + ); + + expect(detailsTextArea).toHaveValue(pagerDutyAdditionalDetailsDefaultValue); + }); + it('Should check if Group label, text area, and info (help_pager_group) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_group', + testId: 'pager-group-textarea', + helpText: 'help_pager_group', + }); + }); + it('Should check if Class label, text area, and info (help_pager_class) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_class', + testId: 'pager-class-textarea', + helpText: 'help_pager_class', + }); + }); + it('Should check if Client label, text area, and info (Shows up as event source in Pagerduty) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_client', + testId: 'pager-client-textarea', + helpText: 'help_pager_client', + }); + }); + it('Should check if Client input contains the default value "SigNoz Alert Manager"', () => { + const clientTextArea = screen.getByTestId('pager-client-textarea'); + + expect(clientTextArea).toHaveValue('SigNoz Alert Manager'); + }); + it('Should check if Client URL label, text area, and info (Shows up as event source link in Pagerduty) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_client_url', + testId: 'pager-client-url-textarea', + helpText: 'help_pager_client_url', + }); + }); + it('Should check if Client URL contains the default value "https://enter-signoz-host-n-port-here/alerts"', () => { + const clientUrlTextArea = screen.getByTestId('pager-client-url-textarea'); + + expect(clientUrlTextArea).toHaveValue( + 'https://enter-signoz-host-n-port-here/alerts', + ); + }); + }); + describe('Opsgenie', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Opsgenie"', () => { + expect(screen.getByText('Opsgenie')).toBeInTheDocument(); + }); + + it('Should check if API key label, required, and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_api_key', + testId: 'opsgenie-api-key-textbox', + required: true, + }); + }); + + it('Should check if Message label, required, info (Shows up as message in opsgenie), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_message', + testId: 'opsgenie-message-textarea', + helpText: 'help_opsgenie_message', + required: true, + }); + }); + + it('Should check if Message contains the default template ', () => { + const messageTextArea = screen.getByTestId('opsgenie-message-textarea'); + + expect(messageTextArea).toHaveValue(opsGenieMessageDefaultValue); + }); + + it('Should check if Description label, required, info (Shows up as description in opsgenie), and text area are displayed properly `{{ if gt (len .Alerts.Firing) 0 -}}', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_description', + testId: 'opsgenie-description-textarea', + helpText: 'help_opsgenie_description', + required: true, + }); + }); + + it('Should check if Description label, required, info (Shows up as description in opsgenie), and text area are displayed properly `{{ if gt (len .Alerts.Firing) 0 -}}', () => { + const descriptionTextArea = screen.getByTestId( + 'opsgenie-description-textarea', + ); + + expect(descriptionTextArea).toHaveTextContent( + opsGenieDescriptionDefaultValue, + ); + }); + + it('Should check if Priority label, required, info (help_opsgenie_priority), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_priority', + testId: 'opsgenie-priority-textarea', + helpText: 'help_opsgenie_priority', + required: true, + }); + }); + + it('Should check if Message contains the default template', () => { + const priorityTextArea = screen.getByTestId('opsgenie-priority-textarea'); + + expect(priorityTextArea).toHaveValue(opsGeniePriorityDefaultValue); + }); + }); + describe('Opsgenie', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Email"', () => { + expect(screen.getByText('Email')).toBeInTheDocument(); + }); + it('Should check if API key label, required, info(help_email_to), and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_email_to', + testId: 'email-to-textbox', + helpText: 'help_email_to', + required: true, + }); + }); + }); + describe('Microsoft Teams', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "msteams"', () => { + expect(screen.getByText('msteams')).toBeInTheDocument(); + }); + + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + }); + }); + + it('Should check if Title label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_title', + testId: 'title-textarea', + }); + }); + + it('Should check if Title contains template', () => { + const titleTextArea = screen.getByTestId('title-textarea'); + + expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue); + }); + it('Should check if Description label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_description', + testId: 'description-textarea', + }); + }); + + it('Should check if Description contains template', () => { + const descriptionTextArea = screen.getByTestId('description-textarea'); + + expect(descriptionTextArea).toHaveTextContent(slackDescriptionDefaultValue); + }); + }); + }); +}); diff --git a/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannelNormalUser.test.tsx b/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannelNormalUser.test.tsx new file mode 100644 index 0000000000..7c9ec5618f --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/CreateAlertChannelNormalUser.test.tsx @@ -0,0 +1,348 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +/* eslint-disable sonarjs/no-identical-functions */ + +import { SIGNOZ_UPGRADE_PLAN_URL } from 'constants/app'; +import CreateAlertChannels from 'container/CreateAlertChannels'; +import { ChannelType } from 'container/CreateAlertChannels/config'; +import { + opsGenieDescriptionDefaultValue, + opsGenieMessageDefaultValue, + opsGeniePriorityDefaultValue, + pagerDutyAdditionalDetailsDefaultValue, + pagerDutyDescriptionDefaultVaule, + pagerDutySeverityTextDefaultValue, + slackDescriptionDefaultValue, + slackTitleDefaultValue, +} from 'mocks-server/__mockdata__/alerts'; +import { render, screen } from 'tests/test-utils'; + +import { testLabelInputAndHelpValue } from './testUtils'; + +describe('Create Alert Channel (Normal User)', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel ', () => { + beforeEach(() => { + render(); + }); + it('Should check if the title is "New Notification Channels"', () => { + expect(screen.getByText('page_title_create')).toBeInTheDocument(); + }); + it('Should check if the name label and textbox are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_name', + testId: 'channel-name-textbox', + }); + }); + it('Should check if Send resolved alerts label and checkbox are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_send_resolved', + testId: 'field-send-resolved-checkbox', + }); + }); + it('Should check if channel type label and dropdown are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_type', + testId: 'channel-type-select', + }); + }); + // Default Channel type (Slack) fields + it('Should check if the selected item in the type dropdown has text "Slack"', () => { + expect(screen.getByText('Slack')).toBeInTheDocument(); + }); + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + }); + }); + it('Should check if Recepient label, input, and help text are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_recipient', + testId: 'slack-channel-textbox', + helpText: 'slack_channel_help', + }); + }); + + it('Should check if Title label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_title', + testId: 'title-textarea', + }); + }); + it('Should check if Title contains template', () => { + const titleTextArea = screen.getByTestId('title-textarea'); + + expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue); + }); + it('Should check if Description label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_description', + testId: 'description-textarea', + }); + }); + it('Should check if Description contains template', () => { + const descriptionTextArea = screen.getByTestId('description-textarea'); + + expect(descriptionTextArea).toHaveTextContent(slackDescriptionDefaultValue); + }); + it('Should check if the form buttons are displayed properly (Save, Test, Back)', () => { + expect(screen.getByText('button_save_channel')).toBeInTheDocument(); + expect(screen.getByText('button_test_channel')).toBeInTheDocument(); + expect(screen.getByText('button_return')).toBeInTheDocument(); + }); + }); + describe('New Alert Channel Cascading Fields Based on Channel Type', () => { + describe('Webhook', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Webhook"', () => { + expect(screen.getByText('Webhook')).toBeInTheDocument(); + }); + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + }); + }); + it('Should check if Webhook User Name label, input, and help text are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_username', + testId: 'webhook-username-textbox', + helpText: 'help_webhook_username', + }); + }); + it('Should check if Password label and textbox, and help text are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'Password (optional)', + testId: 'webhook-password-textbox', + helpText: 'help_webhook_password', + }); + }); + }); + describe('PagerDuty', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Pagerduty"', () => { + expect(screen.getByText('Pagerduty')).toBeInTheDocument(); + }); + it('Should check if Routing key label, required, and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_routing_key', + testId: 'pager-routing-key-textbox', + }); + }); + it('Should check if Description label, required, info (Shows up as description in pagerduty), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_description', + testId: 'pager-description-textarea', + helpText: 'help_pager_description', + }); + }); + it('Should check if the description contains default template', () => { + const descriptionTextArea = screen.getByTestId( + 'pager-description-textarea', + ); + + expect(descriptionTextArea).toHaveTextContent( + pagerDutyDescriptionDefaultVaule, + ); + }); + it('Should check if Severity label, info (help_pager_severity), and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_severity', + testId: 'pager-severity-textbox', + helpText: 'help_pager_severity', + }); + }); + it('Should check if Severity contains the default template', () => { + const severityTextbox = screen.getByTestId('pager-severity-textbox'); + + expect(severityTextbox).toHaveValue(pagerDutySeverityTextDefaultValue); + }); + it('Should check if Additional Information label, text area, and help text (help_pager_details) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_details', + testId: 'pager-additional-details-textarea', + helpText: 'help_pager_details', + }); + }); + it('Should check if Additional Information contains the default template', () => { + const detailsTextArea = screen.getByTestId( + 'pager-additional-details-textarea', + ); + + expect(detailsTextArea).toHaveValue(pagerDutyAdditionalDetailsDefaultValue); + }); + it('Should check if Group label, text area, and info (help_pager_group) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_group', + testId: 'pager-group-textarea', + helpText: 'help_pager_group', + }); + }); + it('Should check if Class label, text area, and info (help_pager_class) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_class', + testId: 'pager-class-textarea', + helpText: 'help_pager_class', + }); + }); + it('Should check if Client label, text area, and info (Shows up as event source in Pagerduty) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_client', + testId: 'pager-client-textarea', + helpText: 'help_pager_client', + }); + }); + it('Should check if Client input contains the default value "SigNoz Alert Manager"', () => { + const clientTextArea = screen.getByTestId('pager-client-textarea'); + + expect(clientTextArea).toHaveValue('SigNoz Alert Manager'); + }); + it('Should check if Client URL label, text area, and info (Shows up as event source link in Pagerduty) are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_pager_client_url', + testId: 'pager-client-url-textarea', + helpText: 'help_pager_client_url', + }); + }); + it('Should check if Client URL contains the default value "https://enter-signoz-host-n-port-here/alerts"', () => { + const clientUrlTextArea = screen.getByTestId('pager-client-url-textarea'); + + expect(clientUrlTextArea).toHaveValue( + 'https://enter-signoz-host-n-port-here/alerts', + ); + }); + }); + describe('Opsgenie', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Opsgenie"', () => { + expect(screen.getByText('Opsgenie')).toBeInTheDocument(); + }); + + it('Should check if API key label, required, and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_api_key', + testId: 'opsgenie-api-key-textbox', + required: true, + }); + }); + + it('Should check if Message label, required, info (Shows up as message in opsgenie), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_message', + testId: 'opsgenie-message-textarea', + helpText: 'help_opsgenie_message', + required: true, + }); + }); + + it('Should check if Message contains the default template ', () => { + const messageTextArea = screen.getByTestId('opsgenie-message-textarea'); + + expect(messageTextArea).toHaveValue(opsGenieMessageDefaultValue); + }); + + it('Should check if Description label, required, info (Shows up as description in opsgenie), and text area are displayed properly `{{ if gt (len .Alerts.Firing) 0 -}}', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_description', + testId: 'opsgenie-description-textarea', + helpText: 'help_opsgenie_description', + required: true, + }); + }); + + it('Should check if Description label, required, info (Shows up as description in opsgenie), and text area are displayed properly `{{ if gt (len .Alerts.Firing) 0 -}}', () => { + const descriptionTextArea = screen.getByTestId( + 'opsgenie-description-textarea', + ); + + expect(descriptionTextArea).toHaveTextContent( + opsGenieDescriptionDefaultValue, + ); + }); + + it('Should check if Priority label, required, info (help_opsgenie_priority), and text area are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_opsgenie_priority', + testId: 'opsgenie-priority-textarea', + helpText: 'help_opsgenie_priority', + required: true, + }); + }); + + it('Should check if Message contains the default template', () => { + const priorityTextArea = screen.getByTestId('opsgenie-priority-textarea'); + + expect(priorityTextArea).toHaveValue(opsGeniePriorityDefaultValue); + }); + }); + describe('Opsgenie', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Email"', () => { + expect(screen.getByText('Email')).toBeInTheDocument(); + }); + it('Should check if API key label, required, info(help_email_to), and textbox are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_email_to', + testId: 'email-to-textbox', + helpText: 'help_email_to', + required: true, + }); + }); + }); + describe('Microsoft Teams', () => { + beforeEach(() => { + render(); + }); + + it('Should check if the selected item in the type dropdown has text "Microsoft Teams (Supported in Paid Plans Only)"', () => { + expect( + screen.getByText('Microsoft Teams (Supported in Paid Plans Only)'), + ).toBeInTheDocument(); + }); + + it('Should check if the upgrade plan message is shown', () => { + expect(screen.getByText('Upgrade to a Paid Plan')).toBeInTheDocument(); + expect( + screen.getByText(/This feature is available for paid plans only./), + ).toBeInTheDocument(); + const link = screen.getByRole('link', { name: 'Click here' }); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute('href', SIGNOZ_UPGRADE_PLAN_URL); + expect(screen.getByText(/to Upgrade/)).toBeInTheDocument(); + }); + it('Should check if the form buttons are displayed properly (Save, Test, Back)', () => { + expect( + screen.getByRole('button', { name: 'button_save_channel' }), + ).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'button_test_channel' }), + ).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'button_return' }), + ).toBeInTheDocument(); + }); + it('Should check if save and test buttons are disabled', () => { + expect( + screen.getByRole('button', { name: 'button_save_channel' }), + ).toBeDisabled(); + expect( + screen.getByRole('button', { name: 'button_test_channel' }), + ).toBeDisabled(); + }); + }); + }); +}); diff --git a/frontend/src/container/AllAlertChannels/__tests__/EditAlertChannel.test.tsx b/frontend/src/container/AllAlertChannels/__tests__/EditAlertChannel.test.tsx new file mode 100644 index 0000000000..afd1a20bfd --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/EditAlertChannel.test.tsx @@ -0,0 +1,118 @@ +import EditAlertChannels from 'container/EditAlertChannels'; +import { + editAlertChannelInitialValue, + editSlackDescriptionDefaultValue, + slackTitleDefaultValue, +} from 'mocks-server/__mockdata__/alerts'; +import { render, screen } from 'tests/test-utils'; + +import { testLabelInputAndHelpValue } from './testUtils'; + +const successNotification = jest.fn(); +const errorNotification = jest.fn(); +jest.mock('hooks/useNotifications', () => ({ + __esModule: true, + useNotifications: jest.fn(() => ({ + notifications: { + success: successNotification, + error: errorNotification, + }, + })), +})); + +jest.mock('hooks/useFeatureFlag', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + active: true, + })), +})); + +describe('Should check if the edit alert channel is properly displayed ', () => { + beforeEach(() => { + render(); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('Should check if the title is "Edit Notification Channels"', () => { + expect(screen.getByText('page_title_edit')).toBeInTheDocument(); + }); + + it('Should check if the name label and textbox are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_name', + testId: 'channel-name-textbox', + value: 'Dummy-Channel', + }); + }); + it('Should check if Send resolved alerts label and checkbox are displayed properly and the checkbox is checked ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_send_resolved', + testId: 'field-send-resolved-checkbox', + }); + expect(screen.getByTestId('field-send-resolved-checkbox')).toBeChecked(); + }); + + it('Should check if channel type label and dropdown are displayed properly', () => { + testLabelInputAndHelpValue({ + labelText: 'field_channel_type', + testId: 'channel-type-select', + }); + }); + + it('Should check if the selected item in the type dropdown has text "Slack"', () => { + expect(screen.getByText('Slack')).toBeInTheDocument(); + }); + + it('Should check if Webhook URL label and input are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_webhook_url', + testId: 'webhook-url-textbox', + value: + 'https://discord.com/api/webhooks/dummy_webhook_id/dummy_webhook_token/slack', + }); + }); + + it('Should check if Recepient label, input, and help text are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_recipient', + testId: 'slack-channel-textbox', + helpText: 'slack_channel_help', + value: '#dummy_channel', + }); + }); + + it('Should check if Title label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_title', + testId: 'title-textarea', + }); + }); + + it('Should check if Title contains template', () => { + const titleTextArea = screen.getByTestId('title-textarea'); + + expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue); + }); + + it('Should check if Description label and text area are displayed properly ', () => { + testLabelInputAndHelpValue({ + labelText: 'field_slack_description', + testId: 'description-textarea', + }); + }); + + it('Should check if Description contains template', () => { + const descriptionTextArea = screen.getByTestId('description-textarea'); + + expect(descriptionTextArea).toHaveTextContent( + editSlackDescriptionDefaultValue, + ); + }); + + it('Should check if the form buttons are displayed properly (Save, Test, Back)', () => { + expect(screen.getByText('button_save_channel')).toBeInTheDocument(); + expect(screen.getByText('button_test_channel')).toBeInTheDocument(); + expect(screen.getByText('button_return')).toBeInTheDocument(); + }); +}); diff --git a/frontend/src/container/AllAlertChannels/__tests__/testUtils.ts b/frontend/src/container/AllAlertChannels/__tests__/testUtils.ts new file mode 100644 index 0000000000..bae773f2fb --- /dev/null +++ b/frontend/src/container/AllAlertChannels/__tests__/testUtils.ts @@ -0,0 +1,31 @@ +import { screen } from 'tests/test-utils'; + +export const testLabelInputAndHelpValue = ({ + labelText, + testId, + helpText, + required = false, + value, +}: { + labelText: string; + testId: string; + helpText?: string; + required?: boolean; + value?: string; +}): void => { + const label = screen.getByText(labelText); + expect(label).toBeInTheDocument(); + + const input = screen.getByTestId(testId); + expect(input).toBeInTheDocument(); + + if (helpText !== undefined) { + expect(screen.getByText(helpText)).toBeInTheDocument(); + } + if (required) { + expect(input).toBeRequired(); + } + if (value) { + expect(input).toHaveValue(value); + } +}; diff --git a/frontend/src/container/FormAlertChannels/Settings/Email.tsx b/frontend/src/container/FormAlertChannels/Settings/Email.tsx index 398e172a57..4d57d72f6d 100644 --- a/frontend/src/container/FormAlertChannels/Settings/Email.tsx +++ b/frontend/src/container/FormAlertChannels/Settings/Email.tsx @@ -27,6 +27,7 @@ function EmailForm({ setSelectedConfig }: EmailFormProps): JSX.Element { diff --git a/frontend/src/container/FormAlertChannels/Settings/MsTeams.tsx b/frontend/src/container/FormAlertChannels/Settings/MsTeams.tsx index 48751f4acc..52ef85acff 100644 --- a/frontend/src/container/FormAlertChannels/Settings/MsTeams.tsx +++ b/frontend/src/container/FormAlertChannels/Settings/MsTeams.tsx @@ -17,6 +17,7 @@ function MsTeams({ setSelectedConfig }: MsTeamsProps): JSX.Element { webhook_url: event.target.value, })); }} + data-testid="webhook-url-textbox" /> @@ -30,6 +31,7 @@ function MsTeams({ setSelectedConfig }: MsTeamsProps): JSX.Element { title: event.target.value, })) } + data-testid="title-textarea" /> @@ -41,6 +43,7 @@ function MsTeams({ setSelectedConfig }: MsTeamsProps): JSX.Element { text: event.target.value, })) } + data-testid="description-textarea" placeholder={t('placeholder_slack_description')} /> diff --git a/frontend/src/container/FormAlertChannels/Settings/Opsgenie.tsx b/frontend/src/container/FormAlertChannels/Settings/Opsgenie.tsx index 009dd01882..1472ca0b4e 100644 --- a/frontend/src/container/FormAlertChannels/Settings/Opsgenie.tsx +++ b/frontend/src/container/FormAlertChannels/Settings/Opsgenie.tsx @@ -20,7 +20,10 @@ function OpsgenieForm({ setSelectedConfig }: OpsgenieFormProps): JSX.Element { return ( <> - + @@ -46,6 +50,7 @@ function OpsgenieForm({ setSelectedConfig }: OpsgenieFormProps): JSX.Element { rows={4} onChange={handleInputChange('description')} placeholder={t('placeholder_opsgenie_description')} + data-testid="opsgenie-description-textarea" /> @@ -59,6 +64,7 @@ function OpsgenieForm({ setSelectedConfig }: OpsgenieFormProps): JSX.Element { rows={4} onChange={handleInputChange('priority')} placeholder={t('placeholder_opsgenie_priority')} + data-testid="opsgenie-priority-textarea" /> diff --git a/frontend/src/container/FormAlertChannels/Settings/Pager.tsx b/frontend/src/container/FormAlertChannels/Settings/Pager.tsx index ec228f4b8d..61df458941 100644 --- a/frontend/src/container/FormAlertChannels/Settings/Pager.tsx +++ b/frontend/src/container/FormAlertChannels/Settings/Pager.tsx @@ -18,6 +18,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { routing_key: event.target.value, })); }} + data-testid="pager-routing-key-textbox" /> @@ -36,6 +37,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { })) } placeholder={t('placeholder_pager_description')} + data-testid="pager-description-textarea" /> @@ -51,6 +53,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { severity: event.target.value, })) } + data-testid="pager-severity-textbox" /> @@ -67,6 +70,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { details: event.target.value, })) } + data-testid="pager-additional-details-textarea" /> @@ -97,6 +101,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { group: event.target.value, })) } + data-testid="pager-group-textarea" /> @@ -112,6 +117,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { class: event.target.value, })) } + data-testid="pager-class-textarea" /> @@ -141,6 +148,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element { client_url: event.target.value, })) } + data-testid="pager-client-url-textarea" /> diff --git a/frontend/src/container/FormAlertChannels/Settings/Slack.tsx b/frontend/src/container/FormAlertChannels/Settings/Slack.tsx index c344df8ff5..5321fa5fe6 100644 --- a/frontend/src/container/FormAlertChannels/Settings/Slack.tsx +++ b/frontend/src/container/FormAlertChannels/Settings/Slack.tsx @@ -19,6 +19,7 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element { api_url: event.target.value, })); }} + data-testid="webhook-url-textbox" /> @@ -34,11 +35,13 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element { channel: event.target.value, })) } + data-testid="slack-channel-textbox" />