Skip to content

Commit

Permalink
feat(apimock): automatic fallbacks
Browse files Browse the repository at this point in the history
ApiMock can now activate automatically on request errors. So it’ll try
to access the API and if it fails then it will try to do a rerouted
mock request instead. The flag is `auto` and can be set globally in
browser url `?apiMock=auto` or locally on $http request (`$http.get({
url: ‘…’, apiMock: ‘auto’ })`).
  • Loading branch information
seriema committed May 12, 2014
1 parent 2c0ba9f commit 9245bc8
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
42 changes: 42 additions & 0 deletions app/scripts/angular-apimock.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ angular.module('apiMock', [])
var apiPath = '/api';
var $location;
var $q;
var fallbacks = [];

function determineMock(obj) {
switch (typeof obj) {
Expand All @@ -57,6 +58,9 @@ angular.module('apiMock', [])
case 'number':
return !obj ? false : obj;

// case 'string':
// return obj === 'auto' ? true : !!obj;

default:
return !!obj;
}
Expand Down Expand Up @@ -106,13 +110,33 @@ angular.module('apiMock', [])
return !!(mock && this._isApiPath(req));
};

p.shouldAutoMock = function (req) {
return $location.search('apiMock') === 'auto' || req.apiMock === 'auto';
};

p.doMock = function (req) {
if (req && typeof req.apiMock === 'number') {
return httpStatusResponse(req);
}
return mockDataResponse(req);
};

p.prepare = function (req) {
fallbacks.push(req);
};

p.remove = function (res) {
var found = false;
angular.forEach(fallbacks, function (fallback, index) {
if (fallback.method === res.method && fallback.url === res.url) {
found = true;
fallbacks.removeAt(index);
}
});

return found;
};

p._isApiPath = function (req) {
return req && req.url.indexOf(config.apiPath) === 0;
};
Expand Down Expand Up @@ -154,11 +178,29 @@ angular.module('apiMock', [])
`apiMock` to determine if a mock should be done, then do the actual mocking.
*/
this.request = function (req) {
if (req && apiMock.shouldAutoMock(req)) {
apiMock.prepare(req);
}
else
if (req && apiMock.shouldMock(req)) {
req = apiMock.doMock(req);
}

// Return the request or promise.
return req || $q.when(req);
};

this.response = function (res) {
apiMock.remove(res);

return res || $q.when(res);
};

this.responseError = function (rejection) {
if (apiMock.remove(rejection)) {
return apiMock.doMock(rejection);
}

return $q.reject(rejection);
};
});
53 changes: 53 additions & 0 deletions test/spec/services/angular-apimock.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,59 @@ describe('Service: apiMock', function () {

$httpBackend.flush();
});

it('should automatically mock when request fails, with global flag auto', function (done) {
// Set global flag: auto
$location.search('apiMock', 'auto');

// Don't include override
var mockRequest = {
url: '/api/people/pokemon',
method: 'GET'
};

// Do a call, and expect it to recover from fail.
$httpBackend.when('GET', '/api/people/pokemon').respond(404);
$httpBackend.when('GET', '/mock_data/people/pokemon.get.json').respond(200);
$http(mockRequest)
.success(function() {
done();
})
.error(function() {
expect(true).to.be.false; // Todo: How to fail the test if this happens?
done();
});

$httpBackend.flush();
});

it('cant automatically mock request failure if the URL is an invalid API url', function (done) {
// Set global flag: auto
$location.search('apiMock', 'auto');

// Don't include override, but use an URL that doesn't pass the isApiPath test.
var mockRequest = {
url: '/something/people/pokemon',
method: 'GET'
};

// Verify the API path is invalid.
expect(apiMock._isApiPath(mockRequest)).to.be.false;

// Do a call, and expect it to fail.
$httpBackend.when('GET', '/something/people/pokemon').respond(404);
$http(mockRequest)
.success(function() {
expect(true).to.be.false; // Todo: How to fail the test if this happens?
done();
})
.error(function(data, status) {
expect(status).to.equal(404);
done();
});

$httpBackend.flush();
});
});

});

0 comments on commit 9245bc8

Please sign in to comment.