Fixed #1687 - Removed Growth Experiment 3 Code
This commit is contained in:
Родитель
ea15f5fa25
Коммит
31cc8a74a3
|
@ -5,8 +5,6 @@ const DB = require("../db/DB");
|
|||
const { scanResult } = require("../scan-results");
|
||||
const { generatePageToken } = require("./utils");
|
||||
|
||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||
|
||||
async function home(req, res) {
|
||||
|
||||
const formTokens = {
|
||||
|
@ -17,14 +15,6 @@ async function home(req, res) {
|
|||
let featuredBreach = null;
|
||||
let scanFeaturedBreach = false;
|
||||
|
||||
// Growth Experiment: Set experiment branch from the homepage through URL queryParams
|
||||
// but do not render any info on the /home template.
|
||||
if (EXPERIMENTS_ENABLED && req.query.experimentBranch) {
|
||||
if (["va", "vb"].includes(req.query.experimentBranch)) {
|
||||
req.session.experimentBranch = req.query.experimentBranch;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.session.user && !req.query.breach) {
|
||||
return res.redirect("/user/dashboard");
|
||||
}
|
||||
|
|
|
@ -14,11 +14,13 @@ const sha1 = require("../sha1-utils");
|
|||
|
||||
const log = mozlog("controllers.oauth");
|
||||
|
||||
// Growth Experiment
|
||||
const utmArray = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
|
||||
|
||||
function getUTMNames() {
|
||||
return utmArray;
|
||||
}
|
||||
// Growth Experiment
|
||||
// function getUTMNames() {
|
||||
// return utmArray;
|
||||
// }
|
||||
|
||||
function init(req, res, next, client = FxAOAuthClient) {
|
||||
// Set a random state string in a cookie so that we can verify
|
||||
|
@ -34,6 +36,7 @@ function init(req, res, next, client = FxAOAuthClient) {
|
|||
url.searchParams.append("action", "email");
|
||||
|
||||
for (const param of fxaParams.searchParams.keys()) {
|
||||
// Growth Experiment
|
||||
if (utmArray.includes(param)) {
|
||||
req.session.utmContents[param] = fxaParams.searchParams.get(param);
|
||||
}
|
||||
|
@ -66,13 +69,14 @@ async function confirmed(req, res, next, client = FxAOAuthClient) {
|
|||
|
||||
const returnURL = new URL("/user/dashboard", AppConstants.SERVER_URL);
|
||||
|
||||
if (req.session.utmContents) {
|
||||
getUTMNames().forEach(param => {
|
||||
if (req.session.utmContents[param]) {
|
||||
returnURL.searchParams.append(param, req.session.utmContents[param]);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Growth Experiment
|
||||
// if (req.session.utmContents) {
|
||||
// getUTMNames().forEach(param => {
|
||||
// if (req.session.utmContents[param]) {
|
||||
// returnURL.searchParams.append(param, req.session.utmContents[param]);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// Check if user is signing up or signing in,
|
||||
// then add new users to db and send email.
|
||||
|
|
|
@ -12,11 +12,8 @@ const HIBP = require("../hibp");
|
|||
const { resultsSummary } = require("../scan-results");
|
||||
const sha1 = require("../sha1-utils");
|
||||
|
||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||
|
||||
const FXA_MONITOR_SCOPE = "https://identity.mozilla.com/apps/monitor";
|
||||
|
||||
|
||||
async function removeEmail(req, res) {
|
||||
const emailId = req.body.emailId;
|
||||
const sessionUser = req.user;
|
||||
|
@ -231,18 +228,6 @@ async function getDashboard(req, res) {
|
|||
const allBreaches = req.app.locals.breaches;
|
||||
const { verifiedEmails, unverifiedEmails } = await getAllEmailsAndBreaches(user, allBreaches);
|
||||
|
||||
let experimentBranch = null;
|
||||
let isUserInExperiment = null;
|
||||
let experimentBranchB = null;
|
||||
|
||||
if (EXPERIMENTS_ENABLED && req.session.experimentBranch) {
|
||||
if (!req.session.excludeFromExperiment) {
|
||||
experimentBranch = req.session.experimentBranch;
|
||||
isUserInExperiment = (experimentBranch === "vb");
|
||||
experimentBranchB = (experimentBranch === "vb" && isUserInExperiment);
|
||||
}
|
||||
}
|
||||
|
||||
let lastAddedEmail = null;
|
||||
|
||||
req.session.user = await DB.setBreachesLastShownNow(user);
|
||||
|
@ -258,9 +243,6 @@ async function getDashboard(req, res) {
|
|||
verifiedEmails,
|
||||
unverifiedEmails,
|
||||
whichPartial: "dashboards/breaches-dash",
|
||||
experimentBranch,
|
||||
isUserInExperiment,
|
||||
experimentBranchB,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -574,6 +556,7 @@ async function getBreachStats(req, res) {
|
|||
|
||||
|
||||
function logout(req, res) {
|
||||
// Growth Experiment
|
||||
if (AppConstants.EXPERIMENT_ACTIVE) {
|
||||
// Persist experimentBranch across session reset
|
||||
const excludeFromExperiment = req.session.excludeFromExperiment;
|
||||
|
|
|
@ -33,13 +33,32 @@ function hasUserSignedUpForRelay(user) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function getExperimentBranch(req, sorterNum) {
|
||||
function getExperimentBranch(req, language, sorterNum) {
|
||||
|
||||
if (!sorterNum) {
|
||||
sorterNum = Math.floor(Math.random() * 100);
|
||||
}
|
||||
|
||||
if (req.session.excludeFromExperiment && !req.query.experimentBranch) {
|
||||
log.debug("This session has already been excluded from the experiment");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we cannot parse req.headers["accept-language"], we should not
|
||||
// enroll users in the experiment.
|
||||
if (!language || !req.headers || !req.headers["accept-language"]){
|
||||
log.debug("No headers or accept-language information present.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the user doesn't have an English variant langauge selected as their primary language,
|
||||
// we do not enroll them in the experiment.
|
||||
const lang = req.headers["accept-language"].split(",");
|
||||
if (language && !lang[0].includes(language)) {
|
||||
log.debug("Preferred language is not English variant: ", lang[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If URL param has experimentBranch entry, use that branch;
|
||||
if (req.query.experimentBranch) {
|
||||
if (!["va", "vb"].includes(req.query.experimentBranch)) {
|
||||
|
|
|
@ -112,10 +112,6 @@
|
|||
transition: all 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.temp-marketing-btn-blue.experiment {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.temp-marketing-btn-blue:hover {
|
||||
background-color: var(--blue4);
|
||||
transition: all 0.15s ease-in-out;
|
||||
|
|
|
@ -155,6 +155,7 @@ function setGAListeners(){
|
|||
});
|
||||
});
|
||||
|
||||
// Growth Experiment
|
||||
if (document.body.dataset.experiment) {
|
||||
document.querySelectorAll(".ga-growth-ping").forEach((el) => {
|
||||
el.addEventListener("click", async(e) => {
|
||||
|
@ -211,6 +212,8 @@ function setGAListeners(){
|
|||
ga("create", "UA-77033033-16");
|
||||
ga("set", "anonymizeIp", true);
|
||||
ga("set", "dimension6", `${document.body.dataset.signedInUser}`);
|
||||
|
||||
// Growth Experiment
|
||||
if (document.body.dataset.experiment) {
|
||||
// If an experiment is active, set the "Growth Experiment Version"
|
||||
// Custom Dimension to whichever branch is active.
|
||||
|
|
|
@ -46,35 +46,6 @@ function doOauth(el) {
|
|||
}
|
||||
});
|
||||
|
||||
// Growth Experiment: OAuth Entry Point IDs are unique to the experiment.
|
||||
const oAuthEntryPointIds = [
|
||||
"fx-monitor-alert-me-blue-btn-top",
|
||||
"fx-monitor-alert-me-blue-btn-bottom",
|
||||
"fx-monitor-alert-me-blue-btn",
|
||||
"fx-monitor-alert-me-blue-link",
|
||||
];
|
||||
|
||||
if (oAuthEntryPointIds.includes(el.dataset.entrypoint)) {
|
||||
// Growth Experiment: Reset UTMs from in-line body tag data elements.
|
||||
["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content" ].forEach(key => {
|
||||
if (document.body.dataset[key]) {
|
||||
url.searchParams.delete(key);
|
||||
url.searchParams.append(key, document.body.dataset[key]);
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof(ga) !== "undefined") {
|
||||
ga("send", {
|
||||
hitType: "event",
|
||||
eventCategory: document.body.dataset.utm_campaign,
|
||||
eventAction: document.body.dataset.experiment,
|
||||
eventLabel: el.dataset.entrypoint,
|
||||
transport: "beacon",
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!sessionStorage) {
|
||||
window.location.assign(url);
|
||||
return;
|
||||
|
@ -133,10 +104,6 @@ function handleFormSubmits(formEvent) {
|
|||
thisForm.email.value = email;
|
||||
}
|
||||
const formClassList = thisForm.classList;
|
||||
// Growth
|
||||
if (formClassList.contains("skip")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (thisForm.email && !isValidEmail(email)) {
|
||||
sendPing(thisForm, "Failure");
|
||||
|
|
|
@ -4,28 +4,30 @@ const { URL } = require("url");
|
|||
|
||||
const HIBP = require("./hibp");
|
||||
const sha1 = require("./sha1-utils");
|
||||
const { getExperimentBranch } = require("./controllers/utils");
|
||||
|
||||
const AppConstants = require("./app-constants");
|
||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||
// Growth Experiment
|
||||
// const { getExperimentBranch } = require("./controllers/utils");
|
||||
// const AppConstants = require("./app-constants");
|
||||
// const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||
|
||||
const scanResult = async(req, selfScan=false) => {
|
||||
|
||||
const allBreaches = req.app.locals.breaches;
|
||||
let scannedEmail = null;
|
||||
|
||||
let experimentBranch = null;
|
||||
let isUserInExperiment = null;
|
||||
let experimentBranchB = null;
|
||||
// Growth Experiment
|
||||
// let experimentBranch = null;
|
||||
// let isUserInExperiment = null;
|
||||
// let experimentBranchB = null;
|
||||
|
||||
if (EXPERIMENTS_ENABLED) {
|
||||
const coinFlipNumber = Math.floor(Math.random() * 100);
|
||||
experimentBranch = getExperimentBranch(req, coinFlipNumber);
|
||||
if (!experimentBranch) { req.session.excludeFromExperiment = true; }
|
||||
req.session.experimentBranch = experimentBranch;
|
||||
isUserInExperiment = (experimentBranch === "vb");
|
||||
experimentBranchB = (experimentBranch === "vb" && isUserInExperiment);
|
||||
}
|
||||
// Growth Experiment
|
||||
// if (EXPERIMENTS_ENABLED) {
|
||||
// experimentBranch = getExperimentBranch(req, "en");
|
||||
// if (!experimentBranch) { req.session.excludeFromExperiment = true; }
|
||||
// req.session.experimentBranch = experimentBranch;
|
||||
// isUserInExperiment = (experimentBranch === "vb");
|
||||
// experimentBranchB = (experimentBranch === "vb" && isUserInExperiment);
|
||||
// }
|
||||
|
||||
const title = req.fluentFormat("scan-title");
|
||||
let foundBreaches = [];
|
||||
|
@ -41,7 +43,6 @@ const scanResult = async(req, selfScan=false) => {
|
|||
signedInUser = req.session.user;
|
||||
}
|
||||
|
||||
|
||||
// Checks if the user scanning their own verified email.
|
||||
if (req.body && req.body.emailHash) {
|
||||
scannedEmail = req.body.emailHash;
|
||||
|
@ -113,9 +114,9 @@ const scanResult = async(req, selfScan=false) => {
|
|||
fullReport,
|
||||
userDash,
|
||||
scannedEmailId,
|
||||
experimentBranch,
|
||||
isUserInExperiment,
|
||||
experimentBranchB,
|
||||
// experimentBranch,
|
||||
// isUserInExperiment,
|
||||
// experimentBranchB,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,20 +2,10 @@
|
|||
|
||||
const AppConstants = require("../../app-constants");
|
||||
const home = require("../../controllers/home");
|
||||
const { getExperimentBranch } = require("../../controllers/utils");
|
||||
const { scanResult } = require("../../scan-results");
|
||||
|
||||
let mockRequest = { fluentFormat: jest.fn(), csrfToken: jest.fn() };
|
||||
|
||||
function mockRequestSessionReset(mockRequest) {
|
||||
mockRequest.session = {
|
||||
excludeFromExperiment: false,
|
||||
experimentBranch: false,
|
||||
};
|
||||
return mockRequest;
|
||||
}
|
||||
|
||||
|
||||
function addBreachesToMockRequest(mockRequest) {
|
||||
const mockBreaches = [
|
||||
{Name: "Test"},
|
||||
|
@ -70,51 +60,3 @@ test("notFound set status 404 and renders 404", () => {
|
|||
expect(mockStatusCallArgs[0]).toBe(404);
|
||||
expect(mockRenderCallArgs[0]).toBe("subpage");
|
||||
});
|
||||
|
||||
test("Experiment 3 Cohort Assignment Unit Test", () => {
|
||||
mockRequest.headers = {
|
||||
"accept-language": "en",
|
||||
};
|
||||
|
||||
mockRequest.session = {
|
||||
excludeFromExperiment: false,
|
||||
};
|
||||
|
||||
// The session is assigned to the control group when the coin flip is 0;
|
||||
let experimentNumber = 0;
|
||||
let experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBe("va");
|
||||
|
||||
mockRequestSessionReset(mockRequest);
|
||||
|
||||
// The session is assigned to the control group when the coin flip is 29;
|
||||
experimentNumber = 29;
|
||||
experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBe("va");
|
||||
|
||||
mockRequestSessionReset(mockRequest);
|
||||
|
||||
// The session is assigned to the treatment group when the coin flip is 30;
|
||||
experimentNumber = 30;
|
||||
experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBe("vb");
|
||||
|
||||
// The session is assigned to the treatment group when the coin flip is 59;
|
||||
experimentNumber = 59;
|
||||
experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBe("vb");
|
||||
|
||||
mockRequestSessionReset(mockRequest);
|
||||
|
||||
// The session is assigned to the treatment group when the coin flip is 60
|
||||
experimentNumber = 60;
|
||||
experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBeFalsy();
|
||||
|
||||
mockRequestSessionReset(mockRequest);
|
||||
|
||||
// The session is excluded from the experiment when the coin flip is 99
|
||||
experimentNumber = 99;
|
||||
experimentBranch = getExperimentBranch(mockRequest, experimentNumber);
|
||||
expect(experimentBranch).toBeFalsy();
|
||||
});
|
||||
|
|
|
@ -15,15 +15,7 @@
|
|||
{{else}}
|
||||
<h2 class="headline scan-results-headline">{{{ fluentNestedBold "scan-results-known-breaches" breachCount=foundBreaches.length }}}</h2>
|
||||
<button id="new-scan-page"
|
||||
class="open-oauth ga-growth-ping {{#if experimentBranchB}} temp-marketing-btn-blue experiment {{else}} blue-link temp-marketing-alert-me-link {{/if}}"
|
||||
{{#if experimentBranchB}}
|
||||
{{> analytics/fxa id="fx-monitor-alert-me-blue-btn-top" }}
|
||||
{{else}}
|
||||
{{> analytics/fxa id="fx-monitor-alert-me-blue-link" }}
|
||||
{{/if}}
|
||||
data-event-category="Alert me about new breaches">
|
||||
{{ getString "alert-about-new-breaches" }}
|
||||
</button>
|
||||
class="open-oauth blue-link temp-marketing-alert-me-link" {{> analytics/fxa id="fx-monitor-alert-me-blue-link" }} data-event-category="Alert me about new breaches"> {{ getString "alert-about-new-breaches" }} </button>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,13 +43,7 @@
|
|||
to match the "Alert me.." button on the other version of the scan results page and to make comparisons
|
||||
between this button and the "Alert me.." button on the other version of the scan results page easier
|
||||
-->
|
||||
<button class="open-oauth temp-marketing-btn-blue ga-growth-ping {{#if experimentBranchB}} experiment {{/if}}"
|
||||
{{#if experimentBranchB}}
|
||||
{{> analytics/fxa id="fx-monitor-alert-me-blue-btn-bottom" }}
|
||||
{{else}}
|
||||
{{> analytics/fxa id="fx-monitor-alert-me-blue-btn" }}
|
||||
{{/if}}"
|
||||
data-event-category="Alert me about new breaches - Banner">{{ getString "alert-about-new-breaches" }}</button>
|
||||
<button class="open-oauth temp-marketing-btn-blue " {{> analytics/fxa id="fx-monitor-alert-me-blue-btn" }} data-event-category="Alert me about new breaches - Banner">{{ getString "alert-about-new-breaches" }}</button>
|
||||
{{> sign-up-banners/browser-not-required }}
|
||||
</div>
|
||||
</section>
|
||||
|
|
Загрузка…
Ссылка в новой задаче