diff --git a/chrome/content/zotero/xpcom/connector/server_connector.js b/chrome/content/zotero/xpcom/connector/server_connector.js index b2b33778b4..dd891125ed 100644 --- a/chrome/content/zotero/xpcom/connector/server_connector.js +++ b/chrome/content/zotero/xpcom/connector/server_connector.js @@ -265,8 +265,13 @@ Zotero.Server.Connector.SaveSession.prototype.update = async function (targetID, await item.eraseTx(); } let actionUC = Zotero.Utilities.capitalize(this._action); - let newItems = await Zotero.Server.Connector[actionUC].prototype[this._action]( - targetID, this._requestData + // saveItems has a different signature with the session as the first argument + let params = [targetID, this._requestData]; + if (this._action == 'saveItems') { + params.unshift(this); + } + let newItems = await Zotero.Server.Connector[actionUC].prototype[this._action].apply( + Zotero.Server.Connector[actionUC], params ); // saveSnapshot only returns a single item if (this._action == 'saveSnapshot') { diff --git a/test/tests/server_connectorTest.js b/test/tests/server_connectorTest.js index 41992da77c..d90f9ddf8d 100644 --- a/test/tests/server_connectorTest.js +++ b/test/tests/server_connectorTest.js @@ -1132,6 +1132,191 @@ describe("Connector Server", function () { assert.isTrue(item.hasTag("A")); assert.isTrue(item.hasTag("B")); }); + + it("should move item saved via /saveItems to another library", async function () { + var group = await createGroup({ editable: true, filesEditable: false }); + await selectLibrary(win); + await waitForItemsLoad(win); + + var sessionID = Zotero.Utilities.randomString(); + var body = { + sessionID, + items: [ + { + itemType: "newspaperArticle", + title: "Title", + attachments: [ + { + title: "Attachment", + url: `${testServerPath}/attachment`, + mimeType: "text/html" + } + ] + } + ], + uri: "http://example.com" + }; + + httpd.registerPathHandler( + "/attachment", + { + handle: function (request, response) { + response.setStatusLine(null, 200, "OK"); + response.write("TitleBody"); + } + } + ); + + var reqPromise = Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/saveItems", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + } + ); + + var ids1 = await waitForItemEvent('add'); + var item1 = Zotero.Items.get(ids1[0]); + await waitForItemEvent('add'); + + var req = await reqPromise; + assert.equal(req.status, 201); + + // Move item to group without file attachment + reqPromise = Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/updateSession", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + target: group.treeViewID + }) + } + ); + + var ids2 = await waitForItemEvent('add'); + var item2 = Zotero.Items.get(ids2[0]); + + req = await reqPromise; + assert.equal(req.status, 200); + assert.isFalse(Zotero.Items.exists(item1.id)); + assert.equal(item2.libraryID, group.libraryID); + assert.equal(item2.numAttachments(), 0); + + // Move back to My Library and resave attachment + reqPromise = Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/updateSession", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + target: Zotero.Libraries.userLibrary.treeViewID + }) + } + ); + + var ids3 = await waitForItemEvent('add'); + var item3 = Zotero.Items.get(ids3[0]); + await waitForItemEvent('add'); + + req = await reqPromise; + assert.equal(req.status, 200); + assert.isFalse(Zotero.Items.exists(item2.id)); + assert.equal(item3.libraryID, Zotero.Libraries.userLibraryID); + assert.equal(item3.numAttachments(), 1); + }); + + it("should move item saved via /saveSnapshot to another library", async function () { + var group = await createGroup({ editable: true, filesEditable: false }); + await selectLibrary(win); + await waitForItemsLoad(win); + var sessionID = Zotero.Utilities.randomString(); + + // saveSnapshot saves parent and child before returning + var ids1; + var promise = waitForItemEvent('add').then(function (ids) { + ids1 = ids; + return waitForItemEvent('add').then(function (ids) { + ids1 = ids1.concat(ids); + }); + }); + await Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/saveSnapshot", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + url: "http://example.com", + html: "TitleBody" + }) + } + ); + + assert.isTrue(promise.isFulfilled()); + + var item1 = Zotero.Items.get(ids1[0]); + + // Move item to group without file attachment + var reqPromise = Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/updateSession", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + target: group.treeViewID + }) + } + ); + + var ids2 = await waitForItemEvent('add'); + var item2 = Zotero.Items.get(ids2[0]); + + var req = await reqPromise; + assert.equal(req.status, 200); + assert.isFalse(Zotero.Items.exists(item1.id)); + assert.equal(item2.libraryID, group.libraryID); + assert.equal(item2.numAttachments(), 0); + + // Move back to My Library and resave attachment + reqPromise = Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/updateSession", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + sessionID, + target: Zotero.Libraries.userLibrary.treeViewID + }) + } + ); + + var ids3 = await waitForItemEvent('add'); + var item3 = Zotero.Items.get(ids3[0]); + await waitForItemEvent('add'); + + req = await reqPromise; + assert.equal(req.status, 200); + assert.isFalse(Zotero.Items.exists(item2.id)); + assert.equal(item3.libraryID, Zotero.Libraries.userLibraryID); + assert.equal(item3.numAttachments(), 1); + }); }); describe('/connector/installStyle', function() {