Skip to content

Commit b3cc721

Browse files
committed
Merge branch 'main' of https://github.com/bcgov/nr-bcws-wfprev into feature/WFPREV-402
2 parents fb4541a + 759e5bc commit b3cc721

File tree

7 files changed

+93
-7
lines changed

7 files changed

+93
-7
lines changed

client/wfprev-war/src/main/angular/src/app/components/shared-layout/app-header/app-header.component.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
}
8383

8484
button {
85+
white-space: nowrap;
8586
display: flex;
8687
align-items: center;
8788
color: white;

client/wfprev-war/src/main/angular/src/app/components/shared-layout/app-header/app-header.component.spec.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,65 @@ import { Router } from '@angular/router';
44
import { By } from '@angular/platform-browser';
55
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
66
import { ResourcesRoutes } from 'src/app/utils';
7+
import { HttpClientTestingModule } from '@angular/common/http/testing';
8+
import { AppConfigService } from 'src/app/services/app-config.service';
9+
import { Subject } from 'rxjs';
10+
import { TokenService } from 'src/app/services/token.service';
711

812
describe('AppHeaderComponent', () => {
913
let component: AppHeaderComponent;
1014
let fixture: ComponentFixture<AppHeaderComponent>;
15+
let mockTokenService: any;
16+
let credentialsSubject: Subject<void>;
17+
18+
const mockConfig = {
19+
application: {
20+
lazyAuthenticate: false,
21+
enableLocalStorageToken: true,
22+
localStorageTokenKey: 'test-oauth',
23+
allowLocalExpiredToken: false,
24+
baseUrl: 'http://test.com'
25+
},
26+
webade: {
27+
oauth2Url: 'http://oauth.test',
28+
clientId: 'test-client',
29+
authScopes: ['GET_PROJECT'],
30+
enableCheckToken: false,
31+
checkTokenUrl: 'http://check-token.test'
32+
}
33+
};
34+
35+
const mockAppConfigService = {
36+
getConfig: jasmine.createSpy('getConfig').and.returnValue(mockConfig),
37+
loadConfig: jasmine.createSpy('loadConfig').and.returnValue(Promise.resolve(mockConfig))
38+
};
1139

1240
beforeEach(async () => {
41+
credentialsSubject = new Subject<void>();
42+
43+
mockTokenService = {
44+
getUserFullName: jasmine.createSpy('getUserFullName').and.returnValue('Mocked User'),
45+
credentialsEmitter: credentialsSubject
46+
};
47+
1348
await TestBed.configureTestingModule({
1449
imports: [
1550
AppHeaderComponent,
1651
BrowserAnimationsModule,
52+
HttpClientTestingModule
1753
],
1854
providers: [
1955
{ provide: Router, useValue: { navigate: jasmine.createSpy('navigate') } },
56+
{ provide: AppConfigService, useValue: mockAppConfigService },
57+
{ provide: TokenService, useValue: mockTokenService }
2058
],
2159
}).compileComponents();
22-
60+
2361
fixture = TestBed.createComponent(AppHeaderComponent);
2462
component = fixture.componentInstance;
2563
fixture.detectChanges();
2664
});
65+
2766

2867
it('should create the component', () => {
2968
expect(component).toBeTruthy();
@@ -95,4 +134,15 @@ describe('AppHeaderComponent', () => {
95134
const menuElement = fixture.debugElement.query(By.css('mat-menu'));
96135
expect(menuElement).toBeTruthy();
97136
});
137+
138+
it('should set currentUser when credentialsEmitter emits a value', () => {
139+
const mockName = 'Mike David';
140+
mockTokenService.getUserFullName.and.returnValue(mockName);
141+
142+
component.ngOnInit();
143+
credentialsSubject.next();
144+
145+
expect(component.currentUser).toBe(mockName);
146+
});
147+
98148
});

client/wfprev-war/src/main/angular/src/app/components/shared-layout/app-header/app-header.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Component } from '@angular/core';
1+
import { Component, OnInit } from '@angular/core';
22
import { Router } from '@angular/router';
33
import { ResourcesRoutes } from 'src/app/utils';
44
import { MatMenuModule } from '@angular/material/menu';
55
import { MatButtonModule } from '@angular/material/button';
66
import { MatIconModule } from '@angular/material/icon';
77
import { CommonModule } from '@angular/common';
8+
import { TokenService } from 'src/app/services/token.service';
89

910
@Component({
1011
selector: 'app-app-header',
@@ -18,10 +19,11 @@ import { CommonModule } from '@angular/common';
1819
templateUrl: './app-header.component.html',
1920
styleUrls: ['./app-header.component.scss']
2021
})
21-
export class AppHeaderComponent {
22+
export class AppHeaderComponent implements OnInit{
2223

2324
constructor(
2425
protected router: Router,
26+
private readonly tokenService: TokenService
2527
) {
2628
}
2729

@@ -30,6 +32,15 @@ export class AppHeaderComponent {
3032
title:string = 'PREVENTION'
3133
currentUser: string = 'User_1'
3234

35+
ngOnInit(): void {
36+
this.tokenService.credentialsEmitter.subscribe(() => {
37+
const name = this.tokenService.getUserFullName();
38+
if (name) {
39+
this.currentUser = name;
40+
}
41+
});
42+
}
43+
3344
onLogoutClick(){
3445
//clear token will be implemented after authorization piece done
3546
// this.tokenService.clearLocalStorageToken();

client/wfprev-war/src/main/angular/src/app/services/token.service.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,21 @@ describe('emitTokens', () => {
310310
});
311311
});
312312

313+
describe('getUserFullName', () => {
314+
it('should return full name when both first and last names are present', () => {
315+
service['tokenDetails'] = { given_name: 'John', family_name: 'Doe' };
316+
expect(service.getUserFullName()).toBe('John Doe');
317+
});
318+
319+
it('should return null if both names are missing', () => {
320+
service['tokenDetails'] = {};
321+
expect(service.getUserFullName()).toBeNull();
322+
});
323+
324+
it('should return null if tokenDetails is undefined', () => {
325+
service['tokenDetails'] = undefined!;
326+
expect(service.getUserFullName()).toBeNull();
327+
});
328+
});
329+
313330
});

client/wfprev-war/src/main/angular/src/app/services/token.service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ export class TokenService {
215215
return this.oauth?.access_token ?? null;
216216
}
217217

218+
public getUserFullName(): string | null {
219+
const first = (this.tokenDetails?.given_name ?? this.tokenDetails?.givenName) ?? '';
220+
const last = (this.tokenDetails?.family_name ?? this.tokenDetails?.familyName) ?? '';
221+
const fullName = `${first} ${last}`.trim();
222+
return fullName || null;
223+
}
224+
218225
public doesUserHaveApplicationPermissions(scopes?: string[]): boolean {
219226
if (this.tokenDetails?.scope?.length > 0 && scopes?.length) {
220227
return scopes.every(scope => this.tokenDetails.scope.includes(scope));

client/wfprev-war/src/main/angular/src/assets/data/appConfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
"webade": {
77
"oauth2Url": "#{WEBADE_OAUTH2_CHECK_AUTHORIZE_URL}#",
8-
"clientId": "WFNEWS-UI",
9-
"authScopes": "WFNEWS.* WFDM.*",
8+
"clientId": "WFPREV-UI",
9+
"authScopes": "WFPREV.* WFDM.*",
1010
"enableCheckToken": true,
1111
"checkTokenUrl": "#{WFPREV_CHECK_TOKEN_URL}#"
1212
},

client/wfprev-war/src/main/angular/src/assets/data/appConfig.local.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
"webade": {
77
"oauth2Url": "https://wfappsi.nrs.gov.bc.ca/ext/oauth2/v1/oauth/authorize",
8-
"clientId": "WFNEWS-UI",
9-
"authScopes": "WFNEWS.* WFDM.*",
8+
"clientId": "WFPREV-UI",
9+
"authScopes": "WFPREV.* WFDM.*",
1010
"enableCheckToken": true,
1111
"checkTokenUrl": "./assets/data/checktoken-user.json"
1212
},

0 commit comments

Comments
 (0)