diff --git a/bower.json b/bower.json index 646c879..3df1a86 100644 --- a/bower.json +++ b/bower.json @@ -1,23 +1,24 @@ { - "name": "ng-jwt-auth", - "version": "0.0.0", - "description": "Angular JSON Web Token Authentication Module", - "main": "dist/ngHttpProgress.js", - "dependencies": { - "lodash": "~3.9.3", - "moment": "~2.10.3", - "angular": "~1.4.1", - "ngprogress": "1.0.7" - }, - "devDependencies": { - "angular-mocks": "~1.4.1" - }, - "resolutions": { - "angular": "~1.4.1" - }, - "ignore": [ - "**/.*", - "typings", - "test" - ] + "name": "angular-http-progress", + "version": "0.0.0", + "description": "Wrapper for https://github.com/victorbjelkholm/ngprogress - automatically handles http progress with interceptor", + "main": "dist/ngHttpProgress.js", + "dependencies": { + "lodash": "~3.9.3", + "moment": "~2.10.3", + "angular": "~1.4.1", + "ngprogress": "1.0.7" + }, + "devDependencies": { + "angular-mocks": "~1.4.1", + "jquery": "~2.1.4" + }, + "resolutions": { + "angular": "~1.4.1" + }, + "ignore": [ + "**/.*", + "typings", + "test" + ] } diff --git a/dist/ngHttpProgress.d.ts b/dist/ngHttpProgress.d.ts index ee2a3c8..efa371c 100644 --- a/dist/ngHttpProgress.d.ts +++ b/dist/ngHttpProgress.d.ts @@ -1,13 +1,25 @@ +/// /// /// declare module NgHttpProgress { + interface ngProgress { + start(): void; + height(cssHeight: string): void; + color(cssColor: string): void; + status(): number; + stop(): void; + set(percentage: number): void; + reset(): void; + complete(): void; + getDomElement(): Element; + } interface INgHttpProgressService { - start(): boolean; - stop(): boolean; - complete(): boolean; - reset(): boolean; + start(): ng.IPromise; + stop(): ng.IPromise; + complete(): ng.IPromise; + rewind(): ng.IPromise; status(): number; - set(): boolean; + set(percentage: number): void; } interface IngHttpProgressServiceProvider { configure(config: INgHttpProgressServiceConfig): NgHttpProgressServiceProvider; @@ -28,7 +40,7 @@ declare module NgHttpProgress { * @param _$injector */ static $inject: string[]; - constructor(_$q: ng.IQService, _$injector: ng.auto.IInjectorService); + constructor($q: ng.IQService, $injector: ng.auto.IInjectorService); private getNgHttpProgressService; request: (config: any) => any; response: (response: any) => any; @@ -38,25 +50,78 @@ declare module NgHttpProgress { declare module NgHttpProgress { class NgHttpProgressService implements INgHttpProgressService { private config; - private $http; private $q; - private $window; - private $interval; + private $timeout; + private ngProgress; + private currentProgressDeferred; + private progressPromise; + static ngProgressFinishTime: number; + private pendingDelays; + private stopped; /** * Construct the service with dependencies injected - * @param _config - * @param _$http - * @param _$q - * @param _$window - * @param _$interval + * @param config + * @param $q + * @param $timeout + * @param ngProgress + */ + constructor(config: INgHttpProgressServiceConfig, $q: ng.IQService, $timeout: ng.ITimeoutService, ngProgress: ngProgress); + /** + * Start the progress bar running + * @returns {any} + */ + start(): ng.IPromise; + /** + * Bump back the current status to less completed + * @returns {number} + */ + private bumpBack(); + /** + * Halt the progress bar + * @returns {IPromise} + */ + stop(): ng.IPromise; + /** + * Complete the progress + * @returns {IPromise} + */ + complete(): ng.IPromise; + /** + * Reset the progress bar to zero + * @returns {IPromise} + */ + rewind(): ng.IPromise; + /** + * Get the status of the progress bar + * @returns {number} */ - constructor(_config: INgHttpProgressServiceConfig, _$http: ng.IHttpService, _$q: ng.IQService, _$window: ng.IWindowService, _$interval: ng.IIntervalService); - start(): boolean; - stop(): boolean; - complete(): boolean; - reset(): boolean; status(): number; - set(): boolean; + progressStatus(): ng.IPromise; + /** + * Set the status of the progress bar + * @param percentage + */ + set(percentage: number): ng.IPromise; + /** + * Finish the progress of the promise + * @returns {IPromise} + */ + private finish(); + /** + * Handle the reset. Immediately invoke as the ngProgress service executes immediately + * @returns {IPromise} + */ + private reset(); + /** + * Handle the stopping. + * @returns {IPromise} + */ + private halt(); + /** + * Intialise the progress deferred promise + * @returns {IPromise} + */ + private initProgressMeter(); } } declare module NgHttpProgress { @@ -83,6 +148,6 @@ declare module NgHttpProgress { * @returns {NgHttpProgress.NgHttpProgressServiceProvider} */ configure(config: INgHttpProgressServiceConfig): NgHttpProgressServiceProvider; - $get: (string | (($http: any, $q: any, $window: any, $interval: any) => NgHttpProgressService))[]; + $get: (string | (($q: any, $timeout: any, ngProgress: any) => NgHttpProgressService))[]; } } diff --git a/dist/ngHttpProgress.js b/dist/ngHttpProgress.js index 25a9011..a06f80a 100644 --- a/dist/ngHttpProgress.js +++ b/dist/ngHttpProgress.js @@ -1,34 +1,34 @@ -/// -/// +/// +/// /// var NgHttpProgress; (function (NgHttpProgress) { var NgHttpProgressInterceptor = (function () { - function NgHttpProgressInterceptor(_$q, _$injector) { + function NgHttpProgressInterceptor($q, $injector) { var _this = this; + this.$q = $q; + this.$injector = $injector; this.getNgHttpProgressService = function () { if (_this.ngHttpProgressService == null) { - _this.ngHttpProgressService = _this.$injector.get('ngHttpProgressService'); + _this.ngHttpProgressService = _this.$injector.get('ngHttpProgress'); } return _this.ngHttpProgressService; }; this.request = function (config) { - var ngHttpProgressService = _this.getNgHttpProgressService(); - //@todo start progress bar + var progress = _this.getNgHttpProgressService(); + progress.start(); return config; }; this.response = function (response) { - var ngHttpProgressService = _this.getNgHttpProgressService(); - //@todo advance progress bar to end + var progress = _this.getNgHttpProgressService(); + progress.complete(); return response; }; this.responseError = function (response) { - var ngHttpProgressService = _this.getNgHttpProgressService(); - //@todo rewind progress bar + var progress = _this.getNgHttpProgressService(); + progress.rewind(); return response; }; - this.$q = _$q; - this.$injector = _$injector; } /** * Construct the service with dependencies injected @@ -48,37 +48,168 @@ var NgHttpProgress; var NgHttpProgressService = (function () { /** * Construct the service with dependencies injected - * @param _config - * @param _$http - * @param _$q - * @param _$window - * @param _$interval + * @param config + * @param $q + * @param $timeout + * @param ngProgress */ - function NgHttpProgressService(_config, _$http, _$q, _$window, _$interval) { - this.config = _config; - this.$http = _$http; - this.$q = _$q; - this.$window = _$window; - this.$interval = _$interval; + function NgHttpProgressService(config, $q, $timeout, ngProgress) { + this.config = config; + this.$q = $q; + this.$timeout = $timeout; + this.ngProgress = ngProgress; + this.pendingDelays = 0; + this.stopped = false; + this.ngProgress.color(this.config.color); + this.ngProgress.height(this.config.height); } + /** + * Start the progress bar running + * @returns {any} + */ NgHttpProgressService.prototype.start = function () { - return undefined; + this.pendingDelays++; + if (this.currentProgressDeferred) { + if (this.stopped) { + this.stopped = false; + this.currentProgressDeferred.notify('start'); + } + else { + this.currentProgressDeferred.notify('bumpback'); + } + return this.progressPromise; + } + return this.initProgressMeter(); + }; + /** + * Bump back the current status to less completed + * @returns {number} + */ + NgHttpProgressService.prototype.bumpBack = function () { + var currentProgress = this.status(), fallBackTo = currentProgress - currentProgress * (currentProgress / 120); + this.set(fallBackTo); + return this.progressPromise; }; + /** + * Halt the progress bar + * @returns {IPromise} + */ NgHttpProgressService.prototype.stop = function () { - return undefined; + this.currentProgressDeferred.notify('stop'); + return this.progressPromise; }; + /** + * Complete the progress + * @returns {IPromise} + */ NgHttpProgressService.prototype.complete = function () { - return undefined; + this.pendingDelays--; + if (this.pendingDelays === 0) { + this.currentProgressDeferred.resolve(); + } + return this.progressPromise; }; - NgHttpProgressService.prototype.reset = function () { - return undefined; + /** + * Reset the progress bar to zero + * @returns {IPromise} + */ + NgHttpProgressService.prototype.rewind = function () { + this.currentProgressDeferred.reject(); + return this.progressPromise; }; + /** + * Get the status of the progress bar + * @returns {number} + */ NgHttpProgressService.prototype.status = function () { - return undefined; + return this.ngProgress.status(); + }; + NgHttpProgressService.prototype.progressStatus = function () { + return this.progressPromise; }; - NgHttpProgressService.prototype.set = function () { - return undefined; + /** + * Set the status of the progress bar + * @param percentage + */ + NgHttpProgressService.prototype.set = function (percentage) { + var _this = this; + this.$timeout(function () { + _this.ngProgress.set(percentage); + }); + return this.progressPromise; + }; + /** + * Finish the progress of the promise + * @returns {IPromise} + */ + NgHttpProgressService.prototype.finish = function () { + var _this = this; + var finishStatus = this.status(); + this.$timeout(function () { + _this.ngProgress.complete(); + }); + return this.$timeout(function () { + return finishStatus; + }, NgHttpProgressService.ngProgressFinishTime); + }; + /** + * Handle the reset. Immediately invoke as the ngProgress service executes immediately + * @returns {IPromise} + */ + NgHttpProgressService.prototype.reset = function () { + var _this = this; + return this.$timeout(function () { + var finishStatus = _this.status(); + _this.ngProgress.reset(); + return finishStatus; + }); + }; + /** + * Handle the stopping. + * @returns {IPromise} + */ + NgHttpProgressService.prototype.halt = function () { + var _this = this; + this.stopped = true; + return this.$timeout(function () { + var currentStatus = _this.status(); + _this.ngProgress.stop(); + return currentStatus; + }); + }; + /** + * Intialise the progress deferred promise + * @returns {IPromise} + */ + NgHttpProgressService.prototype.initProgressMeter = function () { + var _this = this; + this.currentProgressDeferred = this.$q.defer(); + this.ngProgress.start(); + return this.progressPromise = this.currentProgressDeferred.promise + .then(function () { + return _this.finish(); + }, function () { + return _this.reset(); + }, function (action) { + switch (action) { + case 'start': + _this.ngProgress.start(); + break; + case 'stop': + _this.halt(); + break; + case 'bumpback': + _this.bumpBack(); + break; + } + }) + .finally(function () { + _this.currentProgressDeferred = null; //clear the current progress + _this.progressPromise = null; //clear the current progress + _this.pendingDelays = 0; //reset + }); }; + NgHttpProgressService.ngProgressFinishTime = 1600; //time for finish to complete return NgHttpProgressService; })(); NgHttpProgress.NgHttpProgressService = NgHttpProgressService; @@ -116,8 +247,8 @@ var NgHttpProgress; * Initialise the service provider */ function NgHttpProgressServiceProvider() { - this.$get = ['$http', '$q', '$window', '$interval', function ngHttpProgressServiceFactory($http, $q, $window, $interval) { - return new NgHttpProgress.NgHttpProgressService(this.config, $http, $q, $window, $interval); + this.$get = ['$q', '$timeout', 'ngProgress', function ngHttpProgressServiceFactory($q, $timeout, ngProgress) { + return new NgHttpProgress.NgHttpProgressService(this.config, $q, $timeout, ngProgress); }]; //initialise service config this.config = { @@ -131,13 +262,17 @@ var NgHttpProgress; * @returns {NgHttpProgress.NgHttpProgressServiceProvider} */ NgHttpProgressServiceProvider.prototype.configure = function (config) { + var mismatchedConfig = _.xor(_.keys(config), _.keys(this.config)); + if (mismatchedConfig.length > 0) { + throw new NgHttpProgressException("Invalid properties [" + mismatchedConfig.join(',') + "] passed to config)"); + } this.config = _.defaults(config, this.config); return this; }; return NgHttpProgressServiceProvider; })(); NgHttpProgress.NgHttpProgressServiceProvider = NgHttpProgressServiceProvider; - angular.module('ngHttpProgress', []) + angular.module('ngHttpProgress', ['ngProgress']) .provider('ngHttpProgress', NgHttpProgressServiceProvider) .service('ngHttpProgressInterceptor', NgHttpProgress.NgHttpProgressInterceptor) .config(['$httpProvider', '$injector', function ($httpProvider) { diff --git a/dist/ngHttpProgress.js.map b/dist/ngHttpProgress.js.map index 7d8a882..f7913c5 100644 --- a/dist/ngHttpProgress.js.map +++ b/dist/ngHttpProgress.js.map @@ -1 +1 @@ -{"version":3,"file":"ngHttpProgress.js","sourceRoot":"/Users/zak/sites/spira/angular-http-progress/src/","sources":["ngHttpProgressInterfaces.ts","ngHttpProgressInterceptor.ts","ngHttpProgressService.ts","ngHttpProgressServiceProvider.ts"],"names":["NgHttpProgress","NgHttpProgress.NgHttpProgressInterceptor","NgHttpProgress.NgHttpProgressInterceptor.constructor","NgHttpProgress.NgHttpProgressService","NgHttpProgress.NgHttpProgressService.constructor","NgHttpProgress.NgHttpProgressService.start","NgHttpProgress.NgHttpProgressService.stop","NgHttpProgress.NgHttpProgressService.complete","NgHttpProgress.NgHttpProgressService.reset","NgHttpProgress.NgHttpProgressService.status","NgHttpProgress.NgHttpProgressService.set","NgHttpProgress.NgHttpProgressException","NgHttpProgress.NgHttpProgressException.constructor","NgHttpProgress.NgHttpProgressException.toString","NgHttpProgress.NgHttpProgressServiceProvider","NgHttpProgress.NgHttpProgressServiceProvider.constructor","NgHttpProgress.NgHttpProgressServiceProvider.constructor.ngHttpProgressServiceFactory","NgHttpProgress.NgHttpProgressServiceProvider.configure"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"ngHttpProgress.js","sourceRoot":"/Users/zak/sites/spira/angular-http-progress/src/","sources":["ngHttpProgressInterfaces.ts","ngHttpProgressInterceptor.ts","ngHttpProgressService.ts","ngHttpProgressServiceProvider.ts"],"names":["NgHttpProgress","NgHttpProgress.NgHttpProgressInterceptor","NgHttpProgress.NgHttpProgressInterceptor.constructor","NgHttpProgress.NgHttpProgressService","NgHttpProgress.NgHttpProgressService.constructor","NgHttpProgress.NgHttpProgressService.start","NgHttpProgress.NgHttpProgressService.bumpBack","NgHttpProgress.NgHttpProgressService.stop","NgHttpProgress.NgHttpProgressService.complete","NgHttpProgress.NgHttpProgressService.rewind","NgHttpProgress.NgHttpProgressService.status","NgHttpProgress.NgHttpProgressService.progressStatus","NgHttpProgress.NgHttpProgressService.set","NgHttpProgress.NgHttpProgressService.finish","NgHttpProgress.NgHttpProgressService.reset","NgHttpProgress.NgHttpProgressService.halt","NgHttpProgress.NgHttpProgressService.initProgressMeter","NgHttpProgress.NgHttpProgressException","NgHttpProgress.NgHttpProgressException.constructor","NgHttpProgress.NgHttpProgressException.toString","NgHttpProgress.NgHttpProgressServiceProvider","NgHttpProgress.NgHttpProgressServiceProvider.constructor","NgHttpProgress.NgHttpProgressServiceProvider.constructor.ngHttpProgressServiceFactory","NgHttpProgress.NgHttpProgressServiceProvider.configure"],"mappings":"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"} \ No newline at end of file diff --git a/src/ngHttpProgressInterceptor.ts b/src/ngHttpProgressInterceptor.ts index 3b7c2ce..d36f1dd 100644 --- a/src/ngHttpProgressInterceptor.ts +++ b/src/ngHttpProgressInterceptor.ts @@ -1,14 +1,10 @@ -/// -/// +/// /// module NgHttpProgress { export class NgHttpProgressInterceptor { - //list injected dependencies - private $q: ng.IQService; - private $injector: ng.auto.IInjectorService; private ngHttpProgressService: NgHttpProgressService; @@ -18,39 +14,40 @@ module NgHttpProgress { * @param _$injector */ static $inject = ['$q', '$injector']; - constructor(_$q: ng.IQService, _$injector: ng.auto.IInjectorService) { + constructor( + private $q: ng.IQService, + private $injector: ng.auto.IInjectorService) { - this.$q = _$q; - this.$injector = _$injector; } private getNgHttpProgressService = (): NgHttpProgressService=> { if (this.ngHttpProgressService == null) { - this.ngHttpProgressService = this.$injector.get('ngHttpProgressService'); + this.ngHttpProgressService = this.$injector.get('ngHttpProgress'); } return this.ngHttpProgressService; }; public request = (config):any => { - let ngHttpProgressService = this.getNgHttpProgressService(); - //@todo start progress bar + let progress = this.getNgHttpProgressService(); + + progress.start(); return config; }; public response = (response):any => { - let ngHttpProgressService = this.getNgHttpProgressService(); - //@todo advance progress bar to end + let progress = this.getNgHttpProgressService(); + progress.complete(); return response; }; public responseError = (response):any => { - let ngHttpProgressService = this.getNgHttpProgressService(); - //@todo rewind progress bar + let progress = this.getNgHttpProgressService(); + progress.rewind(); return response; }; diff --git a/src/ngHttpProgressInterfaces.ts b/src/ngHttpProgressInterfaces.ts index 01d2850..9613858 100644 --- a/src/ngHttpProgressInterfaces.ts +++ b/src/ngHttpProgressInterfaces.ts @@ -1,12 +1,26 @@ +/// + module NgHttpProgress { + export interface ngProgress { + start():void; + height(cssHeight:string):void + color(cssColor:string):void + status():number; + stop():void; + set(percentage:number):void; + reset():void; + complete():void; + getDomElement():Element; + } + export interface INgHttpProgressService { - start(): boolean; - stop(): boolean; - complete(): boolean; - reset(): boolean; + start(): ng.IPromise; + stop(): ng.IPromise; + complete(): ng.IPromise; + rewind(): ng.IPromise; status(): number; - set(): boolean; + set(percentage:number):void; } export interface IngHttpProgressServiceProvider { diff --git a/src/ngHttpProgressService.ts b/src/ngHttpProgressService.ts index 345937f..18342c1 100644 --- a/src/ngHttpProgressService.ts +++ b/src/ngHttpProgressService.ts @@ -6,55 +6,211 @@ module NgHttpProgress { export class NgHttpProgressService implements INgHttpProgressService { - //list injected dependencies - private config: INgHttpProgressServiceConfig; - private $http: ng.IHttpService; - private $q: ng.IQService; - private $window: ng.IWindowService; - private $interval:ng.IIntervalService; + private currentProgressDeferred:ng.IDeferred; + private progressPromise:ng.IPromise; + static ngProgressFinishTime = 1600; //time for finish to complete + + private pendingDelays = 0; + + private stopped:boolean = false; /** * Construct the service with dependencies injected - * @param _config - * @param _$http - * @param _$q - * @param _$window - * @param _$interval + * @param config + * @param $q + * @param $timeout + * @param ngProgress */ - constructor(_config:INgHttpProgressServiceConfig, _$http: ng.IHttpService, _$q: ng.IQService, _$window: ng.IWindowService, _$interval: ng.IIntervalService) { + constructor( + private config:INgHttpProgressServiceConfig, + private $q: ng.IQService, + private $timeout: ng.ITimeoutService, + private ngProgress: ngProgress + ) { - this.config = _config; - this.$http = _$http; - this.$q = _$q; - this.$window = _$window; - this.$interval = _$interval; + this.ngProgress.color(this.config.color); + this.ngProgress.height(this.config.height); } - start():boolean { - return undefined; + /** + * Start the progress bar running + * @returns {any} + */ + public start():ng.IPromise { + + this.pendingDelays ++; + + if (this.currentProgressDeferred){ //exists + + if (this.stopped){ + this.stopped = false; + this.currentProgressDeferred.notify('start'); + }else{ + this.currentProgressDeferred.notify('bumpback'); + } + + return this.progressPromise; + } + + + return this.initProgressMeter(); } - stop():boolean { - return undefined; + + /** + * Bump back the current status to less completed + * @returns {number} + */ + private bumpBack():ng.IPromise { + + let currentProgress = this.status(), + fallBackTo = currentProgress - currentProgress * (currentProgress/120); + + this.set(fallBackTo); + return this.progressPromise; } - complete():boolean { - return undefined; + /** + * Halt the progress bar + * @returns {IPromise} + */ + public stop():ng.IPromise { + this.currentProgressDeferred.notify('stop'); + return this.progressPromise; } - reset():boolean { - return undefined; + /** + * Complete the progress + * @returns {IPromise} + */ + public complete():ng.IPromise { + + this.pendingDelays --; + if (this.pendingDelays === 0){ //no more delays remaining + this.currentProgressDeferred.resolve(); + } + + return this.progressPromise; } - status():number { - return undefined; + /** + * Reset the progress bar to zero + * @returns {IPromise} + */ + public rewind():ng.IPromise { + this.currentProgressDeferred.reject(); + return this.progressPromise; } - set():boolean { - return undefined; + /** + * Get the status of the progress bar + * @returns {number} + */ + public status():number { + return this.ngProgress.status(); + } + + public progressStatus():ng.IPromise { + return this.progressPromise; } + /** + * Set the status of the progress bar + * @param percentage + */ + public set(percentage:number):ng.IPromise { + + this.$timeout(() => { //immediately invoke timeout in case a $digest cycle is busy + this.ngProgress.set(percentage); + }); + + return this.progressPromise; + } + + /** + * Finish the progress of the promise + * @returns {IPromise} + */ + private finish():ng.IPromise { + let finishStatus = this.status(); + + this.$timeout(() => { //wrap in $timeout to allow $digest to have a cycle + this.ngProgress.complete(); + }); + + return this.$timeout(() => { //wait for the animation to finish before setting status + return finishStatus; + }, NgHttpProgressService.ngProgressFinishTime); + } + + /** + * Handle the reset. Immediately invoke as the ngProgress service executes immediately + * @returns {IPromise} + */ + private reset():ng.IPromise { + + return this.$timeout(() => { //wrap in $timeout to allow $digest to have a cycle + let finishStatus = this.status(); + this.ngProgress.reset(); + return finishStatus; + }); + + } + + /** + * Handle the stopping. + * @returns {IPromise} + */ + private halt():ng.IPromise { + + this.stopped = true; + + return this.$timeout(() => { //wrap in $timeout to allow $digest to have a cycle + let currentStatus = this.status(); + this.ngProgress.stop(); + return currentStatus; + }); + + } + + /** + * Intialise the progress deferred promise + * @returns {IPromise} + */ + private initProgressMeter():ng.IPromise { + + this.currentProgressDeferred = this.$q.defer(); + + this.ngProgress.start(); + + return this.progressPromise = this.currentProgressDeferred.promise + .then(() => { //success + return this.finish(); + }, () => { //error + return this.reset(); + }, (action:string) => { //notify + + switch(action){ + case 'start': + this.ngProgress.start(); + break; + case 'stop': + this.halt(); + break; + case 'bumpback': + this.bumpBack(); + break; + } + + }) + .finally(() => { + this.currentProgressDeferred = null; //clear the current progress + this.progressPromise = null; //clear the current progress + this.pendingDelays = 0; //reset + }); + + } } } diff --git a/src/ngHttpProgressServiceProvider.ts b/src/ngHttpProgressServiceProvider.ts index 5cba6d3..f3d35e5 100644 --- a/src/ngHttpProgressServiceProvider.ts +++ b/src/ngHttpProgressServiceProvider.ts @@ -49,19 +49,25 @@ module NgHttpProgress { * @returns {NgHttpProgress.NgHttpProgressServiceProvider} */ public configure(config:INgHttpProgressServiceConfig) : NgHttpProgressServiceProvider { + + let mismatchedConfig = _.xor(_.keys(config), _.keys(this.config)); + if (mismatchedConfig.length > 0){ + throw new NgHttpProgressException("Invalid properties ["+mismatchedConfig.join(',')+"] passed to config)"); + } + this.config = _.defaults(config, this.config); return this; } - public $get = ['$http', '$q', '$window', '$interval', function ngHttpProgressServiceFactory($http, $q, $window, $interval) { - return new NgHttpProgressService(this.config, $http, $q, $window, $interval); + public $get = ['$q', '$timeout', 'ngProgress', function ngHttpProgressServiceFactory($q, $timeout, ngProgress) { + return new NgHttpProgressService(this.config, $q, $timeout, ngProgress); }]; } - angular.module('ngHttpProgress', []) + angular.module('ngHttpProgress', ['ngProgress']) .provider('ngHttpProgress', NgHttpProgressServiceProvider) .service('ngHttpProgressInterceptor', NgHttpProgressInterceptor) .config(['$httpProvider', '$injector', ($httpProvider:ng.IHttpProvider) => { diff --git a/test/test.ts b/test/test.ts index a11ccff..863864d 100644 --- a/test/test.ts +++ b/test/test.ts @@ -7,28 +7,99 @@ let expect = chai.expect; let fixtures = { - get foo(){ - return 'bar'; + get customConfig():NgHttpProgress.INgHttpProgressServiceConfig{ + return { + color: 'rgb(255, 0, 255)', + height: '2px' + }; }, }; +let $http:ng.IHttpService; +let $q:ng.IQService; +let $interval:ng.IIntervalService; +let $timeout:ng.ITimeoutService; +let clock:Sinon.SinonFakeTimers = sinon.useFakeTimers(); + +//we need to both tick setInterval and $interval as for some reason ngProgress uses both +let tickTime = (seconds) => { + + let millis = seconds * 1000; + + clock.tick(millis); + $interval.flush(millis); + $timeout.flush(millis); + +}; + + + +describe('Custom configuration', function () { + + let ngHttpProgressProvider:NgHttpProgress.NgHttpProgressServiceProvider; + let customProgressService:NgHttpProgress.NgHttpProgressService; + + beforeEach(() => { + + module('ngHttpProgress', (_ngHttpProgressProvider_) => { + ngHttpProgressProvider = _ngHttpProgressProvider_; //register injection of service provider + + ngHttpProgressProvider.configure(fixtures.customConfig); + + }); + + }); + + it('should throw an exception when invalid configuration is passed', () => { + + let testInvalidConfigurationFn = () => { + ngHttpProgressProvider.configure({invalid:'config'}); + }; + + expect(testInvalidConfigurationFn).to.throw(NgHttpProgress.NgHttpProgressException); + + }); + + beforeEach(()=>{ + inject((_ngHttpProgress_) => { + customProgressService = _ngHttpProgress_; + }) + }); + + it('should have the configured color and height', function() { + + let element:Element = (customProgressService).ngProgress.getDomElement(), + styledElement = jQuery(element).find('#ngProgress') + ; + expect(styledElement.css('backgroundColor')).to.equal(fixtures.customConfig.color); + expect(styledElement.css('height')).to.equal(fixtures.customConfig.height); + }); + + +}); describe('Service tests', () => { let $httpBackend:ng.IHttpBackendService; let ngHttpProgressService:NgHttpProgress.NgHttpProgressService; + beforeEach(()=>{ module('ngHttpProgress'); - inject((_$httpBackend_, _ngHttpProgress_) => { + inject((_$httpBackend_, _ngHttpProgress_, _$http_, _$q_, _$interval_, _$timeout_) => { - if (!ngHttpProgressService){ //dont rebind, so each test gets the singleton + if (!ngHttpProgressService){ $httpBackend = _$httpBackend_; - ngHttpProgressService = _ngHttpProgress_; //register injected of service provider + ngHttpProgressService = _ngHttpProgress_; //register injected service provider + $http = _$http_; + $q = _$q_; + $interval = _$interval_; + $timeout = _$timeout_; } + }); }); @@ -48,4 +119,148 @@ describe('Service tests', () => { }); + describe('direct api call', () => { + + it('should start the progress bar when called directly', () => { + + let completionPromise = ngHttpProgressService.start(); + + expect(completionPromise).eventually.to.be.within(0, 100); + + tickTime(2); //fast forward intervals by 2 seconds + + expect(ngHttpProgressService.status()).to.be.greaterThan(0); + + }); + + it('should complete the progress bar when called', function(done) { + + expect(ngHttpProgressService.status()).to.be.greaterThan(0); + + let completionPromise = ngHttpProgressService.complete(); + + expect(completionPromise).eventually.to.be.greaterThan(0); //status when the progress bar was completed + + completionPromise.then(() => { + expect(ngHttpProgressService.status()).to.equal(100); + done(); + }); + + tickTime(2); //fast forward intervals by 2 seconds + + }); + + it.skip('should stop the progress bar when called', function(done){ + + ngHttpProgressService.start(); + + tickTime(0.5); //fast forward intervals by 2 seconds + + ngHttpProgressService.stop(); + + tickTime(0.5); //let more time elapse + + expect((ngHttpProgressService).stopped).to.be.true; + + ngHttpProgressService.start(); //restart + + tickTime(0.5); //let more time elapse + + let completionPromise = ngHttpProgressService.complete(); //resume and finish + + tickTime(2); //let more time elapse + + completionPromise.then(() => { + expect(ngHttpProgressService.status()).to.equal(100); + done(); + }); + + tickTime(2); //fast forward intervals by 2 seconds + + }); + + }); + + describe('$http interceptor', () => { + + + it('should start the progress bar when an $http request starts', (done) => { + + $httpBackend.expectGET('/any').respond('foobar'); + + expect((ngHttpProgressService).progressPromise).not.to.be.ok; + + $http.get('/any'); + tickTime(2); //wait for the request to get to the interceptor + + let progressPromise = ngHttpProgressService.progressStatus(); + + expect(progressPromise).to.be.ok; + expect(progressPromise.then).to.be.instanceOf(Function); + + $httpBackend.flush(); + + expect(progressPromise).eventually.to.be.greaterThan(0); + + progressPromise.then(() => { + expect(ngHttpProgressService.status()).to.equal(0); + done(); + }); + + tickTime(2); //flush the timeouts + + }); + + it('should rewind the progress bar when an $http request fails', (done) => { + + $httpBackend.expectGET('/any').respond(500, 'foobar'); + + $http.get('/any'); + tickTime(2); //wait for the request to get to the interceptor + + let progressPromise = ngHttpProgressService.progressStatus(); + + $httpBackend.flush(); + + expect(progressPromise).eventually.to.be.fulfilled; + expect(progressPromise).eventually.to.be.greaterThan(0); + + progressPromise.then(() => { + expect(ngHttpProgressService.status()).to.equal(0); + done(); + }); + + tickTime(2); //flush the timeouts + + }); + + + it('should be able to handle multiple http requests', (done) => { + + $httpBackend.whenGET('/any').respond('foobar'); + + $http.get('/any'); + tickTime(0.5); //delay dispatching the next request + $http.get('/any'); + tickTime(0.5); //delay dispatching the next request + $http.get('/any'); + tickTime(0.5); //delay dispatching the next request + + let progressPromise = ngHttpProgressService.progressStatus(); + + expect(progressPromise).eventually.to.be.greaterThan(0); + + $httpBackend.flush(); + + progressPromise.then(() => { + done(); + }); + + tickTime(2); //flush the completion timeout + + }) + + }); + + });