Fix Bug 1501817 - Create FxA onboarding card (#4526)

This commit is contained in:
Ursula Sarracini 2018-11-06 11:28:45 -05:00 коммит произвёл GitHub
Родитель 89c7a43a65
Коммит fde609a8ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 115 добавлений и 16 удалений

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

@ -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 {

Двоичные данные
data/content/assets/illustration-sync@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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