Bug 1649538 - Add new Snippets template for Send to Device r=k88hudson

Differential Revision: https://phabricator.services.mozilla.com/D83135
This commit is contained in:
Andrei Oprea 2020-07-22 20:56:31 +00:00
Родитель 05bded91a1
Коммит 7e6bdb7722
12 изменённых файлов: 571 добавлений и 73 удалений

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

@ -70,3 +70,7 @@ export const SendToDeviceSnippet = props => {
/>
);
};
export const SendToDeviceScene2Snippet = props => {
return <SendToDeviceSnippet expandedAlt={true} {...props} />;
};

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

@ -0,0 +1,163 @@
{
"title": "SubmitFormSnippet",
"description": "A template with two states: a SimpleSnippet and another that contains a form",
"version": "1.2.0",
"type": "object",
"definitions": {
"plainText": {
"description": "Plain text (no HTML allowed)",
"type": "string"
},
"richText": {
"description": "Text with HTML subset allowed: i, b, u, strong, em, br",
"type": "string"
},
"link_url": {
"description": "Target for links or buttons",
"type": "string",
"format": "uri"
}
},
"properties": {
"locale": {
"type": "string",
"description": "Two to five character string for the locale code"
},
"country": {
"type": "string",
"description": "Two character string for the country code (used for SMS)"
},
"section_title_icon": {
"type": "string",
"description": "Section title icon. 16x16px. SVG or PNG preferred. section_title_text must also be specified to display."
},
"section_title_icon_dark_theme": {
"type": "string",
"description": "Section title icon, dark theme variant. 16x16px. SVG or PNG preferred. section_title_text must also be specified to display."
},
"section_title_text": {
"type": "string",
"description": "Section title text. section_title_icon must also be specified to display."
},
"scene2_title": {
"allOf": [
{"$ref": "#/definitions/plainText"},
{"description": "Title displayed before text in scene 2. Should be plain text."}
]
},
"scene2_text": {
"allOf": [
{"$ref": "#/definitions/richText"},
{"description": "Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}
]
},
"form_action": {
"type": "string",
"description": "Endpoint to submit form data."
},
"success_title": {
"type": "string",
"description": "(send to device) Title shown before text on successful registration."
},
"success_text": {
"type": "string",
"description": "Message shown on successful registration."
},
"error_text": {
"type": "string",
"description": "Message shown if registration failed."
},
"scene2_email_placeholder_text": {
"type": "string",
"description": "Value to show while input is empty."
},
"scene2_input_placeholder": {
"type": "string",
"description": "(send to device) Value to show while input is empty."
},
"scene2_button_label": {
"type": "string",
"description": "Label for form submit button"
},
"scene2_privacy_html": {
"type": "string",
"description": "Information about how the form data is used."
},
"scene2_disclaimer_html": {
"type": "string",
"description": "(send to device) Html for disclaimer and link underneath input box."
},
"scene2_icon": {
"type": "string",
"description": "(send to device) Image to display above the form. 98x98px. SVG or PNG preferred."
},
"scene2_icon_dark_theme": {
"type": "string",
"description": "(send to device) Image to display above the form. Dark theme variant. 98x98px. SVG or PNG preferred."
},
"scene2_icon_alt_text": {
"type": "string",
"description": "Alt text describing scene2 icon for screen readers",
"default": ""
},
"scene2_newsletter": {
"type": "string",
"description": "Newsletter/basket id user is subscribing to. Must be a value from the 'Slug' column here: https://basket.mozilla.org/news/. Default 'mozilla-foundation'."
},
"hidden_inputs": {
"type": "object",
"description": "Each entry represents a hidden input, key is used as value for the name property."
},
"retry_button_label": {
"allOf": [
{"$ref": "#/definitions/plainText"},
{"description": "Text for the button in the event of a submission error/failure."}
],
"default": "Try again"
},
"do_not_autoblock": {
"type": "boolean",
"description": "Used to prevent blocking the snippet after the CTA (link or button) has been clicked"
},
"include_sms": {
"type": "boolean",
"description": "(send to device) Allow users to send an SMS message with the form?"
},
"message_id_sms": {
"type": "string",
"description": "(send to device) Newsletter/basket id representing the SMS message to be sent."
},
"message_id_email": {
"type": "string",
"description": "(send to device) Newsletter/basket id representing the email message to be sent. Must be a value from the 'Slug' column here: https://basket.mozilla.org/news/."
},
"utm_campaign": {
"type": "string",
"description": "(fxa) Value to pass through to GA as utm_campaign."
},
"utm_term": {
"type": "string",
"description": "(fxa) Value to pass through to GA as utm_term."
},
"links": {
"additionalProperties": {
"url": {
"allOf": [
{"$ref": "#/definitions/link_url"},
{"description": "The url where the link points to."}
]
},
"metric": {
"type": "string",
"description": "Custom event name sent with telemetry event."
}
}
}
},
"additionalProperties": false,
"required": ["scene2_text"],
"dependencies": {
"section_title_icon": ["section_title_text"],
"section_title_icon_dark_theme": ["section_title_text"]
}
}

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

@ -8,6 +8,7 @@ import { RichText } from "../../components/RichText/RichText";
import { safeURI } from "../../template-utils";
import { SimpleSnippet } from "../SimpleSnippet/SimpleSnippet";
import { SnippetBase } from "../../components/SnippetBase/SnippetBase";
import ConditionalWrapper from "../../components/ConditionalWrapper/ConditionalWrapper";
// Alt text placeholder in case the prop from the server isn't available
const ICON_ALT_TEXT = "";
@ -226,6 +227,53 @@ export class SubmitFormSnippet extends React.PureComponent {
);
}
renderForm() {
return (
<form
action={this.props.form_action}
method={this.props.form_method}
onSubmit={this.handleSubmit}
ref="form"
>
{this.renderHiddenFormInputs()}
<div>
{this.renderInput()}
<button
type="submit"
className="ASRouterButton primary"
onClick={this.handleSubmitAttempt}
ref="formSubmitBtn"
>
{this.props.content.scene2_button_label}
</button>
</div>
{this.renderFormPrivacyNotice() || this.renderDisclaimer()}
</form>
);
}
renderScene2Icon() {
const { content } = this.props;
if (!content.scene2_icon) {
return null;
}
return (
<div className="scene2Icon">
<img
src={safeURI(content.scene2_icon)}
className="icon-light-theme"
alt={content.scene2_icon_alt_text || ICON_ALT_TEXT}
/>
<img
src={safeURI(content.scene2_icon_dark_theme || content.scene2_icon)}
className="icon-dark-theme"
alt={content.scene2_icon_alt_text || ICON_ALT_TEXT}
/>
</div>
);
}
renderSignupView() {
const { content } = this.props;
const containerClass = `SubmitFormSnippet ${this.props.className}`;
@ -235,22 +283,7 @@ export class SubmitFormSnippet extends React.PureComponent {
className={containerClass}
footerDismiss={true}
>
{content.scene2_icon ? (
<div className="scene2Icon">
<img
src={safeURI(content.scene2_icon)}
className="icon-light-theme"
alt={content.scene2_icon_alt_text || ICON_ALT_TEXT}
/>
<img
src={safeURI(
content.scene2_icon_dark_theme || content.scene2_icon
)}
className="icon-dark-theme"
alt={content.scene2_icon_alt_text || ICON_ALT_TEXT}
/>
</div>
) : null}
{this.renderScene2Icon()}
<div className="message">
<p>
{content.scene2_title && (
@ -264,26 +297,70 @@ export class SubmitFormSnippet extends React.PureComponent {
)}
</p>
</div>
<form
action={this.props.form_action}
method={this.props.form_method}
onSubmit={this.handleSubmit}
ref="form"
>
{this.renderHiddenFormInputs()}
<div>
{this.renderInput()}
<button
type="submit"
className="ASRouterButton primary"
onClick={this.handleSubmitAttempt}
ref="formSubmitBtn"
>
{content.scene2_button_label}
</button>
</div>
{this.renderFormPrivacyNotice() || this.renderDisclaimer()}
</form>
{this.renderForm()}
</SnippetBase>
);
}
renderSectionHeader() {
const { props } = this;
// an icon and text must be specified to render the section header
if (props.content.section_title_icon && props.content.section_title_text) {
const sectionTitleIconLight = safeURI(props.content.section_title_icon);
const sectionTitleIconDark = safeURI(
props.content.section_title_icon_dark_theme ||
props.content.section_title_icon
);
const sectionTitleURL = props.content.section_title_url;
return (
<div className="section-header">
<h3 className="section-title">
<ConditionalWrapper condition={sectionTitleURL}>
<span
className="icon icon-small-spacer icon-light-theme"
style={{ backgroundImage: `url("${sectionTitleIconLight}")` }}
/>
<span
className="icon icon-small-spacer icon-dark-theme"
style={{ backgroundImage: `url("${sectionTitleIconDark}")` }}
/>
<span className="section-title-text">
{props.content.section_title_text}
</span>
</ConditionalWrapper>
</h3>
</div>
);
}
return null;
}
renderSignupViewAlt() {
const { content } = this.props;
const containerClass = `SubmitFormSnippet ${this.props.className} scene2Alt`;
return (
<SnippetBase
{...this.props}
className={containerClass}
// Don't show bottom dismiss button
footerDismiss={false}
>
{this.renderSectionHeader()}
{this.renderScene2Icon()}
<div className="message">
<p>
{content.scene2_text && (
<RichText
scene2_text={content.scene2_text}
localization_id="scene2_text"
/>
)}
</p>
{this.renderForm()}
</div>
</SnippetBase>
);
}
@ -306,6 +383,10 @@ export class SubmitFormSnippet extends React.PureComponent {
if (this.state.expanded) {
return this.renderSignupView();
}
// Render only scene 2 (signup view)
if (this.props.expandedAlt) {
return this.renderSignupViewAlt();
}
return (
<SimpleSnippet
{...this.props}

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

@ -4,7 +4,7 @@
width: 100%;
.disclaimerText {
margin: 20px 0 0;
margin: 5px 0 0;
font-size: 12px;
color: var(--newtab-text-secondary-color);
}
@ -72,7 +72,8 @@
}
.innerWrapper {
max-width: 670px;
// https://github.com/mozmeao/snippets/blob/2054899350590adcb3c0b0a341c782b0e2f81d0b/activity-stream/newsletter-subscribe.html#L46
max-width: 736px;
flex-wrap: wrap;
justify-items: center;
padding-top: 40px;
@ -121,6 +122,36 @@
}
}
}
&.scene2Alt {
text-align: start;
.scene2Icon {
flex: 1;
margin-bottom: 0;
}
.message {
flex: 5;
margin-bottom: 0;
p {
margin-bottom: 10px;
}
}
.section-header {
width: 100%;
.icon {
margin-inline-end: 0;
}
}
.innerWrapper {
padding: 0 0 16px;
}
}
}
.submissionStatus {

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

@ -5,7 +5,10 @@
import { EOYSnippet } from "./EOYSnippet/EOYSnippet";
import { FXASignupSnippet } from "./FXASignupSnippet/FXASignupSnippet";
import { NewsletterSnippet } from "./NewsletterSnippet/NewsletterSnippet";
import { SendToDeviceSnippet } from "./SendToDeviceSnippet/SendToDeviceSnippet";
import {
SendToDeviceSnippet,
SendToDeviceScene2Snippet,
} from "./SendToDeviceSnippet/SendToDeviceSnippet";
import { SimpleBelowSearchSnippet } from "./SimpleBelowSearchSnippet/SimpleBelowSearchSnippet";
import { SimpleSnippet } from "./SimpleSnippet/SimpleSnippet";
@ -15,6 +18,7 @@ export const SnippetsTemplates = {
newsletter_snippet: NewsletterSnippet,
fxa_signup_snippet: FXASignupSnippet,
send_to_device_snippet: SendToDeviceSnippet,
send_to_device_scene2_snippet: SendToDeviceScene2Snippet,
eoy_snippet: EOYSnippet,
simple_below_search_snippet: SimpleBelowSearchSnippet,
};

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

@ -3942,7 +3942,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
flex: 1 1 100%;
width: 100%; }
.SubmitFormSnippet .disclaimerText {
margin: 20px 0 0;
margin: 5px 0 0;
font-size: 12px;
color: var(--newtab-text-secondary-color); }
.SubmitFormSnippet p {
@ -3984,7 +3984,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: flex;
flex: 0 0 100%; }
.SubmitFormSnippet .innerWrapper {
max-width: 670px;
max-width: 736px;
flex-wrap: wrap;
justify-items: center;
padding-top: 40px;
@ -4015,6 +4015,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.SubmitFormSnippet input.mainInput:focus {
border: 1px solid var(--newtab-textbox-focus-color);
box-shadow: var(--newtab-textbox-focus-boxshadow); }
.SubmitFormSnippet.scene2Alt {
text-align: start; }
.SubmitFormSnippet.scene2Alt .scene2Icon {
flex: 1;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message {
flex: 5;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message p {
margin-bottom: 10px; }
.SubmitFormSnippet.scene2Alt .section-header {
width: 100%; }
.SubmitFormSnippet.scene2Alt .section-header .icon {
margin-inline-end: 0; }
.SubmitFormSnippet.scene2Alt .innerWrapper {
padding: 0 0 16px; }
.submissionStatus {
text-align: center;

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

@ -3945,7 +3945,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
flex: 1 1 100%;
width: 100%; }
.SubmitFormSnippet .disclaimerText {
margin: 20px 0 0;
margin: 5px 0 0;
font-size: 12px;
color: var(--newtab-text-secondary-color); }
.SubmitFormSnippet p {
@ -3987,7 +3987,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: flex;
flex: 0 0 100%; }
.SubmitFormSnippet .innerWrapper {
max-width: 670px;
max-width: 736px;
flex-wrap: wrap;
justify-items: center;
padding-top: 40px;
@ -4018,6 +4018,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.SubmitFormSnippet input.mainInput:focus {
border: 1px solid var(--newtab-textbox-focus-color);
box-shadow: var(--newtab-textbox-focus-boxshadow); }
.SubmitFormSnippet.scene2Alt {
text-align: start; }
.SubmitFormSnippet.scene2Alt .scene2Icon {
flex: 1;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message {
flex: 5;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message p {
margin-bottom: 10px; }
.SubmitFormSnippet.scene2Alt .section-header {
width: 100%; }
.SubmitFormSnippet.scene2Alt .section-header .icon {
margin-inline-end: 0; }
.SubmitFormSnippet.scene2Alt .innerWrapper {
padding: 0 0 16px; }
.submissionStatus {
text-align: center;

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

@ -3942,7 +3942,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
flex: 1 1 100%;
width: 100%; }
.SubmitFormSnippet .disclaimerText {
margin: 20px 0 0;
margin: 5px 0 0;
font-size: 12px;
color: var(--newtab-text-secondary-color); }
.SubmitFormSnippet p {
@ -3984,7 +3984,7 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: flex;
flex: 0 0 100%; }
.SubmitFormSnippet .innerWrapper {
max-width: 670px;
max-width: 736px;
flex-wrap: wrap;
justify-items: center;
padding-top: 40px;
@ -4015,6 +4015,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.SubmitFormSnippet input.mainInput:focus {
border: 1px solid var(--newtab-textbox-focus-color);
box-shadow: var(--newtab-textbox-focus-boxshadow); }
.SubmitFormSnippet.scene2Alt {
text-align: start; }
.SubmitFormSnippet.scene2Alt .scene2Icon {
flex: 1;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message {
flex: 5;
margin-bottom: 0; }
.SubmitFormSnippet.scene2Alt .message p {
margin-bottom: 10px; }
.SubmitFormSnippet.scene2Alt .section-header {
width: 100%; }
.SubmitFormSnippet.scene2Alt .section-header .icon {
margin-inline-end: 0; }
.SubmitFormSnippet.scene2Alt .innerWrapper {
padding: 0 0 16px; }
.submissionStatus {
text-align: center;

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

@ -12819,6 +12819,7 @@ function SubmitFormSnippet_extends() { SubmitFormSnippet_extends = Object.assign
// Alt text placeholder in case the prop from the server isn't available
const SubmitFormSnippet_ICON_ALT_TEXT = "";
@ -13052,32 +13053,8 @@ class SubmitFormSnippet_SubmitFormSnippet extends external_React_default.a.PureC
});
}
renderSignupView() {
const {
content
} = this.props;
const containerClass = `SubmitFormSnippet ${this.props.className}`;
return external_React_default.a.createElement(SnippetBase_SnippetBase, SubmitFormSnippet_extends({}, this.props, {
className: containerClass,
footerDismiss: true
}), content.scene2_icon ? external_React_default.a.createElement("div", {
className: "scene2Icon"
}, external_React_default.a.createElement("img", {
src: Object(template_utils["safeURI"])(content.scene2_icon),
className: "icon-light-theme",
alt: content.scene2_icon_alt_text || SubmitFormSnippet_ICON_ALT_TEXT
}), external_React_default.a.createElement("img", {
src: Object(template_utils["safeURI"])(content.scene2_icon_dark_theme || content.scene2_icon),
className: "icon-dark-theme",
alt: content.scene2_icon_alt_text || SubmitFormSnippet_ICON_ALT_TEXT
})) : null, external_React_default.a.createElement("div", {
className: "message"
}, external_React_default.a.createElement("p", null, content.scene2_title && external_React_default.a.createElement("h3", {
className: "scene2Title"
}, content.scene2_title), " ", content.scene2_text && external_React_default.a.createElement(RichText["RichText"], {
scene2_text: content.scene2_text,
localization_id: "scene2_text"
}))), external_React_default.a.createElement("form", {
renderForm() {
return external_React_default.a.createElement("form", {
action: this.props.form_action,
method: this.props.form_method,
onSubmit: this.handleSubmit,
@ -13087,7 +13064,97 @@ class SubmitFormSnippet_SubmitFormSnippet extends external_React_default.a.PureC
className: "ASRouterButton primary",
onClick: this.handleSubmitAttempt,
ref: "formSubmitBtn"
}, content.scene2_button_label)), this.renderFormPrivacyNotice() || this.renderDisclaimer()));
}, this.props.content.scene2_button_label)), this.renderFormPrivacyNotice() || this.renderDisclaimer());
}
renderScene2Icon() {
const {
content
} = this.props;
if (!content.scene2_icon) {
return null;
}
return external_React_default.a.createElement("div", {
className: "scene2Icon"
}, external_React_default.a.createElement("img", {
src: Object(template_utils["safeURI"])(content.scene2_icon),
className: "icon-light-theme",
alt: content.scene2_icon_alt_text || SubmitFormSnippet_ICON_ALT_TEXT
}), external_React_default.a.createElement("img", {
src: Object(template_utils["safeURI"])(content.scene2_icon_dark_theme || content.scene2_icon),
className: "icon-dark-theme",
alt: content.scene2_icon_alt_text || SubmitFormSnippet_ICON_ALT_TEXT
}));
}
renderSignupView() {
const {
content
} = this.props;
const containerClass = `SubmitFormSnippet ${this.props.className}`;
return external_React_default.a.createElement(SnippetBase_SnippetBase, SubmitFormSnippet_extends({}, this.props, {
className: containerClass,
footerDismiss: true
}), this.renderScene2Icon(), external_React_default.a.createElement("div", {
className: "message"
}, external_React_default.a.createElement("p", null, content.scene2_title && external_React_default.a.createElement("h3", {
className: "scene2Title"
}, content.scene2_title), " ", content.scene2_text && external_React_default.a.createElement(RichText["RichText"], {
scene2_text: content.scene2_text,
localization_id: "scene2_text"
}))), this.renderForm());
}
renderSectionHeader() {
const {
props
} = this; // an icon and text must be specified to render the section header
if (props.content.section_title_icon && props.content.section_title_text) {
const sectionTitleIconLight = Object(template_utils["safeURI"])(props.content.section_title_icon);
const sectionTitleIconDark = Object(template_utils["safeURI"])(props.content.section_title_icon_dark_theme || props.content.section_title_icon);
const sectionTitleURL = props.content.section_title_url;
return external_React_default.a.createElement("div", {
className: "section-header"
}, external_React_default.a.createElement("h3", {
className: "section-title"
}, external_React_default.a.createElement(ConditionalWrapper_ConditionalWrapper, {
condition: sectionTitleURL
}, external_React_default.a.createElement("span", {
className: "icon icon-small-spacer icon-light-theme",
style: {
backgroundImage: `url("${sectionTitleIconLight}")`
}
}), external_React_default.a.createElement("span", {
className: "icon icon-small-spacer icon-dark-theme",
style: {
backgroundImage: `url("${sectionTitleIconDark}")`
}
}), external_React_default.a.createElement("span", {
className: "section-title-text"
}, props.content.section_title_text))));
}
return null;
}
renderSignupViewAlt() {
const {
content
} = this.props;
const containerClass = `SubmitFormSnippet ${this.props.className} scene2Alt`;
return external_React_default.a.createElement(SnippetBase_SnippetBase, SubmitFormSnippet_extends({}, this.props, {
className: containerClass // Don't show bottom dismiss button
,
footerDismiss: false
}), this.renderSectionHeader(), this.renderScene2Icon(), external_React_default.a.createElement("div", {
className: "message"
}, external_React_default.a.createElement("p", null, content.scene2_text && external_React_default.a.createElement(RichText["RichText"], {
scene2_text: content.scene2_text,
localization_id: "scene2_text"
})), this.renderForm()));
}
getFirstSceneContent() {
@ -13108,6 +13175,11 @@ class SubmitFormSnippet_SubmitFormSnippet extends external_React_default.a.PureC
if (this.state.expanded) {
return this.renderSignupView();
} // Render only scene 2 (signup view)
if (this.props.expandedAlt) {
return this.renderSignupViewAlt();
}
return external_React_default.a.createElement(SimpleSnippet_SimpleSnippet, SubmitFormSnippet_extends({}, this.props, {
@ -13298,6 +13370,11 @@ const SendToDeviceSnippet = props => {
processFormData: processFormData
}));
};
const SendToDeviceScene2Snippet = props => {
return external_React_default.a.createElement(SendToDeviceSnippet, SendToDeviceSnippet_extends({
expandedAlt: true
}, props));
};
// CONCATENATED MODULE: ./content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.jsx
function SimpleBelowSearchSnippet_extends() { SimpleBelowSearchSnippet_extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return SimpleBelowSearchSnippet_extends.apply(this, arguments); }
@ -13443,6 +13520,7 @@ const SnippetsTemplates = {
newsletter_snippet: NewsletterSnippet,
fxa_signup_snippet: FXASignupSnippet,
send_to_device_snippet: SendToDeviceSnippet,
send_to_device_scene2_snippet: SendToDeviceScene2Snippet,
eoy_snippet: EOYSnippet,
simple_below_search_snippet: SimpleBelowSearchSnippet_SimpleBelowSearchSnippet
};

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

@ -383,6 +383,39 @@ const MESSAGES = () => [
},
},
},
{
id: "SNIPPETS_SCENE2_SEND_TO_DEVICE_TEST",
template: "send_to_device_scene2_snippet",
content: {
include_sms: true,
locale: "en-CA",
country: "us",
message_id_sms: "ff-mobilesn-download",
message_id_email: "download-firefox-mobile",
scene2_icon: TEST_ICON,
section_title_icon:
"https://snippets.cdn.mozilla.net/media/icons/094b0707-ab65-4b2e-99a1-a84122b6ab26.png",
section_title_text: "Messages from Firefox",
scene2_button_label: "Send",
scene2_disclaimer_html:
"The intended recipient of the email must have consented. <privacyLink>Learn more</privacyLink>.",
scene2_input_placeholder: "Your email address or phone number",
scene2_text:
"Send Firefox to your phone and take a powerful independent browser with you.",
scene2_title: "Let's do this!",
error_text: "Oops, there was a problem.",
success_title: "Your download link was sent.",
success_text: "Check your device for the email message!",
links: {
privacyLink: {
url:
"https://www.mozilla.org/privacy/websites/?sample_rate=0.001&snippet_name=7894",
},
},
},
},
{
id: "SNIPPETS_SEND_TO_DEVICE_TEST_NO_DARK_THEME",
template: "send_to_device_snippet",

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

@ -3,12 +3,14 @@ import SimpleBelowSearchSnippetSchema from "../../../content-src/asrouter/templa
import SimpleSnippetSchema from "../../../content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.schema.json";
import { SnippetsTestMessageProvider } from "../../../lib/SnippetsTestMessageProvider.jsm";
import SubmitFormSnippetSchema from "../../../content-src/asrouter/templates/SubmitFormSnippet/SubmitFormSnippet.schema.json";
import SubmitFormScene2SnippetSchema from "../../../content-src/asrouter/templates/SubmitFormSnippet/SubmitFormScene2Snippet.schema.json";
const schemas = {
simple_snippet: SimpleSnippetSchema,
newsletter_snippet: SubmitFormSnippetSchema,
fxa_signup_snippet: SubmitFormSnippetSchema,
send_to_device_snippet: SubmitFormSnippetSchema,
send_to_device_scene2_snippet: SubmitFormScene2SnippetSchema,
eoy_snippet: EOYSnippetSchema,
simple_below_search_snippet: SimpleBelowSearchSnippetSchema,
};

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

@ -1,12 +1,18 @@
import { mount } from "enzyme";
import React from "react";
import schema from "content-src/asrouter/templates/SendToDeviceSnippet/SendToDeviceSnippet.schema.json";
import { SendToDeviceSnippet } from "content-src/asrouter/templates/SendToDeviceSnippet/SendToDeviceSnippet";
import {
SendToDeviceSnippet,
SendToDeviceScene2Snippet,
} from "content-src/asrouter/templates/SendToDeviceSnippet/SendToDeviceSnippet";
import { SnippetsTestMessageProvider } from "lib/SnippetsTestMessageProvider.jsm";
const DEFAULT_CONTENT = SnippetsTestMessageProvider.getMessages().find(
msg => msg.template === "send_to_device_snippet"
).content;
const DEFAULT_SCENE2_CONTENT = SnippetsTestMessageProvider.getMessages().find(
msg => msg.template === "send_to_device_scene2_snippet"
).content;
async function testBodyContains(body, key, value) {
const regex = new RegExp(
@ -174,4 +180,52 @@ describe("SendToDeviceSnippet", () => {
assert.ok(testBodyContains(body, "msg_name", "foo"), "has msg_name");
});
});
describe("SendToDeviceScene2Snippet", () => {
function mountWithProps(content = {}) {
const props = {
id: "foo123",
content: Object.assign({}, DEFAULT_SCENE2_CONTENT, content),
onBlock() {},
onDismiss: sandbox.stub(),
sendUserActionTelemetry: sandbox.stub(),
onAction: sandbox.stub(),
};
return mount(<SendToDeviceScene2Snippet {...props} />);
}
it("should render scene 2", () => {
const wrapper = mountWithProps();
assert.lengthOf(wrapper.find(".scene2Icon"), 1, "Found scene 2 icon");
assert.lengthOf(
wrapper.find(".scene2Title"),
0,
"Should not have a large header"
);
});
it("should have block button", () => {
const wrapper = mountWithProps();
assert.lengthOf(
wrapper.find(".blockButton"),
1,
"Found the block button"
);
});
it("should render title text", () => {
const wrapper = mountWithProps();
assert.lengthOf(
wrapper.find(".section-title-text"),
1,
"Found the section title"
);
assert.lengthOf(
wrapper.find(".section-title .icon"),
2, // light and dark theme
"Found scene 2 title"
);
});
});
});