From 5519358df8ec1d4d2e39b24d991ec9f110ef92d9 Mon Sep 17 00:00:00 2001 From: Samira Mokaram Date: Fri, 20 Nov 2020 12:05:51 +0100 Subject: [PATCH] update tests --- .../components/Escalation/Escalation.test.tsx | 80 +++++++-- .../components/Incident/Incidents.test.tsx | 151 +++++++++++------ .../src/components/PagerDutyCard.test.tsx | 153 ++++++++++++++++++ .../TriggerDialog/TriggerDialog.test.tsx | 27 ++-- 4 files changed, 335 insertions(+), 76 deletions(-) create mode 100644 plugins/pagerduty/src/components/PagerDutyCard.test.tsx 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';