From 1a83f93ae7916f2b9b06d776471e9fcb8e44a3db Mon Sep 17 00:00:00 2001 From: Mike Eldridge Date: Fri, 2 Feb 2018 00:17:02 -0600 Subject: [PATCH] if usePendingFind or usePendingFindAll is disabled, disable storing pending queries in the corresponding pendingQueries cache (ref #364) --- bower.json | 4 +- src/datastore/async_methods/find.js | 13 ++++-- src/datastore/async_methods/findAll.js | 13 ++++-- .../datastore/async_methods/find.test.js | 42 ++++++++++++++++++- .../datastore/async_methods/findAll.test.js | 40 ++++++++++++++++++ 5 files changed, 103 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index bc5f22bf..ef7f79e3 100644 --- a/bower.json +++ b/bower.json @@ -28,7 +28,7 @@ ], "devDependencies": { "observe-js": "0.5.5", - "js-data-http": ">=2.0.0", - "js-data-localstorage": ">=2.0.0" + "js-data-http": "^2.0.0", + "js-data-localstorage": "^2.0.0" } } diff --git a/src/datastore/async_methods/find.js b/src/datastore/async_methods/find.js index 57763c01..995604ff 100644 --- a/src/datastore/async_methods/find.js +++ b/src/datastore/async_methods/find.js @@ -54,8 +54,9 @@ module.exports = function find (resourceName, id, options) { } }).then(function (item) { if (!item) { + let query const usePendingFind = DSUtils.isFunction(options.usePendingFind) ? options.usePendingFind.call(this, resourceName, id, options) : options.usePendingFind - if (!(id in resource.pendingQueries) && usePendingFind) { + if (!(id in resource.pendingQueries) || !usePendingFind) { let promise let strategy = options.findStrategy || options.strategy @@ -80,7 +81,7 @@ module.exports = function find (resourceName, id, options) { promise = _this.adapters[adapter].find(definition, id, options) } - resource.pendingQueries[id] = promise + query = promise .then(function (data) { return options.afterFind.call(data, options, data) }) .then(function (data) { // Query is no longer pending @@ -97,8 +98,14 @@ module.exports = function find (resourceName, id, options) { return definition.createInstance(data, options.orig()) } }) + + if (usePendingFind) { + resource.pendingQueries[id] = query + } + } else { + query = resource.pendingQueries[id] } - return resource.pendingQueries[id] + return query } else { // resolve immediately with the item return item diff --git a/src/datastore/async_methods/findAll.js b/src/datastore/async_methods/findAll.js index 9132aa3c..74eddd8b 100644 --- a/src/datastore/async_methods/findAll.js +++ b/src/datastore/async_methods/findAll.js @@ -97,8 +97,9 @@ module.exports = function findAll (resourceName, params, options) { } }).then(function (items) { if (!items) { + let query const usePendingFindAll = DSUtils.isFunction(options.usePendingFindAll) ? options.usePendingFindAll.call(this, resourceName, params, options) : options.usePendingFindAll - if (!(queryHash in resource.pendingQueries) && usePendingFindAll) { + if (!(queryHash in resource.pendingQueries) || !usePendingFindAll) { let promise let strategy = options.findAllStrategy || options.strategy @@ -123,7 +124,7 @@ module.exports = function findAll (resourceName, params, options) { promise = _this.adapters[adapter].findAll(definition, params, options) } - resource.pendingQueries[queryHash] = promise + query = promise .then(function (data) { return options.afterFindAll.call(data, options, data) }) .then(function (data) { // Query is no longer pending @@ -140,9 +141,15 @@ module.exports = function findAll (resourceName, params, options) { return data } }) + + if (usePendingFindAll) { + resource.pendingQueries[queryHash] = query + } + } else { + query = resource.pendingQueries[queryHash] } - return resource.pendingQueries[queryHash] + return query } else { // resolve immediately with the items return items diff --git a/test/browser/datastore/async_methods/find.test.js b/test/browser/datastore/async_methods/find.test.js index efb00539..2c06dd3a 100644 --- a/test/browser/datastore/async_methods/find.test.js +++ b/test/browser/datastore/async_methods/find.test.js @@ -15,7 +15,7 @@ describe('DS#find', function () { // Should have no effect because there is already a pending query return Post.find(5) .then(function (post) { - assert.deepEqual(JSON.stringify(post), JSON.stringify(p1)); + assert.deepEqual(JSON.stringify(post), JSON.stringify(p1), 'Post.find result'); assert.deepEqual(JSON.stringify(Post.get(5)), JSON.stringify(p1), 'The post is now in the datastore'); assert.isNumber(Post.lastModified(5)); assert.isNumber(Post.lastSaved(5)); @@ -435,4 +435,44 @@ describe('DS#find', function () { assert.equal(lifecycle.deserialize.callCount, 2, 'deserialize should have been called'); }); }); + + it('should track pending queries if usePendingFind is enabled', function () { + var _this = this; + + Post.ejectAll(); + + var promise = Post.find(5, { usePendingFind : true }); + + setTimeout(function () { + assert.equal(1, _this.requests.length, 'has pending request'); + assert.equal(_this.requests[0].url, 'http://test.js-data.io/posts/5', 'pending request url'); + assert.equal(_this.requests[0].method, 'GET', 'pending request method'); + assert.deepEqual(Object.keys(store.store.post.pendingQueries), ['5'], 'pending query list contains hashed query'); + _this.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify(p1)); + }, 100); + + return promise.then(function (data) { + assert.equal(JSON.stringify(data), JSON.stringify(p1), 'response data'); + }); + }); + + it('should not track pending queries if usePendingFind is disabled', function () { + var _this = this; + + Post.ejectAll(); + + var promise = Post.find(5, { usePendingFind : false }); + + setTimeout(function () { + assert.equal(1, _this.requests.length, 'has pending request'); + assert.equal(_this.requests[0].url, 'http://test.js-data.io/posts/5', 'pending request url'); + assert.equal(_this.requests[0].method, 'GET', 'pending request method'); + assert.deepEqual(Object.keys(store.store.post.pendingQueries), [], 'pending query list is empty'); + _this.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify(p1)); + }, 100); + + return promise.then(function (data) { + assert.equal(JSON.stringify(data), JSON.stringify(p1), 'response data'); + }); + }); }); diff --git a/test/browser/datastore/async_methods/findAll.test.js b/test/browser/datastore/async_methods/findAll.test.js index d6c63ba3..3c11f7c0 100644 --- a/test/browser/datastore/async_methods/findAll.test.js +++ b/test/browser/datastore/async_methods/findAll.test.js @@ -465,4 +465,44 @@ describe('DS#findAll', function () { assert.equal(p.length, 3); }); }); + + it('should track pending queries if usePendingFindAll is enabled', function () { + var _this = this; + + Post.ejectAll(); + + var promise = Post.findAll(null, { usePendingFindAll : true }); + + setTimeout(function () { + assert.equal(1, _this.requests.length, 'has pending request'); + assert.equal(_this.requests[0].url, 'http://test.js-data.io/posts', 'pending request url'); + assert.equal(_this.requests[0].method, 'GET', 'pending request method'); + assert.deepEqual(Object.keys(store.store.post.pendingQueries), ['{}'], 'pending query list contains hashed query'); + _this.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify([p1, p2, p3, p4])); + }, 100); + + return promise.then(function (data) { + assert.equal(JSON.stringify(data), JSON.stringify([p1, p2, p3, p4])); + }); + }); + + it('should not track pending queries if usePendingFindAll is disabled', function () { + var _this = this; + + Post.ejectAll(); + + var promise = Post.findAll(null, { usePendingFindAll : false }); + + setTimeout(function () { + assert.equal(1, _this.requests.length, 'has pending request'); + assert.equal(_this.requests[0].url, 'http://test.js-data.io/posts', 'pending request url'); + assert.equal(_this.requests[0].method, 'GET', 'pending request method'); + assert.deepEqual(Object.keys(store.store.post.pendingQueries), [], 'pending query list is empty'); + _this.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify([p1, p2, p3, p4])); + }, 100); + + return promise.then(function (data) { + assert.equal(JSON.stringify(data), JSON.stringify([p1, p2, p3, p4])); + }); + }); });