diff --git a/docs/tests/post_v1_message-batches/validation.md b/docs/tests/post_v1_message-batches/validation.md index 982c489b1..102a37739 100644 --- a/docs/tests/post_v1_message-batches/validation.md +++ b/docs/tests/post_v1_message-batches/validation.md @@ -457,19 +457,3 @@ Below is a table showing the required attributes and their locations as seen in | messageReference | /data/attributes/messages/0/messageReference | | recipient | /data/attributes/messages/0/recipient | | nhsNumber | /data/attributes/messages/0/recipient/nhsNumber | - - -## Scenario: An API consumer submitting a request with an personalisation field too large receives a 400 ‘Invalid personalisation’ response - -Personalisation fields must not be too large for their given template - -**Given** the API consumer provides a message body with a personalisation field that is too large -
-**When** the request is submitted -
-**Then** the response returns a 400 Invalid personalisation error -
- -**Asserts** -- Response returns a 400 ‘Invalid personalisation’ error -- Response returns the expected error message body with references to the invalid attribute diff --git a/docs/tests/post_v1_single-message/validation.md b/docs/tests/post_v1_single-message/validation.md index c20b4c5a9..a8f173f69 100644 --- a/docs/tests/post_v1_single-message/validation.md +++ b/docs/tests/post_v1_single-message/validation.md @@ -317,19 +317,3 @@ Below is a table showing the required attributes and their locations as seen in | messageReference | /data/attributes/messageReference | | recipient | /data/attributes/recipient | | nhsNumber | /data/attributes/recipient/nhsNumber | - - -## Scenario: An API consumer submitting a request with an personalisation field too large receives a 400 ‘Invalid personalisation’ response - -Personalisation fields must not be too large for their given template - -**Given** the API consumer provides a message body with a personalisation field that is too large -
-**When** the request is submitted -
-**Then** the response returns a 400 Invalid personalisation error -
- -**Asserts** -- Response returns a 400 ‘Invalid personalisation’ error -- Response returns the expected error message body with references to the invalid attribute diff --git a/package-lock.json b/package-lock.json index 6be4ec5f5..bc28668b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2342,19 +2342,6 @@ "node": ">= 0.6" } }, - "node_modules/core-js": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", - "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.47.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", diff --git a/sandbox/__test__/batch_send.spec.js b/sandbox/__test__/batch_send.spec.js index 4b9ca1c49..9be9f383b 100644 --- a/sandbox/__test__/batch_send.spec.js +++ b/sandbox/__test__/batch_send.spec.js @@ -559,79 +559,6 @@ describe("/api/v1/send", () => { .expect("Content-Type", /json/, done); }); - it("responds with a 400 for missing personalisation for global NHS app routing plan", (done) => { - request(server) - .post("/api/v1/send") - .send({ - data: { - type: "MessageBatch", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000001", - messageBatchReference: "request-id", - messages: [ - { - messageReference: "1", - recipient: { - nhsNumber: "1", - }, - }, - { - messageReference: "2", - recipient: { - nhsNumber: "2", - }, - personalisation: { - body: "Free text message 2", - }, - }, - ], - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for missing body for global NHS app routing plan", (done) => { - request(server) - .post("/api/v1/send") - .send({ - data: { - type: "MessageBatch", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000001", - messageBatchReference: "request-id", - messages: [ - { - messageReference: "1", - recipient: { - nhsNumber: "1", - }, - personalisation: { - body: "Free text message 1", - }, - }, - { - messageReference: "2", - recipient: { - nhsNumber: "2", - }, - personalisation: { - unknownField: "Free text message 2", - }, - }, - ], - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: body", - }) - .expect("Content-Type", /json/, done); - }); - it("responds with a 200 for redundant personalisation for global NHS app routing plan", (done) => { request(server) .post("/api/v1/send") @@ -669,69 +596,6 @@ describe("/api/v1/send", () => { .expect("Content-Type", /json/, done); }); - it("responds with a 400 for missing personalisation fields for global email routing plan", (done) => { - request(server) - .post("/api/v1/send") - .send({ - data: { - type: "MessageBatch", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000002", - messageBatchReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - messages: [ - { - messageReference: "1", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: {}, - }, - ], - }, - }, - }) - .expect(400, { - message: - "Some personalisation fields are missing: email_subject,email_body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for missing personalisation field for global email routing plan", (done) => { - request(server) - .post("/api/v1/send") - .send({ - data: { - type: "MessageBatch", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000002", - messageBatchReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - messages: [ - { - messageReference: "1", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: { - email_subject: "test", - }, - }, - ], - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: email_body", - }) - .expect("Content-Type", /json/, done); - }); - it("responds with a 200 when required fields provided for global email routing plan", (done) => { request(server) .post("/api/v1/send") @@ -763,36 +627,6 @@ describe("/api/v1/send", () => { .expect("Content-Type", /json/, done); }); - it("responds with a 400 for missing personalisation for global sms routing plan", (done) => { - request(server) - .post("/api/v1/send") - .send({ - data: { - type: "MessageBatch", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000003", - messageBatchReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - messages: [ - { - messageReference: "1", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: {}, - }, - ], - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: sms_body", - }) - .expect("Content-Type", /json/, done); - }); - it("responds with a 200 when required fields provided for global sms routing plan", (done) => { request(server) .post("/api/v1/send") diff --git a/sandbox/__test__/messages.spec.js b/sandbox/__test__/messages.spec.js index ac943f583..42c5e93c5 100644 --- a/sandbox/__test__/messages.spec.js +++ b/sandbox/__test__/messages.spec.js @@ -210,138 +210,6 @@ describe("/api/v1/messages", () => { .expect("Content-Type", /json/, done); }); - it("responds with a 400 for missing personalisation for global NHS app routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000001", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for missing body for global NHS app routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000001", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - }, - personalisation: { - unknownField: "Free text message", - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for redundant personalisation for global NHS app routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000001", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - }, - personalisation: { - body: "Free text message", - unknownField: "Free text message", - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for missing personalisation fields for global email routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000002", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: {}, - }, - }, - }) - .expect(400, { - message: - "Some personalisation fields are missing: email_subject,email_body", - }) - .expect("Content-Type", /json/, done); - }); - - it("responds with a 400 for missing personalisation field for global email routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000002", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: { - email_subject: "test", - }, - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: email_body", - }) - .expect("Content-Type", /json/, done); - }); - it("responds with a 200 when required fields provided for global email routing plan", (done) => { request(server) .post("/api/v1/messages") @@ -368,31 +236,6 @@ describe("/api/v1/messages", () => { .expect("Content-Type", /json/, done); }); - it("responds with a 400 for missing personalisation for global sms routing plan", (done) => { - request(server) - .post("/api/v1/messages") - .send({ - data: { - type: "Message", - attributes: { - routingPlanId: "00000000-0000-0000-0000-000000000003", - messageReference: "b5bb84b9-a522-41e9-aa8b-ad1b6a454243", - recipient: { - nhsNumber: "1", - }, - originator: { - odsCode: "X123", - }, - personalisation: {}, - }, - }, - }) - .expect(400, { - message: "Some personalisation fields are missing: sms_body", - }) - .expect("Content-Type", /json/, done); - }); - it("responds with a 200 when required fields provided for global sms routing plan", (done) => { request(server) .post("/api/v1/messages") diff --git a/sandbox/handlers/batch_send.js b/sandbox/handlers/batch_send.js index 255fd1e46..b5a9f04ec 100644 --- a/sandbox/handlers/batch_send.js +++ b/sandbox/handlers/batch_send.js @@ -1,6 +1,5 @@ import KSUID from "ksuid"; import { sendError, writeLog } from "./utils.js"; -import { getGlobalFreeTextError } from "./error_scenarios/global_free_text.js"; import { getSendingGroupIdError } from "./error_scenarios/sending_group_id.js"; import { getOdsCodeError } from "./error_scenarios/ods_code.js"; import { mandatoryBatchMessageFieldValidation } from "./validation/mandatory_batch_message_fields.js"; @@ -28,23 +27,6 @@ export async function batchSend(req, res, next) { const { routingPlanId, messages } = body.data.attributes; - const messagePersonsalisations = messages.map( - (message) => message.personalisation - ); - for (const personalisation of messagePersonsalisations) { - const globalFreeTextError = getGlobalFreeTextError( - personalisation, - routingPlanId - ); - - if (globalFreeTextError !== null) { - const [errorCode, errorMessage] = globalFreeTextError; - sendError(res, errorCode, errorMessage); - next(); - return; - } - } - const odsCodes = messages.map( (message) => message?.originator?.odsCode ); diff --git a/sandbox/handlers/error_scenarios/global_free_text.js b/sandbox/handlers/error_scenarios/global_free_text.js deleted file mode 100644 index 17bd33362..000000000 --- a/sandbox/handlers/error_scenarios/global_free_text.js +++ /dev/null @@ -1,50 +0,0 @@ -import { - globalFreeTextEmailSendingGroupId, - globalFreeTextNhsAppSendingGroupId, - globalFreeTextSmsSendingGroupId, -} from "../config.js"; - -const globalFreeTextPersonalisationFields = { - [globalFreeTextNhsAppSendingGroupId]: ["body"], - [globalFreeTextEmailSendingGroupId]: ["email_subject", "email_body"], - [globalFreeTextSmsSendingGroupId]: ["sms_body"], -}; - -export function getGlobalFreeTextError(personalisation, sendingGroupId) { - const requiredPersonalisationFields = - globalFreeTextPersonalisationFields[sendingGroupId]; - - if (!requiredPersonalisationFields) { - return null; - } - - if (!personalisation) { - return [ - 400, - `Some personalisation fields are missing: ${requiredPersonalisationFields.join( - "," - )}`, - ]; - } - - const personalisationFields = Object.keys(personalisation); - - const missingPersonalisationFields = []; - - for (const requiredField of requiredPersonalisationFields) { - if (!personalisationFields.includes(requiredField)) { - missingPersonalisationFields.push(requiredField); - } - } - - if (missingPersonalisationFields.length) { - return [ - 400, - `Some personalisation fields are missing: ${missingPersonalisationFields.join( - "," - )}`, - ]; - } - - return null; -} diff --git a/sandbox/handlers/messages.js b/sandbox/handlers/messages.js index c990735cd..2d3197bc9 100644 --- a/sandbox/handlers/messages.js +++ b/sandbox/handlers/messages.js @@ -5,7 +5,6 @@ import { getSendingGroupIdError } from "./error_scenarios/sending_group_id.js"; import { getOdsCodeError } from "./error_scenarios/ods_code.js"; import { mandatorySingleMessageFieldValidation } from "./validation/mandatory_single_message_fields.js"; import { getAlternateContactDetailsError } from "./error_scenarios/override_contact_details.js"; -import { getGlobalFreeTextError } from "./error_scenarios/global_free_text.js"; export async function messages(req, res, next) { if (req.headers.authorization === "banned") { @@ -36,18 +35,6 @@ export async function messages(req, res, next) { return; } - const personalisation = req.body.data?.attributes?.personalisation; - const globalFreeTextError = getGlobalFreeTextError( - personalisation, - routingPlanId - ); - if (globalFreeTextError !== null) { - const [errorCode, errorMessage] = globalFreeTextError; - sendError(res, errorCode, errorMessage); - next(); - return; - } - const odsCode = req.body.data?.attributes?.originator?.odsCode; const odsCodeError = getOdsCodeError(odsCode, req.headers.authorization); if (odsCodeError !== null) { diff --git a/specification/documentation/CreateMessageBatch.md b/specification/documentation/CreateMessageBatch.md index c0b9a0c0d..af66080fb 100644 --- a/specification/documentation/CreateMessageBatch.md +++ b/specification/documentation/CreateMessageBatch.md @@ -17,7 +17,7 @@ The per message reference (`messageReference`) needs to be unique within the mes You may be required to send through specific personalisation fields based upon the routing plan (`routingPlanId`). These will have been setup during your [onboarding](#overview--onboarding) process. -These are validated according to the routing plan when we store your message batch. If there are missing values then the entire batch will be rejected with a `CM_INVALID_VALUE` code. The detail and source fields will provide further information about the error. +Messages that are missing required personalisation fields, or have personalisation content that is too long for the routing plan that it is used in, will be accepted by the API but will not be sent. ### Sandbox diff --git a/tests/api/message_batches/field_validation/test_400_too_large.py b/tests/api/message_batches/field_validation/test_400_too_large.py deleted file mode 100644 index 630c1766f..000000000 --- a/tests/api/message_batches/field_validation/test_400_too_large.py +++ /dev/null @@ -1,38 +0,0 @@ -import requests -import pytest -from lib import Assertions, Generators -from lib.fixtures import * # NOSONAR -from lib.constants.constants import GLOBAL_ROUTING_CONFIGURATION_SMS -from lib.constants.message_batches_paths import MESSAGE_BATCHES_ENDPOINT - - -@pytest.mark.test -@pytest.mark.devtest -@pytest.mark.inttest -def test_too_large_personalisation(url, bearer_token): - """ - .. include:: ../partials/validation/test_too_large_personalisation.rst - """ - headers = Generators.generate_valid_headers(bearer_token.value) - data = Generators.generate_valid_create_message_batch_body("dev") - data["data"]["attributes"]["routingPlanId"] = GLOBAL_ROUTING_CONFIGURATION_SMS - data["data"]["attributes"]["messages"][0]["personalisation"] = { - 'sms_body': 'x'*919 - } - while len(data["data"]["attributes"]["messages"]) > 1: - del data["data"]["attributes"]["messages"][1] - - resp = requests.post( - f"{url}{MESSAGE_BATCHES_ENDPOINT}", - headers=headers, - json=data - ) - - Assertions.assert_error_with_optional_correlation_id( - resp, - 400, - Generators.generate_invalid_personalisation_error( - "Total personalisation length of 919 exceeding the maximum length of 918", - "/data/attributes/messages/0/personalisation"), - None - ) diff --git a/tests/api/single_message/field_validation/test_400_too_large.py b/tests/api/single_message/field_validation/test_400_too_large.py deleted file mode 100644 index 6fc32d95e..000000000 --- a/tests/api/single_message/field_validation/test_400_too_large.py +++ /dev/null @@ -1,36 +0,0 @@ -import requests -import pytest -from lib import Assertions, Generators -from lib.fixtures import * # NOSONAR -from lib.constants.messages_paths import MESSAGES_ENDPOINT -from lib.constants.constants import GLOBAL_ROUTING_CONFIGURATION_SMS - - -@pytest.mark.test -@pytest.mark.devtest -@pytest.mark.inttest -def test_too_large_personalisation(url, bearer_token): - """ - .. include:: ../partials/validation/test_too_large_personalisation.rst - """ - headers = Generators.generate_valid_headers(bearer_token.value) - data = Generators.generate_valid_create_message_body("dev") - data["data"]["attributes"]["routingPlanId"] = GLOBAL_ROUTING_CONFIGURATION_SMS - data["data"]["attributes"]["personalisation"] = { - 'sms_body': 'x'*919 - } - - resp = requests.post( - f"{url}{MESSAGES_ENDPOINT}", - headers=headers, - json=data - ) - - Assertions.assert_error_with_optional_correlation_id( - resp, - 400, - Generators.generate_invalid_personalisation_error( - "Total personalisation length of 919 exceeding the maximum length of 918", - "/data/attributes/personalisation"), - None - ) diff --git a/tests/docs/post_v1_message-batches/validation.rst b/tests/docs/post_v1_message-batches/validation.rst index cb25a1771..6955ebcb5 100644 --- a/tests/docs/post_v1_message-batches/validation.rst +++ b/tests/docs/post_v1_message-batches/validation.rst @@ -24,7 +24,3 @@ Validation Tests .. automodule:: api.message_batches.field_validation.test_400_too_few_items :noindex: :members: - -.. automodule:: api.message_batches.field_validation.test_400_too_large - :noindex: - :members: \ No newline at end of file diff --git a/tests/docs/post_v1_single-message/validation.rst b/tests/docs/post_v1_single-message/validation.rst index 31321c9cb..8c8249fde 100644 --- a/tests/docs/post_v1_single-message/validation.rst +++ b/tests/docs/post_v1_single-message/validation.rst @@ -16,7 +16,3 @@ Validation Tests .. automodule:: api.single_message.field_validation.test_400_property_missing :noindex: :members: - -.. automodule:: api.single_message.field_validation.test_400_too_large - :noindex: - :members: