aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/user/user-login
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-03-11 19:52:29 +0800
committerGitHub <noreply@github.com>2019-03-11 19:52:29 +0800
commit8caef17dd3e455de27f44d13751c27ee4dfe2e1e (patch)
tree5b485ad438c9be9c180d425453588ff1c575a42d /Timeline/ClientApp/src/app/user/user-login
parent17d90077b289c6b2203a34de727dd77c1985f146 (diff)
parentb26342764046d188d223aa494c3bbbf76deb4927 (diff)
downloadtimeline-8caef17dd3e455de27f44d13751c27ee4dfe2e1e.tar.gz
timeline-8caef17dd3e455de27f44d13751c27ee4dfe2e1e.tar.bz2
timeline-8caef17dd3e455de27f44d13751c27ee4dfe2e1e.zip
Merge pull request #11 from crupest/7-user-route
Use named route in user dialog.
Diffstat (limited to 'Timeline/ClientApp/src/app/user/user-login')
-rw-r--r--Timeline/ClientApp/src/app/user/user-login/user-login.component.spec.ts75
-rw-r--r--Timeline/ClientApp/src/app/user/user-login/user-login.component.ts25
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);
}
}