import { AboutWelcomeDefaults } from "aboutwelcome/lib/AboutWelcomeDefaults.jsm";
import { MultiStageProtonScreen } from "content-src/aboutwelcome/components/MultiStageProtonScreen";
import { AWScreenUtils } from "lib/AWScreenUtils.jsm";
import React from "react";
import { mount } from "enzyme";
describe("MultiStageAboutWelcomeProton module", () => {
let sandbox;
let clock;
beforeEach(() => {
clock = sinon.useFakeTimers();
sandbox = sinon.createSandbox();
});
afterEach(() => {
clock.restore();
sandbox.restore();
});
describe("MultiStageAWProton component", () => {
it("should render MultiStageProton Screen", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
subtitle: "test subtitle",
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
});
it("should render secondary section for split positioned screens", () => {
const SCREEN_PROPS = {
content: {
position: "split",
title: "test title",
hero_text: "test subtitle",
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".welcome-text h1").text(), "test title");
assert.equal(
wrapper.find(".section-secondary h1").text(),
"test subtitle"
);
assert.equal(wrapper.find("main").prop("pos"), "split");
});
it("should render secondary section with content background for split positioned screens", () => {
const BACKGROUND_URL =
"chrome://activity-stream/content/data/content/assets/confetti.svg";
const SCREEN_PROPS = {
content: {
position: "split",
background: `url(${BACKGROUND_URL}) var(--mr-secondary-position) no-repeat`,
split_narrow_bkg_position: "10px",
title: "test title",
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.ok(
wrapper
.find("div.section-secondary")
.prop("style")
.background.includes("--mr-secondary-position")
);
assert.ok(
wrapper.find("div.section-secondary").prop("style")[
"--mr-secondary-background-position-y"
],
"10px"
);
});
it("should render with secondary section for split positioned screens", () => {
const SCREEN_PROPS = {
content: {
position: "split",
title: "test title",
hero_text: "test subtitle",
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".welcome-text h1").text(), "test title");
assert.equal(
wrapper.find(".section-secondary h1").text(),
"test subtitle"
);
assert.equal(wrapper.find("main").prop("pos"), "split");
});
it("should render with no secondary section for center positioned screens", () => {
const SCREEN_PROPS = {
content: {
position: "center",
title: "test title",
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".section-secondary").exists(), false);
assert.equal(wrapper.find(".welcome-text h1").text(), "test title");
assert.equal(wrapper.find("main").prop("pos"), "center");
});
it("should not render multiple action buttons if an additional button does not exist", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
primary_button: {
label: "test primary button",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.isFalse(wrapper.find(".additional-cta").exists());
});
it("should render an additional action button with primary styling if no style has been specified", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
primary_button: {
label: "test primary button",
},
additional_button: {
label: "test additional button",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.isTrue(wrapper.find(".additional-cta.primary").exists());
});
it("should render an additional action button with secondary styling", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
primary_button: {
label: "test primary button",
},
additional_button: {
label: "test additional button",
style: "secondary",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".additional-cta.secondary").exists(), true);
});
it("should render an additional action button with primary styling", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
primary_button: {
label: "test primary button",
},
additional_button: {
label: "test additional button",
style: "primary",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".additional-cta.primary").exists(), true);
});
it("should render an additional action with link styling", () => {
const SCREEN_PROPS = {
content: {
position: "split",
title: "test title",
primary_button: {
label: "test primary button",
},
additional_button: {
label: "test additional button",
style: "link",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".additional-cta.cta-link").exists(), true);
});
it("should render an additional button with vertical orientation", () => {
const SCREEN_PROPS = {
content: {
position: "center",
title: "test title",
primary_button: {
label: "test primary button",
},
additional_button: {
label: "test additional button",
style: "secondary",
flow: "column",
},
},
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(
wrapper.find(".additional-cta-container[flow='column']").exists(),
true
);
});
it("should not render a progress bar if there is 1 step", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
progress_bar: true,
},
isSingleScreen: true,
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".steps.progress-bar").exists(), false);
});
it("should render a progress bar if there are 2 steps", () => {
const SCREEN_PROPS = {
content: {
title: "test title",
progress_bar: true,
},
totalNumberOfScreens: 2,
};
const wrapper = mount();
assert.ok(wrapper.exists());
assert.equal(wrapper.find(".steps.progress-bar").exists(), true);
});
});
describe("AboutWelcomeDefaults for proton", () => {
const getData = () => AboutWelcomeDefaults.getDefaults();
async function prepConfig(config, evalFalseScreenIds) {
let data = await getData();
if (evalFalseScreenIds?.length) {
data.screens.forEach(async screen => {
if (evalFalseScreenIds.includes(screen.id)) {
screen.targeting = false;
}
});
data.screens = await AWScreenUtils.evaluateTargetingAndRemoveScreens(
data.screens
);
}
return AboutWelcomeDefaults.prepareContentForReact({
...data,
...config,
});
}
beforeEach(() => {
sandbox.stub(global.Services.prefs, "getBoolPref").returns(true);
sandbox.stub(AWScreenUtils, "evaluateScreenTargeting").returnsArg(0);
// This is necessary because there are still screens being removed with
// `removeScreens` in `prepareContentForReact()`. Once we've migrated
// to using screen targeting instead of manually removing screens,
// we can remove this stub.
sandbox
.stub(global.AWScreenUtils, "removeScreens")
.callsFake((screens, callback) =>
AWScreenUtils.removeScreens(screens, callback)
);
});
it("should have 'pin' button by default", async () => {
const data = await prepConfig({ needPin: true }, [
"AW_EASY_SETUP",
"AW_WELCOME_BACK",
]);
assert.propertyVal(
data.screens[0].content.primary_button.action,
"type",
"PIN_FIREFOX_TO_TASKBAR"
);
});
it("should have 'pin' button if we need default and pin", async () => {
const data = await prepConfig(
{
needDefault: true,
needPin: true,
},
["AW_EASY_SETUP", "AW_WELCOME_BACK"]
);
assert.propertyVal(
data.screens[0].content.primary_button.action,
"type",
"PIN_FIREFOX_TO_TASKBAR"
);
assert.propertyVal(data.screens[0], "id", "AW_PIN_FIREFOX");
assert.propertyVal(data.screens[1], "id", "AW_SET_DEFAULT");
assert.lengthOf(data.screens, getData().screens.length - 3);
});
it("should keep 'pin' and remove 'default' if already default", async () => {
const data = await prepConfig({ needPin: true }, [
"AW_EASY_SETUP",
"AW_WELCOME_BACK",
]);
assert.propertyVal(data.screens[0], "id", "AW_PIN_FIREFOX");
assert.propertyVal(data.screens[1], "id", "AW_IMPORT_SETTINGS");
assert.lengthOf(data.screens, getData().screens.length - 4);
});
it("should switch to 'default' if already pinned", async () => {
const data = await prepConfig({ needDefault: true }, [
"AW_EASY_SETUP",
"AW_WELCOME_BACK",
]);
assert.propertyVal(data.screens[0], "id", "AW_ONLY_DEFAULT");
assert.propertyVal(data.screens[1], "id", "AW_IMPORT_SETTINGS");
assert.lengthOf(data.screens, getData().screens.length - 4);
});
it("should switch to 'start' if already pinned and default", async () => {
const data = await prepConfig({}, ["AW_EASY_SETUP", "AW_WELCOME_BACK"]);
assert.propertyVal(data.screens[0], "id", "AW_GET_STARTED");
assert.propertyVal(data.screens[1], "id", "AW_IMPORT_SETTINGS");
assert.lengthOf(data.screens, getData().screens.length - 4);
});
it("should have a FxA button", async () => {
const data = await prepConfig({}, ["AW_WELCOME_BACK"]);
assert.notProperty(data, "skipFxA");
assert.property(data.screens[0].content, "secondary_button_top");
});
it("should remove the FxA button if pref disabled", async () => {
global.Services.prefs.getBoolPref.returns(false);
const data = await prepConfig();
assert.property(data, "skipFxA", true);
assert.notProperty(data.screens[0].content, "secondary_button_top");
});
it("should remove the caption if deleteIfNotEn is true", async () => {
sandbox.stub(global.Services.locale, "appLocaleAsBCP47").value("de");
const data = await prepConfig({
id: "DEFAULT_ABOUTWELCOME_PROTON",
template: "multistage",
transitions: true,
background_url:
"chrome://activity-stream/content/data/content/assets/confetti.svg",
screens: [
{
id: "AW_PIN_FIREFOX",
content: {
position: "corner",
help_text: {
deleteIfNotEn: true,
string_id: "mr1-onboarding-welcome-image-caption",
},
},
},
],
});
assert.notProperty(data.screens[0].content, "help_text");
});
});
describe("AboutWelcomeDefaults for MR split template proton", () => {
const getData = () => AboutWelcomeDefaults.getDefaults(true);
beforeEach(() => {
sandbox.stub(global.Services.prefs, "getBoolPref").returns(true);
});
it("should use 'split' position template by default", async () => {
const data = await getData();
assert.propertyVal(data.screens[0].content, "position", "split");
});
it("should not include noodles by default", async () => {
const data = await getData();
assert.notProperty(data.screens[0].content, "has_noodles");
});
});
describe("AboutWelcomeDefaults prepareMobileDownload", () => {
const TEST_CONTENT = {
screens: [
{
id: "AW_MOBILE_DOWNLOAD",
content: {
title: "test",
hero_image: {
url: "https://example.com/test.svg",
},
cta_paragraph: {
text: {},
action: {},
},
},
},
],
};
it("should not set url for default qrcode svg", async () => {
sandbox.stub(global.AppConstants, "isChinaRepack").returns(false);
const data = await AboutWelcomeDefaults.prepareContentForReact(
TEST_CONTENT
);
assert.propertyVal(
data.screens[0].content.hero_image,
"url",
"https://example.com/test.svg"
);
});
it("should set url for cn qrcode svg", async () => {
sandbox.stub(global.AppConstants, "isChinaRepack").returns(true);
const data = await AboutWelcomeDefaults.prepareContentForReact(
TEST_CONTENT
);
assert.propertyVal(
data.screens[0].content.hero_image,
"url",
"https://example.com/test-cn.svg"
);
});
});
describe("AboutWelcomeDefaults prepareContentForReact", () => {
it("should not set action without screens", async () => {
const data = await AboutWelcomeDefaults.prepareContentForReact({
ua: "test",
});
assert.propertyVal(data, "ua", "test");
assert.notProperty(data, "screens");
});
it("should set action for import action", async () => {
const TEST_CONTENT = {
ua: "test",
screens: [
{
id: "AW_IMPORT_SETTINGS",
content: {
primary_button: {
action: {
type: "SHOW_MIGRATION_WIZARD",
},
},
},
},
],
};
const data = await AboutWelcomeDefaults.prepareContentForReact(
TEST_CONTENT
);
assert.propertyVal(data, "ua", "test");
assert.propertyVal(
data.screens[0].content.primary_button.action.data,
"source",
"test"
);
});
it("should not set action if the action type != SHOW_MIGRATION_WIZARD", async () => {
const TEST_CONTENT = {
ua: "test",
screens: [
{
id: "AW_IMPORT_SETTINGS",
content: {
primary_button: {
action: {
type: "SHOW_FIREFOX_ACCOUNTS",
data: {},
},
},
},
},
],
};
const data = await AboutWelcomeDefaults.prepareContentForReact(
TEST_CONTENT
);
assert.propertyVal(data, "ua", "test");
assert.notPropertyVal(
data.screens[0].content.primary_button.action.data,
"source",
"test"
);
});
it("should remove theme screens on win7", async () => {
sandbox
.stub(global.AppConstants, "isPlatformAndVersionAtMost")
.returns(true);
sandbox
.stub(global.AWScreenUtils, "removeScreens")
.callsFake((screens, screen) =>
AWScreenUtils.removeScreens(screens, screen)
);
const { screens } = await AboutWelcomeDefaults.prepareContentForReact({
screens: [
{
content: {
tiles: { type: "theme" },
},
},
{ id: "hello" },
{
content: {
tiles: { type: "theme" },
},
},
{ id: "world" },
],
});
assert.deepEqual(screens, [{ id: "hello" }, { id: "world" }]);
});
it("shouldn't remove colorway screens on win7", async () => {
sandbox
.stub(global.AppConstants, "isPlatformAndVersionAtMost")
.returns(true);
sandbox
.stub(global.AWScreenUtils, "removeScreens")
.callsFake((screens, screen) =>
AWScreenUtils.removeScreens(screens, screen)
);
const { screens } = await AboutWelcomeDefaults.prepareContentForReact({
screens: [
{
content: {
tiles: { type: "colorway" },
},
},
{ id: "hello" },
{
content: {
tiles: { type: "theme" },
},
},
{ id: "world" },
],
});
assert.deepEqual(screens, [
{
content: {
tiles: { type: "colorway" },
},
},
{ id: "hello" },
{ id: "world" },
]);
});
});
});