Skip to content

Commit 82410b4

Browse files
committed
Add unit test on webapp's tcr-role-component initialization
1 parent cea8ef0 commit 82410b4

11 files changed

+101
-26
lines changed

webapp/src/app/components/tcr-console/tcr-console.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class TcrConsoleComponent implements OnInit {
3131
@ViewChild('term', {static: false}) child!: NgTerminal;
3232

3333
constructor(private messageService: TcrMessageService) {
34-
this.tcrMessage = toSignal(this.messageService.webSocket$);
34+
this.tcrMessage = toSignal(this.messageService.message$);
3535

3636
effect(() => {
3737
// When receiving a message from the server

webapp/src/app/components/tcr-role/tcr-role.component.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
'navigator-on': role.active && role.name === 'navigator',
44
'driver-on' : role.active && role.name === 'driver',
55
'role-off': !role.active}"
6+
data-testid="role-component"
67
class="wrap">
78
<div class="ico-wrap">
8-
<span class="mbr-iconfont fa-compass fa" *ngIf="role.name === 'navigator'"></span>
9-
<span class="mbr-iconfont fa-keyboard-o fa" *ngIf="role.name === 'driver'"></span>
9+
<span class="mbr-iconfont fa-compass fa" *ngIf="role.name === 'navigator'" data-testid="role-icon"></span>
10+
<span class="mbr-iconfont fa-keyboard-o fa" *ngIf="role.name === 'driver'" data-testid="role-icon"></span>
1011
</div>
1112
<div class="text-wrap vcenter">
12-
<h2 class="mbr-fonts-style mbr-bold mbr-section-title3 display-5">{{ role.description }}</h2>
13+
<h2 class="mbr-fonts-style mbr-bold mbr-section-title3 display-5" data-testid="role-label">{{ role.description }}</h2>
1314
</div>
1415
</div>
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import {ComponentFixture, TestBed} from '@angular/core/testing';
22

33
import {TcrRoleComponent} from './tcr-role.component';
4-
import {HttpClientTestingModule} from "@angular/common/http/testing";
5-
import {Observable, Subject} from "rxjs";
4+
import {Observable, of} from "rxjs";
65
import {TcrMessage} from "../../interfaces/tcr-message";
76
import {TcrRolesService} from "../../services/trc-roles.service";
87
import {TcrRole} from "../../interfaces/tcr-role";
8+
import {By} from "@angular/platform-browser";
99

1010
class TcrRolesServiceFake implements Partial<TcrRolesService> {
11-
webSocket$: Subject<TcrMessage> = new Subject<TcrMessage>();
11+
constructor(public message$ = new Observable<TcrMessage>()) {
12+
}
1213

13-
getRole(name: string): Observable<TcrRole> {
14-
return new Observable<TcrRole>();
14+
getRole(): Observable<TcrRole> {
15+
return of({name: "", description: "", active: false});
1516
}
1617
}
1718

@@ -22,20 +23,93 @@ describe('TcrRoleComponent', () => {
2223

2324
beforeEach(async () => {
2425
await TestBed.configureTestingModule({
25-
imports: [TcrRoleComponent, HttpClientTestingModule],
26+
imports: [TcrRoleComponent],
2627
providers: [
2728
{provide: TcrRolesService, useClass: TcrRolesServiceFake},
2829
]
2930
}).compileComponents();
3031

32+
serviceFake = TestBed.inject(TcrRolesService);
3133
fixture = TestBed.createComponent(TcrRoleComponent);
3234
component = fixture.componentInstance;
33-
serviceFake = TestBed.inject(TcrRolesService);
3435
fixture.detectChanges();
3536
});
3637

37-
it('should create', () => {
38-
expect(component).toBeTruthy();
38+
describe('component instance', () => {
39+
it('should be created', () => {
40+
expect(component).toBeTruthy();
41+
});
42+
});
43+
44+
describe('component initialization', () => {
45+
const testCases = [
46+
{
47+
name: "driver",
48+
description: "driver role",
49+
active: true,
50+
componentClass: 'driver-on',
51+
iconClass: 'fa-keyboard-o'
52+
},
53+
{
54+
name: "driver",
55+
description: "driver role",
56+
active: false,
57+
componentClass: 'role-off',
58+
iconClass: 'fa-keyboard-o'
59+
},
60+
{
61+
name: "navigator",
62+
description: "navigator role",
63+
active: true,
64+
componentClass: 'navigator-on',
65+
iconClass: 'fa-compass'
66+
},
67+
{
68+
name: "navigator",
69+
description: "navigator role",
70+
active: false,
71+
componentClass: 'role-off',
72+
iconClass: 'fa-compass'
73+
}
74+
];
75+
76+
testCases.forEach(testCase => {
77+
it(`should work with ${testCase.name} role ${testCase.active ? "on" : "off"}`, (done) => {
78+
const role: TcrRole = {
79+
name: testCase.name,
80+
description: testCase.description,
81+
active: testCase.active,
82+
};
83+
84+
// Have the service fake's getRole method return the role
85+
serviceFake.getRole = () => of(role);
86+
fixture = TestBed.createComponent(TcrRoleComponent);
87+
component = fixture.componentInstance;
88+
fixture.detectChanges();
89+
done()
90+
91+
// Verify that the component's role attribute is set correctly
92+
expect(component.role).toEqual(role);
93+
94+
// Verify that the component is rendered with the expected CSS class
95+
const componentElement = fixture.debugElement.query(
96+
By.css(`[data-testid="role-component"]`));
97+
expect(componentElement).toBeTruthy();
98+
expect(componentElement.nativeElement.classList).toContain(testCase.componentClass);
99+
100+
// Verify that the right role icon is rendered
101+
const iconElement = fixture.debugElement.query(
102+
By.css(`[data-testid="role-icon"]`));
103+
expect(iconElement).toBeTruthy();
104+
expect(iconElement.nativeElement.classList).toContain(testCase.iconClass);
105+
106+
// Verify that the role label is rendered
107+
const labelElement = fixture.debugElement.query(
108+
By.css(`[data-testid="role-label"]`));
109+
expect(labelElement).toBeTruthy();
110+
expect(labelElement.nativeElement.textContent).toEqual(role.description);
111+
});
112+
});
39113
});
40114
});
41115

webapp/src/app/components/tcr-role/tcr-role.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class TcrRoleComponent implements OnInit {
2121
roleMessage: Signal<TcrMessage | undefined>;
2222

2323
constructor(private rolesService: TcrRolesService) {
24-
this.roleMessage = toSignal(this.rolesService.webSocket$);
24+
this.roleMessage = toSignal(this.rolesService.message$);
2525

2626
effect(() => {
2727
// When receiving a role message from the server

webapp/src/app/components/tcr-timer/tcr-timer.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class TcrTimerComponent implements OnInit, AfterViewInit {
2929
private SYNC_INTERVAL = 10;
3030

3131
constructor(private timerService: TcrTimerService) {
32-
this.timerMessage = toSignal(this.timerService.webSocket$);
32+
this.timerMessage = toSignal(this.timerService.message$);
3333

3434
effect(() => {
3535
// When receiving a timer message from the server

webapp/src/app/services/tcr-message.service.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('TcrMessageService', () => {
4343
timestamp: "",
4444
};
4545
let actual: TcrMessage | undefined;
46-
service.webSocket$.subscribe((msg) => {
46+
service.message$.subscribe((msg) => {
4747
actual = msg;
4848
done();
4949
});

webapp/src/app/services/tcr-message.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
88
providedIn: 'root'
99
})
1010
export class TcrMessageService {
11-
public webSocket$: Observable<TcrMessage>;
11+
public message$: Observable<TcrMessage>;
1212

1313
constructor(private ws: WebsocketService) {
14-
this.webSocket$ = this.ws.webSocket$.pipe(
14+
this.message$ = this.ws.webSocket$.pipe(
1515
retry({delay: 5_000}),
1616
takeUntilDestroyed(),
1717
)

webapp/src/app/services/tcr-timer.service.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('TcrTimerService', () => {
8686
timestamp: "",
8787
};
8888
let actual: TcrMessage | undefined;
89-
service.webSocket$.subscribe((msg) => {
89+
service.message$.subscribe((msg) => {
9090
actual = msg;
9191
done();
9292
});
@@ -103,7 +103,7 @@ describe('TcrTimerService', () => {
103103
timestamp: "",
104104
};
105105
let actual: TcrMessage | undefined;
106-
service.webSocket$.subscribe((msg) => {
106+
service.message$.subscribe((msg) => {
107107
actual = msg;
108108
done();
109109
});

webapp/src/app/services/tcr-timer.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
1111
})
1212
export class TcrTimerService {
1313
private apiUrl = `/api`; // URL to web api
14-
public webSocket$: Observable<TcrMessage>;
14+
public message$: Observable<TcrMessage>;
1515

1616
constructor(private http: HttpClient, private ws: WebsocketService) {
17-
this.webSocket$ = this.ws.webSocket$.pipe(
17+
this.message$ = this.ws.webSocket$.pipe(
1818
filter(message => message.type === TcrMessageType.TIMER),
1919
retry({delay: 5_000}),
2020
takeUntilDestroyed(),

webapp/src/app/services/trc-roles.service.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ describe('TcrRolesService', () => {
133133
timestamp: "",
134134
};
135135
let actual: TcrMessage | undefined;
136-
service.webSocket$.subscribe((msg) => {
136+
service.message$.subscribe((msg) => {
137137
actual = msg;
138138
done();
139139
});
@@ -150,7 +150,7 @@ describe('TcrRolesService', () => {
150150
timestamp: "",
151151
};
152152
let actual: TcrMessage | undefined;
153-
service.webSocket$.subscribe((msg) => {
153+
service.message$.subscribe((msg) => {
154154
actual = msg;
155155
done();
156156
});

webapp/src/app/services/trc-roles.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
1111
})
1212
export class TcrRolesService {
1313
private apiUrl = `/api`; // URL to web api
14-
public webSocket$: Observable<TcrMessage>;
14+
public message$: Observable<TcrMessage>;
1515

1616
constructor(private http: HttpClient, private ws: WebsocketService) {
17-
this.webSocket$ = this.ws.webSocket$.pipe(
17+
this.message$ = this.ws.webSocket$.pipe(
1818
filter(message => message.type === TcrMessageType.ROLE),
1919
retry({delay: 5_000}),
2020
takeUntilDestroyed(),

0 commit comments

Comments
 (0)