Skip to content

Commit

Permalink
test(apimock): raise test coverage
Browse files Browse the repository at this point in the history
From 97.2% to 100%.

* Removed unnecessary guard clauses in things I borrowed from AngularJS
source code (mostly for IE8 support).
* Used $filter instead of manually removing elements from array in
removeFallback().
* Added tests to better flex the query handling feature in #23.
** Testing array of objects.
** Undefined and empty URL param values.
** Date-type in params object.

Closes #44
  • Loading branch information
seriema committed Oct 18, 2015
1 parent 7fa7fdc commit 11fa90f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 37 deletions.
59 changes: 22 additions & 37 deletions app/scripts/angular-apimock.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ angular.module('apiMock', [])
var $location;
var $log;
var $q;
var $filter;
var config = {
defaultMock: false,
mockDataPath: '/mock_data',
Expand All @@ -68,7 +69,7 @@ angular.module('apiMock', [])
return keys;
}

// Taken from Angular 1.4.x: https://github.com/angular/angular.js/blob/f13852c179ffd9ec18b7a94df27dec39eb5f19fc/src/Angular.js#L296
// Taken as-is from Angular 1.4.x: https://github.com/angular/angular.js/blob/f13852c179ffd9ec18b7a94df27dec39eb5f19fc/src/Angular.js#L296
function forEachSorted(obj, iterator, context) {
var keys = objectKeys(obj).sort();
for (var i = 0; i < keys.length; i++) {
Expand All @@ -77,38 +78,31 @@ angular.module('apiMock', [])
return keys;
}

// Taken from Angular 1.4.x: https://github.com/angular/angular.js/blob/929ec6ba5a60e926654583033a90aebe716123c0/src/ng/http.js#L18
// Modified from Angular 1.4.x: https://github.com/angular/angular.js/blob/929ec6ba5a60e926654583033a90aebe716123c0/src/ng/http.js#L18
function serializeValue(v) {
if (angular.isObject(v)) {
return angular.isDate(v) ? v.toISOString() : angular.toJson(v);
if (angular.isDate(v)) {
return v.toISOString();
}

return v;
}

// Taken from Angular 1.4.x: https://github.com/angular/angular.js/blob/720012eab6fef5e075a1d6876dd2e508c8e95b73/src/ngResource/resource.js#L405
function encodeUriQuery(val, pctEncodeSpaces) {
// Modified from Angular 1.4.x: https://github.com/angular/angular.js/blob/720012eab6fef5e075a1d6876dd2e508c8e95b73/src/ngResource/resource.js#L405
function encodeUriQuery(val) {
return encodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
replace(/%20/g, '+');
}

// TODO: replace with a $httpParamSerializerJQLikeProvider() call when we require Angular 1.4 (i.e. when we drop 1.2 and 1.3).
// Taken from Angular 1.4.x: https://github.com/angular/angular.js/blob/929ec6ba5a60e926654583033a90aebe716123c0/src/ng/http.js#L108
// Modified from Angular 1.4.x: https://github.com/angular/angular.js/blob/929ec6ba5a60e926654583033a90aebe716123c0/src/ng/http.js#L108
function jQueryLikeParamSerializer(params) {
if (!params) {
return '';
}

var parts = [];

function serialize(toSerialize, prefix, topLevel) {
if (toSerialize === null || angular.isUndefined(toSerialize)) {
return;
}

if (angular.isArray(toSerialize)) {
angular.forEach(toSerialize, function (value, index) {
serialize(value, prefix + '[' + (angular.isObject(value) ? index : '') + ']');
Expand Down Expand Up @@ -247,15 +241,13 @@ angular.module('apiMock', [])
}

function removeFallback(res) {
var found = false;
angular.forEach(fallbacks, function (fallback, index) {
if (fallback.method === res.method && fallback.url === res.url) {
found = true;
fallbacks.splice(index, 1);
}
});
var startLength = fallbacks.length;
fallbacks = $filter('filter')(fallbacks, {
method: '!' + res.method,
url: '!' + res.url
}, true);

return found;
return startLength > fallbacks.length;
}

function reroute(req) {
Expand Down Expand Up @@ -309,10 +301,11 @@ angular.module('apiMock', [])
// Expose public interface for provider instance
//

function ApiMock(_$location, _$log, _$q) {
function ApiMock(_$location, _$log, _$q, _$filter) {
$location = _$location;
$log = _$log;
$q = _$q;
$filter = _$filter;
}

var p = ApiMock.prototype;
Expand Down Expand Up @@ -342,18 +335,13 @@ angular.module('apiMock', [])
case 'respond':
return httpStatusResponse(command.value);
case 'ignore':
return req;

/* falls through */
default:
return req;
}
};

p.onResponse = function (res) {
if (config.disable) {
return res;
}

removeFallback(res);
return res;
};
Expand Down Expand Up @@ -382,8 +370,8 @@ angular.module('apiMock', [])
angular.extend(config, options);
};

this.$get = function ($location, $log, $q) {
return new ApiMock($location, $log, $q);
this.$get = function ($location, $log, $q, $filter) {
return new ApiMock($location, $log, $q, $filter);
};
})

Expand All @@ -393,10 +381,7 @@ angular.module('apiMock', [])
* `apiMock` to determine if a mock should be done, then do the actual mocking.
*/
this.request = function (req) {
req = apiMock.onRequest(req);

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

this.response = function (res) {
Expand Down
46 changes: 46 additions & 0 deletions test/spec/services/angular-apimock.js
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,52 @@ describe('Service: apiMock', function () {

expectHttpSuccess();
});

it('should serialize objects nested inside arrays', function () {
defaultRequest.url = '/api/pokemon';
defaultRequest.params = {
'moves': [ {
'Thunderbolt': {
power: 95,
type: 'Electric'
}}, {
'Double Edge': {
power: 120,
type: 'Normal'
}
} ]
};
defaultExpectPath = '/mock_data/pokemon/moves%5b0%5d%5bthunderbolt%5d%5bpower%5d=95&moves%5b0%5d%5bthunderbolt%5d%5btype%5d=electric&moves%5b1%5d%5bdouble+edge%5d%5bpower%5d=120&moves%5b1%5d%5bdouble+edge%5d%5btype%5d=normal.get.json';

expectHttpSuccess();
});

it('should handle empty value', function () {
defaultRequest.url = '/api/pokemon?releaseDate';
defaultExpectPath = '/mock_data/pokemon/releasedate=.get.json';

expectHttpSuccess();
});

it('should handle undefined value', function () {
defaultRequest.url = '/api/pokemon';
defaultRequest.params = {
'releaseDate': undefined
};
defaultExpectPath = '/mock_data/pokemon/releasedate=undefined.get.json';

expectHttpSuccess();
});

it('should serialize date type', function () {
defaultRequest.url = '/api/pokemon';
defaultRequest.params = {
'releaseDate': new Date(Date.UTC(96, 1, 27, 0, 0, 0))
};
defaultExpectPath = '/mock_data/pokemon/releasedate=1996-02-27t00:00:00.000z.get.json';

expectHttpSuccess();
});
});

describe('delay option', function () {
Expand Down

0 comments on commit 11fa90f

Please sign in to comment.