feat(plugins/pagerduty): lookup by service-id if that is available
* prefer integration-key value over service-id * disable creation of incidents if integration-key is not available Signed-off-by: Alec Jacobs <cajacobs5401@gmail.com>
This commit is contained in:
@@ -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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityWithServiceId}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityWithServiceId}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityWithServiceId}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityWithServiceId}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entityWithServiceId}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityProvider entity={entity}>
|
||||
<PagerDutyCard />
|
||||
</EntityProvider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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<boolean>(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: <WebIcon />,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: <AlarmAddIcon />,
|
||||
color: 'secondary',
|
||||
disabled: createIncidentDisabled,
|
||||
title: createIncidentDisabled
|
||||
? 'Must provide an integration-key to create incidents'
|
||||
: '',
|
||||
};
|
||||
|
||||
const escalationPolicyLink: IconLinkVerticalProps = {
|
||||
@@ -171,12 +185,14 @@ export const PagerDutyCard = () => {
|
||||
<EscalationPolicy policyId={service!.policyId} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<TriggerDialog
|
||||
data-testid="trigger-dialog"
|
||||
showDialog={dialogShown}
|
||||
handleDialog={hideDialog}
|
||||
onIncidentCreated={handleRefresh}
|
||||
/>
|
||||
{!createIncidentDisabled && (
|
||||
<TriggerDialog
|
||||
data-testid="trigger-dialog"
|
||||
showDialog={dialogShown}
|
||||
handleDialog={hideDialog}
|
||||
onIncidentCreated={handleRefresh}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user