Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(RELEASE-123): merge holding branch back into develop #1490

Merged
merged 32 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1645ddd
feat(cb2-10241): update adr notes to use custom component (#1446)
BrandonT95 Mar 28, 2024
e7e4fd5
feat/CB2-11250 - Edit button on additional examiner notes takes you t…
tomcrawleyy Apr 2, 2024
40463f6
feat(CB2-9916): Add warning to cherished transfer (#1451)
BrandonT95 Apr 3, 2024
6ffb3c3
feat(cb2-10032): add pagination to adr examiner notes (#1450)
BrandonT95 Apr 3, 2024
5b4e5c1
feat(cb2-11103): createdAtDate for adr examiner notes now save as ful…
BrandonT95 Apr 5, 2024
3269b25
feat/CB2-10033 - Additional Examiner Note (#1448)
tomcrawleyy Apr 5, 2024
6ec627a
feat(cb2-10033): upped char count to 151 (#1453)
tomevs88 Apr 9, 2024
88de19d
feat(cb2-10033): upped char count to 150
Apr 9, 2024
eb0b98d
feat(cb2-10033): upped char count to 150
pbardy2000 Apr 9, 2024
81853a2
Merge branch 'feature/RELEASE-123' of https://github.com/dvsa/cvs-app…
pbardy2000 Apr 9, 2024
9c22cc8
feat(cb2-10033): upped char count to 15 again
Apr 9, 2024
d8db074
feat(cb2-10033): css removed
Apr 9, 2024
ae21ae2
fix(cb2-11103): re-add missing timestamp from adr notes view (#1460)
BrandonT95 Apr 9, 2024
e689ac8
feat(cb2-10286): add hint text to 3 month extension (#1462)
pbardy2000 Apr 11, 2024
aff9b85
feat(cb2-10973): feature flags changed to show IVA flow in all envs (…
tomevs88 Apr 11, 2024
0fd205a
feat(cb2-10125): make adr guidance notes a checkbox group (#1466)
pbardy2000 Apr 11, 2024
57326c2
feat(cb2-11546): make 'make' required for HGVs and TRLs which carry d…
pbardy2000 Apr 12, 2024
49993bd
feat(cb2-10286): add new certificate required field (#1463)
pbardy2000 Apr 15, 2024
e5d2de9
feat/CB2-10740 - Mark if a vehicle is used for international journeys…
tomcrawleyy Apr 15, 2024
d9c602a
fix(cb2-9747): fix failing unit test (#1468)
BrandonT95 Apr 15, 2024
3e639e7
fix(cb2-9747): create mocked date to fix failing unit test (#1469)
BrandonT95 Apr 16, 2024
78ade7b
feat(cb2-11185): ensure correct text-wrapping. (#1473)
pbardy2000 Apr 18, 2024
c5623f8
fix(cb2-10419): change casing in select defect (#1474)
pbardy2000 Apr 18, 2024
c6dc792
fix(cb2-11302): correct spelling of accessor to assessor (#1475)
pbardy2000 Apr 18, 2024
98adb0a
fix(cb2-10562): prevent submitting a psv with one axle (#1480)
pbardy2000 Apr 18, 2024
7663404
fix(cb2-11069): reset error message when new data is provided (#1479)
pbardy2000 Apr 18, 2024
8da1e80
fix(cb2-11068): allow unset as form node width so it never hides opti…
pbardy2000 Apr 18, 2024
cf85771
fix(CB2-11243): prevent SR field in tyres component being cut-off on …
pbardy2000 Apr 18, 2024
ab070d6
fix(CB2-11453): prevent download .zip file in seperate window (as thi…
pbardy2000 Apr 18, 2024
7cc436a
feat(cb2-11930): ensure certificate number is sent to backend if it e…
pbardy2000 May 2, 2024
0af03f0
fix(cb2-11908): remove duplicate label from additional examiner notes…
pbardy2000 May 2, 2024
e4699cd
feat(cb2-12056): test codes moved (#1487)
tomevs88 May 3, 2024
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@angular/router": "^17.2.1",
"@azure/msal-angular": "^3.0.13",
"@azure/msal-browser": "^3.10.0",
"@dvsa/cvs-type-definitions": "^6.1.0",
"@dvsa/cvs-type-definitions": "^6.3.0",
"@ngrx/effects": "^17.1.0",
"@ngrx/entity": "^17.1.0",
"@ngrx/router-store": "^17.1.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<div *ngIf="techRecord">
<app-field-warning-message
*ngIf="showWarning"
[warningMessage]="
'Cherished transfers will update the VRM on the most recent test record for HGVs and PSVs, where an annual test certificate has been generated'
"
></app-field-warning-message>
<h2 class="govuk-heading-l">{{ makeAndModel }}</h2>

<dl class="govuk-summary-list">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {
ComponentFixture, fakeAsync, TestBed,
} from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, ActivatedRouteSnapshot, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
Expand Down Expand Up @@ -31,6 +29,7 @@ const mockTechRecordService = {
validateVrmDoesNotExist: jest.fn(),
validateVrmForCherishedTransfer: jest.fn(),
checkVrmNotActive: jest.fn(),
getVehicleTypeWithSmallTrl: jest.fn(),
};

const mockDynamicFormService = {
Expand Down Expand Up @@ -170,4 +169,34 @@ describe('TechRecordChangeVrmComponent', () => {
);
});
});

describe('showWarning', () => {
it('should return true if the vehicle type is a psv', () => {
component.techRecord = { techRecord_vehicleType: 'psv' } as VehiclesOtherThan<'trl'>;
mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('psv');

expect(component.showWarning).toBe(true);
});

it('should return true if the vehicle type is a hgv', () => {
component.techRecord = { techRecord_vehicleType: 'hgv' } as VehiclesOtherThan<'trl'>;
mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('hgv');

expect(component.showWarning).toBe(true);
});

it('should return false if the vehicle type is not a psv or hgv', () => {
component.techRecord = { techRecord_vehicleType: 'lgv' } as VehiclesOtherThan<'trl'>;
mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('lgv');

expect(component.showWarning).toBe(false);
});

it('should default to false if the vehicle type is not present', () => {
component.techRecord = undefined;
mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue(undefined);

expect(component.showWarning).toBe(false);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,11 @@ export class AmendVrmComponent implements OnDestroy, OnInit {
}
return true;
}

get showWarning(): boolean {
if (this.vehicleType) {
return this.vehicleType === 'psv' || this.vehicleType === 'hgv';
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div *ngIf="currentTechRecord">
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<dl class="govuk-summary-list">
<h1 class="govuk-heading-l">Edit Additional Examiner Note</h1>
<div class="parent-div">
<td class="govuk-heading-s">Date</td>
<td class="table-value">{{ examinerNoteObj.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }}</td>
<td class="govuk-heading-s">Created by</td>
<td class="table-value">{{ examinerNoteObj.lastUpdatedBy }}</td>
</div>
<div class="govuk-summary-list__row">
<form [formGroup]="form">
<app-text-area
#examinerNote
formControlName="additionalExaminerNote"
name="AdditionalExaminerNote"
[width]="width.L"
(ngModelChange)="ngOnChanges(examinerNote.value)"
>
</app-text-area>
</form>
</div>
</dl>
</div>
</div>
<app-button-group>
<app-button id="submit-examiner-note" (clicked)="handleSubmit()">Save</app-button>
<app-button id="cancel-amend-examiner-note" design="link" data-module="govuk-button" (clicked)="navigateBack()">Cancel</app-button>
</app-button-group>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.parent-div {
display: flex;
flex-direction: row;
}
.table-value {
margin-left: 1%;
margin-right: 1%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DynamicFormsModule } from '@forms/dynamic-forms.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { TechnicalRecordService } from '@services/technical-record/technical-record.service';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { initialAppState } from '@store/index';
import { ActivatedRoute, Router } from '@angular/router';
import { of } from 'rxjs';
import { GlobalErrorService } from '@core/components/global-error/global-error.service';
import { TechRecordEditAdditionalExaminerNoteComponent } from './tech-record-edit-additional-examiner-note.component';

const mockTechRecordService = {
techRecord$: jest.fn(),
};
describe('TechRecordEditAdditionalExaminerNoteComponent', () => {
let fixture: ComponentFixture<TechRecordEditAdditionalExaminerNoteComponent>;
let component: TechRecordEditAdditionalExaminerNoteComponent;
let router: Router;
let errorService: GlobalErrorService;
let route: ActivatedRoute;
let store: MockStore;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TechRecordEditAdditionalExaminerNoteComponent],
imports: [DynamicFormsModule, FormsModule, ReactiveFormsModule, RouterTestingModule],
providers: [
{ provide: TechnicalRecordService, useValue: mockTechRecordService },
provideMockStore({ initialState: initialAppState }),
{ provide: ActivatedRoute, useValue: { params: of([{ id: 1 }]) } },
],
}).compileComponents();
fixture = TestBed.createComponent(TechRecordEditAdditionalExaminerNoteComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
errorService = TestBed.inject(GlobalErrorService);
route = TestBed.inject(ActivatedRoute);
store = TestBed.inject(MockStore);
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('ngOnInit', () => {
it('should call all initialisation functions', () => {
const examinerNoteSpy = jest.spyOn(component, 'getExaminerNote').mockReturnValue();
const techRecordSpy = jest.spyOn(component, 'getTechRecord').mockReturnValue();
const formSpy = jest.spyOn(component, 'setupForm').mockReturnValue();
component.ngOnInit();
expect(examinerNoteSpy).toHaveBeenCalled();
expect(formSpy).toHaveBeenCalled();
expect(techRecordSpy).toHaveBeenCalled();
});
});
describe('navigateBack', () => {
it('should clear all errors', () => {
jest.spyOn(router, 'navigate').mockImplementation();

const clearErrorsSpy = jest.spyOn(errorService, 'clearErrors');

component.navigateBack();

expect(clearErrorsSpy).toHaveBeenCalledTimes(1);
});

it('should navigate back to the previous page', () => {
const navigateSpy = jest.spyOn(router, 'navigate').mockImplementation(() => Promise.resolve(true));

component.navigateBack();

expect(navigateSpy).toHaveBeenCalledWith(['../../'], { relativeTo: route });
});
});
describe('handleSubmit', () => {
it('should not dispatch an action if the notes are the same', () => {
const storeSpy = jest.spyOn(store, 'dispatch');
const navigateBackSpy = jest.spyOn(component, 'navigateBack').mockReturnValue();
component.originalExaminerNote = 'foobar';
component.editedExaminerNote = 'foobar';
component.handleSubmit();
expect(storeSpy).not.toHaveBeenCalled();
expect(navigateBackSpy).toHaveBeenCalled();
});

it('should dispatch an action if the notes are not the same', () => {
const storeSpy = jest.spyOn(store, 'dispatch');
const navigateBackSpy = jest.spyOn(component, 'navigateBack').mockReturnValue();
component.originalExaminerNote = 'foo';
component.editedExaminerNote = 'bar';
component.handleSubmit();
expect(storeSpy).toHaveBeenCalled();
expect(navigateBackSpy).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { TechnicalRecordService } from '@services/technical-record/technical-record.service';
import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type';
import { ReplaySubject, take, takeUntil } from 'rxjs';
import { GlobalErrorService } from '@core/components/global-error/global-error.service';
import {
CustomFormControl,
FormNodeEditTypes,
FormNodeTypes,
FormNodeWidth,
} from '@forms/services/dynamic-form.types';
import { FormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { State } from '@store/index';
import { updateExistingADRAdditionalExaminerNote } from '@store/technical-records';
import { AdditionalExaminerNotes } from '@dvsa/cvs-type-definitions/types/v3/tech-record/get/hgv/complete';

@Component({
selector: 'tech-record-edit-additional-examiner-note',
templateUrl: './tech-record-edit-additional-examiner-note.component.html',
styleUrls: ['./tech-record-edit-additional-examiner-note.component.scss'],
})
export class TechRecordEditAdditionalExaminerNoteComponent implements OnInit {
currentTechRecord!: TechRecordType<'hgv' | 'trl' | 'lgv'>;
examinerNoteIndex!: number;
editedExaminerNote: string = '';
originalExaminerNote: string = '';
examinerNoteObj!: AdditionalExaminerNotes;
destroy$ = new ReplaySubject<boolean>(1);
form!: FormGroup;
formControl!: CustomFormControl;

constructor(
private router: Router,
private route: ActivatedRoute,
private technicalRecordService: TechnicalRecordService,
private globalErrorService: GlobalErrorService,
private store: Store<State>,
) { }

ngOnInit() {
this.getTechRecord();
this.getExaminerNote();
this.setupForm();
}

getTechRecord() {
this.technicalRecordService.techRecord$.pipe(takeUntil(this.destroy$)).subscribe((currentTechRecord) => {
this.currentTechRecord = currentTechRecord as TechRecordType<'hgv' | 'lgv' | 'trl'>;
});
}

getExaminerNote() {
this.route.params.pipe(take(1)).subscribe((params) => {
this.examinerNoteIndex = params['examinerNoteIndex'];
});
const additionalExaminerNotes = this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes;
if (additionalExaminerNotes) {
const examinerNote = additionalExaminerNotes[this.examinerNoteIndex].note;
if (examinerNote) {
this.examinerNoteObj = additionalExaminerNotes[this.examinerNoteIndex];
this.originalExaminerNote = examinerNote;
this.editedExaminerNote = examinerNote;
}
}
}

setupForm() {
this.formControl = new CustomFormControl({
name: 'additionalExaminerNote', type: FormNodeTypes.CONTROL,
}, '', [Validators.required]);
this.form = new FormGroup({
additionalExaminerNote: this.formControl,
});
this.formControl.patchValue(this.editedExaminerNote);
}

navigateBack() {
this.globalErrorService.clearErrors();
void this.router.navigate(['../../'], { relativeTo: this.route });
}

handleSubmit(): void {
if (this.originalExaminerNote !== this.editedExaminerNote) {
this.store.dispatch(
updateExistingADRAdditionalExaminerNote({
examinerNoteIndex: this.examinerNoteIndex,
additionalExaminerNote: this.editedExaminerNote,
}),
);
}
this.navigateBack();
}

ngOnChanges(examinerNote: string) {
this.editedExaminerNote = examinerNote;
}

get editTypes(): typeof FormNodeEditTypes {
return FormNodeEditTypes;
}

get width(): typeof FormNodeWidth {
return FormNodeWidth;
}

}
Loading
Loading