Skip to content
Merged

PO-2420 #2350

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6732c9c
PO-2420
Arnabsubedi233 Mar 18, 2026
161a4f9
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 18, 2026
bb99846
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 18, 2026
aa87636
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 18, 2026
fbd5717
remove unused import
Arnabsubedi233 Mar 19, 2026
d8a725c
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 19, 2026
689bf9b
Comment response
Arnabsubedi233 Mar 19, 2026
385ab3e
Bumping chart version/ fixing aliases
hmcts-jenkins-cnp[bot] Mar 19, 2026
c2c4c55
Merge branch 'PO-2417' of https://github.com/hmcts/opal-frontend into…
Arnabsubedi233 Mar 24, 2026
ceaff7e
fixing merge issues
Arnabsubedi233 Mar 24, 2026
c42a563
Bumping chart version/ fixing aliases
hmcts-jenkins-cnp[bot] Mar 24, 2026
b485ddd
Merge branch 'PO-2417' into PO-2420
jonathanDuffy Mar 24, 2026
64fc427
Merge branch 'PO-2417' into PO-2420
jonathanDuffy Mar 26, 2026
96e0d31
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 26, 2026
c4c196f
fixing accessibility issue
Arnabsubedi233 Mar 26, 2026
21857bb
Merge branch 'PO-2417' into PO-2420
jonathanDuffy Mar 27, 2026
85cb1e3
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 30, 2026
21405e4
Merge branch 'PO-2417' into PO-2420
jonathanDuffy Mar 30, 2026
71b5caf
Fixing bold display on tables.
Arnabsubedi233 Mar 30, 2026
ff5f80d
Merge branch 'PO-2420' of https://github.com/hmcts/opal-frontend into…
Arnabsubedi233 Mar 30, 2026
6278fca
Merge branch 'PO-2417' into PO-2420
Arnabsubedi233 Mar 30, 2026
b29c8ba
Add Consolidation Result Test Coverage (#2368)
jonathanDuffy Mar 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
777 changes: 777 additions & 0 deletions cypress/component/fines/consolidation/AccountResult.cy.ts

Large diffs are not rendered by default.

311 changes: 236 additions & 75 deletions cypress/component/fines/consolidation/AccountSearch.cy.ts

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions cypress/component/fines/consolidation/ErrorPage.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { mount } from 'cypress/angular';
import { ActivatedRoute, provideRouter } from '@angular/router';
import { FinesConSearchErrorComponent } from 'src/app/flows/fines/fines-con/consolidate-acc/fines-con-search-error/fines-con-search-error.component';
import { FinesConStore } from 'src/app/flows/fines/fines-con/stores/fines-con.store';
import { ErrorPageLocators } from 'cypress/shared/selectors/consolidation/ErrorPage.locators';

const CONSOLIDATION_JIRA_LABEL = '@JIRA-LABEL:consolidation';
const CONSOLIDATION_STORY_LABEL = '@JIRA-STORY:PO-2417';

const buildTags = (...tags: string[]): string[] => [...tags, CONSOLIDATION_JIRA_LABEL, CONSOLIDATION_STORY_LABEL];

describe('FinesConSearchErrorComponent', () => {
const setupComponent = (defendantType: 'individual' | 'company') => {
return mount(FinesConSearchErrorComponent, {
providers: [
provideRouter([]),
FinesConStore,
{
provide: ActivatedRoute,
useValue: {
parent: {},
},
},
],
}).then(({ fixture }) => {
const store = fixture.componentRef.injector.get(FinesConStore);
cy.stub(store, 'getDefendantType').returns(defendantType);
expect(store.getDefendantType()).to.equal(defendantType);
fixture.detectChanges();
});
};

const assertHeadingAndIntro = () => {
cy.get(ErrorPageLocators.heading).should('contain', 'There is a problem');
cy.get(ErrorPageLocators.message)
.invoke('text')
.then((text) => {
const normalisedText = text.replace(/\s+/g, ' ').trim();
expect(normalisedText).to.equal(
'Reference data and account information cannot be entered together when searching for an account. Search using either:',
);
});
};

it('AC2a. displays the individual search error heading and message text', { tags: buildTags() }, () => {
setupComponent('individual');

assertHeadingAndIntro();
cy.get(ErrorPageLocators.bulletItems).then(($items) => {
const items = [...$items].map((item) => item.textContent?.replace(/\s+/g, ' ').trim());
expect(items).to.deep.equal(['account number, or', 'National Insurance number, or', 'advanced search']);
});
});

it('AC2b. displays the company search error heading and message text', { tags: buildTags() }, () => {
setupComponent('company');

assertHeadingAndIntro();
cy.get(ErrorPageLocators.bulletItems).then(($items) => {
const items = [...$items].map((item) => item.textContent?.replace(/\s+/g, ' ').trim());
expect(items).to.deep.equal(['account number, or', 'advanced search']);
});
});
});
183 changes: 183 additions & 0 deletions cypress/component/fines/consolidation/mocks/account_results_mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { IFinesConSearchResultDefendantAccount } from '@app/flows/fines/fines-con/consolidate-acc/fines-con-search-result/interfaces/fines-con-search-result-defendant-account.interface';
import { FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK } from '@app/flows/fines/fines-con/consolidate-acc/fines-con-search-result/mocks/fines-con-search-result-defendant-accounts-company-formatting.mock';
import { FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK } from '@app/flows/fines/fines-con/consolidate-acc/fines-con-search-result/mocks/fines-con-search-result-defendant-accounts-formatting.mock';

export const createFalseyResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK[0]),
defendant_account_id: 12,
account_number: 'ACC002',
aliases: null,
address_line_1: null,
postcode: null,
prosecutor_case_reference: null,
last_enforcement_action: null,
account_balance: null,
defendant_firstnames: null,
defendant_surname: null,
birth_date: null,
national_insurance_number: null,
collection_order: false,
last_enforcement: null,
has_paying_parent_guardian: false,
checks: {
errors: [],
warnings: [],
},
});

