blob: 3eef9a0055b502457fcc88c47494e1f87e10f55e [file] [log] [blame]
Rouslan Solomakhincb29c4f2019-08-16 22:49:391// Copyright 2019 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 "base/macros.h"
6#include "base/strings/utf_string_conversions.h"
Danyao Wang2f9cdb842019-11-22 16:58:257#include "base/test/metrics/histogram_tester.h"
Rouslan Solomakhincb29c4f2019-08-16 22:49:398#include "base/test/scoped_feature_list.h"
9#include "build/build_config.h"
Sahel Sharify35b1b5d2020-02-25 18:17:4710#include "chrome/test/payments/payment_request_platform_browsertest_base.h"
Danyao Wangf81d3612020-03-09 16:13:4411#include "chrome/test/payments/personal_data_manager_test_util.h"
Rouslan Solomakhincb29c4f2019-08-16 22:49:3912#include "components/payments/core/features.h"
Danyao Wang2f9cdb842019-11-22 16:58:2513#include "components/payments/core/journey_logger.h"
Peter Kasting919ce652020-05-07 10:22:3614#include "content/public/test/browser_test.h"
Rouslan Solomakhincb29c4f2019-08-16 22:49:3915#include "testing/gtest/include/gtest/gtest.h"
16
Rouslan Solomakhincb29c4f2019-08-16 22:49:3917namespace payments {
18namespace {
19
Danyao Wang3f9d32272019-11-25 17:16:4520enum HasEnrolledInstrumentMode {
21 STRICT_HAS_ENROLLED_INSTRUMENT,
22 LEGACY_HAS_ENROLLED_INSTRUMENT,
23};
24
25// A parameterized test to test both values of
26// features::kStrictHasEnrolledAutofillInstrument.
27class HasEnrolledInstrumentTest
Sahel Sharify35b1b5d2020-02-25 18:17:4728 : public PaymentRequestPlatformBrowserTestBase,
Danyao Wang3f9d32272019-11-25 17:16:4529 public testing::WithParamInterface<HasEnrolledInstrumentMode> {
Rouslan Solomakhincb29c4f2019-08-16 22:49:3930 public:
Sahel Sharify35b1b5d2020-02-25 18:17:4731 HasEnrolledInstrumentTest() {
Danyao Wang3f9d32272019-11-25 17:16:4532 if (GetParam() == STRICT_HAS_ENROLLED_INSTRUMENT) {
33 feature_list_.InitWithFeatures(
34 /*enabled_features=*/{features::kStrictHasEnrolledAutofillInstrument},
35 /*disabled_features=*/{features::kPaymentRequestSkipToGPay});
36 }
37 }
Rouslan Solomakhincb29c4f2019-08-16 22:49:3938
Sahel Sharify35b1b5d2020-02-25 18:17:4739 ~HasEnrolledInstrumentTest() override = default;
Rouslan Solomakhincb29c4f2019-08-16 22:49:3940
41 void SetUpOnMainThread() override {
Sahel Sharify35b1b5d2020-02-25 18:17:4742 PaymentRequestPlatformBrowserTestBase::SetUpOnMainThread();
43 NavigateTo("/has_enrolled_instrument.html");
Rouslan Solomakhincb29c4f2019-08-16 22:49:3944 }
45
Rouslan Solomakhin2dc99c32020-03-24 21:25:0346 std::string not_supported_message() const {
47 return "NotSupportedError: The payment method \"basic-card\" is not "
48 "supported. User does not have valid information on file.";
Rouslan Solomakhin1dca2a922019-09-06 22:25:0749 }
50
Danyao Wang3f9d32272019-11-25 17:16:4551 // Helper function to test that all variations of hasEnrolledInstrument()
52 // returns |expected|.
53 void ExpectHasEnrolledInstrumentIs(bool expected) {
54 EXPECT_EQ(expected, content::EvalJs(GetActiveWebContents(),
55 "hasEnrolledInstrument()"));
56 EXPECT_EQ(expected,
57 content::EvalJs(GetActiveWebContents(),
58 "hasEnrolledInstrument({requestShipping:true})"));
59 EXPECT_EQ(expected, content::EvalJs(
60 GetActiveWebContents(),
61 "hasEnrolledInstrument({requestPayerEmail:true})"));
62 }
63
64 // Helper function to test that all variants of show() rejects with
65 // not_supported_message().
66 void ExpectShowRejects() {
67 // Only check show() if feature is on.
68 if (GetParam() == STRICT_HAS_ENROLLED_INSTRUMENT) {
69 base::HistogramTester histogram_tester;
70 base::HistogramBase::Count expected_count =
71 histogram_tester.GetBucketCount(
72 "PaymentRequest.CheckoutFunnel.NoShow",
73 JourneyLogger::NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD);
74
Danyao Wangd77ef782019-11-25 21:22:3675 // Check code path where show() is called before instruments are ready.
Danyao Wang3f9d32272019-11-25 17:16:4576 EXPECT_EQ(not_supported_message(),
77 content::EvalJs(GetActiveWebContents(), "show()"));
78 // TODO(crbug.com/1027322): Fix NoShow logging on Android.
79#if !defined(OS_ANDROID)
80 expected_count++;
81#endif
82 histogram_tester.ExpectBucketCount(
83 "PaymentRequest.CheckoutFunnel.NoShow",
84 JourneyLogger::NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD,
85 expected_count);
86 EXPECT_EQ(not_supported_message(),
87 content::EvalJs(GetActiveWebContents(),
88 "show({requestShipping:true})"));
89 EXPECT_EQ(not_supported_message(),
90 content::EvalJs(GetActiveWebContents(),
91 "show({requestPayerEmail:true})"));
Danyao Wangd77ef782019-11-25 21:22:3692
93 // Check code path where show() is called after instruments are ready.
94 EXPECT_EQ(not_supported_message(),
95 content::EvalJs(GetActiveWebContents(), "delayedShow()"));
96 EXPECT_EQ(not_supported_message(),
97 content::EvalJs(GetActiveWebContents(),
98 "delayedShow({requestShipping:true})"));
99 EXPECT_EQ(not_supported_message(),
100 content::EvalJs(GetActiveWebContents(),
101 "delayedShow({requestPayerEmail:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45102 }
103 }
104
Rouslan Solomakhincb29c4f2019-08-16 22:49:39105 private:
Danyao Wang3f9d32272019-11-25 17:16:45106 base::test::ScopedFeatureList feature_list_;
Rouslan Solomakhincb29c4f2019-08-16 22:49:39107
108 DISALLOW_COPY_AND_ASSIGN(HasEnrolledInstrumentTest);
109};
110
Danyao Wang3f9d32272019-11-25 17:16:45111IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, NoCard) {
112 ExpectHasEnrolledInstrumentIs(false);
113 ExpectShowRejects();
Ken Rockot12375dba2019-10-11 16:16:01114}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39115
Danyao Wang3f9d32272019-11-25 17:16:45116IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, NoBillingAddress) {
Sahel Sharify35b1b5d2020-02-25 18:17:47117 AddCreditCard(autofill::test::GetCreditCard());
Danyao Wang3f9d32272019-11-25 17:16:45118 ExpectHasEnrolledInstrumentIs(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT);
119 ExpectShowRejects();
Ken Rockot12375dba2019-10-11 16:16:01120}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39121
Danyao Wang3f9d32272019-11-25 17:16:45122IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39123 HaveShippingNoBillingAddress) {
Sahel Sharify35b1b5d2020-02-25 18:17:47124 CreateAndAddAutofillProfile();
125 AddCreditCard(autofill::test::GetCreditCard());
Rouslan Solomakhincb29c4f2019-08-16 22:49:39126
Danyao Wang3f9d32272019-11-25 17:16:45127 ExpectHasEnrolledInstrumentIs(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT);
128 ExpectShowRejects();
Ken Rockot12375dba2019-10-11 16:16:01129}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39130
Danyao Wang3f9d32272019-11-25 17:16:45131IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39132 HaveShippingAndBillingAddress) {
Sahel Sharify35b1b5d2020-02-25 18:17:47133 CreateAndAddCreditCardForProfile(CreateAndAddAutofillProfile());
Rouslan Solomakhincb29c4f2019-08-16 22:49:39134
Danyao Wang3f9d32272019-11-25 17:16:45135 ExpectHasEnrolledInstrumentIs(true);
Ken Rockot12375dba2019-10-11 16:16:01136}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39137
Danyao Wang3f9d32272019-11-25 17:16:45138IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, InvalidCardNumber) {
Rouslan Solomakhincb29c4f2019-08-16 22:49:39139 autofill::AutofillProfile address = autofill::test::GetFullProfile();
Sahel Sharify35b1b5d2020-02-25 18:17:47140 AddAutofillProfile(address);
141 autofill::CreditCard card = CreatCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39142 card.SetRawInfo(autofill::ServerFieldType::CREDIT_CARD_NUMBER,
Jan Wilken Dörrie78e88d82e2021-03-23 15:24:22143 u"1111111111111111");
Sahel Sharify35b1b5d2020-02-25 18:17:47144 AddCreditCard(card);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39145
Danyao Wang3f9d32272019-11-25 17:16:45146 ExpectHasEnrolledInstrumentIs(false);
147 ExpectShowRejects();
Ken Rockot12375dba2019-10-11 16:16:01148}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39149
Danyao Wang3f9d32272019-11-25 17:16:45150IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, ExpiredCard) {
Rouslan Solomakhincb29c4f2019-08-16 22:49:39151 autofill::AutofillProfile address = autofill::test::GetFullProfile();
Sahel Sharify35b1b5d2020-02-25 18:17:47152 AddAutofillProfile(address);
153 autofill::CreditCard card = CreatCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39154 card.SetExpirationYear(2000);
Sahel Sharify35b1b5d2020-02-25 18:17:47155 AddCreditCard(card);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39156
Danyao Wang3f9d32272019-11-25 17:16:45157 ExpectHasEnrolledInstrumentIs(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT);
158 ExpectShowRejects();
Rouslan Solomakhincb29c4f2019-08-16 22:49:39159}
160
161// TODO(https://crbug.com/994799): Unify autofill data validation and returned
162// data across platforms.
Danyao Wang3f9d32272019-11-25 17:16:45163IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39164 HaveNoNameShippingAndBillingAddress) {
165 autofill::AutofillProfile address = autofill::test::GetFullProfile();
Jan Wilken Dörriedec99122021-03-11 18:02:30166 address.SetRawInfo(autofill::ServerFieldType::NAME_FIRST, std::u16string());
167 address.SetRawInfo(autofill::ServerFieldType::NAME_MIDDLE, std::u16string());
168 address.SetRawInfo(autofill::ServerFieldType::NAME_LAST, std::u16string());
Matthias Körberc2d21072021-02-10 14:35:46169 // For structured names, it is necessary to explicitly reset the full name
170 // and the full name with the prefix.
Jan Wilken Dörriedec99122021-03-11 18:02:30171 address.SetInfo(autofill::ServerFieldType::NAME_FULL, std::u16string(),
Matthias Körber4da55b32020-08-19 14:10:29172 "en-US");
Matthias Körberc2d21072021-02-10 14:35:46173 address.SetInfo(autofill::ServerFieldType::NAME_FULL_WITH_HONORIFIC_PREFIX,
Jan Wilken Dörriedec99122021-03-11 18:02:30174 std::u16string(), "en-US");
Sahel Sharify35b1b5d2020-02-25 18:17:47175 AddAutofillProfile(address);
176 CreateAndAddCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39177
Danyao Wang3f9d32272019-11-25 17:16:45178 // Recipient name is required for shipping address in strict mode.
179 EXPECT_EQ(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39180 content::EvalJs(GetActiveWebContents(),
181 "hasEnrolledInstrument({requestShipping:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45182 if (GetParam() == STRICT_HAS_ENROLLED_INSTRUMENT) {
183 EXPECT_EQ(not_supported_message(),
184 content::EvalJs(GetActiveWebContents(),
185 "show({requestShipping:true})"));
186 }
Rouslan Solomakhincb29c4f2019-08-16 22:49:39187
Danyao Wang3f9d32272019-11-25 17:16:45188 // Recipient name should be required for billing address in strict mode, but
189 // current desktop implementation doesn't match this requirement.
190 // TODO(https://crbug.com/994799): Unify autofill data requirements between
191 // desktop and Android.
Rouslan Solomakhincb29c4f2019-08-16 22:49:39192#if defined(OS_ANDROID)
Danyao Wang3f9d32272019-11-25 17:16:45193 bool is_no_name_billing_address_valid =
194 GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT;
Rouslan Solomakhincb29c4f2019-08-16 22:49:39195#else
Ken Rockot12375dba2019-10-11 16:16:01196 bool is_no_name_billing_address_valid = true;
Danyao Wang3f9d32272019-11-25 17:16:45197#endif
Rouslan Solomakhin1dca2a922019-09-06 22:25:07198
Ken Rockot12375dba2019-10-11 16:16:01199 EXPECT_EQ(is_no_name_billing_address_valid,
200 content::EvalJs(GetActiveWebContents(), "hasEnrolledInstrument()"));
201 EXPECT_EQ(is_no_name_billing_address_valid,
202 content::EvalJs(GetActiveWebContents(),
203 "hasEnrolledInstrument({requestPayerEmail:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45204 if (!is_no_name_billing_address_valid) {
205 EXPECT_EQ(not_supported_message(),
206 content::EvalJs(GetActiveWebContents(), "show()"));
207 EXPECT_EQ(not_supported_message(),
208 content::EvalJs(GetActiveWebContents(),
209 "show({requestPayerEmail:true})"));
210 }
Rouslan Solomakhincb29c4f2019-08-16 22:49:39211}
212
Danyao Wang3f9d32272019-11-25 17:16:45213IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39214 HaveNoStreetShippingAndBillingAddress) {
215 autofill::AutofillProfile address = autofill::test::GetFullProfile();
216 address.SetRawInfo(autofill::ServerFieldType::ADDRESS_HOME_STREET_ADDRESS,
Jan Wilken Dörriedec99122021-03-11 18:02:30217 std::u16string());
Sahel Sharify35b1b5d2020-02-25 18:17:47218 AddAutofillProfile(address);
219 CreateAndAddCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39220
Danyao Wang3f9d32272019-11-25 17:16:45221 ExpectHasEnrolledInstrumentIs(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT);
222 ExpectShowRejects();
Ken Rockot12375dba2019-10-11 16:16:01223}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39224
Danyao Wang3f9d32272019-11-25 17:16:45225IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, NoEmailAddress) {
Rouslan Solomakhincb29c4f2019-08-16 22:49:39226 autofill::AutofillProfile address = autofill::test::GetFullProfile();
227 address.SetRawInfo(autofill::ServerFieldType::EMAIL_ADDRESS,
Jan Wilken Dörriedec99122021-03-11 18:02:30228 std::u16string());
Sahel Sharify35b1b5d2020-02-25 18:17:47229 AddAutofillProfile(address);
230 CreateAndAddCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39231
232 EXPECT_EQ(true,
233 content::EvalJs(GetActiveWebContents(), "hasEnrolledInstrument()"));
234 EXPECT_EQ(true,
235 content::EvalJs(GetActiveWebContents(),
236 "hasEnrolledInstrument({requestShipping:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45237 // StrictHasEnrolledAutofillInstrument considers a profile with missing email
238 // address as invalid.
239 EXPECT_EQ(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39240 content::EvalJs(GetActiveWebContents(),
241 "hasEnrolledInstrument({requestPayerEmail:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45242 if (GetParam() == STRICT_HAS_ENROLLED_INSTRUMENT) {
243 EXPECT_EQ(not_supported_message(),
244 content::EvalJs(GetActiveWebContents(),
245 "show({requestPayerEmail:true})"));
246 }
Ken Rockot12375dba2019-10-11 16:16:01247}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39248
Danyao Wang3f9d32272019-11-25 17:16:45249IN_PROC_BROWSER_TEST_P(HasEnrolledInstrumentTest, InvalidEmailAddress) {
Rouslan Solomakhincb29c4f2019-08-16 22:49:39250 autofill::AutofillProfile address = autofill::test::GetFullProfile();
251 address.SetRawInfo(autofill::ServerFieldType::EMAIL_ADDRESS,
Jan Wilken Dörrie78e88d82e2021-03-23 15:24:22252 u"this-is-not-a-valid-email-address");
Sahel Sharify35b1b5d2020-02-25 18:17:47253 AddAutofillProfile(address);
254 CreateAndAddCreditCardForProfile(address);
Rouslan Solomakhincb29c4f2019-08-16 22:49:39255
256 EXPECT_EQ(true,
257 content::EvalJs(GetActiveWebContents(), "hasEnrolledInstrument()"));
258 EXPECT_EQ(true,
259 content::EvalJs(GetActiveWebContents(),
260 "hasEnrolledInstrument({requestShipping:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45261
262 // StrictHasEnrolledAutofillInstrument considers a profile with missing email
263 // address as invalid.
264 EXPECT_EQ(GetParam() != STRICT_HAS_ENROLLED_INSTRUMENT,
Rouslan Solomakhincb29c4f2019-08-16 22:49:39265 content::EvalJs(GetActiveWebContents(),
266 "hasEnrolledInstrument({requestPayerEmail:true})"));
Danyao Wang3f9d32272019-11-25 17:16:45267 if (GetParam() == STRICT_HAS_ENROLLED_INSTRUMENT) {
268 EXPECT_EQ(not_supported_message(),
269 content::EvalJs(GetActiveWebContents(),
270 "show({requestPayerEmail:true})"));
271 }
Ken Rockot12375dba2019-10-11 16:16:01272}
Rouslan Solomakhincb29c4f2019-08-16 22:49:39273
Danyao Wang3f9d32272019-11-25 17:16:45274// Run all tests with both values for
275// features::kStrictHasEnrolledAutofillInstrument.
Rouslan Solomakhin2dc99c32020-03-24 21:25:03276INSTANTIATE_TEST_SUITE_P(All,
277 HasEnrolledInstrumentTest,
278 ::testing::Values(STRICT_HAS_ENROLLED_INSTRUMENT,
279 LEGACY_HAS_ENROLLED_INSTRUMENT));
Rouslan Solomakhincb29c4f2019-08-16 22:49:39280} // namespace
281} // namespace payments