diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js index aa26f30b5..9696e75f2 100644 --- a/chrome/content/zotero/xpcom/collectionTreeView.js +++ b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -1340,7 +1340,7 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi /** - * Returns libraryID or FALSE if not a library + * Return libraryID of selected row (which could be a collection, etc.) */ Zotero.CollectionTreeView.prototype.getSelectedLibraryID = function() { if (!this.selection || !this.selection.count || this.selection.currentIndex == -1) return false; diff --git a/chrome/content/zotero/xpcom/server_connector.js b/chrome/content/zotero/xpcom/server_connector.js index e2e69b9f0..bb6a33799 100644 --- a/chrome/content/zotero/xpcom/server_connector.js +++ b/chrome/content/zotero/xpcom/server_connector.js @@ -333,16 +333,39 @@ Zotero.Server.Connector.SaveItem.prototype = { * @param {Object} data POST data or GET query string * @param {Function} sendResponseCallback function to send HTTP response */ - "init":function(url, data, sendResponseCallback) { + "init": Zotero.Promise.coroutine(function* (url, data, sendResponseCallback) { // figure out where to save - var libraryID = null; - var collectionID = null; var zp = Zotero.getActiveZoteroPane(); try { var libraryID = zp.getSelectedLibraryID(); var collection = zp.getSelectedCollection(); } catch(e) {} + // Default to My Library if present if pane not yet opened + if (!libraryID) { + let userLibrary = Zotero.Libraries.userLibrary; + if (userLibrary) { + libraryID = userLibrary.id; + } + } + + // If library isn't editable (or directly editable, in the case of My Publications), switch to + // My Library if present and editable, and otherwise fail + var library = Zotero.Libraries.get(libraryID); + if (!library.editable || library.libraryType == 'publications') { + let userLibrary = Zotero.Libraries.userLibrary; + if (userLibrary && userLibrary.editable) { + yield zp.collectionsView.selectLibrary(userLibrary.id); + libraryID = userLibrary.id; + collection = null; + } + else { + Zotero.logError("Can't add item to read-only library " + library.name); + sendResponseCallback(500); + return; + } + } + var cookieSandbox = data["uri"] ? new Zotero.CookieSandbox(null, data["uri"], data["detailedCookies"] ? "" : data["cookie"] || "", url.userAgent) : null; if(cookieSandbox && data.detailedCookies) { @@ -384,7 +407,7 @@ Zotero.Server.Connector.SaveItem.prototype = { sendResponseCallback(500); } }, Zotero.Server.Connector.AttachmentProgressManager.onProgress); - } + }) } /** @@ -418,9 +441,29 @@ Zotero.Server.Connector.SaveSnapshot.prototype = { var collection = zp.getSelectedCollection(); } catch(e) {} - // Default to personal library if pane not yet opened + // Default to My Library if present if pane not yet opened if (!libraryID) { - libraryID = Zotero.Libraries.userLibraryID + let userLibrary = Zotero.Libraries.userLibrary; + if (userLibrary) { + libraryID = userLibrary.id; + } + } + + // If library isn't editable (or directly editable, in the case of My Publications), switch to + // My Library if present and editable, and otherwise fail + var library = Zotero.Libraries.get(libraryID); + if (!library.editable || library.libraryType == 'publications') { + let userLibrary = Zotero.Libraries.userLibrary; + if (userLibrary && userLibrary.editable) { + yield zp.collectionsView.selectLibrary(userLibrary.id); + libraryID = userLibrary.id; + collection = null; + } + else { + Zotero.logError("Can't add item to read-only library " + library.name); + sendResponseCallback(500); + return; + } } // determine whether snapshot can be saved diff --git a/test/tests/server_connectorTest.js b/test/tests/server_connectorTest.js index 21c2f0e87..14b5bda47 100644 --- a/test/tests/server_connectorTest.js +++ b/test/tests/server_connectorTest.js @@ -101,6 +101,58 @@ describe("Connector Server", function () { // Wait until indexing is done yield waitForItemEvent('refresh'); }); + + + it("should save to My Library if read-only library is selected", function* () { + var group = yield createGroup({ + editable: false + }); + yield selectLibrary(win, group.libraryID); + yield waitForItemsLoad(win); + + var body = { + items: [ + { + itemType: "newspaperArticle", + title: "Title", + creators: [ + { + firstName: "First", + lastName: "Last", + creatorType: "author" + } + ], + attachments: [] + } + ], + uri: "http://example.com" + }; + + var promise = waitForItemEvent('add'); + var req = yield Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/saveItems", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + } + ); + + // Check item + var ids = yield promise; + assert.lengthOf(ids, 1); + var item = Zotero.Items.get(ids[0]); + assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'newspaperArticle'); + // Item should've been saved to My Library + assert.equal(item.libraryID, Zotero.Libraries.userLibraryID); + + // My Library should've been selected + assert.equal( + win.ZoteroPane.collectionsView.getSelectedLibraryID(), Zotero.Libraries.userLibraryID + ); + }); }); describe("/connector/saveSnapshot", function () { @@ -184,5 +236,51 @@ describe("Connector Server", function () { assert.equal(item.attachmentContentType, 'application/pdf'); assert.isTrue(collection.hasItem(item.id)); }); + + it("should save a webpage item to My Library if a read-only library is selected", function* () { + var group = yield createGroup({ + editable: false + }); + yield selectLibrary(win, group.libraryID); + yield waitForItemsLoad(win); + + // saveSnapshot saves parent and child before returning + var ids1, ids2; + var promise = waitForItemEvent('add').then(function (ids) { + ids1 = ids; + return waitForItemEvent('add').then(function (ids) { + ids2 = ids; + }); + }); + yield Zotero.HTTP.request( + 'POST', + connectorServerPath + "/connector/saveSnapshot", + { + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + url: "http://example.com", + html: "TitleBody" + }) + } + ); + + assert.isTrue(promise.isFulfilled()); + + // Check parent item + assert.lengthOf(ids1, 1); + var item = Zotero.Items.get(ids1[0]); + assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'webpage'); + assert.equal(item.getField('title'), 'Title'); + assert.equal(item.libraryID, Zotero.Libraries.userLibraryID); + // Item should've been saved to My Library + assert.equal(item.libraryID, Zotero.Libraries.userLibraryID); + + // My Library should've been selected + assert.equal( + win.ZoteroPane.collectionsView.getSelectedLibraryID(), Zotero.Libraries.userLibraryID + ); + }); }); });