www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

tagSelectorTest.js (12803B)


      1 "use strict";
      2 
      3 describe("Tag Selector", function () {
      4 	var win, doc, collectionsView, tagSelector;
      5 	
      6 	var clearTagColors = Zotero.Promise.coroutine(function* (libraryID) {
      7 		var tagColors = Zotero.Tags.getColors(libraryID);
      8 		for (let name of tagColors.keys()) {
      9 			yield Zotero.Tags.setColor(libraryID, name, false);
     10 		}
     11 	});
     12 	
     13 	function getColoredTags() {
     14 		var tagsBox = tagSelector.id('tags-box');
     15 		var elems = tagsBox.getElementsByTagName('button');
     16 		var names = [];
     17 		for (let i = 0; i < elems.length; i++) {
     18 			if (elems[i].style.order < 0) {
     19 				names.push(elems[i].textContent);
     20 			}
     21 		}
     22 		return names;
     23 	}
     24 	
     25 	function getRegularTags() {
     26 		var tagsBox = tagSelector.id('tags-box');
     27 		var elems = tagsBox.getElementsByTagName('button');
     28 		var names = [];
     29 		for (let i = 0; i < elems.length; i++) {
     30 			if (elems[i].style.order >= 0 && elems[i].style.display != 'none') {
     31 				names.push(elems[i].textContent);
     32 			}
     33 		}
     34 		return names;
     35 	}
     36 	
     37 	
     38 	before(function* () {
     39 		win = yield loadZoteroPane();
     40 		doc = win.document;
     41 		collectionsView = win.ZoteroPane.collectionsView;
     42 		tagSelector = doc.getElementById('zotero-tag-selector');
     43 		
     44 		// Wait for things to settle
     45 		yield Zotero.Promise.delay(100);
     46 	});
     47 	
     48 	beforeEach(function* () {
     49 		var libraryID = Zotero.Libraries.userLibraryID;
     50 		yield clearTagColors(libraryID);
     51 		// Default "Display All Tags in This Library" off
     52 		tagSelector.filterToScope = true;
     53 		tagSelector.setSearch('');
     54 		yield tagSelector.refresh(true);
     55 	})
     56 	
     57 	after(function () {
     58 		win.close();
     59 	});
     60 	
     61 	describe("#setSearch()", function () {
     62 		it("should filter to tags matching the search", function* () {
     63 			var collection = yield createDataObject('collection');
     64 			var item = createUnsavedDataObject('item', { collections: [collection.id] });
     65 			item.setTags(['a', 'b', 'c']);
     66 			var promise = waitForTagSelector(win);
     67 			yield item.saveTx();
     68 			yield promise;
     69 			
     70 			var tagsSearch = doc.getElementById('tags-search');
     71 			tagsSearch.value = 'a';
     72 			tagsSearch.doCommand();
     73 			
     74 			var tags = getRegularTags();
     75 			assert.sameMembers(tags, ['a']);
     76 			
     77 			tagsSearch.value = '';
     78 			tagsSearch.doCommand();
     79 			yield item.eraseTx();
     80 		});
     81 	});
     82 	
     83 	describe("#refresh()", function () {
     84 		it("should remove tags not on matching items on tag click", function* () {
     85 			var collection = yield createDataObject('collection');
     86 			var item1 = createUnsavedDataObject('item', { collections: [collection.id] });
     87 			item1.setTags([
     88 				{
     89 					tag: "A"
     90 				}
     91 			]);
     92 			var item2 = createUnsavedDataObject('item', { collections: [collection.id] });
     93 			item2.setTags([
     94 				{
     95 					tag: "A"
     96 				},
     97 				{
     98 					tag: "B"
     99 				}
    100 			]);
    101 			var item3 = createUnsavedDataObject('item', { collections: [collection.id] });
    102 			item3.setTags([
    103 				{
    104 					tag: "C"
    105 				}
    106 			]);
    107 			var promise = waitForTagSelector(win);
    108 			yield Zotero.DB.executeTransaction(function* () {
    109 				yield item1.save();
    110 				yield item2.save();
    111 				yield item3.save();
    112 			});
    113 			yield promise;
    114 			
    115 			var buttons = tagSelector.id('tags-box').getElementsByTagName('button');
    116 			var spy = sinon.spy(win.ZoteroPane, "updateTagFilter");
    117 			buttons[0].click();
    118 			
    119 			yield spy.returnValues[0];
    120 			
    121 			spy.restore();
    122 			
    123 			var tags = getRegularTags();
    124 			assert.sameMembers(tags, ['A', 'B']);
    125 		});
    126 	});
    127 	
    128 	
    129 	describe("#filterToScope", function () {
    130 		it("should show all tags in library when false", function* () {
    131 			tagSelector.filterToScope = false;
    132 			
    133 			var collection = yield createDataObject('collection');
    134 			var item1 = createUnsavedDataObject('item');
    135 			item1.setTags([
    136 				{
    137 					tag: "A"
    138 				}
    139 			]);
    140 			var item2 = createUnsavedDataObject('item', { collections: [collection.id] });
    141 			item2.setTags([
    142 				{
    143 					tag: "B"
    144 				}
    145 			]);
    146 			var item3 = createUnsavedDataObject('item', { collections: [collection.id] });
    147 			item3.setTags([
    148 				{
    149 					tag: "C"
    150 				}
    151 			]);
    152 			var promise = waitForTagSelector(win);
    153 			yield Zotero.DB.executeTransaction(function* () {
    154 				yield item1.save();
    155 				yield item2.save();
    156 				yield item3.save();
    157 			});
    158 			yield promise;
    159 			
    160 			var tags = getRegularTags();
    161 			assert.sameMembers(tags, ['A', 'B', 'C']);
    162 		});
    163 	});
    164 	
    165 	
    166 	describe("#notify()", function () {
    167 		it("should add a tag when added to an item in the library root", function* () {
    168 			var promise, tagSelector;
    169 			
    170 			if (collectionsView.selection.currentIndex != 0) {
    171 				promise = waitForTagSelector(win);
    172 				yield collectionsView.selectLibrary();
    173 				yield promise;
    174 			}
    175 			
    176 			// Add item with tag to library root
    177 			var item = createUnsavedDataObject('item');
    178 			item.setTags([
    179 				{
    180 					tag: 'A'
    181 				},
    182 				{
    183 					tag: 'B',
    184 					type: 1
    185 				}
    186 			]);
    187 			promise = waitForTagSelector(win);
    188 			yield item.saveTx();
    189 			yield promise;
    190 			
    191 			// Tag selector should have at least one tag
    192 			assert.isAbove(getRegularTags().length, 1);
    193 		});
    194 		
    195 		it("should add a tag when an item is added in a collection", function* () {
    196 			var promise, tagSelector;
    197 			
    198 			// Add collection
    199 			promise = waitForTagSelector(win);
    200 			var collection = yield createDataObject('collection');
    201 			yield promise;
    202 			
    203 			// Tag selector should be empty in new collection
    204 			assert.equal(getRegularTags().length, 0);
    205 			
    206 			// Add item with tag to collection
    207 			var item = createUnsavedDataObject('item');
    208 			item.setTags([
    209 				{
    210 					tag: 'C'
    211 				}
    212 			]);
    213 			item.setCollections([collection.id]);
    214 			promise = waitForTagSelector(win)
    215 			yield item.saveTx();
    216 			yield promise;
    217 			
    218 			// Tag selector should show the new item's tag
    219 			assert.equal(getRegularTags().length, 1);
    220 		})
    221 		
    222 		it("should add a tag when an item is added to a collection", function* () {
    223 			var promise, tagSelector;
    224 			
    225 			// Add collection
    226 			promise = waitForTagSelector(win);
    227 			var collection = yield createDataObject('collection');
    228 			yield promise;
    229 			
    230 			// Tag selector should be empty in new collection
    231 			assert.equal(getRegularTags().length, 0);
    232 			
    233 			// Add item with tag to library root
    234 			var item = createUnsavedDataObject('item');
    235 			item.setTags([
    236 				{
    237 					tag: 'C'
    238 				}
    239 			]);
    240 			promise = waitForTagSelector(win)
    241 			yield item.saveTx();
    242 			yield promise;
    243 			
    244 			// Tag selector should still be empty in collection
    245 			assert.equal(getRegularTags().length, 0);
    246 			
    247 			item.setCollections([collection.id]);
    248 			promise = waitForTagSelector(win);
    249 			yield item.saveTx();
    250 			yield promise;
    251 			
    252 			// Tag selector should show the new item's tag
    253 			assert.equal(getRegularTags().length, 1);
    254 		})
    255 		
    256 		it("should show a colored tag at the top of the list even when linked to no items", function* () {
    257 			var libraryID = Zotero.Libraries.userLibraryID;
    258 			
    259 			var tagElems = tagSelector.id('tags-box').getElementsByTagName('button');
    260 			var count = tagElems.length;
    261 			
    262 			yield Zotero.Tags.setColor(libraryID, "Top", '#AAAAAA');
    263 			
    264 			assert.equal(tagElems.length, count + 1);
    265 		});
    266 		
    267 		it("shouldn't re-insert a new tag that matches an existing color", function* () {
    268 			var libraryID = Zotero.Libraries.userLibraryID;
    269 			
    270 			/*// Remove all tags in library
    271 			var tags = yield Zotero.Tags.getAll(libraryID);
    272 			tags.forEach(function (tag) {
    273 				var tagID = Zotero.Tags.getID(tag);
    274 				yield Zotero.Tags.removeFromLibrary(libraryID, tagID);
    275 			});*/
    276 			
    277 			// Add B and A as colored tags without any items
    278 			yield Zotero.Tags.setColor(libraryID, "B", '#990000');
    279 			yield Zotero.Tags.setColor(libraryID, "A", '#CC9933');
    280 			
    281 			// Add A to an item to make it a real tag
    282 			var item = createUnsavedDataObject('item');
    283 			item.setTags([
    284 				{
    285 					tag: "A"
    286 				}
    287 			]);
    288 			var promise = waitForTagSelector(win);
    289 			yield item.saveTx();
    290 			yield promise;
    291 			
    292 			var tagElems = tagSelector.id('tags-box').getElementsByTagName('button');
    293 			
    294 			// Make sure the colored tags are still in the right position
    295 			var tags = new Map();
    296 			for (let i = 0; i < tagElems.length; i++) {
    297 				tags.set(tagElems[i].textContent, tagElems[i].style.order);
    298 			}
    299 			assert.isBelow(parseInt(tags.get("B")), 0);
    300 			assert.isBelow(parseInt(tags.get("B")), parseInt(tags.get("A")));
    301 		})
    302 		
    303 		it("should remove a tag when an item is removed from a collection", function* () {
    304 			// Add collection
    305 			var promise = waitForTagSelector(win);
    306 			var collection = yield createDataObject('collection');
    307 			yield promise;
    308 			
    309 			// Add item with tag to collection
    310 			var item = createUnsavedDataObject('item');
    311 			item.setTags([
    312 				{
    313 					tag: 'A'
    314 				}
    315 			]);
    316 			item.setCollections([collection.id]);
    317 			promise = waitForTagSelector(win);
    318 			yield item.saveTx();
    319 			yield promise;
    320 			
    321 			// Tag selector should show the new item's tag
    322 			assert.equal(getRegularTags().length, 1);
    323 			
    324 			item.setCollections();
    325 			promise = waitForTagSelector(win);
    326 			yield item.saveTx();
    327 			yield promise;
    328 			
    329 			// Tag selector shouldn't show the removed item's tag
    330 			assert.equal(getRegularTags().length, 0);
    331 		})
    332 		
    333 		it("should remove a tag when an item in a collection is moved to the trash", function* () {
    334 			// Add collection
    335 			var promise = waitForTagSelector(win);
    336 			var collection = yield createDataObject('collection');
    337 			yield promise;
    338 			
    339 			// Add item with tag to collection
    340 			var item = createUnsavedDataObject('item');
    341 			item.setTags([
    342 				{
    343 					tag: 'A'
    344 				}
    345 			]);
    346 			item.setCollections([collection.id]);
    347 			promise = waitForTagSelector(win)
    348 			yield item.saveTx();
    349 			yield promise;
    350 			
    351 			// Tag selector should show the new item's tag
    352 			assert.equal(getRegularTags().length, 1);
    353 			
    354 			// Move item to trash
    355 			item.deleted = true;
    356 			promise = waitForTagSelector(win);
    357 			yield item.saveTx();
    358 			yield promise;
    359 			
    360 			// Tag selector shouldn't show the deleted item's tag
    361 			assert.equal(getRegularTags().length, 0);
    362 		})
    363 		
    364 		it("should remove a tag when a tag is deleted for a library", function* () {
    365 			yield selectLibrary(win);
    366 			
    367 			var item = createUnsavedDataObject('item');
    368 			item.setTags([
    369 				{
    370 					tag: 'A'
    371 				}
    372 			]);
    373 			var promise = waitForTagSelector(win);
    374 			yield item.saveTx();
    375 			yield promise;
    376 			
    377 			// Tag selector should show the new item's tag
    378 			assert.include(getRegularTags(), "A");
    379 			
    380 			// Remove tag from library
    381 			promise = waitForTagSelector(win);
    382 			var dialogPromise = waitForDialog();
    383 			yield tagSelector.deleteTag("A");
    384 			yield promise;
    385 			
    386 			// Tag selector shouldn't show the deleted item's tag
    387 			assert.notInclude(getRegularTags(), "A");
    388 		})
    389 	})
    390 	
    391 	describe("#rename()", function () {
    392 		it("should rename a tag and update the tag selector", function* () {
    393 			yield selectLibrary(win);
    394 			
    395 			var tag = Zotero.Utilities.randomString();
    396 			var newTag = Zotero.Utilities.randomString();
    397 			var item = createUnsavedDataObject('item');
    398 			item.setTags([
    399 				{
    400 					tag: tag
    401 				}
    402 			]);
    403 			var promise = waitForTagSelector(win);
    404 			yield item.saveTx();
    405 			yield promise;
    406 			
    407 			promise = waitForTagSelector(win);
    408 			var promptPromise = waitForWindow("chrome://global/content/commonDialog.xul", function (dialog) {
    409 				dialog.document.getElementById('loginTextbox').value = newTag;
    410 				dialog.document.documentElement.acceptDialog();
    411 			})
    412 			yield tagSelector.rename(tag);
    413 			yield promise;
    414 			
    415 			var tags = getRegularTags();
    416 			assert.include(tags, newTag);
    417 		});
    418 		
    419 		it("should rename a non-matching colored tag and update the tag selector", function* () {
    420 			yield selectLibrary(win);
    421 			
    422 			var oldTag = Zotero.Utilities.randomString();
    423 			var newTag = Zotero.Utilities.randomString();
    424 			
    425 			var libraryID = Zotero.Libraries.userLibraryID;
    426 			var promise = waitForTagSelector(win);
    427 			yield Zotero.Tags.setColor(libraryID, oldTag, "#F3F3F3");
    428 			yield promise;
    429 			
    430 			promise = waitForTagSelector(win);
    431 			var promptPromise = waitForWindow("chrome://global/content/commonDialog.xul", function (dialog) {
    432 				dialog.document.getElementById('loginTextbox').value = newTag;
    433 				dialog.document.documentElement.acceptDialog();
    434 			})
    435 			yield tagSelector.rename(oldTag);
    436 			yield promise;
    437 			
    438 			var tags = getColoredTags();
    439 			assert.notInclude(tags, oldTag);
    440 			assert.include(tags, newTag);
    441 		});
    442 	})
    443 	
    444 	describe("#_openColorPickerWindow()", function () {
    445 		it("should assign a color to a tag", function* () {
    446 			yield selectLibrary(win);
    447 			var tag = "b " + Zotero.Utilities.randomString();
    448 			var item = createUnsavedDataObject('item');
    449 			item.setTags([
    450 				{
    451 					tag: "a"
    452 				},
    453 				{
    454 					tag: tag
    455 				}
    456 			]);
    457 			var promise = waitForTagSelector(win);
    458 			yield item.saveTx();
    459 			yield promise;
    460 			
    461 			
    462 			assert.include(getRegularTags(), "a");
    463 			
    464 			var dialogPromise = waitForDialog(false, undefined, 'chrome://zotero/content/tagColorChooser.xul');
    465 			var tagSelectorPromise = waitForTagSelector(win);
    466 			yield tagSelector._openColorPickerWindow(tag);
    467 			yield dialogPromise;
    468 			yield tagSelectorPromise;
    469 			
    470 			assert.include(getColoredTags(), tag);
    471 			assert.notInclude(getRegularTags(), tag);
    472 		})
    473 	});
    474 })