diff options
Diffstat (limited to 'Timeline/ClientApp/src/app/user/user-login')
-rw-r--r-- | Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts | 75 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/user/user-login/user-login.component.ts | 25 |
2 files changed, 81 insertions, 19 deletions
diff --git a/Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts b/Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts index acd13721..9c9ee1dc 100644 --- a/Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts +++ b/Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts @@ -1,17 +1,33 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; +import { ActivatedRoute } from '@angular/router'; -import { UserLoginComponent, LoginEvent } from './user-login.component'; +import { of, throwError } from 'rxjs'; + +import { createMockInternalUserService } from '../internal-user-service/internal-user.service.mock'; +import { MockActivatedRoute } from '../../test-utilities/activated-route.mock'; +import { UserLoginComponent } from './user-login.component'; +import { InternalUserService } from '../internal-user-service/internal-user.service'; +import { UserInfo } from '../entities'; describe('UserLoginComponent', () => { let component: UserLoginComponent; let fixture: ComponentFixture<UserLoginComponent>; + let mockInternalUserService: jasmine.SpyObj<InternalUserService>; + let mockActivatedRoute: MockActivatedRoute; beforeEach(async(() => { + mockInternalUserService = createMockInternalUserService(); + mockActivatedRoute = new MockActivatedRoute(); + TestBed.configureTestingModule({ declarations: [UserLoginComponent], + providers: [ + { provide: InternalUserService, useValue: mockInternalUserService }, + { provide: ActivatedRoute, useValue: mockActivatedRoute } + ], imports: [ReactiveFormsModule], schemas: [NO_ERRORS_SCHEMA] }) @@ -21,14 +37,16 @@ describe('UserLoginComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(UserLoginComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); it('should create', () => { + fixture.detectChanges(); expect(component).toBeTruthy(); }); it('reactive form should work well', () => { + fixture.detectChanges(); + const usernameInput = fixture.debugElement.query(By.css('input[type=text]')).nativeElement as HTMLInputElement; const passwordInput = fixture.debugElement.query(By.css('input[type=password]')).nativeElement as HTMLInputElement; @@ -45,16 +63,57 @@ describe('UserLoginComponent', () => { }); }); - it('login event should work well', fakeAsync(() => { - let userCredential: LoginEvent; - component.login.subscribe((e: LoginEvent) => { userCredential = e; }); + it('login should work well', () => { fixture.detectChanges(); + const mockValue = { username: 'user', password: 'user' }; + + mockInternalUserService.tryLogin.withArgs(mockValue).and.returnValue(of(<UserInfo>{ username: 'user', roles: ['user'] })); + component.form.setValue(mockValue); component.onLoginButtonClick(); - expect(userCredential).toEqual(mockValue); - })); + + expect(mockInternalUserService.tryLogin).toHaveBeenCalledWith(mockValue); + expect(mockInternalUserService.userRouteNavigate).toHaveBeenCalledWith(['success', { reason: 'login' }]); + }); + + describe('message display', () => { + it('nologin reason should display', () => { + mockActivatedRoute.pushSnapshotWithParamMap({ reason: 'nologin' }); + fixture.detectChanges(); + expect(component.message).toBe('nologin'); + expect((fixture.debugElement.query(By.css('p.mat-body')).nativeElement as + HTMLParagraphElement).textContent).toBe('You haven\'t login.'); + }); + + it('invalid login reason should display', () => { + mockActivatedRoute.pushSnapshotWithParamMap({ reason: 'invalidlogin' }); + fixture.detectChanges(); + expect(component.message).toBe('invalidlogin'); + expect((fixture.debugElement.query(By.css('p.mat-body')).nativeElement as + HTMLParagraphElement).textContent).toBe('Your login is no longer valid.'); + }); + + it('custom error message should display', () => { + const customMessage = 'custom message'; + + fixture.detectChanges(); + + const mockValue = { + username: 'user', + password: 'user' + }; + mockInternalUserService.tryLogin.withArgs(mockValue).and.returnValue(throwError(new Error(customMessage))); + component.form.setValue(mockValue); + component.onLoginButtonClick(); + + fixture.detectChanges(); + expect(component.message).toBe(customMessage); + expect((fixture.debugElement.query(By.css('p.mat-body')).nativeElement as + HTMLParagraphElement).textContent).toBe(customMessage); + }); + }); }); diff --git a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts index da642cb8..79a788de 100644 --- a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts +++ b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts @@ -1,32 +1,35 @@ -import { Component, Output, OnInit, EventEmitter, Input } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; + +import { InternalUserService } from '../internal-user-service/internal-user.service'; export type LoginMessage = 'nologin' | 'invalidlogin' | string; -export class LoginEvent { - username: string; - password: string; -} @Component({ selector: 'app-user-login', templateUrl: './user-login.component.html', styleUrls: ['./user-login.component.css'] }) -export class UserLoginComponent { +export class UserLoginComponent implements OnInit { - @Input() - message: LoginMessage; + constructor(private route: ActivatedRoute, private userService: InternalUserService) { } - @Output() - login = new EventEmitter<LoginEvent>(); + message: LoginMessage; form = new FormGroup({ username: new FormControl(''), password: new FormControl('') }); + ngOnInit() { + this.message = this.route.snapshot.paramMap.get('reason'); + } + onLoginButtonClick() { - this.login.emit(this.form.value); + this.userService.tryLogin(this.form.value).subscribe(_ => { + this.userService.userRouteNavigate(['success', { reason: 'login' }]); + }, (error: Error) => this.message = error.message); } } |