diff --git a/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx b/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
index 2b309533ed..54b58489be 100644
--- a/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
+++ b/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
@@ -252,4 +252,134 @@ describe('PageDutyCard', () => {
});
expect(getByRole('dialog')).toBeInTheDocument();
});
+
+ describe('when entity has the pagerduty.com/service-id annotation', () => {
+ it('Renders PagerDuty service information', async () => {
+ mockPagerDutyApi.getServiceByServiceId = jest
+ .fn()
+ .mockImplementationOnce(async () => service);
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(getByText('Service Directory')).toBeInTheDocument();
+ expect(getByText('Create Incident')).toBeInTheDocument();
+ expect(getByText('Nice! No incidents found!')).toBeInTheDocument();
+ expect(getByText('Empty escalation policy')).toBeInTheDocument();
+ });
+
+ it('Handles custom error for missing token', async () => {
+ mockPagerDutyApi.getServiceByServiceId = jest
+ .fn()
+ .mockRejectedValueOnce(new UnauthorizedError());
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(
+ getByText('Missing or invalid PagerDuty Token'),
+ ).toBeInTheDocument();
+ });
+
+ it('Handles custom NotFoundError', async () => {
+ mockPagerDutyApi.getServiceByServiceId = jest
+ .fn()
+ .mockRejectedValueOnce(new NotFoundError());
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(getByText('PagerDuty Service Not Found')).toBeInTheDocument();
+ });
+
+ it('handles general error', async () => {
+ mockPagerDutyApi.getServiceByServiceId = 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('disables the Create Incident button', async () => {
+ mockPagerDutyApi.getServiceByServiceId = jest
+ .fn()
+ .mockImplementationOnce(async () => service);
+
+ const { queryByTestId, getByTitle } = render(
+ wrapInTestApp(
+
+
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(queryByTestId('trigger-dialoger')).not.toBeInTheDocument();
+ expect(
+ getByTitle('Must provide an integration-key to create incidents')
+ .className,
+ ).toMatch('disabled');
+ });
+ });
+
+ describe('when entity has all annotations', () => {
+ it('queries by integration key', async () => {
+ mockPagerDutyApi.getServiceByIntegrationKey = jest
+ .fn()
+ .mockImplementationOnce(async () => [service]);
+ mockPagerDutyApi.getServiceByServiceId = jest.fn();
+
+ const { getByText, queryByTestId } = render(
+ wrapInTestApp(
+
+
+
+
+ ,
+ ),
+ );
+ await waitFor(() => !queryByTestId('progress'));
+ expect(mockPagerDutyApi.getServiceByServiceId).not.toHaveBeenCalled();
+ expect(getByText('Service Directory')).toBeInTheDocument();
+ expect(getByText('Create Incident')).toBeInTheDocument();
+ expect(getByText('Nice! No incidents found!')).toBeInTheDocument();
+ expect(getByText('Empty escalation policy')).toBeInTheDocument();
+ });
+ });
});
diff --git a/plugins/pagerduty/src/components/PagerDutyCard/index.tsx b/plugins/pagerduty/src/components/PagerDutyCard/index.tsx
index b4b20fb25b..308d17a08d 100644
--- a/plugins/pagerduty/src/components/PagerDutyCard/index.tsx
+++ b/plugins/pagerduty/src/components/PagerDutyCard/index.tsx
@@ -52,7 +52,7 @@ export const isPluginApplicableToEntity = (entity: Entity) =>
);
export const PagerDutyCard = () => {
- const { integrationKey } = usePagerdutyEntity();
+ const { integrationKey, serviceId } = usePagerdutyEntity();
const api = useApi(pagerDutyApiRef);
const [refreshIncidents, setRefreshIncidents] = useState(false);
const [refreshChangeEvents, setRefreshChangeEvents] =
@@ -77,12 +77,16 @@ export const PagerDutyCard = () => {
error,
} = useAsync(async () => {
let service: Service;
- const services = await api.getServiceByIntegrationKey(
- integrationKey as string,
- );
- service = services[0];
- if (!service) throw new NotFoundError();
+ if (integrationKey) {
+ const services = await api.getServiceByIntegrationKey(
+ integrationKey as string,
+ );
+ service = services[0];
+ if (!service) throw new NotFoundError();
+ } else {
+ service = await api.getServiceByServiceId(serviceId);
+ }
return {
id: service.id,
@@ -128,11 +132,21 @@ export const PagerDutyCard = () => {
icon: ,
};
+ /**
+ * In order to create incidents using the REST API, a valid user email address must be present.
+ * There is no guarantee the current user entity has a valid email association, so instead just
+ * only allow triggering incidents when an integration key is present.
+ */
+ const createIncidentDisabled = !integrationKey;
const triggerLink: IconLinkVerticalProps = {
label: 'Create Incident',
onClick: showDialog,
icon: ,
color: 'secondary',
+ disabled: createIncidentDisabled,
+ title: createIncidentDisabled
+ ? 'Must provide an integration-key to create incidents'
+ : '',
};
const escalationPolicyLink: IconLinkVerticalProps = {
@@ -171,12 +185,14 @@ export const PagerDutyCard = () => {
-
+ {!createIncidentDisabled && (
+
+ )}
>
);
};