Skip to content

Instantly share code, notes, and snippets.

@er-ant
Created August 1, 2018 17:33
Show Gist options
  • Save er-ant/009589338479328bb5c0af9cddf02b5b to your computer and use it in GitHub Desktop.
Save er-ant/009589338479328bb5c0af9cddf02b5b to your computer and use it in GitHub Desktop.
Code examples: test for auth service.
import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule, HttpErrorResponse } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from '@angular/common/http/testing';
import { Observable } from 'rxjs/Observable';
import { IUser, IAuthData, HttpRequestOptions } from '../models/auth-models';
import { SIGN_IN_DATA_MOCK, USER_DATA_MOCK, AUTH_HEADERS_MOCK, PROCESSED_AUTH_HEADERS_MOCK } from '../models/auth-data-stub';
import { AuthService } from './auth.service';
describe('Auth Module: Auth Service', () => {
let authService: AuthService;
let backendMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
HttpClientTestingModule
],
providers: [AuthService]
});
});
beforeEach(inject([AuthService, HttpTestingController], (service: AuthService, backend: HttpTestingController) => {
authService = service;
backendMock = backend;
}));
afterEach(inject([HttpTestingController], (backend: HttpTestingController) => {
backend.verify();
authService.currentAuthData = undefined;
authService.currentUserData = undefined;
}));
describe('setter method', () => {
it('currentAuthData should set authentication data and local storage', () => {
authService.currentAuthData = <IAuthData>AUTH_HEADERS_MOCK;
expect(localStorage.getItem('accessToken')).toBe(AUTH_HEADERS_MOCK.accessToken);
expect(localStorage.getItem('client')).toBe(AUTH_HEADERS_MOCK.client);
expect(localStorage.getItem('expiry')).toBe(AUTH_HEADERS_MOCK.expiry);
expect(localStorage.getItem('tokenType')).toBe(AUTH_HEADERS_MOCK.tokenType);
expect(localStorage.getItem('uid')).toBe(AUTH_HEADERS_MOCK.uid);
expect(authService['_currentAuthData']).toEqual(AUTH_HEADERS_MOCK);
});
it('currentAuthData should clear authentication data and local storage, if wrong data or nothing was assigned', () => {
authService.currentAuthData = <IAuthData>{};
expect(localStorage.getItem('accessToken')).toBe(null);
expect(localStorage.getItem('client')).toBe(null);
expect(localStorage.getItem('expiry')).toBe(null);
expect(localStorage.getItem('tokenType')).toBe(null);
expect(localStorage.getItem('uid')).toBe(null);
expect(authService['_currentAuthData']).not.toBeDefined();
});
it('currentUserData should set user data', () => {
authService.currentUserData = <IUser>USER_DATA_MOCK;
expect(authService['_currentUserData']).toEqual(USER_DATA_MOCK);
});
});
describe('getter method', () => {
it('currentAuthData should return authentication data', () => {
authService['_currentAuthData'] = <IAuthData>AUTH_HEADERS_MOCK;
expect(authService.currentAuthData).toEqual(AUTH_HEADERS_MOCK);
});
it('currentUserData should return user data', () => {
authService['_currentUserData'] = <IUser>USER_DATA_MOCK;
expect(authService.currentUserData).toEqual(USER_DATA_MOCK);
});
it('currentAuthHeadersObject should return an object with authentication data', () => {
authService['_currentAuthData'] = <IAuthData>AUTH_HEADERS_MOCK;
expect(authService.currentAuthHeadersObject).toEqual(PROCESSED_AUTH_HEADERS_MOCK);
});
it('currentAuthHeadersObject should return an empty object if current authentication data was not setted', () => {
expect(authService.currentAuthHeadersObject).toEqual({});
});
});
describe('localstorage method', () => {
let store = {};
beforeEach(() => {
spyOn(localStorage, 'getItem').and.callFake(key => {
return store[key];
});
spyOn(localStorage, 'setItem').and.callFake((key, value) => {
store[key] = value + '';
});
spyOn(localStorage, 'removeItem').and.callFake(key => {
delete store[key];
});
});
afterEach(() => {
store = {};
});
it('localStorageGetAuthData should return an array with auth data from localstorage', () => {
Object.assign(store, AUTH_HEADERS_MOCK);
expect(authService['localStorageGetAuthData']()).toEqual(AUTH_HEADERS_MOCK);
});
it('localStorageSetAuthData should set an array with auth data to localstorage', () => {
authService['localStorageSetAuthData'](AUTH_HEADERS_MOCK);
expect(store).toEqual(AUTH_HEADERS_MOCK);
});
it('localStorageResetAuthData should clear auth data from localstorage', () => {
Object.assign(store, AUTH_HEADERS_MOCK);
authService['localStorageResetAuthData']();
expect(store).toEqual({});
});
it('getSetAuthDataFromStorage should set auth headers from localstorage if it is relevant', () => {
Object.assign(store, AUTH_HEADERS_MOCK);
authService['getSetAuthDataFromStorage']();
expect(authService.currentAuthData).toEqual(AUTH_HEADERS_MOCK);
});
it('getSetAuthDataFromStorage should not set auth headers from localstorage if it is not relevant', () => {
Object.assign(store, <IAuthData>{});
authService['getSetAuthDataFromStorage']();
expect(authService.currentAuthData).toBeUndefined();
});
});
it('method mergeRequestOptionsArgs should merge options for http request and return them.', () => {
const predefinedOptions: HttpRequestOptions = <HttpRequestOptions>{url: 'testurl'};
const newOptions: HttpRequestOptions = <HttpRequestOptions>{observe: 'response'};
expect(authService['mergeRequestOptionsArgs'](predefinedOptions, newOptions)).toEqual({url: 'testurl', observe: 'response'});
});
it('method signedIn returns true if user is logged in', () => {
authService.currentAuthData = AUTH_HEADERS_MOCK;
expect(authService.signedIn()).toBeTruthy();
});
it('method signedIn returns false if user is logged out', () => {
expect(authService.signedIn()).toBeFalsy();
});
describe('request', () => {
describe('signIn', () => {
it('should log in user and set user\'s data if request was successful', () => {
authService.signIn(SIGN_IN_DATA_MOCK).subscribe(
success => {
expect(success).toEqual(USER_DATA_MOCK);
expect(authService.currentUserData).toEqual(USER_DATA_MOCK);
},
err => fail('expected user data, not error')
);
backendMock.expectOne('api/auth/sign_in').flush({data: USER_DATA_MOCK}, { status: 200, statusText: 'Ok' });
});
it('should not log in user if request has failed', () => {
const errorResponse = new HttpErrorResponse({
error: ['Invalid login credentials. Please try again.'],
status: 401,
statusText: 'Unauthorized'
});
authService.signIn(SIGN_IN_DATA_MOCK).subscribe(
success => fail('expected an error, not user data'),
err => {
expect(err).toBeDefined();
expect(authService.currentUserData).toBeUndefined();
}
);
backendMock.expectOne('api/auth/sign_in').flush({errors: ['Invalid login credentials. Please try again.']}, errorResponse);
});
});
describe('signOut', () => {
it('should log out user and reset user\'s, auth data and localStorage if request was successful', () => {
authService.signOut().subscribe(
success => {
expect(authService.currentAuthData).toBeUndefined();
expect(authService.currentUserData).toBeUndefined();
},
err => fail('expected sign out')
);
backendMock.expectOne('api/auth/sign_out').flush({}, { status: 200, statusText: 'Ok' });
});
it('should not log out user if request has failed', () => {
const errorResponse = new HttpErrorResponse({
error: ['Invalid login credentials. Please try again.'],
status: 401,
statusText: 'Unauthorized'
});
authService.signOut().subscribe(
success => fail('expected an error'),
err => {
expect(err).toBeDefined();
expect(authService.currentUserData).toBeUndefined();
}
);
backendMock.expectOne('api/auth/sign_out').flush({errors: ['Invalid login credentials. Please try again.']}, errorResponse);
});
});
describe('validateToken', () => {
it('should validate user\'s token and set user\'s data if request was successful', () => {
authService.validateToken().subscribe(
success => {
expect(success).toBeTruthy();
expect(authService.currentUserData).toEqual(USER_DATA_MOCK);
},
err => fail('expected user data, not error')
);
backendMock.expectOne('api/auth/validate_token').flush({data: USER_DATA_MOCK}, { status: 200, statusText: 'Ok' });
});
it('should throw an error if request has failed', () => {
const errorResponse = new HttpErrorResponse({
error: ['Invalid login credentials. Please try again.'],
status: 401,
statusText: 'Unauthorized'
});
authService.validateToken().subscribe(
success => fail('expected an error, not user data'),
err => {
expect(err).toBeDefined();
expect(authService.currentUserData).toBeUndefined();
}
);
backendMock.expectOne('api/auth/validate_token').flush({errors: ['Invalid login credentials. Please try again.']}, errorResponse);
});
});
});
it('method checkAuthDataRelevance should return false if new authData is not defined', () => {
expect(authService.checkAuthDataRelevance(<IAuthData>{})).toBeFalsy();
});
it('method checkAuthDataRelevance should return true if new authData is defined and currentAuthData is not defined', () => {
expect(authService.checkAuthDataRelevance(AUTH_HEADERS_MOCK)).toBeTruthy();
});
it('method checkAuthDataRelevance should compare expiry of new authData and currentAuthData and return result', () => {
const expiredHeaders = Object.assign({}, AUTH_HEADERS_MOCK);
const newHeaders = Object.assign({}, AUTH_HEADERS_MOCK);
authService.currentAuthData = AUTH_HEADERS_MOCK;
expect(authService.checkAuthDataRelevance(AUTH_HEADERS_MOCK)).toBeTruthy();
expiredHeaders.expiry = (+expiredHeaders.expiry) - 2 + '';
expect(authService.checkAuthDataRelevance(expiredHeaders)).toBeFalsy();
newHeaders.expiry = (+newHeaders.expiry) + 2 + '';
expect(authService.checkAuthDataRelevance(newHeaders)).toBeTruthy();
});
describe('http wrapper: ', () => {
it('base method request should return observable with template for http request', () => {
expect(authService.request('get', <HttpRequestOptions>{url: 'test'})).toEqual(jasmine.any(Observable));
});
it('post should send post request with correct body', () => {
let requestMock: TestRequest;
authService.post('api/test', {testBody: 1}).subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('POST');
expect(requestMock.request.body).toEqual({testBody: 1});
});
it('get should send get request', () => {
let requestMock: TestRequest;
authService.get('api/test').subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('GET');
});
it('put should send put request with correct body', () => {
let requestMock: TestRequest;
authService.put('api/test', {testBody: 1}).subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('PUT');
expect(requestMock.request.body).toEqual({testBody: 1});
});
it('patch should send patch request with correct body', () => {
let requestMock: TestRequest;
authService.patch('api/test', {testBody: 1}).subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('PATCH');
expect(requestMock.request.body).toEqual({testBody: 1});
});
it('delete should send delete request', () => {
let requestMock: TestRequest;
authService.delete('api/test').subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('DELETE');
});
it('head should send head request', () => {
let requestMock: TestRequest;
authService.head('api/test').subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('HEAD');
});
it('options should send options request', () => {
let requestMock: TestRequest;
authService.options('api/test').subscribe();
requestMock = backendMock.expectOne('api/test');
expect(requestMock.request.method).toEqual('OPTIONS');
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment