1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/mozapps/extensions/test/browser/browser_searching.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,695 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.6 + */ 1.7 + 1.8 +// Tests that searching for add-ons works correctly 1.9 + 1.10 +const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; 1.11 +const SEARCH_URL = TESTROOT + "browser_searching.xml"; 1.12 +const NO_MATCH_URL = TESTROOT + "browser_searching_empty.xml"; 1.13 + 1.14 +const QUERY = "SEARCH"; 1.15 +const NO_MATCH_QUERY = "NOMATCHQUERY"; 1.16 +const REMOTE_TO_INSTALL = "remote1"; 1.17 +const REMOTE_INSTALL_URL = TESTROOT + "addons/browser_searching.xpi"; 1.18 + 1.19 +var gManagerWindow; 1.20 +var gCategoryUtilities; 1.21 +var gProvider; 1.22 +var gServer; 1.23 +var gAddonInstalled = false; 1.24 + 1.25 +function test() { 1.26 + requestLongerTimeout(2); 1.27 + // Turn on searching for this test 1.28 + Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15); 1.29 + Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true); 1.30 + 1.31 + waitForExplicitFinish(); 1.32 + 1.33 + gProvider = new MockProvider(); 1.34 + 1.35 + gProvider.createAddons([{ 1.36 + id: "addon1@tests.mozilla.org", 1.37 + name: "PASS - f", 1.38 + description: "Test description - SEARCH", 1.39 + size: 3, 1.40 + version: "1.0", 1.41 + updateDate: new Date(2010, 4, 2, 0, 0, 1) 1.42 + }, { 1.43 + id: "fail-addon1@tests.mozilla.org", 1.44 + name: "FAIL", 1.45 + description: "Does not match query" 1.46 + }, { 1.47 + id: "addon2@tests.mozilla.org", 1.48 + name: "PASS - c", 1.49 + description: "Test description - reSEARCHing SEARCH SEARCH", 1.50 + size: 6, 1.51 + version: "2.0", 1.52 + updateDate: new Date(2010, 4, 2, 0, 0, 0) 1.53 + }]); 1.54 + 1.55 + var installs = gProvider.createInstalls([{ 1.56 + name: "PASS - a - SEARCHing", 1.57 + sourceURI: "http://example.com/install1.xpi" 1.58 + }, { 1.59 + name: "PASS - g - reSEARCHing SEARCH", 1.60 + sourceURI: "http://example.com/install2.xpi" 1.61 + }, { 1.62 + // Does not match query 1.63 + name: "FAIL", 1.64 + sourceURI: "http://example.com/fail-install1.xpi" 1.65 + }]); 1.66 + 1.67 + for (let install of installs ) 1.68 + install.install(); 1.69 + 1.70 + open_manager("addons://list/extension", function(aWindow) { 1.71 + gManagerWindow = aWindow; 1.72 + gCategoryUtilities = new CategoryUtilities(gManagerWindow); 1.73 + run_next_test(); 1.74 + }); 1.75 +} 1.76 + 1.77 +function end_test() { 1.78 + close_manager(gManagerWindow, function() { 1.79 + var installedAddon = get_addon_item(REMOTE_TO_INSTALL).mAddon; 1.80 + installedAddon.uninstall(); 1.81 + 1.82 + AddonManager.getAllInstalls(function(aInstallsList) { 1.83 + for (var install of aInstallsList) { 1.84 + var sourceURI = install.sourceURI.spec; 1.85 + if (sourceURI == REMOTE_INSTALL_URL || 1.86 + sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/) != null) 1.87 + install.cancel(); 1.88 + } 1.89 + 1.90 + finish(); 1.91 + }); 1.92 + }); 1.93 +} 1.94 + 1.95 +function getAnonymousElementByAttribute(aElement, aName, aValue) { 1.96 + return gManagerWindow.document.getAnonymousElementByAttribute(aElement, 1.97 + aName, 1.98 + aValue); 1.99 +} 1.100 + 1.101 +/* 1.102 + * Checks whether or not the Add-ons Manager is currently searching 1.103 + * 1.104 + * @param aExpectedSearching 1.105 + * The expected isSearching state 1.106 + */ 1.107 +function check_is_searching(aExpectedSearching) { 1.108 + var loading = gManagerWindow.document.getElementById("search-loading"); 1.109 + is(!is_hidden(loading), aExpectedSearching, 1.110 + "Search throbber should be showing iff currently searching"); 1.111 +} 1.112 + 1.113 +/* 1.114 + * Completes a search 1.115 + * 1.116 + * @param aQuery 1.117 + * The query to search for 1.118 + * @param aFinishImmediately 1.119 + * Boolean representing whether or not the search is expected to 1.120 + * finish immediately 1.121 + * @param aCallback 1.122 + * The callback to call when the search is done 1.123 + * @param aCategoryType 1.124 + * The expected selected category after the search is done. 1.125 + * Optional and defaults to "search" 1.126 + */ 1.127 +function search(aQuery, aFinishImmediately, aCallback, aCategoryType) { 1.128 + // Point search to the correct xml test file 1.129 + var url = (aQuery == NO_MATCH_QUERY) ? NO_MATCH_URL : SEARCH_URL; 1.130 + Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, url); 1.131 + 1.132 + aCategoryType = aCategoryType ? aCategoryType : "search"; 1.133 + 1.134 + var searchBox = gManagerWindow.document.getElementById("header-search"); 1.135 + searchBox.value = aQuery; 1.136 + 1.137 + EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow); 1.138 + EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow); 1.139 + 1.140 + var finishImmediately = true; 1.141 + wait_for_view_load(gManagerWindow, function() { 1.142 + is(gCategoryUtilities.selectedCategory, aCategoryType, "Expected category view should be selected"); 1.143 + is(gCategoryUtilities.isTypeVisible("search"), aCategoryType == "search", 1.144 + "Search category should only be visible if it is the current view"); 1.145 + check_is_searching(false); 1.146 + is(finishImmediately, aFinishImmediately, "Search should finish immediately only if expected"); 1.147 + 1.148 + aCallback(); 1.149 + }); 1.150 + 1.151 + finishImmediately = false 1.152 + if (!aFinishImmediately) 1.153 + check_is_searching(true); 1.154 +} 1.155 + 1.156 +/* 1.157 + * Return results of a search 1.158 + * 1.159 + * @return Array of objects, each containing the name and item of a specific 1.160 + * result 1.161 + */ 1.162 +function get_actual_results() { 1.163 + var list = gManagerWindow.document.getElementById("search-list"); 1.164 + var rows = list.getElementsByTagName("richlistitem"); 1.165 + 1.166 + var results = []; 1.167 + for (var item of rows) { 1.168 + 1.169 + // Only consider items that are currently showing 1.170 + var style = gManagerWindow.document.defaultView.getComputedStyle(item, ""); 1.171 + if (style.display == "none" || style.visibility != "visible") 1.172 + continue; 1.173 + 1.174 + if (item.mInstall || item.isPending("install")) { 1.175 + var sourceURI = item.mInstall.sourceURI.spec; 1.176 + if (sourceURI == REMOTE_INSTALL_URL) { 1.177 + results.push({name: REMOTE_TO_INSTALL, item: item}); 1.178 + continue; 1.179 + } 1.180 + 1.181 + var result = sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/); 1.182 + if (result != null) { 1.183 + is(item.mInstall.name.indexOf("PASS"), 0, "Install name should start with PASS"); 1.184 + results.push({name: result[1], item: item}); 1.185 + continue; 1.186 + } 1.187 + } 1.188 + else if (item.mAddon) { 1.189 + var result = item.mAddon.id.match(/^(.+)@tests\.mozilla\.org$/); 1.190 + if (result != null) { 1.191 + is(item.mAddon.name.indexOf("PASS"), 0, "Addon name should start with PASS"); 1.192 + results.push({name: result[1], item: item}); 1.193 + continue; 1.194 + } 1.195 + } 1.196 + else { 1.197 + ok(false, "Found an item in the list that was neither installing or installed"); 1.198 + } 1.199 + } 1.200 + 1.201 + return results; 1.202 +} 1.203 + 1.204 +/* 1.205 + * Returns expected results when searching for QUERY with default ordering 1.206 + * 1.207 + * @param aSortBy 1.208 + * How the results are sorted (e.g. "name") 1.209 + * @param aLocalExpected 1.210 + * Boolean representing if local results are expected 1.211 + * @return A pair: [array of results with an expected order, 1.212 + * array of results with unknown order] 1.213 + */ 1.214 +function get_expected_results(aSortBy, aLocalExpected) { 1.215 + var expectedOrder = null, unknownOrder = null; 1.216 + switch (aSortBy) { 1.217 + case "relevancescore": 1.218 + expectedOrder = [ "addon2" , "remote1", "install2", "addon1", 1.219 + "install1", "remote2", "remote3" , "remote4" ]; 1.220 + unknownOrder = []; 1.221 + break; 1.222 + case "name": 1.223 + // Defaults to ascending order 1.224 + expectedOrder = [ "install1", "remote1", "addon2" , "remote2", 1.225 + "remote3" , "addon1" , "install2", "remote4" ]; 1.226 + unknownOrder = []; 1.227 + break; 1.228 + case "dateUpdated": 1.229 + expectedOrder = [ "addon1", "addon2" ]; 1.230 + // Updated date not available for installs and remote add-ons 1.231 + unknownOrder = [ "install1", "install2", "remote1", 1.232 + "remote2" , "remote3" , "remote4" ]; 1.233 + break; 1.234 + default: 1.235 + ok(false, "Should recognize sortBy when checking the order of items"); 1.236 + } 1.237 + 1.238 + // Only keep expected results 1.239 + function filterResults(aId) { 1.240 + // Include REMOTE_TO_INSTALL as a local add-on if it has been installed 1.241 + if (gAddonInstalled && aId == REMOTE_TO_INSTALL) 1.242 + return aLocalExpected; 1.243 + 1.244 + if (aId.indexOf("addon") == 0 || aId.indexOf("install") == 0) 1.245 + return aLocalExpected; 1.246 + if (aId.indexOf("remote") == 0) 1.247 + return !aLocalExpected; 1.248 + 1.249 + return false; 1.250 + } 1.251 + 1.252 + 1.253 + return [expectedOrder.filter(filterResults), 1.254 + unknownOrder.filter(filterResults)] 1.255 +} 1.256 + 1.257 +/* 1.258 + * Check that the actual and expected results are the same 1.259 + * 1.260 + * @param aQuery 1.261 + * The search query used 1.262 + * @param aSortBy 1.263 + * How the results are sorted (e.g. "name") 1.264 + * @param aReverseOrder 1.265 + * Boolean representing if the results are in reverse default order 1.266 + * @param aShowLocal 1.267 + * Boolean representing if local results are being shown 1.268 + */ 1.269 +function check_results(aQuery, aSortBy, aReverseOrder, aShowLocal) { 1.270 + 1.271 + var xpinstall_enabled = true; 1.272 + try { 1.273 + xpinstall_enabled = Services.prefs.getBoolPref(PREF_XPI_ENABLED); 1.274 + } 1.275 + catch (e) {}; 1.276 + 1.277 + // When XPI Instalation is disabled, those buttons are hidden and unused 1.278 + if (xpinstall_enabled) { 1.279 + var localFilterSelected = gManagerWindow.document.getElementById("search-filter-local").selected; 1.280 + var remoteFilterSelected = gManagerWindow.document.getElementById("search-filter-remote").selected; 1.281 + is(localFilterSelected, aShowLocal, "Local filter should be selected if showing local items"); 1.282 + is(remoteFilterSelected, !aShowLocal, "Remote filter should be selected if showing remote items"); 1.283 + } 1.284 + 1.285 + // Get expected order assuming default order 1.286 + var expectedOrder = [], unknownOrder = []; 1.287 + if (aQuery == QUERY) 1.288 + [expectedOrder, unknownOrder] = get_expected_results(aSortBy, aShowLocal); 1.289 + 1.290 + // Get actual order of results 1.291 + var actualResults = get_actual_results(); 1.292 + var actualOrder = [result.name for each(result in actualResults)]; 1.293 + 1.294 + // Reverse array of actual results if supposed to be in reverse order. 1.295 + // Reverse actualOrder instead of expectedOrder so can always check 1.296 + // expectedOrder before unknownOrder 1.297 + if (aReverseOrder) 1.298 + actualOrder.reverse(); 1.299 + 1.300 + // Check actual vs. expected list of results 1.301 + var totalExpectedResults = expectedOrder.length + unknownOrder.length; 1.302 + is(actualOrder.length, totalExpectedResults, "Should get correct number of results"); 1.303 + 1.304 + // Check the "first" and "last" attributes are set correctly 1.305 + for (let i = 0; i < actualResults.length; i++) { 1.306 + if (i == 0) { 1.307 + is(actualResults[0].item.hasAttribute("first"), true, 1.308 + "First item should have 'first' attribute set"); 1.309 + is(actualResults[0].item.hasAttribute("last"), false, 1.310 + "First item should not have 'last' attribute set"); 1.311 + } else if (i == (actualResults.length - 1)) { 1.312 + is(actualResults[actualResults.length - 1].item.hasAttribute("first"), false, 1.313 + "Last item should not have 'first' attribute set"); 1.314 + is(actualResults[actualResults.length - 1].item.hasAttribute("last"), true, 1.315 + "Last item should have 'last' attribute set"); 1.316 + } else { 1.317 + is(actualResults[i].item.hasAttribute("first"), false, 1.318 + "Item " + i + " should not have 'first' attribute set"); 1.319 + is(actualResults[i].item.hasAttribute("last"), false, 1.320 + "Item " + i + " should not have 'last' attribute set"); 1.321 + } 1.322 + } 1.323 + 1.324 + var i = 0; 1.325 + for (; i < expectedOrder.length; i++) 1.326 + is(actualOrder[i], expectedOrder[i], "Should have seen expected item"); 1.327 + 1.328 + // Items with data that is unknown can appear in any order among themselves, 1.329 + // so just check that these items exist 1.330 + for (; i < actualOrder.length; i++) { 1.331 + var unknownOrderIndex = unknownOrder.indexOf(actualOrder[i]); 1.332 + ok(unknownOrderIndex >= 0, "Should expect to see item with data that is unknown"); 1.333 + unknownOrder[unknownOrderIndex] = null; 1.334 + } 1.335 + 1.336 + // Check status of empty notice 1.337 + var emptyNotice = gManagerWindow.document.getElementById("search-list-empty"); 1.338 + is(emptyNotice.hidden, totalExpectedResults > 0, 1.339 + "Empty notice should be hidden only if expecting shown items"); 1.340 +} 1.341 + 1.342 +/* 1.343 + * Check results of a search with different filterings 1.344 + * 1.345 + * @param aQuery 1.346 + * The search query used 1.347 + * @param aSortBy 1.348 + * How the results are sorted (e.g. "name") 1.349 + * @param aReverseOrder 1.350 + * Boolean representing if the results are in reverse default order 1.351 + * @param aLocalOnly 1.352 + * Boolean representing if the results are local only, can be undefined 1.353 + */ 1.354 +function check_filtered_results(aQuery, aSortBy, aReverseOrder, aLocalOnly) { 1.355 + var localFilter = gManagerWindow.document.getElementById("search-filter-local"); 1.356 + var remoteFilter = gManagerWindow.document.getElementById("search-filter-remote"); 1.357 + 1.358 + var list = gManagerWindow.document.getElementById("search-list"); 1.359 + list.ensureElementIsVisible(localFilter); 1.360 + 1.361 + // Check with showing local add-ons 1.362 + EventUtils.synthesizeMouseAtCenter(localFilter, { }, gManagerWindow); 1.363 + check_results(aQuery, aSortBy, aReverseOrder, true); 1.364 + 1.365 + // Check with showing remote add-ons 1.366 + aLocalOnly = aLocalOnly || false; 1.367 + EventUtils.synthesizeMouseAtCenter(remoteFilter, { }, gManagerWindow); 1.368 + check_results(aQuery, aSortBy, aReverseOrder, aLocalOnly); 1.369 +} 1.370 + 1.371 +/* 1.372 + * Get item for a specific add-on by name 1.373 + * 1.374 + * @param aName 1.375 + * The name of the add-on to search for 1.376 + * @return Row of add-on if found, null otherwise 1.377 + */ 1.378 +function get_addon_item(aName) { 1.379 + var id = aName + "@tests.mozilla.org"; 1.380 + var list = gManagerWindow.document.getElementById("search-list"); 1.381 + var rows = list.getElementsByTagName("richlistitem"); 1.382 + for (var row of rows) { 1.383 + if (row.mAddon && row.mAddon.id == id) 1.384 + return row; 1.385 + } 1.386 + 1.387 + return null; 1.388 +} 1.389 + 1.390 +/* 1.391 + * Get item for a specific install by name 1.392 + * 1.393 + * @param aName 1.394 + * The name of the install to search for 1.395 + * @return Row of install if found, null otherwise 1.396 + */ 1.397 +function get_install_item(aName) { 1.398 + var sourceURI = "http://example.com/" + aName + ".xpi"; 1.399 + var list = gManagerWindow.document.getElementById("search-list"); 1.400 + var rows = list.getElementsByTagName("richlistitem"); 1.401 + for (var row of rows) { 1.402 + if (row.mInstall && row.mInstall.sourceURI.spec == sourceURI) 1.403 + return row; 1.404 + } 1.405 + 1.406 + return null; 1.407 +} 1.408 + 1.409 +/* 1.410 + * Gets the install button for a specific item 1.411 + * 1.412 + * @param aItem 1.413 + * The item to get the install button for 1.414 + * @return The install button for aItem 1.415 + */ 1.416 +function get_install_button(aItem) { 1.417 + isnot(aItem, null, "Item should not be null when checking state of install button"); 1.418 + var installStatus = getAnonymousElementByAttribute(aItem, "anonid", "install-status"); 1.419 + return getAnonymousElementByAttribute(installStatus, "anonid", "install-remote-btn"); 1.420 +} 1.421 + 1.422 + 1.423 +// Tests that searching for the empty string does nothing when not in the search view 1.424 +add_test(function() { 1.425 + is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should initially be hidden"); 1.426 + 1.427 + var selectedCategory = gCategoryUtilities.selectedCategory; 1.428 + isnot(selectedCategory, "search", "Selected type should not initially be the search view"); 1.429 + search("", true, run_next_test, selectedCategory); 1.430 +}); 1.431 + 1.432 +// Tests that the results from a query are sorted by relevancescore in descending order. 1.433 +// Also test that double clicking non-install items goes to the detail view, and that 1.434 +// only remote items have install buttons showing 1.435 +add_test(function() { 1.436 + search(QUERY, false, function() { 1.437 + check_filtered_results(QUERY, "relevancescore", false); 1.438 + 1.439 + var list = gManagerWindow.document.getElementById("search-list"); 1.440 + var results = get_actual_results(); 1.441 + for (var result of results) { 1.442 + var installBtn = get_install_button(result.item); 1.443 + is(installBtn.hidden, result.name.indexOf("remote") != 0, 1.444 + "Install button should only be showing for remote items"); 1.445 + } 1.446 + 1.447 + var currentIndex = -1; 1.448 + function run_next_double_click_test() { 1.449 + currentIndex++; 1.450 + if (currentIndex >= results.length) { 1.451 + run_next_test(); 1.452 + return; 1.453 + } 1.454 + 1.455 + var result = results[currentIndex]; 1.456 + if (result.name.indexOf("install") == 0) { 1.457 + run_next_double_click_test(); 1.458 + return; 1.459 + } 1.460 + 1.461 + var item = result.item; 1.462 + list.ensureElementIsVisible(item); 1.463 + EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow); 1.464 + EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow); 1.465 + wait_for_view_load(gManagerWindow, function() { 1.466 + var name = gManagerWindow.document.getElementById("detail-name").textContent; 1.467 + is(name, item.mAddon.name, "Name in detail view should be correct"); 1.468 + var version = gManagerWindow.document.getElementById("detail-version").value; 1.469 + is(version, item.mAddon.version, "Version in detail view should be correct"); 1.470 + 1.471 + EventUtils.synthesizeMouseAtCenter(gManagerWindow.document.getElementById("category-search"), 1.472 + { }, gManagerWindow); 1.473 + wait_for_view_load(gManagerWindow, run_next_double_click_test); 1.474 + }); 1.475 + } 1.476 + 1.477 + run_next_double_click_test(); 1.478 + }); 1.479 +}); 1.480 + 1.481 +// Tests that the sorters and filters correctly manipulate the results 1.482 +add_test(function() { 1.483 + var sorters = gManagerWindow.document.getElementById("search-sorters"); 1.484 + var originalHandler = sorters.handler; 1.485 + 1.486 + var sorterNames = ["name", "dateUpdated"]; 1.487 + var buttonIds = ["name-btn", "date-btn"]; 1.488 + var currentIndex = 0; 1.489 + var currentReversed = false; 1.490 + 1.491 + function run_sort_test() { 1.492 + if (currentIndex >= sorterNames.length) { 1.493 + sorters.handler = originalHandler; 1.494 + run_next_test(); 1.495 + return; 1.496 + } 1.497 + 1.498 + // Simulate clicking on a specific sorter 1.499 + var buttonId = buttonIds[currentIndex]; 1.500 + var sorter = getAnonymousElementByAttribute(sorters, "anonid", buttonId); 1.501 + is_element_visible(sorter); 1.502 + EventUtils.synthesizeMouseAtCenter(sorter, { }, gManagerWindow); 1.503 + } 1.504 + 1.505 + sorters.handler = { 1.506 + onSortChanged: function(aSortBy, aAscending) { 1.507 + if (originalHandler && "onSortChanged" in originalHandler) 1.508 + originalHandler.onSortChanged(aSortBy, aAscending); 1.509 + 1.510 + check_filtered_results(QUERY, sorterNames[currentIndex], currentReversed); 1.511 + 1.512 + if (currentReversed) 1.513 + currentIndex++; 1.514 + currentReversed = !currentReversed; 1.515 + 1.516 + run_sort_test(); 1.517 + } 1.518 + }; 1.519 + 1.520 + check_filtered_results(QUERY, "relevancescore", false); 1.521 + run_sort_test(); 1.522 +}); 1.523 + 1.524 +// Tests that searching for the empty string does nothing when in search view 1.525 +add_test(function() { 1.526 + search("", true, function() { 1.527 + check_filtered_results(QUERY, "dateUpdated", true); 1.528 + run_next_test(); 1.529 + }); 1.530 +}); 1.531 + 1.532 +// Tests that clicking a different category hides the search query 1.533 +add_test(function() { 1.534 + gCategoryUtilities.openType("extension", function() { 1.535 + is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden"); 1.536 + is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension"); 1.537 + run_next_test(); 1.538 + }); 1.539 +}); 1.540 + 1.541 +// Tests that re-searching for query doesn't actually complete a new search, 1.542 +// and the last sort is still used 1.543 +add_test(function() { 1.544 + search(QUERY, true, function() { 1.545 + check_filtered_results(QUERY, "dateUpdated", true); 1.546 + run_next_test(); 1.547 + }); 1.548 +}); 1.549 + 1.550 +// Tests that getting zero results works correctly 1.551 +add_test(function() { 1.552 + search(NO_MATCH_QUERY, false, function() { 1.553 + check_filtered_results(NO_MATCH_QUERY, "relevancescore", false); 1.554 + run_next_test(); 1.555 + }); 1.556 +}); 1.557 + 1.558 +// Tests that installing a remote add-on works 1.559 +add_test(function() { 1.560 + var installBtn = null; 1.561 + 1.562 + var listener = { 1.563 + onInstallEnded: function(aInstall, aAddon) { 1.564 + // Don't immediately consider the installed add-on as local because 1.565 + // if the user was filtering out local add-ons, the installed add-on 1.566 + // would vanish. Only consider add-on as local on new searches. 1.567 + 1.568 + aInstall.removeListener(this); 1.569 + 1.570 + is(installBtn.hidden, true, "Install button should be hidden after install ended"); 1.571 + check_filtered_results(QUERY, "relevancescore", false); 1.572 + run_next_test(); 1.573 + } 1.574 + } 1.575 + 1.576 + search(QUERY, false, function() { 1.577 + var list = gManagerWindow.document.getElementById("search-list"); 1.578 + var remoteItem = get_addon_item(REMOTE_TO_INSTALL); 1.579 + list.ensureElementIsVisible(remoteItem); 1.580 + 1.581 + installBtn = get_install_button(remoteItem); 1.582 + is(installBtn.hidden, false, "Install button should be showing before install"); 1.583 + remoteItem.mAddon.install.addListener(listener); 1.584 + EventUtils.synthesizeMouseAtCenter(installBtn, { }, gManagerWindow); 1.585 + }); 1.586 +}); 1.587 + 1.588 +// Tests that re-searching for query results in correct results 1.589 +add_test(function() { 1.590 + // Select a different category 1.591 + gCategoryUtilities.openType("extension", function() { 1.592 + is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden"); 1.593 + is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension"); 1.594 + 1.595 + var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL)); 1.596 + is(installBtn.hidden, true, "Install button should be hidden for installed item"); 1.597 + 1.598 + search(QUERY, true, function() { 1.599 + check_filtered_results(QUERY, "relevancescore", false); 1.600 + run_next_test(); 1.601 + }); 1.602 + }); 1.603 +}); 1.604 + 1.605 +// Tests that incompatible add-ons are shown with a warning if compatibility checking is disabled 1.606 +add_test(function() { 1.607 + AddonManager.checkCompatibility = false; 1.608 + search("incompatible", false, function() { 1.609 + var item = get_addon_item("remote5"); 1.610 + is_element_visible(item, "Incompatible addon should be visible"); 1.611 + is(item.getAttribute("notification"), "warning", "Compatibility warning should be shown"); 1.612 + 1.613 + item = get_addon_item("remote6"); 1.614 + is(item, null, "Addon incompatible with the product should not be visible"); 1.615 + 1.616 + AddonManager.checkCompatibility = true; 1.617 + run_next_test(); 1.618 + }); 1.619 +}); 1.620 + 1.621 +// Tests that compatible-by-default addons are shown if strict compatibility checking is disabled 1.622 +add_test(function() { 1.623 + restart_manager(gManagerWindow, null, function(aWindow) { 1.624 + gManagerWindow = aWindow; 1.625 + gCategoryUtilities = new CategoryUtilities(gManagerWindow); 1.626 + 1.627 + Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false); 1.628 + search("incompatible", false, function() { 1.629 + var item = get_addon_item("remote5"); 1.630 + is_element_visible(item, "Incompatible addon should be visible"); 1.631 + isnot(item.getAttribute("notification"), "warning", "Compatibility warning should not be shown"); 1.632 + 1.633 + var item = get_addon_item("remote6"); 1.634 + is(item, null, "Addon incompatible with the product should not be visible"); 1.635 + 1.636 + Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true); 1.637 + run_next_test(); 1.638 + }); 1.639 + }); 1.640 +}); 1.641 + 1.642 + 1.643 +// Tests that restarting the manager doesn't change search results 1.644 +add_test(function() { 1.645 + restart_manager(gManagerWindow, null, function(aWindow) { 1.646 + gManagerWindow = aWindow; 1.647 + gCategoryUtilities = new CategoryUtilities(gManagerWindow); 1.648 + 1.649 + // We never restore to the search pane 1.650 + is(gCategoryUtilities.selectedCategory, "discover", "View should have changed to discover"); 1.651 + 1.652 + // Installed add-on is considered local on new search 1.653 + gAddonInstalled = true; 1.654 + 1.655 + search(QUERY, false, function() { 1.656 + check_filtered_results(QUERY, "relevancescore", false); 1.657 + 1.658 + var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL)); 1.659 + is(installBtn.hidden, true, "Install button should be hidden for installed item"); 1.660 + 1.661 + run_next_test(); 1.662 + }); 1.663 + }); 1.664 +}); 1.665 + 1.666 +function bug_815120_test_search(aLocalOnly) { 1.667 + restart_manager(gManagerWindow, "addons://list/extension", function(aWindow) { 1.668 + gManagerWindow = aWindow; 1.669 + gCategoryUtilities = new CategoryUtilities(gManagerWindow); 1.670 + 1.671 + // Installed add-on is considered local on new search 1.672 + gAddonInstalled = true; 1.673 + 1.674 + // The search buttons should be hidden in the LocalOnly setup 1.675 + var localFilterButton = aWindow.document.getElementById("search-filter-local"); 1.676 + is(aLocalOnly, is_hidden(localFilterButton), "Local filter button visibility does not match, aLocalOnly = " + aLocalOnly); 1.677 + 1.678 + var remoteFilterButton = aWindow.document.getElementById("search-filter-remote"); 1.679 + is(aLocalOnly, is_hidden(remoteFilterButton), "Remote filter button visibility does not match, aLocalOnly = " + aLocalOnly); 1.680 + 1.681 + search(QUERY, false, function() { 1.682 + check_filtered_results(QUERY, "relevancescore", false, aLocalOnly); 1.683 + run_next_test(); 1.684 + }); 1.685 + }); 1.686 +} 1.687 + 1.688 +// Tests for Bug 815120 1.689 +add_test(function() { 1.690 + Services.prefs.setBoolPref(PREF_XPI_ENABLED, false); 1.691 + bug_815120_test_search(true); 1.692 +}); 1.693 + 1.694 +add_test(function() { 1.695 + Services.prefs.setBoolPref(PREF_XPI_ENABLED, true); 1.696 + bug_815120_test_search(false); 1.697 +}); 1.698 +