diff --git a/chrome/content/zotero/xpcom/data/tags.js b/chrome/content/zotero/xpcom/data/tags.js index 24adff6be0..bbb5c8d69c 100644 --- a/chrome/content/zotero/xpcom/data/tags.js +++ b/chrome/content/zotero/xpcom/data/tags.js @@ -431,9 +431,11 @@ Zotero.Tags = new function() { Zotero.DB.requireTransaction(); + var sql; + // Use given tags, as long as they're orphaned if (tagIDs) { - let sql = "CREATE TEMPORARY TABLE tagDelete (tagID INT PRIMARY KEY)"; + sql = "CREATE TEMPORARY TABLE tagDelete (tagID INT PRIMARY KEY)"; yield Zotero.DB.queryAsync(sql); yield Zotero.Utilities.Internal.forEachChunkAsync( tagIDs, @@ -446,13 +448,17 @@ Zotero.Tags = new function() { ); } ); - sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID) " - + "WHERE tagID NOT IN (SELECT tagID FROM itemTags)"; + + // Skip tags that are still linked to items + sql = "DELETE FROM tagDelete WHERE tagID IN (SELECT tagID FROM itemTags)"; + yield Zotero.DB.queryAsync(sql); + + sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID)"; var toDelete = yield Zotero.DB.queryAsync(sql); } // Look for orphaned tags else { - var sql = "CREATE TEMPORARY TABLE tagDelete AS " + sql = "CREATE TEMPORARY TABLE tagDelete AS " + "SELECT tagID FROM tags WHERE tagID NOT IN (SELECT tagID FROM itemTags)"; yield Zotero.DB.queryAsync(sql); @@ -461,11 +467,10 @@ Zotero.Tags = new function() { sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID)"; var toDelete = yield Zotero.DB.queryAsync(sql); - - if (!toDelete.length) { - sql = "DROP TABLE tagDelete"; - return Zotero.DB.queryAsync(sql); - } + } + + if (!toDelete.length) { + return Zotero.DB.queryAsync("DROP TABLE tagDelete"); } var ids = []; diff --git a/test/tests/tagsTest.js b/test/tests/tagsTest.js index 6063469857..9362ed350b 100644 --- a/test/tests/tagsTest.js +++ b/test/tests/tagsTest.js @@ -39,35 +39,46 @@ describe("Zotero.Tags", function () { }); describe("#removeFromLibrary()", function () { - it("should remove tags in given library", function* () { + it("should remove tags in given library", async function () { var libraryID = Zotero.Libraries.userLibraryID; - var groupLibraryID = (yield getGroup()).libraryID; + var groupLibraryID = (await getGroup()).libraryID; var tags = []; var items = []; - yield Zotero.DB.executeTransaction(function* () { + await Zotero.DB.executeTransaction(async function () { for (let i = 0; i < 10; i++) { let tagName = Zotero.Utilities.randomString(); tags.push(tagName); - let item = createUnsavedDataObject('item'); - item.addTag(tagName); - yield item.save(); + let item = createUnsavedDataObject('item', { tags: [tagName] }); + await item.save(); items.push(item); } }); - var groupTagName = Zotero.Utilities.randomString(); - var groupItem = createUnsavedDataObject('item', { libraryID: groupLibraryID }); - groupItem.addTag(groupTagName); - yield groupItem.saveTx(); + var groupTagName = tags[0]; + var groupItem = await createDataObject( + 'item', + { + libraryID: groupLibraryID, + tags: [groupTagName] + } + ); var tagIDs = tags.map(tag => Zotero.Tags.getID(tag)); - yield Zotero.Tags.removeFromLibrary(libraryID, tagIDs); + await Zotero.Tags.removeFromLibrary(libraryID, tagIDs); items.forEach(item => assert.lengthOf(item.getTags(), 0)); // Group item should still have the tag - assert.lengthOf(groupItem.getTags(), 1); - }) + assert.sameDeepMembers(groupItem.getTags(), [{ tag: groupTagName }]); + assert.equal( + await Zotero.DB.valueQueryAsync( + "SELECT COUNT(*) FROM itemTags WHERE itemID=?", + groupItem.id + ), + 1 + ); + }); + it("should reload tags of associated items", function* () { var libraryID = Zotero.Libraries.userLibraryID;