aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/user/user-dialog
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/ClientApp/src/app/user/user-dialog')
-rw-r--r--Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html7
-rw-r--r--Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.spec.ts86
-rw-r--r--Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts47
3 files changed, 55 insertions, 85 deletions
diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
index 50d6ba56..58dff0e4 100644
--- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
+++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
@@ -1,5 +1,4 @@
-<div [ngSwitch]="state" class="container">
- <mat-progress-spinner *ngSwitchCase="'loading'" mode="indeterminate" diameter="50"></mat-progress-spinner>
- <app-user-login *ngSwitchCase="'login'" (login)="login($event)" [message]="loginMessage"></app-user-login>
- <app-user-login-success *ngSwitchCase="'success'" [userInfo]="userInfo" [displayLoginSuccessMessage]="displayLoginSuccessMessage"></app-user-login-success>
+<div class="container">
+ <mat-progress-spinner *ngIf="isLoading" mode="indeterminate" diameter="50"></mat-progress-spinner>
+ <router-outlet name="user"></router-outlet>
</div>
diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.spec.ts b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.spec.ts
index d24c0cd2..c56e1ed1 100644
--- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.spec.ts
+++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.spec.ts
@@ -1,13 +1,13 @@
-import { Component, Output, EventEmitter } from '@angular/core';
+import { Component } from '@angular/core';
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
-import { of } from 'rxjs';
+import { Router, Event } from '@angular/router';
+import { of, Observable } from 'rxjs';
import { delay } from 'rxjs/operators';
-import { UserInfo } from '../user-info';
import { UserDialogComponent } from './user-dialog.component';
-import { UserService, UserLoginState } from '../user-service/user.service';
-import { LoginEvent } from '../user-login/user-login.component';
+import { createMockInternalUserService } from '../internal-user-service/internal-user.service.mock';
+import { InternalUserService, UserLoginState } from '../internal-user-service/internal-user.service';
@Component({
/* tslint:disable-next-line:component-selector*/
@@ -17,36 +17,30 @@ import { LoginEvent } from '../user-login/user-login.component';
class MatProgressSpinnerStubComponent { }
@Component({
- selector: 'app-user-login',
- /* tslint:disable-next-line:use-input-property-decorator*/
- inputs: ['message'],
+ /* tslint:disable-next-line:component-selector*/
+ selector: 'router-outlet',
template: ''
})
-class UserLoginStubComponent {
- @Output()
- login = new EventEmitter<LoginEvent>();
-}
+class RouterOutletStubComponent { }
-@Component({
- selector: 'app-user-login-success',
- /* tslint:disable-next-line:use-input-property-decorator*/
- inputs: ['userInfo', 'displayLoginSuccessMessage'],
- template: ''
-})
-class UserLoginSuccessStubComponent { }
describe('UserDialogComponent', () => {
let component: UserDialogComponent;
let fixture: ComponentFixture<UserDialogComponent>;
- let mockUserService: jasmine.SpyObj<UserService>;
+ let mockInternalUserService: jasmine.SpyObj<InternalUserService>;
+
beforeEach(async(() => {
- mockUserService = jasmine.createSpyObj('UserService', ['validateUserLoginState', 'tryLogin']);
+ mockInternalUserService = createMockInternalUserService();
TestBed.configureTestingModule({
- declarations: [UserDialogComponent, MatProgressSpinnerStubComponent,
- UserLoginStubComponent, UserLoginSuccessStubComponent],
- providers: [{ provide: UserService, useValue: mockUserService }]
+ declarations: [UserDialogComponent, MatProgressSpinnerStubComponent, RouterOutletStubComponent],
+ providers: [{ provide: InternalUserService, useValue: mockInternalUserService },
+ { // for the workaround
+ provide: Router, useValue: {
+ events: new Observable<Event>()
+ }
+ }]
})
.compileComponents();
}));
@@ -57,7 +51,7 @@ describe('UserDialogComponent', () => {
});
it('progress spinner should work well', fakeAsync(() => {
- mockUserService.validateUserLoginState.and.returnValue(of(<UserLoginState>{ state: 'nologin' }).pipe(delay(10)));
+ mockInternalUserService.refreshAndGetUserState.and.returnValue(of(<UserLoginState>'nologin').pipe(delay(10)));
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('mat-progress-spinner'))).toBeTruthy();
tick(10);
@@ -66,49 +60,29 @@ describe('UserDialogComponent', () => {
}));
it('nologin should work well', () => {
- mockUserService.validateUserLoginState.and.returnValue(of(<UserLoginState>{ state: 'nologin' }));
+ mockInternalUserService.refreshAndGetUserState.and.returnValue(of(<UserLoginState>'nologin'));
fixture.detectChanges();
- expect(mockUserService.validateUserLoginState).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('app-user-login'))).toBeTruthy();
- expect(fixture.debugElement.query(By.css('app-user-login-success'))).toBeFalsy();
+ expect(mockInternalUserService.refreshAndGetUserState).toHaveBeenCalled();
+ expect(mockInternalUserService.userRouteNavigate).toHaveBeenCalledWith(['login', { reason: 'nologin' }]);
});
- it('success should work well', () => {
- mockUserService.validateUserLoginState.and.returnValue(of(<UserLoginState>{ state: 'success', userInfo: {} }));
+ it('invalid login should work well', () => {
+ mockInternalUserService.refreshAndGetUserState.and.returnValue(of(<UserLoginState>'invalidlogin'));
fixture.detectChanges();
- expect(mockUserService.validateUserLoginState).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('app-user-login'))).toBeFalsy();
- expect(fixture.debugElement.query(By.css('app-user-login-success'))).toBeTruthy();
+ expect(mockInternalUserService.refreshAndGetUserState).toHaveBeenCalled();
+ expect(mockInternalUserService.userRouteNavigate).toHaveBeenCalledWith(['login', { reason: 'invalidlogin' }]);
});
- it('login should work well', () => {
- mockUserService.validateUserLoginState.and.returnValue(of(<UserLoginState>{ state: 'nologin' }));
-
- fixture.detectChanges();
- expect(mockUserService.validateUserLoginState).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('app-user-login'))).toBeTruthy();
- expect(fixture.debugElement.query(By.css('app-user-login-success'))).toBeFalsy();
-
- mockUserService.tryLogin.withArgs('user', 'user').and.returnValue(of(<UserInfo>{
- username: 'user',
- roles: ['user']
- }));
-
- (fixture.debugElement.query(By.css('app-user-login')).componentInstance as
- UserLoginStubComponent).login.emit(<LoginEvent>{
- username: 'user',
- password: 'user'
- });
+ it('success should work well', () => {
+ mockInternalUserService.refreshAndGetUserState.and.returnValue(of(<UserLoginState>'success'));
fixture.detectChanges();
- expect(mockUserService.tryLogin).toHaveBeenCalledWith('user', 'user');
-
- expect(fixture.debugElement.query(By.css('app-user-login'))).toBeFalsy();
- expect(fixture.debugElement.query(By.css('app-user-login-success'))).toBeTruthy();
+ expect(mockInternalUserService.refreshAndGetUserState).toHaveBeenCalled();
+ expect(mockInternalUserService.userRouteNavigate).toHaveBeenCalledWith(['success', { reason: 'already' }]);
});
});
diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
index 7511de16..498ffaa1 100644
--- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
+++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
@@ -1,43 +1,40 @@
-import { Component, OnInit } from '@angular/core';
-import { UserInfo } from '../user-info';
-import { UserService } from '../user-service/user.service';
-import { LoginEvent, LoginMessage } from '../user-login/user-login.component';
+import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
+import { InternalUserService } from '../internal-user-service/internal-user.service';
+import { RouterOutlet, Router, ActivationStart } from '@angular/router';
@Component({
selector: 'app-user-dialog',
templateUrl: './user-dialog.component.html',
styleUrls: ['./user-dialog.component.css']
})
-export class UserDialogComponent implements OnInit {
+export class UserDialogComponent implements OnInit, OnDestroy {
- constructor(private userService: UserService) { }
+ constructor(private userService: InternalUserService, private router: Router) { }
- state: 'loading' | 'login' | 'success' = 'loading';
+ @ViewChild(RouterOutlet) outlet: RouterOutlet;
- loginMessage: LoginMessage;
-
- displayLoginSuccessMessage = false;
- userInfo: UserInfo;
+ isLoading = true;
ngOnInit() {
- this.userService.validateUserLoginState().subscribe(result => {
- if (result.state === 'success') {
- this.userInfo = result.userInfo;
- this.state = 'success';
+ // this is a workaround for a bug. see https://github.com/angular/angular/issues/20694
+ this.router.events.subscribe(e => {
+ if (e instanceof ActivationStart && e.snapshot.outlet === 'user') {
+ this.outlet.deactivate();
+ }
+ });
+
+
+ this.userService.refreshAndGetUserState().subscribe(result => {
+ this.isLoading = false;
+ if (result === 'success') {
+ this.userService.userRouteNavigate(['success', { reason: 'already' }]);
} else {
- this.loginMessage = result.state;
- this.state = 'login';
+ this.userService.userRouteNavigate(['login', { reason: result }]);
}
});
}
- login(event: LoginEvent) {
- this.userService.tryLogin(event.username, event.password).subscribe(result => {
- this.userInfo = result;
- this.displayLoginSuccessMessage = true;
- this.state = 'success';
- }, (error: Error) => {
- this.loginMessage = error.message;
- });
+ ngOnDestroy() {
+ this.userService.userRouteNavigate(null);
}
}