Bug 1546248 - Add notice to discopane when TAAR is enabled r=mstriemer,flod
authorRob Wu <rob@robwu.nl>
Thu, 09 May 2019 14:22:16 +0000
changeset 473219 76eb966c5aa706e93e06e9b463bb1d305ff1b7f4
parent 473218 23d7d4098ba3d98352b9d018161b2a676c3e5500
child 473220 53535f2ceb4c5569b7aa615ec1aee176bed92e17
push id35991
push usernbeleuzu@mozilla.com
push dateThu, 09 May 2019 21:40:43 +0000
treeherdermozilla-central@912b44cef0bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstriemer, flod
bugs1546248
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1546248 - Add notice to discopane when TAAR is enabled r=mstriemer,flod The `<message-bar>` custom element used in this patch will be introduced by https://phabricator.services.mozilla.com/D27547 The notice text and SUMO link target were taken from https://github.com/mozilla/addons-frontend/blob/6d2de7e52a2ff8d50d4ab1181974c39a3a7f1d8f/src/disco/pages/DiscoPane/index.js#L211-L213 Differential Revision: https://phabricator.services.mozilla.com/D29477
toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
toolkit/mozapps/extensions/content/aboutaddons.html
toolkit/mozapps/extensions/content/aboutaddons.js
toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js
toolkit/mozapps/extensions/test/browser/browser_html_discover_view_clientid.js
--- a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
+++ b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
@@ -350,16 +350,22 @@ go-back-button =
 discopane-intro =
     Extensions and themes are like apps for your browser, and they let you
     protect passwords, download videos, find deals, block annoying ads, change
     how your browser looks, and much more. These small software programs are
     often developed by a third party. Here’s a selection { -brand-product-name }
     <a data-l10n-name="learn-more-trigger">recommends</a> for exceptional
     security, performance, and functionality.
 
+# Notice to make user aware that the recommendations are personalized.
+discopane-notice-recommendations =
+    Some of these recommendations are personalized. They are based on other
+    extensions you’ve installed, profile preferences, and usage statistics.
+discopane-notice-learn-more = Learn more
+
 privacy-policy = Privacy Policy
 
 # Refers to the author of an add-on, shown below the name of the add-on.
 # Variables:
 #   $author (string) - The name of the add-on developer.
 created-by-author = by <a data-l10n-name="author">{ $author }</a>
 install-extension-button = Add to { -brand-product-name }
 install-theme-button = Install Theme
--- a/toolkit/mozapps/extensions/content/aboutaddons.html
+++ b/toolkit/mozapps/extensions/content/aboutaddons.html
@@ -170,16 +170,22 @@
             <a
               class="discopane-intro-learn-more-link"
               data-l10n-name="learn-more-trigger"
               target="_blank">
             </a>
           </span>
         </p>
       </header>
+      <message-bar class="discopane-notice">
+        <div class="discopane-notice-content">
+          <span data-l10n-id="discopane-notice-recommendations"></span>
+          <button data-l10n-id="discopane-notice-learn-more" action="notice-learn-more"></button>
+        </div>
+      </message-bar>
       <recommended-addon-list></recommended-addon-list>
       <footer class="discopane-footer">
         <div>
           <button class="primary" action="open-amo" data-l10n-id="find-more-addons"></button>
         </div>
         <div>
           <a
             class="discopane-privacy-policy-link"
