commit 5b9a31d66c3b23e04534ba1b94f3546ec4bf5fbf
parent 19389430a0d4c73ecf991eeb6f27bb74f128a41a
Author: Sebastian Streich <sstreich@mozilla.com>
Date: Tue, 30 Sep 2025 14:50:24 +0000
Bug 1990490 - Patch 1 - Allow enrollment into other experiment types r=ip-protection-reviewers,rking
Differential Revision: https://phabricator.services.mozilla.com/D266013
Diffstat:
2 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/browser/components/ipprotection/GuardianClient.sys.mjs b/browser/components/ipprotection/GuardianClient.sys.mjs
@@ -73,12 +73,15 @@ export class GuardianClient {
/**
* Tries to enroll the user to the proxy service.
* It will silently try to sign in the user into guardian using their FxA account.
- * If the user already has a proxy entitlement, nothing will happen.
+ * If the user already has a proxy entitlement, the experiment type will update.
+ *
+ * @param { "alpha" | "beta" | "delta" | "gamma" } aExperimentType - The experiment type to enroll the user into.
+ * The experiment type controls which feature set the user will get in Firefox.
*
* @param { AbortSignal | null } aAbortSignal - An AbortSignal to cancel the operation.
- * @returns {Promise<{error?: string, ok?: boolean}>} Re
+ * @returns {Promise<{error?: string, ok?: boolean}>}
*/
- async enroll(aAbortSignal) {
+ async enroll(aExperimentType = "alpha", aAbortSignal = null) {
// We abort loading the page if the origion is not allowed.
const allowedOrigins = [
new URL(this.guardianEndpoint).origin,
@@ -111,7 +114,9 @@ export class GuardianClient {
}
return false;
});
- browser.loadURI(Services.io.newURI(this.#loginURL.href), {
+ const loginURL = this.#loginURL;
+ loginURL.searchParams.set("experiment", aExperimentType);
+ browser.loadURI(Services.io.newURI(loginURL.href), {
// TODO: Make sure this is the right principal to use?
triggeringPrincipal:
Services.scriptSecurityManager.getSystemPrincipal(),
diff --git a/browser/components/ipprotection/tests/browser/browser_guardian_client.js b/browser/components/ipprotection/tests/browser/browser_guardian_client.js
@@ -37,6 +37,16 @@ const testcases = [
ok: true,
error: undefined,
},
+ experimentType: "alpha",
+ },
+ {
+ name: "Successful enrollment with custom experiment",
+ responseURL: "/oauth/success?code=abc123",
+ expects: {
+ ok: true,
+ error: undefined,
+ },
+ experimentType: "beta",
},
{
name: "Failed enrollment - error in success URL",
@@ -45,12 +55,13 @@ const testcases = [
ok: false,
error: "generic_error",
},
+ experimentType: "alpha",
},
];
// Run each test case as a separate task to ensure clean state
testcases
- .map(({ name, responseURL, expects }) => {
+ .map(({ name, responseURL, expects, experimentType }) => {
return async () => {
requestLongerTimeout(2); // Increase timeout for this test case
info(`Running test case: ${name}`);
@@ -60,6 +71,18 @@ testcases
enroll: (request, response) => {
info(`Handling enroll request, redirecting to ${responseURL}`);
+ // Assert that the experiment query parameter is present
+ const queryParams = new URLSearchParams(request.queryString);
+ Assert.ok(
+ queryParams.has("experiment"),
+ "Request should include 'experiment' query parameter"
+ );
+ Assert.equal(
+ queryParams.get("experiment"),
+ experimentType,
+ `Experiment type should be '${experimentType}'`
+ );
+
// Set up a proper HTTP redirect
response.setStatusLine(request.httpVersion, 302, "Found");
@@ -77,7 +100,7 @@ testcases
try {
// Call the actual enroll method - no mocking!
- const result = await client.enroll();
+ const result = await client.enroll(experimentType);
// Check the results
Assert.equal(