Use JS client lib for authentication service

- Fix up, modify and simplify tests

Refs #161
This commit is contained in:
Will Abson
2016-06-07 15:53:41 +01:00
parent fa6d54bad1
commit 0ee3dbe4f0
3 changed files with 100 additions and 53 deletions

View File

@@ -0,0 +1,62 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class AlfrescoApiMock {
static getClientWithTicket(basePath: string, ticket: string) {
return {};
}
}
export module AlfrescoApiMock {
export module Auth {
export class AuthenticationApi {
constructor(alfrescoClient: any) {
}
createTicket(loginRequest: any) {
if (loginRequest.userId === 'fake-username' && loginRequest.password === 'fake-password') {
return new Promise(function (resolve, reject) {
resolve({
userId: 'fake-username',
ticket: 'TICKET_blah'
});
});
} else {
new Promise(function (resolve, reject) {
reject();
});
}
}
deleteTicket(loginRequest: any) {
return new Promise(function (resolve, reject) {
resolve();
});
}
}
export class LoginRequest {
}
}
}

View File

@@ -16,25 +16,20 @@
*/ */
import { it, describe, beforeEach } from 'angular2/testing'; import { it, describe, beforeEach } from 'angular2/testing';
import { provide, Injector } from 'angular2/core'; import { Injector } from 'angular2/core';
import { Http, HTTP_PROVIDERS, XHRBackend, Response, ResponseOptions } from 'angular2/http';
import { MockBackend } from 'angular2/http/testing';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service'; import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoApiMock } from '../assets/AlfrescoApi.mock';
declare var AlfrescoApi: any;
describe('AlfrescoAuthentication', () => { describe('AlfrescoAuthentication', () => {
let injector, let injector,
backend,
mockBackend,
httpService,
service; service;
beforeEach(() => { beforeEach(() => {
injector = Injector.resolveAndCreate([ injector = Injector.resolveAndCreate([
HTTP_PROVIDERS,
MockBackend,
provide(XHRBackend, {useClass: MockBackend}),
AlfrescoAuthenticationService, AlfrescoAuthenticationService,
AlfrescoSettingsService AlfrescoSettingsService
]); ]);
@@ -58,14 +53,12 @@ describe('AlfrescoAuthentication', () => {
return keys[i] || null; return keys[i] || null;
}); });
mockBackend = injector.get(MockBackend); window['AlfrescoApi'] = AlfrescoApiMock;
backend = injector.get(XHRBackend);
httpService = injector.get(Http);
service = injector.get(AlfrescoAuthenticationService); service = injector.get(AlfrescoAuthenticationService);
}); });
it('should return true and token if the user is logged in', () => { it('should return true and token if the user is logged in', () => {
service.saveJwt('fake-local-token'); service.saveToken('fake-local-token');
expect(service.isLoggedIn()).toBe(true); expect(service.isLoggedIn()).toBe(true);
expect(localStorage.getItem('token')).toBeDefined(); expect(localStorage.getItem('token')).toBeDefined();
expect(localStorage.getItem('token')).toEqual('fake-local-token'); expect(localStorage.getItem('token')).toEqual('fake-local-token');
@@ -78,11 +71,8 @@ describe('AlfrescoAuthentication', () => {
}); });
it('should return true and token on sign in', () => { it('should return true and token on sign in', () => {
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(new ResponseOptions({body: {data: {ticket: 'fake-post-token'}}})));
});
service.token = ''; service.token = '';
service.login('POST', 'fakeUser', 'fakePassword') service.login('fake-username', 'fake-password')
.subscribe(() => { .subscribe(() => {
expect(service.isLoggedIn()).toBe(true); expect(service.isLoggedIn()).toBe(true);
expect(service.token).toEqual('fake-post-token'); expect(service.token).toEqual('fake-post-token');
@@ -104,16 +94,4 @@ describe('AlfrescoAuthentication', () => {
); );
}); });
it('should return no error if method value is GET', () => {
expect(service.login('GET', 'fakeUser', 'fakePassword').hasErrored).toBe(false);
});
it('should return no error if method value is POST', () => {
expect(service.login('POST', 'fakeUser', 'fakePassword').hasErrored).toBe(false);
});
it('should throw an exception if method value is different from GET or POST', () => {
expect(service.login('PUT', 'fakeUser', 'fakePassword').error).toEqual('Invalid method name the value should be GET or POST');
});
}); });

View File

@@ -20,6 +20,8 @@ import { Observable } from 'rxjs/Rx';
import { Http, Headers, Response } from 'angular2/http'; import { Http, Headers, Response } from 'angular2/http';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service'; import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
declare let AlfrescoApi: any;
/** /**
* The AlfrescoAuthenticationService provide the login service and store the token in the localStorage * The AlfrescoAuthenticationService provide the login service and store the token in the localStorage
*/ */
@@ -30,15 +32,19 @@ export class AlfrescoAuthenticationService {
/** /**
* Constructor * Constructor
* @param http * @param alfrescoSettingsService
*/ */
constructor(public http: Http, private alfrescoSettingsService: AlfrescoSettingsService) { constructor(private alfrescoSettingsService: AlfrescoSettingsService) {
} }
getBaseUrl(): string { getBaseUrl(): string {
return this.alfrescoSettingsService.host + this._authUrl; return this.alfrescoSettingsService.host + this._authUrl;
} }
private getAlfrescoClient() {
return AlfrescoApi.getClientWithTicket(this.getBaseUrl(), this.getToken());
}
/** /**
* The method return tru if the user is logged in * The method return tru if the user is logged in
* @returns {boolean} * @returns {boolean}
@@ -58,49 +64,50 @@ export class AlfrescoAuthenticationService {
} }
/** /**
* The method provide the login with POST Request * Perform a login on behalf of the user and store the ticket returned
*
* @param username * @param username
* @param password * @param password
* @returns {Observable<R>|Observable<T>} * @returns {Observable<R>|Observable<T>}
*/ */
loginPost(username: string, password: string) { loginPost(username: string, password: string) {
let credentials = '{ "userId": "' + username + '", "password": "' + password + '" }'; return Observable.fromPromise(this.getCreateTicketPromise(username, password))
.map(res => <any> res)
let headers = new Headers(); .do(response => {
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
return this.http.post(this.getBaseUrl() + '/tickets', credentials, {
headers: headers
})
.map((res: any) => {
let response = res.json();
this.saveToken(response.entry.id); this.saveToken(response.entry.id);
return this.getToken(); return this.getToken();
}) })
.catch(this.handleError); .catch(this.handleError);
} }
getCreateTicketPromise(username: string, password: string) {
let apiInstance = new AlfrescoApi.Auth.AuthenticationApi(this.getAlfrescoClient());
let loginRequest = new AlfrescoApi.Auth.LoginRequest();
loginRequest.userId = username;
loginRequest.password = password;
return apiInstance.createTicket(loginRequest);
}
/** /**
* Delete the current login ticket from the server * Delete the current login ticket from the server
* *
* @returns {Observable<R>|Observable<T>} * @returns {Observable<R>|Observable<T>}
*/ */
loginDelete() { loginDelete() {
let headers = new Headers(); return Observable.fromPromise(this.getDeleteTicketPromise())
headers.append('Content-Type', 'application/json'); .map(res => <any> res)
headers.append('Authorization', 'Basic ' + btoa(this.getToken())); .do(response => {
return this.http.delete(this.getBaseUrl() + '/tickets/-me-', {
headers: headers
})
.map((res: any) => {
this.removeToken(); this.removeToken();
this.saveToken(''); this.saveToken('');
}) })
.catch(this.handleError); .catch(this.handleError);
} }
getDeleteTicketPromise() {
let apiInstance = new AlfrescoApi.Auth.AuthenticationApi(this.getAlfrescoClient());
return apiInstance.deleteTicket();
}
/** /**
* Return the token stored in the localStorage * Return the token stored in the localStorage
* @param token * @param token
@@ -141,6 +148,6 @@ export class AlfrescoAuthenticationService {
*/ */
private handleError(error: Response) { private handleError(error: Response) {
console.error('Error when logging in', error); console.error('Error when logging in', error);
return Observable.throw(error.json().message || 'Server error'); return Observable.throw(error || 'Server error');
} }
} }