1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
6
7 #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
8 #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h"
9 #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
10 #include "third_party/blink/renderer/core/dom/document.h"
11 #include "third_party/blink/renderer/platform/bindings/script_state.h"
12 #include "third_party/blink/renderer/platform/heap/heap_allocator.h"
13 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
14
15 namespace blink {
16 namespace {
17
18 static int g_unique_id = 0;
19 // PaymentItem and PaymentShippingOption have identical structure
20 // except for the "id" field, which is present only in PaymentShippingOption.
21 template <typename PaymentItemOrPaymentShippingOption>
SetValues(PaymentItemOrPaymentShippingOption * original,PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)22 void SetValues(PaymentItemOrPaymentShippingOption* original,
23 PaymentTestDataToChange data,
24 PaymentTestModificationType modification_type,
25 const String& value_to_use) {
26 PaymentCurrencyAmount* item_amount = PaymentCurrencyAmount::Create();
27 if (data == kPaymentTestDataCurrencyCode) {
28 if (modification_type == kPaymentTestOverwriteValue)
29 item_amount->setCurrency(value_to_use);
30 } else {
31 item_amount->setCurrency("USD");
32 }
33
34 if (data == kPaymentTestDataValue) {
35 if (modification_type == kPaymentTestOverwriteValue)
36 item_amount->setValue(value_to_use);
37 } else {
38 item_amount->setValue("9.99");
39 }
40
41 if (data != kPaymentTestDataAmount ||
42 modification_type != kPaymentTestRemoveKey)
43 original->setAmount(item_amount);
44
45 if (data == kPaymentTestDataLabel) {
46 if (modification_type == kPaymentTestOverwriteValue)
47 original->setLabel(value_to_use);
48 } else {
49 original->setLabel("Label");
50 }
51 }
52
BuildPaymentDetailsBase(PaymentTestDetailToChange detail,PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use,PaymentDetailsBase * details)53 void BuildPaymentDetailsBase(PaymentTestDetailToChange detail,
54 PaymentTestDataToChange data,
55 PaymentTestModificationType modification_type,
56 const String& value_to_use,
57 PaymentDetailsBase* details) {
58 PaymentItem* item = nullptr;
59 if (detail == kPaymentTestDetailItem) {
60 item = BuildPaymentItemForTest(data, modification_type, value_to_use);
61 } else {
62 item = BuildPaymentItemForTest();
63 }
64 DCHECK(item);
65
66 PaymentShippingOption* shipping_option = nullptr;
67 if (detail == kPaymentTestDetailShippingOption) {
68 shipping_option =
69 BuildShippingOptionForTest(data, modification_type, value_to_use);
70 } else {
71 shipping_option = BuildShippingOptionForTest();
72 }
73 DCHECK(shipping_option);
74
75 PaymentDetailsModifier* modifier = nullptr;
76 if (detail == kPaymentTestDetailModifierTotal ||
77 detail == kPaymentTestDetailModifierItem) {
78 modifier = BuildPaymentDetailsModifierForTest(
79 detail, data, modification_type, value_to_use);
80 } else {
81 modifier = BuildPaymentDetailsModifierForTest();
82 }
83 DCHECK(modifier);
84
85 details->setDisplayItems(HeapVector<Member<PaymentItem>>(1, item));
86 details->setShippingOptions(
87 HeapVector<Member<PaymentShippingOption>>(1, shipping_option));
88 details->setModifiers(
89 HeapVector<Member<PaymentDetailsModifier>>(1, modifier));
90 }
91
92 } // namespace
93
BuildPaymentItemForTest(PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)94 PaymentItem* BuildPaymentItemForTest(
95 PaymentTestDataToChange data,
96 PaymentTestModificationType modification_type,
97 const String& value_to_use) {
98 DCHECK_NE(data, kPaymentTestDataId);
99 PaymentItem* item = PaymentItem::Create();
100 SetValues(item, data, modification_type, value_to_use);
101 return item;
102 }
103
BuildShippingOptionForTest(PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)104 PaymentShippingOption* BuildShippingOptionForTest(
105 PaymentTestDataToChange data,
106 PaymentTestModificationType modification_type,
107 const String& value_to_use) {
108 PaymentShippingOption* shipping_option = PaymentShippingOption::Create();
109 if (data == kPaymentTestDataId) {
110 if (modification_type == kPaymentTestOverwriteValue)
111 shipping_option->setId(value_to_use);
112 } else {
113 shipping_option->setId("id" + String::Number(g_unique_id++));
114 }
115 SetValues(shipping_option, data, modification_type, value_to_use);
116 return shipping_option;
117 }
118
BuildPaymentDetailsModifierForTest(PaymentTestDetailToChange detail,PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)119 PaymentDetailsModifier* BuildPaymentDetailsModifierForTest(
120 PaymentTestDetailToChange detail,
121 PaymentTestDataToChange data,
122 PaymentTestModificationType modification_type,
123 const String& value_to_use) {
124 PaymentItem* total = nullptr;
125 if (detail == kPaymentTestDetailModifierTotal) {
126 total = BuildPaymentItemForTest(data, modification_type, value_to_use);
127 } else {
128 total = BuildPaymentItemForTest();
129 }
130 DCHECK(total);
131
132 PaymentItem* item = nullptr;
133 if (detail == kPaymentTestDetailModifierItem) {
134 item = BuildPaymentItemForTest(data, modification_type, value_to_use);
135 } else {
136 item = BuildPaymentItemForTest();
137 }
138 DCHECK(item);
139
140 PaymentDetailsModifier* modifier = PaymentDetailsModifier::Create();
141 modifier->setSupportedMethod("foo");
142 modifier->setTotal(total);
143 modifier->setAdditionalDisplayItems(HeapVector<Member<PaymentItem>>(1, item));
144 return modifier;
145 }
146
BuildPaymentDetailsInitForTest(PaymentTestDetailToChange detail,PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)147 PaymentDetailsInit* BuildPaymentDetailsInitForTest(
148 PaymentTestDetailToChange detail,
149 PaymentTestDataToChange data,
150 PaymentTestModificationType modification_type,
151 const String& value_to_use) {
152 PaymentDetailsInit* details = PaymentDetailsInit::Create();
153 BuildPaymentDetailsBase(detail, data, modification_type, value_to_use,
154 details);
155
156 if (detail == kPaymentTestDetailTotal) {
157 details->setTotal(
158 BuildPaymentItemForTest(data, modification_type, value_to_use));
159 } else {
160 details->setTotal(BuildPaymentItemForTest());
161 }
162
163 return details;
164 }
165
BuildPaymentDetailsUpdateForTest(PaymentTestDetailToChange detail,PaymentTestDataToChange data,PaymentTestModificationType modification_type,const String & value_to_use)166 PaymentDetailsUpdate* BuildPaymentDetailsUpdateForTest(
167 PaymentTestDetailToChange detail,
168 PaymentTestDataToChange data,
169 PaymentTestModificationType modification_type,
170 const String& value_to_use) {
171 PaymentDetailsUpdate* details = PaymentDetailsUpdate::Create();
172 BuildPaymentDetailsBase(detail, data, modification_type, value_to_use,
173 details);
174
175 if (detail == kPaymentTestDetailTotal) {
176 details->setTotal(
177 BuildPaymentItemForTest(data, modification_type, value_to_use));
178 } else {
179 details->setTotal(BuildPaymentItemForTest());
180 }
181
182 if (detail == kPaymentTestDetailError)
183 details->setError(value_to_use);
184
185 return details;
186 }
187
BuildPaymentDetailsErrorMsgForTest(const String & value_to_use)188 PaymentDetailsUpdate* BuildPaymentDetailsErrorMsgForTest(
189 const String& value_to_use) {
190 return BuildPaymentDetailsUpdateForTest(
191 kPaymentTestDetailError, kPaymentTestDataNone, kPaymentTestOverwriteValue,
192 value_to_use);
193 }
194
BuildPaymentMethodDataForTest()195 HeapVector<Member<PaymentMethodData>> BuildPaymentMethodDataForTest() {
196 HeapVector<Member<PaymentMethodData>> method_data(
197 1, PaymentMethodData::Create());
198 method_data[0]->setSupportedMethod("foo");
199 return method_data;
200 }
201
BuildPaymentResponseForTest()202 payments::mojom::blink::PaymentResponsePtr BuildPaymentResponseForTest() {
203 payments::mojom::blink::PaymentResponsePtr result =
204 payments::mojom::blink::PaymentResponse::New();
205 result->payer = payments::mojom::blink::PayerDetail::New();
206 return result;
207 }
208
BuildPaymentAddressForTest()209 payments::mojom::blink::PaymentAddressPtr BuildPaymentAddressForTest() {
210 payments::mojom::blink::PaymentAddressPtr result =
211 payments::mojom::blink::PaymentAddress::New();
212 result->country = "US";
213 return result;
214 }
215
PaymentRequestV8TestingScope()216 PaymentRequestV8TestingScope::PaymentRequestV8TestingScope()
217 : V8TestingScope(KURL("https://www.example.com/")) {
218 GetDocument().SetSecureContextModeForTesting(
219 SecureContextMode::kSecureContext);
220 }
221
PaymentRequestMockFunctionScope(ScriptState * script_state)222 PaymentRequestMockFunctionScope::PaymentRequestMockFunctionScope(
223 ScriptState* script_state)
224 : script_state_(script_state) {}
225
~PaymentRequestMockFunctionScope()226 PaymentRequestMockFunctionScope::~PaymentRequestMockFunctionScope() {
227 v8::MicrotasksScope::PerformCheckpoint(script_state_->GetIsolate());
228 for (MockFunction* mock_function : mock_functions_) {
229 testing::Mock::VerifyAndClearExpectations(mock_function);
230 }
231 }
232
ExpectCall(String * captor)233 v8::Local<v8::Function> PaymentRequestMockFunctionScope::ExpectCall(
234 String* captor) {
235 mock_functions_.push_back(
236 MakeGarbageCollected<MockFunction>(script_state_, captor));
237 EXPECT_CALL(*mock_functions_.back(), Call(testing::_));
238 return mock_functions_.back()->Bind();
239 }
240
ExpectCall()241 v8::Local<v8::Function> PaymentRequestMockFunctionScope::ExpectCall() {
242 mock_functions_.push_back(MakeGarbageCollected<MockFunction>(script_state_));
243 EXPECT_CALL(*mock_functions_.back(), Call(testing::_));
244 return mock_functions_.back()->Bind();
245 }
246
ExpectNoCall()247 v8::Local<v8::Function> PaymentRequestMockFunctionScope::ExpectNoCall() {
248 mock_functions_.push_back(MakeGarbageCollected<MockFunction>(script_state_));
249 EXPECT_CALL(*mock_functions_.back(), Call(testing::_)).Times(0);
250 return mock_functions_.back()->Bind();
251 }
252
ACTION_P2(SaveValueIn,script_state,captor)253 ACTION_P2(SaveValueIn, script_state, captor) {
254 *captor = ToCoreString(
255 arg0.V8Value()->ToString(script_state->GetContext()).ToLocalChecked());
256 }
257
MockFunction(ScriptState * script_state)258 PaymentRequestMockFunctionScope::MockFunction::MockFunction(
259 ScriptState* script_state)
260 : ScriptFunction(script_state) {
261 ON_CALL(*this, Call(testing::_)).WillByDefault(testing::ReturnArg<0>());
262 }
263
MockFunction(ScriptState * script_state,String * captor)264 PaymentRequestMockFunctionScope::MockFunction::MockFunction(
265 ScriptState* script_state,
266 String* captor)
267 : ScriptFunction(script_state), value_(captor) {
268 ON_CALL(*this, Call(testing::_))
269 .WillByDefault(
270 testing::DoAll(SaveValueIn(WrapPersistent(script_state), value_),
271 testing::ReturnArg<0>()));
272 }
273
Bind()274 v8::Local<v8::Function> PaymentRequestMockFunctionScope::MockFunction::Bind() {
275 return BindToV8Function();
276 }
277
278 } // namespace blink
279