Added tests

This commit is contained in:
Giuseppe Digilio
2018-05-17 11:05:26 +02:00
parent 240e1ee0af
commit f66dd32658
4 changed files with 161 additions and 43 deletions

View File

@@ -1,7 +1,12 @@
import { cold, hot } from 'jasmine-marbles';
import { Observable } from 'rxjs/Observable';
import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { Store } from '@ngrx/store';
import { cold, hot } from 'jasmine-marbles';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of'
import { AuthEffects } from './auth.effects';
import {
AuthActionTypes,
@@ -20,25 +25,27 @@ import { AuthTokenInfo } from './models/auth-token-info.model';
import { AuthServiceStub } from '../../shared/testing/auth-service-stub';
import { AuthService } from './auth.service';
import { TruncatablesState } from '../../shared/truncatable/truncatable.reducer';
import { Store } from '@ngrx/store';
import { EpersonMock } from '../../shared/testing/eperson-mock';
describe('AuthEffects', () => {
let authEffects: AuthEffects;
let actions: Observable<any>;
const authServiceStub = new AuthServiceStub();
const store: Store<TruncatablesState> = jasmine.createSpyObj('store', {
/* tslint:disable:no-empty */
dispatch: {},
/* tslint:enable:no-empty */
select: Observable.of(true)
});
const token = new AuthTokenInfo('token_test');
const token = authServiceStub.getToken();
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
AuthEffects,
{provide: AuthService, useClass: AuthServiceStub},
{provide: AuthService, useValue: authServiceStub},
{provide: Store, useValue: store},
provideMockActions(() => actions),
// other providers
@@ -58,7 +65,8 @@ describe('AuthEffects', () => {
}
});
const expected = cold('--b-', {b: new AuthenticationSuccessAction(new AuthTokenInfo('token_test'))});
const expected = cold('--b-', {b: new AuthenticationSuccessAction(token)});
expect(authEffects.authenticate$).toBeObservable(expected);
});
@@ -87,7 +95,7 @@ describe('AuthEffects', () => {
it('should return a AUTHENTICATED action in response to a AUTHENTICATE_SUCCESS action', () => {
actions = hot('--a-', {a: {type: AuthActionTypes.AUTHENTICATE_SUCCESS, payload: token}});
const expected = cold('--b-', {b: new AuthenticatedAction(new AuthTokenInfo('token_test'))});
const expected = cold('--b-', {b: new AuthenticatedAction(token)});
expect(authEffects.authenticateSuccess$).toBeObservable(expected);
});
@@ -125,7 +133,7 @@ describe('AuthEffects', () => {
actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN}});
const expected = cold('--b-', {b: new AuthenticatedAction(new AuthTokenInfo('token_test'))});
const expected = cold('--b-', {b: new AuthenticatedAction(token)});
expect(authEffects.checkToken$).toBeObservable(expected);
});
@@ -151,7 +159,7 @@ describe('AuthEffects', () => {
actions = hot('--a-', {a: {type: AuthActionTypes.REFRESH_TOKEN}});
const expected = cold('--b-', {b: new RefreshTokenSuccessAction(new AuthTokenInfo('token_test'))});
const expected = cold('--b-', {b: new RefreshTokenSuccessAction(token)});
expect(authEffects.refreshToken$).toBeObservable(expected);
});

View File

