generated from ministryofjustice/hmpps-template-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
1,068 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
integration_tests/e2e/personalDetails/editContactDetails.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import Page from '../../pages/page' | ||
import EditContactDetails from '../../pages/personalDetails/editContactDetails' | ||
|
||
context('Edit contact details', () => { | ||
it('Edit contact details page is rendered based on non fixed address', () => { | ||
cy.visit('/case/X000001/personal-details/edit-contact-details') | ||
const page = Page.verifyOnPage(EditContactDetails) | ||
page.getElement('phoneNumber').should('be.visible') | ||
page.getElement('mobileNumber').should('be.visible') | ||
page.getElement('emailAddress').should('be.visible') | ||
page.getElement('buildingName').should('not.be.visible') | ||
page.getElement('buildingNumber').should('not.be.visible') | ||
page.getElement('streetName').should('not.be.visible') | ||
page.getElement('district').should('not.be.visible') | ||
page.getElement('town').should('not.be.visible') | ||
page.getElement('county').should('not.be.visible') | ||
page.getElement('postcode').should('not.be.visible') | ||
page.getElement('startDate').should('be.visible') | ||
page.getElement('endDate').should('be.visible') | ||
page.getElement('notes').should('be.visible') | ||
page.getCheckboxField('noFixedAddress').click() | ||
page.getElement('buildingName').should('be.visible') | ||
page.getElement('buildingNumber').should('be.visible') | ||
page.getElement('streetName').should('be.visible') | ||
page.getElement('district').should('be.visible') | ||
page.getElement('town').should('be.visible') | ||
page.getElement('county').should('be.visible') | ||
page.getElement('postcode').should('be.visible') | ||
}) | ||
it('Submitting successfully should redirect to Personal details screen with update banner', () => { | ||
cy.visit('/case/X000001/personal-details/edit-contact-details') | ||
const page = Page.verifyOnPage(EditContactDetails) | ||
page.getElement('submit-btn').click() | ||
page.getElement('updateBanner').should('contain.text', 'Contact details updated') | ||
}) | ||
it('Submitting with an end date should stay on edit page with warning banner, then second submit will redirect to Personal details screen with update banner', () => { | ||
cy.visit('/case/X000001/personal-details/edit-contact-details') | ||
const page = Page.verifyOnPage(EditContactDetails) | ||
page.getElementInput('endDate').type('03/02/2025') | ||
page.getElement('submit-btn').click() | ||
page | ||
.getElement('infoBanner') | ||
.should( | ||
'contain.text', | ||
'An end will change this to a previous address and you will need to add a new main address.', | ||
) | ||
page.getElement('submit-btn').click() | ||
page.getElement('updateBanner').should('contain.text', 'Contact details updated') | ||
}) | ||
|
||
it('Submitting with invalid data with over 35 chars should show error messages', () => { | ||
cy.visit('/case/X000001/personal-details/edit-contact-details') | ||
const page = Page.verifyOnPage(EditContactDetails) | ||
page.getElementInput('phoneNumber').clear().type('1'.repeat(36)) | ||
page.getElementInput('mobileNumber').clear().type('1'.repeat(36)) | ||
page.getElementInput('emailAddress').clear().type('1'.repeat(36)) | ||
page.getCheckboxField('noFixedAddress').click() | ||
page.getElementInput('buildingName').clear().type('1'.repeat(36)) | ||
page.getElementInput('buildingNumber').clear().type('1'.repeat(36)) | ||
page.getElementInput('streetName').clear().type('1'.repeat(36)) | ||
page.getElementInput('district').clear().type('1'.repeat(36)) | ||
page.getElementInput('town').clear().type('1'.repeat(36)) | ||
page.getElementInput('county').clear().type('1'.repeat(36)) | ||
page.getElementInput('postcode').clear().type('1'.repeat(36)) | ||
|
||
page.getElement('submit-btn').click() | ||
page.getElement('phoneNumberError').should('contain.text', 'Phone number must be 35 characters or less.') | ||
page.getElement('mobileNumberError').should('contain.text', 'Mobile number must be 35 characters or less.') | ||
page.getElement('emailAddress').should('contain.text', 'Enter an email address in the correct format.') | ||
|
||
page.getElement('buildingName').should('contain.text', 'Building name must be 35 characters or less.') | ||
page.getElement('buildingNumber').should('contain.text', 'Building number must be 35 characters or less.') | ||
page.getElement('streetName').should('contain.text', 'Street name must be 35 characters or less.') | ||
page.getElement('district').should('contain.text', 'District must be 35 characters or less.') | ||
page.getElement('town').should('contain.text', 'Town or city must be 35 characters or less.') | ||
page.getElement('county').should('contain.text', 'County must be 35 characters or less.') | ||
page.getElement('postcode').should('contain.text', 'Enter a full UK postcode.') | ||
}) | ||
|
||
it('Submitting with a dates later than today should show error messages', () => { | ||
cy.visit('/case/X000001/personal-details/edit-contact-details') | ||
const page = Page.verifyOnPage(EditContactDetails) | ||
page.getElementInput('endDate').type('03/02/2099') | ||
page.getElementInput('startDate').clear().type('03/02/2099') | ||
page.getElement('submit-btn').click() | ||
page.getElement('endDateError').should('contain.text', 'End date can not be later than today.') | ||
page.getElement('startDateError').should('contain.text', 'Start date can not be later than today.') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
integration_tests/pages/personalDetails/editContactDetails.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Page, { PageElement } from '../page' | ||
|
||
export default class EditContactDetails extends Page { | ||
constructor() { | ||
super('Edit contact details') | ||
} | ||
|
||
getNoFixedAddress = (addressId: string, rowName: string, type: string): PageElement => { | ||
return cy.get(`#noFixedAddress`) | ||
} | ||
|
||
getElement = (name: string): PageElement => { | ||
return cy.get(`[data-qa="${name}"]`) | ||
} | ||
|
||
getElementInput = (name: string): PageElement => { | ||
return cy.get(`[data-qa="${name}"] input`) | ||
} | ||
|
||
getDateElementInput = (name: string): PageElement => { | ||
return cy.get(`[data-qa="${name}"] govuk-input moj-js-datepicker-input`) | ||
} | ||
|
||
getCheckboxField = (name: string): PageElement => { | ||
return cy.get(`input[type="checkbox"]`) | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { postcodeValidator } from 'postcode-validator' | ||
import { DateTime } from 'luxon' | ||
import { PersonalDetailsUpdateRequest } from '../../data/model/personalDetails' | ||
|
||
export interface ErrorCheck { | ||
fn: (...args: any[]) => boolean | ||
msg: string | ||
length?: number | ||
crossField?: string | ||
} | ||
|
||
export interface ErrorChecks { | ||
optional: boolean | ||
checks: ErrorCheck[] | ||
} | ||
|
||
export interface ValidationSpec { | ||
[index: string]: ErrorChecks | ||
} | ||
|
||
export const isEmail = (string: string) => /[a-z0-9]+@[a-z]+\.[a-z]{2,3}/.test(string) | ||
export const isNotEmpty = (args: any[]) => { | ||
return !!args[0] && args[0] !== undefined | ||
} | ||
export const isNumeric = (args: any[]) => /^[+-]?\d+(\.\d+)?$/.test(args[0]) | ||
export const isUkEmail = (args: any[]) => { | ||
return postcodeValidator(args[0], 'GB') | ||
} | ||
export const charsOrLess = (args: any[]) => { | ||
return !(args[1].length > args[0]) | ||
} | ||
export const isValidDate = (args: any[]) => { | ||
return DateTime.fromFormat(args[0], 'd/M/yyyy').isValid | ||
} | ||
|
||
export const isNotLaterThanToday = (args: any[]) => { | ||
const date = DateTime.fromFormat(args[0], 'd/M/yyyy') | ||
return date.isValid && date <= DateTime.now() | ||
} | ||
|
||
export const isNotLaterThan = (args: any[]) => { | ||
const notLaterThanDate = DateTime.fromFormat(args[0], 'd/M/yyyy') | ||
const date = DateTime.fromFormat(args[1], 'd/M/yyyy') | ||
if (!notLaterThanDate.isValid || !date.isValid) { | ||
return true | ||
} | ||
return notLaterThanDate <= date | ||
} | ||
|
||
export function validateWithSpec(request: PersonalDetailsUpdateRequest, validationSpec: ValidationSpec) { | ||
const errors: Record<string, string> = {} | ||
Object.entries(validationSpec).forEach(entry => { | ||
const fieldName = entry[0] | ||
const checks = entry[1] | ||
if (Object.prototype.hasOwnProperty.call(request, fieldName)) { | ||
if (!request[fieldName] && checks.optional === true) { | ||
return | ||
} | ||
for (const c of checks.checks) { | ||
let args: any[] = c?.length ? [c.length, request[fieldName]] : [request[fieldName]] | ||
if (c?.crossField) { | ||
args = [request[c?.crossField], request[fieldName]] | ||
} | ||
if (!c.fn(args)) { | ||
errors[fieldName] = c.msg | ||
break | ||
} | ||
} | ||
} else if (checks.optional === false) { | ||
errors[fieldName] = checks.checks[0].msg | ||
} | ||
}) | ||
return errors | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.