Index: third_party/WebKit/Source/modules/payments/PaymentRequest.cpp |
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp |
index 6ef24d6953625f6400b42886923c0f6bcd7854e9..b714ad694eba2cfa9da60da2279478a1c7819b21 100644 |
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp |
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp |
@@ -79,11 +79,18 @@ struct TypeConverter<PaymentDetailsPtr, blink::PaymentDetails> { |
static PaymentDetailsPtr Convert(const blink::PaymentDetails& input) |
{ |
PaymentDetailsPtr output = PaymentDetails::New(); |
- output->display_items = mojo::WTFArray<PaymentItemPtr>::From(input.displayItems()); |
+ output->total = PaymentItem::From(input.total()); |
+ |
+ if (input.hasDisplayItems()) |
+ output->display_items = mojo::WTFArray<PaymentItemPtr>::From(input.displayItems()); |
+ else |
+ output->display_items = mojo::WTFArray<PaymentItemPtr>::New(0); |
+ |
if (input.hasShippingOptions()) |
output->shipping_options = mojo::WTFArray<ShippingOptionPtr>::From(input.shippingOptions()); |
else |
output->shipping_options = mojo::WTFArray<ShippingOptionPtr>::New(0); |
+ |
return output; |
} |
}; |
@@ -103,74 +110,90 @@ struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> { |
namespace blink { |
namespace { |
-// Validates ShippingOption and PaymentItem dictionaries, which happen to have identical fields, |
+// Validates ShippingOption or PaymentItem, which happen to have identical fields, |
// except for "id", which is present only in ShippingOption. |
template <typename T> |
-void validateShippingOptionsOrPaymentItems(HeapVector<T> items, ExceptionState& exceptionState) |
+void validateShippingOptionOrPaymentItem(const T& item, ExceptionState& exceptionState) |
{ |
- String errorMessage; |
- for (const auto& item : items) { |
- if (!item.hasLabel() || item.label().isEmpty()) { |
- exceptionState.throwTypeError("Item label required"); |
- return; |
- } |
+ if (!item.hasLabel() || item.label().isEmpty()) { |
+ exceptionState.throwTypeError("Item label required"); |
+ return; |
+ } |
- if (!item.hasAmount()) { |
- exceptionState.throwTypeError("Currency amount required"); |
- return; |
- } |
+ if (!item.hasAmount()) { |
+ exceptionState.throwTypeError("Currency amount required"); |
+ return; |
+ } |
- if (!item.amount().hasCurrency()) { |
- exceptionState.throwTypeError("Currency code required"); |
- return; |
- } |
+ if (!item.amount().hasCurrency()) { |
+ exceptionState.throwTypeError("Currency code required"); |
+ return; |
+ } |
- if (!item.amount().hasValue()) { |
- exceptionState.throwTypeError("Currency value required"); |
- return; |
- } |
+ if (!item.amount().hasValue()) { |
+ exceptionState.throwTypeError("Currency value required"); |
+ return; |
+ } |
- if (!PaymentsValidators::isValidCurrencyCodeFormat(item.amount().currency(), &errorMessage)) { |
- exceptionState.throwTypeError(errorMessage); |
- return; |
- } |
+ String errorMessage; |
+ if (!PaymentsValidators::isValidCurrencyCodeFormat(item.amount().currency(), &errorMessage)) { |
+ exceptionState.throwTypeError(errorMessage); |
+ return; |
+ } |
- if (!PaymentsValidators::isValidAmountFormat(item.amount().value(), &errorMessage)) { |
- exceptionState.throwTypeError(errorMessage); |
+ if (!PaymentsValidators::isValidAmountFormat(item.amount().value(), &errorMessage)) { |
+ exceptionState.throwTypeError(errorMessage); |
+ return; |
+ } |
+} |
+ |
+void validateDisplayItems(const HeapVector<PaymentItem>& items, ExceptionState& exceptionState) |
+{ |
+ for (const auto& item : items) { |
+ validateShippingOptionOrPaymentItem(item, exceptionState); |
+ if (exceptionState.hadException()) |
return; |
- } |
} |
} |
-void validateShippingOptionsIds(HeapVector<ShippingOption> options, ExceptionState& exceptionState) |
+void validateShippingOptions(const HeapVector<ShippingOption>& options, ExceptionState& exceptionState) |
{ |
for (const auto& option : options) { |
if (!option.hasId() || option.id().isEmpty()) { |
exceptionState.throwTypeError("ShippingOption id required"); |
return; |
} |
+ |
+ validateShippingOptionOrPaymentItem(option, exceptionState); |
+ if (exceptionState.hadException()) |
+ return; |
} |
} |
void validatePaymentDetails(const PaymentDetails& details, ExceptionState& exceptionState) |
{ |
- if (!details.hasDisplayItems()) { |
- exceptionState.throwTypeError("Must specify display items"); |
+ if (!details.hasTotal()) { |
+ exceptionState.throwTypeError("Must specify total"); |
return; |
} |
- if (details.displayItems().isEmpty()) { |
- exceptionState.throwTypeError("Must specify at least one item"); |
+ validateShippingOptionOrPaymentItem(details.total(), exceptionState); |
+ if (exceptionState.hadException()) |
return; |
- } |
- validateShippingOptionsOrPaymentItems(details.displayItems(), exceptionState); |
- if (exceptionState.hadException()) |
+ if (details.total().amount().value()[0] == '-') { |
+ exceptionState.throwTypeError("Total amount value should be non-negative"); |
return; |
+ } |
+ |
+ if (details.hasDisplayItems()) { |
+ validateDisplayItems(details.displayItems(), exceptionState); |
+ if (exceptionState.hadException()) |
+ return; |
+ } |
if (details.hasShippingOptions()) { |
- validateShippingOptionsOrPaymentItems(details.shippingOptions(), exceptionState); |
- validateShippingOptionsIds(details.shippingOptions(), exceptionState); |
+ validateShippingOptions(details.shippingOptions(), exceptionState); |
} |
} |