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

feat(EMS-3977): broker details - form validation updates #3312

Merged
merged 20 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion database/exip.sql
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ DROP TABLE IF EXISTS `Broker`;
CREATE TABLE `Broker` (
`id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`application` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`buildingNumberOrName` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`buildingNumberOrName` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`isUsingBroker` tinyint(1) DEFAULT NULL,
`isBasedInUk` tinyint(1) DEFAULT NULL,
`name` varchar(800) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
Expand Down
23 changes: 21 additions & 2 deletions e2e-tests/commands/insurance/complete-broker-details-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import mockApplication from '../../fixtures/application';
const { BROKER } = mockApplication;

const {
BROKER_DETAILS: { NAME },
BROKER_DETAILS: { NAME, POSTCODE, BUILDING_NUMBER_OR_NAME },
} = POLICY_FIELD_IDS;

const { EMAIL } = ACCOUNT_FIELD_IDS;
Expand All @@ -17,10 +17,29 @@ const { EMAIL } = ACCOUNT_FIELD_IDS;
* @param {String} name: Broker name
* @param {String} email: Broker email
* @param {String} fullAddress: Broker's full address
* @param {Boolean} isBasedInUk: Broker is based in the UK
* @param {String} postcode: Broker's postcode
* @param {String} buildingNumberOrName: Broker's building name or number
*/
const completeBrokerDetailsForm = ({ name = BROKER[NAME], email = BROKER[EMAIL] }) => {
const completeBrokerDetailsForm = ({
name = BROKER[NAME],
email = BROKER[EMAIL],
// TODO: EMS-3974 - make this have a true default
isBasedInUk = false,
postcode = BROKER[POSTCODE],
buildingNumberOrName = BROKER[BUILDING_NUMBER_OR_NAME],
}) => {
cy.keyboardInput(field(NAME).input(), name);
cy.keyboardInput(field(EMAIL).input(), email);

if (isBasedInUk) {
cy.clickYesRadioInput();

cy.keyboardInput(field(POSTCODE).input(), postcode);
cy.keyboardInput(field(BUILDING_NUMBER_OR_NAME).input(), buildingNumberOrName);
} else {
cy.clickNoRadioInput();
}
};

export default completeBrokerDetailsForm;
1 change: 1 addition & 0 deletions e2e-tests/constants/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const MAXIMUM_CHARACTERS = {
AGENT_SERVICE_DESCRIPTION: 1000,
BIC_SWIFT_CODE: 11,
BROKER_NAME: 800,
BROKER_BUILDING_NUMBER_OR_NAME: 100,
BUSINESS: {
GOODS_OR_SERVICES_DESCRIPTION: 1000,
},
Expand Down
11 changes: 11 additions & 0 deletions e2e-tests/content-strings/error-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,17 @@ export const ERROR_MESSAGES = {
ABOVE_MAXIMUM: `The broker or company email cannot be more than ${MAXIMUM_CHARACTERS.EMAIL} characters`,
INCORRECT_FORMAT: 'Enter the broker or company email address in the correct format, like name@example.com',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.IS_BASED_IN_UK]: {
IS_EMPTY: 'Select if the broker you are using in the UK',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.POSTCODE]: {
IS_EMPTY: "Enter the broker's postcode",
INCORRECT_FORMAT: 'Enter a full UK postcode',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.BUILDING_NUMBER_OR_NAME]: {
IS_EMPTY: "Enter the broker's building number or name",
ABOVE_MAXIMUM: `The broker's building number or name cannot be more than ${MAXIMUM_CHARACTERS.BROKER_BUILDING_NUMBER_OR_NAME} characters`,
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.FULL_ADDRESS]: {
IS_EMPTY: "Enter the broker's address",
ABOVE_MAXIMUM: `The broker's address cannot be more than ${MAXIMUM_CHARACTERS.FULL_ADDRESS} characters`,
Expand Down
5 changes: 4 additions & 1 deletion e2e-tests/fixtures/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EXPORT_CONTRACT_AWARD_METHOD,
FIELD_IDS,
FIELD_VALUES,
VALID_POSTCODES,
TOTAL_CONTRACT_VALUE as TOTAL_CONTRACT_VALUE_CONSTANTS,
WEBSITE_EXAMPLES,
} from '../constants';
Expand Down Expand Up @@ -48,7 +49,7 @@ const {
CREDIT_PERIOD_WITH_BUYER,
REQUESTED_JOINTLY_INSURED_PARTY: { COMPANY_NAME, COMPANY_NUMBER, COUNTRY_CODE },
USING_BROKER,
BROKER_DETAILS: { NAME, EMAIL, FULL_ADDRESS: BROKER_FULL_ADDRESS },
BROKER_DETAILS: { NAME, EMAIL, FULL_ADDRESS: BROKER_FULL_ADDRESS, POSTCODE, BUILDING_NUMBER_OR_NAME },
LOSS_PAYEE_FINANCIAL_UK: { ACCOUNT_NUMBER, SORT_CODE },
LOSS_PAYEE_FINANCIAL_INTERNATIONAL: { BIC_SWIFT_CODE, IBAN },
FINANCIAL_ADDRESS,
Expand Down Expand Up @@ -195,6 +196,8 @@ const application = {
[NAME]: 'Mock broker name',
[EMAIL]: Cypress.env('GOV_NOTIFY_EMAIL_RECIPIENT_1'),
[BROKER_FULL_ADDRESS]: mockAddress0,
[BUILDING_NUMBER_OR_NAME]: 'Mock building name',
[POSTCODE]: VALID_POSTCODES.WITH_SPACE,
},
BUYER: {
[COMPANY_OR_ORGANISATION_NAME]: 'Test name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { MAXIMUM_CHARACTERS } from '../../../../../../../constants/validation';
import { assertEmailFieldValidation } from '../../../../../../../shared-test-assertions';

const {
BROKER_DETAILS: { NAME, EMAIL, FULL_ADDRESS },
BROKER_DETAILS: { NAME, EMAIL, IS_BASED_IN_UK, POSTCODE, BUILDING_NUMBER_OR_NAME },
} = POLICY_FIELD_IDS;

const {
Expand Down Expand Up @@ -85,39 +85,51 @@ context('Insurance - Policy - Broker details page - validation', () => {
totalExpectedOtherErrorsWithValidEmail: 2,
});

// TODO: EMS-3975
describe.skip(FULL_ADDRESS, () => {
const field = fieldSelector(FULL_ADDRESS);
describe(`when ${IS_BASED_IN_UK} is 'yes'`, () => {
beforeEach(() => {
cy.navigateToUrl(url);

const textareaField = {
...field,
input: field.textarea,
};
cy.clickYesRadioInput();
});

const errorIndex = 2;
const expectedErrorsCount = 3;
it(`should render a validation error when ${POSTCODE} is not provided`, () => {
const field = fieldSelector(POSTCODE);

const ERROR_MESSAGES_OBJECT = BROKER_DETAILS_ERROR_MESSAGES[FULL_ADDRESS];
const ERROR_MESSAGES_OBJECT = BROKER_DETAILS_ERROR_MESSAGES[POSTCODE];

it(`should render validation errors when ${FULL_ADDRESS} is left empty`, () => {
cy.navigateToUrl(url);
cy.submitAndAssertFieldErrors({
field,
value: '',
errorIndex: 2,
expectedErrorsCount: 4,
expectedErrorMessage: ERROR_MESSAGES_OBJECT.IS_EMPTY,
});
});

it(`should render a validation error when ${BUILDING_NUMBER_OR_NAME} is not provided`, () => {
const field = fieldSelector(BUILDING_NUMBER_OR_NAME);

const ERROR_MESSAGES_OBJECT = BROKER_DETAILS_ERROR_MESSAGES[BUILDING_NUMBER_OR_NAME];

cy.submitAndAssertFieldErrors({
field: textareaField,
errorIndex,
expectedErrorsCount,
field,
value: '',
errorIndex: 3,
expectedErrorsCount: 4,
expectedErrorMessage: ERROR_MESSAGES_OBJECT.IS_EMPTY,
});
});

it(`should render validation errors when ${FULL_ADDRESS} is over ${MAXIMUM_CHARACTERS.FULL_ADDRESS} characters`, () => {
cy.navigateToUrl(url);
it(`should render a validation error when ${BUILDING_NUMBER_OR_NAME} is above the maximum`, () => {
const field = fieldSelector(BUILDING_NUMBER_OR_NAME);

const ERROR_MESSAGES_OBJECT = BROKER_DETAILS_ERROR_MESSAGES[BUILDING_NUMBER_OR_NAME];

cy.submitAndAssertFieldErrors({
field: textareaField,
value: 'a'.repeat(MAXIMUM_CHARACTERS.FULL_ADDRESS + 1),
errorIndex,
expectedErrorsCount,
field,
value: 'a'.repeat(MAXIMUM_CHARACTERS.BROKER_BUILDING_NUMBER_OR_NAME) + 1,
errorIndex: 3,
expectedErrorsCount: 4,
expectedErrorMessage: ERROR_MESSAGES_OBJECT.ABOVE_MAXIMUM,
});
});
Expand Down
5 changes: 4 additions & 1 deletion src/api/.keystone/config.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/api/constants/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const MAXIMUM_CHARACTERS = {
AGENT_SERVICE_DESCRIPTION: 1000,
BIC_SWIFT_CODE: 11,
BROKER_NAME: 800,
BROKER_BUILDING_NUMBER_OR_NAME: 100,
BUSINESS: {
GOODS_OR_SERVICES_DESCRIPTION: 1000,
},
Expand Down
2 changes: 1 addition & 1 deletion src/api/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ model Broker {
id String @id @default(cuid())
application Application? @relation("Broker_application", fields: [applicationId], references: [id])
applicationId String? @map("application")
buildingNumberOrName String @default("")
buildingNumberOrName String @default("") @mysql.VarChar(100)
isUsingBroker Boolean?
isBasedInUk Boolean?
name String @default("") @mysql.VarChar(800)
Expand Down
4 changes: 3 additions & 1 deletion src/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,9 @@ export const lists = {
Broker: list({
fields: {
application: relationship({ ref: 'Application' }),
buildingNumberOrName: text(),
buildingNumberOrName: text({
db: { nativeType: 'VarChar(100)' },
}),
isUsingBroker: nullableCheckbox(),
isBasedInUk: nullableCheckbox(),
name: text({
Expand Down
1 change: 1 addition & 0 deletions src/ui/server/constants/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const MAXIMUM_CHARACTERS = {
AGENT_SERVICE_DESCRIPTION: 1000,
BIC_SWIFT_CODE: 11,
BROKER_NAME: 800,
BROKER_BUILDING_NUMBER_OR_NAME: 100,
BUSINESS: {
GOODS_OR_SERVICES_DESCRIPTION: 1000,
},
Expand Down
11 changes: 11 additions & 0 deletions src/ui/server/content-strings/error-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,17 @@ export const ERROR_MESSAGES = {
ABOVE_MAXIMUM: `The broker or company email cannot be more than ${MAXIMUM_CHARACTERS.EMAIL} characters`,
INCORRECT_FORMAT: 'Enter the broker or company email address in the correct format, like name@example.com',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.IS_BASED_IN_UK]: {
IS_EMPTY: 'Select if the broker you are using in the UK',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.POSTCODE]: {
IS_EMPTY: "Enter the broker's postcode",
INCORRECT_FORMAT: 'Enter a full UK postcode',
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.BUILDING_NUMBER_OR_NAME]: {
IS_EMPTY: "Enter the broker's building number or name",
ABOVE_MAXIMUM: `The broker's building number or name cannot be more than ${MAXIMUM_CHARACTERS.BROKER_BUILDING_NUMBER_OR_NAME} characters`,
},
[FIELD_IDS.INSURANCE.POLICY.BROKER_DETAILS.FULL_ADDRESS]: {
IS_EMPTY: "Enter the broker's address",
ABOVE_MAXIMUM: `The broker's address cannot be more than ${MAXIMUM_CHARACTERS.FULL_ADDRESS} characters`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ describe('controllers/insurance/policy/broker-details', () => {
const validBody = {
[NAME]: broker[NAME],
[EMAIL]: broker[EMAIL],
[IS_BASED_IN_UK]: broker[IS_BASED_IN_UK],
[IS_BASED_IN_UK]: 'true',
[POSTCODE]: broker[POSTCODE],
[BUILDING_NUMBER_OR_NAME]: broker[BUILDING_NUMBER_OR_NAME],
};

mapAndSave.broker = jest.fn(() => Promise.resolve(true));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import buildingNumberOrNameRules from '.';
import { MAXIMUM_CHARACTERS } from '../../../../../../../constants';
import { POLICY as POLICY_FIELD_IDS } from '../../../../../../../constants/field-ids/insurance/policy';
import { ERROR_MESSAGES } from '../../../../../../../content-strings';
import providedAndMaxLength from '../../../../../../../shared-validation/provided-and-max-length';
import { mockErrors } from '../../../../../../../test-mocks';

const {
BROKER_DETAILS: { IS_BASED_IN_UK, BUILDING_NUMBER_OR_NAME: FIELD_ID },
} = POLICY_FIELD_IDS;

const {
BROKER_DETAILS: { [FIELD_ID]: ERROR_MESSAGES_OBJECT },
} = ERROR_MESSAGES.INSURANCE.POLICY;

describe('controllers/insurance/policy/broker-details/validation/rules/building-number-or-name', () => {
const mockBody = {
[FIELD_ID]: '',
};

describe(`when ${IS_BASED_IN_UK} is true`, () => {
it('should return the result of providedAndMaxLength', () => {
mockBody[IS_BASED_IN_UK] = 'true';

const result = buildingNumberOrNameRules(mockBody, mockErrors);

const expected = providedAndMaxLength(mockBody, FIELD_ID, ERROR_MESSAGES_OBJECT, mockErrors, MAXIMUM_CHARACTERS.BROKER_BUILDING_NUMBER_OR_NAME);

expect(result).toEqual(expected);
});
});

describe(`when ${IS_BASED_IN_UK} is false`, () => {
it('should return the provided errors object', () => {
mockBody[IS_BASED_IN_UK] = 'false';

const result = buildingNumberOrNameRules(mockBody, mockErrors);

expect(result).toEqual(mockErrors);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { MAXIMUM_CHARACTERS } from '../../../../../../../constants';
import { POLICY as POLICY_FIELD_IDS } from '../../../../../../../constants/field-ids/insurance/policy';
import { ERROR_MESSAGES } from '../../../../../../../content-strings';
import providedAndMaxLength from '../../../../../../../shared-validation/provided-and-max-length';
import { RequestBody } from '../../../../../../../../types';

const {
BROKER_DETAILS: { IS_BASED_IN_UK, BUILDING_NUMBER_OR_NAME: FIELD_ID },
} = POLICY_FIELD_IDS;

const {
BROKER_DETAILS: { [FIELD_ID]: ERROR_MESSAGES_OBJECT },
} = ERROR_MESSAGES.INSURANCE.POLICY;

/**
* validate the "broker building number or name" field
* @param {RequestBody} formBody: Form body
* @param {Object} errors: Errors from previous validation errors
* @returns {ValidationErrors} providedAndMaxLength
*/
const buildingNumberOrNameRules = (formBody: RequestBody, errors: object) => {
if (formBody[IS_BASED_IN_UK] === 'true') {
return providedAndMaxLength(formBody, FIELD_ID, ERROR_MESSAGES_OBJECT, errors, MAXIMUM_CHARACTERS.BROKER_BUILDING_NUMBER_OR_NAME);
}

return errors;
};

export default buildingNumberOrNameRules;
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import nameRules from './name';
import emailRules from './email';

// TODO: EMS-3978
// import fullAddressRules from './full-address';
import isBasedInUkRules from './is-based-in-uk';
import postcodeRules from './postcode';
import buildingNumberOrNameRules from './building-number-or-name';
import { ValidationErrors } from '../../../../../../../types';

// const rules = [nameRules, emailRules, fullAddressRules];
const rules = [nameRules, emailRules];
const rules = [nameRules, emailRules, isBasedInUkRules, postcodeRules, buildingNumberOrNameRules];

const validationRules = rules as Array<() => ValidationErrors>;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import isBasedInUkRules from '.';
import { POLICY as POLICY_FIELD_IDS } from '../../../../../../../constants/field-ids/insurance/policy';
import { ERROR_MESSAGES } from '../../../../../../../content-strings';
import emptyFieldValidation from '../../../../../../../shared-validation/empty-field';
import { mockErrors } from '../../../../../../../test-mocks';

const {
BROKER_DETAILS: { IS_BASED_IN_UK: FIELD_ID },
} = POLICY_FIELD_IDS;

const {
BROKER_DETAILS: { [FIELD_ID]: ERROR_MESSAGE },
} = ERROR_MESSAGES.INSURANCE.POLICY;

describe('controllers/insurance/policy/broker-details/validation/rules/is-based-in-uk', () => {
const mockBody = {
[FIELD_ID]: '',
};

it('should return the result of emptyFieldValidation', () => {
const result = isBasedInUkRules(mockBody, mockErrors);

const expected = emptyFieldValidation(mockBody, FIELD_ID, ERROR_MESSAGE.IS_EMPTY, mockErrors);

expect(result).toEqual(expected);
});
});
Loading
Loading