1
- /*! Angular API Mock v0.1.5
1
+ /*! Angular API Mock v0.1.6
2
2
* Licensed with MIT
3
3
* Made with ♥ from Seriema + Redhorn */
4
4
/* Create the main module, `apiMock`. It's the one that needs to be included in
@@ -39,47 +39,16 @@ angular.module('apiMock', []).config([
39
39
*/
40
40
// Helper objects
41
41
//
42
- var mockDataPath = '/mock_data' ;
43
- var apiPath = '/api' ;
44
42
var $location ;
43
+ var $log ;
45
44
var $q ;
45
+ var config = {
46
+ mockDataPath : '/mock_data' ,
47
+ apiPath : '/api'
48
+ } ;
46
49
var fallbacks = [ ] ;
47
50
// Helper methods
48
51
//
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
- }
83
52
function detectParameter ( keys ) {
84
53
var regex = / a p i m o c k / i;
85
54
var result ;
@@ -93,24 +62,28 @@ angular.module('apiMock', []).config([
93
62
function localMock ( req ) {
94
63
return detectParameter ( req ) ;
95
64
}
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 ;
98
71
}
99
72
function getCommand ( mockValue ) {
100
73
switch ( typeof mockValue ) {
101
74
case 'number' :
102
- if ( mockValue !== 0 ) {
75
+ if ( mockValue !== 0 && ! isNaN ( mockValue ) ) {
103
76
return {
104
77
type : 'respond' ,
105
78
value : mockValue
106
79
} ;
107
80
}
108
81
break ;
109
82
case 'string' :
110
- if ( mockValue . toLowerCase ( ) === 'auto' ) {
83
+ switch ( mockValue . toLowerCase ( ) ) {
84
+ case 'auto' :
111
85
return { type : 'recover' } ;
112
- }
113
- if ( mockValue . toLowerCase ( ) === 'true' ) {
86
+ case 'true' :
114
87
return { type : 'reroute' } ;
115
88
}
116
89
break ;
@@ -122,12 +95,29 @@ angular.module('apiMock', []).config([
122
95
}
123
96
return { type : 'ignore' } ;
124
97
}
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 ) {
126
116
if ( isApiPath ( req . url ) ) {
127
117
fallbacks . push ( req ) ;
128
118
}
129
- } ;
130
- var removeFallback = function ( res ) {
119
+ }
120
+ function removeFallback ( res ) {
131
121
var found = false ;
132
122
angular . forEach ( fallbacks , function ( fallback , index ) {
133
123
if ( fallback . method === res . method && fallback . url === res . url ) {
@@ -136,16 +126,34 @@ angular.module('apiMock', []).config([
136
126
}
137
127
} ) ;
138
128
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 ;
146
149
}
147
150
// Expose public interface for provider instance
148
151
//
152
+ function ApiMock ( _$location , _$log , _$q ) {
153
+ $location = _$location ;
154
+ $log = _$log ;
155
+ $q = _$q ;
156
+ }
149
157
var p = ApiMock . prototype ;
150
158
p . _countFallbacks = function ( ) {
151
159
return fallbacks . length ;
@@ -177,30 +185,29 @@ angular.module('apiMock', []).config([
177
185
return false ;
178
186
}
179
187
if ( removeFallback ( rej . config ) ) {
188
+ $log . info ( 'apiMock: recovering from failure at ' + rej . config . url ) ;
180
189
return reroute ( rej . config ) ;
181
190
}
182
191
return false ;
183
192
} ;
184
- var config = {
185
- mockDataPath : mockDataPath ,
186
- apiPath : apiPath
187
- } ;
188
193
// Expose Provider interface
189
194
//
190
195
this . config = function ( options ) {
191
196
angular . extend ( config , options ) ;
192
197
} ;
193
198
this . $get = [
194
199
'$location' ,
200
+ '$log' ,
195
201
'$q' ,
196
- function ( $location , $q ) {
197
- return new ApiMock ( $location , $q ) ;
202
+ function ( $location , $log , $ q) {
203
+ return new ApiMock ( $location , $log , $ q) ;
198
204
}
199
205
] ;
200
206
} ) . service ( 'httpInterceptor' , [
207
+ '$injector' ,
201
208
'$q' ,
202
209
'apiMock' ,
203
- function ( $q , apiMock ) {
210
+ function ( $injector , $ q, apiMock ) {
204
211
/* The main service. Is jacked in as a interceptor on `$http` so it gets called
205
212
* on every http call. This allows us to do our magic. It uses the provider
206
213
* `apiMock` to determine if a mock should be done, then do the actual mocking.
@@ -215,7 +222,12 @@ angular.module('apiMock', []).config([
215
222
return res || $q . when ( res ) ;
216
223
} ;
217
224
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 ) ;
219
231
} ;
220
232
}
221
233
] ) ;
0 commit comments