From 1599e0043c2836f804d014bedc40e9af447947a5 Mon Sep 17 00:00:00 2001 From: Phil Gee Date: Wed, 10 Jul 2024 16:14:52 +0000 Subject: [PATCH 1/4] AEA-4190 First implementation. --- .devcontainer/devcontainer.json | 2 +- ...scription-status-update-api.code-workspace | 17 +++++++++++ .../src/validation/content.ts | 30 +++++++++++++++++++ .../tests/utils/nhsNumber.ts | 6 ++-- .../testRequestContentValidation.test.ts | 26 +++++++++++++++- 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e20876250..71ffa9ec4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -43,7 +43,7 @@ "python.analysis.extraPaths": [], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, - "python.linting.pylintEnabled": false, + "pylint.enabled": false, "python.linting.flake8Enabled": true, "python.linting.enabled": true, // required to format on save "editor.defaultFormatter": "rvest.vs-code-prettier-eslint", diff --git a/.vscode/eps-prescription-status-update-api.code-workspace b/.vscode/eps-prescription-status-update-api.code-workspace index adfbf1377..07253fd63 100644 --- a/.vscode/eps-prescription-status-update-api.code-workspace +++ b/.vscode/eps-prescription-status-update-api.code-workspace @@ -66,9 +66,14 @@ "Codeable", "codeinline", "codesystem", + "cpsu", + "dbaeumer", "devcontainer", + "direnv", + "eamodio", "eps-prescription-status-update-api", "esbuild", + "excelviewer", "fhir", "Formik", "Fulfillment", @@ -78,34 +83,46 @@ "Helpdesk", "homecare", "HSCN", + "kohler", "liter", + "mermade", "milliliter", + "mkhl", "nHSCHI", "NHSD", "nhsdlogin", "nhslogin", "NOSONAR", "OIDC", + "openapi", + "orta", "Orthoptist", "Payor", "pino", "pollable", "powertools", + "pratica", "Prosthetist", + "pylint", + "pytest", "querystring", "reingest", "reingested", "Reingestion", + "rvest", "serialisation", + "shellcheck", "smartcard", "smartcards", "Snomed", "sourcetype", + "timonwong", "Truststore", "URID", "URPID", "uuidv4", "vars", + "venv", "versionable", "whens" ], diff --git a/packages/updatePrescriptionStatus/src/validation/content.ts b/packages/updatePrescriptionStatus/src/validation/content.ts index 2b10415e3..1abf21432 100644 --- a/packages/updatePrescriptionStatus/src/validation/content.ts +++ b/packages/updatePrescriptionStatus/src/validation/content.ts @@ -74,6 +74,36 @@ export function nhsNumber(task: Task): string | undefined { return validateNhsNumber(nhsNumber) ? undefined : message } +export function nhsNumberRange(task: Task): string | undefined { + type Range = {low: number; high: number; description?: string} + + const validRanges: Array = [ + {low: 3_113_000_000, high: 4_999_999_999}, + {low: 6_000_000_000, high: 7_999_999_999} + ] + + const nhsNumber = Number(task.for?.identifier?.value) + for (const range of validRanges) { + if (range.low <= nhsNumber && nhsNumber <= range.high) { + return undefined + } + } + + const invalidRanges: Array = [ + {low: 101_000_000, high: 320_000_000, description: "Scottish"}, + {low: 320_000_001, high: 399_999_999, description: "Northern Irish"}, + {low: 400_000_000, high: 3_112_999_999, description: "Scottish"} + ] + + for (const range of invalidRanges) { + if (range.low <= nhsNumber && nhsNumber <= range.high) { + return `NHS number is in the ${range.description} range.` + } + } + + return "NHS number is not in a known, valid range." +} + export function resourceType(task: Task): string | undefined { const message = "Resource's resourceType is not 'Task'." const isTask = task.resourceType === "Task" diff --git a/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts b/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts index 1e66f230e..3fb450e4d 100644 --- a/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts +++ b/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts @@ -3,10 +3,10 @@ import {faker} from "@faker-js/faker" import {calculateCheckDigit} from "../../src/utils/nhsNumber" -export function generateValidNhsNumbers(num: number) { +export function generateValidNhsNumbers(num: number, min: number = 100_000_000, max: number = 999_999_999) { const numbers: Array = [] while (numbers.length < num) { - const numString = faker.number.int({min: 100000000, max: 999999999}).toString() + const numString = faker.number.int({min: min, max: max}).toString() let checkDigit = calculateCheckDigit(numString) if (checkDigit === 11) { @@ -23,7 +23,7 @@ export function generateValidNhsNumbers(num: number) { export function generateInvalidNhsNumbers(num: number) { const numbers: Array = [] while (numbers.length < num) { - const numString = faker.number.int({min: 100000000, max: 999999999}).toString() + const numString = faker.number.int({min: 100_000_000, max: 999_999_999}).toString() const checkDigit = calculateCheckDigit(numString) const invalidCheckDigit = (checkDigit + 1) % 10 diff --git a/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts b/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts index eb7b3069d..d9c175b85 100644 --- a/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts +++ b/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts @@ -23,7 +23,8 @@ import { validateEntry, ValidationOutcome, validateContent, - entryContent + entryContent, + nhsNumberRange } from "../../src/validation/content" import {generateInvalidNhsNumbers, generateValidNhsNumbers} from "../utils/nhsNumber" @@ -210,6 +211,29 @@ describe("Unit tests for validation of NHS number", () => { }) }) +describe("Unit tests for validation of NHS number range", () => { + it.each([ + { + nhsNumbers: [101_000_000, 311_299_9999], + expected: "NHS number is in the Scottish range.", + scenarioDescription: "When NHS number is in the Scottish range, should return expected issue." + }, + { + nhsNumbers: [320_000_001, 399_999_999], + expected: "NHS number is in the Northern Irish range.", + scenarioDescription: "When NHS number is in the Northern Irish range, should return expected issue." + } + ])("$scenarioDescription", async ({nhsNumbers, expected}) => { + for (const _nhsNumber of nhsNumbers) { + const task = {for: {identifier: {value: String(_nhsNumber)}}} + + const actual = nhsNumberRange(task as Task) + + expect(actual).toEqual(expected) + } + }) +}) + describe("Unit tests for validation of status against business status", () => { describe("When task status is 'completed'", () => { it.each([ From 44c908658296f35c9408ab940a248e71cebddde4 Mon Sep 17 00:00:00 2001 From: Phil Gee Date: Thu, 11 Jul 2024 11:19:37 +0000 Subject: [PATCH 2/4] AEA-4190 Corrections for inclusion of check digit. --- .../eps-prescription-status-update-api.code-workspace | 1 + .../src/validation/content.ts | 8 ++++---- .../validation/testRequestContentValidation.test.ts | 11 ++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.vscode/eps-prescription-status-update-api.code-workspace b/.vscode/eps-prescription-status-update-api.code-workspace index 07253fd63..b16ce7f1a 100644 --- a/.vscode/eps-prescription-status-update-api.code-workspace +++ b/.vscode/eps-prescription-status-update-api.code-workspace @@ -91,6 +91,7 @@ "nHSCHI", "NHSD", "nhsdlogin", + "NHSE", "nhslogin", "NOSONAR", "OIDC", diff --git a/packages/updatePrescriptionStatus/src/validation/content.ts b/packages/updatePrescriptionStatus/src/validation/content.ts index 1abf21432..2e431126b 100644 --- a/packages/updatePrescriptionStatus/src/validation/content.ts +++ b/packages/updatePrescriptionStatus/src/validation/content.ts @@ -78,7 +78,8 @@ export function nhsNumberRange(task: Task): string | undefined { type Range = {low: number; high: number; description?: string} const validRanges: Array = [ - {low: 3_113_000_000, high: 4_999_999_999}, + {low: 3_113_000_000, high: 3_200_000_000}, + {low: 4_000_000_000, high: 4_999_999_999}, {low: 6_000_000_000, high: 7_999_999_999} ] @@ -90,9 +91,8 @@ export function nhsNumberRange(task: Task): string | undefined { } const invalidRanges: Array = [ - {low: 101_000_000, high: 320_000_000, description: "Scottish"}, - {low: 320_000_001, high: 399_999_999, description: "Northern Irish"}, - {low: 400_000_000, high: 3_112_999_999, description: "Scottish"} + {low: 101_000_000, high: 3_112_999_999, description: "Scottish"}, + {low: 3_200_000_001, high: 3_999_999_999, description: "Northern Irish"} ] for (const range of invalidRanges) { diff --git a/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts b/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts index d9c175b85..ece37471b 100644 --- a/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts +++ b/packages/updatePrescriptionStatus/tests/validation/testRequestContentValidation.test.ts @@ -214,18 +214,23 @@ describe("Unit tests for validation of NHS number", () => { describe("Unit tests for validation of NHS number range", () => { it.each([ { - nhsNumbers: [101_000_000, 311_299_9999], + nhsNumbers: ["0101000000", "3112999999"], expected: "NHS number is in the Scottish range.", scenarioDescription: "When NHS number is in the Scottish range, should return expected issue." }, { - nhsNumbers: [320_000_001, 399_999_999], + nhsNumbers: ["3200000001", "3999999999"], expected: "NHS number is in the Northern Irish range.", scenarioDescription: "When NHS number is in the Northern Irish range, should return expected issue." + }, + { + nhsNumbers: ["3113000000", "3200000000", "4000000000", "4999999999", "6000000000", "7999999999"], + expected: undefined, + scenarioDescription: "When NHS number is in the NHSE range." } ])("$scenarioDescription", async ({nhsNumbers, expected}) => { for (const _nhsNumber of nhsNumbers) { - const task = {for: {identifier: {value: String(_nhsNumber)}}} + const task = {for: {identifier: {value: _nhsNumber}}} const actual = nhsNumberRange(task as Task) From e51c92b3092c67b52fe48b2878ece4230b9eff6f Mon Sep 17 00:00:00 2001 From: Phil Gee Date: Thu, 11 Jul 2024 11:26:45 +0000 Subject: [PATCH 3/4] AEA-4190 Remove unnecessary changes to utils. --- packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts b/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts index 3fb450e4d..1e66f230e 100644 --- a/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts +++ b/packages/updatePrescriptionStatus/tests/utils/nhsNumber.ts @@ -3,10 +3,10 @@ import {faker} from "@faker-js/faker" import {calculateCheckDigit} from "../../src/utils/nhsNumber" -export function generateValidNhsNumbers(num: number, min: number = 100_000_000, max: number = 999_999_999) { +export function generateValidNhsNumbers(num: number) { const numbers: Array = [] while (numbers.length < num) { - const numString = faker.number.int({min: min, max: max}).toString() + const numString = faker.number.int({min: 100000000, max: 999999999}).toString() let checkDigit = calculateCheckDigit(numString) if (checkDigit === 11) { @@ -23,7 +23,7 @@ export function generateValidNhsNumbers(num: number, min: number = 100_000_000, export function generateInvalidNhsNumbers(num: number) { const numbers: Array = [] while (numbers.length < num) { - const numString = faker.number.int({min: 100_000_000, max: 999_999_999}).toString() + const numString = faker.number.int({min: 100000000, max: 999999999}).toString() const checkDigit = calculateCheckDigit(numString) const invalidCheckDigit = (checkDigit + 1) % 10 From 08a050e20889731423d57dcd71dd5e4cfc428aa2 Mon Sep 17 00:00:00 2001 From: Phil Gee Date: Thu, 11 Jul 2024 12:40:30 +0000 Subject: [PATCH 4/4] AEA-4190 NHS number definitely exists. --- packages/updatePrescriptionStatus/src/validation/content.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/updatePrescriptionStatus/src/validation/content.ts b/packages/updatePrescriptionStatus/src/validation/content.ts index 2e431126b..f46842b34 100644 --- a/packages/updatePrescriptionStatus/src/validation/content.ts +++ b/packages/updatePrescriptionStatus/src/validation/content.ts @@ -83,7 +83,7 @@ export function nhsNumberRange(task: Task): string | undefined { {low: 6_000_000_000, high: 7_999_999_999} ] - const nhsNumber = Number(task.for?.identifier?.value) + const nhsNumber = Number(task.for!.identifier!.value) for (const range of validRanges) { if (range.low <= nhsNumber && nhsNumber <= range.high) { return undefined