Skip to content

Commit 3cd068c

Browse files
committed
Created tests for frontend
1 parent 7cf5017 commit 3cd068c

18 files changed

+1139
-62
lines changed
+14-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
import { TestBed } from '@angular/core/testing';
22
import { AppComponent } from './app.component';
3-
import { NxWelcomeComponent } from './nx-welcome.component';
4-
import { RouterModule } from '@angular/router';
3+
import { provideRouter } from '@angular/router';
4+
import { appRoutes } from './app.routes';
55

66
describe('AppComponent', () => {
77
beforeEach(async () => {
88
await TestBed.configureTestingModule({
9-
imports: [AppComponent, NxWelcomeComponent, RouterModule.forRoot([])],
9+
providers: [provideRouter(appRoutes)],
10+
imports: [AppComponent],
1011
}).compileComponents();
1112
});
1213

13-
it('should render title', () => {
14+
it('should create the app', () => {
1415
const fixture = TestBed.createComponent(AppComponent);
15-
fixture.detectChanges();
16-
const compiled = fixture.nativeElement as HTMLElement;
17-
expect(compiled.querySelector('h1')?.textContent).toContain(
18-
'Welcome car-rental'
19-
);
16+
const app = fixture.componentInstance;
17+
expect(app).toBeTruthy();
2018
});
2119

2220
it(`should have as title 'car-rental'`, () => {
2321
const fixture = TestBed.createComponent(AppComponent);
2422
const app = fixture.componentInstance;
2523
expect(app.title).toEqual('car-rental');
2624
});
25+
26+
it('should render router-outlet', () => {
27+
const fixture = TestBed.createComponent(AppComponent);
28+
fixture.detectChanges();
29+
const compiled = fixture.nativeElement as HTMLElement;
30+
expect(compiled.querySelector('router-outlet')).not.toBeNull();
31+
});
2732
});
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
1+
import { TestBed } from '@angular/core/testing';
22
import { PageNotFoundComponent } from './page-not-found.component';
3+
import { CommonModule } from '@angular/common';
34

45
describe('PageNotFoundComponent', () => {
5-
let component: PageNotFoundComponent;
6-
let fixture: ComponentFixture<PageNotFoundComponent>;
7-
86
beforeEach(async () => {
97
await TestBed.configureTestingModule({
10-
imports: [PageNotFoundComponent],
8+
imports: [CommonModule, PageNotFoundComponent], // Import the standalone component
119
}).compileComponents();
12-
13-
fixture = TestBed.createComponent(PageNotFoundComponent);
14-
component = fixture.componentInstance;
15-
fixture.detectChanges();
1610
});
1711

18-
it('should create', () => {
12+
it('should create the component', () => {
13+
const fixture = TestBed.createComponent(PageNotFoundComponent);
14+
const component = fixture.componentInstance;
1915
expect(component).toBeTruthy();
2016
});
17+
18+
it('should render the correct content', () => {
19+
const fixture = TestBed.createComponent(PageNotFoundComponent);
20+
fixture.detectChanges();
21+
const compiled = fixture.nativeElement as HTMLElement;
22+
expect(compiled.querySelector('h2')?.textContent).toContain(
23+
'Page Not Found'
24+
);
25+
expect(compiled.querySelector('p')?.textContent).toContain(
26+
"We couldn't find that page! Not even with x-ray vision."
27+
);
28+
});
2129
});

apps/car-rental/src/components/vehicles/confirm-vehicle-removal/confirm-vehicle-removal.component.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ <h2 mat-dialog-title>Potwierdź usunięcie pojazdu</h2>
88
<p>Czy na pewno chcesz usunąć pojazd o numerze rejestracyjnym: <strong>{{ vehicle.registrationNumber }}</strong>?</p>
99
</mat-dialog-content>
1010
<mat-dialog-actions>
11-
<button mat-button (click)="onCancel()">ANULUJ</button>
12-
<button mat-button (click)="onConfirm()">USUŃ</button>
11+
<button mat-button id="cancel" (click)="onCancel()">ANULUJ</button>
12+
<button mat-button id="confirm" (click)="onConfirm()">USUŃ</button>
1313
</mat-dialog-actions>
1414
</ng-container>
1515
</ng-container>
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,124 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
1+
import { TestBed, ComponentFixture } from '@angular/core/testing';
22
import { ConfirmVehicleRemovalComponent } from './confirm-vehicle-removal.component';
3+
import { CommonModule } from '@angular/common';
4+
import {
5+
MatDialogRef,
6+
MAT_DIALOG_DATA,
7+
MatDialogModule,
8+
} from '@angular/material/dialog';
9+
import { MatButtonModule } from '@angular/material/button';
10+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
11+
import { VehiclesService } from '../../../services/vehicles.service';
12+
import { NotificationService } from '../../../../src/services/notification.service';
13+
import { of, throwError } from 'rxjs';
14+
import { VehicleDto } from '../../../dtos/vehicle';
15+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
316

417
describe('ConfirmVehicleRemovalComponent', () => {
518
let component: ConfirmVehicleRemovalComponent;
619
let fixture: ComponentFixture<ConfirmVehicleRemovalComponent>;
20+
let vehiclesService: jest.Mocked<VehiclesService>;
21+
let notificationService: jest.Mocked<NotificationService>;
22+
let dialogRef: jest.Mocked<MatDialogRef<ConfirmVehicleRemovalComponent>>;
723

824
beforeEach(async () => {
25+
const vehiclesServiceMock = {
26+
removeVehicle: jest.fn(),
27+
};
28+
const notificationServiceMock = {
29+
showSuccess: jest.fn(),
30+
showError: jest.fn(),
31+
};
32+
const dialogRefMock = {
33+
close: jest.fn(),
34+
};
35+
936
await TestBed.configureTestingModule({
10-
imports: [ConfirmVehicleRemovalComponent],
37+
imports: [
38+
CommonModule,
39+
MatButtonModule,
40+
MatProgressSpinnerModule,
41+
MatDialogModule,
42+
ConfirmVehicleRemovalComponent,
43+
NoopAnimationsModule,
44+
],
45+
providers: [
46+
{ provide: VehiclesService, useValue: vehiclesServiceMock },
47+
{ provide: NotificationService, useValue: notificationServiceMock },
48+
{ provide: MatDialogRef, useValue: dialogRefMock },
49+
{
50+
provide: MAT_DIALOG_DATA,
51+
useValue: { id: 1, registrationNumber: 'ABC123' } as VehicleDto,
52+
},
53+
],
1154
}).compileComponents();
1255

1356
fixture = TestBed.createComponent(ConfirmVehicleRemovalComponent);
1457
component = fixture.componentInstance;
15-
fixture.detectChanges();
58+
vehiclesService = TestBed.inject(
59+
VehiclesService
60+
) as jest.Mocked<VehiclesService>;
61+
notificationService = TestBed.inject(
62+
NotificationService
63+
) as jest.Mocked<NotificationService>;
64+
dialogRef = TestBed.inject(MatDialogRef) as jest.Mocked<
65+
MatDialogRef<ConfirmVehicleRemovalComponent>
66+
>;
1667
});
1768

18-
it('should create', () => {
69+
it('should create the component', () => {
1970
expect(component).toBeTruthy();
2071
});
72+
73+
it('should render the correct content', () => {
74+
fixture.detectChanges();
75+
const compiled = fixture.nativeElement as HTMLElement;
76+
expect(compiled.querySelector('h2')?.textContent).toContain(
77+
'Potwierdź usunięcie pojazdu'
78+
);
79+
expect(compiled.querySelector('p')?.textContent).toContain(
80+
'Czy na pewno chcesz usunąć pojazd o numerze rejestracyjnym: ABC123?'
81+
);
82+
});
83+
84+
it('should call onCancel when the cancel button is clicked', () => {
85+
jest.spyOn(component, 'onCancel');
86+
fixture.detectChanges();
87+
const button = fixture.nativeElement.querySelector(
88+
'button#cancel'
89+
);
90+
button.click();
91+
expect(component.onCancel).toHaveBeenCalled();
92+
expect(dialogRef.close).toHaveBeenCalled();
93+
});
94+
95+
it('should call onConfirm when the confirm button is clicked', () => {
96+
jest.spyOn(component, 'onConfirm');
97+
vehiclesService.removeVehicle.mockReturnValue(of(void 0));
98+
fixture.detectChanges();
99+
const button = fixture.nativeElement.querySelector('button#confirm');
100+
button.click();
101+
expect(component.onConfirm).toHaveBeenCalled();
102+
expect(vehiclesService.removeVehicle).toHaveBeenCalledWith(1);
103+
expect(notificationService.showSuccess).toHaveBeenCalledWith(
104+
'Pojazd został usunięty. 🚗'
105+
);
106+
expect(dialogRef.close).toHaveBeenCalledWith('vehicleRemoved');
107+
});
108+
109+
it('should handle error when vehicle removal fails', () => {
110+
jest.spyOn(component, 'onConfirm');
111+
vehiclesService.removeVehicle.mockReturnValue(
112+
throwError(() => ({ error: { status: 404 } }))
113+
);
114+
fixture.detectChanges();
115+
const button = fixture.nativeElement.querySelector('button#confirm');
116+
button.click();
117+
expect(component.onConfirm).toHaveBeenCalled();
118+
expect(vehiclesService.removeVehicle).toHaveBeenCalledWith(1);
119+
expect(notificationService.showError).toHaveBeenCalledWith(
120+
'Nie znaleziono takiego pojazdu.😥'
121+
);
122+
expect(dialogRef.close).not.toHaveBeenCalledWith('vehicleRemoved');
123+
});
21124
});
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,173 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
1+
import { TestBed, ComponentFixture } from '@angular/core/testing';
22
import { CreateVehicleFormComponent } from './create-vehicle-form.component';
3+
import { CommonModule } from '@angular/common';
4+
import { ReactiveFormsModule } from '@angular/forms';
5+
import { MatFormFieldModule } from '@angular/material/form-field';
6+
import { MatInputModule } from '@angular/material/input';
7+
import { MatSelectModule } from '@angular/material/select';
8+
import { MatButtonModule } from '@angular/material/button';
9+
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
10+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
11+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
12+
import { VehicleBrandsService } from '../../../../src/services/vehicle-brands.service';
13+
import { VehiclesService } from '../../../../src/services/vehicles.service';
14+
import { NotificationService } from '../../../../src/services/notification.service';
15+
import { of, throwError } from 'rxjs';
16+
import { VehicleBrandDto } from '../../../dtos/vehicle-brand';
17+
import { VehicleDto } from '../../../dtos/vehicle';
18+
import { Page } from '../../../dtos/page';
19+
import { MatSelect } from '@angular/material/select';
320

421
describe('CreateVehicleFormComponent', () => {
522
let component: CreateVehicleFormComponent;
623
let fixture: ComponentFixture<CreateVehicleFormComponent>;
24+
let vehicleBrandsService: jest.Mocked<VehicleBrandsService>;
25+
let vehiclesService: jest.Mocked<VehiclesService>;
26+
let notificationService: jest.Mocked<NotificationService>;
27+
let dialogRef: jest.Mocked<MatDialogRef<CreateVehicleFormComponent>>;
728

829
beforeEach(async () => {
30+
const vehicleBrandsServiceMock = {
31+
getVehicleBrands: jest.fn().mockReturnValue(
32+
of({
33+
data: [],
34+
meta: { itemCount: 0 },
35+
} as unknown as Page<VehicleBrandDto>)
36+
),
37+
};
38+
const vehiclesServiceMock = {
39+
createVehicle: jest.fn().mockReturnValue(of({} as VehicleDto)),
40+
};
41+
const notificationServiceMock = {
42+
showSuccess: jest.fn(),
43+
showError: jest.fn(),
44+
};
45+
const dialogRefMock = {
46+
close: jest.fn(),
47+
};
48+
949
await TestBed.configureTestingModule({
10-
imports: [CreateVehicleFormComponent],
50+
imports: [
51+
CommonModule,
52+
ReactiveFormsModule,
53+
MatFormFieldModule,
54+
MatInputModule,
55+
MatSelectModule,
56+
MatButtonModule,
57+
MatDialogModule,
58+
MatProgressSpinnerModule,
59+
BrowserAnimationsModule,
60+
CreateVehicleFormComponent, // Import the standalone component
61+
],
62+
providers: [
63+
{ provide: VehicleBrandsService, useValue: vehicleBrandsServiceMock },
64+
{ provide: VehiclesService, useValue: vehiclesServiceMock },
65+
{ provide: NotificationService, useValue: notificationServiceMock },
66+
{ provide: MatDialogRef, useValue: dialogRefMock },
67+
],
1168
}).compileComponents();
1269

1370
fixture = TestBed.createComponent(CreateVehicleFormComponent);
1471
component = fixture.componentInstance;
72+
vehicleBrandsService = TestBed.inject(
73+
VehicleBrandsService
74+
) as jest.Mocked<VehicleBrandsService>;
75+
vehiclesService = TestBed.inject(
76+
VehiclesService
77+
) as jest.Mocked<VehiclesService>;
78+
notificationService = TestBed.inject(
79+
NotificationService
80+
) as jest.Mocked<NotificationService>;
81+
dialogRef = TestBed.inject(MatDialogRef) as jest.Mocked<
82+
MatDialogRef<CreateVehicleFormComponent>
83+
>;
1584
fixture.detectChanges();
85+
86+
// Initialize the brandDropdown element
87+
component.brandDropdown = {
88+
panel: {
89+
nativeElement: document.createElement('div'),
90+
},
91+
} as MatSelect;
1692
});
1793

18-
it('should create', () => {
94+
it('should create the component', () => {
1995
expect(component).toBeTruthy();
2096
});
97+
98+
it('should render the correct content', () => {
99+
fixture.detectChanges();
100+
const compiled = fixture.nativeElement as HTMLElement;
101+
expect(compiled.querySelector('h2')?.textContent).toContain('Dodaj pojazd');
102+
expect(
103+
compiled.querySelector('button[type="submit"]')?.textContent
104+
).toContain('DODAJ');
105+
});
106+
107+
it('should call onSubmit when the form is submitted', () => {
108+
jest.spyOn(component, 'onSubmit');
109+
vehiclesService.createVehicle.mockReturnValue(of({} as VehicleDto));
110+
fixture.detectChanges();
111+
const form = fixture.nativeElement.querySelector('form');
112+
form.dispatchEvent(new Event('submit'));
113+
expect(component.onSubmit).toHaveBeenCalled();
114+
expect(vehiclesService.createVehicle).toHaveBeenCalledWith(
115+
component.vehicleForm.value
116+
);
117+
expect(notificationService.showSuccess).toHaveBeenCalledWith(
118+
'Dodano pojazd.🥳'
119+
);
120+
expect(dialogRef.close).toHaveBeenCalledWith('vehicleCreated');
121+
});
122+
123+
it('should handle error when vehicle creation fails', () => {
124+
jest.spyOn(component, 'onSubmit');
125+
vehiclesService.createVehicle.mockReturnValue(
126+
throwError(() => ({ error: { status: 409 } }))
127+
);
128+
fixture.detectChanges();
129+
const form = fixture.nativeElement.querySelector('form');
130+
form.dispatchEvent(new Event('submit'));
131+
expect(component.onSubmit).toHaveBeenCalled();
132+
expect(vehiclesService.createVehicle).toHaveBeenCalledWith(
133+
component.vehicleForm.value
134+
);
135+
expect(notificationService.showError).toHaveBeenCalledWith(
136+
'Pojazd o podanym numerze rejestracyjnym lub numerze VIN już istnieje.😥'
137+
);
138+
expect(dialogRef.close).not.toHaveBeenCalledWith('vehicleCreated');
139+
});
140+
141+
it('should load vehicle brands on init', () => {
142+
const vehicleBrands: VehicleBrandDto[] = [
143+
{ name: 'Toyota' } as VehicleBrandDto,
144+
{ name: 'Honda' } as VehicleBrandDto,
145+
];
146+
vehicleBrandsService.getVehicleBrands.mockReturnValue(
147+
of({
148+
data: vehicleBrands,
149+
meta: { itemCount: 2 },
150+
} as Page<VehicleBrandDto>)
151+
);
152+
component.ngOnInit();
153+
expect(vehicleBrandsService.getVehicleBrands).toHaveBeenCalled();
154+
expect(component.vehicleBrands).toEqual(vehicleBrands);
155+
});
156+
157+
it('should call onDropdownOpened when the dropdown is opened', () => {
158+
jest.spyOn(component, 'onDropdownOpened');
159+
fixture.detectChanges();
160+
const dropdown = fixture.nativeElement.querySelector('mat-select');
161+
dropdown.dispatchEvent(new Event('openedChange'));
162+
expect(component.onDropdownOpened).toHaveBeenCalled();
163+
});
164+
165+
it('should call loadVehicleBrands on scroll', () => {
166+
jest.spyOn(component, 'loadVehicleBrands');
167+
component.vehicleBrandsCurrentPage = 1;
168+
component.vehicleBrands = [{ name: 'Toyota' } as VehicleBrandDto];
169+
fixture.detectChanges();
170+
component.onScroll();
171+
expect(component.loadVehicleBrands).toHaveBeenCalled();
172+
});
21173
});

0 commit comments

Comments
 (0)