Fix Bug 1515411 - Disable Return to AMO for 65 Beta and Release (#4627)

This commit is contained in:
Andrei Oprea 2019-01-07 16:08:22 +00:00 коммит произвёл GitHub
Родитель 9f3d228bad
Коммит 41af1777aa
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 102 добавлений и 6 удалений

Просмотреть файл

@ -340,10 +340,15 @@ class _ASRouter {
}
}
// Group existing blocked messages with messages blocked through preferences
const excludeList = ASRouterPreferences.providers.filter(p => p.exclude)
.reduce((blocked, p) => blocked.concat(p.exclude), this.state.messageBlockList);
this.setState(prevState => ({
providers,
// Clear any messages from removed providers
messages: [...prevState.messages.filter(message => providerIDs.includes(message.provider))],
messageBlockList: excludeList,
}));
}

Просмотреть файл

@ -153,6 +153,24 @@ function sortMessagesByWeightedRank(messages) {
.map(({message}) => message);
}
/**
* Messages with targeting should get evaluated first, this way we can have
* fallback messages (no targeting at all) that will show up if nothing else
* matched
*/
function sortMessagesByTargeting(messages) {
return messages.sort((a, b) => {
if (a.targeting && !b.targeting) {
return -1;
}
if (!a.targeting && b.targeting) {
return 1;
}
return 0;
});
}
const TargetingGetters = {
get locale() {
return Services.locale.appLocaleAsLangTag;
@ -347,7 +365,8 @@ this.ASRouterTargeting = {
* @returns {obj} an AS router message
*/
async findMatchingMessage({messages, trigger, context, onError}) {
const sortedMessages = sortMessagesByWeightedRank([...messages]);
const weightSortedMessages = sortMessagesByWeightedRank([...messages]);
const sortedMessages = sortMessagesByTargeting(weightSortedMessages);
for (const candidate of sortedMessages) {
if (

Просмотреть файл

@ -212,6 +212,8 @@ const PREFS_CONFIG = new Map([
type: "local",
localProvider: "OnboardingMessageProvider",
enabled: true,
// Block specific messages from this local provider
exclude: ["RETURN_TO_AMO_1"],
}),
}],
// See browser/app/profile/firefox.js for other ASR preferences. They must be defined there to enable roll-outs.

Просмотреть файл

@ -145,7 +145,6 @@ const ONBOARDING_MESSAGES = async () => ([
{
id: "FXA_1",
template: "fxa_overlay",
targeting: "attributionData.campaign != 'non-fx-button' && attributionData.source != 'addons.mozilla.org'",
trigger: {id: "firstRun"},
},
{

Просмотреть файл

@ -130,6 +130,14 @@ describe("ASRouter", () => {
assert.deepEqual(Router.state.messageBlockList, ["foo"]);
});
it("should set state.messageBlockList to the block list in ASRouterPreferences", async () => {
setMessageProviderPref([{id: "onboarding", type: "local", exclude: ["RTAMO"]}]);
messageBlockList = ["foo"];
Router = new _ASRouter();
await Router.init(channel, createFakeStorage(), dispatchStub);
assert.deepEqual(Router.state.messageBlockList, ["foo", "RTAMO"]);
});
it("should set state.messageImpressions to the messageImpressions object in persistent storage", async () => {
// Note that messageImpressions are only kept if a message exists in router and has a .frequency property,
// otherwise they will be cleaned up by .cleanupImpressions()

Просмотреть файл

@ -1,4 +1,5 @@
import {CachedTargetingGetter} from "lib/ASRouterTargeting.jsm";
import {ASRouterTargeting, CachedTargetingGetter} from "lib/ASRouterTargeting.jsm";
import {OnboardingMessageProvider} from "lib/OnboardingMessageProvider.jsm";
// Note that tests for the ASRouterTargeting environment can be found in
// test/functional/mochitest/browser_asrouter_targeting.js
@ -50,4 +51,23 @@ describe("#CachedTargetingGetter", () => {
assert.calledOnce(global.Cu.reportError);
}
});
it("should check targeted message before message without targeting", async () => {
const messages = (await OnboardingMessageProvider.getUntranslatedMessages());
const stub = sandbox.stub(ASRouterTargeting, "checkMessageTargeting").resolves();
const context = {attributionData: {campaign: "non-fx-button", source: "addons.mozilla.org"}};
await ASRouterTargeting.findMatchingMessage({messages, trigger: {id: "firstRun"}, context});
assert.calledTwice(stub);
assert.equal(stub.firstCall.args[0].id, "RETURN_TO_AMO_1");
assert.equal(stub.secondCall.args[0].id, "FXA_1");
});
it("should return FxA message (is fallback)", async () => {
const messages = (await OnboardingMessageProvider.getUntranslatedMessages())
.filter(m => m.id !== "RETURN_TO_AMO_1");
const context = {attributionData: {campaign: "non-fx-button", source: "addons.mozilla.org"}};
const result = await ASRouterTargeting.findMatchingMessage({messages, trigger: {id: "firstRun"}, context});
assert.isDefined(result);
assert.equal(result.id, "FXA_1");
});
});

Просмотреть файл

@ -0,0 +1,22 @@
import {mountWithIntl} from "test/unit/utils";
import React from "react";
import {ReturnToAMO} from "content-src/asrouter/templates/ReturnToAMO/ReturnToAMO";
describe("<ReturnToAMO>", () => {
let dispatch;
let onReady;
beforeEach(() => {
dispatch = sinon.stub();
onReady = sinon.stub();
const content = {
primary_button: {},
secondary_button: {},
};
mountWithIntl(<ReturnToAMO onReady={onReady} dispatch={dispatch} content={content} />);
});
it("should call onReady on componentDidMount", () => {
assert.calledOnce(onReady);
});
});

Просмотреть файл

@ -8,19 +8,35 @@ describe("<StartupOverlay>", () => {
let dispatch;
let onReady;
let onBlock;
let sandbox;
beforeEach(() => {
dispatch = sinon.stub();
onReady = sinon.stub();
onBlock = sinon.stub();
sandbox = sinon.sandbox.create();
dispatch = sandbox.stub();
onReady = sandbox.stub();
onBlock = sandbox.stub();
wrapper = mountWithIntl(<StartupOverlay onBlock={onBlock} onReady={onReady} dispatch={dispatch} />);
});
afterEach(() => {
sandbox.restore();
});
it("should not render if state.show is false", () => {
wrapper.setState({overlayRemoved: true});
assert.isTrue(wrapper.isEmptyRender());
});
it("should call prop.onReady after mount + timeout", async () => {
const clock = sandbox.useFakeTimers();
wrapper = mountWithIntl(<StartupOverlay onBlock={onBlock} onReady={onReady} dispatch={dispatch} />);
wrapper.setState({overlayRemoved: false});
clock.tick(10);
assert.calledOnce(onReady);
});
it("should emit UserEvent SKIPPED_SIGNIN when you click the skip button", () => {
let skipButton = wrapper.find(".skip-button");
assert.ok(skipButton.exists());

Просмотреть файл

@ -270,6 +270,11 @@ const TEST_GLOBAL = {
return Promise.resolve(stringsIds.map(({id, args}) => ({value: {string_id: id, args}})));
}
},
FxAccountsConfig: {
promiseEmailFirstURI(id) {
return Promise.resolve(id);
},
},
};
overrider.set(TEST_GLOBAL);