Commit 4ad48945 authored by Rouslan Solomakhin's avatar Rouslan Solomakhin Committed by Commit Bot

[Payments] Handle absence of total in modifier.

Before this patch, a modifier without a total field would crash on
desktop.

This patch adds a check for presence of the total field in the modifier
before dereferencing it. If the modifier total is absent, then the
global total is used.

After this patch, a modifier without a total field results in the global
total being used without a crash.

Bug: 814968
Change-Id: I1f946ed4526b948b2836e2144e3bdb2e7c167321
Reviewed-on: https://chromium-review.googlesource.com/935426Reviewed-by: default avataranthonyvd <anthonyvd@chromium.org>
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#539176}
parent d32a80e4
...@@ -288,4 +288,40 @@ IN_PROC_BROWSER_TEST_F(PaymentRequestModifiersTest, ...@@ -288,4 +288,40 @@ IN_PROC_BROWSER_TEST_F(PaymentRequestModifiersTest,
->child_count()); ->child_count());
} }
IN_PROC_BROWSER_TEST_F(PaymentRequestModifiersTest,
NoTotalInModifierDoesNotCrash) {
NavigateTo("/payment_request_bobpay_and_basic_card_with_modifiers_test.html");
autofill::AutofillProfile profile(autofill::test::GetFullProfile());
AddAutofillProfile(profile);
autofill::CreditCard card(autofill::test::GetCreditCard()); // Visa card.
// Change to Mastercard to match the test case.
card.SetRawInfo(autofill::CREDIT_CARD_NUMBER,
base::ASCIIToUTF16("5555555555554444"));
card.set_billing_address_id(profile.guid());
AddCreditCard(card);
ResetEventWaiter(DialogEvent::DIALOG_OPENED);
content::WebContents* web_contents = GetActiveWebContents();
const std::string click_buy_button_js =
"(function() { document.getElementById('no_total').click(); })();";
ASSERT_TRUE(content::ExecuteScript(web_contents, click_buy_button_js));
WaitForObservedEvent();
// The web-modal dialog should be open.
web_modal::WebContentsModalDialogManager* web_contents_modal_dialog_manager =
web_modal::WebContentsModalDialogManager::FromWebContents(web_contents);
EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());
OpenOrderSummaryScreen();
// The price is the global total, because the modifier does not have total.
EXPECT_EQ(base::ASCIIToUTF16("$5.00"),
GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
// Only global total is available.
EXPECT_EQ(1, dialog_view()
->view_stack_for_testing()
->top()
->GetViewByID(static_cast<int>(DialogViewID::CONTENT_VIEW))
->child_count());
}
} // namespace payments } // namespace payments
...@@ -189,7 +189,7 @@ const mojom::PaymentItemPtr& PaymentRequestSpec::GetTotal( ...@@ -189,7 +189,7 @@ const mojom::PaymentItemPtr& PaymentRequestSpec::GetTotal(
PaymentInstrument* selected_instrument) const { PaymentInstrument* selected_instrument) const {
const mojom::PaymentDetailsModifierPtr* modifier = const mojom::PaymentDetailsModifierPtr* modifier =
GetApplicableModifier(selected_instrument); GetApplicableModifier(selected_instrument);
return modifier ? (*modifier)->total : details_->total; return modifier && (*modifier)->total ? (*modifier)->total : details_->total;
} }
std::vector<const mojom::PaymentItemPtr*> PaymentRequestSpec::GetDisplayItems( std::vector<const mojom::PaymentItemPtr*> PaymentRequestSpec::GetDisplayItems(
......
...@@ -53,8 +53,7 @@ function buy() { // eslint-disable-line no-unused-vars ...@@ -53,8 +53,7 @@ function buy() { // eslint-disable-line no-unused-vars
function buyWithBobPayDiscount() { // eslint-disable-line no-unused-vars function buyWithBobPayDiscount() { // eslint-disable-line no-unused-vars
try { try {
new PaymentRequest( new PaymentRequest(
[{supportedMethods: ['https://bobpay.com', 'basic-card']}], [{supportedMethods: ['https://bobpay.com', 'basic-card']}], {
{
total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}, total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}},
modifiers: [{ modifiers: [{
supportedMethods: ['https://bobpay.com'], supportedMethods: ['https://bobpay.com'],
...@@ -72,13 +71,13 @@ function buyWithBobPayDiscount() { // eslint-disable-line no-unused-vars ...@@ -72,13 +71,13 @@ function buyWithBobPayDiscount() { // eslint-disable-line no-unused-vars
.show() .show()
.then(function(resp) { .then(function(resp) {
resp.complete('success') resp.complete('success')
.then(function() { .then(function() {
print(JSON.stringify(resp, undefined, 2)); print(JSON.stringify(resp, undefined, 2));
}) })
.catch(function(error) { .catch(function(error) {
print(error.message); print(error.message);
}); });
}) })
.catch(function(error) { .catch(function(error) {
print(error.message); print(error.message);
}); });
...@@ -137,40 +136,40 @@ function creditSupportedType() { // eslint-disable-line no-unused-vars ...@@ -137,40 +136,40 @@ function creditSupportedType() { // eslint-disable-line no-unused-vars
function debitSupportedType() { // eslint-disable-line no-unused-vars function debitSupportedType() { // eslint-disable-line no-unused-vars
try { try {
new PaymentRequest( new PaymentRequest(
[{supportedMethods: ['https://bobpay.com', 'basic-card']}], { [{supportedMethods: ['https://bobpay.com', 'basic-card']}], {
total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}, total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}},
modifiers: [{ modifiers: [{
supportedMethods: ['basic-card'], supportedMethods: ['basic-card'],
total: { total: {
label: 'Total', label: 'Total',
amount: {currency: 'USD', value: '4.00'}, amount: {currency: 'USD', value: '4.00'},
}, },
additionalDisplayItems: [{ additionalDisplayItems: [{
label: 'basic-card discount', label: 'basic-card discount',
amount: {currency: 'USD', value: '-1.00'}, amount: {currency: 'USD', value: '-1.00'},
}],
data: {
discountProgramParticipantId: '86328764873265',
supportedTypes: ['debit'],
},
}], }],
data: { })
discountProgramParticipantId: '86328764873265', .show()
supportedTypes: ['debit'], .then(function(resp) {
}, resp.complete('success')
}], .then(function() {
}) print(JSON.stringify(resp, undefined, 2));
.show() })
.then(function(resp) { .catch(function(error) {
resp.complete('success') print(error.message);
.then(function() { });
print(JSON.stringify(resp, undefined, 2));
}) })
.catch(function(error) { .catch(function(error) {
print(error.message); print(error.message);
}); });
}) } catch (error) {
.catch(function(error) { print(error.message);
print(error.message); }
});
} catch (error) {
print(error.message);
}
} }
/** /**
...@@ -266,7 +265,7 @@ function mastercardSupportedNetwork() { // eslint-disable-line no-unused-vars ...@@ -266,7 +265,7 @@ function mastercardSupportedNetwork() { // eslint-disable-line no-unused-vars
* Launches the PaymentRequest UI with Bob Pay and basic-card as payment * Launches the PaymentRequest UI with Bob Pay and basic-card as payment
* methods and a modifier for basic-card with "mastercard" network. * methods and a modifier for basic-card with "mastercard" network.
*/ */
function mastercardAnySupportedType() { // eslint-disable-line no-unused-vars function mastercardAnySupportedType() { // eslint-disable-line no-unused-vars
try { try {
new PaymentRequest( new PaymentRequest(
[{supportedMethods: ['https://bobpay.com', 'basic-card']}], { [{supportedMethods: ['https://bobpay.com', 'basic-card']}], {
...@@ -304,3 +303,40 @@ function mastercardAnySupportedType() { // eslint-disable-line no-unused-vars ...@@ -304,3 +303,40 @@ function mastercardAnySupportedType() { // eslint-disable-line no-unused-vars
print(error.message); print(error.message);
} }
} }
/**
* Launches the PaymentRequest UI with basic-card as payment method and a
* modifier for basic-card with "mastercard" network, but the modifier does not
* have a total specified.
*/
function noTotal() { // eslint-disable-line no-unused-vars
try {
new PaymentRequest([{supportedMethods: 'basic-card'}], {
total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}},
modifiers: [
{
supportedMethods: ['basic-card'],
data: {
mastercardProgramParticipantId: '86328764873265',
supportedNetworks: ['mastercard'],
},
},
],
})
.show()
.then(function(resp) {
resp.complete('success')
.then(function() {
print(JSON.stringify(resp, undefined, 2));
})
.catch(function(error) {
print(error.message);
});
})
.catch(function(error) {
print(error.message);
});
} catch (error) {
print(error.message);
}
}
...@@ -19,6 +19,7 @@ found in the LICENSE file. ...@@ -19,6 +19,7 @@ found in the LICENSE file.
<button onclick="visaSupportedNetwork()" id="visa_supported_network">Bob Pay and Basic-Card with Basic-Card modifiers Test with visa supported network and credit supported type</button> <button onclick="visaSupportedNetwork()" id="visa_supported_network">Bob Pay and Basic-Card with Basic-Card modifiers Test with visa supported network and credit supported type</button>
<button onclick="mastercardSupportedNetwork()" id="mastercard_supported_network">Bob Pay and Basic-Card with Basic-Card modifiers Test with mastercard supported network and credit supported type</button> <button onclick="mastercardSupportedNetwork()" id="mastercard_supported_network">Bob Pay and Basic-Card with Basic-Card modifiers Test with mastercard supported network and credit supported type</button>
<button onclick="mastercardAnySupportedType()" id="mastercard_any_supported_type">Bob Pay and Basic-Card with Basic-Card modifiers Test with mastercard supported network and any supported type</button> <button onclick="mastercardAnySupportedType()" id="mastercard_any_supported_type">Bob Pay and Basic-Card with Basic-Card modifiers Test with mastercard supported network and any supported type</button>
<button onclick="noTotal()" id="no_total">No Total</button>
<pre id="result"></pre> <pre id="result"></pre>
<script src="util.js"></script> <script src="util.js"></script>
<script src="bobpay_and_basic_card_with_modifiers.js"></script> <script src="bobpay_and_basic_card_with_modifiers.js"></script>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment