From 12ad74908740abc8f64a6d5394f1c3af06fd2732 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Wed, 8 Feb 2017 14:12:16 -0500 Subject: [PATCH] Fix additional file sync error with no remote stored hash Follow-up to c9694e93b0 --- chrome/content/zotero/xpcom/storage/zfs.js | 4 +- test/tests/zfsTest.js | 151 ++++++++++++--------- 2 files changed, 87 insertions(+), 68 deletions(-) diff --git a/chrome/content/zotero/xpcom/storage/zfs.js b/chrome/content/zotero/xpcom/storage/zfs.js index 7a9d505828..d984f08aad 100644 --- a/chrome/content/zotero/xpcom/storage/zfs.js +++ b/chrome/content/zotero/xpcom/storage/zfs.js @@ -412,6 +412,7 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = { } delete headers["If-Match"]; headers["If-None-Match"] = "*"; + storedHash = null; Zotero.debug("Retrying with If-None-Match"); } else { @@ -728,7 +729,8 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = { successCodes: [204], requestObserver: function (xmlhttp) { request.setChannel(xmlhttp.channel); - } + }, + debug: true } ); } diff --git a/test/tests/zfsTest.js b/test/tests/zfsTest.js index 271a3be48e..97978e56a6 100644 --- a/test/tests/zfsTest.js +++ b/test/tests/zfsTest.js @@ -670,6 +670,90 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () { assert.equal(item.attachmentSyncedHash, hash); assert.equal(item.version, newVersion); }) + + + it("should retry with If-None-Match on 412 with missing remote hash", function* () { + var { engine, client, caller } = yield setup(); + var zfs = new Zotero.Sync.Storage.Mode.ZFS({ + apiClient: client + }) + + var file = getTestDataDirectory(); + file.append('test.png'); + var item = yield Zotero.Attachments.importFromFile({ file }); + item.version = 5; + item.synced = true; + item.attachmentSyncedModificationTime = Date.now(); + item.attachmentSyncedHash = 'bd4c33e03798a7e8bc0b46f8bda74fac' + yield item.saveTx(); + + var contentType = 'image/png'; + var prefix = Zotero.Utilities.randomString(); + var suffix = Zotero.Utilities.randomString(); + var uploadKey = Zotero.Utilities.randomString(32, 'abcdef0123456789'); + + var called = 0; + // https://github.com/cjohansen/Sinon.JS/issues/607 + let fixSinonBug = ";charset=utf-8"; + server.respond(function (req) { + // Try with If-Match + if (req.method == "POST" + && req.url == `${baseURL}users/1/items/${item.key}/file` + && !req.requestBody.includes('upload=') + && req.requestHeaders["If-Match"] == item.attachmentSyncedHash) { + called++; + req.respond( + 412, + { + "Content-Type": "application/json" + }, + "If-Match set but file does not exist" + ); + } + // Retry with If-None-Match + else if (req.method == "POST" + && req.url == `${baseURL}users/1/items/${item.key}/file` + && !req.requestBody.includes('upload=') + && req.requestHeaders["If-None-Match"] == "*") { + assert.equal(called++, 1); + req.respond( + 200, + { + "Content-Type": "application/json" + }, + JSON.stringify({ + url: baseURL + "pretend-s3/1", + contentType: contentType, + prefix: prefix, + suffix: suffix, + uploadKey: uploadKey + }) + ); + } + // Upload file to S3 + else if (req.method == "POST" && req.url == baseURL + "pretend-s3/1") { + assert.equal(called++, 2); + req.respond(201, {}, ""); + } + // Use If-None-Match when registering upload + else if (req.method == "POST" + && req.url == `${baseURL}users/1/items/${item.key}/file` + && req.requestBody.includes('upload=')) { + assert.equal(called++, 3); + assert.equal(req.requestHeaders["If-None-Match"], "*"); + req.respond( + 204, + { + "Last-Modified-Version": 10 + }, + "" + ); + } + }); + + var result = yield engine.start(); + assert.equal(called, 4); + }); }) @@ -819,73 +903,6 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () { assert.isTrue(result.syncRequired); }); - it("should retry with If-None-Match on 412 with missing remote hash", function* () { - var { engine, client, caller } = yield setup(); - var zfs = new Zotero.Sync.Storage.Mode.ZFS({ - apiClient: client - }) - - var file = getTestDataDirectory(); - file.append('test.png'); - var item = yield Zotero.Attachments.importFromFile({ file }); - item.version = 5; - item.synced = true; - item.attachmentSyncedModificationTime = Date.now(); - item.attachmentSyncedHash = 'bd4c33e03798a7e8bc0b46f8bda74fac' - yield item.saveTx(); - - var contentType = 'image/png'; - var prefix = Zotero.Utilities.randomString(); - var suffix = Zotero.Utilities.randomString(); - var uploadKey = Zotero.Utilities.randomString(32, 'abcdef0123456789'); - - var called = 0; - server.respond(function (req) { - if (req.method == "POST" - && req.url == `${baseURL}users/1/items/${item.key}/file` - && !req.requestBody.includes('upload=') - && req.requestHeaders["If-Match"] == item.attachmentSyncedHash) { - called++; - req.respond( - 412, - { - "Content-Type": "application/json" - }, - "If-Match set but file does not exist" - ); - } - else if (req.method == "POST" - && req.url == `${baseURL}users/1/items/${item.key}/file` - && !req.requestBody.includes('upload=') - && req.requestHeaders["If-None-Match"] == "*") { - assert.equal(called++, 1) - req.respond( - 200, - { - "Content-Type": "application/json" - }, - JSON.stringify({ - url: baseURL + "pretend-s3/1", - contentType: contentType, - prefix: prefix, - suffix: suffix, - uploadKey: uploadKey - }) - ); - } - }) - - var stub = sinon.stub(zfs, "_uploadFile"); - - yield zfs._processUploadFile({ - name: item.libraryKey - }); - - assert.equal(called, 2); - assert.ok(stub.called); - - stub.restore(); - }); it("should handle 413 on quota limit", function* () { var { engine, client, caller } = yield setup();