From 7cc95725a86fd9f548bb9751cec0b33f1a542fa2 Mon Sep 17 00:00:00 2001 From: christophercr Date: Fri, 28 Sep 2018 17:49:26 +0200 Subject: [PATCH] fix(stark-ui): perform the session login in the Preloading page after fetching the user profile ISSUES CLOSED: #726 --- .../components/breadcrumb.component.spec.ts | 2 +- .../components/breadcrumb.component.ts | 1 - .../language-selector.component.spec.ts | 2 +- .../pages/login/login-page.component.spec.ts | 81 ++++++++-------- .../preloading-page.component.spec.ts | 96 ++++++++++++++++--- .../preloading/preloading-page.component.ts | 12 ++- .../session-expired-page.component.spec.ts | 13 +-- .../session-logout-page.component.spec.ts | 9 +- .../components/slider.component.spec.ts | 2 +- .../toast-notification.service.spec.ts | 2 +- 10 files changed, 142 insertions(+), 78 deletions(-) diff --git a/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.spec.ts b/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.spec.ts index b43663d8de..984c1ace2a 100644 --- a/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.spec.ts +++ b/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.spec.ts @@ -22,7 +22,7 @@ class TestHostComponent { public breadcrumbConfig?: StarkBreadcrumbConfig; } -describe("DemoBreadcrumbComponent", () => { +describe("BreadcrumbComponent", () => { let component: StarkBreadcrumbComponent; let hostComponent: TestHostComponent; let hostFixture: ComponentFixture; diff --git a/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.ts b/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.ts index ff042c86e8..d587c07370 100644 --- a/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.ts +++ b/packages/stark-ui/src/modules/breadcrumb/components/breadcrumb.component.ts @@ -71,7 +71,6 @@ export class StarkBreadcrumbComponent extends AbstractStarkUiComponent implement // then refresh the config after every successful transition this.transitionHookDeregisterFn = this.routingService.addTransitionHook(StarkRoutingTransitionHook.ON_SUCCESS, {}, () => { this.breadcrumbConfig = { breadcrumbPaths: this.getPathsFromStateTree() }; - console.log("breadcrumb: this.breadcrumbConfig -> ", this.breadcrumbConfig); }); } } diff --git a/packages/stark-ui/src/modules/language-selector/components/language-selector.component.spec.ts b/packages/stark-ui/src/modules/language-selector/components/language-selector.component.spec.ts index 8c80aa0ba0..8c058b32d1 100644 --- a/packages/stark-ui/src/modules/language-selector/components/language-selector.component.spec.ts +++ b/packages/stark-ui/src/modules/language-selector/components/language-selector.component.spec.ts @@ -43,7 +43,7 @@ class TestHostComponent { public mode: StarkLanguageSelectorMode; } -describe("StarkLanguageSelectorComponent", () => { +describe("LanguageSelectorComponent", () => { let component: StarkLanguageSelectorComponent; let hostComponent: TestHostComponent; let hostFixture: ComponentFixture; diff --git a/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.spec.ts b/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.spec.ts index 655a114ae0..3b7b659b20 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.spec.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/login/login-page.component.spec.ts @@ -1,39 +1,36 @@ /* tslint:disable:completed-docs */ -/* angular imports */ import { async, ComponentFixture, TestBed } from "@angular/core/testing"; import { CommonModule } from "@angular/common"; -/* stark-core imports */ import { STARK_LOGGING_SERVICE, STARK_ROUTING_SERVICE, STARK_SESSION_SERVICE, STARK_USER_SERVICE, - StarkUser + StarkUser, + StarkRoutingService, + StarkSessionService, + StarkUserService } from "@nationalbankbelgium/stark-core"; - -import { TranslateModule } from "@ngx-translate/core"; -import { RawParams } from "@uirouter/core"; - import { MockStarkLoggingService, MockStarkRoutingService, MockStarkSessionService, MockStarkUserService } from "@nationalbankbelgium/stark-core/testing"; -/* stark-ui imports */ +import { TranslateModule } from "@ngx-translate/core"; +import { RawParams } from "@uirouter/core"; import { StarkLoginPageComponent } from "./login-page.component"; +import Spy = jasmine.Spy; -describe("StarkLoginPageComponent", () => { +describe("LoginPageComponent", () => { let component: StarkLoginPageComponent; let fixture: ComponentFixture; - const mockUser: StarkUser = { - firstName: "John", - lastName: "Doe", - username: "jdoe", - uuid: "mock-uuid", - roles: [] - }; + const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); + const mockUserService: StarkUserService = new MockStarkUserService(); + const mockSessionService: StarkSessionService = new MockStarkSessionService(); + const mockRoutingService: StarkRoutingService = new MockStarkRoutingService(); + const mockUser: StarkUser = { firstName: "John", lastName: "Doe", username: "jdoe", uuid: "mock-uuid", roles: [] }; const mockUserWithRoles: StarkUser = { firstName: "John", @@ -44,15 +41,14 @@ describe("StarkLoginPageComponent", () => { }; beforeEach(async(() => { - const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); return TestBed.configureTestingModule({ declarations: [StarkLoginPageComponent], imports: [CommonModule, TranslateModule.forRoot()], providers: [ { provide: STARK_LOGGING_SERVICE, useValue: mockLogger }, - { provide: STARK_ROUTING_SERVICE, useClass: MockStarkRoutingService }, - { provide: STARK_USER_SERVICE, useClass: MockStarkUserService }, - { provide: STARK_SESSION_SERVICE, useValue: new MockStarkSessionService() } + { provide: STARK_ROUTING_SERVICE, useValue: mockRoutingService }, + { provide: STARK_USER_SERVICE, useValue: mockUserService }, + { provide: STARK_SESSION_SERVICE, useValue: mockSessionService } ] }).compileComponents(); })); @@ -60,6 +56,10 @@ describe("StarkLoginPageComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(StarkLoginPageComponent); component = fixture.componentInstance; + + (mockSessionService.login).calls.reset(); + (mockRoutingService.navigateTo).calls.reset(); + (mockRoutingService.navigateToHome).calls.reset(); }); describe("on initialization", () => { @@ -78,13 +78,11 @@ describe("StarkLoginPageComponent", () => { }); describe("userProfilesAvailable", () => { - it("should return FALSE if users is undefined", () => { + it("should return FALSE if users array is undefined or empty", () => { component.users = undefined; expect(component.userProfilesAvailable()).toBe(false); - }); - it("should return FALSE if users array is empty", () => { - component.users = []; + component.users = []; expect(component.userProfilesAvailable()).toBe(false); }); @@ -95,39 +93,40 @@ describe("StarkLoginPageComponent", () => { }); describe("getUserRoles", () => { - it("should return empty string if passed user has no defined roles", () => { + it("should return empty string if the given user has no defined roles", () => { expect(component.getUserRoles(mockUser)).toBe(""); }); - it("should return string with defined roles of the passed user", () => { + it("should return string with defined roles of the given user", () => { expect(component.getUserRoles(mockUserWithRoles)).toBe("admin,developer"); }); }); describe("authenticateUser", () => { - it("should navigateTo to the provided targetState and login the user through the session service", () => { + it("should log the user in and navigate to home or to the target state if defined", () => { + component.authenticateUser(mockUser); + + expect(mockSessionService.login).toHaveBeenCalledTimes(1); + expect(mockSessionService.login).toHaveBeenCalledWith(mockUser); + expect(mockRoutingService.navigateTo).not.toHaveBeenCalled(); + expect(mockRoutingService.navigateToHome).toHaveBeenCalledTimes(1); + + (mockSessionService.login).calls.reset(); + (mockRoutingService.navigateToHome).calls.reset(); const mockState: string = "mock-state"; const mockStateParams: RawParams = { param: "mock-state-param" }; component.targetState = mockState; component.targetStateParams = mockStateParams; - fixture.detectChanges(); - component.authenticateUser(mockUser); - expect(component.routingService.navigateTo).toHaveBeenCalledTimes(1); - expect(component.routingService.navigateTo).toHaveBeenCalledWith(mockState, mockStateParams); - expect(component.routingService.navigateToHome).not.toHaveBeenCalled(); - expect(component.sessionService.login).toHaveBeenCalledTimes(1); - expect(component.sessionService.login).toHaveBeenCalledWith(mockUser); - expect(component.logger.error).not.toHaveBeenCalled(); - }); - it("should navigateToHome and login the user through the session service", () => { component.authenticateUser(mockUser); - expect(component.routingService.navigateTo).not.toHaveBeenCalled(); - expect(component.routingService.navigateToHome).toHaveBeenCalledTimes(1); - expect(component.sessionService.login).toHaveBeenCalledTimes(1); - expect(component.sessionService.login).toHaveBeenCalledWith(mockUser); + + expect(mockSessionService.login).toHaveBeenCalledTimes(1); + expect(mockSessionService.login).toHaveBeenCalledWith(mockUser); + expect(mockRoutingService.navigateTo).toHaveBeenCalledTimes(1); + expect(mockRoutingService.navigateTo).toHaveBeenCalledWith(mockState, mockStateParams); + expect(mockRoutingService.navigateToHome).not.toHaveBeenCalled(); expect(component.logger.error).not.toHaveBeenCalled(); }); }); diff --git a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.spec.ts b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.spec.ts index 6763a2e356..418aee6332 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.spec.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.spec.ts @@ -1,30 +1,47 @@ /* tslint:disable:completed-docs */ -/* angular imports */ -import { async, ComponentFixture, TestBed } from "@angular/core/testing"; +import { async, ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; import { CommonModule } from "@angular/common"; -/* stark-core imports */ -import { STARK_LOGGING_SERVICE, STARK_ROUTING_SERVICE, STARK_USER_SERVICE } from "@nationalbankbelgium/stark-core"; - +import { + STARK_LOGGING_SERVICE, + STARK_ROUTING_SERVICE, + STARK_USER_SERVICE, + STARK_SESSION_SERVICE, + StarkUser, + StarkUserService, + StarkRoutingService, + StarkSessionService +} from "@nationalbankbelgium/stark-core"; +import { + MockStarkLoggingService, + MockStarkRoutingService, + MockStarkUserService, + MockStarkSessionService +} from "@nationalbankbelgium/stark-core/testing"; import { TranslateModule } from "@ngx-translate/core"; - -import { MockStarkLoggingService, MockStarkRoutingService, MockStarkUserService } from "@nationalbankbelgium/stark-core/testing"; -/* stark-ui imports */ -import { StarkPreloadingPageComponent } from "./preloading-page.component"; import { MatButtonModule } from "@angular/material/button"; +import { of, throwError } from "rxjs"; +import { StarkPreloadingPageComponent } from "./preloading-page.component"; +import Spy = jasmine.Spy; -describe("StarkPreloadingPageComponent", () => { +describe("PreloadingPageComponent", () => { let component: StarkPreloadingPageComponent; let fixture: ComponentFixture; + const mockUser: StarkUser = { firstName: "John", lastName: "Doe", username: "jdoe", uuid: "mock-uuid", roles: [] }; + const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); + const mockUserService: StarkUserService = new MockStarkUserService(); + const mockSessionService: StarkSessionService = new MockStarkSessionService(); + const mockRoutingService: StarkRoutingService = new MockStarkRoutingService(); + beforeEach(async(() => { - const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); return TestBed.configureTestingModule({ declarations: [StarkPreloadingPageComponent], imports: [CommonModule, MatButtonModule, TranslateModule.forRoot()], providers: [ { provide: STARK_LOGGING_SERVICE, useValue: mockLogger }, - { provide: STARK_ROUTING_SERVICE, useClass: MockStarkRoutingService }, - { provide: STARK_USER_SERVICE, useClass: MockStarkUserService } + { provide: STARK_ROUTING_SERVICE, useValue: mockRoutingService }, + { provide: STARK_USER_SERVICE, useValue: mockUserService }, + { provide: STARK_SESSION_SERVICE, useValue: mockSessionService } ] }).compileComponents(); })); @@ -32,6 +49,11 @@ describe("StarkPreloadingPageComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(StarkPreloadingPageComponent); component = fixture.componentInstance; + + (mockUserService.fetchUserProfile).calls.reset(); + (mockSessionService.login).calls.reset(); + (mockRoutingService.navigateTo).calls.reset(); + (mockRoutingService.navigateToHome).calls.reset(); }); describe("on initialization", () => { @@ -47,6 +69,54 @@ describe("StarkPreloadingPageComponent", () => { }); }); + describe("ngOnInit", () => { + it("should log the user in automatically after fetching the user profile successfully", fakeAsync(() => { + (mockUserService.fetchUserProfile).and.returnValue(of(mockUser)); + component.loginDelay = 1; // override login delay to make unit tests faster + + component.ngOnInit(); + tick(1); + + expect(mockUserService.fetchUserProfile).toHaveBeenCalledTimes(1); + expect(mockSessionService.login).toHaveBeenCalledTimes(1); + expect(mockSessionService.login).toHaveBeenCalledWith(mockUser); + expect(component.userFetchingFailed).toBeFalsy(); + })); + + it("should navigate to home or the target state if defined after fetching the user profile successfully", fakeAsync(() => { + (mockUserService.fetchUserProfile).and.returnValue(of(mockUser)); + component.loginDelay = 1; // override login delay to make unit tests faster + + component.ngOnInit(); + tick(1); + + expect(mockRoutingService.navigateToHome).toHaveBeenCalledTimes(1); + expect(mockRoutingService.navigateTo).not.toHaveBeenCalled(); + + (mockRoutingService.navigateToHome).calls.reset(); + component.targetState = "dummy state"; + component.targetStateParams = { someParam: "dummy param" }; + component.ngOnInit(); + tick(1); + + expect(mockRoutingService.navigateToHome).not.toHaveBeenCalled(); + expect(mockRoutingService.navigateTo).toHaveBeenCalledTimes(1); + expect(mockRoutingService.navigateTo).toHaveBeenCalledWith(component.targetState, component.targetStateParams); + })); + + it("should NOT do anything when the user profile cannot be fetched", fakeAsync(() => { + (mockUserService.fetchUserProfile).and.returnValue(throwError("could not fetch user profile")); + component.loginDelay = 1; // override login delay to make unit tests faster + + component.ngOnInit(); + tick(1); + + expect(mockRoutingService.navigateToHome).not.toHaveBeenCalled(); + expect(mockRoutingService.navigateTo).not.toHaveBeenCalled(); + expect(component.userFetchingFailed).toBe(true); + })); + }); + describe("reload", () => { it("should call reload method of routingService", () => { component.reload(); diff --git a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts index f29504a109..cc0f9ee0c7 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/preloading/preloading-page.component.ts @@ -6,9 +6,12 @@ import { STARK_LOGGING_SERVICE, STARK_ROUTING_SERVICE, STARK_USER_SERVICE, + STARK_SESSION_SERVICE, + StarkSessionService, StarkLoggingService, StarkRoutingService, - StarkUserService + StarkUserService, + StarkUser } from "@nationalbankbelgium/stark-core"; /** @@ -35,10 +38,12 @@ export class StarkPreloadingPageComponent implements OnInit { public userFetchingFailed: boolean; public correlationId: string; + public loginDelay: number = 200; public constructor( @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, @Inject(STARK_USER_SERVICE) public userService: StarkUserService, + @Inject(STARK_SESSION_SERVICE) public sessionService: StarkSessionService, @Inject(STARK_ROUTING_SERVICE) public routingService: StarkRoutingService ) {} @@ -52,10 +57,11 @@ export class StarkPreloadingPageComponent implements OnInit { .fetchUserProfile() .pipe( take(1), // this ensures that the observable will be automatically unsubscribed after emitting the value - delay(200) + delay(this.loginDelay) ) .subscribe( - (/*user: StarkUser*/) => { + (user: StarkUser) => { + this.sessionService.login(user); if (this.targetState) { this.routingService.navigateTo(this.targetState, this.targetStateParams); } else { diff --git a/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.spec.ts b/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.spec.ts index 540011fa57..cc4339297a 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.spec.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/session-expired/session-expired-page.component.spec.ts @@ -1,27 +1,22 @@ /* tslint:disable:completed-docs */ -/* angular imports */ import { async, ComponentFixture, TestBed } from "@angular/core/testing"; import { CommonModule } from "@angular/common"; -/* stark-core imports */ import { STARK_APP_CONFIG, STARK_LOGGING_SERVICE, StarkApplicationConfig } from "@nationalbankbelgium/stark-core"; - -import { TranslateModule } from "@ngx-translate/core"; - import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; -/* stark-ui imports */ -import { StarkSessionExpiredPageComponent } from "./session-expired-page.component"; import { MatButtonModule } from "@angular/material/button"; +import { TranslateModule } from "@ngx-translate/core"; +import { StarkSessionExpiredPageComponent } from "./session-expired-page.component"; -describe("StarkSessionExpiredPageComponent", () => { +describe("SessionExpiredPageComponent", () => { let component: StarkSessionExpiredPageComponent; let fixture: ComponentFixture; + const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); const mockStarkAppConfig: Partial = { baseUrl: "base-url" }; beforeEach(async(() => { - const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); return TestBed.configureTestingModule({ declarations: [StarkSessionExpiredPageComponent], imports: [CommonModule, MatButtonModule, TranslateModule.forRoot()], diff --git a/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.spec.ts b/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.spec.ts index a207cf2019..63281ccbc3 100644 --- a/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.spec.ts +++ b/packages/stark-ui/src/modules/session-ui/pages/session-logout/session-logout-page.component.spec.ts @@ -1,17 +1,12 @@ /* tslint:disable:completed-docs */ -/* angular imports */ import { async, ComponentFixture, TestBed } from "@angular/core/testing"; import { CommonModule } from "@angular/common"; -/* stark-core imports */ import { STARK_APP_CONFIG, STARK_LOGGING_SERVICE, StarkApplicationConfig } from "@nationalbankbelgium/stark-core"; - -import { TranslateModule } from "@ngx-translate/core"; - import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; -/* stark-ui imports */ +import { TranslateModule } from "@ngx-translate/core"; import { StarkSessionLogoutPageComponent } from "./session-logout-page.component"; -describe("StarkSessionLogoutPageComponent", () => { +describe("SessionLogoutPageComponent", () => { let component: StarkSessionLogoutPageComponent; let fixture: ComponentFixture; diff --git a/packages/stark-ui/src/modules/slider/components/slider.component.spec.ts b/packages/stark-ui/src/modules/slider/components/slider.component.spec.ts index c77db86f3e..ffe5832d5f 100644 --- a/packages/stark-ui/src/modules/slider/components/slider.component.spec.ts +++ b/packages/stark-ui/src/modules/slider/components/slider.component.spec.ts @@ -40,7 +40,7 @@ class TestHostComponent { } } -describe("SliderController", () => { +describe("SliderComponent", () => { let component: StarkSliderComponent; let hostComponent: TestHostComponent; let hostFixture: ComponentFixture; diff --git a/packages/stark-ui/src/modules/toast-notification/services/toast-notification.service.spec.ts b/packages/stark-ui/src/modules/toast-notification/services/toast-notification.service.spec.ts index 88991b747e..28e494c9fc 100644 --- a/packages/stark-ui/src/modules/toast-notification/services/toast-notification.service.spec.ts +++ b/packages/stark-ui/src/modules/toast-notification/services/toast-notification.service.spec.ts @@ -11,7 +11,7 @@ import { StarkToastNotificationServiceImpl } from "./toast-notification.service" import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; import { Observable, Observer } from "rxjs"; -describe("Service: StarkToastNotificationService", () => { +describe("ToastNotificationService", () => { const message: StarkToastMessage = { key: "testMessage", id: "1",