diff --git a/package.json b/package.json index aaa0ab8212..a8165e5c21 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "@hmcts/info-provider": "^1.1.0", "@hmcts/nodejs-healthcheck": "^1.8.5", "@hmcts/nodejs-logging": "^4.0.4", - "@hmcts/opal-frontend-common": "^0.0.66", + "@hmcts/opal-frontend-common": "^0.0.67", "@hmcts/opal-frontend-common-node": "^0.0.27", "@hmcts/properties-volume": "^1.1.0", "@hmcts/zephyr-automation-nodejs": "0.0.6", diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-at-a-glance-tab/fines-acc-defendant-details-at-a-glance-tab.component.html b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-at-a-glance-tab/fines-acc-defendant-details-at-a-glance-tab.component.html index 6d6bf36d3a..409d2f89ac 100644 --- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-at-a-glance-tab/fines-acc-defendant-details-at-a-glance-tab.component.html +++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-at-a-glance-tab/fines-acc-defendant-details-at-a-glance-tab.component.html @@ -244,22 +244,12 @@
- Add enforcement action + Add enforcement action
} @if ( @@ -345,13 +345,13 @@- Request an HMRC check + Request an HMRC check
} diff --git a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts index bcace27490..a31790ff9f 100644 --- a/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts +++ b/src/app/flows/fines/fines-acc/fines-acc-defendant-details/fines-acc-defendant-details-enforcement-tab/fines-acc-defendant-details-enforcement-tab.component.spec.ts @@ -22,6 +22,56 @@ describe('FinesAccDefendantDetailsEnforcementTab', () => { expect(component).toBeTruthy(); }); + it('should enforce action link template semantics', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const templateConsts = ((FinesAccDefendantDetailsEnforcementTab as any).ɵcmp?.consts ?? []).filter( + (entry: unknown) => Array.isArray(entry), + ) as unknown[][]; + const templateFunction = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ((FinesAccDefendantDetailsEnforcementTab as any).ɵcmp?.template?.toString() as string | undefined) ?? ''; + const actionLinkConsts = templateConsts.filter( + (entry) => + entry.includes('govuk-link') && entry.includes('govuk-link--no-visited-state') && entry.includes('href'), + ); + + expect(actionLinkConsts.length).toBeGreaterThan(0); + actionLinkConsts.forEach((entry) => { + expect(entry).toContain('href'); + expect(entry).toContain(''); + expect(entry).not.toContain('tabindex'); + }); + expect(templateFunction).not.toContain('keydown.enter'); + expect(templateFunction).not.toContain('keyup.enter'); + }); + + it('should render action links with empty href, no visited state, and no tabindex', () => { + const tabData = structuredClone(OPAL_FINES_ACCOUNT_DEFENDANT_DETAILS_ENFORCEMENT_TAB_REF_DATA_MOCK); + tabData.enforcement_override = null; + + fixture.componentRef.setInput('tabData', tabData); + fixture.componentRef.setInput('hasAccountMaintenancePermission', true); + fixture.componentRef.setInput('hasEnterEnforcementPermission', true); + fixture.detectChanges(); + + const actionLinks = Array.from( + fixture.nativeElement.querySelectorAll('div.govuk-grid-column-one-third p > a.govuk-link'), + ) as HTMLAnchorElement[]; + + expect(actionLinks).toHaveLength(3); + expect(actionLinks.map((link) => link.textContent?.trim())).toEqual([ + 'Add enforcement action', + 'Add enforcement override', + 'Request an HMRC check', + ]); + + actionLinks.forEach((link) => { + expect(link.classList.contains('govuk-link--no-visited-state')).toBe(true); + expect(link.getAttribute('href')).toBe(''); + expect(link.getAttribute('tabindex')).toBeNull(); + }); + }); + it('should handleAddEnforcementOverride when add enforcement override button is clicked', () => { const eventEmitterSpy = vi.spyOn(component.addEnforcementOverride, 'emit'); const event = { preventDefault: vi.fn() } as unknown as Event; diff --git a/src/app/flows/fines/fines-acc/fines-acc-party-add-amend-convert/fines-acc-party-add-amend-convert-form/fines-acc-party-add-amend-convert-form.component.html b/src/app/flows/fines/fines-acc/fines-acc-party-add-amend-convert/fines-acc-party-add-amend-convert-form/fines-acc-party-add-amend-convert-form.component.html index 6bf7655a37..63dbf6fa68 100644 --- a/src/app/flows/fines/fines-acc/fines-acc-party-add-amend-convert/fines-acc-party-add-amend-convert-form/fines-acc-party-add-amend-convert-form.component.html +++ b/src/app/flows/fines/fines-acc/fines-acc-party-add-amend-convert/fines-acc-party-add-amend-convert-form/fines-acc-party-add-amend-convert-form.component.html @@ -85,9 +85,10 @@To resubmit accounts for other team members, you can view all rejected accounts.
diff --git a/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.spec.ts b/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.spec.ts index de182ccabb..d957a798c7 100644 --- a/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.spec.ts +++ b/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.spec.ts @@ -150,6 +150,40 @@ describe('FinesDraftCreateAndManageTabsComponent', () => { expect(mockRouter.navigate).toHaveBeenCalledWith([route], { relativeTo: component['activatedRoute'].parent }); }); + it('should prevent default and navigate when handleRoute is called with an event', () => { + const route = 'some/route'; + const event = new Event('click'); + const preventDefaultSpy = vi.spyOn(event, 'preventDefault'); + component.activeTab = 'review'; + + component.handleRoute(route, event); + + expect(preventDefaultSpy).toHaveBeenCalled(); + expect(finesDraftStore.fragment()).toEqual('review'); + expect(mockRouter.navigate).toHaveBeenCalledWith([route], { relativeTo: component['activatedRoute'].parent }); + }); + + it('should enforce view all rejected accounts link template semantics', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const templateConsts = ((FinesDraftCreateAndManageTabsComponent as any).ɵcmp?.consts ?? []).filter( + (entry: unknown) => Array.isArray(entry), + ) as unknown[][]; + const templateFunction = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ((FinesDraftCreateAndManageTabsComponent as any).ɵcmp?.template?.toString() as string | undefined) ?? ''; + const rejectedLinkConst = templateConsts.find( + (entry) => entry.includes('govuk-link') && entry.includes('href') && entry.includes('click'), + ); + + expect(rejectedLinkConst).toBeTruthy(); + expect(rejectedLinkConst).toContain('govuk-link--no-visited-state'); + expect(rejectedLinkConst).toContain('href'); + expect(rejectedLinkConst).toContain(''); + expect(rejectedLinkConst).not.toContain('tabindex'); + expect(templateFunction).not.toContain('keydown.enter'); + expect(templateFunction).not.toContain('keyup.enter'); + }); + it('should show "0" when getDraftAccounts returns count 0', async () => { mockOpalFinesService.getDraftAccounts.mockReturnValue(of({ count: 0, summaries: [] })); finesDraftService.populateTableData.mockReturnValue([]); diff --git a/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.ts b/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.ts index 6a1c90cdc3..b97252f3d1 100644 --- a/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.ts +++ b/src/app/flows/fines/fines-draft/fines-draft-create-and-manage/fines-draft-create-and-manage-tabs/fines-draft-create-and-manage-tabs.component.ts @@ -229,8 +229,10 @@ export class FinesDraftCreateAndManageTabsComponent extends AbstractTabData impl * Also sets the current active tab as a fragment in the fines draft store. * * @param route - The route path to navigate to. + * @param event - The event object associated with the navigation action. */ - public handleRoute(route: string): void { + public handleRoute(route: string, event?: Event): void { + event?.preventDefault(); this.finesDraftStore.setFragment(this.activeTab); this['router'].navigate([route], { relativeTo: this['activatedRoute'].parent }); } diff --git a/src/app/flows/fines/fines-draft/fines-draft-table-wrapper/fines-draft-table-wrapper.component.html b/src/app/flows/fines/fines-draft/fines-draft-table-wrapper/fines-draft-table-wrapper.component.html index fa5b5797a1..0cadef6136 100644 --- a/src/app/flows/fines/fines-draft/fines-draft-table-wrapper/fines-draft-table-wrapper.component.html +++ b/src/app/flows/fines/fines-draft/fines-draft-table-wrapper/fines-draft-table-wrapper.component.html @@ -97,9 +97,8 @@- Check your search and try again @@ -145,7 +145,7 @@
- Try adding more information
to your search
diff --git a/src/app/flows/fines/fines-sa/fines-sa-results/fines-sa-results.component.spec.ts b/src/app/flows/fines/fines-sa/fines-sa-results/fines-sa-results.component.spec.ts
index 076c510c5f..16ca62f190 100644
--- a/src/app/flows/fines/fines-sa/fines-sa-results/fines-sa-results.component.spec.ts
+++ b/src/app/flows/fines/fines-sa/fines-sa-results/fines-sa-results.component.spec.ts
@@ -56,6 +56,29 @@ describe('FinesSaResultsComponent', () => {
expect(component).toBeTruthy();
});
+ it('should enforce current template link semantics', () => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const templateConsts = ((FinesSaResultsComponent as any).ɵcmp?.consts ?? []).filter((entry: unknown) =>
+ Array.isArray(entry),
+ ) as unknown[][];
+ const templateFunction =
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ ((FinesSaResultsComponent as any).ɵcmp?.template?.toString() as string | undefined) ?? '';
+ const actionLinkConsts = templateConsts.filter(
+ (entry) => entry.includes('govuk-link') && entry.includes('href') && entry.includes('click'),
+ );
+
+ expect(actionLinkConsts.length).toBeGreaterThanOrEqual(1);
+ actionLinkConsts.forEach((entry) => {
+ expect(entry).toContain('govuk-link--no-visited-state');
+ expect(entry).toContain('href');
+ expect(entry).toContain('');
+ expect(entry).not.toContain('tabindex');
+ });
+ expect(templateFunction).not.toContain('keydown.enter');
+ expect(templateFunction).not.toContain('keyup.enter');
+ });
+
it('should initialise resultView, load snapshot data, and set up fragment listener on init', () => {
const resultView = 'accountNumber';
const searchAccount = {};
@@ -283,6 +306,52 @@ describe('FinesSaResultsComponent', () => {
);
});
+ it('should prevent default and navigate when navigateBackToSearch is called with an event', () => {
+ const event = new Event('click');
+ const preventDefaultSpy = vi.spyOn(event, 'preventDefault');
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ vi.spyOn
To search major creditors,
- filter by a single business unit
Major creditors
} @else {
There is a problem