@@ -0,0 +1,98 @@
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController, } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { AuthInterceptor } from './auth.interceptor';
import { AuthService } from './auth.service';
import { DSpaceRESTv2Service } from '../dspace-rest-v2/dspace-rest-v2.service';
import { RestRequestMethod } from '../data/request.models';
import { RouterStub } from '../../shared/testing/router-stub';
import { TruncatablesState } from '../../shared/truncatable/truncatable.reducer';
import { AuthServiceStub } from '../../shared/testing/auth-service-stub';
describe(`AuthInterceptor`, () => {
let service: DSpaceRESTv2Service;
let httpMock: HttpTestingController;
const authServiceStub = new AuthServiceStub();
const store: Store<TruncatablesState> = jasmine.createSpyObj('store', {
/* tslint:disable:no-empty */
dispatch: {},
/* tslint:enable:no-empty */
select: Observable.of(true)
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
DSpaceRESTv2Service,
{provide: AuthService, useValue: authServiceStub},
{provide: Router, useClass: RouterStub},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},
{provide: Store, useValue: store},
],
});
service = TestBed.get(DSpaceRESTv2Service);
httpMock = TestBed.get(HttpTestingController);
});
describe('when has a valid token', () => {
it('should not add an Authorization header when were sending a HTTP request to \'authn\' endpoint', () => {
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/authn/login', 'password=password&user=user').subscribe((response) => {
expect(response).toBeTruthy();
});
const httpRequest = httpMock.expectOne(`dspace-spring-rest/api/authn/login`);
const token = httpRequest.request.headers.get('authorization');
expect(token).toBeNull();
});
it('should add an Authorization header when were sending a HTTP request to \'authn\' endpoint', () => {
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'test').subscribe((response) => {
expect(response).toBeTruthy();
});
const httpRequest = httpMock.expectOne(`dspace-spring-rest/api/submission/workspaceitems`);
expect(httpRequest.request.headers.has('authorization'));
const token = httpRequest.request.headers.get('authorization');
expect(token).toBe('Bearer token_test');
});
});
describe('when has an expired token', () => {
beforeEach(() => {
authServiceStub.setTokenAsExpired();
});
afterEach(() => {
authServiceStub.setTokenAsNotExpired();
});
it('should redirect to login', () => {
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user').subscribe((response) => {
expect(response).toBeTruthy();
});
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user');
httpMock.expectNone('dspace-spring-rest/api/submission/workspaceitems');
});
})
});

View File

@@ -4,39 +4,10 @@ import { AuthStatus } from '../../core/auth/models/auth-status.model';
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
import { Eperson } from '../../core/eperson/models/eperson.model';
import { isNotEmpty } from '../empty.util';
import { EpersonMock } from './eperson-mock';
export class AuthRequestServiceStub {
protected mockUser: Eperson = Object.assign(new Eperson(), {
id: 'test',
uuid: 'test',
name: 'User Test',
handle: 'test',
metadata: [
{
key: 'eperson.firstname',
value: 'User',
language: null,
authority: null,
confidence: 0
},
{
key: 'eperson.lastname',
value: 'Test',
language: null,
authority: null,
confidence: 0
}
],
groups: [],
netid: 'test',
lastActive: '',
canLogIn: true,
email: 'test@test.com',
requireCertificate: true,
selfRegistered: false,
self: {},
type: 'eperson'
});
protected mockUser: Eperson = EpersonMock;
protected mockTokenInfo = new AuthTokenInfo('test_token');
public postToEndpoint(method: string, body: any, options?: HttpOptions): Observable<any> {

View File

@@ -6,12 +6,19 @@ import { Eperson } from '../../core/eperson/models/eperson.model';
export class AuthServiceStub {
token: AuthTokenInfo = new AuthTokenInfo('token_test');
private _tokenExpired = false;
constructor() {
this.token.expires = Date.now() + (1000 * 60 * 60);
}
public authenticate(user: string, password: string): Observable<AuthStatus> {
if (user === 'user' && password === 'password') {
const authStatus = new AuthStatus();
authStatus.okay = true;
authStatus.authenticated = true;
authStatus.token = new AuthTokenInfo('token_test');
authStatus.token = this.token;
authStatus.eperson = [EpersonMock];
return Observable.of(authStatus);
} else {
@@ -28,16 +35,46 @@ export class AuthServiceStub {
}
}
public buildAuthHeader(token?: AuthTokenInfo): string {
return `Bearer ${token.accessToken}`;
}
public getToken(): AuthTokenInfo {
return this.token;
}
public hasValidAuthenticationToken(): Observable<AuthTokenInfo> {
return Observable.of(new AuthTokenInfo('token_test'));
return Observable.of(this.token);
}
public logout(): Observable<boolean> {
return Observable.of(true);
}
public isTokenExpired(token?: AuthTokenInfo): boolean {
return this._tokenExpired;
}
/**
* This method is used to ease testing
*/
public setTokenAsExpired() {
this._tokenExpired = true
}
/**
* This method is used to ease testing
*/
public setTokenAsNotExpired() {
this._tokenExpired = false
}
public isTokenExpiring(): Observable<boolean> {
return Observable.of(false);
}
public refreshAuthenticationToken(token: AuthTokenInfo): Observable<AuthTokenInfo> {
return Observable.of(new AuthTokenInfo('token_test'));
return Observable.of(this.token);
}
public redirectToPreviousUrl() {
@@ -48,6 +85,10 @@ export class AuthServiceStub {
return;
}
setRedirectUrl(url: string) {
return;
}
public storeToken(token: AuthTokenInfo) {
return;
}