mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1421806 - Create a mixin to subscribe to payment store changes. r=jaws
MozReview-Commit-ID: IGvvx7JDRtP --HG-- extra : rebase_source : 33452110c0810194c825af76efa4201c047bfea5
This commit is contained in:
parent
f5c90d1f80
commit
f2930c7a77
@ -11,6 +11,7 @@ toolkit.jar:
|
||||
% resource payments %res/payments/
|
||||
res/payments (res/paymentRequest.*)
|
||||
res/payments/components/ (res/components/*.js)
|
||||
res/payments/containers/ (res/containers/*.js)
|
||||
res/payments/debugging.html (res/debugging.html)
|
||||
res/payments/debugging.js (res/debugging.js)
|
||||
res/payments/mixins/ (res/mixins/*.js)
|
||||
|
@ -57,6 +57,9 @@ function ObservedPropertiesMixin(superClass) {
|
||||
}
|
||||
|
||||
attributeChangedCallback(attr, oldValue, newValue) {
|
||||
if (super.attributeChangedCallback) {
|
||||
super.attributeChangedCallback(attr, oldValue, newValue);
|
||||
}
|
||||
if (oldValue === newValue) {
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* global PaymentsStore */
|
||||
|
||||
/**
|
||||
* A mixin for a custom element to observe store changes to information about a payment request.
|
||||
*/
|
||||
|
||||
/**
|
||||
* State of the payment request dialog.
|
||||
*/
|
||||
let requestStore = new PaymentsStore({
|
||||
request: {
|
||||
tabId: null,
|
||||
topLevelPrincipal: {URI: {displayHost: null}},
|
||||
requestId: null,
|
||||
paymentMethods: [],
|
||||
paymentDetails: {
|
||||
id: null,
|
||||
totalItem: {label: null, amount: {currency: null, value: null}},
|
||||
displayItems: [],
|
||||
shippingOptions: [],
|
||||
modifiers: null,
|
||||
error: "",
|
||||
},
|
||||
paymentOptions: {
|
||||
requestPayerName: false,
|
||||
requestPayerEmail: false,
|
||||
requestPayerPhone: false,
|
||||
requestShipping: false,
|
||||
shippingType: "shipping",
|
||||
},
|
||||
},
|
||||
savedAddresses: [],
|
||||
savedBasicCards: [],
|
||||
});
|
||||
|
||||
|
||||
/* exported PaymentStateSubscriberMixin */
|
||||
|
||||
/**
|
||||
* A mixin to render UI based upon the requestStore and get updated when that store changes.
|
||||
*
|
||||
* Attaches `requestStore` to the element to give access to the store.
|
||||
* @param {class} superClass The class to extend
|
||||
* @returns {class}
|
||||
*/
|
||||
function PaymentStateSubscriberMixin(superClass) {
|
||||
return class PaymentStateSubscriber extends superClass {
|
||||
constructor() {
|
||||
super();
|
||||
this.requestStore = requestStore;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.requestStore.subscribe(this);
|
||||
this.render(this.requestStore.getState());
|
||||
if (super.connectedCallback) {
|
||||
super.connectedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.requestStore.unsubscribe(this);
|
||||
if (super.disconnectedCallback) {
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the store upon state changes.
|
||||
* @param {object} state The current state
|
||||
*/
|
||||
stateChangeCallback(state) {
|
||||
this.render(state);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
../../../../../testing/modules/sinon-2.3.2.js
|
||||
../../res/PaymentsStore.js
|
||||
../../res/components/currency-amount.js
|
||||
../../res/mixins/ObservedPropertiesMixin.js
|
||||
../../res/mixins/PaymentStateSubscriberMixin.js
|
||||
../../res/vendor/custom-elements.min.js
|
||||
../../res/vendor/custom-elements.min.js.map
|
||||
payments_common.js
|
||||
|
||||
[test_currency_amount.html]
|
||||
[test_ObservedPropertiesMixin.html]
|
||||
[test_PaymentStateSubscriberMixin.html]
|
||||
|
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test the PaymentStateSubscriberMixin
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the PaymentStateSubscriberMixin</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script src="sinon-2.3.2.js"></script>
|
||||
<script src="payments_common.js"></script>
|
||||
<script src="custom-elements.min.js"></script>
|
||||
<script src="PaymentsStore.js"></script>
|
||||
<script src="PaymentStateSubscriberMixin.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
<test-element id="el1"></test-element>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script type="application/javascript">
|
||||
/** Test the PaymentStateSubscriberMixin **/
|
||||
|
||||
/* global sinon */
|
||||
/* import-globals-from payments_common.js */
|
||||
/* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
|
||||
|
||||
class TestElement extends PaymentStateSubscriberMixin(HTMLElement) {
|
||||
render(state) {
|
||||
this.textContent = JSON.stringify(state);
|
||||
}
|
||||
}
|
||||
|
||||
// We must spy on the prototype by creating the instance in order to test Custom Element reactions.
|
||||
sinon.spy(TestElement.prototype, "disconnectedCallback");
|
||||
|
||||
customElements.define("test-element", TestElement);
|
||||
let el1 = document.getElementById("el1");
|
||||
|
||||
sinon.spy(el1, "render");
|
||||
sinon.spy(el1, "stateChangeCallback");
|
||||
|
||||
add_task(async function test_initialState() {
|
||||
let parsedState = JSON.parse(el1.textContent);
|
||||
ok(!!parsedState.request, "Check initial state contains `request`");
|
||||
ok(!!parsedState.savedAddresses, "Check initial state contains `savedAddresses`");
|
||||
ok(!!parsedState.savedBasicCards, "Check initial state contains `savedBasicCards`");
|
||||
});
|
||||
|
||||
add_task(async function test_async_batched_render() {
|
||||
el1.requestStore.setState({a: 1});
|
||||
el1.requestStore.setState({b: 2});
|
||||
await asyncElementRendered();
|
||||
ok(el1.stateChangeCallback.calledOnce, "stateChangeCallback called once");
|
||||
ok(el1.render.calledOnce, "render called once");
|
||||
|
||||
let parsedState = JSON.parse(el1.textContent);
|
||||
is(parsedState.a, 1, "Check a");
|
||||
is(parsedState.b, 2, "Check b");
|
||||
});
|
||||
|
||||
add_task(async function test_disconnect() {
|
||||
el1.disconnectedCallback.reset();
|
||||
el1.render.reset();
|
||||
el1.stateChangeCallback.reset();
|
||||
el1.remove();
|
||||
ok(el1.disconnectedCallback.calledOnce, "disconnectedCallback called once");
|
||||
await el1.requestStore.setState({a: 3});
|
||||
await asyncElementRendered();
|
||||
ok(el1.stateChangeCallback.notCalled, "stateChangeCallback not called");
|
||||
ok(el1.render.notCalled, "render not called");
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user