Skip to content

Commit

Permalink
feat(DTFS2-7049): test unknown Gov.UK Notify responses
Browse files Browse the repository at this point in the history
  • Loading branch information
avaitonis committed May 31, 2024
1 parent 8acb0e9 commit 8f2f357
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 8 deletions.
34 changes: 31 additions & 3 deletions src/helper-modules/govuk-notify/govuk-notify.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('GovukNotifyService', () => {
});

describe('sendEmail', () => {
const generateNotifyError = (status: number, message: string) => {
const generateNotifyError = (status: number, message?: string) => {
const response = {
data: {
status_code: status,
Expand Down Expand Up @@ -96,8 +96,15 @@ describe('GovukNotifyService', () => {
error: 'Internal Server Error',
status: 500,
},
{
exceptionClass: InternalServerErrorException,
exceptionName: 'Internal Server Error Exception',
error: 'Internal Server Error',
status: 500,
},
])('throws exception $exceptionName for unexpected $status', async ({ exceptionClass, exceptionName, error, status }) => {
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(generateNotifyError(status, errorMessage)));
const notifyError = generateNotifyError(status, errorMessage);
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(notifyError));

const resultPromise = service.sendEmail(govUkNotifyKey, { sendToEmailAddress, templateId, personalisation });

Expand All @@ -106,18 +113,37 @@ describe('GovukNotifyService', () => {
await expect(resultPromise).rejects.toThrow(exceptionName);
await expect(resultPromise).rejects.toHaveProperty('status', status);
await expect(resultPromise).rejects.toHaveProperty('response', { message: [errorMessage], error, statusCode: status });
expect(loggerError).toHaveBeenCalledTimes(1);
expect(loggerError).toHaveBeenCalledWith(notifyError);
});

it('throws generic Error exception for unexpected status', async () => {
const unexpectedStatus = valueGenerator.integer({ min: 900, max: 999 });
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(generateNotifyError(unexpectedStatus, errorMessage)));
const notifyError = generateNotifyError(unexpectedStatus, errorMessage);
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(notifyError));

const resultPromise = service.sendEmail(govUkNotifyKey, { sendToEmailAddress, templateId, personalisation });

expect(sendEmailMethodMock).toHaveBeenCalledTimes(1);
await expect(resultPromise).rejects.toBeInstanceOf(Error);
await expect(resultPromise).rejects.toThrow(errorMessage);
await expect(resultPromise).rejects.toHaveProperty('message', errorMessage);
expect(loggerError).toHaveBeenCalledTimes(1);
expect(loggerError).toHaveBeenCalledWith(notifyError);
});

it('throws generic Error exception for error without error message', async () => {
const notifyError = generateNotifyError(400);
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(notifyError));

const resultPromise = service.sendEmail(govUkNotifyKey, { sendToEmailAddress, templateId, personalisation });

expect(sendEmailMethodMock).toHaveBeenCalledTimes(1);
await expect(resultPromise).rejects.toBeInstanceOf(Error);
await expect(resultPromise).rejects.toThrow('NotifyClient failed with unexpected error %o');
await expect(resultPromise).rejects.toHaveProperty('message', 'NotifyClient failed with unexpected error %o');
expect(loggerError).toHaveBeenCalledTimes(1);
expect(loggerError).toHaveBeenCalledWith(notifyError);
});

it('throws exception UnprocessableEntityException for empty response from GOV.UK Notify client', async () => {
Expand All @@ -128,6 +154,8 @@ describe('GovukNotifyService', () => {
expect(sendEmailMethodMock).toHaveBeenCalledTimes(1);
await expect(resultPromise).rejects.toBeInstanceOf(UnprocessableEntityException);
await expect(resultPromise).rejects.toThrow('No GOV.UK Notify response');
expect(loggerError).toHaveBeenCalledTimes(1);
expect(loggerError).toHaveBeenCalledWith('Empty response from GOV.UK Notify');
});
});
});
2 changes: 1 addition & 1 deletion src/helper-modules/govuk-notify/govuk-notify.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class GovukNotifyService {
throw new Error(err.response.data.errors[0].message);
}
} else {
throw new Error(JSON.stringify(err.response.data));
throw new Error('NotifyClient failed with unexpected error %o', err);
}
});

Expand Down
2 changes: 1 addition & 1 deletion src/modules/emails/emails.controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('EmailsController', () => {
const govUkNotifyKey = valueGenerator.string({ length: 10 });

it('returns receipt response for sent email', async () => {
when(emailsServiceSendEmail).calledWith(govUkNotifyKey, request[0]).mockResolvedValueOnce(postEmailsResponse[0]);
when(emailsServiceSendEmail).calledWith(govUkNotifyKey, request).mockResolvedValueOnce(postEmailsResponse[0]);

const response = await controller.postEmail(govUkNotifyKey, request);

Expand Down
21 changes: 18 additions & 3 deletions test/emails/post-emails.api-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,28 @@ describe('POST /emails', () => {
});
});

it('returns a 500 response if the Notify client responds with status 500', async () => {
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(generateNotifyError(500)));
it('returns a 500 response if the Notify client responds with unexpected status', async () => {
const unexpectedStatus = valueGenerator.integer({ min: 900, max: 999 });
const error = generateNotifyError(unexpectedStatus, errorMessage);
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(error));

const { status, body } = await api.post(mdmPath, request, { govUkNotifyKey });

expect(status).toBe(500);
expect(body).toStrictEqual({
expect(body).toMatchObject({
statusCode: 500,
message: 'Internal server error',
});
});

it("returns a 500 response if the Notify client error doesn't have message attribute", async () => {
const error = generateNotifyError(400);
jest.mocked(sendEmailMethodMock).mockImplementation(() => Promise.reject(error));

const { status, body } = await api.post(mdmPath, request, { govUkNotifyKey });

expect(status).toBe(500);
expect(body).toMatchObject({
statusCode: 500,
message: 'Internal server error',
});
Expand Down

0 comments on commit 8f2f357

Please sign in to comment.