Fix Bug 1501817 - Create FxA onboarding card (#4526)
This commit is contained in:
Родитель
89c7a43a65
Коммит
fde609a8ab
|
@ -9,6 +9,7 @@ Please note that some targeting attributes require stricter controls on the tele
|
|||
## Available attributes
|
||||
|
||||
* [addonsInfo](#addonsinfo)
|
||||
* [attributionData](#attributiondata)
|
||||
* [browserSettings](#browsersettings)
|
||||
* [currentDate](#currentdate)
|
||||
* [devToolsOpenedCount](#devtoolsopenedcount)
|
||||
|
@ -76,20 +77,40 @@ interface AddonsInfoResponse {
|
|||
};
|
||||
}
|
||||
```
|
||||
### `attributionData`
|
||||
|
||||
An object containing information on exactly how Firefox was downloaded
|
||||
|
||||
#### Examples
|
||||
* Was the browser installed via the `"back_to_school"` campaign?
|
||||
```java
|
||||
attributionData && attributionData.campaign == "back_to_school"
|
||||
```
|
||||
|
||||
#### Definition
|
||||
```ts
|
||||
declare const attributionData: AttributionCode;
|
||||
interface AttributionCode {
|
||||
// Descriptor for where the download started from
|
||||
campaign: string,
|
||||
// A source, like addons.mozilla.org, or google.com
|
||||
source: string,
|
||||
// The medium for the download, like if this was referral
|
||||
medium: string,
|
||||
// Additional content, like an addonID for instance
|
||||
content: string
|
||||
}
|
||||
```
|
||||
|
||||
### `browserSettings`
|
||||
|
||||
Includes two properties:
|
||||
* `attribution`, which indicates how Firefox was downloaded,
|
||||
* `attribution`, which indicates how Firefox was downloaded - DEPRECATED - please use [attributionData](#attributiondata)
|
||||
* `update`, which has information about how Firefox updates
|
||||
|
||||
Note that attribution can be `undefined`, so you should check that it exists first.
|
||||
|
||||
#### Examples
|
||||
* Was the browser installed via the `"back_to_school"` campaign?
|
||||
```java
|
||||
browserSettings.attribution && browserSettings.attribution.campaign == "back_to_school"
|
||||
```
|
||||
* Is updating enabled?
|
||||
```java
|
||||
browserSettings.update.enabled
|
||||
|
|
|
@ -86,6 +86,10 @@
|
|||
&.gift {
|
||||
background-image: url('resource://activity-stream/data/content/assets/illustration-gift@2x.png');
|
||||
}
|
||||
|
||||
&.sync {
|
||||
background-image: url('resource://activity-stream/data/content/assets/illustration-sync@2x.png');
|
||||
}
|
||||
}
|
||||
|
||||
.onboardingContent {
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 12 KiB |
|
@ -15,8 +15,8 @@ ChromeUtils.defineModuleGetter(this, "TelemetryEnvironment",
|
|||
"resource://gre/modules/TelemetryEnvironment.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "NewTabUtils",
|
||||
"resource://gre/modules/NewTabUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "AttributionCode",
|
||||
"resource:///modules/AttributionCode.jsm");
|
||||
|
||||
const FXA_USERNAME_PREF = "services.sync.username";
|
||||
const SEARCH_REGION_PREF = "browser.search.region";
|
||||
|
@ -163,10 +163,15 @@ const TargetingGetters = {
|
|||
get browserSettings() {
|
||||
const {settings} = TelemetryEnvironment.currentEnvironment;
|
||||
return {
|
||||
// This way of getting attribution is deprecated - use atttributionData instead
|
||||
attribution: settings.attribution,
|
||||
update: settings.update,
|
||||
};
|
||||
},
|
||||
get attributionData() {
|
||||
// Attribution is determined at startup - so we can use the cached attribution at this point
|
||||
return AttributionCode.getCachedAttributionData();
|
||||
},
|
||||
get currentDate() {
|
||||
return new Date();
|
||||
},
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
ChromeUtils.import("resource://gre/modules/Localization.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/FxAccountsConfig.jsm");
|
||||
|
||||
const L10N = new Localization([
|
||||
"branding/brand.ftl",
|
||||
"browser/branding/sync-brand.ftl",
|
||||
"browser/newtab/onboarding.ftl",
|
||||
]);
|
||||
|
||||
const ONBOARDING_MESSAGES = () => ([
|
||||
const ONBOARDING_MESSAGES = async () => ([
|
||||
{
|
||||
id: "ONBOARDING_1",
|
||||
template: "onboarding",
|
||||
|
@ -55,6 +58,7 @@ const ONBOARDING_MESSAGES = () => ([
|
|||
data: {args: "addons"},
|
||||
},
|
||||
},
|
||||
targeting: "attributionData.campaign != 'non-fx-button' && attributionData.source != 'addons.mozilla.org'",
|
||||
trigger: {id: "firstRun"},
|
||||
},
|
||||
{
|
||||
|
@ -75,6 +79,24 @@ const ONBOARDING_MESSAGES = () => ([
|
|||
targeting: "providerCohorts.onboarding == 'ghostery'",
|
||||
trigger: {id: "firstRun"},
|
||||
},
|
||||
{
|
||||
id: "ONBOARDING_5",
|
||||
template: "onboarding",
|
||||
bundled: 3,
|
||||
order: 4,
|
||||
content: {
|
||||
title: {string_id: "onboarding-fxa-title"},
|
||||
text: {string_id: "onboarding-fxa-text"},
|
||||
icon: "sync",
|
||||
button_label: {string_id: "onboarding-button-label-get-started"},
|
||||
button_action: {
|
||||
type: "OPEN_URL",
|
||||
data: {args: await FxAccountsConfig.promiseEmailFirstURI("onboarding")},
|
||||
},
|
||||
},
|
||||
targeting: "attributionData.campaign == 'non-fx-button' && attributionData.source == 'addons.mozilla.org'",
|
||||
trigger: {id: "firstRun"},
|
||||
},
|
||||
]);
|
||||
|
||||
const OnboardingMessageProvider = {
|
||||
|
@ -86,12 +108,13 @@ const OnboardingMessageProvider = {
|
|||
return {header: header.value, button_label: button_label.value};
|
||||
},
|
||||
async getMessages() {
|
||||
const messages = await this.translateMessages(ONBOARDING_MESSAGES());
|
||||
const messages = await this.translateMessages(await ONBOARDING_MESSAGES());
|
||||
return messages;
|
||||
},
|
||||
getUntranslatedMessages() {
|
||||
async getUntranslatedMessages() {
|
||||
// This is helpful for jsonSchema testing - since we are localizing in the provider
|
||||
return ONBOARDING_MESSAGES();
|
||||
const messages = await ONBOARDING_MESSAGES();
|
||||
return messages;
|
||||
},
|
||||
async translateMessages(messages) {
|
||||
let translatedMessages = [];
|
||||
|
|
|
@ -385,9 +385,6 @@ add_task(async function check_region() {
|
|||
});
|
||||
|
||||
add_task(async function check_browserSettings() {
|
||||
is(await ASRouterTargeting.Environment.browserSettings.attribution, TelemetryEnvironment.currentEnvironment.settings.attribution,
|
||||
"should return correct attribution info");
|
||||
|
||||
is(await JSON.stringify(ASRouterTargeting.Environment.browserSettings.update), JSON.stringify(TelemetryEnvironment.currentEnvironment.settings.update),
|
||||
"should return correct update info");
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import {GlobalOverrider} from "test/unit/utils";
|
||||
import {OnboardingMessageProvider} from "lib/OnboardingMessageProvider.jsm";
|
||||
import schema from "content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.schema.json";
|
||||
|
||||
|
@ -21,14 +22,25 @@ const L10N_CONTENT = {
|
|||
};
|
||||
|
||||
describe("OnboardingMessage", () => {
|
||||
let globals;
|
||||
let sandbox;
|
||||
beforeEach(() => {
|
||||
globals = new GlobalOverrider();
|
||||
sandbox = sinon.sandbox.create();
|
||||
globals.set("FxAccountsConfig", {promiseEmailFirstURI: sandbox.stub().resolves("some/url")});
|
||||
});
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
globals.restore();
|
||||
});
|
||||
it("should validate DEFAULT_CONTENT", () => {
|
||||
assert.jsonSchema(DEFAULT_CONTENT, schema);
|
||||
});
|
||||
it("should validate L10N_CONTENT", () => {
|
||||
assert.jsonSchema(L10N_CONTENT, schema);
|
||||
});
|
||||
it("should validate all messages from OnboardingMessageProvider", () => {
|
||||
const messages = OnboardingMessageProvider.getUntranslatedMessages();
|
||||
it("should validate all messages from OnboardingMessageProvider", async () => {
|
||||
const messages = await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
messages.forEach(msg => assert.jsonSchema(msg.content, schema));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource:///modules/AttributionCode.jsm");
|
||||
ChromeUtils.import("resource://activity-stream/lib/ASRouterTargeting.jsm");
|
||||
|
||||
add_task(async function check_attribution_data() {
|
||||
// Some setup to fake the correct attribution data
|
||||
const appPath = Services.dirsvc.get("GreD", Ci.nsIFile).parent.parent.path;
|
||||
const attributionSvc = Cc["@mozilla.org/mac-attribution;1"]
|
||||
.getService(Ci.nsIMacAttributionService);
|
||||
const campaign = "non-fx-button";
|
||||
const source = "addons.mozilla.org";
|
||||
const referrer = `https://allizom.org/anything/?utm_campaign=${campaign}&utm_source=${source}`;
|
||||
attributionSvc.setReferrerUrl(appPath, referrer, true);
|
||||
AttributionCode._clearCache();
|
||||
AttributionCode.getAttrDataAsync();
|
||||
|
||||
const {campaign: attributionCampain, source: attributionSource} = ASRouterTargeting.Environment.attributionData;
|
||||
equal(attributionCampain, campaign, "should get the correct campaign out of attributionData");
|
||||
equal(attributionSource, source, "should get the correct source out of attributionData");
|
||||
|
||||
const messages = [
|
||||
{id: "foo1", targeting: "attributionData.campaign == 'back_to_school' && attributionData.source == 'addons.mozilla.org'"},
|
||||
{id: "foo2", targeting: "attributionData.campaign == 'non-fx-button' && attributionData.source == 'addons.mozilla.org'"},
|
||||
];
|
||||
|
||||
equal(await ASRouterTargeting.findMatchingMessage({messages}), messages[1],
|
||||
"should select the message with the correct campaign and source");
|
||||
AttributionCode._clearCache();
|
||||
});
|
|
@ -4,3 +4,5 @@ firefox-appdir = browser
|
|||
skip-if = toolkit == 'android'
|
||||
|
||||
[test_AboutNewTabService.js]
|
||||
[test_ASRouterTargeting_attribution.js]
|
||||
skip-if = toolkit != "cocoa" # osx specific tests
|
||||
|
|
Загрузка…
Ссылка в новой задаче