Skip to content

Commit

Permalink
Split tests across files, various style fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
zakhenry committed Apr 6, 2016
1 parent 2a9209c commit 83978c5
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 257 deletions.
1 change: 1 addition & 0 deletions src/declarations.d.ts
@@ -0,0 +1 @@
declare function require(string: string): string;
106 changes: 106 additions & 0 deletions src/fixtures.spec.ts
@@ -0,0 +1,106 @@
import {Chance} from "chance";
import * as _ from "lodash";
import * as moment from "moment";
import {IJwtToken, IUser} from "./ngJwtAuthInterfaces";

let seededChance:Chance.Chance = new Chance(1);
export const fixtures = {
user: {
_self: '/users/1',
userId: 1,
email: 'joe.bloggs@example.com',
firstName: seededChance.first(),
lastName: seededChance.last(),
password: 'password',
phone: seededChance.phone()
},

get userResponse():IUser{
return <IUser>_.omit(fixtures.user, 'password');
},

get authBasic():string{
return 'Basic '+btoa(fixtures.user.email+':'+fixtures.user.password)
},

buildToken: (overrides = {}) => {
let defaultConfig = {
header: {
alg: 'RS256',
typ: 'JWT'
},
data: {
iss: 'api.spira.io',
aud: 'spira.io',
sub: fixtures.user.userId,
iat: Number(moment().format('X')),
exp: Number(moment().add(1, 'hours').format('X')),
jti: 'random-hash',
'#user': fixtures.userResponse,
},
signature: 'this-is-the-signed-hash'
};

let token:IJwtToken = <any>_.merge(defaultConfig, overrides);

return btoa(JSON.stringify(token.data))
+ '.' + btoa(JSON.stringify(token.data))
+ '.' + token.signature
;
},

get token(){

return fixtures.buildToken(); //no customisations
}
};


export function locationFactoryMock(hostname:string) {
return () => {

return {
host: function () {
return hostname;
}
};
};
}

export function cookiesFactoryMock(allowDomain:string) {

let cookieStore = {};

return () => {

return {
/* If you need more then $location.host(), add more methods */
put: (key, value, conf) => {

if (conf.domain && conf.domain !== allowDomain || value.split('.')[2] == 'always-fail-domain'){
return false;
}

cookieStore[key] = {
value: value,
conf: conf
};
},

get: (key) => {
if (!cookieStore[key]){
return undefined;
}
return cookieStore[key].value;
},

getObject: (key) => {
return cookieStore[key];
},

remove: (key) => {
delete cookieStore[key];
}
};
};
};
4 changes: 2 additions & 2 deletions src/index.ts
Expand Up @@ -2,8 +2,8 @@ import "angular";
import "angular-cookies";
import "angular-utf8-base64";

import {NgJwtAuthServiceProvider} from "./ngJwtAuthServiceProvider";
import {NgJwtAuthInterceptor} from "./ngJwtAuthInterceptor";
import {NgJwtAuthServiceProvider} from "./provider/ngJwtAuthServiceProvider";
import {NgJwtAuthInterceptor} from "./interceptor/ngJwtAuthInterceptor";

angular.module('ngJwtAuth', ['utf8-base64', 'ngCookies'])
.provider('ngJwtAuthService', NgJwtAuthServiceProvider)
Expand Down
@@ -1,11 +1,10 @@
import {NgJwtAuthService} from "../service/ngJwtAuthService";


import {NgJwtAuthService} from "./ngJwtAuthService";
export const authorizationUpdateHeader:string = 'Authorization-Update';

