angular-http-cache
Advanced tools
Comparing version 1.0.7 to 1.2.1
{ | ||
"name": "angular-http-cache", | ||
"version": "1.0.7", | ||
"version": "1.2.1", | ||
"description": "An angular module that sits on top of $http and adds caching support and application wide notifications when cached data is updated.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
'use strict'; | ||
angular.module('angular-http-cache', ['angular-local-db']) | ||
.service('$httpCache', | ||
['$http', '$localDb', '$rootScope', '$q', | ||
function ($http, $localDb, $rootScope, $q) { | ||
angular.module('angular-http-cache', ['angular-local-db']).service('$httpCache', ['$http', '$localDb', '$rootScope', '$q', function ($http, $localDb, $rootScope, $q) { | ||
/** | ||
* @param {Object} object | ||
* @param {string} object.collection | ||
* @param {boolean} object.caching | ||
* @param {string} object.domain | ||
* @return {httpCache} | ||
* @api public | ||
*/ | ||
var httpCache = function (options) { | ||
if (!(this instanceof httpCache)) { | ||
return new httpCache(options); | ||
} | ||
* @param {Object} _options | ||
* @param {string} _options.collection | ||
* @param {boolean} _options.caching | ||
* @param {string} _options.domain | ||
* @return {httpCache} | ||
* @api public | ||
*/ | ||
var httpCache = function httpCache(_options) { | ||
if (!(this instanceof httpCache)) { | ||
return new httpCache(_options); | ||
} | ||
options == options || {}; | ||
this.setCollection(options.collection); | ||
this.setDocCaching(options.caching); | ||
this.setDomain(options.domain); | ||
var options = _options || {}; | ||
this.setCollection(options.collection); | ||
this.setDocCaching(options.caching); | ||
this.setDomain(options.domain); | ||
}; | ||
/** | ||
* @param {string|int} id | ||
* @param {object} params | ||
* @param {boolean} params.ignoreCache | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.get = function (id, params) { | ||
return $q((function (resolve, reject) { | ||
* @param {string|int} id | ||
* @param {object} _params | ||
* @param {boolean} _params.ignoreCache | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.get = function (id, _params) { | ||
var _this = this; | ||
params = params || {}; | ||
this._catchExecute('get', {id:id}); | ||
return $q.resolve().then(function () { | ||
var params = _params || {}; | ||
_this._catchExecute('get', { id: id }); | ||
var cached = $localDb.getIndex(this._getCacheKey(), id); | ||
if (cached && !params.ignoreCache) { resolve(cached);} | ||
var cached = $localDb.getIndex(_this._getCacheKey(), id); | ||
if (cached && !params.ignoreCache) { | ||
return cached; | ||
} | ||
$http({method: 'GET', url: '/' + this._getUrlPredicate() + '/' + id}) | ||
.success((function (data, status, headers, config) { | ||
this._handleDoc(data.doc); | ||
if (!cached || !this._caching || params.ignoreCache) { | ||
resolve(data.doc); | ||
} | ||
$rootScope.$broadcast(this._getCacheBroadcastPredicate() + '-cache-updated', {trigger: 'get', doc: data.doc}); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
return $http({ | ||
method: 'GET', | ||
url: '/' + _this._getUrlPredicate() + '/' + id | ||
}).then(function (res) { | ||
return res.data; | ||
}).then(function (data) { | ||
_this._handleDoc(data.doc); | ||
}).bind(this)) | ||
$rootScope.$broadcast(_this._getCacheBroadcastPredicate() + '-cache-updated', { | ||
trigger: 'get', | ||
doc: data.doc | ||
}); | ||
return data.doc; | ||
}); | ||
}); | ||
}; | ||
/** | ||
* @param {object} params | ||
* @param {boolean} params.ignoreCache | ||
* @param {string|int} params.index | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.fetch = function (params) { | ||
return $q((function (resolve, reject) { | ||
* @param {object} _params | ||
* @param {boolean} _params.ignoreCache | ||
* @param {string|int} _params.index | ||
* @param {string|int} _params.offset | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.fetch = function (_params) { | ||
var _this2 = this; | ||
this._catchExecute('fetch', {options:params}); | ||
return $q.resolve().then(function () { | ||
var cached = $localDb.get(this._getCacheKey()); | ||
if (cached && !params.ignoreCache) { | ||
if (!params.offset) { | ||
resolve({docs: cached, data: {}}) | ||
} else if (params.offset < cached.length) { | ||
resolve({docs: cached, data: {}}) | ||
} | ||
} | ||
var params = angular.isObject(_params) ? _params : {}; | ||
$http({method: 'GET', url: '/' + this._getUrlPredicate(), params: params }) | ||
.success((function (data, status, headers, config) { | ||
for (var i = 0; i < data.docs.length; i++) { | ||
this._handleDoc(data.docs[i], params.index); | ||
} | ||
if (!this._caching || params.ignoreCache) { | ||
resolve({docs: data.docs, data: data.data}) | ||
} else if (!cached) { | ||
resolve({docs: $localDb.get(this._getCacheKey()), data: data.data}) | ||
} | ||
$rootScope.$broadcast(this._getCacheBroadcastPredicate() + '-cache-updated', {trigger: 'fetch', docs: $localDb.get(this._getCacheKey()), index: params.index, data: data.data}); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
var cached = $localDb.get(_this2._getCacheKey()); | ||
if (cached && !params.ignoreCache && (!params.offset || params.offset < cached.length)) { | ||
return { | ||
docs: cached, | ||
data: {} | ||
}; | ||
} | ||
}).bind(this)) | ||
delete params.ignoreCache; | ||
return $http({ | ||
method: 'GET', | ||
url: '/' + _this2._getUrlPredicate(), | ||
params: params | ||
}).then(function (res) { | ||
return res.data; | ||
}).then(function (data) { | ||
for (var i = 0; i < data.docs.length; i++) { | ||
_this2._handleDoc(data.docs[i], params.index); | ||
} | ||
var _data = data.data || {}; | ||
$rootScope.$broadcast(_this2._getCacheBroadcastPredicate() + '-cache-updated', { | ||
trigger: 'fetch', | ||
docs: $localDb.get(_this2._getCacheKey()), | ||
index: params.index, | ||
data: _data | ||
}); | ||
if (!_this2._caching || params.ignoreCache) { | ||
return { | ||
docs: data.docs, | ||
data: _data | ||
}; | ||
} | ||
return { | ||
docs: $localDb.get(_this2._getCacheKey()), | ||
data: _data | ||
}; | ||
}); | ||
}); | ||
}; | ||
/** | ||
* @param {object} data | ||
* @return Promise | ||
* @api public | ||
*/ | ||
* @param {object} data | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.create = function (data) { | ||
return $q((function (resolve, reject) { | ||
var _this3 = this; | ||
this._catchExecute('create', {data:data}); | ||
$http({method: 'POST', url: '/' + this._getUrlPredicate(), data: data}) | ||
.success((function (data, status, headers, config) { | ||
this._handleDoc(data.doc); | ||
resolve(data.doc); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
}).bind(this)) | ||
return $q.resolve().then(function () { | ||
_this3._catchExecute('create', { data: data }); | ||
return $http({ | ||
method: 'POST', | ||
url: '/' + _this3._getUrlPredicate(), | ||
data: data | ||
}); | ||
}).then(function (res) { | ||
return res.data; | ||
}).then(function (data) { | ||
_this3._handleDoc(data.doc); | ||
return data.doc; | ||
}); | ||
}; | ||
/** | ||
* @param {object} doc | ||
* @return Promise | ||
* @api public | ||
*/ | ||
* @param {object} doc | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.update = function (doc) { | ||
return $q((function (resolve, reject) { | ||
delete doc.$$hashKey; | ||
this._catchExecute('update', {doc:doc}); | ||
var _this4 = this; | ||
$http({method: 'PUT', url: '/' + this._getUrlPredicate() + '/' + doc.id, data:{doc:doc}}) | ||
.success((function (data, status, headers, config) { | ||
this._handleDoc(data.doc); | ||
resolve(data.doc); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
}).bind(this)) | ||
return $q.resolve().then(function () { | ||
_this4._catchExecute('update', { doc: doc }); | ||
delete doc.$$hashKey; | ||
return $http({ | ||
method: 'PUT', | ||
url: '/' + _this4._getUrlPredicate() + '/' + doc.id, | ||
data: { doc: doc } | ||
}); | ||
}).then(function (res) { | ||
return res.data; | ||
}).then(function (data) { | ||
_this4._handleDoc(data.doc); | ||
return data.doc; | ||
}); | ||
}; | ||
/** | ||
* @param {string|int} id | ||
* @param {string|int} prop | ||
* @param {string|int|array|object} value | ||
* @return Promise | ||
* @api public | ||
*/ | ||
* @param {string|int} id | ||
* @param {string|int} prop | ||
* @param {string|int|Array|object} value | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.patch = function (id, prop, value) { | ||
return $q((function (resolve, reject) { | ||
var _this5 = this; | ||
this._catchExecute('patch', {id:id, prop:prop, value:value}); | ||
return $q.resolve().then(function () { | ||
_this5._catchExecute('patch', { | ||
id: id, | ||
prop: prop, | ||
value: value | ||
}); | ||
$http({method: 'PATCH', url: '/' + this._getUrlPredicate() + '/' + id, data:{prop:prop,value:value}}) | ||
.success((function (data, status, headers, config) { | ||
this._handleDoc(data.doc); | ||
resolve(data.doc); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
}).bind(this)) | ||
return $http({ | ||
method: 'PATCH', | ||
url: '/' + _this5._getUrlPredicate() + '/' + id, | ||
data: { | ||
prop: prop, | ||
value: value | ||
} | ||
}); | ||
}).then(function (res) { | ||
return res.data; | ||
}).then(function (data) { | ||
_this5._handleDoc(data.doc); | ||
return data.doc; | ||
}); | ||
}; | ||
/** | ||
* @param {string|int} id | ||
* @return Promise | ||
* @api public | ||
*/ | ||
* @param {string|int} id | ||
* @return Promise | ||
* @api public | ||
*/ | ||
httpCache.prototype.delete = function (id) { | ||
return $q((function (resolve, reject) { | ||
var _this6 = this; | ||
this._catchExecute('delete', {id:id}); | ||
$http({method: 'DELETE', url: '/' + this._getUrlPredicate() + '/' + id}) | ||
.success((function (data, status, headers, config) { | ||
this._handleDocRemoval(id); | ||
resolve(true); | ||
}).bind(this)) | ||
.error(function (data, status, headers, config) { | ||
reject(data.message); | ||
}); | ||
}).bind(this)) | ||
return $q.resolve().then(function () { | ||
_this6._catchExecute('delete', { id: id }); | ||
return $http({ | ||
method: 'DELETE', | ||
url: '/' + _this6._getUrlPredicate() + '/' + id | ||
}); | ||
}).then(function () { | ||
_this6._handleDocRemoval(id); | ||
return true; | ||
}).catch(function (res) { | ||
throw new Error(res.data.message); | ||
}); | ||
}; | ||
/** | ||
* @api public | ||
*/ | ||
* @api public | ||
*/ | ||
httpCache.prototype.initIndexes = function () { | ||
this._indexMap = {}; | ||
this._indexMap = {}; | ||
}; | ||
/** | ||
* @param {string} collection | ||
* @api public | ||
*/ | ||
* @param {string} collection | ||
* @api public | ||
*/ | ||
httpCache.prototype.setCollection = function (collection) { | ||
this._collection = collection; | ||
this._collection = collection; | ||
return this; | ||
}; | ||
/** | ||
* @api public | ||
*/ | ||
* @api public | ||
*/ | ||
httpCache.prototype.getCollection = function () { | ||
return this._collection; | ||
return this._collection; | ||
}; | ||
/** | ||
* @param {boolean} caching | ||
* @api public | ||
*/ | ||
* @param {boolean} caching | ||
* @api public | ||
*/ | ||
httpCache.prototype.setDocCaching = function (caching) { | ||
this._caching = caching; | ||
this._caching = caching; | ||
return this; | ||
}; | ||
/** | ||
* @api public | ||
*/ | ||
* @api public | ||
*/ | ||
httpCache.prototype.getDocCaching = function () { | ||
return this._caching; | ||
return this._caching; | ||
}; | ||
/** | ||
* @param {string} domain | ||
* @api public | ||
*/ | ||
* @param {string} domain | ||
* @api public | ||
*/ | ||
httpCache.prototype.setDomain = function (domain) { | ||
this._domain = domain; | ||
this._domain = domain; | ||
return this; | ||
}; | ||
/** | ||
* @api public | ||
*/ | ||
* @api public | ||
*/ | ||
httpCache.prototype.getDomain = function () { | ||
return this._domain; | ||
return this._domain; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._init = function () { | ||
this.initIndexes(); | ||
this._caching = true; | ||
this._collection = ''; | ||
this._domain = ''; | ||
this.initIndexes(); | ||
this._caching = true; | ||
this._collection = ''; | ||
this._domain = ''; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._getUrlPredicate = function () { | ||
return this._domain ? this._domain + '/' + this._collection : this._collection; | ||
return this._domain ? this._domain + '/' + this._collection : this._collection; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._getCacheKey = function () { | ||
return this._domain ? this._domain + ':' + this._collection : this._collection; | ||
return this._domain ? this._domain + ':' + this._collection : this._collection; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._getCacheBroadcastPredicate = function () { | ||
return this._domain ? this._domain + '-' + this._collection : this._collection; | ||
return this._domain ? this._domain + '-' + this._collection : this._collection; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._handleDoc = function (doc, index, secondary) { | ||
if (!doc || !this._caching) return; | ||
if (!doc || !this._caching) return; | ||
$localDb.setIndex(this._getCacheKey(), doc.id, doc); | ||
$localDb.addToSet(this._getCacheKey(), doc); | ||
$localDb.setIndex(this._getCacheKey(), doc.id, doc); | ||
$localDb.addToSet(this._getCacheKey(), doc); | ||
if (secondary && index) { | ||
if (this._indexMap[index].indexOf(secondary) == -1) { this._indexMap[index].push(secondary); } | ||
$localDb.addToSecondaryIndexSet(this._getCacheKey(), index, secondary, doc); | ||
} else if (index) { | ||
this._indexMap[index] = this._indexMap[index] || []; | ||
$localDb.addToIndexSet(this._getCacheKey(), index, doc); | ||
} | ||
if (secondary && index) { | ||
if (this._indexMap[index].indexOf(secondary) == -1) { | ||
this._indexMap[index].push(secondary); | ||
} | ||
$localDb.addToSecondaryIndexSet(this._getCacheKey(), index, secondary, doc); | ||
} else if (index) { | ||
this._indexMap[index] = this._indexMap[index] || []; | ||
$localDb.addToIndexSet(this._getCacheKey(), index, doc); | ||
} | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._handleDocRemoval = function (id) { | ||
if (!id || !this._caching) return; | ||
if (!id || !this._caching) return; | ||
$localDb.clearIndex(this._getCacheKey(), id); | ||
$localDb.clearFromSet(this._getCacheKey(), id); | ||
$localDb.clearIndex(this._getCacheKey(), id); | ||
$localDb.clearFromSet(this._getCacheKey(), id); | ||
for (var index in this._indexMap) { | ||
$localDb.clearFromIndexSet(this._getCacheKey(), index, id); | ||
for (var index in this._indexMap) { | ||
$localDb.clearFromIndexSet(this._getCacheKey(), index, id); | ||
if (this._indexMap[index]) { | ||
var secondaryIndexes = this._indexMap[index]; | ||
if (this._indexMap[index]) { | ||
var secondaryIndexes = this._indexMap[index]; | ||
for (var i = 0; i < secondaryIndexes.length; i++) { | ||
$localDb.clearFromSecondaryIndexSet(this._getCacheKey(), index, secondaryIndexes[i], id); | ||
} | ||
for (var i = 0; i < secondaryIndexes.length; i++) { | ||
$localDb.clearFromSecondaryIndexSet(this._getCacheKey(), index, secondaryIndexes[i], id); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
* @api private | ||
*/ | ||
httpCache.prototype._catchExecute = function (method, params) { | ||
if (!this._collection) { | ||
throw new Error ('Set a collection in httpCache before using method: \'' + method + '\''); | ||
} | ||
var collection = this._collection; | ||
if (!this._collection) { | ||
throw new Error('Set a collection in httpCache before using method: ' + method); | ||
} | ||
switch (method) { | ||
case 'get': | ||
if (!params.id) { | ||
throw new Error ('Missing required paramater: \'id\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\''); | ||
} | ||
break; | ||
case 'fetch': | ||
if (!params.options) { | ||
throw new Error ('Missing required paramater: \'options\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
break; | ||
case 'create': | ||
if (!params.data) { | ||
throw new Error ('Missing required paramater: \'data\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
break; | ||
case 'update': | ||
if (!params.doc) { | ||
throw new Error ('Missing required paramater: \'doc\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
break; | ||
case 'patch': | ||
if (!params.id) { | ||
throw new Error ('Missing required paramater: \'id\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
if (!params.prop) { | ||
throw new Error ('Missing required paramater: \'prop\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
if (!params.value) { | ||
throw new Error ('Missing required paramater: \'value\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\'') | ||
} | ||
break; | ||
case 'delete': | ||
if (!params.id) { | ||
throw new Error ('Missing required paramater: \'id\' in httpCache method: \'' + method + '\' with collection: \'' + this._collection + '\''); | ||
} | ||
break; | ||
} | ||
function getError(propName) { | ||
throw new Error('Missing or invalid parameter "' + propName + '" in httpCache method "' + method + '" with collection "' + collection + '"'); | ||
} | ||
switch (method) { | ||
case 'get': | ||
if (!params.id) { | ||
getError('id'); | ||
} | ||
break; | ||
case 'create': | ||
if (!params.data) { | ||
getError('data'); | ||
} | ||
break; | ||
case 'update': | ||
if (!params.doc) { | ||
getError('doc'); | ||
} | ||
break; | ||
case 'patch': | ||
if (!params.id) { | ||
getError('id'); | ||
} | ||
if (!params.prop) { | ||
getError('prop'); | ||
} | ||
if (!params.value) { | ||
getError('value'); | ||
} | ||
break; | ||
case 'delete': | ||
if (!params.id) { | ||
getError('id'); | ||
} | ||
break; | ||
} | ||
}; | ||
return httpCache; | ||
}]); |
// Karma configuration | ||
// Generated on Thu Jun 30 2016 10:58:38 GMT-0400 (EDT) | ||
module.exports = function(config) { | ||
config.set({ | ||
module.exports = (config) => { | ||
config.set({ | ||
// base path that will be used to resolve all patterns (eg. files, exclude) | ||
basePath: '', | ||
// base path that will be used to resolve all patterns (eg. files, exclude) | ||
basePath: '', | ||
// frameworks to use | ||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter | ||
frameworks: ['jasmine'], | ||
// frameworks to use | ||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter | ||
frameworks: ['mocha', 'chai', 'chai-as-promised', 'sinon'], | ||
// list of files / patterns to load in the browser | ||
files: [ | ||
'./node_modules/angular/angular.js', | ||
'./node_modules/angular-ui-router/release/angular-ui-router.js', | ||
'./node_modules/angular-mocks/angular-mocks.js', | ||
'./node_modules/angular-local-db/dist/angular-local-db.js', | ||
'./dist/angular-http-cache.js', | ||
'./test/httpCacheSpec.js' | ||
], | ||
// list of files / patterns to load in the browser | ||
files: [ | ||
'./node_modules/angular/angular.js', | ||
'./node_modules/angular-ui-router/release/angular-ui-router.js', | ||
'./node_modules/angular-mocks/angular-mocks.js', | ||
'./node_modules/angular-local-db/dist/angular-local-db.js', | ||
'./src/angular-http-cache.js', | ||
'./test/httpCacheSpec.js' | ||
], | ||
// list of files to exclude | ||
exclude: [ | ||
], | ||
// list of files to exclude | ||
exclude: [], | ||
// preprocess matching files before serving them to the browser | ||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor | ||
preprocessors: { | ||
}, | ||
// preprocess matching files before serving them to the browser | ||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor | ||
preprocessors: {}, | ||
// test results reporter to use | ||
// possible values: 'dots', 'progress' | ||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter | ||
reporters: ['progress'], | ||
// test results reporter to use | ||
// possible values: 'dots', 'progress' | ||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter | ||
reporters: ['progress'], | ||
// web server port | ||
port: 9876, | ||
// web server port | ||
port: 9876, | ||
// enable / disable colors in the output (reporters and logs) | ||
colors: true, | ||
// enable / disable colors in the output (reporters and logs) | ||
colors: true, | ||
// level of logging | ||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG | ||
logLevel: config.LOG_INFO, | ||
// level of logging | ||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG | ||
logLevel: config.LOG_INFO, | ||
// enable / disable watching file and executing tests whenever any file changes | ||
autoWatch: true, | ||
// enable / disable watching file and executing tests whenever any file changes | ||
autoWatch: true, | ||
// start these browsers | ||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher | ||
browsers: ['Chrome'], | ||
// start these browsers | ||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher | ||
browsers: ['Chrome'], | ||
// Continuous Integration mode | ||
// if true, Karma captures browsers, runs the tests and exits | ||
singleRun: false, | ||
// Continuous Integration mode | ||
// if true, Karma captures browsers, runs the tests and exits | ||
singleRun: false, | ||
// Concurrency level | ||
// how many browser should be started simultaneous | ||
concurrency: Infinity | ||
}) | ||
// Concurrency level | ||
// how many browser should be started simultaneous | ||
concurrency: Infinity | ||
}) | ||
} |
{ | ||
"name": "angular-http-cache", | ||
"version": "1.0.7", | ||
"version": "1.2.1", | ||
"description": "An angular module that sits on top of $http and adds caching support and application wide notifications when cached data is updated. ", | ||
@@ -28,8 +28,12 @@ "main": "index.js", | ||
"angular-mocks": "^1.5.7", | ||
"angular-ui-router": "^0.3.1", | ||
"jasmine-core": "^2.4.1", | ||
"karma": "^1.1.0", | ||
"babel-preset-es2015": "^6.18.0", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2", | ||
"karma": "^1.3.0", | ||
"karma-chai-plugins": "^0.8.0", | ||
"karma-chrome-launcher": "^1.0.1", | ||
"karma-jasmine": "^1.0.2" | ||
"karma-mocha": "^1.3.0", | ||
"karma-sinon": "^1.0.5", | ||
"mocha": "^3.2.0" | ||
} | ||
} |
'use strict'; | ||
const expect = chai.expect; | ||
describe('angular-http-cache', () => { | ||
var $httpCache; | ||
beforeEach(angular.mock.module('angular-local-db')); | ||
beforeEach(angular.mock.module('angular-http-cache')); | ||
let $httpCache; | ||
let $httpBackend; | ||
let $http; | ||
let $rootScope; | ||
let $localDb; | ||
let box; | ||
beforeEach(inject((_$httpCache_) => { | ||
$httpCache = _$httpCache_; | ||
})); | ||
beforeEach(angular.mock.module('angular-local-db')); | ||
beforeEach(angular.mock.module('angular-http-cache')); | ||
it('should exist', () => { | ||
expect($httpCache).toBeDefined(); | ||
}); | ||
beforeEach(inject((_$httpCache_, _$httpBackend_, _$rootScope_, _$localDb_, _$http_) => { | ||
$httpCache = _$httpCache_; | ||
$httpBackend = _$httpBackend_; | ||
$rootScope = _$rootScope_; | ||
$localDb = _$localDb_; | ||
$http = _$http_; | ||
})); | ||
it('should initialize with a collection', () => { | ||
const service = $httpCache({collection: 'users'}) | ||
expect(service.getCollection()).toEqual('users') | ||
}) | ||
beforeEach(() => { | ||
box = sinon.sandbox.create(); | ||
}); | ||
afterEach(() => { | ||
box && box.restore; | ||
}); | ||
it('should initialize with caching', () => { | ||
const service = $httpCache({caching: true}) | ||
expect(service.getDocCaching()).toEqual(true) | ||
}) | ||
it('should exist', () => { | ||
expect($httpCache).to.exist; | ||
}); | ||
it('should initialize with a domain', () => { | ||
const service = $httpCache({domain: 'admin'}) | ||
expect(service.getDomain()).toEqual('admin') | ||
}) | ||
describe('constructor', () => { | ||
let service; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true, domain: 'admin'}); | ||
}); | ||
// TODO | ||
// write unit tests for methods | ||
it('should initialize with a collection', () => { | ||
expect(service.getCollection()).to.equal('users'); | ||
}); | ||
}); | ||
it('should initialize with caching', () => { | ||
expect(service.getDocCaching()).to.equal(true); | ||
}); | ||
it('should initialize with a domain', () => { | ||
expect(service.getDomain()).to.equal('admin'); | ||
}); | ||
}); | ||
describe('httpCache.prototype.get method', () => { | ||
let service; | ||
const id = 1; | ||
const data = { | ||
doc: { | ||
id: id | ||
} | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.get).to.be.a('function'); | ||
}); | ||
it('should reject if id param is not provided', () => { | ||
expect(service.get()).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should issue a GET request to path/:id when cache is ignored', () => { | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}/${id}`).respond(200, data); | ||
let actual; | ||
service.get(id, {ignoreCache: true}) | ||
.then((doc) => { | ||
actual = doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(actual).to.deep.equal(data.doc); | ||
}); | ||
it('should return a cached value when cache exists and is not ignored', () => { | ||
const cachedDoc = angular.copy(data.doc); | ||
expect(cachedDoc.cached).to.not.exist; | ||
cachedDoc.cached = true; | ||
box.stub($localDb, 'getIndex', () => cachedDoc); | ||
let actual; | ||
service.get(id) | ||
.then((doc) => { | ||
actual = doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$rootScope.$apply(); | ||
expect(actual).to.equal(cachedDoc); | ||
expect(actual).to.not.equal(data.doc); | ||
}); | ||
it('should return a cached value on subsequent calls', () => { | ||
let first; | ||
let second; | ||
// We expect only one request | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}/${id}`).respond(200, data); | ||
// Clear the cache first | ||
$localDb.clearIndex(service._getCacheKey(), id); | ||
// First call | ||
service.get(id) | ||
.then((doc) => { | ||
first = doc; | ||
// Second (cached) call | ||
return service.get(id); | ||
}) | ||
.then((doc) => { | ||
second = doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(first).to.deep.equal(data.doc); | ||
expect(second).to.deep.equal(data.doc); | ||
}); | ||
}); | ||
describe('httpCache.prototype.fetch method', () => { | ||
let service; | ||
const data = { | ||
docs: [{ | ||
id: 1 | ||
}, { | ||
id: 2 | ||
}] | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.fetch).to.be.a('function'); | ||
}); | ||
it('should return an object', () => { | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}`).respond(200, data); | ||
// Clear the cache first | ||
$localDb.clear(service._getCacheKey()); | ||
service.fetch() | ||
.then((res) => { | ||
expect(res).to.be.an('object'); | ||
expect(res.docs).to.be.an('array'); | ||
expect(res.data).to.be.an('object'); | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
}); | ||
it('should return a cached value on subsequent calls', () => { | ||
let first; | ||
let second; | ||
// We expect only one request | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}`).respond(200, data); | ||
// Clear the cache first | ||
$localDb.clear(service._getCacheKey()), | ||
// First call | ||
service.fetch() | ||
.then((res) => { | ||
first = res.docs; | ||
// Second (cached) call | ||
return service.fetch(); | ||
}) | ||
.then((res) => { | ||
second = res.docs; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(first).to.deep.equal(data.docs); | ||
expect(second).to.deep.equal(data.docs); | ||
}); | ||
it('should ignore the cache if "ignoreCache" param is set', () => { | ||
let first; | ||
let second; | ||
// We expect two requests | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}`).respond(200, data); | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}`).respond(200, data); | ||
// Clear the cache first | ||
$localDb.clear(service._getCacheKey()); | ||
// First call | ||
service.fetch({ignoreCache: true}) | ||
.then((res) => { | ||
first = res.docs; | ||
// Second call | ||
return service.fetch({ignoreCache: true}); | ||
}) | ||
.then((res) => { | ||
second = res.docs; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(first).to.deep.equal(data.docs); | ||
expect(second).to.deep.equal(data.docs); | ||
}); | ||
it('should issue a GET request to "/collection"', () => { | ||
$httpBackend.expectGET(`/${service._getUrlPredicate()}`).respond(200, data); | ||
// Clear the cache first | ||
$localDb.clear(service._getCacheKey()); | ||
service.fetch(); | ||
$httpBackend.flush(); | ||
}); | ||
}); | ||
describe('httpCache.prototype.create method', () => { | ||
let service; | ||
const doc = { | ||
id: 1, | ||
str: 'string', | ||
num: 100.99 | ||
}; | ||
const response = { | ||
doc: doc | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.create).to.be.a('function'); | ||
}); | ||
it('should reject if data is missing', () => { | ||
expect(service.create()).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should issue a POST request to "/collection"', () => { | ||
$httpBackend.expectPOST(`/${service._getUrlPredicate()}`).respond(200, response); | ||
let actual; | ||
service.create(doc) | ||
.then((_doc) => { | ||
actual = _doc; | ||
}) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
expect(actual).to.deep.equal(doc); | ||
}); | ||
it('should return an object', () => { | ||
let actual; | ||
$httpBackend.expectPOST(`/${service._getUrlPredicate()}`).respond(200, response); | ||
service.create(doc) | ||
.then((_doc) => { | ||
actual = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(actual).to.deep.equal(doc); | ||
}); | ||
it('should cache created doc', () => { | ||
let created; | ||
let cached; | ||
$httpBackend.expectPOST(`/${service._getUrlPredicate()}`).respond(200, response); | ||
service.create(doc) | ||
.then((_doc) => { | ||
created = _doc; | ||
return service.get(_doc.id); | ||
}) | ||
.then((_doc) => { | ||
cached = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(created).to.deep.equal(doc); | ||
expect(cached).to.deep.equal(doc); | ||
}); | ||
}); | ||
describe('httpCache.prototype.update method', () => { | ||
let service; | ||
const doc = { | ||
id: 1, | ||
str: 'string', | ||
num: 100.99 | ||
}; | ||
const response = { | ||
doc: doc | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.update).to.be.a('function'); | ||
}); | ||
it('should reject if doc is missing', () => { | ||
expect(service.update()).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should issue a POST request to "/collection/:id"', () => { | ||
$httpBackend.expectPUT(`/${service._getUrlPredicate()}/${doc.id}`).respond(200, response); | ||
let actual; | ||
service.update(doc) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
}); | ||
it('should return updated doc', () => { | ||
let updatedDoc; | ||
$httpBackend.expectPUT(`/${service._getUrlPredicate()}/${doc.id}`).respond(200, response); | ||
service.update(doc) | ||
.then((_doc) => { | ||
updatedDoc = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(updatedDoc).to.deep.equal(doc); | ||
}); | ||
it('should cache updated doc', () => { | ||
let updatedDoc; | ||
let cached; | ||
$httpBackend.expectPUT(`/${service._getUrlPredicate()}/${doc.id}`).respond(200, response); | ||
service.update(doc) | ||
.then((_doc) => { | ||
updatedDoc = _doc; | ||
return service.get(_doc.id); | ||
}) | ||
.then((_doc) => { | ||
cached = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(updatedDoc).to.deep.equal(doc); | ||
expect(cached).to.deep.equal(doc); | ||
}); | ||
}); | ||
describe('httpCache.prototype.patch method', () => { | ||
let service; | ||
const doc = { | ||
id: 1, | ||
str: 'string', | ||
num: 100.99 | ||
}; | ||
const response = { | ||
doc: doc | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.patch).to.be.a('function'); | ||
}); | ||
it('should reject if any of the parameters is missing', () => { | ||
expect(service.update()).to.eventually.be.rejectedWith(Error); | ||
expect(service.update(doc.id)).to.eventually.be.rejectedWith(Error); | ||
expect(service.update(doc.id, 'str')).to.eventually.be.rejectedWith(Error); | ||
expect(service.update(doc.id, null, 'newvalue')).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should issue a PATCH request to "/collection/:id"', () => { | ||
const prop = 'str'; | ||
const value = 'newvalue'; | ||
const _data = { | ||
prop: prop, | ||
value: value | ||
}; | ||
$httpBackend.expectPATCH(`/${service._getUrlPredicate()}/${doc.id}`, _data).respond(200, response); | ||
let actual; | ||
service.patch(doc.id, prop, value) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
}); | ||
it('should return patched doc', () => { | ||
const prop = 'str'; | ||
const value = 'newvalue'; | ||
const _data = { | ||
prop: prop, | ||
value: value | ||
}; | ||
let patchedDoc; | ||
const response = { | ||
doc: doc | ||
}; | ||
response.doc[prop] = value; | ||
$httpBackend.expectPATCH(`/${service._getUrlPredicate()}/${doc.id}`, _data).respond(200, response); | ||
service.patch(doc.id, prop, value) | ||
.then((_doc) => { | ||
patchedDoc = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(patchedDoc).to.be.an('object'); | ||
expect(patchedDoc[prop]).to.equal(value); | ||
}); | ||
it('should cache patched doc', () => { | ||
const prop = 'str'; | ||
const value = 'newvalue'; | ||
const _data = { | ||
prop: prop, | ||
value: value | ||
}; | ||
let patchedDoc; | ||
let cached; | ||
const response = { | ||
doc: doc | ||
}; | ||
response.doc[prop] = value; | ||
$httpBackend.expectPATCH(`/${service._getUrlPredicate()}/${doc.id}`, _data).respond(200, response); | ||
service.patch(doc.id, prop, value) | ||
.then((_doc) => { | ||
patchedDoc = _doc; | ||
return service.get(_doc.id); | ||
}) | ||
.then((_doc) => { | ||
cached = _doc; | ||
}) | ||
.catch((e) => { | ||
throw e; | ||
}); | ||
$httpBackend.flush(); | ||
expect(patchedDoc).to.be.an('object'); | ||
expect(patchedDoc[prop]).to.equal(value); | ||
expect(cached).to.be.an('object'); | ||
expect(cached[prop]).to.equal(value); | ||
}); | ||
}); | ||
describe('httpCache.prototype.delete method', () => { | ||
let service; | ||
const doc = { | ||
id: 1, | ||
str: 'string', | ||
num: 100.99 | ||
}; | ||
const response = { | ||
doc: doc | ||
}; | ||
beforeEach(() => { | ||
service = $httpCache({collection: 'users', caching: true}); | ||
}); | ||
afterEach(function () { | ||
$httpBackend.verifyNoOutstandingExpectation(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
it('should exist', () => { | ||
expect(service.delete).to.be.a('function'); | ||
}); | ||
it('should reject if doc.id is missing', () => { | ||
expect(service.delete()).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should issue a DELETE request to "/collection/:id"', () => { | ||
$httpBackend.expectDELETE(`/${service._getUrlPredicate()}/${doc.id}`).respond(200); | ||
let actual; | ||
service.delete(doc.id) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
}); | ||
it('should return true on success', () => { | ||
$httpBackend.expectDELETE(`/${service._getUrlPredicate()}/${doc.id}`).respond(200); | ||
let actual; | ||
service.delete(doc.id) | ||
.then((res) => { | ||
actual = res; | ||
}) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
expect(actual).to.equal(true); | ||
}); | ||
it('should remove doc cache', () => { | ||
service._handleDoc(doc); | ||
let cached = $localDb.getIndex(service._getCacheKey(), doc.id); | ||
expect(cached).to.deep.equal(doc); | ||
$httpBackend.expectDELETE(`/${service._getUrlPredicate()}/${doc.id}`).respond(200); | ||
service.delete(doc.id) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
$httpBackend.flush(); | ||
cached = $localDb.getIndex(service._getCacheKey(), doc.id); | ||
expect(cached).to.not.exist; | ||
}); | ||
}); | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
48934
13
1289
12
1