diff --git a/chrome/content/zotero/xpcom/retractions.js b/chrome/content/zotero/xpcom/retractions.js index 89f8a47cbf..32e4d561b9 100644 --- a/chrome/content/zotero/xpcom/retractions.js +++ b/chrome/content/zotero/xpcom/retractions.js @@ -525,9 +525,10 @@ Zotero.Retractions = { return; } - // Download list + // Download list. Skip the conditional request if the cached list was saved by a + // different version, so that a version bump forces a full refresh of stored data. var headers = {}; - if (this._cacheETag) { + if (this._cacheETag && this._cacheVersion == this._version) { headers["If-None-Match"] = this._cacheETag; } var req = await Zotero.HTTP.request( diff --git a/test/tests/retractionsTest.js b/test/tests/retractionsTest.js index 434e280c9f..a575bd54d7 100644 --- a/test/tests/retractionsTest.js +++ b/test/tests/retractionsTest.js @@ -199,6 +199,64 @@ describe("Retractions", function () { assert.isFalse(Zotero.Retractions.isRetracted(item)); }); + + it("should refresh stored data for a version bump when the list is unchanged", async function () { + var doi = '10.1234/cdefg'; + var hash = Zotero.Utilities.Internal.sha1(doi); + var line = Zotero.Retractions.TYPE_DOI + hash.substr(0, 5) + ' 12345\n'; + var version = Zotero.Retractions._version; + var reason = "Error in Data"; + + server.respond(function (req) { + if (req.method == 'GET' && req.url == baseURL + 'list') { + // The list itself never changes, so a conditional request gets a 304 + if (req.requestHeaders['If-None-Match'] == 'unchanged') { + req.respond(304, {}, ''); + return; + } + req.respond(200, { 'Content-Type': 'text/plain', 'ETag': 'unchanged' }, line); + } + else if (req.method == 'POST' && req.url == baseURL + 'search') { + req.respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify([ + { + doi: hash, + retractionDOI: '10.1234/defgh', + date: '2019-01-02', + reasons: [reason], + urls: [] + } + ]) + ); + } + }); + + try { + await Zotero.Retractions.updateFromServer(); + + let promise = waitForItemEvent('refresh'); + let item = createUnsavedDataObject('item', { itemType: 'journalArticle' }); + item.setField('DOI', doi); + await item.saveTx(); + await promise; + assert.sameMembers((await Zotero.Retractions.getData(item)).reasons, [reason]); + + // An update with the same version gets a 304 and leaves the stored data alone + reason = "Error in Text"; + await Zotero.Retractions.updateFromServer(); + assert.sameMembers((await Zotero.Retractions.getData(item)).reasons, ["Error in Data"]); + + // A version bump skips the conditional request and rewrites it + Zotero.Retractions._version = version + 1; + await Zotero.Retractions.updateFromServer(); + assert.sameMembers((await Zotero.Retractions.getData(item)).reasons, [reason]); + } + finally { + Zotero.Retractions._version = version; + } + }); });