Skip to content

Commit

Permalink
Merge branch 'master' into exui-2344-translation-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
RiteshHMCTS authored Nov 13, 2024
2 parents 247747d + 1558ef9 commit fccc35e
Show file tree
Hide file tree
Showing 61 changed files with 5,764 additions and 2,178 deletions.
3 changes: 3 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## RELEASE NOTES

### Version 7.0.75
**EXUI-2415** Redirect to an new event by a hyperlink

### Version 7.0.74
**EXUI-1108** Fix yarn npm audit in ccd-case-ui-toolkit

Expand Down
9 changes: 8 additions & 1 deletion demo/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ export class AppConfig extends AbstractAppConfig {
'access_management_mode': true,
'refunds_url': '/api/refunds',
'payment_return_url': 'https://paymentoutcome-web.demo.platform.hmcts.net/',
'case_flags_refdata_api_url': '/refdata/commondata/caseflags/service-id=:sid'
'case_flags_refdata_api_url': '/refdata/commondata/caseflags/service-id=:sid',
'events_to_hide': [
'queryManagementRespondQuery'
]
};

constructor(private http: HttpClient) {
Expand Down Expand Up @@ -187,4 +190,8 @@ export class AppConfig extends AbstractAppConfig {
public getCaseFlagsRefdataApiUrl(): string {
return this.config.case_flags_refdata_api_url;
}

public getEventsToHide(): string[] {
return this.config.events_to_hide;
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hmcts/ccd-case-ui-toolkit",
"version": "7.0.74-welsh-translation-testing",
"version": "7.0.74-welsh-translation-testing-rc1",
"engines": {
"node": ">=18.19.0"
},
Expand Down
2 changes: 1 addition & 1 deletion projects/ccd-case-ui-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hmcts/ccd-case-ui-toolkit",
"version": "7.0.74-welsh-translation-testing",
"version": "7.0.74-welsh-translation-testing-rc1",
"engines": {
"node": ">=18.19.0"
},
Expand Down
10 changes: 8 additions & 2 deletions projects/ccd-case-ui-toolkit/src/lib/app-config.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,20 +207,26 @@ export class AppMockConfig implements AbstractAppConfig {
return '';
}

public getEventsToHide(): string[] {
return [];
}

public getEnableRestrictedCaseAccessConfig(): boolean {
return true;
}

public getEnableCaseFileViewVersion1_1(): boolean {
return true;
}

public getIcpEnable(): boolean {
return false;
}

public getIcpJurisdictions(): string[] {
return ['', ''];
}
public logMessage(): void {

public logMessage(msg: string): void {
console.log(msg);
}
}
2 changes: 2 additions & 0 deletions projects/ccd-case-ui-toolkit/src/lib/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export abstract class AbstractAppConfig {
public abstract getCaseFlagsRefdataApiUrl(): string;
public abstract getRDCommonDataApiUrl(): string;
public abstract getCaseDataStoreApiUrl(): string;
public abstract getEventsToHide(): string[];
public abstract getEnableRestrictedCaseAccessConfig(): boolean;
public abstract getEnableCaseFileViewVersion1_1(): boolean;
}
Expand Down Expand Up @@ -194,4 +195,5 @@ export class CaseEditorConfig {
public enable_case_file_view_version_1_1: boolean;
public icp_enabled: boolean;
public icp_jurisdictions: string[];
public events_to_hide: string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,46 @@ describe('CaseEditComponent', () => {
expect(mockWorkAllocationService.completeTask).not.toHaveBeenCalled();
});

it('should submit the case for a Case Flags submission', () => {
const mockClass = {
submit: () => of({})
};
spyOn(mockClass, 'submit').and.returnValue(of({
id: 'id',
/* tslint:disable:object-literal-key-quotes */
'callback_response_status': 'CALLBACK_HASNOT_COMPLETED',
/* tslint:disable:object-literal-key-quotes */
'after_submit_callback_response': {
/* tslint:disable:object-literal-key-quotes */
'confirmation_header': 'confirmation_header',
/* tslint:disable:object-literal-key-quotes */
'confirmation_body': 'confirmation_body'
}
}));

spyOn(component, 'confirm');

component.isCaseFlagSubmission = true;
component.confirmation = {} as unknown as Confirmation;

formValueService.sanitise.and.returnValue({name: 'sweet'});
component.onEventCanBeCompleted({
eventTrigger: component.eventTrigger,
eventCanBeCompleted: true,
caseDetails: component.caseDetails,
form: component.form,
submit: mockClass.submit,
});

expect(component.confirm).toHaveBeenCalled();
expect(formValueService.populateLinkedCasesDetailsFromCaseFields).toHaveBeenCalled();
expect(formValueService.removeCaseFieldsOfType)
.toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Array), ['FlagLauncher', 'ComponentLauncher']);
expect(formValueService.repopulateFormDataFromCaseFieldValues).toHaveBeenCalled();
expect(validPageListCaseFieldsService.deleteNonValidatedFields).toHaveBeenCalled();
expect(formValueService.removeUnnecessaryFields).not.toHaveBeenCalled();
});

it('should NOT submit the case due to error', () => {
const mockClass = {
submit: () => of({})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ export class CaseEditComponent implements OnInit, OnDestroy {
this.isPageRefreshed = JSON.parse(this.sessionStorageService.getItem('isPageRefreshed'));

this.checkPageRefresh();
/* istanbul ignore else */
if (this.router.url && !this.isPageRefreshed) {
this.sessionStorageService.setItem('eventUrl', this.router.url);
}

this.form = this.fb.group({
data: new FormGroup({}),
Expand Down Expand Up @@ -408,43 +404,51 @@ export class CaseEditComponent implements OnInit, OnDestroy {
if (caseField && caseField.retain_hidden_value &&
(caseField.hidden || (caseField.hidden !== false && parentField && parentField.hidden))) {
if (caseField.field_type.type === 'Complex') {
// Note: Deliberate use of equality (==) and non-equality (!=) operators for null checks throughout, to
// handle both null and undefined values
if (caseField.value != null) {
// Call this function recursively to replace the Complex field's sub-fields as necessary, passing the
// CaseField itself (the sub-fields do not contain any values, so these need to be obtained from the
// parent)
// Update rawFormValueData for this field
// creating form group and adding control into it in case caseField is of complext type and and part of formGroup
const form: FormGroup = new FormGroup({});
if (formGroup.controls[key].value) {
Object.keys(formGroup.controls[key].value).forEach((item) => {
form.addControl(item, new FormControl(formGroup.controls[key].value[item]));
});
}
rawFormValueData[key] = this.replaceHiddenFormValuesWithOriginalCaseData(
form, caseField.field_type.complex_fields, caseField);
}
this.handleComplexField(caseField, formGroup, key, rawFormValueData);
} else {
// Default case also handles collections of *all* types; the entire collection in rawFormValueData will be
// replaced with the original from formatted_value
// Use the CaseField's existing *formatted_value* from the parent, if available. (This is necessary for
// Complex fields, whose sub-fields do not hold any values in the model.) Otherwise, use formatted_value
// from the CaseField itself.
if (parentField && parentField.formatted_value) {
rawFormValueData[key] = parentField.formatted_value[caseField.id];
} else {
if (!(caseField.hidden && caseField.retain_hidden_value)) {
rawFormValueData[key] = caseField.formatted_value;
}
}
this.handleNonComplexField(parentField, rawFormValueData, key, caseField);
}
}
});

return rawFormValueData;
}

private handleNonComplexField(parentField: CaseField, rawFormValueData, key: string, caseField: CaseField) {
// Default case also handles collections of *all* types; the entire collection in rawFormValueData will be
// replaced with the original from formatted_value
// Use the CaseField's existing *formatted_value* from the parent, if available. (This is necessary for
// Complex fields, whose sub-fields do not hold any values in the model.) Otherwise, use formatted_value
// from the CaseField itself.
if (parentField && parentField.formatted_value) {
rawFormValueData[key] = parentField.formatted_value[caseField.id];
} else {
if (!(caseField.hidden && caseField.retain_hidden_value)) {
rawFormValueData[key] = caseField.formatted_value;
}
}
}

private handleComplexField(caseField: CaseField, formGroup: FormGroup<any>, key: string, rawFormValueData) {
// Note: Deliberate use of equality (==) and non-equality (!=) operators for null checks throughout, to
// handle both null and undefined values
if (caseField.value != null) {
// Call this function recursively to replace the Complex field's sub-fields as necessary, passing the
// CaseField itself (the sub-fields do not contain any values, so these need to be obtained from the
// parent)
// Update rawFormValueData for this field
// creating form group and adding control into it in case caseField is of complext type and and part of formGroup
const form: FormGroup = new FormGroup({});
if (formGroup.controls[key].value) {
Object.keys(formGroup.controls[key].value).forEach((item) => {
form.addControl(item, new FormControl(formGroup.controls[key].value[item]));
});
}
rawFormValueData[key] = this.replaceHiddenFormValuesWithOriginalCaseData(
form, caseField.field_type.complex_fields, caseField);
}
}

private caseSubmit({ form, caseEventData, submit }: CaseEditCaseSubmit): void {
const loadingSpinnerToken = this.loadingService.register();
// keep the initial event response to finalise process after task completion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,17 @@ import { Draft } from '../../domain/draft.model';
})

export class CaseHeaderComponent implements OnInit {

@Input()
public caseDetails: CaseView;
@Input() public caseDetails: CaseView;
public caseTitle: CaseField;
public caseFields: CaseField[];

public ngOnInit(): void {
this.caseTitle = new CaseField();
if (!this.isDraft() && this.caseDetails.state.title_display) {
this.caseTitle.label = this.caseDetails.state.title_display;
this.caseFields = this.getCaseFields();
}
}

public isDraft(): boolean {
return Draft.isDraft(this.caseDetails.case_id);
this.caseTitle.label = this.caseDetails.state.title_display;
this.caseFields = this.getCaseFieldsInfo();
}

private getCaseFields(): CaseField[] {
private getCaseFieldsInfo(): CaseField[] {
const caseDataFields = this.caseDetails.tabs.reduce((acc, tab) => {
return acc.concat(tab.fields);
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,6 @@ let caseNotifier: jasmine.SpyObj<CaseNotifier>;
let navigationNotifierService: NavigationNotifierService;
let errorNotifierService: ErrorNotifierService;


describe('CaseFullAccessViewComponent', () => {
let caseViewData: CaseView;
let FIELDS: CaseField[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { AbstractAppConfig } from '../../../app.config';
import { CaseViewTrigger } from '../../domain';
import { OrderService } from '../../services';
import { attr, text } from '../../test/helpers';
Expand Down Expand Up @@ -29,6 +30,12 @@ describe('EventTriggerComponent', () => {
name: 'Create a bundle',
description: 'Create a bundle',
order: 3
},
{
id: 'queryManagementRespondQuery',
name: 'QueryManagementRespondQuery',
description: 'Query Management Respond to a query',
order: 4
}
];

Expand All @@ -52,7 +59,7 @@ describe('EventTriggerComponent', () => {
const $EVENT_TRIGGER_FORM = By.css('.event-trigger');

let orderService: any;

let appConfig: jasmine.SpyObj<AbstractAppConfig>;
let fixture: ComponentFixture<EventTriggerComponent>;
let component: EventTriggerComponent;
let de: DebugElement;
Expand All @@ -61,6 +68,8 @@ describe('EventTriggerComponent', () => {
beforeEach(waitForAsync(() => {
orderService = createSpyObj<OrderService>('orderService', ['sort']);
orderService.sort.and.returnValue(SORTED_TRIGGERS);
appConfig = createSpyObj<AbstractAppConfig>('appConfig', ['getEventsToHide']);
appConfig.getEventsToHide.and.returnValue(['']);

TestBed
.configureTestingModule({
Expand All @@ -72,7 +81,8 @@ describe('EventTriggerComponent', () => {
MockRpxTranslatePipe
],
providers: [
{provide: OrderService, useValue: orderService}
{provide: OrderService, useValue: orderService},
{provide: AbstractAppConfig, useValue: appConfig}
]
})
.compileComponents();
Expand Down Expand Up @@ -106,7 +116,7 @@ describe('EventTriggerComponent', () => {
it('should render a <select> with an <option> for every trigger', () => {
const options = de.queryAll($SELECT_OPTIONS);

expect(options.length).toBe(3);
expect(options.length).toBe(4);

TRIGGERS.forEach(trigger => {
const optionDe = options.find(option => text(option) === trigger.name);
Expand Down Expand Up @@ -222,6 +232,8 @@ describe('EventTriggerComponent', () => {
beforeEach(waitForAsync(() => {
orderService = createSpyObj<OrderService>('orderService', ['sort']);
orderService.sort.and.returnValue([ TRIGGERS[0] ]);
appConfig = createSpyObj<AbstractAppConfig>('appConfig', ['getEventsToHide']);
appConfig.getEventsToHide.and.returnValue(['queryManagementRespondQuery']);

TestBed
.configureTestingModule({
Expand All @@ -233,7 +245,8 @@ describe('EventTriggerComponent', () => {
MockRpxTranslatePipe
],
providers: [
{provide: OrderService, useValue: orderService}
{provide: OrderService, useValue: orderService},
{provide: AbstractAppConfig, useValue: appConfig}
]
})
.compileComponents();
Expand Down Expand Up @@ -261,4 +274,54 @@ describe('EventTriggerComponent', () => {
expect(component.triggerForm.valid).toBeTruthy();
});
});

describe('Hide events', () => {
beforeEach(waitForAsync(() => {
orderService = createSpyObj<OrderService>('orderService', ['sort']);
appConfig = createSpyObj<AbstractAppConfig>('appConfig', ['getEventsToHide']);

TestBed.configureTestingModule({
imports: [
ReactiveFormsModule
],
declarations: [
EventTriggerComponent,
MockRpxTranslatePipe
],
providers: [
{provide: OrderService, useValue: orderService},
{provide: AbstractAppConfig, useValue: appConfig}
]
})
.compileComponents();

fixture = TestBed.createComponent(EventTriggerComponent);
component = fixture.componentInstance;
component.triggerForm = new FormGroup({
trigger: new FormControl('')
});
component.triggers = TRIGGERS;
fixture.detectChanges();
}));

it('should hide the respond to query event from the dropdown', () => {
orderService.sort.and.returnValue([TRIGGERS[0], TRIGGERS[1]]);
appConfig.getEventsToHide.and.returnValue(['queryManagementRespondQuery']);
component.ngOnChanges(trigersChangeDummy(TRIGGERS));
fixture.detectChanges();
const triggerIds = component.triggers.map((trigger) => trigger.id);
expect(triggerIds.includes('queryManagementRespondQuery')).toBe(false);
expect(component.triggers.length).toEqual(2);
});

it('should show the respond to query event from the dropdown', () => {
orderService.sort.and.returnValue(TRIGGERS);
appConfig.getEventsToHide.and.returnValue(['']);
component.ngOnChanges(trigersChangeDummy(TRIGGERS));
fixture.detectChanges();
const triggerIds = component.triggers.map((trigger) => trigger.id);
expect(triggerIds.includes('queryManagementRespondQuery')).toBe(true);
expect(component.triggers.length).toEqual(4);
});
});
});
Loading

0 comments on commit fccc35e

Please sign in to comment.