Skip to content

Commit

Permalink
PRMP 534 - NACK POC testing (#82)
Browse files Browse the repository at this point in the history
* [PRMP-534] Removed unused gender-code function

* [PRMP-534] unit testing for negative acknowledgement sending

---------

Co-authored-by: Andy Flint <[email protected]>
  • Loading branch information
AndyFlintNHS and AndyFlintAnswerDigital authored Jul 25, 2024
1 parent c215df0 commit 6b42396
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { buildEhrAcknowledgementPayload } from '../../../templates/generate-ehr-
import { getPracticeAsid } from '../../../services/fhir/sds-fhir-client';
import { sendMessage } from '../../../services/mhs/mhs-outbound-client';
import { logError, logInfo } from '../../../middleware/logging';
import {AcknowledgementErrorCode} from "../../../constants/enums";

jest.mock('../../../middleware/logging');
jest.mock('../../../middleware/auth');
Expand Down Expand Up @@ -46,6 +47,8 @@ describe('POST /health-record-requests/{conversation-id}/acknowledgement', () =>
const message = 'fake-acknowledgement-message';
const repositoryAsid = '200000001162';
const practiceAsid = '200000001163';
const errorCode = AcknowledgementErrorCode.ERROR_CODE_06.errorCode;
const errorDisplayName = AcknowledgementErrorCode.ERROR_CODE_06.errorDisplayName;
const ackParametersUsingConversationIdAsAckMessageId = {
acknowledgementMessageId: conversationId,
receivingAsid: practiceAsid,
Expand All @@ -56,7 +59,7 @@ describe('POST /health-record-requests/{conversation-id}/acknowledgement', () =>
describe('sendEhrAcknowledgement', () => {
getPracticeAsid.mockReturnValue(practiceAsid);

it('should return a 204 status code and build ack with necessary params including using conversationID as unique ackMessageId and sent EHR core messageId as acknowledged message id', done => {
it('should return a 204 status code and build positive ack with necessary params including using conversationID as unique ackMessageId and sent EHR core messageId as acknowledged message id', done => {
request(app)
.post(`/health-record-requests/${nhsNumber}/acknowledgement`)
.send({
Expand All @@ -78,6 +81,32 @@ describe('POST /health-record-requests/{conversation-id}/acknowledgement', () =>
.end(done);
});

it('should return a 204 status code and build negative ack with necessary params including using conversationID as unique ackMessageId and sent EHR core messageId as acknowledged message id', done => {
request(app)
.post(`/health-record-requests/${nhsNumber}/acknowledgement`)
.send({
conversationId,
messageId: ehrCoreMessageId,
odsCode,
repositoryAsid,
errorCode,
errorDisplayName
})
.expect(204)
.expect(() => {
expect(getPracticeAsid).toHaveBeenCalledWith(odsCode, serviceId);
expect(buildEhrAcknowledgementPayload).toHaveBeenCalledWith({
acknowledgementMessageId: conversationId,
receivingAsid: practiceAsid,
sendingAsid: repositoryAsid,
acknowledgedMessageId: ehrCoreMessageId,
errorCode,
errorDisplayName
});
})
.end(done);
});

it('should accept a messageId with uuidv4', done => {
request(app)
.post(`/health-record-requests/${nhsNumber}/acknowledgement`)
Expand Down
5 changes: 5 additions & 0 deletions src/constants/enums.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const AcknowledgementErrorCode = {
ERROR_CODE_06: { errorCode: '06', errorDisplayName: 'Patient not at surgery.' },
ERROR_CODE_30: { errorCode: '30', errorDisplayName: 'Large Message general failure' },
ERROR_CODE_99: { errorCode: '99', errorDisplayName: 'Unexpected condition.' }
}
85 changes: 69 additions & 16 deletions src/templates/__tests__/generate-ehr-acknowledgement.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,91 @@ import dateFormat from 'dateformat';
import testData from './testData.json';
import { buildEhrAcknowledgementPayload } from '../generate-ehr-acknowledgement';
import { XmlParser } from '../../services/parser/xml-parser/xml-parser';
import { AcknowledgementErrorCode } from '../../constants/enums';

function parse(payload) {
return new XmlParser().parse(payload);
}

describe('generateEhrAcknowledgement', () => {
it('should return the acknowledgement message template with correct values populated', async () => {
const parameters = {
acknowledgementMessageId: '11111111-28C0-41EB-ADC1-0242AC120002',
receivingAsid: testData.emisPractise.asid,
sendingAsid: testData.mhs.asid,
acknowledgedMessageId: '22222222-28C0-41EB-ADC1-0242AC120002'
};
// ============ COMMON PROPERTIES ============
const ACKNOWLEDGEMENT_MESSAGE_ID = '11111111-28C0-41EB-ADC1-0242AC120002';
const RECEIVING_ASID = testData.emisPractise.asid;
const SENDING_ASID = testData.mhs.asid;
const ACKNOWLEDGED_MESSAGE_ID = '22222222-28C0-41EB-ADC1-0242AC120002';
// =================== END ===================

it('should return a positive acknowledgement message template with correct values populated', async () => {
const timestamp = dateFormat(Date.now(), 'yyyymmddHHMMss');
const payload = buildEhrAcknowledgementPayload(parameters);
const payload = buildEhrAcknowledgementPayload({
acknowledgementMessageId: ACKNOWLEDGEMENT_MESSAGE_ID,
receivingAsid: RECEIVING_ASID,
sendingAsid: SENDING_ASID,
acknowledgedMessageId: ACKNOWLEDGED_MESSAGE_ID
});

const ack = (await new XmlParser().parse(payload)).data.MCCI_IN010000UK13;

expect(ack.id).toEqual({ root: parameters.acknowledgementMessageId });
expect(ack.acknowledgement.messageRef.id).toEqual({ root: parameters.acknowledgedMessageId });
expect(ack.id.root).toEqual(ACKNOWLEDGEMENT_MESSAGE_ID);
expect(ack.acknowledgement.messageRef.id.root).toEqual(ACKNOWLEDGED_MESSAGE_ID);
expect(ack.acknowledgement.typeCode).toEqual('AA');
expect(ack.acknowledgement.acknowledgementDetail).toBeUndefined();
expect(ack.ControlActEvent.reason).toBeUndefined();

expect(payload).toContain(parameters.sendingAsid);
expect(payload).toContain(parameters.receivingAsid);
expect(payload).toContain(SENDING_ASID);
expect(payload).toContain(RECEIVING_ASID);
expect(payload).toContain(timestamp);
});

it.each([
[
'AR',
AcknowledgementErrorCode.ERROR_CODE_06.errorCode,
AcknowledgementErrorCode.ERROR_CODE_06.errorDisplayName
],
[
'AE',
AcknowledgementErrorCode.ERROR_CODE_99.errorCode,
AcknowledgementErrorCode.ERROR_CODE_99.errorDisplayName
]
])(
'should return a negative acknowledgement message template with correct values populated',
async (typeCode, errorCode, errorDisplayName) => {
const timestamp = dateFormat(Date.now(), 'yyyymmddHHMMss');
const payload = buildEhrAcknowledgementPayload({
acknowledgementMessageId: ACKNOWLEDGEMENT_MESSAGE_ID,
receivingAsid: RECEIVING_ASID,
sendingAsid: SENDING_ASID,
acknowledgedMessageId: ACKNOWLEDGED_MESSAGE_ID,
errorCode,
errorDisplayName
});

const ack = (await new XmlParser().parse(payload)).data.MCCI_IN010000UK13;

expect(ack.id.root).toEqual(ACKNOWLEDGEMENT_MESSAGE_ID);
expect(ack.acknowledgement.typeCode).toEqual(typeCode);
expect(ack.acknowledgement.acknowledgementDetail.typeCode).toEqual(typeCode);
expect(ack.acknowledgement.acknowledgementDetail.code.code).toEqual(errorCode);
expect(ack.acknowledgement.acknowledgementDetail.code.displayName).toEqual(errorDisplayName);
expect(ack.acknowledgement.messageRef.id.root).toEqual(ACKNOWLEDGED_MESSAGE_ID);
expect(ack.ControlActEvent.reason.justifyingDetectedIssueEvent.code.code).toEqual(errorCode);
expect(ack.ControlActEvent.reason.justifyingDetectedIssueEvent.code.displayName).toEqual(
errorDisplayName
);

expect(payload).toContain(SENDING_ASID);
expect(payload).toContain(RECEIVING_ASID);
expect(payload).toContain(timestamp);
}
);

it('should populate the acknowledgement message forcing message IDs to uppercase', async () => {
const parameters = {
acknowledgementMessageId: '11111111-28c0-41eb-adc1-0242ac120002',
receivingAsid: testData.emisPractise.asid,
sendingAsid: testData.mhs.asid,
acknowledgedMessageId: '22222222-28c0-41eb-adc1-0242ac120002'
acknowledgementMessageId: ACKNOWLEDGEMENT_MESSAGE_ID,
receivingAsid: RECEIVING_ASID,
sendingAsid: SENDING_ASID,
acknowledgedMessageId: ACKNOWLEDGED_MESSAGE_ID
};
const payload = buildEhrAcknowledgementPayload(parameters);

Expand Down
5 changes: 3 additions & 2 deletions src/templates/generate-ehr-acknowledgement.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dateFormat from 'dateformat';
import { logInfo } from '../middleware/logging';
import { AcknowledgementErrorCode } from '../constants/enums';

export const buildEhrAcknowledgementPayload = ({
acknowledgementMessageId,
Expand All @@ -22,8 +23,8 @@ export const buildEhrAcknowledgementPayload = ({
receivingAsid,
sendingAsid
});
case '30': // negative ACK, unknown failure reason
case '99': // negative ACK, unknown failure reason
case AcknowledgementErrorCode.ERROR_CODE_30.errorCode: // negative ACK, large message general failure, unknown failure reason
case AcknowledgementErrorCode.ERROR_CODE_99.errorCode: // negative ACK, unknown failure reason
logInfo(
`Building negative acknowledgement message with typeCode: AE, errorCode: ${errorCode} and errorDisplayName: ${errorDisplayName}`
);
Expand Down
27 changes: 0 additions & 27 deletions src/templates/utils/__tests__/gender-code.test.js

This file was deleted.

15 changes: 0 additions & 15 deletions src/templates/utils/gender-code.js

This file was deleted.

0 comments on commit 6b42396

Please sign in to comment.