Bug 1653119 - redesign Pioneer study cards, and include new schema plus validation for mock r=fluent-reviewers,sfoster
authorRobert Helmer <rhelmer@mozilla.com>
Thu, 06 Aug 2020 19:57:27 +0000
changeset 543683 b41de9e8fd9a2c93f2e64833a230d72f8c16374e
parent 543682 4101493c2f41fdcea2d14635215d5babde0a8064
child 543684 9b48053f30035789d9c05aa2847c70b9bb892103
push id123616
push userrhelmer@mozilla.com
push dateThu, 06 Aug 2020 21:49:18 +0000
treeherderautoland@b41de9e8fd9a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfluent-reviewers, sfoster
bugs1653119
milestone81.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 1653119 - redesign Pioneer study cards, and include new schema plus validation for mock r=fluent-reviewers,sfoster Differential Revision: https://phabricator.services.mozilla.com/D85537
browser/components/pioneer/content/pioneer.css
browser/components/pioneer/content/pioneer.ftl
browser/components/pioneer/content/pioneer.html
browser/components/pioneer/content/pioneer.js
browser/components/pioneer/moz.build
browser/components/pioneer/schemas/PioneerStudyAddonsSchema.json
browser/components/pioneer/test/browser/browser_pioneer_ui.js
--- a/browser/components/pioneer/content/pioneer.css
+++ b/browser/components/pioneer/content/pioneer.css
@@ -53,36 +53,43 @@ details > summary {
 
 .card-name {
   margin: 0;
   font-size: 16px;
   font-weight: 600;
   line-height: 1;
 }
 
-.card-creator {
+.card-author {
   margin: 0;
   font-size: 14px;
   font-weight: 400;
 }
 
 .card-actions {
   align-self: center;
   flex-shrink: 0;
+  min-width: 120px;
 }
 
 .join-button {
   max-width: 200px;
   margin: 0;
   margin-inline-end: 16px;
 }
 
 .card-description {
   font-size: 14px;
   font-weight: normal;
+  width: 100%;
+}
+
+.card-data-collected {
+  font-size: 14px;
+  font-weight: normal;
 }
 
 *[hidden] {
   display: none !important;
 }
 
 #pioneer-icon {
   -moz-context-properties: fill;
--- a/browser/components/pioneer/content/pioneer.ftl
+++ b/browser/components/pioneer/content/pioneer.ftl
@@ -8,12 +8,13 @@
 
 -pioneer-brand-short-name = Pioneer
 pioneer = { -pioneer-brand-short-name }
 pioneer-title = Introducing { -brand-short-name } { -pioneer-brand-short-name }
 pioneer-summary = { -pioneer-brand-short-name } is an experimental program that allows you to donate your data to public interest scientific studies in areas such as internet misinformation, data privacy, and ethical AI.
 pioneer-voluntary-notice = Participation in { -pioneer-brand-short-name } is strictly voluntary.
 pioneer-details = When you enroll in the { -pioneer-brand-short-name } program, you will receive periodic offers to join studies led by top research teams in collaborations with Mozilla. Your participation in each study is voluntary. You can leave an individual study or leave the { -pioneer-brand-short-name } program entirely at any time.
 pioneer-join-study = Join Study
+pioneer-leave-study = Leave Study
 pioneer-enrollment-button = Enroll
 pioneer-unenrollment-button = Leave
 pioneer-available-studies = Available Studies
 pioneer-end-study = End Study
--- a/browser/components/pioneer/content/pioneer.html
+++ b/browser/components/pioneer/content/pioneer.html
@@ -7,17 +7,16 @@
   <head>
     <meta charset="utf-8">
     <meta http-equiv="Content-Security-Policy" content="default-src chrome: blob:; img-src https:; object-src 'none'">
     <link rel="localization" href="browser/branding/brandings.ftl">
     <link rel="localization" href="branding/brand.ftl">
     <!-- Temporary "en-US"-only l10n strings -->
     <link rel="localization" href="preview/pioneer.ftl">
     <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
-    <link rel="stylesheet" href="chrome://global/skin/in-content/toggle-button.css">
     <link rel="stylesheet" href="chrome://browser/content/pioneer.css">
     <script src="chrome://browser/content/pioneer.js"></script>
     <link rel="icon" href="chrome://browser/skin/pioneer.svg">
     <title data-l10n-id="pioneer"></title>
   </head>
 
   <body>
     <div id="report-content">
@@ -88,17 +87,17 @@
         <p>To leave individual studies:</p>
         <ol>
           <li>
             Return to this page by clicking the Pioneer toolbar icon in Firefox
             or typing about:pioneer into the location bar and pressing Enter.
           </li>
           <li>
             All the studies that you have joined will be listed. To leave a
-            specific study, click on the toggle button next to the study.
+            specific study, click on the Leave Study button next to the study.
           </li>
           <li>
             Leaving a study will immediately stop collection of data associated
             with that study and remove any changes made to the browser as part
             of the study.
           </li>
         </ol>
         <p>
--- a/browser/components/pioneer/content/pioneer.js
+++ b/browser/components/pioneer/content/pioneer.js
@@ -34,17 +34,20 @@ XPCOMUtils.defineLazyModuleGetters(this,
 
 const PREF_PIONEER_ID = "toolkit.telemetry.pioneerId";
 const PREF_PIONEER_NEW_STUDIES_AVAILABLE =
   "toolkit.telemetry.pioneer-new-studies-available";
 
 /**
  * This is the Remote Settings key that we use to get the list of available studies.
  */
-const STUDY_ADDON_COLLECTION_KEY = "pioneer-study-addons";
+const STUDY_ADDON_COLLECTION_KEY = "pioneer-study-addons-v1";
+
+const PREF_TEST_CACHED_ADDONS = "toolkit.pioneer.testCachedAddons";
+const PREF_TEST_ADDONS = "toolkit.pioneer.testAddons";
 
 function showEnrollmentStatus() {
   const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
 
   const enrollmentButton = document.getElementById("enrollment-button");
 
   document.l10n.setAttributes(
     enrollmentButton,
@@ -58,17 +61,17 @@ async function showAvailableStudies(cach
     if (!cachedAddon) {
       console.error(
         `about:pioneer - Study addon ID not found in cache: ${studyAddonId}`
       );
       return;
     }
 
     if (cachedAddon.isDefault) {
-      return;
+      continue;
     }
 
     const studyAddonId = cachedAddon.addon_id;
 
     const study = document.createElement("div");
     study.setAttribute("id", studyAddonId);
     study.setAttribute("class", "card card-no-hover");
 
@@ -83,129 +86,151 @@ async function showAvailableStudies(cach
     studyBody.classList.add("card-body");
     study.appendChild(studyBody);
 
     const studyName = document.createElement("h3");
     studyName.setAttribute("class", "card-name");
     studyName.textContent = cachedAddon.name;
     studyBody.appendChild(studyName);
 
-    const studyCreator = document.createElement("span");
-    studyCreator.setAttribute("class", "card-creator");
-    studyCreator.textContent = cachedAddon.creator.name;
-    studyBody.appendChild(studyCreator);
+    const studyAuthor = document.createElement("span");
+    studyAuthor.setAttribute("class", "card-author");
+    studyAuthor.textContent = cachedAddon.authors.name;
+    studyBody.appendChild(studyAuthor);
 
     const actions = document.createElement("div");
     actions.classList.add("card-actions");
     study.appendChild(actions);
 
     const joinBtn = document.createElement("button");
     joinBtn.setAttribute("id", `${studyAddonId}-join-button`);
     joinBtn.classList.add("primary");
     joinBtn.classList.add("join-button");
     document.l10n.setAttributes(joinBtn, "pioneer-join-study");
     actions.appendChild(joinBtn);
 
-    const enrollStudyBtn = document.createElement("input");
-    enrollStudyBtn.setAttribute("id", `${studyAddonId}-toggle-button`);
-    enrollStudyBtn.setAttribute("class", "toggle-button");
-    enrollStudyBtn.setAttribute("type", "checkbox");
-    actions.appendChild(enrollStudyBtn);
-
     const studyDesc = document.createElement("div");
     studyDesc.setAttribute("class", "card-description");
     study.appendChild(studyDesc);
 
     const shortDesc = document.createElement("p");
     shortDesc.textContent = cachedAddon.description;
     studyDesc.appendChild(shortDesc);
 
-    const fullDesc = document.createElement("p");
-    fullDesc.textContent = cachedAddon.fullDescription;
-    studyDesc.appendChild(fullDesc);
+    const privacyPolicyLink = document.createElement("a");
+    privacyPolicyLink.href = cachedAddon.privacyPolicy.spec;
+    privacyPolicyLink.textContent = "privacy policy";
+
+    const privacyPolicy = document.createElement("p");
+    const privacyPolicyStart = document.createElement("span");
+    privacyPolicyStart.textContent = "You can always find the ";
+    privacyPolicy.append(privacyPolicyStart);
+    privacyPolicy.append(privacyPolicyLink);
+    const privacyPolicyEnd = document.createElement("span");
+    privacyPolicyEnd.textContent = " at our website.";
+    privacyPolicy.append(privacyPolicyEnd);
+    studyDesc.appendChild(privacyPolicy);
+
+    const studyDataCollected = document.createElement("div");
+    studyDataCollected.setAttribute("class", "card-data-collected");
+    study.appendChild(studyDataCollected);
+
+    const dataCollectionDetailsHeader = document.createElement("p");
+    dataCollectionDetailsHeader.textContent = "This study will collect:";
+    studyDataCollected.appendChild(dataCollectionDetailsHeader);
+
+    const dataCollectionDetails = document.createElement("ul");
+    for (const dataCollectionDetail of cachedAddon.dataCollectionDetails) {
+      const detailsBullet = document.createElement("li");
+      detailsBullet.textContent = dataCollectionDetail;
+      dataCollectionDetails.append(detailsBullet);
+    }
+    studyDataCollected.appendChild(dataCollectionDetails);
 
     async function toggleEnrolled() {
       let addon;
       let install;
 
       if (Cu.isInAutomation) {
-        if (
-          Services.prefs.getBoolPref(
-            "toolkit.pioneer.testAddonInstalled",
-            false
-          )
-        ) {
-          addon = { uninstall() {} };
+        let testAddons = Services.prefs.getStringPref(PREF_TEST_ADDONS, null);
+        testAddons = JSON.parse(testAddons);
+        install = {
+          install: () => {},
+        };
+        for (const testAddon of testAddons) {
+          if (testAddon.id == studyAddonId) {
+            addon = testAddon;
+            addon.install = () => {};
+            addon.uninstall = () => {
+              Services.prefs.setStringPref(PREF_TEST_ADDONS, "[]");
+            };
+          }
         }
-
-        install = { install() {} };
       } else {
         addon = await AddonManager.getAddonByID(studyAddonId);
         install = await AddonManager.getInstallForURL(
           cachedAddon.sourceURI.spec
         );
       }
 
       if (addon) {
+        joinBtn.disabled = true;
         await addon.uninstall();
+        document.l10n.setAttributes(joinBtn, "pioneer-join-study");
+        joinBtn.disabled = false;
       } else {
         joinBtn.disabled = true;
         await install.install();
+        document.l10n.setAttributes(joinBtn, "pioneer-leave-study");
+        joinBtn.disabled = false;
       }
       await updateStudy(studyAddonId);
     }
 
-    enrollStudyBtn.addEventListener("input", toggleEnrolled);
     joinBtn.addEventListener("click", toggleEnrolled);
 
     const availableStudies = document.getElementById("available-studies");
     availableStudies.appendChild(study);
 
     await updateStudy(studyAddonId);
   }
 
   const availableStudies = document.getElementById("header-available-studies");
   document.l10n.setAttributes(availableStudies, "pioneer-available-studies");
 }
 
 async function updateStudy(studyAddonId) {
   let addon;
   if (Cu.isInAutomation) {
-    if (
-      Services.prefs.getBoolPref("toolkit.pioneer.testAddonInstalled", false)
-    ) {
+    if (Services.prefs.getBoolPref(PREF_TEST_ADDONS, false)) {
       addon = { uninstall() {} };
     }
   } else {
     addon = await AddonManager.getAddonByID(studyAddonId);
   }
 
   const study = document.querySelector(`.card[id="${studyAddonId}"`);
 
-  const enrollStudyBtn = study.querySelector(".toggle-button");
   const joinBtn = study.querySelector(".join-button");
 
   const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
 
   if (pioneerId) {
     study.style.opacity = 1;
+    joinBtn.disabled = false;
 
-    enrollStudyBtn.disabled = false;
-    enrollStudyBtn.checked = !!addon;
-
-    joinBtn.disabled = false;
-    joinBtn.hidden = !!addon;
+    if (addon) {
+      document.l10n.setAttributes(joinBtn, "pioneer-leave-study");
+    } else {
+      document.l10n.setAttributes(joinBtn, "pioneer-join-study");
+    }
   } else {
+    document.l10n.setAttributes(joinBtn, "pioneer-join-study");
     study.style.opacity = 0.5;
-
-    enrollStudyBtn.disabled = true;
-    enrollStudyBtn.checked = false;
-
     joinBtn.disabled = true;
-    joinBtn.hidden = false;
   }
 }
 
 // equivalent to what we use for Telemetry IDs
 // https://searchfox.org/mozilla-central/rev/9193635dca8cfdcb68f114306194ffc860456044/toolkit/components/telemetry/app/TelemetryUtils.jsm#222
 function generateUUID() {
   let str = Cc["@mozilla.org/uuid-generator;1"]
     .getService(Ci.nsIUUIDGenerator)
@@ -305,17 +330,17 @@ document.addEventListener("DOMContentLoa
   showEnrollmentStatus();
 
   document.addEventListener("focus", removeBadge);
   removeBadge();
 
   let cachedAddons;
   if (Cu.isInAutomation) {
     let testCachedAddons = Services.prefs.getStringPref(
-      "toolkit.pioneer.testCachedAddons",
+      PREF_TEST_CACHED_ADDONS,
       null
     );
     if (testCachedAddons) {
       cachedAddons = JSON.parse(testCachedAddons);
     }
   } else {
     cachedAddons = await RemoteSettings(STUDY_ADDON_COLLECTION_KEY).get();
   }
--- a/browser/components/pioneer/moz.build
+++ b/browser/components/pioneer/moz.build
@@ -5,8 +5,12 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
 JAR_MANIFESTS += ['jar.mn']
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'General')
+
+TESTING_JS_MODULES += [
+    'schemas/PioneerStudyAddonsSchema.json',
+]
new file mode 100644
--- /dev/null
+++ b/browser/components/pioneer/schemas/PioneerStudyAddonsSchema.json
@@ -0,0 +1,96 @@
+{
+  "type": "object",
+  "properties": {
+    "addon_id": {
+      "type": "string"
+    },
+    "icons": {
+      "type": "object",
+      "properties": {
+        "32": {
+          "type": "string"
+        },
+        "64": {
+          "type": "string"
+        },
+        "128": {
+          "type": "string"
+        }
+      }
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 75
+    },
+    "version": {
+      "type": "string"
+    },
+    "sourceURI": {
+      "type": "object",
+      "properties": {
+        "spec": {
+          "type": "string"
+        }
+      }
+    },
+    "description": {
+      "type": "string"
+    },
+    "privacyPolicy": {
+      "type": "object",
+      "properties": {
+        "spec": {
+          "type": "string"
+        }
+      }
+    },
+    "studyType": {
+      "type": "string"
+    },
+    "moreInfo": {
+      "type": "object",
+      "properties": {
+        "spec": {
+          "type": "string"
+        }
+      }
+    },
+    "dataCollectionDetails": {
+      "type": "array",
+      "properties": {
+        "collectionDetail": {
+          "type": "string"
+        }
+      }
+    },
+    "authors": {
+      "type": "object",
+      "properties": {
+        "name": {
+          "type": "string",
+          "maxLength": 75
+        },
+        "moreInfo": {
+          "type": "object",
+          "properties": {
+            "spec": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    }
+  },
+  "required": [
+    "addon_id",
+    "icons",
+    "version",
+    "sourceURI",
+    "description",
+    "privacyPolicy",
+    "studyType",
+    "moreInfo",
+    "dataCollectionDetails",
+    "authors"
+  ]
+}
--- a/browser/components/pioneer/test/browser/browser_pioneer_ui.js
+++ b/browser/components/pioneer/test/browser/browser_pioneer_ui.js
@@ -3,110 +3,160 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+ChromeUtils.defineModuleGetter(
+  this,
+  "Ajv",
+  "resource://testing-common/ajv-4.1.1.js"
+);
+
 const PREF_PIONEER_ID = "toolkit.telemetry.pioneerId";
 const PREF_PIONEER_NEW_STUDIES_AVAILABLE =
   "toolkit.telemetry.pioneer-new-studies-available";
 
-const PREF_CACHED_ADDONS = "toolkit.pioneer.testCachedAddons";
-const PREF_TEST_ADDON_INSTALLED = "toolkit.pioneer.testAddonInstalled";
+const PREF_TEST_CACHED_ADDONS = "toolkit.pioneer.testCachedAddons";
+const PREF_TEST_ADDONS = "toolkit.pioneer.testAddons";
 
 const CACHED_ADDONS = [
   {
     addon_id: "pioneer-v2-example@mozilla.org",
     icons: {
       "32":
         "https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
       "64":
         "https://localhost/user-media/addon_icons/2644/2644632-64.png?modified=4a64e2bc",
       "128":
         "https://localhost/user-media/addon_icons/2644/2644632-128.png?modified=4a64e2bc",
     },
-    _unsupportedProperties: {},
     name: "Demo Study",
     version: "1.0",
     sourceURI: {
       spec: "https://localhost",
     },
-    homepageURL: "https://github.com/rhelmer/pioneer-v2-example",
-    supportURL: null,
     description: "Study purpose: Testing Pioneer.",
-    fullDescription:
-      "Data collected: An encrypted ping containing the current date and time is sent to Mozilla's servers.",
-    weeklyDownloads: 0,
-    type: "extension",
-    creator: {
+    privacyPolicy: {
+      spec: "http://localhost",
+    },
+    studyType: "extension",
+    authors: {
       name: "Pioneer Developers",
       url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
     },
-    developers: [],
-    screenshots: [],
-    contributionURL: "",
-    averageRating: 0,
-    reviewCount: 0,
-    reviewURL:
-      "https://addons.mozilla.org/en-US/firefox/addon/pioneer-v2-example/reviews/",
-    updateDate: "2020-05-27T20:47:35.000Z",
+    dataCollectionDetails: ["test123", "test345"],
+    moreInfo: {
+      spec: "http://localhost",
+    },
+    isDefault: false,
   },
   {
     addon_id: "pioneer-v2-default-example@mozilla.org",
     icons: {
       "32":
         "https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
       "64":
         "https://localhost/user-media/addon_icons/2644/2644632-64.png?modified=4a64e2bc",
       "128":
         "https://localhost/user-media/addon_icons/2644/2644632-128.png?modified=4a64e2bc",
     },
-    _unsupportedProperties: {},
     name: "Demo Default Study",
     version: "1.0",
     sourceURI: {
       spec: "https://localhost",
     },
-    homepageURL: "https://github.com/rhelmer/pioneer-v2-example",
-    supportURL: null,
     description: "Study purpose: Testing Pioneer.",
-    fullDescription:
-      "Data collected: An encrypted ping containing the current date and time is sent to Mozilla's servers.",
-    weeklyDownloads: 0,
-    type: "extension",
-    creator: {
+    privacyPolicy: {
+      spec: "http://localhost",
+    },
+    studyType: "extension",
+    authors: {
       name: "Pioneer Developers",
       url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
     },
-    developers: [],
-    screenshots: [],
-    contributionURL: "",
-    averageRating: 0,
-    reviewCount: 0,
-    reviewURL:
-      "https://addons.mozilla.org/en-US/firefox/addon/pioneer-v2-example/reviews/",
-    updateDate: "2020-05-27T20:47:35.000Z",
+    dataCollectionDetails: ["test123", "test345"],
+    moreInfo: {
+      spec: "http://localhost",
+    },
     isDefault: true,
   },
+  {
+    addon_id: "study@partner",
+    icons: {
+      "32":
+        "https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
+      "64":
+        "https://localhost/user-media/addon_icons/2644/2644632-64.png?modified=4a64e2bc",
+      "128":
+        "https://localhost/user-media/addon_icons/2644/2644632-128.png?modified=4a64e2bc",
+    },
+    name: "Example Partner Study",
+    version: "1.0",
+    sourceURI: {
+      spec: "https://localhost",
+    },
+    description: "Study purpose: Testing Pioneer.",
+    privacyPolicy: {
+      spec: "http://localhost",
+    },
+    studyType: "extension",
+    authors: {
+      name: "Stusdy Partners",
+      url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
+    },
+    dataCollectionDetails: ["test123", "test345"],
+    moreInfo: {
+      spec: "http://localhost",
+    },
+    isDefault: false,
+  },
+];
+
+const TEST_ADDONS = [
+  { id: "pioneer-v2-example@pioneer.mozilla.org" },
+  { id: "pioneer-v2-default-example@mozilla.org" },
+  { id: "study@partner" },
 ];
 
 const waitForAnimationFrame = () =>
   new Promise(resolve => {
     content.window.requestAnimationFrame(resolve);
   });
 
+add_task(async function testMockSchema() {
+  const response = await fetch(
+    "resource://testing-common/PioneerStudyAddonsSchema.json"
+  );
+  const schema = await response.json();
+  if (!schema) {
+    throw new Error("Failed to load PioneerStudyAddonsSchema");
+  }
+
+  const ajv = new Ajv();
+  const validate = ajv.compile(schema);
+
+  for (const addon of CACHED_ADDONS) {
+    const valid = validate(addon);
+    if (!valid) {
+      throw new Error(JSON.stringify(validate.errors));
+    }
+  }
+});
+
 add_task(async function testAboutPage() {
   const cachedAddons = JSON.stringify(CACHED_ADDONS);
+
   await SpecialPowers.pushPrefEnv({
     set: [
-      [PREF_CACHED_ADDONS, cachedAddons],
-      [PREF_TEST_ADDON_INSTALLED, false],
+      [PREF_TEST_CACHED_ADDONS, cachedAddons],
+      [PREF_TEST_ADDONS, "[]"],
     ],
     clear: [[PREF_PIONEER_ID, ""]],
   });
 
   await BrowserTestUtils.withNewTab(
     {
       url: "about:pioneer",
       gBrowser,
@@ -174,24 +224,34 @@ add_task(async function testAboutPage() 
           `${addonId}-join-button`
         );
 
         if (cachedAddon.isDefault) {
           ok(!joinButton, "There is no join button for default study.");
           continue;
         }
 
-        ok(!joinButton.hidden, "Join button is not hidden.");
-
-        Services.prefs.setBoolPref(PREF_TEST_ADDON_INSTALLED, true);
+        ok(!joinButton.disabled, "After enrollment, join button is enabled.");
+        ok(!joinButton.hidden, "After enrollment, join button is not hidden.");
+        for (const testAddon of TEST_ADDONS) {
+          if (testAddon.id == addonId) {
+            Services.prefs.setStringPref(
+              PREF_TEST_ADDONS,
+              JSON.stringify([testAddon])
+            );
+          }
+        }
 
         joinButton.click();
         await waitForAnimationFrame();
 
-        ok(joinButton.hidden, "Join button is hidden.");
+        ok(
+          Services.prefs.getStringPref(PREF_TEST_ADDONS, null) == "[]",
+          "Correct add-on was uninstalled"
+        );
       }
 
       enrollmentButton.click();
 
       await waitForAnimationFrame();
 
       const pioneerUnenrolled = Services.prefs.getStringPref(
         PREF_PIONEER_ID,
@@ -200,34 +260,37 @@ add_task(async function testAboutPage() 
       ok(!pioneerUnenrolled, "after unenrollment, Pioneer pref is null.");
 
       const unenrolledToolbarButton = document.getElementById("pioneer-button");
       ok(
         unenrolledToolbarButton.hidden,
         "after unenrollment, Pioneer toolbar button is hidden."
       );
 
+      Services.prefs.setStringPref(PREF_TEST_ADDONS, "[]");
       for (const cachedAddon of CACHED_ADDONS) {
         const addonId = cachedAddon.addon_id;
         const joinButton = content.document.getElementById(
           `${addonId}-join-button`
         );
 
-        Services.prefs.setBoolPref(PREF_TEST_ADDON_INSTALLED, false);
         if (cachedAddon.isDefault) {
           ok(!joinButton, "There is no join button for default study.");
         } else {
           ok(
             joinButton.disabled,
             "After unenrollment, join button is disabled."
           );
           ok(
             !joinButton.hidden,
             "After unenrollment, join button is not hidden."
           );
+
+          joinButton.click();
+          await waitForAnimationFrame();
         }
       }
     }
   );
 });
 
 add_task(async function testPioneerBadge() {
   await SpecialPowers.pushPrefEnv({