diff --git a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
index 4fa65eb999..15ff3278a0 100644
--- a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
+++ b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
@@ -14,34 +14,82 @@
* limitations under the License.
*/
import React from 'react';
-import { render } from '@testing-library/react';
+import { render, waitFor } from '@testing-library/react';
import { EscalationPolicy } from './EscalationPolicy';
import { wrapInTestApp } from '@backstage/test-utils';
import { User } from '../types';
+import { ApiProvider, ApiRegistry } from '@backstage/core';
+import { pagerDutyApiRef } from '../../api';
-const escalations: User[] = [
- {
- name: 'person1',
- id: 'p1',
- summary: 'person1',
- email: 'person1@example.com',
- html_url: 'http://a.com/id1',
- },
-];
+const mockPagerDutyApi = {
+ getOnCallByPolicyId: () => [],
+};
+const apis = ApiRegistry.from([[pagerDutyApiRef, mockPagerDutyApi]]);
describe('Escalation', () => {
- it('render emptyState', () => {
- const { getByText } = render(
- wrapInTestApp(),
+ it('Handles an empty response', async () => {
+ mockPagerDutyApi.getOnCallByPolicyId = jest
+ .fn()
+ .mockImplementationOnce(async () => []);
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
);
+ await waitFor(() => !queryByTestId('progress'));
+
expect(getByText('Empty escalation policy')).toBeInTheDocument();
+ expect(mockPagerDutyApi.getOnCallByPolicyId).toHaveBeenCalledWith('456');
});
- it('render escalation list', () => {
- const { getByText } = render(
- wrapInTestApp(),
+ it('Render a list of users', async () => {
+ mockPagerDutyApi.getOnCallByPolicyId = jest
+ .fn()
+ .mockImplementationOnce(async () => [
+ {
+ user: {
+ name: 'person1',
+ id: 'p1',
+ summary: 'person1',
+ email: 'person1@example.com',
+ html_url: 'http://a.com/id1',
+ } as User,
+ },
+ ]);
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
);
+ await waitFor(() => !queryByTestId('progress'));
+
expect(getByText('person1')).toBeInTheDocument();
expect(getByText('person1@example.com')).toBeInTheDocument();
+ expect(mockPagerDutyApi.getOnCallByPolicyId).toHaveBeenCalledWith('abc');
+ });
+
+ it('Handles errors', async () => {
+ mockPagerDutyApi.getOnCallByPolicyId = jest
+ .fn()
+ .mockRejectedValueOnce(new Error('Error message'));
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+
+ expect(
+ getByText('Error encountered while fetching information. Error message'),
+ ).toBeInTheDocument();
});
});
diff --git a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
index fbe3783d30..6baa410021 100644
--- a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
+++ b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
@@ -14,65 +14,100 @@
* limitations under the License.
*/
import React from 'react';
-import { render } from '@testing-library/react';
+import { render, waitFor } from '@testing-library/react';
import { Incidents } from './Incidents';
import { wrapInTestApp } from '@backstage/test-utils';
+import { ApiProvider, ApiRegistry } from '@backstage/core';
+import { pagerDutyApiRef } from '../../api';
import { Incident } from '../types';
-const incidents: Incident[] = [
- {
- id: 'id1',
- status: 'triggered',
- title: 'title1',
- created_at: '2020-11-06T00:00:00Z',
- assignments: [
- {
- assignee: {
- name: 'person1',
- id: 'p1',
- summary: 'person1',
- email: 'person1@example.com',
- html_url: 'http://a.com/id1',
- },
- },
- ],
- homepageUrl: 'http://a.com/id1',
- serviceId: 'sId1',
- },
- {
- id: 'id2',
- status: 'acknowledged',
- title: 'title2',
- created_at: '2020-11-07T00:00:00Z',
- assignments: [
- {
- assignee: {
- name: 'person2',
- id: 'p2',
- summary: 'person2',
- email: 'person2@example.com',
- html_url: 'http://a.com/id2',
- },
- },
- ],
- homepageUrl: 'http://a.com/id2',
- serviceId: 'sId2',
- },
-];
+const mockPagerDutyApi = {
+ getIncidentsByServiceId: () => [],
+};
+const apis = ApiRegistry.from([[pagerDutyApiRef, mockPagerDutyApi]]);
describe('Incidents', () => {
- it('renders an empty state is there are no incidents', () => {
- const { getByText } = render(wrapInTestApp());
+ it('Renders an empty state when there are no incidents', async () => {
+ mockPagerDutyApi.getIncidentsByServiceId = jest
+ .fn()
+ .mockImplementationOnce(async () => []);
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+ {}}
+ />
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
expect(
getByText('Nice! No incidents are assigned to you!'),
).toBeInTheDocument();
});
- it('renders all incidents', () => {
- const { getByText, getByTitle, getAllByTitle, getByLabelText } = render(
- wrapInTestApp(),
- );
+ it('Renders all incidents', async () => {
+ mockPagerDutyApi.getIncidentsByServiceId = jest.fn().mockImplementationOnce(
+ async () =>
+ [
+ {
+ id: 'id1',
+ status: 'triggered',
+ title: 'title1',
+ created_at: '2020-11-06T00:00:00Z',
+ assignments: [
+ {
+ assignee: {
+ id: 'p1',
+ summary: 'person1',
+ html_url: 'http://a.com/id1',
+ },
+ },
+ ],
+ html_url: 'http://a.com/id1',
+ serviceId: 'sId1',
+ },
+ {
+ id: 'id2',
+ status: 'acknowledged',
+ title: 'title2',
+ created_at: '2020-11-07T00:00:00Z',
+ assignments: [
+ {
+ assignee: {
+ id: 'p2',
+ summary: 'person2',
+ html_url: 'http://a.com/id2',
+ },
+ },
+ ],
+ html_url: 'http://a.com/id2',
+ serviceId: 'sId2',
+ },
+ ] as Incident[],
+ );
+ const {
+ getByText,
+ getByTitle,
+ getAllByTitle,
+ getByLabelText,
+ queryByTestId,
+ } = render(
+ wrapInTestApp(
+
+ {}}
+ />
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
expect(getByText('title1')).toBeInTheDocument();
expect(getByText('title2')).toBeInTheDocument();
expect(getByText('person1')).toBeInTheDocument();
@@ -85,4 +120,26 @@ describe('Incidents', () => {
// assert links, mailto and hrefs, date calculation
expect(getAllByTitle('View in PagerDuty').length).toEqual(2);
});
+
+ it('Handle errors', async () => {
+ mockPagerDutyApi.getIncidentsByServiceId = jest
+ .fn()
+ .mockRejectedValueOnce(new Error('Error occurred'));
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+ {}}
+ />
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(
+ getByText('Error encountered while fetching information. Error occurred'),
+ ).toBeInTheDocument();
+ });
});
diff --git a/plugins/pagerduty/src/components/PagerDutyCard.test.tsx b/plugins/pagerduty/src/components/PagerDutyCard.test.tsx
new file mode 100644
index 0000000000..bca6f9f940
--- /dev/null
+++ b/plugins/pagerduty/src/components/PagerDutyCard.test.tsx
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import { render, waitFor, fireEvent } from '@testing-library/react';
+import { PagerDutyCard } from './PagerdutyCard';
+import { Entity } from '@backstage/catalog-model';
+import { wrapInTestApp } from '@backstage/test-utils';
+import {
+ alertApiRef,
+ ApiProvider,
+ ApiRegistry,
+ createApiRef,
+} from '@backstage/core';
+import { pagerDutyApiRef, UnauthorizedError, PagerDutyClient } from '../api';
+import { Service } from './types';
+import { act } from 'react-dom/test-utils';
+
+const mockPagerDutyApi: Partial = {
+ getServiceByIntegrationKey: async () => [],
+ getOnCallByPolicyId: async () => [],
+ getIncidentsByServiceId: async () => [],
+};
+
+const apis = ApiRegistry.from([
+ [pagerDutyApiRef, mockPagerDutyApi],
+ [
+ alertApiRef,
+ createApiRef({
+ id: 'core.alert',
+ description: 'Used to report alerts and forward them to the app',
+ }),
+ ],
+]);
+const entity: Entity = {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ metadata: {
+ name: 'pagerduty-test',
+ annotations: {
+ 'pagerduty.com/integration-key': 'abc123',
+ },
+ },
+};
+
+const service: Service = {
+ id: 'abc',
+ name: 'pagerduty-name',
+ html_url: 'www.example.com',
+ escalation_policy: {
+ id: 'def',
+ user: {
+ name: 'person1',
+ id: 'p1',
+ summary: 'person1',
+ email: 'person1@example.com',
+ html_url: 'http://a.com/id1',
+ },
+ },
+ integrationKey: 'abcd',
+};
+
+describe('PageDutyCard', () => {
+ it('Render pagerduty', async () => {
+ mockPagerDutyApi.getServiceByIntegrationKey = jest
+ .fn()
+ .mockImplementationOnce(async () => [service]);
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(getByText('View in PagerDuty')).toBeInTheDocument();
+ expect(getByText('Trigger Alarm')).toBeInTheDocument();
+ expect(
+ getByText('Nice! No incidents are assigned to you!'),
+ ).toBeInTheDocument();
+ expect(getByText('Empty escalation policy')).toBeInTheDocument();
+ });
+
+ it('Handles custom error for missing token', async () => {
+ mockPagerDutyApi.getServiceByIntegrationKey = jest
+ .fn()
+ .mockRejectedValueOnce(new UnauthorizedError());
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(getByText('Missing or invalid PagerDuty Token')).toBeInTheDocument();
+ });
+
+ it('handles general error', async () => {
+ mockPagerDutyApi.getServiceByIntegrationKey = jest
+ .fn()
+ .mockRejectedValueOnce(new Error('An error occurred'));
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+
+ expect(
+ getByText(
+ 'Error encountered while fetching information. An error occurred',
+ ),
+ ).toBeInTheDocument();
+ });
+ it('opens the dialog when trigger button is clicked', async () => {
+ mockPagerDutyApi.getServiceByIntegrationKey = jest
+ .fn()
+ .mockImplementationOnce(async () => [service]);
+
+ const { getByText, queryByTestId, getByTestId, getByRole } = render(
+ wrapInTestApp(
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(getByText('View in PagerDuty')).toBeInTheDocument();
+ expect(getByText('Trigger Alarm')).toBeInTheDocument();
+ const triggerButton = getByTestId('trigger-button');
+ await act(async () => {
+ fireEvent.click(triggerButton);
+ });
+ expect(getByRole('dialog')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
index 7e26985136..440621dcf6 100644
--- a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
+++ b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
@@ -25,9 +25,9 @@ import {
identityApiRef,
} from '@backstage/core';
import { pagerDutyApiRef } from '../../api';
-import { TriggerButton } from '../TriggerButton';
import { Entity } from '@backstage/catalog-model';
import { act } from 'react-dom/test-utils';
+import { TriggerDialog } from './TriggerDialog';
describe('TriggerDialog', () => {
const mockIdentityApi: Partial = {
@@ -36,7 +36,7 @@ describe('TriggerDialog', () => {
const mockTriggerAlarmFn = jest.fn();
const mockPagerDutyApi = {
- triggerPagerDutyAlarm: mockTriggerAlarmFn,
+ triggerAlarm: mockTriggerAlarmFn,
};
const apis = ApiRegistry.from([
@@ -63,24 +63,25 @@ describe('TriggerDialog', () => {
},
};
- const { getByText, getByRole, queryByRole, getByTestId } = render(
+ const { getByText, getByRole, getByTestId } = render(
wrapInTestApp(
-
+ {}}
+ name={entity.metadata.name}
+ integrationKey="abc123"
+ setShouldRefreshIncidents={() => {}}
+ />
,
),
);
- expect(queryByRole('dialog')).toBeNull();
- const alarmButton = getByText('Trigger Alarm');
- fireEvent.click(alarmButton);
+
expect(getByRole('dialog')).toBeInTheDocument();
expect(
- getByText(
- 'This action will send PagerDuty alarms and notifications to on-call people responsible for',
- {
- exact: false,
- },
- ),
+ getByText('This action will trigger an incident for ', {
+ exact: false,
+ }),
).toBeInTheDocument();
const input = getByTestId('trigger-input');
const description = 'Test Trigger Alarm';