export const createCompanyFalseyResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK[0]),
defendant_account_id: 22,
account_number: 'COMP002',
aliases: null,
address_line_1: null,
postcode: null,
prosecutor_case_reference: null,
last_enforcement_action: null,
account_balance: null,
organisation_name: null,
collection_order: false,
last_enforcement: null,
checks: {
errors: [],
warnings: [],
},
});

export const createMaxResultsMock = (): IFinesConSearchResultDefendantAccount[] =>
Array.from({ length: 100 }, (_, index) => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK[0]),
defendant_account_id: index + 1,
account_number: `ACC${String(index + 1).padStart(3, '0')}`,
aliases: null,
prosecutor_case_reference: `REF-${index + 1}`,
defendant_firstnames: `First${index + 1}`,
defendant_surname: `Surname${index + 1}`,
birth_date: '1990-01-03',
account_balance: 50 + index,
has_paying_parent_guardian: false,
checks: {
errors: [],
warnings: [],
},
}));

export const createTooManyResultsMock = (): IFinesConSearchResultDefendantAccount[] => [
...createMaxResultsMock(),
{
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK[0]),
defendant_account_id: 101,
account_number: 'ACC101',
aliases: null,
prosecutor_case_reference: 'REF-101',
defendant_firstnames: 'First101',
defendant_surname: 'Surname101',
birth_date: '1990-01-03',
account_balance: 150,
has_paying_parent_guardian: false,
checks: {
errors: [],
warnings: [],
},
},
];

export const createCompanyMaxResultsMock = (): IFinesConSearchResultDefendantAccount[] =>
Array.from({ length: 100 }, (_, index) => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK[0]),
defendant_account_id: index + 1,
account_number: `COMP${String(index + 1).padStart(3, '0')}`,
aliases: null,
prosecutor_case_reference: `COMP-REF-${index + 1}`,
organisation_name: `Company ${index + 1}`,
account_balance: 500 + index,
checks: {
errors: [],
warnings: [],
},
}));

export const createCompanyTooManyResultsMock = (): IFinesConSearchResultDefendantAccount[] => [
...createCompanyMaxResultsMock(),
{
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK[0]),
defendant_account_id: 101,
account_number: 'COMP101',
aliases: null,
prosecutor_case_reference: 'COMP-REF-101',
organisation_name: 'Company 101',
account_balance: 600,
checks: {
errors: [],
warnings: [],
},
},
];

export const createMultipleErrorsAndWarningsResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK[0]),
defendant_account_id: 15,
account_number: 'ACC005',
prosecutor_case_reference: 'REF-5',
defendant_firstnames: 'Erin',
defendant_surname: 'Example',
checks: {
errors: [
{ reference: 'CON.ER.1', message: 'Account status is CS' },
{ reference: 'CON.ER.2', message: 'Account is blocked for consolidation' },
],
warnings: [
{ reference: 'CON.WN.1', message: 'Account has uncleared cheque payments' },
{ reference: 'CON.WN.2', message: 'Account has linked cases' },
],
},
});

export const createMultipleWarningsResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_FORMATTING_MOCK[0]),
defendant_account_id: 16,
account_number: 'ACC006',
prosecutor_case_reference: 'REF-6',
defendant_firstnames: 'Wendy',
defendant_surname: 'Warning',
checks: {
errors: [],
warnings: [
{ reference: 'CON.WN.1', message: 'Account has uncleared cheque payments' },
{ reference: 'CON.WN.2', message: 'Account has linked cases' },
],
},
});

export const createCompanyMultipleErrorsAndWarningsResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK[0]),
defendant_account_id: 25,
account_number: 'COMP005',
prosecutor_case_reference: 'COMP-REF-5',
organisation_name: 'Errors & Warnings Ltd',
checks: {
errors: [
{ reference: 'CON.ER.1', message: 'Account status is CS' },
{ reference: 'CON.ER.2', message: 'Account is blocked for consolidation' },
],
warnings: [
{ reference: 'CON.WN.1', message: 'Account has uncleared cheque payments' },
{ reference: 'CON.WN.2', message: 'Account has linked cases' },
],
},
});

export const createCompanyMultipleWarningsResult = (): IFinesConSearchResultDefendantAccount => ({
...structuredClone(FINES_CON_SEARCH_RESULT_DEFENDANT_ACCOUNTS_COMPANY_FORMATTING_MOCK[0]),
defendant_account_id: 26,
account_number: 'COMP006',
prosecutor_case_reference: 'COMP-REF-6',
organisation_name: 'Warnings Only Ltd',
checks: {
errors: [],
warnings: [
{ reference: 'CON.WN.1', message: 'Account has uncleared cheque payments' },
{ reference: 'CON.WN.2', message: 'Account has linked cases' },
],
},
});
6 changes: 6 additions & 0 deletions cypress/component/fines/consolidation/setup/SetupComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { IComponentProperties } from './setupComponent.interface';
export const setupConsolidationComponent = (componentProperties: IComponentProperties = {}) => {
const fragment = componentProperties.fragments ?? 'search';
const defendantType = componentProperties.defendantType ?? 'individual';
const initialResults = structuredClone(componentProperties.initialResults ?? []);

const finesConSelectBuFormData =
defendantType === 'company'
Expand All @@ -32,6 +33,11 @@ export const setupConsolidationComponent = (componentProperties: IComponentPrope
const store = new FinesConStore();
store.updateSelectBuForm(finesConSelectBuFormData);
store.updateSearchAccountFormTemporary(searchAccountFormData);
if (defendantType === 'company') {
store.updateDefendantResults([], initialResults);
} else {
store.updateDefendantResults(initialResults, []);
}
store.setActiveTab(fragment);

if (componentProperties.updateSearchSpy) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IFinesConSearchAccountState } from 'src/app/flows/fines/fines-con/consolidate-acc/fines-con-search-account/interfaces/fines-con-search-account-state.interface';
import { IFinesConSearchResultDefendantAccount } from 'src/app/flows/fines/fines-con/consolidate-acc/fines-con-search-result/interfaces/fines-con-search-result-defendant-account.interface';

export type ConsolidationTabFragment = 'search' | 'results' | 'for-consolidation';
export type DefendantType = 'individual' | 'company';
Expand All @@ -7,6 +8,7 @@ export interface IComponentProperties {
defendantType?: DefendantType;
fragments?: ConsolidationTabFragment;
searchAccountFormData?: IFinesConSearchAccountState;
initialResults?: IFinesConSearchResultDefendantAccount[];
setupRouterSpy?: boolean;
updateSearchSpy?: (formData: IFinesConSearchAccountState) => void;
}
Loading