From ae4c2298f15f6a36db68c92c0eeea19f08f967a7 Mon Sep 17 00:00:00 2001 From: Bogdan Abaev Date: Thu, 9 Apr 2026 16:31:26 -0700 Subject: [PATCH] connector server: handle metadata edits from popup Handle updates to metadata sent by the connector popup. Needed for: https://github.com/zotero/zotero-connectors/pull/615 --- .../zotero/xpcom/server/server_connector.js | 13 +++ test/tests/server_connectorTest.js | 109 ++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/chrome/content/zotero/xpcom/server/server_connector.js b/chrome/content/zotero/xpcom/server/server_connector.js index a88c9618c3..1bc19daa1d 100644 --- a/chrome/content/zotero/xpcom/server/server_connector.js +++ b/chrome/content/zotero/xpcom/server/server_connector.js @@ -776,6 +776,18 @@ Zotero.Server.Connector.UpdateSession.prototype = { await session.update(data.target, tags, note); + if (data.updatedMetadata) { + let item = session.getItemByConnectorKey(data.updatedMetadata.id); + if (item) { + for (let field of data.updatedMetadata.fields) { + if (field.name === 'itemType') continue; + item.setField(field.name, field.value); + } + item.setCreators(data.updatedMetadata.creators || []); + await item.saveTx(); + } + } + return [200, "application/json", JSON.stringify({})]; } }; @@ -1114,6 +1126,7 @@ Zotero.Server.Connector.Ping.prototype = { downloadAssociatedFiles: Zotero.Prefs.get("downloadAssociatedFiles"), supportsAttachmentUpload: true, supportsTagsAutocomplete: true, + supportsMetadataUpdates: true, googleDocsAddNoteEnabled: true, googleDocsAddAnnotationEnabled: true, canUserAddNote: true, diff --git a/test/tests/server_connectorTest.js b/test/tests/server_connectorTest.js index 165235b016..967eed6963 100644 --- a/test/tests/server_connectorTest.js +++ b/test/tests/server_connectorTest.js @@ -1074,6 +1074,115 @@ describe("Connector Server", function () { assert.equal(note.getNote(), "Test note"); }); + it("should update metadata of item saved via /saveItems", async function () { + var collection = await createDataObject('collection'); + await select(win, collection); + + const id = Zotero.Utilities.randomString(); + var sessionID = Zotero.Utilities.randomString(); + var body = { + sessionID, + items: [ + { + itemType: "newspaperArticle", + title: "Title", + id, + creators: [ + { + firstName: "First", + lastName: "Last", + creatorType: "author" + } + ] + } + ], + uri: "http://example.com" + }; + + var reqPromise = httpRequest( + 'POST', + connectorServerPath + "/connector/saveItems", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + } + ); + + var ids = await waitForItemEvent('add'); + var item = Zotero.Items.get(ids[0]); + var req = await reqPromise; + assert.equal(req.status, 201); + assert.equal(item.getField('title'), "Title"); + + // Update metadata + req = await httpRequest( + 'POST', + connectorServerPath + "/connector/updateSession", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + target: collection.treeViewID, + tags: "", + note: "", + updatedMetadata: { + id, + fields: [ + { + name: "itemType", + label: "Item Type", + value: "newspaperArticle" + }, + { + name: "title", + label: "Title", + value: "Updated Title" + }, + { + name: "abstractNote", + label: "Abstract", + value: "Updated abstract" + }, + { + name: "date", + label: "Date", + value: "2026-04-08" + }, + { + name: "url", + label: "URL", + value: "http://example.com/updated" + } + ], + creators: [ + { + firstName: "New First", + lastName: "New Last", + creatorType: "author" + } + ] + } + }) + } + ); + + assert.equal(req.status, 200); + assert.equal(item.getField('title'), "Updated Title"); + assert.equal(item.getField('abstractNote'), "Updated abstract"); + assert.equal(item.getField('date'), "2026-04-08"); + assert.equal(item.getField('url'), "http://example.com/updated"); + var creators = item.getCreators(); + assert.equal(creators.length, 1); + assert.equal(creators[0].firstName, "New First"); + assert.equal(creators[0].lastName, "New Last"); + // Verify collection is preserved + assert.isTrue(collection.hasItem(item.id)); + }); + it("should update collections and tags of a PDF saved via /saveStandaloneAttachment", async function () { const sessionID = Zotero.Utilities.randomString();