export class NgJwtAuthInterceptor {

//list injected dependencies
private $http:ng.IHttpService;
private $q:ng.IQService;
private $injector:ng.auto.IInjectorService;
private ngJwtAuthService:NgJwtAuthService;
Expand All @@ -15,8 +14,7 @@ export class NgJwtAuthInterceptor {
* @param _$q
* @param _$injector
*/
static $inject = ['$q', '$injector'];

static $inject:string[] = ['$q', '$injector'];
constructor(_$q:ng.IQService, _$injector:ng.auto.IInjectorService) {

this.$q = _$q;
Expand All @@ -32,7 +30,7 @@ export class NgJwtAuthInterceptor {

public response = (response:ng.IHttpPromiseCallbackArg<any>):ng.IHttpPromiseCallbackArg<any> => {

let updateHeader = response.headers('Authorization-Update');
let updateHeader = response.headers(authorizationUpdateHeader);

if (updateHeader) {

Expand Down
105 changes: 105 additions & 0 deletions src/provider/ngJwtAuthServiceProvider.spec.ts
@@ -0,0 +1,105 @@
import {NgJwtAuthServiceProvider, NgJwtAuthException} from "./ngJwtAuthServiceProvider";
import {NgJwtAuthService} from "../service/ngJwtAuthService";
import {INgJwtAuthServiceConfig} from "../ngJwtAuthInterfaces";

import "angular";
import "angular-mocks";
import "../index" //@todo double check this is right

let expect:Chai.ExpectStatic = chai.expect;

let defaultAuthServiceProvider:NgJwtAuthServiceProvider;

describe('Default configuration', function () {

let defaultAuthService:NgJwtAuthService;

beforeEach(() => {

angular.mock.module('ngJwtAuth', (_ngJwtAuthServiceProvider_) => {
defaultAuthServiceProvider = _ngJwtAuthServiceProvider_; //register injection of service provider
});

});

it('should have the default endpoints', () => {
expect((<any>defaultAuthServiceProvider).config.apiEndpoints.base).to.equal('/api/auth');
expect((<any>defaultAuthServiceProvider).config.apiEndpoints.login).to.equal('/login');
expect((<any>defaultAuthServiceProvider).config.apiEndpoints.refresh).to.equal('/refresh');
});

beforeEach(()=>{
inject(function(_ngJwtAuthService_){
defaultAuthService = _ngJwtAuthService_;
})
});

it('should have the default login endpoint', function() {
expect((<any>defaultAuthService).getLoginEndpoint()).to.equal('/api/auth/login');
});

it('should have the default token exchange endpoint', function() {
expect((<any>defaultAuthService).getTokenExchangeEndpoint()).to.equal('/api/auth/token');
});

it('should have the default refresh endpoint', function() {
expect((<any>defaultAuthService).getRefreshEndpoint()).to.equal('/api/auth/refresh');
});

});

describe('Custom configuration', function () {

let authServiceProvider:NgJwtAuthServiceProvider;
let customAuthService:NgJwtAuthService;
let partialCustomConfig:INgJwtAuthServiceConfig = {
tokenLocation: 'token-custom',
tokenUser: '#user-custom',
apiEndpoints: {
base: '/api/auth-custom',
login: '/login-custom',
tokenExchange: '/token-custom',
refresh: '/refresh-custom',
},
//storageKeyName: 'NgJwtAuthToken-custom', //intentionally commented out as this will be tested to be the default
};

beforeEach(() => {

angular.mock.module('ngJwtAuth', (_ngJwtAuthServiceProvider_) => {
authServiceProvider = _ngJwtAuthServiceProvider_; //register injection of service provider

authServiceProvider.configure(partialCustomConfig);
});

});

it('should throw an exception when invalid configuration is passed', () => {

let testInvalidConfigurationFn = () => {
authServiceProvider.configure(<any>{invalid:'config'});
};

expect(testInvalidConfigurationFn).to.throw(NgJwtAuthException);

});

it('should be able to partially configure the service provider', () => {

expect((<any>authServiceProvider).config.apiEndpoints).to.deep.equal(partialCustomConfig.apiEndpoints); //assert that the custom value has come across

expect((<any>authServiceProvider).config.storageKeyName).to.deep.equal((<any>authServiceProvider).config.storageKeyName); //assert that the default was not overridden

});

beforeEach(()=>{
inject((_ngJwtAuthService_) => {
customAuthService = _ngJwtAuthService_;
})
});

it('should have the configured login endpoint', function() {
expect((<any>customAuthService).getLoginEndpoint()).to.equal('/api/auth-custom/login-custom');
});

});
@@ -1,33 +1,36 @@

import {INgJwtAuthServiceConfig, IEndpointDefinition} from "./ngJwtAuthInterfaces";
import {NgJwtAuthService} from "./ngJwtAuthService";
import {INgJwtAuthServiceConfig, IEndpointDefinition} from "../ngJwtAuthInterfaces";
import {NgJwtAuthService} from "../service/ngJwtAuthService";

export declare class Error {
public name: string;
public message: string;
public stack: string;
constructor(message?: string);
public name:string;
public message:string;
public stack:string;

constructor(message?:string);
}

export class NgJwtAuthException extends Error {

constructor(public message: string) {
constructor(public message:string) {
super(message);
this.name = 'NgJwtAuthException';
this.message = message;
this.stack = (<any>new Error()).stack;
}

toString() {
return this.name + ': ' + this.message;
}
}

export class NgJwtAuthTokenExpiredException extends NgJwtAuthException{}
export class NgJwtAuthCredentialsFailedException extends NgJwtAuthException{}
export class NgJwtAuthTokenExpiredException extends NgJwtAuthException {
}
export class NgJwtAuthCredentialsFailedException extends NgJwtAuthException {
}

export class NgJwtAuthServiceProvider implements ng.IServiceProvider {

private config: INgJwtAuthServiceConfig;
private config:INgJwtAuthServiceConfig;

/**
* Initialise the service provider
Expand Down Expand Up @@ -60,13 +63,13 @@ export class NgJwtAuthServiceProvider implements ng.IServiceProvider {
/**
* Set the configuration
* @param config
* @returns {NgJwtAuth.NgJwtAuthServiceProvider}
* @returns {NgJwtAuthServiceProvider}
*/
public configure(config:IEndpointDefinition) : NgJwtAuthServiceProvider {
public configure(config:IEndpointDefinition):NgJwtAuthServiceProvider {

let mismatchedConfig = _.difference(_.keys(config), _.keys(this.config));
if (mismatchedConfig.length > 0){
throw new NgJwtAuthException("Invalid properties ["+mismatchedConfig.join(',')+"] passed to config)");
if (mismatchedConfig.length > 0) {
throw new NgJwtAuthException("Invalid properties [" + mismatchedConfig.join(',') + "] passed to config)");
}

this.config = _.defaultsDeep(config, this.config);
Expand Down

0 comments on commit 83978c5

Please sign in to comment.