diff --git a/plugins/pagerduty/src/components/Escalation.test.tsx b/plugins/pagerduty/src/components/Escalation.test.tsx
new file mode 100644
index 0000000000..db52e36f4a
--- /dev/null
+++ b/plugins/pagerduty/src/components/Escalation.test.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import { EscalationPolicy } from './Escalation';
+import { wrapInTestApp } from '@backstage/test-utils';
+import { Oncall } from './types';
+
+export const escalations: Oncall[] = [
+ {
+ user: {
+ name: 'person1',
+ id: 'p1',
+ summary: 'person1',
+ email: 'person1@example.com',
+ html_url: 'http://a.com/id1',
+ },
+ },
+];
+
+describe('Escalation', () => {
+ it('render emptyState', () => {
+ const { getByText } = render(
+ wrapInTestApp(),
+ );
+ expect(getByText('Empty escalation policy')).toBeInTheDocument();
+ });
+
+ it('render Escalation list', () => {
+ const { getByText } = render(
+ wrapInTestApp(),
+ );
+ expect(getByText('person1')).toBeInTheDocument();
+ expect(getByText('person1@example.com')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/pagerduty/src/components/Incidents.test.tsx b/plugins/pagerduty/src/components/Incidents.test.tsx
new file mode 100644
index 0000000000..62c8151af2
--- /dev/null
+++ b/plugins/pagerduty/src/components/Incidents.test.tsx
@@ -0,0 +1,71 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import { Incidents } from './Incidents';
+import { wrapInTestApp } from '@backstage/test-utils';
+import { Incident } from './types';
+
+export 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',
+ },
+];
+
+describe('Incidents', () => {
+ it('renders an empty state is there are no incidents', () => {
+ const { getByText } = render(wrapInTestApp());
+ expect(getByText('No incidents')).toBeInTheDocument();
+ });
+
+ it('renders all incidents', () => {
+ const { getByText, getByTitle, getAllByTitle, getByLabelText } = render(
+ wrapInTestApp(),
+ );
+
+ expect(getByText('title1')).toBeInTheDocument();
+ expect(getByText('title2')).toBeInTheDocument();
+ expect(getByText('person1')).toBeInTheDocument();
+ expect(getByText('person2')).toBeInTheDocument();
+ expect(getByTitle('triggered')).toBeInTheDocument();
+ expect(getByTitle('acknowledged')).toBeInTheDocument();
+ expect(getByLabelText('Status error')).toBeInTheDocument();
+ expect(getByLabelText('Status warning')).toBeInTheDocument();
+
+ // assert links, mailto and hrefs, date calculation
+ expect(getAllByTitle('View in PagerDuty').length).toEqual(2);
+ });
+});
diff --git a/plugins/pagerduty/src/components/TriggerDialog.test.tsx b/plugins/pagerduty/src/components/TriggerDialog.test.tsx
new file mode 100644
index 0000000000..a99e2c03f4
--- /dev/null
+++ b/plugins/pagerduty/src/components/TriggerDialog.test.tsx
@@ -0,0 +1,101 @@
+import React from 'react';
+import { render, fireEvent, getByTestId } from '@testing-library/react';
+import { wrapInTestApp } from '@backstage/test-utils';
+import { TriggerDialog } from './TriggerDialog';
+import {
+ ApiRegistry,
+ alertApiRef,
+ createApiRef,
+ ApiProvider,
+ IdentityApi,
+ identityApiRef,
+} from '@backstage/core';
+import { pagerDutyApiRef } from '../api/pagerDutyClient';
+import { TriggerButton } from './TriggerButton';
+import { Entity } from '@backstage/catalog-model';
+import { act } from 'react-dom/test-utils';
+
+describe('TriggerDialog', () => {
+ const mockIdentityApi: Partial = {
+ getUserId: () => 'guest@example.com',
+ };
+
+ const mockTriggerAlarmFn = jest.fn();
+ const mockPagerDutyApi = {
+ triggerPagerDutyAlarm: mockTriggerAlarmFn,
+ };
+
+ const apis = ApiRegistry.from([
+ [
+ alertApiRef,
+ createApiRef({
+ id: 'core.alert',
+ description: 'Used to report alerts and forward them to the app',
+ }),
+ ],
+ [identityApiRef, mockIdentityApi],
+ [pagerDutyApiRef, mockPagerDutyApi],
+ ]);
+
+ it('open the dialog and trigger an alarm', async () => {
+ const onClick = jest.fn(async () => {});
+
+ const entity: Entity = {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ metadata: {
+ name: 'pagerduty-test',
+ annotations: {
+ 'pagerduty.com/integration-key': 'abc123',
+ },
+ },
+ };
+
+ const {
+ getByText,
+ getByRole,
+ queryByText,
+ queryByRole,
+ getByTestId,
+ } = render(
+ wrapInTestApp(
+
+
+ {/* */}
+ ,
+ ),
+ );
+ 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,
+ },
+ ),
+ ).toBeInTheDocument();
+ const input = getByTestId('trigger-input');
+ const description = 'Test Trigger Alarm';
+ await act(async () => {
+ fireEvent.change(input, { target: { value: description } });
+ });
+ const triggerButton = getByTestId('trigger-button');
+ await act(async () => {
+ fireEvent.click(triggerButton);
+ });
+ expect(mockTriggerAlarmFn).toHaveBeenCalled();
+ expect(mockTriggerAlarmFn).toHaveBeenCalledWith(
+ entity!.metadata!.annotations!['pagerduty.com/integration-key'],
+ window.location.toString(),
+ description,
+ 'guest@example.com',
+ );
+ });
+});