Created
August 1, 2018 17:33
-
-
Save er-ant/009589338479328bb5c0af9cddf02b5b to your computer and use it in GitHub Desktop.
Code examples: test for auth service.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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