diff --git a/api/registerOrganisation/index.ts b/api/registerOrganisation/index.ts index dbdfe03d3..ea4e5b595 100644 --- a/api/registerOrganisation/index.ts +++ b/api/registerOrganisation/index.ts @@ -64,9 +64,14 @@ export async function handleRegisterOrgRoute(req: Request, res: Response, next: try { const registerRequest = mapRequestObject(registerPayload); const response = await axiosInstance.post(url, registerRequest, options); + res.send(response.data); } catch (error) { - next(error); + if (error.status === 400 && error.data?.errorDescription) { + res.status(400).send(error.data); + } else { + next(error); + } } } diff --git a/package.json b/package.json index 4c584aa49..900f39574 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@hmcts/frontend": "0.0.50-alpha", "@hmcts/nodejs-healthcheck": "1.7.0", "@hmcts/properties-volume": "0.0.13", - "@hmcts/rpx-xui-common-lib": "1.9.0-route-expected-feature-2", + "@hmcts/rpx-xui-common-lib": "1.9.0-error-message-change", "@hmcts/rpx-xui-node-lib": "2.27.1", "@ng-idle/core": "^10.0.0", "@ng-idle/keepalive": "^10.0.0", diff --git a/src/app/components/hmcts-global-header/hmcts-global-header.component.spec.ts b/src/app/components/hmcts-global-header/hmcts-global-header.component.spec.ts index 4bf1e90c1..02cf863a0 100644 --- a/src/app/components/hmcts-global-header/hmcts-global-header.component.spec.ts +++ b/src/app/components/hmcts-global-header/hmcts-global-header.component.spec.ts @@ -67,7 +67,6 @@ describe('HmctsGlobalHeaderComponent', () => { component.headerTitle = { ...component.headerTitle, hideBranding: false }; fixture.detectChanges(); const headerTitle = fixture.debugElement.nativeElement.querySelector('.govuk-header__logotype-text'); - expect(headerTitle).toBeDefined(); expect(headerTitle).not.toBeNull(); expect(headerTitle.textContent).toContain('MyHMCTS'); expect(component.headerTitle.hideBranding).toBeFalsy(); diff --git a/src/app/containers/app/app.component.html b/src/app/containers/app/app.component.html index 5f8c24ba5..926ecfe46 100644 --- a/src/app/containers/app/app.component.html +++ b/src/app/containers/app/app.component.html @@ -1,4 +1,4 @@ -Skip to main content -{{pageTitle$ | async}} { + this.titleService.setTitle(title? title : 'Manage organisation'); + }); + if (this.headersService.isAuthenticated()) { this.userService.getUserDetails().subscribe((user) => { const featureUser: FeatureUser = { @@ -97,9 +104,8 @@ export class AppComponent implements OnInit, OnDestroy { } public ngOnDestroy(): void { - if (this.cookieBannerEnabledSubscription) { - this.cookieBannerEnabledSubscription.unsubscribe(); - } + this.cookieBannerEnabledSubscription?.unsubscribe(); + this.pageTitleSubscription?.unsubscribe(); } public handleCookieBannerFeatureToggle(): void { diff --git a/src/app/containers/redirect/redirect.component.spec.ts b/src/app/containers/redirect/redirect.component.spec.ts index 87df33088..9281345de 100644 --- a/src/app/containers/redirect/redirect.component.spec.ts +++ b/src/app/containers/redirect/redirect.component.spec.ts @@ -37,6 +37,6 @@ describe('AppRedirectComponent', () => { }); it('should have redirect property ', () => { - expect(app.redirected).toBeDefined(); + expect(app.redirected).toBe(false); }); }); diff --git a/src/app/utils/app-utils.spec.ts b/src/app/utils/app-utils.spec.ts index 498e6cf8b..b7df65580 100644 --- a/src/app/utils/app-utils.spec.ts +++ b/src/app/utils/app-utils.spec.ts @@ -1,3 +1,4 @@ +import { LovRefDataModel } from '../../shared/models/lovRefData.model'; import { propsExist } from '../../../api/lib/objectUtilities'; import { AppConstants } from '../app.constants'; import { AppFeatureFlag } from '../store/reducers/app.reducer'; @@ -89,64 +90,131 @@ describe('AppUtils', () => { expect(array).toEqual(state.userNav); }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('invite-users'); - expect(array).toEqual('Invite user - Manage organisation'); - }); + describe('Page title', () => { + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/register'); + expect(array).toEqual('Register - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('organisation-name'); - expect(array).toEqual('Organisation name - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/organisation-type'); + expect(array).toEqual('Organisation type - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('organisation-address'); - expect(array).toEqual('Organisation address - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/company-house-details'); + expect(array).toEqual('Company house details - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('organisation-pba'); - expect(array).toEqual('PBA - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/document-exchange-reference'); + expect(array).toEqual('Document exchange reference - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('have-dx'); - expect(array).toEqual('DX - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/regulatory-organisation-type'); + expect(array).toEqual('Organisation regulators - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('organisation-dx'); - expect(array).toEqual('DX reference - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/organisation-services-access'); + expect(array).toEqual('Services to access - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('haveSra'); - expect(array).toEqual('SRA - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/payment-by-account'); + expect(array).toEqual('Payment by account - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('sraNumber'); - expect(array).toEqual('SRA number - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/individual-registered-with-regulator'); + expect(array).toEqual('Individual regulators - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('name'); - expect(array).toEqual('Name - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org-new/check-your-answers'); + expect(array).toEqual('Check your answers - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('email-address'); - expect(array).toEqual('Email - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/organisation-name'); + expect(array).toEqual('Organisation name - Register organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('check'); - expect(array).toEqual('Check answers - Register organisation'); - }); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/organisation-address'); + expect(array).toEqual('Organisation address - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/organisation-pba'); + expect(array).toEqual('PBA - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/organisation-have-dx'); + expect(array).toEqual('DX - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/organisation-dx'); + expect(array).toEqual('DX reference - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/haveSra'); + expect(array).toEqual('SRA - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/sraNumber'); + expect(array).toEqual('SRA number - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/name'); + expect(array).toEqual('Name - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/email-address'); + expect(array).toEqual('Email - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register/check'); + expect(array).toEqual('Check answers - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('register-org/register'); + expect(array).toEqual('Register - Register organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('invite-users'); + expect(array).toEqual('Invite user - Manage organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('organisation'); + expect(array).toEqual('Organisation details - Manage organisation'); + }); - it('should set correct page titles', () => { - const array = AppUtils.setPageTitle('register-org/register'); - expect(array).toEqual('Register - Register organisation'); + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('users'); + expect(array).toEqual('Users - Manage organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('unassigned-cases'); + expect(array).toEqual('Unassigned cases - Manage organisation'); + }); + + it('should set correct page title', () => { + const array = AppUtils.setPageTitle('assigned-cases'); + expect(array).toEqual('Assigned cases - Manage organisation'); + }); }); it('should switch title', () => { @@ -360,4 +428,68 @@ describe('AppUtils', () => { const result = AppUtils.findLastIndex(htmlComponentArray2, predicate); expect(result).toEqual(-1); }); + + describe('setOtherAsLastOption', () => { + let itmes: LovRefDataModel[]; + let other: LovRefDataModel; + + beforeEach(() => { + itmes = [ + { + active_flag: 'Y', + category_key: 'Org', + child_nodes: null, + hint_text_cy: '', + hint_text_en: '', + key: 'DEFENCE', + lov_order: null, + parent_category: '', + parent_key: '', + value_cy: '', + value_en: 'Defence' + }, + { + active_flag: 'Y', + category_key: 'Org', + child_nodes: null, + hint_text_cy: '', + hint_text_en: '', + key: 'CHARITY', + lov_order: null, + parent_category: '', + parent_key: '', + value_cy: '', + value_en: 'Charity' + } + ]; + + other = { + active_flag: '', + category_key: '', + hint_text_cy: '', + hint_text_en: '', + key: 'OTHER', + lov_order: null, + parent_category: '', + parent_key: '', + value_cy: '', + value_en: 'Other', + child_nodes: null + }; + }); + + it('should set Other as last option if not available in the input list', () => { + const itemsWithOther = AppUtils.setOtherAsLastOption(itmes); + itmes.push(other); + expect(itemsWithOther).toEqual(itmes); + expect(itemsWithOther[itemsWithOther.length - 1]).toEqual(other); + }); + + it('should move other to the last position if it is available in the input list', () => { + itmes.splice(1, 0, other); + const itemsWithOther = AppUtils.setOtherAsLastOption(itmes); + expect(itemsWithOther).toBe(itmes); + expect(itemsWithOther[itemsWithOther.length - 1]).toEqual(other); + }); + }); }); diff --git a/src/app/utils/app-utils.ts b/src/app/utils/app-utils.ts index 204e3e388..da7256756 100644 --- a/src/app/utils/app-utils.ts +++ b/src/app/utils/app-utils.ts @@ -2,6 +2,7 @@ * Contains static stateless utility methods for the App */ import { formatDate } from '@angular/common'; +import { LovRefDataModel } from '../../shared/models/lovRefData.model'; import { AppConstants } from '../app.constants'; import { NavItemModel } from '../models/nav-items.model'; import { AppFeatureFlag } from '../store/reducers/app.reducer'; @@ -76,59 +77,102 @@ export class AppUtils { return is24Hour ? formatDate(date, 'HH:mm', 'en-UK') : formatDate(date, 'h:mm a', 'en-UK').toLowerCase(); } - public static setPageTitle(url): string { + public static setPageTitle(url: string): string { /** * it sets correct page titles based on the url. */ + if (url.indexOf('register-org') !== -1 || url.indexOf('register-org-new') !== -1) { + return AppUtils.getPageTitleForRegisterOrganisation(url); + } if (url.indexOf('invite-user') !== -1) { return 'Invite user - Manage organisation'; } if (url.indexOf('profile') !== -1) { return 'Profile - Manage organisation'; } + if (url.indexOf('organisation') !== -1) { + return 'Organisation details - Manage organisation'; + } if (url.indexOf('users') !== -1) { return 'Users - Manage organisation'; } - if (url.indexOf('organisation-name') !== -1) { + if (url.indexOf('unassigned-cases') !== -1) { + return 'Unassigned cases - Manage organisation'; + } + if (url.indexOf('assigned-cases') !== -1) { + return 'Assigned cases - Manage organisation'; + } + return 'Manage organisation'; + } + + public static getPageTitleForRegisterOrganisation(url: string): string { + if (url.indexOf('register-org-new/register') !== -1) { + return 'Register - Register organisation'; + } + if (url.indexOf('register-org-new/organisation-type') !== -1) { + return 'Organisation type - Register organisation'; + } + if (url.indexOf('register-org-new/company-house-details') !== -1) { + return 'Company house details - Register organisation'; + } + if (url.indexOf('register-org-new/registered-address') !== -1) { + return 'Registered address - Register organisation'; + } + if (url.indexOf('register-org-new/document-exchange-reference') !== -1) { + return 'Document exchange reference - Register organisation'; + } + if (url.indexOf('register-org-new/regulatory-organisation-type') !== -1) { + return 'Organisation regulators - Register organisation'; + } + if (url.indexOf('register-org-new/organisation-services-access') !== -1) { + return 'Services to access - Register organisation'; + } + if (url.indexOf('register-org-new/payment-by-account') !== -1) { + return 'Payment by account - Register organisation'; + } + if (url.indexOf('register-org-new/contact-details') !== -1) { + return 'Contact details - Register organisation'; + } + if (url.indexOf('register-org-new/individual-registered-with-regulator') !== -1) { + return 'Individual regulators - Register organisation'; + } + if (url.indexOf('register-org-new/check-your-answers') !== -1) { + return 'Check your answers - Register organisation'; + } + if (url.indexOf('register-org/register/organisation-name') !== -1) { return 'Organisation name - Register organisation'; } - if (url.indexOf('organisation-address') !== -1) { + if (url.indexOf('register-org/register/organisation-address') !== -1) { return 'Organisation address - Register organisation'; } - if (url.indexOf('organisation-pba') !== -1) { + if (url.indexOf('register-org/register/organisation-pba') !== -1) { return 'PBA - Register organisation'; } - if (url.indexOf('have-dx') !== -1) { + if (url.indexOf('register-org/register/organisation-have-dx') !== -1) { return 'DX - Register organisation'; } - if (url.indexOf('organisation-dx') !== -1) { + if (url.indexOf('register-org/register/organisation-dx') !== -1) { return 'DX reference - Register organisation'; } - if (url.indexOf('haveSra') !== -1) { + if (url.indexOf('register-org/register/haveSra') !== -1) { return 'SRA - Register organisation'; } - if (url.indexOf('sraNumber') !== -1) { + if (url.indexOf('register-org/register/sraNumber') !== -1) { return 'SRA number - Register organisation'; } - if (url.indexOf('name') !== -1) { + if (url.indexOf('register-org/register/name') !== -1) { return 'Name - Register organisation'; } - if (url.indexOf('email-address') !== -1) { + if (url.indexOf('register-org/register/email-address') !== -1) { return 'Email - Register organisation'; } - if (url.indexOf('check') !== -1) { + if (url.indexOf('register-org/register/check') !== -1) { return 'Check answers - Register organisation'; } - if (url.indexOf('organisation') !== -1) { - return 'Organisation details - Manage organisation'; - } - if (url.indexOf('register-org/register') !== -1) { - return 'Register - Register organisation'; - } - if (url.indexOf('register-org/confirmation') !== -1) { + if (url.indexOf('register-org/register/confirmation') !== -1) { return 'Confirmation - Register organisation'; } - return 'Manage organisation'; + return 'Register - Register organisation'; } // 04-Sep-2019 - Author U Denduluri @@ -216,4 +260,31 @@ export class AppUtils { } return -1; } + + public static setOtherAsLastOption(items: LovRefDataModel[], other: LovRefDataModel = null): LovRefDataModel[] { + // To set Other option as the last option + const index = items.findIndex((o) => o.key.toUpperCase() === 'OTHER'); + if (index > 0) { + items.push(items.splice(index, 1)[0]); + } else { + if (!other) { + other = { + active_flag: '', + category_key: '', + hint_text_cy: '', + hint_text_en: '', + key: 'OTHER', + lov_order: null, + parent_category: '', + parent_key: '', + value_cy: '', + value_en: 'Other', + child_nodes: null + }; + } + items.push(other); + } + + return items; + } } diff --git a/src/caa-cases/store/reducers/share-case.reducer.spec.ts b/src/caa-cases/store/reducers/share-case.reducer.spec.ts index b0ead9f48..d7e17ee4e 100644 --- a/src/caa-cases/store/reducers/share-case.reducer.spec.ts +++ b/src/caa-cases/store/reducers/share-case.reducer.spec.ts @@ -16,7 +16,8 @@ describe('Share case reducer', () => { }; const action = new fromActions.AddShareAssignedCases(payload); const state = fromReducer.shareCasesReducer(initialState, action); - expect(state).toBeDefined(); + const mockState = { shareAssignedCases: [], shareUnassignedCases: [], loading: false, error: undefined, users: [] }; + expect(state).toEqual(mockState); }); it('should load state when navigate to share assigned case', () => { diff --git a/src/index.html b/src/index.html index 255258bcd..32e8096d9 100644 --- a/src/index.html +++ b/src/index.html @@ -4,8 +4,8 @@ - + Manage organisation diff --git a/src/organisation/components/pba-success-summary/pba-success-summary.component.spec.ts b/src/organisation/components/pba-success-summary/pba-success-summary.component.spec.ts index bddbc3adb..ad9211054 100644 --- a/src/organisation/components/pba-success-summary/pba-success-summary.component.spec.ts +++ b/src/organisation/components/pba-success-summary/pba-success-summary.component.spec.ts @@ -30,9 +30,8 @@ describe('organisation.PbaSuccessSummaryComponent', () => { expect(component.message).toEqual(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[200]); const wrapper = fixture.nativeElement.querySelector('.hmcts-banner--success'); - expect(wrapper).toBeDefined(); + expect(wrapper).toBeTruthy(); const message = fixture.nativeElement.querySelector('.hmcts-banner__message'); - expect(message).toBeDefined(); expect(message.textContent).toContain(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[200]); }); @@ -43,9 +42,8 @@ describe('organisation.PbaSuccessSummaryComponent', () => { expect(component.message).toEqual(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[202]); const wrapper = fixture.nativeElement.querySelector('.hmcts-banner--success'); - expect(wrapper).toBeDefined(); + expect(wrapper).toBeTruthy(); const message = fixture.nativeElement.querySelector('.hmcts-banner__message'); - expect(message).toBeDefined(); expect(message.textContent).toContain(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[202]); }); @@ -67,7 +65,7 @@ describe('organisation.PbaSuccessSummaryComponent', () => { // Should display an appropriate message. expect(component.message).toEqual(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[202]); let wrapper = fixture.nativeElement.querySelector('.hmcts-banner--success'); - expect(wrapper).toBeDefined(); + expect(wrapper).toBeTruthy(); component.response = null; fixture.detectChanges(); @@ -84,13 +82,13 @@ describe('organisation.PbaSuccessSummaryComponent', () => { expect(component.message).toEqual(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[202]); let wrapper = fixture.nativeElement.querySelector('.hmcts-banner--success'); - expect(wrapper).toBeDefined(); + expect(wrapper).toBeTruthy(); component.response = RESPONSE; fixture.detectChanges(); expect(component.message).toEqual(PbaSuccessSummaryComponent.SUCCESS_MESSAGES[202]); wrapper = fixture.nativeElement.querySelector('.hmcts-banner--success'); - expect(wrapper).toBeDefined(); + expect(wrapper).toBeTruthy(); }); }); diff --git a/src/register-org/components/before-you-start/before-you-start.component.html b/src/register-org/components/before-you-start/before-you-start.component.html index 4d8af27b1..6bc201bca 100644 --- a/src/register-org/components/before-you-start/before-you-start.component.html +++ b/src/register-org/components/before-you-start/before-you-start.component.html @@ -1,22 +1,7 @@
- - -
+

Apply for an organisation to manage civil, family and tribunal cases

@@ -58,9 +43,9 @@

Before you start

-
-

- Error:{{beforeYouStartError.description}} +

+

+ Error:{{beforeYouStartErrors[0].message}}

diff --git a/src/register-org/components/before-you-start/before-you-start.component.spec.ts b/src/register-org/components/before-you-start/before-you-start.component.spec.ts index 1864ccae3..7204c697a 100644 --- a/src/register-org/components/before-you-start/before-you-start.component.spec.ts +++ b/src/register-org/components/before-you-start/before-you-start.component.spec.ts @@ -2,7 +2,6 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { ErrorMessage } from '../../../shared/models/error-message.model'; import { EnvironmentService } from '../../../shared/services/environment.service'; import { BeforeYouStartComponent } from './before-you-start.component'; @@ -53,14 +52,13 @@ describe('BeforeYouStartComponent', () => { scrollIntoView: scrollIntoViewSpy } }; - const errorMessage: ErrorMessage = { - description: 'Please select the checkbox', - title: '', - fieldId: 'confirmed-organisation-account' - }; + const errorMessages = [{ + message: 'Please select the checkbox', + id: 'confirmed-organisation-account' + }]; component.beforeYouStartForm.get('confirmedOrganisationAccount').setValue(null); component.onStart(); - expect(component.beforeYouStartError).toEqual(errorMessage); + expect(component.beforeYouStartErrors).toEqual(errorMessages); expect(scrollIntoViewSpy).toHaveBeenCalled(); }); }); diff --git a/src/register-org/components/before-you-start/before-you-start.component.ts b/src/register-org/components/before-you-start/before-you-start.component.ts index 98e7afc50..f38ecc785 100644 --- a/src/register-org/components/before-you-start/before-you-start.component.ts +++ b/src/register-org/components/before-you-start/before-you-start.component.ts @@ -3,7 +3,6 @@ import { FormControl, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ErrorMessage } from '../../../shared/models/error-message.model'; import { EnvironmentService } from '../../../shared/services/environment.service'; import { RegisterComponent } from '../../containers/register/register-org.component'; import { RegisterOrgService } from '../../services/register-org.service'; @@ -18,7 +17,8 @@ export class BeforeYouStartComponent extends RegisterComponent implements OnInit public manageCaseLink$: Observable; public manageOrgLink$: Observable; public beforeYouStartForm: FormGroup; - public beforeYouStartError: ErrorMessage; + public beforeYouStartErrors: { id: string, message: string }[] = []; + public errorPresent = false; constructor( public readonly router: Router, @@ -52,11 +52,11 @@ export class BeforeYouStartComponent extends RegisterComponent implements OnInit private isFormValid(): boolean { if (this.beforeYouStartForm.invalid || !this.beforeYouStartForm.get('confirmedOrganisationAccount').value) { - this.beforeYouStartError = { - description: 'Please select the checkbox', - title: '', - fieldId: 'confirmed-organisation-account' - }; + this.beforeYouStartErrors = [{ + message: 'Please select the checkbox', + id: 'confirmed-organisation-account' + }]; + this.errorPresent = true; this.mainContentElement.nativeElement.scrollIntoView({ behavior: 'smooth' }); return false; } diff --git a/src/register-org/components/check-your-answers/check-your-answers.component.html b/src/register-org/components/check-your-answers/check-your-answers.component.html index dfda1e8b2..2c046fe0a 100644 --- a/src/register-org/components/check-your-answers/check-your-answers.component.html +++ b/src/register-org/components/check-your-answers/check-your-answers.component.html @@ -1,8 +1,8 @@ -
+
Back - +

Check your answers before you register

Organisation details

@@ -95,9 +95,21 @@

Organisation details

-
-
-
DX reference
+
+
+
Do you have a document exchange reference for your main office?
+
+ {{ registrationData.hasDxReference ? 'Yes' : 'No'}} +
+
+ + ChangeDX reference + +
+
+
+
What's the DX reference for this office?
{{registrationData.dxNumber}}, {{registrationData.dxExchange}}
@@ -127,9 +139,21 @@

Organisation details

-
-
-
PBA number(s)
+
+
+
Does your organisation have a payment by account number?
+
+ {{ registrationData.hasPBA ? 'Yes' : 'No'}} +
+
+ + ChangeOrganisation PBA + +
+
+
+
What PBA numbers does your organisation use?
{{pbaNumber}} @@ -137,7 +161,7 @@

Organisation details

+ routerLink="/{{registerOrgService.REGISTER_ORG_NEW_ROUTE}}/payment-by-account-details"> ChangePBA number(s)
@@ -191,7 +215,7 @@

Administration details

- @@ -199,7 +223,7 @@

Administration details

Confirm your registration details

Ensure that:

    -
  • your personal and organisation detils are correct
  • +
  • your personal and organisation details are correct
  • you have used your registered office address and not a personal or home address
  • you are creating an account for your organisation for the first time
  • you are authorised to register an account on behalf of your organisation
  • @@ -213,14 +237,14 @@

    Confirm your registration detai

-
+
-
+
Error: {{validationErrors[0].message}}
+ name="confirmTermsAndConditions" formControlName="confirmTermsAndConditions">
-
diff --git a/src/register-org/components/check-your-answers/check-your-answers.component.spec.ts b/src/register-org/components/check-your-answers/check-your-answers.component.spec.ts index bdb9983a1..1cab181e8 100644 --- a/src/register-org/components/check-your-answers/check-your-answers.component.spec.ts +++ b/src/register-org/components/check-your-answers/check-your-answers.component.spec.ts @@ -2,23 +2,33 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { throwError } from 'rxjs'; import { RegistrationData } from '../../models/registration-data.model'; +import { RegisterOrgService } from '../../services'; import { CheckYourAnswersComponent } from './check-your-answers.component'; describe('CheckYourAnswersComponent', () => { let component: CheckYourAnswersComponent; let fixture: ComponentFixture; let router: Router; + let registerOrgService: RegisterOrgService; const registrationData: RegistrationData = { - pbaNumbers: [], companyName: 'Minstry of Justice', companyHouseNumber: '11223344', hasDxReference: null, dxNumber: null, dxExchange: null, - services: [], - hasPBA: null, + hasPBA: true, + pbaNumbers: [ + 'PBA1234567', + 'PBA1234568' + ], + services: [ + 'AAA7', + 'ABA3' + ], + otherServices: 'test service', contactDetails: { firstName: 'John', lastName: 'Davis', @@ -29,7 +39,7 @@ describe('CheckYourAnswersComponent', () => { inInternationalMode: true, regulators: [], regulatorRegisteredWith: null, - hasIndividualRegisteredWithRegulator: null, + hasIndividualRegisteredWithRegulator: true, individualRegulators: [] }; @@ -46,9 +56,11 @@ describe('CheckYourAnswersComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(CheckYourAnswersComponent); component = fixture.componentInstance; - component.registrationData = registrationData; router = TestBed.inject(Router); + registerOrgService = TestBed.inject(RegisterOrgService); spyOn(router, 'navigate'); + registerOrgService = TestBed.inject(RegisterOrgService); + spyOn(registerOrgService, 'getRegistrationData').and.returnValue(registrationData); fixture.detectChanges(); }); @@ -60,6 +72,18 @@ describe('CheckYourAnswersComponent', () => { expect(component).toBeTruthy(); }); + it('should getOrganisationType return the correct organisation type from the ref data', () => { + const organisationType = component.getOrganisationType('SolicitorOrganisation'); + expect(organisationType).toEqual('Solicitor Organisation'); + }); + + it('should display error message banner for api error', () => { + spyOn(registerOrgService, 'postRegistration').and.returnValue(throwError('error')); + component.cyaFormGroup.get('confirmTermsAndConditions').setValue(true); + component.onSubmitData(); + expect(component.validationErrors).toEqual([{ id: 'confirm-terms-and-conditions', message: 'Sorry, there is a problem with the service. Try again later' }]); + }); + it('should back link navigate to the individual registered with the regulator details page', () => { component.registrationData.hasIndividualRegisteredWithRegulator = true; component.onBack(); @@ -69,6 +93,12 @@ describe('CheckYourAnswersComponent', () => { it('should back link navigate to the individual registered with the regulator page', () => { component.registrationData.hasIndividualRegisteredWithRegulator = false; component.onBack(); - expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'individual-registered-with-regulator', true]); + expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'individual-registered-with-regulator']); + }); + + it('should invoke the cancel registration journey when clicked on cancel link', () => { + spyOn(component, 'cancelRegistrationJourney'); + component.onCancel(); + expect(component.cancelRegistrationJourney).toHaveBeenCalled(); }); }); diff --git a/src/register-org/components/check-your-answers/check-your-answers.component.ts b/src/register-org/components/check-your-answers/check-your-answers.component.ts index ff51a0048..6a47d1160 100644 --- a/src/register-org/components/check-your-answers/check-your-answers.component.ts +++ b/src/register-org/components/check-your-answers/check-your-answers.component.ts @@ -1,25 +1,26 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { AbstractControl, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; import { Router } from '@angular/router'; -import { HttpErrorResponse } from '@angular/common/http'; import { RegisterComponent } from '../../../register-org/containers'; +import { ORGANISATION_TYPES_REF_DATA } from '../../__mocks__'; import { ORGANISATION_SERVICES } from '../../constants/register-org-constants'; import { RegulatorType, RegulatoryType } from '../../models'; import { RegisterOrgService } from '../../services/register-org.service'; -import { ORGANISATION_TYPES_REF_DATA } from 'src/register-org/__mocks__'; @Component({ selector: 'app-check-your-answers', templateUrl: './check-your-answers.component.html' }) export class CheckYourAnswersComponent extends RegisterComponent implements OnInit { + @ViewChild('mainContent') public mainContentElement: ElementRef; + public cyaFormGroup: FormGroup; public regulatorType = RegulatorType; public regulatoryType = RegulatoryType; public services: string[] = []; public validationErrors: { id: string, message: string }[] = []; - public apiErrors: {id: string, message: string}[] = []; public readonly errorMessage = 'Please select checkbox to confirm you have read and understood the terms and conditions'; + public readonly apiErrorMessage = 'Sorry, there is a problem with the service. Try again later'; constructor(public readonly router: Router, public readonly registerOrgService: RegisterOrgService @@ -43,20 +44,10 @@ export class CheckYourAnswersComponent extends RegisterComponent implements OnIn } } - private getCustomValidationForTermsAndConditions(): ValidatorFn { - // TODO: To be used in the functionality ticket if required - return (control: AbstractControl): { [key: string]: any } => { - if (!control.value) { - return { error: this.errorMessage }; - } - return null; - }; - } - public onBack(): void { this.registrationData.hasIndividualRegisteredWithRegulator ? this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator-details', true]) - : this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator', true]); + : this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator']); } public onSubmitData(): void { @@ -64,41 +55,44 @@ export class CheckYourAnswersComponent extends RegisterComponent implements OnIn this.registerOrgService.postRegistration().subscribe(() => { this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'registration-submitted']); }, - ((errorResponse: HttpErrorResponse) => { - this.apiErrors.push({ - id: 'confirmTermsAndConditions', - message: errorResponse.error.message - }); + ((errorResponse) => { + const returnedError = { id: 'confirm-terms-and-conditions', message: this.apiErrorMessage }; + if (errorResponse?.status === 400 && errorResponse.error?.errorDescription) { + returnedError.message = errorResponse.error.errorDescription; + } + this.validationErrors.push(returnedError); + this.mainContentElement.nativeElement.scrollIntoView({ behavior: 'smooth' }); })); } } + public getOrganisationType(organisationType: string): string { + const orgRefData = ORGANISATION_TYPES_REF_DATA.find((orgType) => orgType.key === organisationType); + return orgRefData ? orgRefData.value_en : null; + } + + public onCancel(): void { + this.cancelRegistrationJourney(); + } + private validateForm(): boolean { this.validationErrors = []; - this.apiErrors = []; if (!this.cyaFormGroup.valid) { this.validationErrors.push({ - id: 'confirmTermsAndConditions', + id: 'confirm-terms-and-conditions', message: this.errorMessage }); } return this.cyaFormGroup.valid; } - public termsAndConditionsChange(event: any): void { - this.validateForm(); - } - - public getErrorMessages(): { id: string; message: string;}[] { - return this.apiErrors; - } - - public getOrganisationType(organisationType: string): string { - const orgRefData = ORGANISATION_TYPES_REF_DATA.find((orgType) => orgType.key === organisationType); - return orgRefData ? orgRefData.value_en : null; - } - - public onCancel(): void { - this.cancelRegistrationJourney(); + private getCustomValidationForTermsAndConditions(): ValidatorFn { + // TODO: To be used in the functionality ticket if required + return (control: AbstractControl): { [key: string]: any } => { + if (!control.value) { + return { error: this.errorMessage }; + } + return null; + }; } } diff --git a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.html b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.html index 4415379cd..e15f27d8c 100644 --- a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.html +++ b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.html @@ -1,5 +1,18 @@
-
+
+
Are you (as an individual) registered with a regulator?
+
+ {{ hasIndividualRegulator ? 'Yes' : 'No'}} +
+
+ + ChangeIndividual regulator + +
+
+
What regulators are you (as an individual) registered with? diff --git a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.spec.ts b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.spec.ts index 940cca28d..ec4a8309d 100644 --- a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.spec.ts +++ b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.spec.ts @@ -86,10 +86,8 @@ describe('RegulatorListComponent', () => { component.regulators = individualRegulators; fixture.detectChanges(); const columnHeadingElement = nativeElement.querySelector('.govuk-summary-list__key') as HTMLElement; - expect(columnHeadingElement.innerText).toContain('What regulators are you (as an individual) registered with?'); + expect(columnHeadingElement.innerText).toContain('Are you (as an individual) registered with a regulator?'); const columnValueElement = nativeElement.querySelector('.govuk-summary-list__value') as HTMLElement; - expect(columnValueElement.innerText).toContain('Other: qwerty ref: 12345'); - expect(columnValueElement.innerText).toContain('OISC ref: 76843'); - expect(columnValueElement.innerText).toContain('NA'); + expect(columnValueElement.innerText).toContain('No'); }); }); diff --git a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.ts b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.ts index 66efe4882..46c6f25db 100644 --- a/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.ts +++ b/src/register-org/components/check-your-answers/regulator-list/regulator-list.component.ts @@ -9,6 +9,7 @@ import { RegisterOrgService } from '../../../services/register-org.service'; export class RegulatorListComponent { @Input() regulatorType: string; @Input() regulators: Regulator[]; + @Input() hasIndividualRegulator: boolean = false; public registerOrgNewRoute: string; public regulatorTypeEnum = RegulatorType; diff --git a/src/register-org/components/company-house-details/company-house-details.component.html b/src/register-org/components/company-house-details/company-house-details.component.html index 2099ac5b8..a8c057f0a 100644 --- a/src/register-org/components/company-house-details/company-house-details.component.html +++ b/src/register-org/components/company-house-details/company-house-details.component.html @@ -6,7 +6,7 @@ Register an organisation

What is your company name and Companies House number?


-

+

If your company is registered with Companies House, add the company name and number as they appear in the company @@ -18,7 +18,7 @@

What is your company name and Companies House numbe Enter the name of the organisation

- Error: {{ companyNameError.description }} + Error:{{ companyNameError.message }}

diff --git a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.html b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.html index 30905ede7..ca0922c43 100644 --- a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.html +++ b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.html @@ -1,23 +1,9 @@
- - -
Back + + Register an organisation
@@ -29,22 +15,28 @@


- Document Exchange (DX) is a service that enables solicitors to move large amounts of paperwork between one another. + Document Exchange (DX) is a service that enables solicitors to move large amounts of paperwork between one + another.
-
-
- - -
-
- - +
+

+ Error:{{dxErrors[0].message}} +

+
+
+ + +
+
+ + +
@@ -60,4 +52,4 @@

-

+
\ No newline at end of file diff --git a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.spec.ts b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.spec.ts index 5b0a989c6..1c31157a3 100644 --- a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.spec.ts +++ b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.spec.ts @@ -2,7 +2,6 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { ErrorMessage } from '../../../shared/models/error-message.model'; import { RegistrationData } from '../../models/registration-data.model'; import { DocumentExchangeReferenceComponent } from './document-exchange-reference.component'; @@ -72,17 +71,37 @@ describe('DocumentExchangeReferenceComponent', () => { scrollIntoView: scrollIntoViewSpy } }; - const errorMessage: ErrorMessage = { - description: 'Please select at least one option', - title: '', - fieldId: 'document-exchange-yes' - }; + const errorMessages = [{ + message: 'Please select an option', + id: 'document-exchange-yes' + }]; component.dxFormGroup.get('documentExchange').setValue(null); component.onContinue(); - expect(component.dxError).toEqual(errorMessage); + expect(component.dxErrors).toEqual(errorMessages); expect(scrollIntoViewSpy).toHaveBeenCalled(); }); + it('should navigate to document exchange details page', () => { + component.registrationData.hasDxReference = null; + component.dxFormGroup.get('documentExchange').setValue('yes'); + component.onContinue(); + expect(component.registrationData.hasDxReference).toEqual(true); + expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'document-exchange-reference-details']); + }); + + it('should navigate to regulatory organisation type page', () => { + component.registrationData = registrationData; + component.registrationData.hasDxReference = true; + component.registrationData.dxExchange = 'DX Exchange'; + component.registrationData.dxNumber = '12345'; + component.dxFormGroup.get('documentExchange').setValue('no'); + component.onContinue(); + expect(component.registrationData.hasDxReference).toEqual(false); + expect(component.registrationData.dxNumber).toBeNull(); + expect(component.registrationData.dxExchange).toBeNull(); + expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'regulatory-organisation-type']); + }); + it('should invoke the cancel registration journey when clicked on cancel link', () => { spyOn(component, 'cancelRegistrationJourney'); component.onCancel(); diff --git a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.ts b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.ts index cb7aaa029..d6a2e69f4 100644 --- a/src/register-org/components/document-exchange-reference/document-exchange-reference.component.ts +++ b/src/register-org/components/document-exchange-reference/document-exchange-reference.component.ts @@ -1,7 +1,6 @@ import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; -import { ErrorMessage } from '../../../shared/models/error-message.model'; import { RegisterComponent } from '../../containers/register/register-org.component'; import { RegisterOrgService } from '../../services/register-org.service'; @@ -13,7 +12,8 @@ export class DocumentExchangeReferenceComponent extends RegisterComponent implem @ViewChild('errorSummaryTitleElement') public errorSummaryTitleElement: ElementRef; public dxFormGroup: FormGroup; - public dxError: ErrorMessage; + public dxErrors: { id: string, message: string }[] = []; + public errorPresent = false; constructor(public readonly router: Router, public readonly registerOrgService: RegisterOrgService @@ -45,6 +45,8 @@ export class DocumentExchangeReferenceComponent extends RegisterComponent implem } else { // Set corresponding registration data this.registrationData.hasDxReference = false; + this.registrationData.dxNumber = null; + this.registrationData.dxExchange = null; // Navigate to office address page this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'regulatory-organisation-type']); } @@ -76,11 +78,11 @@ export class DocumentExchangeReferenceComponent extends RegisterComponent implem private isFormValid(): boolean { if (this.dxFormGroup.invalid) { - this.dxError = { - description: 'Please select at least one option', - title: '', - fieldId: 'document-exchange-yes' - }; + this.dxErrors = [{ + message: 'Please select an option', + id: 'document-exchange-yes' + }]; + this.errorPresent = true; this.errorSummaryTitleElement.nativeElement.scrollIntoView({ behavior: 'smooth' }); return false; } diff --git a/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.spec.ts b/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.spec.ts index a9c562853..0aba118fd 100644 --- a/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.spec.ts +++ b/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.spec.ts @@ -23,6 +23,7 @@ describe('IndividualRegisteredWithRegulatorComponent', () => { hasPBA: null, contactDetails: null, hasIndividualRegisteredWithRegulator: null, + individualRegulators: [], services: [], address: null, organisationType: null, @@ -103,6 +104,7 @@ describe('IndividualRegisteredWithRegulatorComponent', () => { component.registrationData.hasIndividualRegisteredWithRegulator = false; component.setFormControlValues(); component.onContinue(); + expect(component.registrationData.individualRegulators.length).toEqual(0); expect(mockRouter.navigate).toHaveBeenCalledWith(['register-org-new', 'check-your-answers']); }); diff --git a/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.ts b/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.ts index 64d06e87c..3022bd35d 100644 --- a/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.ts +++ b/src/register-org/components/individual-registered-with-regulator/individual-registered-with-regulator.component.ts @@ -42,6 +42,7 @@ export class IndividualRegisteredWithRegulatorComponent extends RegisterComponen } else { // Set corresponding registration data this.registrationData.hasIndividualRegisteredWithRegulator = false; + this.registrationData.individualRegulators = []; this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, this.registerOrgService.CHECK_YOUR_ANSWERS_ROUTE]); } } diff --git a/src/register-org/components/organisation-services-access/organisation-services-access.component.html b/src/register-org/components/organisation-services-access/organisation-services-access.component.html index 2b1c8e4c8..dee474edd 100644 --- a/src/register-org/components/organisation-services-access/organisation-services-access.component.html +++ b/src/register-org/components/organisation-services-access/organisation-services-access.component.html @@ -19,7 +19,7 @@

You must select at least one option
-
+
Error: {{noServicesError}}
@@ -33,8 +33,8 @@

-
-

diff --git a/src/register-org/components/regulator-details/regulator-details.component.spec.ts b/src/register-org/components/regulator-details/regulator-details.component.spec.ts index 5102cbdcc..819655dab 100644 --- a/src/register-org/components/regulator-details/regulator-details.component.spec.ts +++ b/src/register-org/components/regulator-details/regulator-details.component.spec.ts @@ -254,6 +254,25 @@ describe('RegulatorDetailsComponent', () => { expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'organisation-services-access']); }); + it('should changing the regulator type clear the organisation registration number field', () => { + component.regulatorType = RegulatorType.Organisation; + component.registrationData.regulators = []; + component.setFormControlValues(); + fixture.detectChanges(); + const selectElement0: HTMLSelectElement = nativeElement.querySelector('#regulator-type0'); + selectElement0.selectedIndex = 0; + selectElement0.dispatchEvent(new Event('change')); + fixture.detectChanges(); + const registrationNumberElement = nativeElement.querySelector('#organisation-registration-number0'); + registrationNumberElement.value = '123'; + registrationNumberElement.dispatchEvent(new Event('input')); + fixture.detectChanges(); + selectElement0.selectedIndex = 0; + selectElement0.dispatchEvent(new Event('change')); + fixture.detectChanges(); + expect(registrationNumberElement.value).toEqual(''); + }); + it('should validate the form on clicking "Continue" and not persist data or navigate to next page if validation fails', () => { spyOn(component, 'onContinue').and.callThrough(); component.validationErrors = []; @@ -487,14 +506,14 @@ describe('RegulatorDetailsComponent', () => { }); it('should back link navigate to the individual registered with regulator page', () => { - mockRoute.snapshot.params.backLinkTriggeredFromCYA = true; + mockRoute.snapshot.params.backLinkTriggeredFromCYA = false; component.regulatorType = RegulatorType.Individual; component.onBack(); expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'individual-registered-with-regulator']); }); it('should back link navigate to the document exchange reference details page', () => { - mockRoute.snapshot.params.backLinkTriggeredFromCYA = true; + mockRoute.snapshot.params.backLinkTriggeredFromCYA = false; component.regulatorType = RegulatorType.Organisation; component.registrationData.hasDxReference = true; component.onBack(); @@ -502,7 +521,7 @@ describe('RegulatorDetailsComponent', () => { }); it('should back link navigate to the document exchange reference page', () => { - mockRoute.snapshot.params.backLinkTriggeredFromCYA = true; + mockRoute.snapshot.params.backLinkTriggeredFromCYA = false; component.regulatorType = RegulatorType.Organisation; component.registrationData.hasDxReference = false; component.onBack(); @@ -511,6 +530,7 @@ describe('RegulatorDetailsComponent', () => { it('should back link navigate to the check your answers page', () => { mockRoute.snapshot.params.backLinkTriggeredFromCYA = false; + component.previousUrl = 'check-your-answers'; component.onBack(); expect(router.navigate).toHaveBeenCalledWith(['register-org-new', 'check-your-answers']); }); diff --git a/src/register-org/components/regulator-details/regulator-details.component.ts b/src/register-org/components/regulator-details/regulator-details.component.ts index 696a2b4e9..7f4be87ec 100644 --- a/src/register-org/components/regulator-details/regulator-details.component.ts +++ b/src/register-org/components/regulator-details/regulator-details.component.ts @@ -29,6 +29,7 @@ export class RegulatorDetailsComponent extends RegisterComponent implements OnIn public regulatorTypeEnum = RegulatorType; public validationErrors: { id: string, message: string }[] = []; public duplicatesIndex: number[]; + public previousUrl: string; constructor( private readonly lovRefDataService: LovRefDataService, @@ -42,6 +43,7 @@ export class RegulatorDetailsComponent extends RegisterComponent implements OnIn public ngOnInit(): void { super.ngOnInit(); this.regulatorTypes$ = this.lovRefDataService.getRegulatoryOrganisationTypes(); + this.previousUrl = this.currentNavigation?.previousNavigation?.finalUrl?.toString(); this.setFormControlValues(); } @@ -56,7 +58,11 @@ export class RegulatorDetailsComponent extends RegisterComponent implements OnIn switch (value) { case (RegulatoryType.Other): { formGroup.addControl('regulatorName', new FormControl(formGroup.value.regulatorName, Validators.required)); - formGroup.addControl('organisationRegistrationNumber', new FormControl(formGroup.value.organisationRegistrationNumber, Validators.required)); + if (formGroup.get('organisationRegistrationNumber')) { + formGroup.get('organisationRegistrationNumber').reset(); + } else { + formGroup.addControl('organisationRegistrationNumber', new FormControl(null, Validators.required)); + } break; } case (RegulatoryType.NotApplicable): { @@ -66,7 +72,12 @@ export class RegulatorDetailsComponent extends RegisterComponent implements OnIn } default: { formGroup.removeControl('regulatorName'); - formGroup.addControl('organisationRegistrationNumber', new FormControl(formGroup.value.organisationRegistrationNumber, Validators.required)); + if (formGroup.get('organisationRegistrationNumber')) { + formGroup.get('organisationRegistrationNumber').reset(); + } else { + formGroup.addControl('organisationRegistrationNumber', new FormControl(null, Validators.required)); + } + break; } } } @@ -154,17 +165,29 @@ export class RegulatorDetailsComponent extends RegisterComponent implements OnIn public onBack(): void { if (this.route.snapshot?.params?.backLinkTriggeredFromCYA) { - // Back link triggered from CYA page - if (this.regulatorType === RegulatorType.Individual) { - this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator']); + // Back link clicked on CYA page + // Navigate to individual regulators yes or no screen + this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator']); + } else { + if (this.previousUrl?.includes(this.registerOrgService.CHECK_YOUR_ANSWERS_ROUTE)) { + // Change link clicked on CYA page + // Navigate to CYA page + this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, this.registerOrgService.CHECK_YOUR_ANSWERS_ROUTE]); } else { - this.registrationData.hasDxReference - ? this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'document-exchange-reference-details']) - : this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'document-exchange-reference']); + // Normal registration journey + if (this.regulatorType === RegulatorType.Individual) { + // Currently displayed screen is individual regulator details + // Navigate to individual regulators yes or no screen + this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'individual-registered-with-regulator']); + } else { + // Currently displayed screen is organisation regulator details + // Navigate to document exchange reference details screen if document exchange details were already entered + // Else, navigate to document exchange reference yes or no screen + this.registrationData.hasDxReference + ? this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'document-exchange-reference-details']) + : this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'document-exchange-reference']); + } } - } else { - // Change link triggered from CYA page - this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, this.registerOrgService.CHECK_YOUR_ANSWERS_ROUTE]); } } diff --git a/src/register-org/containers/registered-address/registered-address.component.html b/src/register-org/containers/registered-address/registered-address.component.html index 32b77eb9c..5e59bf6a2 100644 --- a/src/register-org/containers/registered-address/registered-address.component.html +++ b/src/register-org/containers/registered-address/registered-address.component.html @@ -9,7 +9,7 @@ Register an organisation

{{headingText}}


-

Add the main address of your organisation. +

Add the main address of your organisation. If registered with Companies House, add the address listed in the company diff --git a/src/register-org/containers/registered-address/registered-address.component.ts b/src/register-org/containers/registered-address/registered-address.component.ts index 1554892c3..d5f3e21ce 100644 --- a/src/register-org/containers/registered-address/registered-address.component.ts +++ b/src/register-org/containers/registered-address/registered-address.component.ts @@ -69,6 +69,9 @@ export class RegisteredAddressComponent extends RegisterComponent implements OnI public onContinue(): void { if (this.isFormValid()) { this.registrationData.address = this.formGroup.get('address').value; + if (this.registrationData.address.postCode === '') { + this.registrationData.address.postCode = null; + } this.registrationData.inInternationalMode = this.startedInternational; this.router.navigate([this.registerOrgService.REGISTER_ORG_NEW_ROUTE, 'document-exchange-reference']); diff --git a/src/register-org/models/error-messages.model.ts b/src/register-org/models/error-messages.model.ts index 9eaac9273..02fb37c85 100644 --- a/src/register-org/models/error-messages.model.ts +++ b/src/register-org/models/error-messages.model.ts @@ -12,3 +12,9 @@ export enum OrganisationServicesMessage { NO_ORG_SERVICES = 'Please select at least one service', OTHER_SERVICES = 'Enter one or more services' } + +export enum PbaErrorMessage { + GENERIC_ERROR_MESSAGE = 'Enter a valid PBA number', + EXISTING_PBA_NUMBER = 'This PBA number is already associated to your organisation', + UNIQUE_ERROR_MESSAGE = 'You have entered this PBA number more than once' +} diff --git a/src/shared/modules/loader/components/loader.component.html b/src/shared/modules/loader/components/loader.component.html index d393f05e7..e3b840c33 100644 --- a/src/shared/modules/loader/components/loader.component.html +++ b/src/shared/modules/loader/components/loader.component.html @@ -7,7 +7,7 @@

- + Loading
diff --git a/src/users/containers/user-details/user-details.component.spec.ts b/src/users/containers/user-details/user-details.component.spec.ts index b205d2ffe..5ae5b0154 100644 --- a/src/users/containers/user-details/user-details.component.spec.ts +++ b/src/users/containers/user-details/user-details.component.spec.ts @@ -27,8 +27,8 @@ describe('User Details Component', () => { routerStoreSpyObject.pipe.and.returnValue(of({})); userStoreSpyObject.pipe.and.returnValue(of({})); component.ngOnInit(); - expect(component.userSubscription).toBeDefined(); - expect(component.suspendSuccessSubscription).toBeDefined(); + expect(component.userSubscription).toBeTruthy(); + expect(component.suspendSuccessSubscription).toBeTruthy(); }); }); @@ -72,7 +72,14 @@ describe('User Details Component', () => { describe('handleUserSubscription', () => { it('should set actionButtons when user is Active', () => { component.handleUserSubscription({ status: 'Active' }, of(true)); - expect(component.actionButtons).toBeDefined(); + const mockButtons = [ + { + name: 'Suspend account', + class: 'hmcts-button--secondary', + action: undefined + } + ]; + expect(component.actionButtons).toEqual(mockButtons); }); it('should not set actionButtons when user is Suspended', () => { diff --git a/src/users/store/reducers/users.reducer.spec.ts b/src/users/store/reducers/users.reducer.spec.ts index e9d96bc2c..1327a7f0c 100644 --- a/src/users/store/reducers/users.reducer.spec.ts +++ b/src/users/store/reducers/users.reducer.spec.ts @@ -157,10 +157,10 @@ describe('Users Reducer', () => { it('LOAD_USER_DETAILS action should load user details', () => { const { initialState } = fromUsers; - const userIdentifier = 'dummy'; + const userIdentifier = { fullName: 'dummy' }; const action = new fromUserActions.LoadUserDetails(userIdentifier); const state = fromUsers.reducer(initialState, action); - expect(state.userDetails).toBeDefined(); + expect(state.userDetails.fullName).toBe('dummy'); }); it('LOAD_USER_DETAILS_SUCCESS action should load user details successfully', () => { diff --git a/test_codecept/accessibility/tests/registerOrgAndOtherOrgs.js b/test_codecept/accessibility/tests/registerOrgAndOtherOrgs.js index a71e4243d..31f8e27b6 100644 --- a/test_codecept/accessibility/tests/registerOrgAndOtherOrgs.js +++ b/test_codecept/accessibility/tests/registerOrgAndOtherOrgs.js @@ -50,7 +50,7 @@ describe('Regsiter other orgs', function () { await pa11ytest(this, actions); }); }) - + }); diff --git a/test_codecept/backendMock/app.js b/test_codecept/backendMock/app.js index ec5272eac..30432e0c7 100644 --- a/test_codecept/backendMock/app.js +++ b/test_codecept/backendMock/app.js @@ -14,6 +14,7 @@ const healthRoutes = require('./services/health/routes') const sessionRoutes = require('./services/session/routes') const refDataRoutes = require('./services/refData/routes') const ccdRoutes = require('./services/ccd/routes') +const rdCommonDataRoutes = require('./services/rdCommondata/routes') const acseAssignmentsRoutes = require('./services/caseAssignments/routes') const userApiData = require('./services/userApiData'); class MockApp { @@ -27,7 +28,7 @@ class MockApp { init(clientPortStart) { - + } @@ -52,7 +53,7 @@ class MockApp { app.use(bodyParser.json()); app.use(cookieParser()); - app.use(express.json({ type: '*/*' })); + app.use(express.json({ type: '*/*' })); app.use((req,res,next) => { // console.log(`${req.method} : ${req.url}`); @@ -69,6 +70,7 @@ class MockApp { app.use('/health', healthRoutes) app.use('/refdata/external/v1', refDataRoutes) + app.use('/refdata/commondata/lov', rdCommonDataRoutes ) app.use('/ccd', ccdRoutes) app.use('/case-assignments', acseAssignmentsRoutes ) diff --git a/test_codecept/backendMock/services/rdCommondata/index.js b/test_codecept/backendMock/services/rdCommondata/index.js new file mode 100644 index 000000000..6977a4fc2 --- /dev/null +++ b/test_codecept/backendMock/services/rdCommondata/index.js @@ -0,0 +1,537 @@ + +const { v4 } = require('uuid'); + +class RefData{ + + constructor(){ + + } + + getOrganization(){ + return orgResponse; + } + + + getUsers(count){ + const usersResponse = { + "organisationIdentifier": "NPT8F21", + users:[] + } + + for(let i = 0; i< count;i++){ + usersResponse.users.push({ + "userIdentifier": "0407967c-93bd-4890-a2a5-da7dad3d71e1", + "firstName": "Pet", + "lastName": "Solicitor 2", + "email": "div-petsol-2@mailinator.com", + "idamStatus": "ACTIVE" + }) + } + return usersResponse; + } + +} + + +module.exports = new RefData(); + + +const orgResponse = { + "name": "Townley Services (TEST) - LaunchDarkly", + "organisationIdentifier": "NPT8F21", + "contactInformation": [ + { + "addressId": "f0bd992b-a1f1-4aef-9935-b28acf26aa67", + "uprn": null, + "created": "2020-04-28T14:59:38.379", + "addressLine1": "28", + "addressLine2": "Sparrowgrove", + "addressLine3": null, + "townCity": "Otterbourne", + "county": "Winchester", + "country": null, + "postCode": "SE6 TU7", + "dxAddress": [ + { + "dxNumber": "DX87744556322", + "dxExchange": "Winchester" + } + ] + } + ], + "status": "ACTIVE", + "sraId": "SRA542467777", + "sraRegulated": false, + "superUser": { + "firstName": "Townley", + "lastName": "Winchester", + "email": "townley.winchester@mailnesia.com" + }, + "paymentAccount": [ + "PBA0356049", + "PBA2445562" + ], + "pendingPaymentAccount": [], + "dateReceived": "2020-04-28T14:59:38.284", + "dateApproved": null +} + + + +const lovRefData = [ + { + "category_key": "HearingType", + "key": "ABA5-BRE", + "value_en": "Breach", + "value_cy": "Torri Amodau", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 4, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FOF", + "value_en": "Finding of Fact", + "value_cy": "Canfod y Ffeithiau", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 12, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FRF", + "value_en": "Financial remedy first appointment", + "value_cy": "Apwyntiad cyntaf rhwymedi ariannol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FRD", + "value_en": "Financial remedy directions", + "value_cy": "Cyfarwyddiadau rhwymedi ariannol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FRI", + "value_en": "Financial remedy interim order", + "value_cy": "Gorchymyn interim rhwymedi ariannol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FRR", + "value_en": "Financial remedy financial dispute resolution", + "value_cy": "Rhwymedi ariannol datrys anghydfod ariannol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FHD", + "value_en": "First Hearing Dispute Resolution Appointment (FHDRA)", + "value_cy": "Apwyntiad Datrys Anghydfod Gwrandawiad Cyntaf (FHDRA)", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 26, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FHR", + "value_en": "First Hearing", + "value_cy": "Gwrandawiad Cyntaf", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 13, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FFH", + "value_en": "Full/Final hearing", + "value_cy": "Gwrandawiad Llawn/Terfynol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 14, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-SGA", + "value_en": "Safeguarding Gatekeeping Appointment", + "value_cy": "Apwyntiad Neilltuo Diogelwch", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 24, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-SCF", + "value_en": "Settlement Conference", + "value_cy": "Cynhadledd Setlo", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 25, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-JMT", + "value_en": "Judgment", + "value_cy": "Dyfarniad", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 19, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-FCM", + "value_en": "Further Case Management Hearing", + "value_cy": "Gwrandawiad Rheoli Achos Pellach", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 15, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-ALL", + "value_en": "Allocation", + "value_cy": "Dyrannu", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 1, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-APP", + "value_en": "Application", + "value_cy": "Cais", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 3, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-APL", + "value_en": "Appeal", + "value_cy": "Apêl", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 2, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-REV", + "value_en": "Review", + "value_cy": "Adolygiad", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 23, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-NEH", + "value_en": "Neutral Evaluation Hearing", + "value_cy": "Gwrandawiad Gwerthusiad Niwtral", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 20, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-IRH", + "value_en": "Issues Resolution Hearing", + "value_cy": "Gwrandawiad Datrys Materion", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-ISO", + "value_en": "Interim Supervision Order", + "value_cy": "Gorchymyn Goruchwylio Interim", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-ICO", + "value_en": "Interim Care Order", + "value_cy": "Gorchymyn Gofal Interim", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-HRA", + "value_en": "Human Rights Act Application", + "value_cy": "Cais dan y Ddeddf Hawliau Dynol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 18, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-DRA", + "value_en": "Dispute Resolution Appointment", + "value_cy": "Apwyntiad Datrys Anghydfod", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 11, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-DIR", + "value_en": "Directions (First/Further)", + "value_cy": "Cyfarwyddiadau (Cyntaf/Pellach)", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 10, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-PRE", + "value_en": "Preliminary (REMO)", + "value_cy": "Rhagarweiniol (REMO)", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-GRH", + "value_en": "Ground Rules Hearing", + "value_cy": "Gwrandawiad rheolau sylfaenol", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 17, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-CHR", + "value_en": "Celebration hearing", + "value_cy": "Gwrandawiad Dathlu", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-2GA", + "value_en": "2nd Gatekeeping Appointment", + "value_cy": "2il Apwyntiad Neilltuo", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 16, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-PHR", + "value_en": "Pre Hearing Review", + "value_cy": "Adolygiad Cyn Gwrandawiad", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 22, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-COM", + "value_en": "Committal", + "value_cy": "Traddodi", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 7, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-CON", + "value_en": "Conciliation", + "value_cy": "Cymodi", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 8, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-COS", + "value_en": "Costs", + "value_cy": "Costau", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 9, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-PER", + "value_en": "Permission Hearing", + "value_cy": "Gwrandawiad Caniatâd", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 21, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-CMC", + "value_en": "Case Management Conference", + "value_cy": "Cynhadledd Rheoli Achos", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 5, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "HearingType", + "key": "ABA5-CMH", + "value_en": "Case Management Hearing", + "value_cy": "Gwrandawiad Rheoli Achos", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": 6, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + } +] diff --git a/test_codecept/backendMock/services/rdCommondata/routes.js b/test_codecept/backendMock/services/rdCommondata/routes.js new file mode 100644 index 000000000..58e727c4b --- /dev/null +++ b/test_codecept/backendMock/services/rdCommondata/routes.js @@ -0,0 +1,491 @@ + + +const express = require('express') + +const router = express.Router({ mergeParams: true }); +const service = require('./index') + + + +router.get('/categories/OrgType', (req, res) => { + res.send({ list_of_values: lovRefData_OrgTypes }) +}); + + + + +const lovRefData_OrgTypes = [ + { + "category_key": "OrgType", + "key": "BARR", + "value_en": "Barrister", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgType", + "key": "GOVT", + "value_en": "Government Organisation", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgType", + "key": "SOLICITOR", + "value_en": "Solicitor", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgType", + "key": "LOCALAUTH", + "value_en": "Local Authority", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgType", + "key": "OTHER", + "value_en": "Other", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": [ + { + "category_key": "OrgSubType", + "key": "OTHER-ACCOUNT", + "value_en": "Accountancy, banking and finance", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-PUBDEF", + "value_en": "Public sector & defence", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ENV", + "value_en": "Environment and agriculture", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-RETAIL", + "value_en": "Retail & wholesale", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-HEALTH", + "value_en": "Healthcare", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-PROP", + "value_en": "Property and construction", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-EDU", + "value_en": "Education", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-BUSI", + "value_en": "Business, consulting and management", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ADMIN", + "value_en": "Admin and support", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-MARK", + "value_en": "Marketing, advertising and PR", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-NFP", + "value_en": "Not for profit", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-TRANSP", + "value_en": "Transport and logistics", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ACCOM", + "value_en": "Accommodation & food", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-SOCIAL", + "value_en": "Social care", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-SCIENCE", + "value_en": "Science and pharmaceuticals", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ENERGY", + "value_en": "Energy and utilities", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ENGG", + "value_en": "Engineering and manufacturing", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-CHARITY", + "value_en": "Charity and voluntary work", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-MINING", + "value_en": "Mining and quarrying", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-PUBADM", + "value_en": "Public services and administration", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-LAW", + "value_en": "Law enforcement and security", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-MEDIA", + "value_en": "Media and internet", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-HOSP", + "value_en": "Hospitality and events management", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-FIN", + "value_en": "Financial services", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-LEISURE", + "value_en": "Leisure, sport and tourism", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-REC", + "value_en": "Recruitment and HR", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-CREATI", + "value_en": "Creative arts and design", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-SALES", + "value_en": "Sales", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-ITCOMM", + "value_en": "IT & communications", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + }, + { + "category_key": "OrgSubType", + "key": "OTHER-REALT", + "value_en": "Real estate activities", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "OrgType", + "parent_key": "OTHER", + "active_flag": "Y", + "child_nodes": null + } + ] + }, + { + "category_key": "OrgType", + "key": "PROBPRAC", + "value_en": "Probate Practitioner", + "value_cy": "", + "hint_text_en": "", + "hint_text_cy": "", + "lov_order": null, + "parent_category": "", + "parent_key": "", + "active_flag": "Y", + "child_nodes": null + } +] + + +module.exports = router; + diff --git a/test_codecept/codeceptCommon/codecept.conf.ts b/test_codecept/codeceptCommon/codecept.conf.ts index d92a82c5c..55b01239b 100644 --- a/test_codecept/codeceptCommon/codecept.conf.ts +++ b/test_codecept/codeceptCommon/codecept.conf.ts @@ -26,7 +26,7 @@ console.log(`headless : ${!head}`) let pipelineBranch = process.env.TEST_URL.includes('pr-') ? "preview" : "master" let features = '' -if (testType === 'e2e' || testType === 'smoke'){ +if (testType === 'e2e' || testType === 'smoke'){ features = `../e2e/features/app/**/*.feature` } else if (testType === 'ngIntegration' && pipelineBranch === 'preview'){ features = `../ngIntegration/tests/features/**/*.feature` @@ -96,7 +96,6 @@ exports.config = { // '--disable-setuid-sandbox', '--no-zygote ', '--disableChecks' // ] // } - // }, Playwright: { url: "https://manage-case.aat.platform.hmcts.net", @@ -115,7 +114,7 @@ exports.config = { }, "mocha": { // reporter: 'mochawesome', - + // "reporterOptions": { // "reportDir": functional_output_dir, // reportName:'XUI_MC', @@ -138,7 +137,7 @@ exports.config = { // // inlineAssets: true, // }, - + // "mochawesome": { // "stdout": `${functional_output_dir}/`, // "options": { @@ -157,14 +156,14 @@ exports.config = { // } // } // } - + }, plugins:{ screenshotOnFail: { enabled: true, fullPageScreenshots: true }, - + "myPlugin": { "require": "./hooks", "enabled": true @@ -183,7 +182,7 @@ exports.config = { includeExampleValues: false, // if true incorporate actual values from Examples table along with variable placeholder when writing steps to the report timeMultiplier: 1000000, // Used when calculating duration of individual BDD steps. Defaults to nanoseconds } - + }, include: { }, @@ -195,26 +194,26 @@ exports.config = { if(!parallel){ await setup() } - + }, teardown: async () => { if (!parallel) { await teardown() } - - + + }, bootstrapAll: async () => { if (parallel) { await setup() } - + }, - teardownAll: async () => { + teardownAll: async () => { if (parallel) { await teardown() } - + } } @@ -231,7 +230,7 @@ async function setup(){ await backendMockApp.startServer(debugMode); await applicationServer.start() } - + } async function teardown(){ @@ -314,4 +313,4 @@ async function cucumberReportUpdateEmbeddings() { } -} \ No newline at end of file +} diff --git a/test_codecept/e2e/features/app/createOrganisation.feature b/test_codecept/e2e/features/app/createOrganisation.feature index 6630e07c5..aa5ba4e7b 100644 --- a/test_codecept/e2e/features/app/createOrganisation.feature +++ b/test_codecept/e2e/features/app/createOrganisation.feature @@ -1,10 +1,14 @@ -@fullFunctional @AAT_only @functional_debug +@fullFunctional Feature: Register Organization Background: # When I navigate to manage organisation Url # Given I am logged into manage organisation with SSCS judge details # Then I should be redirected to manage organisation dashboard page + When I navigate to manage organisation Url + Given I am logged in with ROO user targetting OFF + Then I should be redirected to manage organisation dashboard page + When I navigate to EUI Manage Organisation Url Then I land on register organisation page and continue diff --git a/test_codecept/e2e/features/app/inviteUser.feature b/test_codecept/e2e/features/app/inviteUser.feature index bc1802665..ca123d88a 100644 --- a/test_codecept/e2e/features/app/inviteUser.feature +++ b/test_codecept/e2e/features/app/inviteUser.feature @@ -47,6 +47,12 @@ Feature: invite user workflow When I not enter the mandatory fields firstname,lastname,emailaddress,permissions and click on send invitation button Then I should be display the validation error +@fullFunctional + Scenario: invite user validation workflow + When I enter mandatory fields firstname,lastname,emailaddress with permissions and click on send invitation button + | Permission | + Then I should be display the validation error + @fullFunctional Scenario: back button workflow When I click on back button diff --git a/test_codecept/e2e/features/app/registerOtherOrg.feature b/test_codecept/e2e/features/app/registerOtherOrg.feature index e4080b6c3..aa9513a4e 100644 --- a/test_codecept/e2e/features/app/registerOtherOrg.feature +++ b/test_codecept/e2e/features/app/registerOtherOrg.feature @@ -1,7 +1,12 @@ -@fullFunctional @preview_only +@fullFunctional Feature: Register other org, registration Scenario: register other org workflow with all optional values + + When I navigate to manage organisation Url + Given I am logged in with ROO user targetting ON + Then I should be redirected to manage organisation dashboard page + Given I navigate to register other org start page Then I am on register other org page "Apply for an organisation to manage civil, family and tribunal cases" Then In register other org page "Apply for an organisation to manage civil, family and tribunal cases", I validate fields displayed @@ -126,7 +131,7 @@ Feature: Register other org, registration | Organisation address | auto building,auto addr 2,auto addr 3,auto city,auto country,SW1V 3BZ,UK | | DX reference | DX12345, HAYES (MIDDLESEX) | | Service to access | Divorce,Damages | - | PBA number(s) | PBA1234567,PBA7654321 | + | What PBA numbers does your organisation use? | PBA1234567,PBA7654321 | | Regulatory organisation type | Other: test name ref: test number | | First name(s) | auto test fn | | Last name | auto test ln | @@ -135,6 +140,10 @@ Feature: Register other org, registration Scenario: register other org workflow with minimum values + When I navigate to manage organisation Url + Given I am logged in with ROO user targetting ON + Then I should be redirected to manage organisation dashboard page + Given I navigate to register other org start page Then I am on register other org page "Apply for an organisation to manage civil, family and tribunal cases" Then In register other org page "Apply for an organisation to manage civil, family and tribunal cases", I validate fields displayed diff --git a/test_codecept/e2e/features/app/registerOtherOrgNavigation.feature b/test_codecept/e2e/features/app/registerOtherOrgNavigation.feature index d2063e09a..f98e50b5a 100644 --- a/test_codecept/e2e/features/app/registerOtherOrgNavigation.feature +++ b/test_codecept/e2e/features/app/registerOtherOrgNavigation.feature @@ -1,8 +1,12 @@ -@fullFunctional @preview_only +@fullFunctional Feature: Register other org, Navigations Background: rgister org fill pages + When I navigate to manage organisation Url + Given I am logged in with ROO user targetting ON + Then I should be redirected to manage organisation dashboard page + Given I navigate to register other org start page Then I am on register other org page "Apply for an organisation to manage civil, family and tribunal cases" Then In register other org page "Apply for an organisation to manage civil, family and tribunal cases", I validate fields displayed @@ -176,7 +180,7 @@ Feature: Register other org, Navigations | Organisation address | What is the registered address of your organisation? | | DX reference | What's the DX reference for this office? | | Service to access | Which services will your organisation need to access? | - | PBA number(s) | Does your organisation have a payment by account number? | + | Does your organisation have a payment by account number? | Does your organisation have a payment by account number? | | Regulatory organisation type | Who is your organisation registered with? | | First name(s) | Provide your contact details | | Last name | Provide your contact details | diff --git a/test_codecept/e2e/features/app/registerOtherOrgPageValidations.feature b/test_codecept/e2e/features/app/registerOtherOrgPageValidations.feature index 3048eab15..662981eb2 100644 --- a/test_codecept/e2e/features/app/registerOtherOrgPageValidations.feature +++ b/test_codecept/e2e/features/app/registerOtherOrgPageValidations.feature @@ -1,6 +1,10 @@ -@fullFunctional @preview_only +@fullFunctional Feature: Register other org, page validations + Background: + When I navigate to manage organisation Url + Given I am logged in with ROO user targetting ON + Then I should be redirected to manage organisation dashboard page Scenario: Register other org, page level validations in What type of organisation are you registering? When In register organisation workflow, I navigate to route "organisation-type" diff --git a/test_codecept/e2e/features/app/unassignedCases.feature b/test_codecept/e2e/features/app/unassignedCases.feature index 7dd085623..db39b9df8 100644 --- a/test_codecept/e2e/features/app/unassignedCases.feature +++ b/test_codecept/e2e/features/app/unassignedCases.feature @@ -1,5 +1,5 @@ -@functional_debug + Feature: Unassigned cases tab Scenario: page validation diff --git a/test_codecept/e2e/features/step_definitions/loginLogout.steps.js b/test_codecept/e2e/features/step_definitions/loginLogout.steps.js index 8e1c4d528..2c3da8b16 100644 --- a/test_codecept/e2e/features/step_definitions/loginLogout.steps.js +++ b/test_codecept/e2e/features/step_definitions/loginLogout.steps.js @@ -12,7 +12,6 @@ const acceptTermsAndConditionsPage = require('../pageObjects/termsAndConditionsC const HeaderPage = require('../pageObjects/headerPage'); const browser = require('../../../codeceptCommon/browser'); -const { THIS_EXPR } = require('@angular/compiler/src/output/output_ast'); const headerPage = new HeaderPage(); async function waitForElement(el) { @@ -136,10 +135,31 @@ async function waitForElement(el) { // await loginPage.password.sendKeys(config.config.townleyPassword); // // browser.sleep(SHORT_DELAY); // await loginPage.signinBtn.click(); - await loginattemptCheckAndRelogin(config.config.townleyUser, config.config.townleyPassword, THIS_EXPR); + const world = this; + await loginattemptCheckAndRelogin(config.config.townleyUser, config.config.townleyPassword, world); }); +Given(/^I am logged in with ROO user targetting ON$/, async function () { + // await loginPage.emailAddress.sendKeys(config.config.townleyUser); //replace username and password + // await loginPage.password.sendKeys(config.config.townleyPassword); + // // browser.sleep(SHORT_DELAY); + // await loginPage.signinBtn.click(); + const world = this; + await loginattemptCheckAndRelogin('xui_mo_roo_on@mailinator.com', 'Welcome01', world); + +}); + +Given(/^I am logged in with ROO user targetting OFF$/, async function () { + // await loginPage.emailAddress.sendKeys(config.config.townleyUser); //replace username and password + // await loginPage.password.sendKeys(config.config.townleyPassword); + // // browser.sleep(SHORT_DELAY); + // await loginPage.signinBtn.click(); + const world = this; + await loginattemptCheckAndRelogin('xui_mo_roo_off@mailinator.com', 'Welcome01', world); + +}); + Given('I am logged into manage organisation with test org user', async function(){ const world = this; this.attach('Login user : ' + global.testorg_rw_superuser_email); diff --git a/yarn.lock b/yarn.lock index 6cd64fe84..e6f2377ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2339,16 +2339,16 @@ __metadata: languageName: node linkType: hard -"@hmcts/rpx-xui-common-lib@npm:1.9.0-route-expected-feature-2": - version: 1.9.0-route-expected-feature-2 - resolution: "@hmcts/rpx-xui-common-lib@npm:1.9.0-route-expected-feature-2" +"@hmcts/rpx-xui-common-lib@npm:1.9.0-error-message-change": + version: 1.9.0-error-message-change + resolution: "@hmcts/rpx-xui-common-lib@npm:1.9.0-error-message-change" dependencies: tslib: ^2.0.0 peerDependencies: launchdarkly-js-client-sdk: ^2.15.2 ngx-pagination: ^3.2.1 rpx-xui-translation: ^0.1.1 - checksum: 6408bf39a6fb459bc624022d4b964e1d034e3d35980a3b602606a9483234981774d12713903b876ebe5bdbc920ff8b68c4ba3d11aa210b3c07219cb1d10d02b8 + checksum: 2e8404920ee29fcbc1f3bb1aa07d00927b6e0b64d967236e586cc537d2a259c74d4c0d53a6e1ee1f08b0f5ffcaf044009859a1dfa0daa75625b4da2241ec03fd languageName: node linkType: hard @@ -20201,7 +20201,7 @@ __metadata: "@hmcts/frontend": 0.0.50-alpha "@hmcts/nodejs-healthcheck": 1.7.0 "@hmcts/properties-volume": 0.0.13 - "@hmcts/rpx-xui-common-lib": 1.9.0-route-expected-feature-2 + "@hmcts/rpx-xui-common-lib": 1.9.0-error-message-change "@hmcts/rpx-xui-node-lib": 2.27.1 "@ng-idle/core": ^10.0.0 "@ng-idle/keepalive": ^10.0.0