Commit be15a422 authored by Jinho Bang's avatar Jinho Bang Committed by Commit Bot

PaymentRequest: Add a use counter for updateWith() w/o shippingOptions

This patch adds a use counter to number of calling updateWith() without
shippingOptions dictionary member on ShippingAddressChange and
ShippingOptionChange events.

Bug: 902291
Change-Id: Iac779040dc1a7245dcfe4db795e09d4ecbca9b90
Reviewed-on: https://chromium-review.googlesource.com/c/1319653
Commit-Queue: Jinho Bang <jinho.bang@samsung.com>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarBryan McQuade <bmcquade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606376}
parent 4926f678
...@@ -62,6 +62,8 @@ bool IsAllowedUkmFeature(blink::mojom::WebFeature feature) { ...@@ -62,6 +62,8 @@ bool IsAllowedUkmFeature(blink::mojom::WebFeature feature) {
WebFeature::kCursorImageGT32x32, WebFeature::kCursorImageLE32x32, WebFeature::kCursorImageGT32x32, WebFeature::kCursorImageLE32x32,
WebFeature::kHistoryPushState, WebFeature::kHistoryReplaceState, WebFeature::kHistoryPushState, WebFeature::kHistoryReplaceState,
WebFeature::kCursorImageGT64x64, WebFeature::kAdClick, WebFeature::kCursorImageGT64x64, WebFeature::kAdClick,
WebFeature::kUpdateWithoutShippingOptionOnShippingAddressChange,
WebFeature::kUpdateWithoutShippingOptionOnShippingOptionChange,
})); }));
return opt_in_features->count(feature); return opt_in_features->count(feature);
} }
...@@ -2071,6 +2071,8 @@ enum WebFeature { ...@@ -2071,6 +2071,8 @@ enum WebFeature {
kGetDisplayMedia = 2619, kGetDisplayMedia = 2619,
kCursorImageGT64x64 = 2620, kCursorImageGT64x64 = 2620,
kAdClick = 2621, kAdClick = 2621,
kUpdateWithoutShippingOptionOnShippingAddressChange = 2622,
kUpdateWithoutShippingOptionOnShippingOptionChange = 2623,
// Add new features immediately above this line. Don't change assigned // Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots. // numbers of any item, and don't reuse removed slots.
// Also, run update_use_counter_feature_enum.py in // Also, run update_use_counter_feature_enum.py in
......
...@@ -980,6 +980,7 @@ ScriptPromise PaymentRequest::Complete(ScriptState* script_state, ...@@ -980,6 +980,7 @@ ScriptPromise PaymentRequest::Complete(ScriptState* script_state,
} }
void PaymentRequest::OnUpdatePaymentDetails( void PaymentRequest::OnUpdatePaymentDetails(
const AtomicString& event_type,
const ScriptValue& details_script_value) { const ScriptValue& details_script_value) {
if (!GetPendingAcceptPromiseResolver() || !payment_provider_) if (!GetPendingAcceptPromiseResolver() || !payment_provider_)
return; return;
...@@ -1016,6 +1017,20 @@ void PaymentRequest::OnUpdatePaymentDetails( ...@@ -1016,6 +1017,20 @@ void PaymentRequest::OnUpdatePaymentDetails(
return; return;
} }
// TODO(https://crbug.com/902291): We should make shippingOptions optional.
if (options_->requestShipping() && !details->hasShippingOptions()) {
if (event_type == event_type_names::kShippingaddresschange) {
UseCounter::Count(
GetExecutionContext(),
WebFeature::kUpdateWithoutShippingOptionOnShippingAddressChange);
}
if (event_type == event_type_names::kShippingoptionchange) {
UseCounter::Count(
GetExecutionContext(),
WebFeature::kUpdateWithoutShippingOptionOnShippingOptionChange);
}
}
if (!options_->requestShipping()) if (!options_->requestShipping())
validated_details->shipping_options.clear(); validated_details->shipping_options.clear();
......
...@@ -88,7 +88,8 @@ class MODULES_EXPORT PaymentRequest final ...@@ -88,7 +88,8 @@ class MODULES_EXPORT PaymentRequest final
ScriptPromise Retry(ScriptState*, const PaymentValidationErrors*) override; ScriptPromise Retry(ScriptState*, const PaymentValidationErrors*) override;
// PaymentUpdater: // PaymentUpdater:
void OnUpdatePaymentDetails(const ScriptValue& details_script_value) override; void OnUpdatePaymentDetails(const AtomicString& event_type,
const ScriptValue& details_script_value) override;
void OnUpdatePaymentDetailsFailure(const String& error) override; void OnUpdatePaymentDetailsFailure(const String& error) override;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h" #include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h"
...@@ -389,6 +390,7 @@ TEST(PaymentRequestTest, IgnoreUpdatePaymentDetailsAfterShowPromiseResolved) { ...@@ -389,6 +390,7 @@ TEST(PaymentRequestTest, IgnoreUpdatePaymentDetailsAfterShowPromiseResolved) {
->OnPaymentResponse(BuildPaymentResponseForTest()); ->OnPaymentResponse(BuildPaymentResponseForTest());
request->OnUpdatePaymentDetails( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(), "foo")); ScriptValue::From(scope.GetScriptState(), "foo"));
} }
...@@ -405,6 +407,7 @@ TEST(PaymentRequestTest, RejectShowPromiseOnNonPaymentDetailsUpdate) { ...@@ -405,6 +407,7 @@ TEST(PaymentRequestTest, RejectShowPromiseOnNonPaymentDetailsUpdate) {
.Then(funcs.ExpectNoCall(), funcs.ExpectCall()); .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
request->OnUpdatePaymentDetails( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(), "NotPaymentDetails")); ScriptValue::From(scope.GetScriptState(), "NotPaymentDetails"));
} }
...@@ -420,11 +423,13 @@ TEST(PaymentRequestTest, RejectShowPromiseOnInvalidPaymentDetailsUpdate) { ...@@ -420,11 +423,13 @@ TEST(PaymentRequestTest, RejectShowPromiseOnInvalidPaymentDetailsUpdate) {
request->show(scope.GetScriptState()) request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall()); .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
request->OnUpdatePaymentDetails(ScriptValue::From( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(
scope.GetScriptState(), scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), "{\"total\": {}}", scope.GetScriptState()->GetContext(),
scope.GetExceptionState()))); "{\"total\": {}}", scope.GetExceptionState())));
EXPECT_FALSE(scope.GetExceptionState().HadException()); EXPECT_FALSE(scope.GetExceptionState().HadException());
} }
...@@ -450,11 +455,13 @@ TEST(PaymentRequestTest, ...@@ -450,11 +455,13 @@ TEST(PaymentRequestTest,
"\"shippingOptions\": [{\"id\": \"standardShippingOption\", \"label\": " "\"shippingOptions\": [{\"id\": \"standardShippingOption\", \"label\": "
"\"Standard shipping\", \"amount\": {\"currency\": \"USD\", \"value\": " "\"Standard shipping\", \"amount\": {\"currency\": \"USD\", \"value\": "
"\"5.00\"}, \"selected\": true}]}"; "\"5.00\"}, \"selected\": true}]}";
request->OnUpdatePaymentDetails(ScriptValue::From( request->OnUpdatePaymentDetails(
scope.GetScriptState(), event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), scope.GetScriptState()->GetContext(),
detail_with_shipping_options, scope.GetExceptionState()))); detail_with_shipping_options,
scope.GetExceptionState())));
EXPECT_FALSE(scope.GetExceptionState().HadException()); EXPECT_FALSE(scope.GetExceptionState().HadException());
EXPECT_EQ("standardShippingOption", request->shippingOption()); EXPECT_EQ("standardShippingOption", request->shippingOption());
String detail_without_shipping_options = String detail_without_shipping_options =
...@@ -462,6 +469,7 @@ TEST(PaymentRequestTest, ...@@ -462,6 +469,7 @@ TEST(PaymentRequestTest,
"\"value\": \"5.00\"}}}"; "\"value\": \"5.00\"}}}";
request->OnUpdatePaymentDetails( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(), ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), scope.GetScriptState()->GetContext(),
...@@ -495,6 +503,7 @@ TEST( ...@@ -495,6 +503,7 @@ TEST(
"\"USD\", \"value\": \"50.00\"}}]}"; "\"USD\", \"value\": \"50.00\"}}]}";
request->OnUpdatePaymentDetails( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(), ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), scope.GetScriptState()->GetContext(),
...@@ -525,6 +534,7 @@ TEST(PaymentRequestTest, UseTheSelectedShippingOptionFromPaymentDetailsUpdate) { ...@@ -525,6 +534,7 @@ TEST(PaymentRequestTest, UseTheSelectedShippingOptionFromPaymentDetailsUpdate) {
"\"USD\", \"value\": \"50.00\"}, \"selected\": true}]}"; "\"USD\", \"value\": \"50.00\"}, \"selected\": true}]}";
request->OnUpdatePaymentDetails( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(scope.GetScriptState(), ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), scope.GetScriptState()->GetContext(),
...@@ -550,7 +560,9 @@ TEST(PaymentRequestTest, NoExceptionWithErrorMessageInUpdate) { ...@@ -550,7 +560,9 @@ TEST(PaymentRequestTest, NoExceptionWithErrorMessageInUpdate) {
"\"value\": \"5.00\"}}," "\"value\": \"5.00\"}},"
"\"error\": \"This is an error message.\"}"; "\"error\": \"This is an error message.\"}";
request->OnUpdatePaymentDetails(ScriptValue::From( request->OnUpdatePaymentDetails(
event_type_names::kShippingaddresschange,
ScriptValue::From(
scope.GetScriptState(), scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(), FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), scope.GetScriptState()->GetContext(),
......
...@@ -23,31 +23,32 @@ constexpr TimeDelta kAbortTimeout = TimeDelta::FromSeconds(60); ...@@ -23,31 +23,32 @@ constexpr TimeDelta kAbortTimeout = TimeDelta::FromSeconds(60);
class UpdatePaymentDetailsFunction : public ScriptFunction { class UpdatePaymentDetailsFunction : public ScriptFunction {
public: public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, static v8::Local<v8::Function> CreateFunction(
PaymentUpdater* updater) { ScriptState* script_state,
PaymentRequestUpdateEvent* update_event) {
UpdatePaymentDetailsFunction* self = UpdatePaymentDetailsFunction* self =
new UpdatePaymentDetailsFunction(script_state, updater); new UpdatePaymentDetailsFunction(script_state, update_event);
return self->BindToV8Function(); return self->BindToV8Function();
} }
void Trace(blink::Visitor* visitor) override { void Trace(blink::Visitor* visitor) override {
visitor->Trace(updater_); visitor->Trace(update_event_);
ScriptFunction::Trace(visitor); ScriptFunction::Trace(visitor);
} }
private: private:
UpdatePaymentDetailsFunction(ScriptState* script_state, UpdatePaymentDetailsFunction(ScriptState* script_state,
PaymentUpdater* updater) PaymentRequestUpdateEvent* update_event)
: ScriptFunction(script_state), updater_(updater) { : ScriptFunction(script_state), update_event_(update_event) {
DCHECK(updater_); DCHECK(update_event_);
} }
ScriptValue Call(ScriptValue value) override { ScriptValue Call(ScriptValue value) override {
updater_->OnUpdatePaymentDetails(value); update_event_->OnUpdatePaymentDetails(update_event_->type(), value);
return ScriptValue(); return ScriptValue();
} }
Member<PaymentUpdater> updater_; Member<PaymentRequestUpdateEvent> update_event_;
}; };
class UpdatePaymentDetailsErrorFunction : public ScriptFunction { class UpdatePaymentDetailsErrorFunction : public ScriptFunction {
...@@ -130,11 +131,12 @@ void PaymentRequestUpdateEvent::updateWith(ScriptState* script_state, ...@@ -130,11 +131,12 @@ void PaymentRequestUpdateEvent::updateWith(ScriptState* script_state,
} }
void PaymentRequestUpdateEvent::OnUpdatePaymentDetails( void PaymentRequestUpdateEvent::OnUpdatePaymentDetails(
const AtomicString& event_type,
const ScriptValue& details_script_value) { const ScriptValue& details_script_value) {
if (!updater_) if (!updater_)
return; return;
abort_timer_.Stop(); abort_timer_.Stop();
updater_->OnUpdatePaymentDetails(details_script_value); updater_->OnUpdatePaymentDetails(event_type, details_script_value);
updater_ = nullptr; updater_ = nullptr;
} }
......
...@@ -41,7 +41,8 @@ class MODULES_EXPORT PaymentRequestUpdateEvent : public Event, ...@@ -41,7 +41,8 @@ class MODULES_EXPORT PaymentRequestUpdateEvent : public Event,
bool is_waiting_for_update() const { return wait_for_update_; } bool is_waiting_for_update() const { return wait_for_update_; }
// PaymentUpdater: // PaymentUpdater:
void OnUpdatePaymentDetails(const ScriptValue& details_script_value) override; void OnUpdatePaymentDetails(const AtomicString& event_type,
const ScriptValue& details_script_value) override;
void OnUpdatePaymentDetailsFailure(const String& error) override; void OnUpdatePaymentDetailsFailure(const String& error) override;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
......
...@@ -28,8 +28,9 @@ class MockPaymentUpdater : public GarbageCollectedFinalized<MockPaymentUpdater>, ...@@ -28,8 +28,9 @@ class MockPaymentUpdater : public GarbageCollectedFinalized<MockPaymentUpdater>,
MockPaymentUpdater() = default; MockPaymentUpdater() = default;
~MockPaymentUpdater() override = default; ~MockPaymentUpdater() override = default;
MOCK_METHOD1(OnUpdatePaymentDetails, MOCK_METHOD2(OnUpdatePaymentDetails,
void(const ScriptValue& detailsScriptValue)); void(const AtomicString& event_type,
const ScriptValue& detailsScriptValue));
MOCK_METHOD1(OnUpdatePaymentDetailsFailure, void(const String& error)); MOCK_METHOD1(OnUpdatePaymentDetailsFailure, void(const String& error));
void Trace(blink::Visitor* visitor) override {} void Trace(blink::Visitor* visitor) override {}
...@@ -49,7 +50,9 @@ TEST(PaymentRequestUpdateEventTest, OnUpdatePaymentDetailsCalled) { ...@@ -49,7 +50,9 @@ TEST(PaymentRequestUpdateEventTest, OnUpdatePaymentDetailsCalled) {
scope.GetExceptionState()); scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException()); EXPECT_FALSE(scope.GetExceptionState().HadException());
EXPECT_CALL(*updater, OnUpdatePaymentDetails(testing::_)); EXPECT_CALL(*updater,
OnUpdatePaymentDetails(event_type_names::kShippingaddresschange,
testing::_));
EXPECT_CALL(*updater, OnUpdatePaymentDetailsFailure(testing::_)).Times(0); EXPECT_CALL(*updater, OnUpdatePaymentDetailsFailure(testing::_)).Times(0);
payment_details->Resolve("foo"); payment_details->Resolve("foo");
...@@ -69,7 +72,10 @@ TEST(PaymentRequestUpdateEventTest, OnUpdatePaymentDetailsFailureCalled) { ...@@ -69,7 +72,10 @@ TEST(PaymentRequestUpdateEventTest, OnUpdatePaymentDetailsFailureCalled) {
scope.GetExceptionState()); scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException()); EXPECT_FALSE(scope.GetExceptionState().HadException());
EXPECT_CALL(*updater, OnUpdatePaymentDetails(testing::_)).Times(0); EXPECT_CALL(*updater,
OnUpdatePaymentDetails(event_type_names::kShippingaddresschange,
testing::_))
.Times(0);
EXPECT_CALL(*updater, OnUpdatePaymentDetailsFailure(testing::_)); EXPECT_CALL(*updater, OnUpdatePaymentDetailsFailure(testing::_));
payment_details->Reject("oops"); payment_details->Reject("oops");
......
...@@ -16,6 +16,7 @@ class ScriptValue; ...@@ -16,6 +16,7 @@ class ScriptValue;
class MODULES_EXPORT PaymentUpdater : public GarbageCollectedMixin { class MODULES_EXPORT PaymentUpdater : public GarbageCollectedMixin {
public: public:
virtual void OnUpdatePaymentDetails( virtual void OnUpdatePaymentDetails(
const AtomicString& event_type,
const ScriptValue& details_script_value) = 0; const ScriptValue& details_script_value) = 0;
virtual void OnUpdatePaymentDetailsFailure(const String& error) = 0; virtual void OnUpdatePaymentDetailsFailure(const String& error) = 0;
......
...@@ -20678,6 +20678,8 @@ Called by update_net_error_codes.py.--> ...@@ -20678,6 +20678,8 @@ Called by update_net_error_codes.py.-->
<int value="2619" label="GetDisplayMedia"/> <int value="2619" label="GetDisplayMedia"/>
<int value="2620" label="CursorImageGT64x64"/> <int value="2620" label="CursorImageGT64x64"/>
<int value="2621" label="AdClick"/> <int value="2621" label="AdClick"/>
<int value="2622" label="UpdateWithoutShippingOptionOnShippingAddressChange"/>
<int value="2623" label="UpdateWithoutShippingOptionOnShippingOptionChange"/>
</enum> </enum>
<enum name="FeaturePolicyFeature"> <enum name="FeaturePolicyFeature">
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