Save uploaded objects to the sync cache on an unchanged response

The cache-existence check didn't await getCacheObject(), so the
promise was always truthy and no cache object was ever saved for
objects the server reported as unchanged. Without a cached version,
later remote changes to those objects produced avoidable conflicts.
This commit is contained in:
Dan Stillman 2026-07-29 00:06:42 -04:00
parent 2fb8d69a93
commit ae98136ec8
2 changed files with 45 additions and 1 deletions

View file

@ -1428,7 +1428,7 @@ Zotero.Sync.Data.Engine.prototype._uploadObjects = async function (objectType, i
// in batches and we only get the final version, but it will guarantee that
// the object won't be redownloaded unnecessarily in the case of a full sync,
// because the version will be higher than whatever version is on the server.
let hasCacheObject = !!Zotero.Sync.Data.Local.getCacheObject(
let hasCacheObject = !!await Zotero.Sync.Data.Local.getCacheObject(
objectType, obj.libraryID, obj.key, obj.version
);
if (!hasCacheObject) {

View file

@ -866,6 +866,50 @@ describe("Zotero.Sync.Data.Engine", function () {
});
it("should save uploaded object to cache after upload on 'unchanged' response", async function () {
({ engine, client, caller } = await setup());
var library = Zotero.Libraries.userLibrary;
var lastLibraryVersion = 5;
library.libraryVersion = lastLibraryVersion;
await library.saveTx();
var item = await createDataObject('item', { version: 1, title: "A" });
server.respond(function (req) {
if (req.method == "POST" && req.url == baseURL + "users/1/items") {
req.respond(
200,
{
"Content-Type": "application/json",
"Last-Modified-Version": ++lastLibraryVersion
},
JSON.stringify({
successful: {},
unchanged: {
"0": item.key
},
failed: {}
})
);
return;
}
});
await engine.start();
// Uploaded data should be saved to the cache with the new library version
var version = await Zotero.Sync.Data.Local.getLatestCacheObjectVersion(
'item', library.id, item.key
);
assert.equal(version, lastLibraryVersion);
var json = await Zotero.Sync.Data.Local.getCacheObject(
'item', library.id, item.key, lastLibraryVersion
);
assert.propertyVal(json.data, 'title', 'A');
});
it("should upload child collection after parent collection", async function () {
({ engine, client, caller } = await setup());