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"
/>
>
diff --git a/frontend/src/container/FormAlertChannels/Settings/Webhook.tsx b/frontend/src/container/FormAlertChannels/Settings/Webhook.tsx
index ead1464734..4031babd82 100644
--- a/frontend/src/container/FormAlertChannels/Settings/Webhook.tsx
+++ b/frontend/src/container/FormAlertChannels/Settings/Webhook.tsx
@@ -17,6 +17,7 @@ function WebhookSettings({ setSelectedConfig }: WebhookProps): JSX.Element {
api_url: event.target.value,
}));
}}
+ data-testid="webhook-url-textbox"
/>
>
diff --git a/frontend/src/container/FormAlertChannels/index.tsx b/frontend/src/container/FormAlertChannels/index.tsx
index 1d772ca7a8..c413588e80 100644
--- a/frontend/src/container/FormAlertChannels/index.tsx
+++ b/frontend/src/container/FormAlertChannels/index.tsx
@@ -85,6 +85,7 @@ function FormAlertChannels({
{
setSelectedConfig((state) => ({
@@ -102,6 +103,7 @@ function FormAlertChannels({
>
{
setSelectedConfig((state) => ({
...state,
@@ -112,24 +114,37 @@ function FormAlertChannels({
-