Skip to content

Commit

Permalink
fix(stark-ui): perform the session login in the Preloading page after…
Browse files Browse the repository at this point in the history
… fetching the user profile

ISSUES CLOSED: #726
  • Loading branch information
christophercr committed Sep 28, 2018
1 parent 16b6869 commit 7cc9572
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class TestHostComponent {
public breadcrumbConfig?: StarkBreadcrumbConfig;
}

describe("DemoBreadcrumbComponent", () => {
describe("BreadcrumbComponent", () => {
let component: StarkBreadcrumbComponent;
let hostComponent: TestHostComponent;
let hostFixture: ComponentFixture<TestHostComponent>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class TestHostComponent {
public mode: StarkLanguageSelectorMode;
}

describe("StarkLanguageSelectorComponent", () => {
describe("LanguageSelectorComponent", () => {
let component: StarkLanguageSelectorComponent;
let hostComponent: TestHostComponent;
let hostFixture: ComponentFixture<TestHostComponent>;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<StarkLoginPageComponent>;

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",
Expand All @@ -44,22 +41,25 @@ 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();
}));

beforeEach(() => {
fixture = TestBed.createComponent(StarkLoginPageComponent);
component = fixture.componentInstance;

(<Spy>mockSessionService.login).calls.reset();
(<Spy>mockRoutingService.navigateTo).calls.reset();
(<Spy>mockRoutingService.navigateToHome).calls.reset();
});

describe("on initialization", () => {
Expand All @@ -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 = <any>undefined;
expect(component.userProfilesAvailable()).toBe(false);
});

it("should return FALSE if users array is empty", () => {
component.users = <any>[];
component.users = [];
expect(component.userProfilesAvailable()).toBe(false);
});

Expand All @@ -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);

(<Spy>mockSessionService.login).calls.reset();
(<Spy>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();
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
/* 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<StarkPreloadingPageComponent>;

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();
}));

beforeEach(() => {
fixture = TestBed.createComponent(StarkPreloadingPageComponent);
component = fixture.componentInstance;

(<Spy>mockUserService.fetchUserProfile).calls.reset();
(<Spy>mockSessionService.login).calls.reset();
(<Spy>mockRoutingService.navigateTo).calls.reset();
(<Spy>mockRoutingService.navigateToHome).calls.reset();
});

describe("on initialization", () => {
Expand All @@ -47,6 +69,54 @@ describe("StarkPreloadingPageComponent", () => {
});
});

describe("ngOnInit", () => {
it("should log the user in automatically after fetching the user profile successfully", fakeAsync(() => {
(<Spy>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(() => {
(<Spy>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();

(<Spy>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(() => {
(<Spy>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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

/**
Expand All @@ -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
) {}

Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<StarkSessionExpiredPageComponent>;

const mockLogger: MockStarkLoggingService = new MockStarkLoggingService();
const mockStarkAppConfig: Partial<StarkApplicationConfig> = {
baseUrl: "base-url"
};

beforeEach(async(() => {
const mockLogger: MockStarkLoggingService = new MockStarkLoggingService();
return TestBed.configureTestingModule({
declarations: [StarkSessionExpiredPageComponent],
imports: [CommonModule, MatButtonModule, TranslateModule.forRoot()],
Expand Down

0 comments on commit 7cc9572

Please sign in to comment.