1- /*! Angular API Mock v0.1.5
1+ /*! Angular API Mock v0.1.6
22 * Licensed with MIT
33 * Made with ♥ from Seriema + Redhorn */
44/* Create the main module, `apiMock`. It's the one that needs to be included in
@@ -39,47 +39,16 @@ angular.module('apiMock', []).config([
3939 */
4040 // Helper objects
4141 //
42- var mockDataPath = '/mock_data' ;
43- var apiPath = '/api' ;
4442 var $location ;
43+ var $log ;
4544 var $q ;
45+ var config = {
46+ mockDataPath : '/mock_data' ,
47+ apiPath : '/api'
48+ } ;
4649 var fallbacks = [ ] ;
4750 // Helper methods
4851 //
49- function httpStatusResponse ( status ) {
50- var response = {
51- status : status ,
52- headers : {
53- 'Content-Type' : 'text/html; charset=utf-8' ,
54- 'Server' : 'Angular ApiMock'
55- }
56- } ;
57- return $q . reject ( response ) ;
58- }
59- function getParameter ( req ) {
60- var mockValue = localMock ( req ) ;
61- if ( mockValue === undefined ) {
62- mockValue = globalMock ( ) ;
63- }
64- return mockValue ;
65- }
66- function reroute ( req ) {
67- if ( ! isApiPath ( req . url ) ) {
68- return req ;
69- }
70- // replace apiPath with mockDataPath.
71- var path = req . url . substring ( config . apiPath . length ) ;
72- req . url = config . mockDataPath + path ;
73- // strip query strings (like ?search=banana).
74- var regex = / [ a - z A - z 0 - 9 / . \- ] * / ;
75- req . url = regex . exec ( req . url ) [ 0 ] ;
76- // add file endings (method verb and .json).
77- if ( req . url [ req . url . length - 1 ] === '/' ) {
78- req . url = req . url . slice ( 0 , - 1 ) ;
79- }
80- req . url += '.' + req . method . toLowerCase ( ) + '.json' ;
81- return req ;
82- }
8352 function detectParameter ( keys ) {
8453 var regex = / a p i m o c k / i;
8554 var result ;
@@ -93,24 +62,28 @@ angular.module('apiMock', []).config([
9362 function localMock ( req ) {
9463 return detectParameter ( req ) ;
9564 }
96- function globalMock ( ) {
97- return detectParameter ( $location . search ( ) ) ;
65+ function getParameter ( req ) {
66+ var mockValue = localMock ( req ) ;
67+ if ( mockValue === undefined ) {
68+ mockValue = globalMock ( ) ;
69+ }
70+ return mockValue ;
9871 }
9972 function getCommand ( mockValue ) {
10073 switch ( typeof mockValue ) {
10174 case 'number' :
102- if ( mockValue !== 0 ) {
75+ if ( mockValue !== 0 && ! isNaN ( mockValue ) ) {
10376 return {
10477 type : 'respond' ,
10578 value : mockValue
10679 } ;
10780 }
10881 break ;
10982 case 'string' :
110- if ( mockValue . toLowerCase ( ) === 'auto' ) {
83+ switch ( mockValue . toLowerCase ( ) ) {
84+ case 'auto' :
11185 return { type : 'recover' } ;
112- }
113- if ( mockValue . toLowerCase ( ) === 'true' ) {
86+ case 'true' :
11487 return { type : 'reroute' } ;
11588 }
11689 break ;
@@ -122,12 +95,29 @@ angular.module('apiMock', []).config([
12295 }
12396 return { type : 'ignore' } ;
12497 }
125- var prepareFallback = function ( req ) {
98+ function globalMock ( ) {
99+ return detectParameter ( $location . search ( ) ) ;
100+ }
101+ function httpStatusResponse ( status ) {
102+ var response = {
103+ status : status ,
104+ headers : {
105+ 'Content-Type' : 'text/html; charset=utf-8' ,
106+ 'Server' : 'Angular ApiMock'
107+ }
108+ } ;
109+ $log . info ( 'apiMock: mocking HTTP status to ' + status ) ;
110+ return $q . reject ( response ) ;
111+ }
112+ function isApiPath ( url ) {
113+ return url . indexOf ( config . apiPath ) === 0 ;
114+ }
115+ function prepareFallback ( req ) {
126116 if ( isApiPath ( req . url ) ) {
127117 fallbacks . push ( req ) ;
128118 }
129- } ;
130- var removeFallback = function ( res ) {
119+ }
120+ function removeFallback ( res ) {
131121 var found = false ;
132122 angular . forEach ( fallbacks , function ( fallback , index ) {
133123 if ( fallback . method === res . method && fallback . url === res . url ) {
@@ -136,16 +126,34 @@ angular.module('apiMock', []).config([
136126 }
137127 } ) ;
138128 return found ;
139- } ;
140- var isApiPath = function ( url ) {
141- return url . indexOf ( config . apiPath ) === 0 ;
142- } ;
143- function ApiMock ( _$location , _$q ) {
144- $location = _$location ;
145- $q = _$q ;
129+ }
130+ function reroute ( req ) {
131+ if ( ! isApiPath ( req . url ) ) {
132+ return req ;
133+ }
134+ // replace apiPath with mockDataPath.
135+ var oldPath = req . url ;
136+ var newPath = req . url . substring ( config . apiPath . length ) ;
137+ newPath = config . mockDataPath + newPath ;
138+ // strip query strings (like ?search=banana).
139+ var regex = / [ a - z A - z 0 - 9 / . \- ] * / ;
140+ newPath = regex . exec ( newPath ) [ 0 ] ;
141+ // add file endings (method verb and .json).
142+ if ( newPath [ newPath . length - 1 ] === '/' ) {
143+ newPath = newPath . slice ( 0 , - 1 ) ;
144+ }
145+ newPath += '.' + req . method . toLowerCase ( ) + '.json' ;
146+ req . url = newPath ;
147+ $log . info ( 'apiMock: rerouting ' + oldPath + ' to ' + newPath ) ;
148+ return req ;
146149 }
147150 // Expose public interface for provider instance
148151 //
152+ function ApiMock ( _$location , _$log , _$q ) {
153+ $location = _$location ;
154+ $log = _$log ;
155+ $q = _$q ;
156+ }
149157 var p = ApiMock . prototype ;
150158 p . _countFallbacks = function ( ) {
151159 return fallbacks . length ;
@@ -177,30 +185,29 @@ angular.module('apiMock', []).config([
177185 return false ;
178186 }
179187 if ( removeFallback ( rej . config ) ) {
188+ $log . info ( 'apiMock: recovering from failure at ' + rej . config . url ) ;
180189 return reroute ( rej . config ) ;
181190 }
182191 return false ;
183192 } ;
184- var config = {
185- mockDataPath : mockDataPath ,
186- apiPath : apiPath
187- } ;
188193 // Expose Provider interface
189194 //
190195 this . config = function ( options ) {
191196 angular . extend ( config , options ) ;
192197 } ;
193198 this . $get = [
194199 '$location' ,
200+ '$log' ,
195201 '$q' ,
196- function ( $location , $q ) {
197- return new ApiMock ( $location , $q ) ;
202+ function ( $location , $log , $ q) {
203+ return new ApiMock ( $location , $log , $ q) ;
198204 }
199205 ] ;
200206} ) . service ( 'httpInterceptor' , [
207+ '$injector' ,
201208 '$q' ,
202209 'apiMock' ,
203- function ( $q , apiMock ) {
210+ function ( $injector , $ q, apiMock ) {
204211 /* The main service. Is jacked in as a interceptor on `$http` so it gets called
205212 * on every http call. This allows us to do our magic. It uses the provider
206213 * `apiMock` to determine if a mock should be done, then do the actual mocking.
@@ -215,7 +222,12 @@ angular.module('apiMock', []).config([
215222 return res || $q . when ( res ) ;
216223 } ;
217224 this . responseError = function ( rej ) {
218- return apiMock . recover ( rej ) || $q . reject ( rej ) ;
225+ var recover = apiMock . recover ( rej ) ;
226+ if ( recover ) {
227+ var $http = $injector . get ( '$http' ) ;
228+ return $http ( recover ) ;
229+ }
230+ return $q . reject ( rej ) ;
219231 } ;
220232 }
221233] ) ;
0 commit comments