Bug 1483470 - Improve the test case for responding a closed PaymentRequest. r=baku

1. Improving the testCloseByRedirectingAfterShow. Try to call
       PaymentRequestService::respondPayment when the PaymentRequest is closed.
    2. Adding a new test testUpdateWithRespondedPayment for the case the merchant
       calls PaymentRequestUpdateEvent::updateWith() and the PaymentRequest is
       rejected by the user.

--HG--
rename : dom/payments/test/test_cleanupPayment.html => dom/payments/test/test_closePayment.html
This commit is contained in:
Eden Chuang 2018-08-24 11:28:50 +02:00
Родитель a29e2c4da2
Коммит 2f8de0fe6b
12 изменённых файлов: 270 добавлений и 113 удалений

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

@ -74,6 +74,8 @@ const detailedResponseUI = {
completePayment: completePaymentResponse,
updatePayment: function(requestId) {
},
closePayment: function (requestId) {
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};
@ -102,6 +104,8 @@ const simpleResponseUI = {
completePayment: completePaymentResponse,
updatePayment: function(requestId) {
},
closePayment: function(requestId) {
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -1,58 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
function emitTestFail(message) {
sendAsyncMessage("test-fail", message);
}
function emitTestPass(message) {
sendAsyncMessage("test-pass", message);
}
addMessageListener("cleanup-check", function() {
const paymentEnum = paymentSrv.enumerate();
if (paymentEnum.hasMoreElements()) {
emitTestFail("Non-empty PaymentRequest queue in PaymentRequestService.");
} else {
emitTestPass("Got empty PaymentRequest queue in PaymentRequestService.");
}
sendAsyncMessage("cleanup-check-complete");
});
var setPaymentNums = 0;
addMessageListener("payment-num-set", function() {
setPaymentNums = 0;
for (let payment of paymentSrv.enumerate()) {
setPaymentNums = setPaymentNums + 1;
}
sendAsyncMessage("payment-num-set-complete");
});
addMessageListener("payment-num-check", function(expectedNumPayments) {
let numPayments = 0;
for (let payment of paymentSrv.enumerate()) {
numPayments = numPayments + 1;
}
if (numPayments !== expectedNumPayments + setPaymentNums) {
emitTestFail("Expected '" + expectedNumPayments +
"' PaymentRequests in PaymentRequestService" + ", but got '" +
numPayments + "'.");
} else {
emitTestPass("Got expected '" + numPayments +
"' PaymentRequests in PaymentRequestService.");
}
// force cleanup PaymentRequests for clear environment to next testcase.
paymentSrv.cleanup();
sendAsyncMessage("payment-num-check-complete");
});
addMessageListener("teardown", function() {
paymentSrv.setTestingUIService(null);
sendAsyncMessage('teardown-complete');
});

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

@ -0,0 +1,117 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
function emitTestFail(message) {
sendAsyncMessage("test-fail", message);
}
function emitTestPass(message) {
sendAsyncMessage("test-pass", message);
}
addMessageListener("close-check", function() {
const paymentEnum = paymentSrv.enumerate();
if (paymentEnum.hasMoreElements()) {
emitTestFail("Non-empty PaymentRequest queue in PaymentRequestService.");
} else {
emitTestPass("Got empty PaymentRequest queue in PaymentRequestService.");
}
sendAsyncMessage("close-check-complete");
});
var setPaymentNums = 0;
addMessageListener("payment-num-set", function() {
setPaymentNums = 0;
const paymentEnum = paymentSrv.enumerate();
while (paymentEnum.hasMoreElements()) {
setPaymentNums = setPaymentNums + 1;
paymentEnum.getNext();
}
sendAsyncMessage("payment-num-set-complete");
});
addMessageListener("payment-num-check", function(expectedNumPayments) {
const paymentEnum = paymentSrv.enumerate();
let numPayments = 0;
while (paymentEnum.hasMoreElements()) {
numPayments = numPayments + 1;
paymentEnum.getNext();
}
if (numPayments !== expectedNumPayments + setPaymentNums) {
emitTestFail("Expected '" + expectedNumPayments +
"' PaymentRequests in PaymentRequestService" + ", but got '" +
numPayments + "'.");
} else {
emitTestPass("Got expected '" + numPayments +
"' PaymentRequests in PaymentRequestService.");
}
// force cleanup PaymentRequests for clear environment to next testcase.
paymentSrv.cleanup();
sendAsyncMessage("payment-num-check-complete");
});
var respondRequestId;
addMessageListener("reject-payment", (expectedError) => {
try {
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
responseData.initData({});
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(respondRequestId,
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
"", // payment method
responseData, // payment method data
"", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
emitTestPass("Reject PaymentRequest successfully");
} catch (error) {
if (expectedError) {
if (error.name === "NS_ERROR_FAILURE") {
emitTestPass("Got expected NS_ERROR_FAILURE when responding a closed PaymentRequest");
sendAsyncMessage("reject-payment-complete");
return;
}
}
emitTestFail("Unexpected error '" + error.name +
"' when reponding a closed PaymentRequest");
}
sendAsyncMessage("reject-payment-complete");
});
addMessageListener("update-payment", () => {
try {
paymentSrv.changeShippingOption(respondRequestId, "");
emitTestPass("Change shippingOption succefully");
} catch (error) {
emitTestFail("Unexpected error '" + error.name +
"' when changing the shipping option");
}
sendAsyncMessage("update-payment-complete");
});
const DummyUIService = {
showPayment: (requestId => {respondRequestId = requestId}),
abortPayment: (requestId) => {respondRequestId = requestId},
completePayment: (requestId) => {respondRequestId = requestId},
updatePayment: (requestId) => {respondRequestId = requestId},
closePayment: (requestId) => {respondRequestId = requestId},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};
paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
addMessageListener("teardown", function() {
paymentSrv.setTestingUIService(null);
sendAsyncMessage('teardown-complete');
});

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

@ -26,6 +26,7 @@ const InvalidDetailsUIService = {
},
completePayment(requestId) {},
updatePayment(requestId) {},
closePayment(requestId) {},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -39,6 +39,8 @@ const UIService = {
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
closePayment: function(requestId) {
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -71,6 +71,8 @@ const NormalUIService = {
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
closePayment: function(requestId) {
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -74,6 +74,8 @@ const TestingUIService = {
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
updatePayment: updateRequest,
closePayment: function(requestId) {
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -150,6 +150,7 @@ const DummyUIService = {
abortPayment: abortRequest,
completePayment: completeRequest,
updatePayment: updateRequest,
closePayment: function(requestId) {},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -146,6 +146,7 @@ const DummyUIService = {
abortPayment: abortRequest,
completePayment: completeRequest,
updatePayment: updateRequest,
closePayment: function(requestId) {},
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
};

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

@ -7,7 +7,7 @@ support-files =
simple_payment_request.html
echo_payment_request.html
BasiccardChromeScript.js
CleanupChromeScript.js
ClosePaymentChromeScript.js
ConstructorChromeScript.js
CurrencyAmountValidationChromeScript.js
DefaultData.js
@ -25,7 +25,7 @@ run-if = nightly_build # Bug 1390018: Depends on the Nightly-only UI service
skip-if = e10s # Bug 1408250: Don't expose PaymentRequest Constructor in non-e10s
[test_canMakePayment.html]
run-if = nightly_build # Bug 1390737: Depends on the Nightly-only UI service
[test_cleanupPayment.html]
[test_closePayment.html]
[test_constructor.html]
[test_currency_amount_validation.html]
skip-if = (verify && debug)

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

@ -14,25 +14,64 @@ const details = {
amount: { currency: "USD", value: "55.00" },
},
};
const updatedDetails = {
id: "simple details",
total: {
label: "Donation",
amount: { currency: "USD", value: "55.00" },
},
error: "",
};
let request;
let shippingChangedEvent;
let msg = "successful";
try {
request = new PaymentRequest(methods, details);
request.onshippingoptionchange = (event) => {
shippingChangedEvent = event;
window.parent.postMessage("successful", "*");
};
request.onshippingaddresschange = (event) => {
shippingChangedEvent = event;
window.parent.postMessage("successful", "*");
};
} catch (err) {
msg = err.name;
}
window.parent.postMessage(msg, "*");
if (request) {
window.onmessage = async ({ data: action }) => {
msg = "successful";
switch (action) {
case "show PaymentRequest":
const responsePromise = request.show();
window.parent.postMessage("successful", "*");
window.parent.postMessage(msg, "*");
try {
await responsePromise;
} catch (err) { /* graceful abort */ }
} catch (err) {
if (err.name !== "AbortError") {
msg = err.name;
}
}
window.parent.postMessage(msg, "*")
break;
case "updateWith PaymentRequest":
if (shippingChangedEvent) {
try {
shippingChangedEvent.updateWith(updatedDetails);
} catch(err) {
if (err.name !== "InvalidStateError") {
msg = err.name;
}
}
window.parent.postMessage(msg, "*");
shippingChangedEvent = undefined;
}
break;
default:
window.parent.postMessage(`fail - unknown postmessage action: ${action}`, "*");

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

@ -5,7 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1408234</title>
<title>Test for closing PaymentRequest</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript">
@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
"use strict";
SimpleTest.waitForExplicitFinish();
var gUrl = SimpleTest.getTestFileURL('CleanupChromeScript.js');
var gUrl = SimpleTest.getTestFileURL('ClosePaymentChromeScript.js');
var gScript = SpecialPowers.loadChromeScript(gUrl);
var testName = "";
@ -25,40 +25,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
}
gScript.addMessageListener("test-fail", testFailHandler);
gScript.addMessageListener("test-pass", testPassHandler);
function cleanupCheck(resolveFunc) {
gScript.addMessageListener("cleanup-check-complete", function checkCompleteHandler() {
gScript.removeMessageListener("cleanup-check-complete", checkCompleteHandler);
resolveFunc();
async function requestChromeAction(action, params) {
gScript.sendAsyncMessage(action, params);
await new Promise(resolve => {
gScript.addMessageListener(`${action}-complete`, function completeListener() {
gScript.removeMessageListener(`${action}-complete`, completeListener);
resolve();
});
});
gScript.sendAsyncMessage("cleanup-check");
}
function paymentNumCheck(resolveFunc, numPayments) {
gScript.addMessageListener("payment-num-check-complete", function checkCompleteHandler() {
gScript.removeMessageListener("payment-num-check-complete", checkCompleteHandler);
resolveFunc();
});
gScript.sendAsyncMessage("payment-num-check", numPayments);
}
function paymentNumSet() {
gScript.addMessageListener("payment-num-set-complete", function setCompleteHandler() {
gScript.removeMessageListener("payment-num-set-complete", setCompleteHandler);
});
gScript.sendAsyncMessage("payment-num-set");
}
function testCleanupByReloading() {
paymentNumSet();
return new Promise((resolve, reject) => {
testName = "testCleanupByReloading";
function testCloseByReloading() {
return new Promise(async (resolve, reject) => {
testName = "testCloseByReloading";
let expectedResults = ["successful", "successful"];
let nextStatus = ["creating", "reloading"];
let currStatus = nextStatus.shift();
let ifr = document.createElement('iframe');
let listener = function(event) {
await requestChromeAction("payment-num-set");
let listener = async function(event) {
let expected = expectedResults.shift();
is(event.data, expected,
testName + ": Expected '" + expected + "' when " + currStatus +
@ -67,8 +53,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
ifr.contentWindow.location.reload();
} else if (currStatus === "reloading") {
window.removeEventListener("message", listener);
paymentNumCheck(resolve, 1);
await requestChromeAction("payment-num-check", 1);
document.body.removeChild(ifr);
resolve();
}
currStatus = nextStatus.shift();
}
@ -78,14 +65,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
});
}
function testCleanupByRedirecting() {
function testCloseByRedirecting() {
return new Promise((resolve, reject) => {
testName = "testCleanupByRedirecting";
testName = "testCloseByRedirecting";
let expectedResults = ["successful", "successful"];
let nextStatus = ["creating", "redirecting"];
let currStatus = nextStatus.shift();
let ifr = document.createElement('iframe');
let listener = function(event) {
let listener = async function(event) {
let expected = expectedResults.shift();
is(event.data, expected,
testName + ": Expected '" + expected + "' when " + currStatus +
@ -94,8 +81,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
ifr.src = "blank_page.html";
} else if (currStatus === "redirecting"){
window.removeEventListener("message", listener);
cleanupCheck(resolve);
await requestChromeAction("close-check");
document.body.removeChild(ifr);
resolve();
}
currStatus = nextStatus.shift();
};
@ -105,27 +93,31 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
});
}
function testCleanupByRedirectingAfterShow() {
function testCloseByRedirectingAfterShow() {
return new Promise((resolve, reject) => {
testName = "testCleanupByRedirectingAfterShow";
testName = "testCloseByRedirectingAfterShow";
let nextStatus = ["creating", "showing", "redirecting"];
let currStatus = nextStatus.shift();
let expectedResults = ["successful", "successful", "successful"];
let ifr = document.createElement('iframe');
let listener = (event) => {
let handler = undefined;
let listener = async (event) => {
let expected = expectedResults.shift();
is(event.data, expected,
testName + ": Expected '" + expected + "' when " + currStatus +
", but got '" + event.data + "'");
if (currStatus === "creating") {
handler = SpecialPowers.getDOMWindowUtils(ifr.contentWindow).setHandlingUserInput(true);
ifr.contentWindow.postMessage("show PaymentRequest", "*");
} else if (currStatus === "showing") {
handler.destruct();
ifr.src = "blank_page.html";
} else if (currStatus === "redirecting") {
window.removeEventListener("message", listener);
cleanupCheck(resolve);
await requestChromeAction("close-check");
await requestChromeAction("reject-payment", true);
document.body.removeChild(ifr);
resolve();
}
currStatus = nextStatus.shift();
}
@ -135,21 +127,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
});
}
function testCleanupByRemovingIframe() {
function testCloseByRemovingIframe() {
return new Promise((resolve, reject) => {
testName = "testCleanupByRemovingIframe";
testName = "testCloseByRemovingIframe";
let expectedResults = ["successful"];
let nextStatus = ["creating"];
let currStatus = nextStatus.shift();
let ifr = document.createElement('iframe');
let listener = function(event) {
let listener = async function(event) {
let expected = expectedResults.shift();
is(event.data, expected,
testName + ": Expected '" + expected + "' when " + currStatus +
", but got '" + event.data + "'");
document.body.removeChild(ifr);
window.removeEventListener("message", listener);
cleanupCheck(resolve);
await requestChromeAction("close-check");
resolve();
};
window.addEventListener("message", listener);
ifr.src = "simple_payment_request.html";
@ -157,18 +150,70 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
});
}
function testUpdateWithRespondedPayment() {
return new Promise(resolve => {
testName = "testUpdateWithRespondedPayment";
let nextStatus = ["creating", "showing", "closing", "updating", "finishing"];
let currStatus = nextStatus.shift();
let ifr = document.createElement('iframe');
let handler = undefined;
let listener = async function(event) {
is(event.data, "successful",
testName + ": Expected 'successful' when " + currStatus +
", but got '" + event.data + "'");
switch (currStatus) {
case "creating":
handler = SpecialPowers.getDOMWindowUtils(ifr.contentWindow).setHandlingUserInput(true);
ifr.contentWindow.postMessage("show PaymentRequest", "*");
break;
case "showing":
await requestChromeAction("update-payment");
break;
case "closing":
await requestChromeAction("reject-payment", false);
break;
case "updating":
await requestChromeAction("close-check");
ifr.contentWindow.postMessage("updateWith PaymentRequest", "*");
break;
case "finishing":
handler.destruct();
document.body.removeChild(ifr);
window.removeEventListener("message", listener);
resolve();
break;
default:
ok(false, testName + ": Unknown status()" + currStatus);
break;
}
currStatus = nextStatus.shift();
}
window.addEventListener("message", listener);
ifr.src = "simple_payment_request.html";
document.body.appendChild(ifr);
});
}
function teardown() {
gScript.removeMessageListener("test-fail", testFailHandler);
gScript.removeMessageListener("test-pass", testPassHandler);
gScript.destroy();
SimpleTest.finish();
return new Promise((resolve, reject) => {
gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
gScript.removeMessageListener("test-fail", testFailHandler);
gScript.removeMessageListener("test-pass", testPassHandler);
gScript.destroy();
SimpleTest.finish();
resolve();
});
gScript.sendAsyncMessage("teardown");
});
}
function runTests() {
testCleanupByReloading()
.then(testCleanupByRedirecting)
.then(testCleanupByRedirectingAfterShow)
.then(testCleanupByRemovingIframe)
testCloseByReloading()
.then(testCloseByRedirecting)
.then(testCloseByRedirectingAfterShow)
.then(testCloseByRemovingIframe)
.then(testUpdateWithRespondedPayment)
.then(teardown)
.catch( e => {
ok(false, "Unexpected error: " + e.name);
@ -187,5 +232,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1408234">Mozilla Bug 1408234</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1483470">Mozilla Bug 1483470</a>
</body>
</html>