toolkit/mozapps/extensions/test/browser/browser_searching.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 3 */
michael@0 4
michael@0 5 // Tests that searching for add-ons works correctly
michael@0 6
michael@0 7 const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
michael@0 8 const SEARCH_URL = TESTROOT + "browser_searching.xml";
michael@0 9 const NO_MATCH_URL = TESTROOT + "browser_searching_empty.xml";
michael@0 10
michael@0 11 const QUERY = "SEARCH";
michael@0 12 const NO_MATCH_QUERY = "NOMATCHQUERY";
michael@0 13 const REMOTE_TO_INSTALL = "remote1";
michael@0 14 const REMOTE_INSTALL_URL = TESTROOT + "addons/browser_searching.xpi";
michael@0 15
michael@0 16 var gManagerWindow;
michael@0 17 var gCategoryUtilities;
michael@0 18 var gProvider;
michael@0 19 var gServer;
michael@0 20 var gAddonInstalled = false;
michael@0 21
michael@0 22 function test() {
michael@0 23 requestLongerTimeout(2);
michael@0 24 // Turn on searching for this test
michael@0 25 Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
michael@0 26 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
michael@0 27
michael@0 28 waitForExplicitFinish();
michael@0 29
michael@0 30 gProvider = new MockProvider();
michael@0 31
michael@0 32 gProvider.createAddons([{
michael@0 33 id: "addon1@tests.mozilla.org",
michael@0 34 name: "PASS - f",
michael@0 35 description: "Test description - SEARCH",
michael@0 36 size: 3,
michael@0 37 version: "1.0",
michael@0 38 updateDate: new Date(2010, 4, 2, 0, 0, 1)
michael@0 39 }, {
michael@0 40 id: "fail-addon1@tests.mozilla.org",
michael@0 41 name: "FAIL",
michael@0 42 description: "Does not match query"
michael@0 43 }, {
michael@0 44 id: "addon2@tests.mozilla.org",
michael@0 45 name: "PASS - c",
michael@0 46 description: "Test description - reSEARCHing SEARCH SEARCH",
michael@0 47 size: 6,
michael@0 48 version: "2.0",
michael@0 49 updateDate: new Date(2010, 4, 2, 0, 0, 0)
michael@0 50 }]);
michael@0 51
michael@0 52 var installs = gProvider.createInstalls([{
michael@0 53 name: "PASS - a - SEARCHing",
michael@0 54 sourceURI: "http://example.com/install1.xpi"
michael@0 55 }, {
michael@0 56 name: "PASS - g - reSEARCHing SEARCH",
michael@0 57 sourceURI: "http://example.com/install2.xpi"
michael@0 58 }, {
michael@0 59 // Does not match query
michael@0 60 name: "FAIL",
michael@0 61 sourceURI: "http://example.com/fail-install1.xpi"
michael@0 62 }]);
michael@0 63
michael@0 64 for (let install of installs )
michael@0 65 install.install();
michael@0 66
michael@0 67 open_manager("addons://list/extension", function(aWindow) {
michael@0 68 gManagerWindow = aWindow;
michael@0 69 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
michael@0 70 run_next_test();
michael@0 71 });
michael@0 72 }
michael@0 73
michael@0 74 function end_test() {
michael@0 75 close_manager(gManagerWindow, function() {
michael@0 76 var installedAddon = get_addon_item(REMOTE_TO_INSTALL).mAddon;
michael@0 77 installedAddon.uninstall();
michael@0 78
michael@0 79 AddonManager.getAllInstalls(function(aInstallsList) {
michael@0 80 for (var install of aInstallsList) {
michael@0 81 var sourceURI = install.sourceURI.spec;
michael@0 82 if (sourceURI == REMOTE_INSTALL_URL ||
michael@0 83 sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/) != null)
michael@0 84 install.cancel();
michael@0 85 }
michael@0 86
michael@0 87 finish();
michael@0 88 });
michael@0 89 });
michael@0 90 }
michael@0 91
michael@0 92 function getAnonymousElementByAttribute(aElement, aName, aValue) {
michael@0 93 return gManagerWindow.document.getAnonymousElementByAttribute(aElement,
michael@0 94 aName,
michael@0 95 aValue);
michael@0 96 }
michael@0 97
michael@0 98 /*
michael@0 99 * Checks whether or not the Add-ons Manager is currently searching
michael@0 100 *
michael@0 101 * @param aExpectedSearching
michael@0 102 * The expected isSearching state
michael@0 103 */
michael@0 104 function check_is_searching(aExpectedSearching) {
michael@0 105 var loading = gManagerWindow.document.getElementById("search-loading");
michael@0 106 is(!is_hidden(loading), aExpectedSearching,
michael@0 107 "Search throbber should be showing iff currently searching");
michael@0 108 }
michael@0 109
michael@0 110 /*
michael@0 111 * Completes a search
michael@0 112 *
michael@0 113 * @param aQuery
michael@0 114 * The query to search for
michael@0 115 * @param aFinishImmediately
michael@0 116 * Boolean representing whether or not the search is expected to
michael@0 117 * finish immediately
michael@0 118 * @param aCallback
michael@0 119 * The callback to call when the search is done
michael@0 120 * @param aCategoryType
michael@0 121 * The expected selected category after the search is done.
michael@0 122 * Optional and defaults to "search"
michael@0 123 */
michael@0 124 function search(aQuery, aFinishImmediately, aCallback, aCategoryType) {
michael@0 125 // Point search to the correct xml test file
michael@0 126 var url = (aQuery == NO_MATCH_QUERY) ? NO_MATCH_URL : SEARCH_URL;
michael@0 127 Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, url);
michael@0 128
michael@0 129 aCategoryType = aCategoryType ? aCategoryType : "search";
michael@0 130
michael@0 131 var searchBox = gManagerWindow.document.getElementById("header-search");
michael@0 132 searchBox.value = aQuery;
michael@0 133
michael@0 134 EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow);
michael@0 135 EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow);
michael@0 136
michael@0 137 var finishImmediately = true;
michael@0 138 wait_for_view_load(gManagerWindow, function() {
michael@0 139 is(gCategoryUtilities.selectedCategory, aCategoryType, "Expected category view should be selected");
michael@0 140 is(gCategoryUtilities.isTypeVisible("search"), aCategoryType == "search",
michael@0 141 "Search category should only be visible if it is the current view");
michael@0 142 check_is_searching(false);
michael@0 143 is(finishImmediately, aFinishImmediately, "Search should finish immediately only if expected");
michael@0 144
michael@0 145 aCallback();
michael@0 146 });
michael@0 147
michael@0 148 finishImmediately = false
michael@0 149 if (!aFinishImmediately)
michael@0 150 check_is_searching(true);
michael@0 151 }
michael@0 152
michael@0 153 /*
michael@0 154 * Return results of a search
michael@0 155 *
michael@0 156 * @return Array of objects, each containing the name and item of a specific
michael@0 157 * result
michael@0 158 */
michael@0 159 function get_actual_results() {
michael@0 160 var list = gManagerWindow.document.getElementById("search-list");
michael@0 161 var rows = list.getElementsByTagName("richlistitem");
michael@0 162
michael@0 163 var results = [];
michael@0 164 for (var item of rows) {
michael@0 165
michael@0 166 // Only consider items that are currently showing
michael@0 167 var style = gManagerWindow.document.defaultView.getComputedStyle(item, "");
michael@0 168 if (style.display == "none" || style.visibility != "visible")
michael@0 169 continue;
michael@0 170
michael@0 171 if (item.mInstall || item.isPending("install")) {
michael@0 172 var sourceURI = item.mInstall.sourceURI.spec;
michael@0 173 if (sourceURI == REMOTE_INSTALL_URL) {
michael@0 174 results.push({name: REMOTE_TO_INSTALL, item: item});
michael@0 175 continue;
michael@0 176 }
michael@0 177
michael@0 178 var result = sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/);
michael@0 179 if (result != null) {
michael@0 180 is(item.mInstall.name.indexOf("PASS"), 0, "Install name should start with PASS");
michael@0 181 results.push({name: result[1], item: item});
michael@0 182 continue;
michael@0 183 }
michael@0 184 }
michael@0 185 else if (item.mAddon) {
michael@0 186 var result = item.mAddon.id.match(/^(.+)@tests\.mozilla\.org$/);
michael@0 187 if (result != null) {
michael@0 188 is(item.mAddon.name.indexOf("PASS"), 0, "Addon name should start with PASS");
michael@0 189 results.push({name: result[1], item: item});
michael@0 190 continue;
michael@0 191 }
michael@0 192 }
michael@0 193 else {
michael@0 194 ok(false, "Found an item in the list that was neither installing or installed");
michael@0 195 }
michael@0 196 }
michael@0 197
michael@0 198 return results;
michael@0 199 }
michael@0 200
michael@0 201 /*
michael@0 202 * Returns expected results when searching for QUERY with default ordering
michael@0 203 *
michael@0 204 * @param aSortBy
michael@0 205 * How the results are sorted (e.g. "name")
michael@0 206 * @param aLocalExpected
michael@0 207 * Boolean representing if local results are expected
michael@0 208 * @return A pair: [array of results with an expected order,
michael@0 209 * array of results with unknown order]
michael@0 210 */
michael@0 211 function get_expected_results(aSortBy, aLocalExpected) {
michael@0 212 var expectedOrder = null, unknownOrder = null;
michael@0 213 switch (aSortBy) {
michael@0 214 case "relevancescore":
michael@0 215 expectedOrder = [ "addon2" , "remote1", "install2", "addon1",
michael@0 216 "install1", "remote2", "remote3" , "remote4" ];
michael@0 217 unknownOrder = [];
michael@0 218 break;
michael@0 219 case "name":
michael@0 220 // Defaults to ascending order
michael@0 221 expectedOrder = [ "install1", "remote1", "addon2" , "remote2",
michael@0 222 "remote3" , "addon1" , "install2", "remote4" ];
michael@0 223 unknownOrder = [];
michael@0 224 break;
michael@0 225 case "dateUpdated":
michael@0 226 expectedOrder = [ "addon1", "addon2" ];
michael@0 227 // Updated date not available for installs and remote add-ons
michael@0 228 unknownOrder = [ "install1", "install2", "remote1",
michael@0 229 "remote2" , "remote3" , "remote4" ];
michael@0 230 break;
michael@0 231 default:
michael@0 232 ok(false, "Should recognize sortBy when checking the order of items");
michael@0 233 }
michael@0 234
michael@0 235 // Only keep expected results
michael@0 236 function filterResults(aId) {
michael@0 237 // Include REMOTE_TO_INSTALL as a local add-on if it has been installed
michael@0 238 if (gAddonInstalled && aId == REMOTE_TO_INSTALL)
michael@0 239 return aLocalExpected;
michael@0 240
michael@0 241 if (aId.indexOf("addon") == 0 || aId.indexOf("install") == 0)
michael@0 242 return aLocalExpected;
michael@0 243 if (aId.indexOf("remote") == 0)
michael@0 244 return !aLocalExpected;
michael@0 245
michael@0 246 return false;
michael@0 247 }
michael@0 248
michael@0 249
michael@0 250 return [expectedOrder.filter(filterResults),
michael@0 251 unknownOrder.filter(filterResults)]
michael@0 252 }
michael@0 253
michael@0 254 /*
michael@0 255 * Check that the actual and expected results are the same
michael@0 256 *
michael@0 257 * @param aQuery
michael@0 258 * The search query used
michael@0 259 * @param aSortBy
michael@0 260 * How the results are sorted (e.g. "name")
michael@0 261 * @param aReverseOrder
michael@0 262 * Boolean representing if the results are in reverse default order
michael@0 263 * @param aShowLocal
michael@0 264 * Boolean representing if local results are being shown
michael@0 265 */
michael@0 266 function check_results(aQuery, aSortBy, aReverseOrder, aShowLocal) {
michael@0 267
michael@0 268 var xpinstall_enabled = true;
michael@0 269 try {
michael@0 270 xpinstall_enabled = Services.prefs.getBoolPref(PREF_XPI_ENABLED);
michael@0 271 }
michael@0 272 catch (e) {};
michael@0 273
michael@0 274 // When XPI Instalation is disabled, those buttons are hidden and unused
michael@0 275 if (xpinstall_enabled) {
michael@0 276 var localFilterSelected = gManagerWindow.document.getElementById("search-filter-local").selected;
michael@0 277 var remoteFilterSelected = gManagerWindow.document.getElementById("search-filter-remote").selected;
michael@0 278 is(localFilterSelected, aShowLocal, "Local filter should be selected if showing local items");
michael@0 279 is(remoteFilterSelected, !aShowLocal, "Remote filter should be selected if showing remote items");
michael@0 280 }
michael@0 281
michael@0 282 // Get expected order assuming default order
michael@0 283 var expectedOrder = [], unknownOrder = [];
michael@0 284 if (aQuery == QUERY)
michael@0 285 [expectedOrder, unknownOrder] = get_expected_results(aSortBy, aShowLocal);
michael@0 286
michael@0 287 // Get actual order of results
michael@0 288 var actualResults = get_actual_results();
michael@0 289 var actualOrder = [result.name for each(result in actualResults)];
michael@0 290
michael@0 291 // Reverse array of actual results if supposed to be in reverse order.
michael@0 292 // Reverse actualOrder instead of expectedOrder so can always check
michael@0 293 // expectedOrder before unknownOrder
michael@0 294 if (aReverseOrder)
michael@0 295 actualOrder.reverse();
michael@0 296
michael@0 297 // Check actual vs. expected list of results
michael@0 298 var totalExpectedResults = expectedOrder.length + unknownOrder.length;
michael@0 299 is(actualOrder.length, totalExpectedResults, "Should get correct number of results");
michael@0 300
michael@0 301 // Check the "first" and "last" attributes are set correctly
michael@0 302 for (let i = 0; i < actualResults.length; i++) {
michael@0 303 if (i == 0) {
michael@0 304 is(actualResults[0].item.hasAttribute("first"), true,
michael@0 305 "First item should have 'first' attribute set");
michael@0 306 is(actualResults[0].item.hasAttribute("last"), false,
michael@0 307 "First item should not have 'last' attribute set");
michael@0 308 } else if (i == (actualResults.length - 1)) {
michael@0 309 is(actualResults[actualResults.length - 1].item.hasAttribute("first"), false,
michael@0 310 "Last item should not have 'first' attribute set");
michael@0 311 is(actualResults[actualResults.length - 1].item.hasAttribute("last"), true,
michael@0 312 "Last item should have 'last' attribute set");
michael@0 313 } else {
michael@0 314 is(actualResults[i].item.hasAttribute("first"), false,
michael@0 315 "Item " + i + " should not have 'first' attribute set");
michael@0 316 is(actualResults[i].item.hasAttribute("last"), false,
michael@0 317 "Item " + i + " should not have 'last' attribute set");
michael@0 318 }
michael@0 319 }
michael@0 320
michael@0 321 var i = 0;
michael@0 322 for (; i < expectedOrder.length; i++)
michael@0 323 is(actualOrder[i], expectedOrder[i], "Should have seen expected item");
michael@0 324
michael@0 325 // Items with data that is unknown can appear in any order among themselves,
michael@0 326 // so just check that these items exist
michael@0 327 for (; i < actualOrder.length; i++) {
michael@0 328 var unknownOrderIndex = unknownOrder.indexOf(actualOrder[i]);
michael@0 329 ok(unknownOrderIndex >= 0, "Should expect to see item with data that is unknown");
michael@0 330 unknownOrder[unknownOrderIndex] = null;
michael@0 331 }
michael@0 332
michael@0 333 // Check status of empty notice
michael@0 334 var emptyNotice = gManagerWindow.document.getElementById("search-list-empty");
michael@0 335 is(emptyNotice.hidden, totalExpectedResults > 0,
michael@0 336 "Empty notice should be hidden only if expecting shown items");
michael@0 337 }
michael@0 338
michael@0 339 /*
michael@0 340 * Check results of a search with different filterings
michael@0 341 *
michael@0 342 * @param aQuery
michael@0 343 * The search query used
michael@0 344 * @param aSortBy
michael@0 345 * How the results are sorted (e.g. "name")
michael@0 346 * @param aReverseOrder
michael@0 347 * Boolean representing if the results are in reverse default order
michael@0 348 * @param aLocalOnly
michael@0 349 * Boolean representing if the results are local only, can be undefined
michael@0 350 */
michael@0 351 function check_filtered_results(aQuery, aSortBy, aReverseOrder, aLocalOnly) {
michael@0 352 var localFilter = gManagerWindow.document.getElementById("search-filter-local");
michael@0 353 var remoteFilter = gManagerWindow.document.getElementById("search-filter-remote");
michael@0 354
michael@0 355 var list = gManagerWindow.document.getElementById("search-list");
michael@0 356 list.ensureElementIsVisible(localFilter);
michael@0 357
michael@0 358 // Check with showing local add-ons
michael@0 359 EventUtils.synthesizeMouseAtCenter(localFilter, { }, gManagerWindow);
michael@0 360 check_results(aQuery, aSortBy, aReverseOrder, true);
michael@0 361
michael@0 362 // Check with showing remote add-ons
michael@0 363 aLocalOnly = aLocalOnly || false;
michael@0 364 EventUtils.synthesizeMouseAtCenter(remoteFilter, { }, gManagerWindow);
michael@0 365 check_results(aQuery, aSortBy, aReverseOrder, aLocalOnly);
michael@0 366 }
michael@0 367
michael@0 368 /*
michael@0 369 * Get item for a specific add-on by name
michael@0 370 *
michael@0 371 * @param aName
michael@0 372 * The name of the add-on to search for
michael@0 373 * @return Row of add-on if found, null otherwise
michael@0 374 */
michael@0 375 function get_addon_item(aName) {
michael@0 376 var id = aName + "@tests.mozilla.org";
michael@0 377 var list = gManagerWindow.document.getElementById("search-list");
michael@0 378 var rows = list.getElementsByTagName("richlistitem");
michael@0 379 for (var row of rows) {
michael@0 380 if (row.mAddon && row.mAddon.id == id)
michael@0 381 return row;
michael@0 382 }
michael@0 383
michael@0 384 return null;
michael@0 385 }
michael@0 386
michael@0 387 /*
michael@0 388 * Get item for a specific install by name
michael@0 389 *
michael@0 390 * @param aName
michael@0 391 * The name of the install to search for
michael@0 392 * @return Row of install if found, null otherwise
michael@0 393 */
michael@0 394 function get_install_item(aName) {
michael@0 395 var sourceURI = "http://example.com/" + aName + ".xpi";
michael@0 396 var list = gManagerWindow.document.getElementById("search-list");
michael@0 397 var rows = list.getElementsByTagName("richlistitem");
michael@0 398 for (var row of rows) {
michael@0 399 if (row.mInstall && row.mInstall.sourceURI.spec == sourceURI)
michael@0 400 return row;
michael@0 401 }
michael@0 402
michael@0 403 return null;
michael@0 404 }
michael@0 405
michael@0 406 /*
michael@0 407 * Gets the install button for a specific item
michael@0 408 *
michael@0 409 * @param aItem
michael@0 410 * The item to get the install button for
michael@0 411 * @return The install button for aItem
michael@0 412 */
michael@0 413 function get_install_button(aItem) {
michael@0 414 isnot(aItem, null, "Item should not be null when checking state of install button");
michael@0 415 var installStatus = getAnonymousElementByAttribute(aItem, "anonid", "install-status");
michael@0 416 return getAnonymousElementByAttribute(installStatus, "anonid", "install-remote-btn");
michael@0 417 }
michael@0 418
michael@0 419
michael@0 420 // Tests that searching for the empty string does nothing when not in the search view
michael@0 421 add_test(function() {
michael@0 422 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should initially be hidden");
michael@0 423
michael@0 424 var selectedCategory = gCategoryUtilities.selectedCategory;
michael@0 425 isnot(selectedCategory, "search", "Selected type should not initially be the search view");
michael@0 426 search("", true, run_next_test, selectedCategory);
michael@0 427 });
michael@0 428
michael@0 429 // Tests that the results from a query are sorted by relevancescore in descending order.
michael@0 430 // Also test that double clicking non-install items goes to the detail view, and that
michael@0 431 // only remote items have install buttons showing
michael@0 432 add_test(function() {
michael@0 433 search(QUERY, false, function() {
michael@0 434 check_filtered_results(QUERY, "relevancescore", false);
michael@0 435
michael@0 436 var list = gManagerWindow.document.getElementById("search-list");
michael@0 437 var results = get_actual_results();
michael@0 438 for (var result of results) {
michael@0 439 var installBtn = get_install_button(result.item);
michael@0 440 is(installBtn.hidden, result.name.indexOf("remote") != 0,
michael@0 441 "Install button should only be showing for remote items");
michael@0 442 }
michael@0 443
michael@0 444 var currentIndex = -1;
michael@0 445 function run_next_double_click_test() {
michael@0 446 currentIndex++;
michael@0 447 if (currentIndex >= results.length) {
michael@0 448 run_next_test();
michael@0 449 return;
michael@0 450 }
michael@0 451
michael@0 452 var result = results[currentIndex];
michael@0 453 if (result.name.indexOf("install") == 0) {
michael@0 454 run_next_double_click_test();
michael@0 455 return;
michael@0 456 }
michael@0 457
michael@0 458 var item = result.item;
michael@0 459 list.ensureElementIsVisible(item);
michael@0 460 EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow);
michael@0 461 EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
michael@0 462 wait_for_view_load(gManagerWindow, function() {
michael@0 463 var name = gManagerWindow.document.getElementById("detail-name").textContent;
michael@0 464 is(name, item.mAddon.name, "Name in detail view should be correct");
michael@0 465 var version = gManagerWindow.document.getElementById("detail-version").value;
michael@0 466 is(version, item.mAddon.version, "Version in detail view should be correct");
michael@0 467
michael@0 468 EventUtils.synthesizeMouseAtCenter(gManagerWindow.document.getElementById("category-search"),
michael@0 469 { }, gManagerWindow);
michael@0 470 wait_for_view_load(gManagerWindow, run_next_double_click_test);
michael@0 471 });
michael@0 472 }
michael@0 473
michael@0 474 run_next_double_click_test();
michael@0 475 });
michael@0 476 });
michael@0 477
michael@0 478 // Tests that the sorters and filters correctly manipulate the results
michael@0 479 add_test(function() {
michael@0 480 var sorters = gManagerWindow.document.getElementById("search-sorters");
michael@0 481 var originalHandler = sorters.handler;
michael@0 482
michael@0 483 var sorterNames = ["name", "dateUpdated"];
michael@0 484 var buttonIds = ["name-btn", "date-btn"];
michael@0 485 var currentIndex = 0;
michael@0 486 var currentReversed = false;
michael@0 487
michael@0 488 function run_sort_test() {
michael@0 489 if (currentIndex >= sorterNames.length) {
michael@0 490 sorters.handler = originalHandler;
michael@0 491 run_next_test();
michael@0 492 return;
michael@0 493 }
michael@0 494
michael@0 495 // Simulate clicking on a specific sorter
michael@0 496 var buttonId = buttonIds[currentIndex];
michael@0 497 var sorter = getAnonymousElementByAttribute(sorters, "anonid", buttonId);
michael@0 498 is_element_visible(sorter);
michael@0 499 EventUtils.synthesizeMouseAtCenter(sorter, { }, gManagerWindow);
michael@0 500 }
michael@0 501
michael@0 502 sorters.handler = {
michael@0 503 onSortChanged: function(aSortBy, aAscending) {
michael@0 504 if (originalHandler && "onSortChanged" in originalHandler)
michael@0 505 originalHandler.onSortChanged(aSortBy, aAscending);
michael@0 506
michael@0 507 check_filtered_results(QUERY, sorterNames[currentIndex], currentReversed);
michael@0 508
michael@0 509 if (currentReversed)
michael@0 510 currentIndex++;
michael@0 511 currentReversed = !currentReversed;
michael@0 512
michael@0 513 run_sort_test();
michael@0 514 }
michael@0 515 };
michael@0 516
michael@0 517 check_filtered_results(QUERY, "relevancescore", false);
michael@0 518 run_sort_test();
michael@0 519 });
michael@0 520
michael@0 521 // Tests that searching for the empty string does nothing when in search view
michael@0 522 add_test(function() {
michael@0 523 search("", true, function() {
michael@0 524 check_filtered_results(QUERY, "dateUpdated", true);
michael@0 525 run_next_test();
michael@0 526 });
michael@0 527 });
michael@0 528
michael@0 529 // Tests that clicking a different category hides the search query
michael@0 530 add_test(function() {
michael@0 531 gCategoryUtilities.openType("extension", function() {
michael@0 532 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden");
michael@0 533 is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
michael@0 534 run_next_test();
michael@0 535 });
michael@0 536 });
michael@0 537
michael@0 538 // Tests that re-searching for query doesn't actually complete a new search,
michael@0 539 // and the last sort is still used
michael@0 540 add_test(function() {
michael@0 541 search(QUERY, true, function() {
michael@0 542 check_filtered_results(QUERY, "dateUpdated", true);
michael@0 543 run_next_test();
michael@0 544 });
michael@0 545 });
michael@0 546
michael@0 547 // Tests that getting zero results works correctly
michael@0 548 add_test(function() {
michael@0 549 search(NO_MATCH_QUERY, false, function() {
michael@0 550 check_filtered_results(NO_MATCH_QUERY, "relevancescore", false);
michael@0 551 run_next_test();
michael@0 552 });
michael@0 553 });
michael@0 554
michael@0 555 // Tests that installing a remote add-on works
michael@0 556 add_test(function() {
michael@0 557 var installBtn = null;
michael@0 558
michael@0 559 var listener = {
michael@0 560 onInstallEnded: function(aInstall, aAddon) {
michael@0 561 // Don't immediately consider the installed add-on as local because
michael@0 562 // if the user was filtering out local add-ons, the installed add-on
michael@0 563 // would vanish. Only consider add-on as local on new searches.
michael@0 564
michael@0 565 aInstall.removeListener(this);
michael@0 566
michael@0 567 is(installBtn.hidden, true, "Install button should be hidden after install ended");
michael@0 568 check_filtered_results(QUERY, "relevancescore", false);
michael@0 569 run_next_test();
michael@0 570 }
michael@0 571 }
michael@0 572
michael@0 573 search(QUERY, false, function() {
michael@0 574 var list = gManagerWindow.document.getElementById("search-list");
michael@0 575 var remoteItem = get_addon_item(REMOTE_TO_INSTALL);
michael@0 576 list.ensureElementIsVisible(remoteItem);
michael@0 577
michael@0 578 installBtn = get_install_button(remoteItem);
michael@0 579 is(installBtn.hidden, false, "Install button should be showing before install");
michael@0 580 remoteItem.mAddon.install.addListener(listener);
michael@0 581 EventUtils.synthesizeMouseAtCenter(installBtn, { }, gManagerWindow);
michael@0 582 });
michael@0 583 });
michael@0 584
michael@0 585 // Tests that re-searching for query results in correct results
michael@0 586 add_test(function() {
michael@0 587 // Select a different category
michael@0 588 gCategoryUtilities.openType("extension", function() {
michael@0 589 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden");
michael@0 590 is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
michael@0 591
michael@0 592 var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL));
michael@0 593 is(installBtn.hidden, true, "Install button should be hidden for installed item");
michael@0 594
michael@0 595 search(QUERY, true, function() {
michael@0 596 check_filtered_results(QUERY, "relevancescore", false);
michael@0 597 run_next_test();
michael@0 598 });
michael@0 599 });
michael@0 600 });
michael@0 601
michael@0 602 // Tests that incompatible add-ons are shown with a warning if compatibility checking is disabled
michael@0 603 add_test(function() {
michael@0 604 AddonManager.checkCompatibility = false;
michael@0 605 search("incompatible", false, function() {
michael@0 606 var item = get_addon_item("remote5");
michael@0 607 is_element_visible(item, "Incompatible addon should be visible");
michael@0 608 is(item.getAttribute("notification"), "warning", "Compatibility warning should be shown");
michael@0 609
michael@0 610 item = get_addon_item("remote6");
michael@0 611 is(item, null, "Addon incompatible with the product should not be visible");
michael@0 612
michael@0 613 AddonManager.checkCompatibility = true;
michael@0 614 run_next_test();
michael@0 615 });
michael@0 616 });
michael@0 617
michael@0 618 // Tests that compatible-by-default addons are shown if strict compatibility checking is disabled
michael@0 619 add_test(function() {
michael@0 620 restart_manager(gManagerWindow, null, function(aWindow) {
michael@0 621 gManagerWindow = aWindow;
michael@0 622 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
michael@0 623
michael@0 624 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false);
michael@0 625 search("incompatible", false, function() {
michael@0 626 var item = get_addon_item("remote5");
michael@0 627 is_element_visible(item, "Incompatible addon should be visible");
michael@0 628 isnot(item.getAttribute("notification"), "warning", "Compatibility warning should not be shown");
michael@0 629
michael@0 630 var item = get_addon_item("remote6");
michael@0 631 is(item, null, "Addon incompatible with the product should not be visible");
michael@0 632
michael@0 633 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
michael@0 634 run_next_test();
michael@0 635 });
michael@0 636 });
michael@0 637 });
michael@0 638
michael@0 639
michael@0 640 // Tests that restarting the manager doesn't change search results
michael@0 641 add_test(function() {
michael@0 642 restart_manager(gManagerWindow, null, function(aWindow) {
michael@0 643 gManagerWindow = aWindow;
michael@0 644 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
michael@0 645
michael@0 646 // We never restore to the search pane
michael@0 647 is(gCategoryUtilities.selectedCategory, "discover", "View should have changed to discover");
michael@0 648
michael@0 649 // Installed add-on is considered local on new search
michael@0 650 gAddonInstalled = true;
michael@0 651
michael@0 652 search(QUERY, false, function() {
michael@0 653 check_filtered_results(QUERY, "relevancescore", false);
michael@0 654
michael@0 655 var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL));
michael@0 656 is(installBtn.hidden, true, "Install button should be hidden for installed item");
michael@0 657
michael@0 658 run_next_test();
michael@0 659 });
michael@0 660 });
michael@0 661 });
michael@0 662
michael@0 663 function bug_815120_test_search(aLocalOnly) {
michael@0 664 restart_manager(gManagerWindow, "addons://list/extension", function(aWindow) {
michael@0 665 gManagerWindow = aWindow;
michael@0 666 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
michael@0 667
michael@0 668 // Installed add-on is considered local on new search
michael@0 669 gAddonInstalled = true;
michael@0 670
michael@0 671 // The search buttons should be hidden in the LocalOnly setup
michael@0 672 var localFilterButton = aWindow.document.getElementById("search-filter-local");
michael@0 673 is(aLocalOnly, is_hidden(localFilterButton), "Local filter button visibility does not match, aLocalOnly = " + aLocalOnly);
michael@0 674
michael@0 675 var remoteFilterButton = aWindow.document.getElementById("search-filter-remote");
michael@0 676 is(aLocalOnly, is_hidden(remoteFilterButton), "Remote filter button visibility does not match, aLocalOnly = " + aLocalOnly);
michael@0 677
michael@0 678 search(QUERY, false, function() {
michael@0 679 check_filtered_results(QUERY, "relevancescore", false, aLocalOnly);
michael@0 680 run_next_test();
michael@0 681 });
michael@0 682 });
michael@0 683 }
michael@0 684
michael@0 685 // Tests for Bug 815120
michael@0 686 add_test(function() {
michael@0 687 Services.prefs.setBoolPref(PREF_XPI_ENABLED, false);
michael@0 688 bug_815120_test_search(true);
michael@0 689 });
michael@0 690
michael@0 691 add_test(function() {
michael@0 692 Services.prefs.setBoolPref(PREF_XPI_ENABLED, true);
michael@0 693 bug_815120_test_search(false);
michael@0 694 });
michael@0 695

mercurial