Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PRMT-4116 #61

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/api/__tests__/health.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ jest.mock('../../middleware/logging');
// Mocked so need to get real for expectedHealthCheckBase ??
describe('GET /health', () => {
it('should return 200 and the response from getHealthCheck', done => {
getHealthCheck.mockReturnValue(Promise.resolve(expectedHealthCheckBase(true)));
getHealthCheck.mockReturnValue(Promise.resolve(expectedHealthCheckBase()));

request(app)
.get('/health')
.expect(200)
.expect(res => {
expect(res.body).toEqual(expectedHealthCheckBase(true));
expect(res.body).toEqual(expectedHealthCheckBase());
})
.end(done);
});

it('should call health check service with no parameters', done => {
getHealthCheck.mockReturnValue(Promise.resolve(expectedHealthCheckBase(true)));
getHealthCheck.mockReturnValue(Promise.resolve(expectedHealthCheckBase()));

request(app)
.get('/health')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,27 @@ describe('POST /health-record-requests/:nhsNumber', () => {
});

describe('ODS code safe list', () => {
it('should return 422 status if ods code is not safe listed', done => {
it('should return 422 status if ods code is not in the safe list array', done => {
initializeConfig.mockReturnValueOnce({
requestEhrOnlyForSafeListedOdsCodesToggle: true,
safeListedOdsCodes: ['SAFE08', 'SAFE09'],
nhsNumberPrefix: '123'
});
request(app)
.post('/health-record-requests/1234567890')
.expect(res => {
expect(res.status).toEqual(422);
expect(res.body).toEqual(
expect.objectContaining({
errors: 'The ODS code provided is not safe listed.'
})
);
})
.send(body)
.end(done);
});

it('should return 422 status if ods code is not in safe list consisting of one string', done => {
initializeConfig.mockReturnValueOnce({
requestEhrOnlyForSafeListedOdsCodesToggle: true,
safeListedOdsCodes: 'SAFE09',
Expand All @@ -184,7 +204,16 @@ describe('POST /health-record-requests/:nhsNumber', () => {
.end(done);
});

it('should return 204 status if ods code is safe listed', done => {
it('should return 204 status if ods code is in the safe list array', done => {
initializeConfig.mockReturnValueOnce({
requestEhrOnlyForSafeListedOdsCodesToggle: true,
safeListedOdsCodes: ['SAFE08', 'practice_ods_code'],
nhsNumberPrefix: '123'
});
request(app).post('/health-record-requests/1234567890').expect(204).send(body).end(done);
});

it('should return 204 status if ods code is in the safe list consisting of one string', done => {
initializeConfig.mockReturnValueOnce({
requestEhrOnlyForSafeListedOdsCodesToggle: true,
safeListedOdsCodes: 'practice_ods_code',
Expand Down
15 changes: 10 additions & 5 deletions src/api/health-record-requests/health-record-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,14 @@ const odsCodeNotInSafeList = (
logInfo(
'process only safe listed ODS code toggle is : ' + requestEhrOnlyForSafeListedOdsCodesToggle
);
if (requestEhrOnlyForSafeListedOdsCodesToggle) {
const caseInsensitiveOdsCode = new RegExp(practiceOdsCode, 'i');
return !caseInsensitiveOdsCode.test(safeListedOdsCodes);
}
return false;
if (!requestEhrOnlyForSafeListedOdsCodesToggle) return false;

return Array.isArray(safeListedOdsCodes)
? !safeListedOdsCodes.some(safeListedOdsCode =>
compareOdsCodesCaseInsensitive(safeListedOdsCode, practiceOdsCode)
)
: !compareOdsCodesCaseInsensitive(safeListedOdsCodes, practiceOdsCode);
};

const compareOdsCodesCaseInsensitive = (odsCode1, odsCode2) =>
odsCode1.toLowerCase() === odsCode2.toLowerCase();
2 changes: 1 addition & 1 deletion src/api/health-record-requests/send-continue-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const sendContinueMessage = async (req, res) => {

try {
const practiceAsid = await getPracticeAsid(gpOdsCode, serviceId);
const message = await generateContinueRequest({
const message = generateContinueRequest({
messageId,
receivingAsid: practiceAsid,
sendingAsid: config.repoAsid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const sendEhrAcknowledgement = async (req, res) => {
const practiceAsid = await getPracticeAsid(odsCode, serviceId);
setCurrentSpanAttributes({ conversationId, messageId: ehrCoreMessageId });

const message = await buildEhrAcknowledgementPayload({
const message = buildEhrAcknowledgementPayload({
acknowledgementMessageId: conversationId,
receivingAsid: practiceAsid,
sendingAsid: repositoryAsid,
Expand Down
2 changes: 1 addition & 1 deletion src/middleware/__tests__/logging.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('logging', () => {
};

eventFinished(mockReq, mockRes);
expect(logger.info).toBeCalledTimes(1);
expect(logger.info).toBeCalledTimes(2);
});

it('should log with level error if status code is not successful', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/middleware/logging.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const logError = (status, error) => logger.error(status, { error });

export const logWarning = status => logger.warn(status);

export const logInfo = status => logger.info(status);
export const logInfo = (...logs) => logs.forEach(log => logger.info(log));

export const logDebug = status => logger.debug(status);

Expand Down
4 changes: 2 additions & 2 deletions src/services/health-check/__tests__/get-health-check.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ describe('get-health-check', () => {
describe('getHealthCheck', () => {
it('should resolve when both checks are ok', () => {
return getHealthCheck().then(result => {
return expect(result).toStrictEqual(expectedHealthCheckBase(true));
return expect(result).toStrictEqual(expectedHealthCheckBase());
});
});

it('should resolve when MHS is not ok', () => {
return getHealthCheck().then(result => {
return expect(result).toStrictEqual(expectedHealthCheckBase(false));
return expect(result).toStrictEqual(expectedHealthCheckBase());
});
});
});
Expand Down
17 changes: 15 additions & 2 deletions src/services/mhs/__tests__/mhs-outbound-client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import generatePdsRetrievalQuery from '../../../templates/generate-pds-retrieval
import testData from '../../../templates/__tests__/testData.json';
import { sendMessage, stripXMLMessage } from '../mhs-outbound-client';
import { sendToQueue } from '../../sqs/sqs-client';
import expect from 'expect';

jest.mock('axios');
jest.mock('../../../config/logging');
Expand Down Expand Up @@ -366,9 +367,21 @@ describe('stripXMLMessage', () => {
expect(stripXMLMessage(pdsRetrievalQuery).match(/> +</g)).toBe(null);
});

it('should trim the message', async () => {
it('should trim the whitespace at the beginning and end of the message', async () => {
// given
const pdsRetrievalQuery = await generatePdsRetrievalQuery(pdsQueryArguments);
expect(stripXMLMessage(` ${pdsRetrievalQuery} `).match(/^ +| +$/)).toBe(null);
const XMLWithLeadingAndTrailingWhitespace = ` ${pdsRetrievalQuery} `;
// identifies trailing whitespace, content, and leading whitespace in 3 capture groups
const whitespaceRegex = '^(s*)(.*?)(s*)$';

// when
const strippedXML = stripXMLMessage(XMLWithLeadingAndTrailingWhitespace);
const regexMatches = strippedXML.match(whitespaceRegex);

// then
expect(regexMatches[1]).toBe('');
expect(regexMatches[2]).not.toBe(''); // should be pdsRetrievalQuery with new lines stripped
expect(regexMatches[3]).toBe('');
});

it('should remove new lines (/n) and carriage return characters (/r)', async () => {
Expand Down
14 changes: 12 additions & 2 deletions src/services/parser/xml-parser/xml-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,30 @@ XmlParser.prototype.findFirst = function (key) {
return foundAll[0];
};

/**
* recursively search the XML to find a key (to a maximum depth), all values that are found will be returned as an array
*/
const searchData = (object, key, maxDepth, found = []) => {
let param;

// if we've recursed deeply enough for maxDepth to have been reached, return
if (maxDepth-- === 0) {
return found;
}

// if we've found the key we're looking for, add the associated value(s) to 'found'
if (key in object) {
Array.isArray(object[key]) ? found.push(...object[key]) : found.push(object[key]);
const value = object[key];

Array.isArray(value)
? found.push(...value)
: found.push(value);
}

// for each child node of this one, recurse
for (param in object) {
if (Object.prototype.hasOwnProperty.call(object, param) && typeof object[param] === 'object') {
found.concat(searchData(object[param], key, maxDepth, found));
searchData(object[param], key, maxDepth, found);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/services/pds/pds-response-handler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { extractPdsId } from '../parser/pds';
import { extractSerialChangeNumber } from '../parser/pds';
import { extractPdsId, extractSerialChangeNumber } from '../parser/pds';
import { extractOdsCode } from '../parser/pds/extract-ods-code';

export const handlePdsResponse = async message => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('generatePdsRetrievalQuery', () => {
const pdsRequestQuery = await generatePdsRetrievalQuery(testObjectComplete);

const checkEntries = object => {
Object.keys(object).map(key => {
Object.keys(object).forEach(key => {
if (typeof object[key] === 'object') {
checkEntries(object[key]);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/templates/generate-update-ods-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const template = ({
timestamp,
receivingService: { asid: receivingAsid },
sendingService: { asid: sendingAsid },
newOdsCode: newOdsCode,
newOdsCode,
patient: { nhsNumber, pdsId, pdsUpdateChangeNumber }
}) =>
`
Expand Down
6 changes: 3 additions & 3 deletions src/templates/utils/check_params.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const recursiveTemplateCheck = (inputObject, maxDepth = 10, errorMessages) => {
const recursiveTemplateCheck = (inputObject, errorMessages, maxDepth = 10) => {
if (maxDepth-- === 0) {
throw new Error('maxDepth reached, exiting');
}
Expand All @@ -12,14 +12,14 @@ const recursiveTemplateCheck = (inputObject, maxDepth = 10, errorMessages) => {
errorMessages.push(` ${key} is undefined`);
}
if (typeof inputObject[key] === 'object') {
recursiveTemplateCheck(inputObject[key], maxDepth, errorMessages);
recursiveTemplateCheck(inputObject[key], errorMessages, maxDepth);
}
});
};

const checkTemplateArguments = (inputObject, maxDepth) => {
const errorMessages = [];
recursiveTemplateCheck(inputObject, maxDepth, errorMessages);
recursiveTemplateCheck(inputObject, errorMessages, maxDepth);
if (errorMessages.length > 0) throw new Error(`Check template parameter error:${errorMessages}`);
};

Expand Down
123 changes: 0 additions & 123 deletions utils/generate-messages.js

This file was deleted.