--- a/toolkit/mozapps/extensions/content/aboutaddons.js
+++ b/toolkit/mozapps/extensions/content/aboutaddons.js
@@ -1672,29 +1672,36 @@ customElements.define("recommended-addon
 
 class DiscoveryPane extends HTMLElement {
   render() {
     this.append(importTemplate("discopane"));
     this.querySelector(".discopane-intro-learn-more-link").href =
       Services.urlFormatter.formatURLPref("app.support.baseURL") +
       "recommended-extensions-program";
 
+    this.querySelector(".discopane-notice").hidden =
+      !DiscoveryAPI.clientIdDiscoveryEnabled;
     this.addEventListener("click", this);
 
     // Hide footer until the cards is loaded, to prevent the content from
     // suddenly shifting when the user attempts to interact with it.
     let footer = this.querySelector("footer");
     footer.hidden = true;
     this.querySelector("recommended-addon-list").loadCardsIfNeeded()
       .finally(() => { footer.hidden = false; });
   }
 
   handleEvent(event) {
     let action = event.target.getAttribute("action");
     switch (action) {
+      case "notice-learn-more":
+        windowRoot.ownerGlobal.openTrustedLinkIn(
+          Services.urlFormatter.formatURLPref("app.support.baseURL") +
+          "personalized-extension-recommendations", "tab");
+        break;
       case "open-amo":
         windowRoot.ownerGlobal.openTrustedLinkIn(
           Services.urlFormatter.formatURLPref("extensions.getAddons.link.url"),
           "tab");
         break;
     }
   }
 }
--- a/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js
@@ -256,16 +256,19 @@ async function testAddonUninstall(card) 
 }
 
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({
     set: [
       ["extensions.getAddons.discovery.api_url",
        `http://${AMO_TEST_HOST}/discoapi`],
       ["extensions.htmlaboutaddons.enabled", true],
+      // Disable the telemetry client ID (and its associated UI warning).
+      // browser_html_discover_view_clientid.js covers this functionality.
+      ["browser.discovery.enabled", false],
     ],
   });
 });
 
 // Test that the discopane can be loaded and that meaningful results are shown.
 // This relies on response data from the AMO API, stored in API_RESPONSE_FILE.
 add_task(async function discopane_with_real_api_data() {
   const apiText = await readAPIResponseFixture();
--- a/toolkit/mozapps/extensions/test/browser/browser_html_discover_view_clientid.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_html_discover_view_clientid.js
@@ -5,16 +5,20 @@ const {ClientID} = ChromeUtils.import("r
 
 const {
   AddonTestUtils,
 } = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
 
 AddonTestUtils.initMochitest(this);
 const server = AddonTestUtils.createHttpServer();
 const serverBaseUrl = `http://localhost:${server.identity.primaryPort}/`;
+server.registerPathHandler("/sumo/personalized-extension-recommendations",
+  (request, response) => {
+    response.write("This is a SUMO page that explains personalized add-ons.");
+  });
 
 // Before a discovery API request is triggered, this method should be called.
 // Resolves with the value of the "telemetry-client-id" query parameter.
 async function promiseOneDiscoveryApiRequest() {
   return new Promise(resolve => {
     let requestCount = 0;
     // Overwrite previous request handler, if any.
     server.registerPathHandler("/discoapi", (request, response) => {
@@ -22,48 +26,73 @@ async function promiseOneDiscoveryApiReq
       response.write(`{"results": []}`);
       let searchParams = new URLSearchParams(request.queryString);
       let clientId = searchParams.get("telemetry-client-id");
       resolve(clientId);
     });
   });
 }
 
+function getNoticeButton(win) {
+  return win.document.querySelector("[action='notice-learn-more']");
+}
+
+function isNoticeVisible(win) {
+  return getNoticeButton(win).closest("message-bar").offsetHeight > 0;
+}
+
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({
     set: [
       // Enable clientid - see Discovery.jsm for the first two prefs.
       ["browser.discovery.enabled", true],
       ["datareporting.healthreport.uploadEnabled", true],
       ["extensions.getAddons.discovery.api_url", `${serverBaseUrl}discoapi`],
+      ["app.support.baseURL", `${serverBaseUrl}sumo/`],
       ["extensions.htmlaboutaddons.enabled", true],
     ],
   });
 });
 
 // Test that the clientid is passed to the API when enabled via prefs.
 add_task(async function clientid_enabled() {
   let EXPECTED_CLIENT_ID = await ClientID.getClientIdHash();
   ok(EXPECTED_CLIENT_ID, "ClientID should be available");
 
   let requestPromise = promiseOneDiscoveryApiRequest();
   let win = await loadInitialView("discover");
+
+  ok(isNoticeVisible(win), "Notice about personalization should be visible");
+
   is(await requestPromise, EXPECTED_CLIENT_ID,
      "Moz-Client-Id should be set when telemetry & discovery are enabled");
+
+  let tabbrowser = win.windowRoot.ownerGlobal.gBrowser;
+  let expectedUrl =
+    `${serverBaseUrl}sumo/personalized-extension-recommendations`;
+  let tabPromise = BrowserTestUtils.waitForNewTab(tabbrowser, expectedUrl);
+
+  getNoticeButton(win).click();
+
+  info(`Waiting for new tab with URL: ${expectedUrl}`);
+  let tab = await tabPromise;
+  BrowserTestUtils.removeTab(tab);
+
   await closeView(win);
 });
 
 // Test that the clientid is not sent when disabled via prefs.
 add_task(async function clientid_disabled() {
   // Temporarily override the prefs that we had set in setup.
   await SpecialPowers.pushPrefEnv({
     set: [["browser.discovery.enabled", false]],
   });
   let requestPromise = promiseOneDiscoveryApiRequest();
   let win = await loadInitialView("discover");
+  ok(!isNoticeVisible(win), "Notice about personalization should be hidden");
   is(await requestPromise, null,
      "Moz-Client-Id should not be sent when discovery is disabled");
   await closeView(win);
   await SpecialPowers.popPrefEnv();
 });
 
 // Test that the clientid is not sent from private windows.
 add_task(async function clientid_from_private_window() {