Fix additional file sync error with no remote stored hash

Follow-up to c9694e93b0
This commit is contained in:
Dan Stillman 2017-02-08 14:12:16 -05:00
parent 1ea80c4352
commit 12ad749087
2 changed files with 87 additions and 68 deletions

View file

@ -412,6 +412,7 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = {
} }
delete headers["If-Match"]; delete headers["If-Match"];
headers["If-None-Match"] = "*"; headers["If-None-Match"] = "*";
storedHash = null;
Zotero.debug("Retrying with If-None-Match"); Zotero.debug("Retrying with If-None-Match");
} }
else { else {
@ -728,7 +729,8 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = {
successCodes: [204], successCodes: [204],
requestObserver: function (xmlhttp) { requestObserver: function (xmlhttp) {
request.setChannel(xmlhttp.channel); request.setChannel(xmlhttp.channel);
} },
debug: true
} }
); );
} }

View file

@ -670,6 +670,90 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.equal(item.attachmentSyncedHash, hash); assert.equal(item.attachmentSyncedHash, hash);
assert.equal(item.version, newVersion); 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); 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* () { it("should handle 413 on quota limit", function* () {
var { engine, client, caller } = yield setup(); var { engine, client, caller } = yield setup();