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 "components/autofill/core/browser/autofill_assistant.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/callback.h"
11 #include "base/feature_list.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/scoped_feature_list.h"
14 #include "base/test/task_environment.h"
15 #include "components/autofill/core/browser/autofill_driver.h"
16 #include "components/autofill/core/browser/autofill_manager.h"
17 #include "components/autofill/core/browser/autofill_test_utils.h"
18 #include "components/autofill/core/browser/data_model/credit_card.h"
19 #include "components/autofill/core/browser/form_structure.h"
20 #include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
21 #include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
22 #include "components/autofill/core/browser/test_autofill_client.h"
23 #include "components/autofill/core/browser/test_autofill_driver.h"
24 #include "components/autofill/core/browser/test_personal_data_manager.h"
25 #include "components/autofill/core/common/autofill_constants.h"
26 #include "components/autofill/core/common/autofill_features.h"
27 #include "services/network/public/cpp/shared_url_loader_factory.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/gurl.h"
31 
32 using testing::_;
33 
34 namespace autofill {
35 namespace {
36 
37 class MockAutofillManager : public AutofillManager {
38  public:
MockAutofillManager(TestAutofillDriver * driver,TestAutofillClient * client,PersonalDataManager * pdm,AutocompleteHistoryManager * ahm)39   MockAutofillManager(TestAutofillDriver* driver,
40                       TestAutofillClient* client,
41                       PersonalDataManager* pdm,
42                       AutocompleteHistoryManager* ahm)
43       // Force to use the constructor designated for unit test.
44       : AutofillManager(driver, client, pdm, ahm) {}
~MockAutofillManager()45   virtual ~MockAutofillManager() {}
46 
47   MOCK_METHOD5(FillCreditCardForm,
48                void(int query_id,
49                     const FormData& form,
50                     const FormFieldData& field,
51                     const CreditCard& credit_card,
52                     const base::string16& cvc));
53 
54   using AutofillManager::mutable_form_structures;
55 
56  private:
57   DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
58 };
59 
60 }  // namespace
61 
62 class AutofillAssistantTest : public testing::Test {
63  protected:
AutofillAssistantTest()64   AutofillAssistantTest()
65       : task_environment_(),
66         autofill_client_(),
67         autofill_driver_(),
68         pdm_(),
69         ahm_() {}
70 
SetUp()71   void SetUp() {
72     payments::TestPaymentsClient* payments_client =
73         new payments::TestPaymentsClient(autofill_driver_.GetURLLoaderFactory(),
74                                          autofill_client_.GetIdentityManager(),
75                                          &pdm_);
76     autofill_client_.set_test_payments_client(
77         std::unique_ptr<payments::TestPaymentsClient>(payments_client));
78     TestCreditCardSaveManager* credit_card_save_manager =
79         new TestCreditCardSaveManager(&autofill_driver_, &autofill_client_,
80                                       payments_client, &pdm_);
81     autofill::TestFormDataImporter* test_form_data_importer =
82         new TestFormDataImporter(
83             &autofill_client_, payments_client,
84             std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager),
85             &pdm_, "en-US");
86     autofill_client_.set_test_form_data_importer(
87         std::unique_ptr<TestFormDataImporter>(test_form_data_importer));
88 
89     autofill_manager_ = std::make_unique<MockAutofillManager>(
90         &autofill_driver_, &autofill_client_, &pdm_, &ahm_);
91 
92     autofill_assistant_ =
93         std::make_unique<AutofillAssistant>(autofill_manager_.get());
94   }
95 
EnableAutofillCreditCardAssist()96   void EnableAutofillCreditCardAssist() {
97     scoped_feature_list_.InitAndEnableFeature(
98         features::kAutofillCreditCardAssist);
99   }
100 
101   // Returns a valid credit card form.
CreateValidCreditCardFormData()102   FormData CreateValidCreditCardFormData() {
103     FormData form;
104     form.url = GURL("https://myform.com");
105     form.action = GURL("https://myform.com/submit");
106 
107     FormFieldData field;
108     field.form_control_type = "text";
109 
110     field.label = base::ASCIIToUTF16("Name on Card");
111     field.name = base::ASCIIToUTF16("name_on_card");
112     form.fields.push_back(field);
113 
114     field.label = base::ASCIIToUTF16("Card Number");
115     field.name = base::ASCIIToUTF16("card_number");
116     form.fields.push_back(field);
117 
118     field.label = base::ASCIIToUTF16("Exp Month");
119     field.name = base::ASCIIToUTF16("ccmonth");
120     form.fields.push_back(field);
121 
122     field.label = base::ASCIIToUTF16("Exp Year");
123     field.name = base::ASCIIToUTF16("ccyear");
124     form.fields.push_back(field);
125 
126     field.label = base::ASCIIToUTF16("Verification");
127     field.name = base::ASCIIToUTF16("verification");
128     form.fields.push_back(field);
129 
130     return form;
131   }
132 
133   // Returns an initialized FormStructure with credit card form data. To be
134   // owned by the caller.
CreateValidCreditCardForm()135   std::unique_ptr<FormStructure> CreateValidCreditCardForm() {
136     std::unique_ptr<FormStructure> form_structure;
137     form_structure.reset(new FormStructure(CreateValidCreditCardFormData()));
138     form_structure->DetermineHeuristicTypes();
139     return form_structure;
140   }
141 
142   // Convenience method to cast the FullCardRequest into a CardUnmaskDelegate.
full_card_unmask_delegate()143   CardUnmaskDelegate* full_card_unmask_delegate() {
144     payments::FullCardRequest* full_card_request =
145         autofill_manager_->credit_card_access_manager_->cvc_authenticator_
146             ->full_card_request_.get();
147     DCHECK(full_card_request);
148     return static_cast<CardUnmaskDelegate*>(full_card_request);
149   }
150 
151   base::test::SingleThreadTaskEnvironment task_environment_;
152   TestAutofillClient autofill_client_;
153   testing::NiceMock<TestAutofillDriver> autofill_driver_;
154   TestPersonalDataManager pdm_;
155   MockAutocompleteHistoryManager ahm_;
156   std::unique_ptr<MockAutofillManager> autofill_manager_;
157   std::unique_ptr<AutofillAssistant> autofill_assistant_;
158   base::test::ScopedFeatureList scoped_feature_list_;
159 };
160 
161 MATCHER_P(CreditCardMatches, guid, "") {
162   return arg.guid() == guid;
163 }
164 
165 // If the feature is turned off, CanShowCreditCardAssist() always returns
166 // false.
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOff)167 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOff) {
168   std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
169 
170   auto& form_structures = *autofill_manager_->mutable_form_structures();
171   auto signature = form_structure->form_signature();
172   form_structures[signature] = std::move(form_structure);
173   EXPECT_FALSE(autofill_assistant_->CanShowCreditCardAssist());
174 }
175 
176 // Tests that with the feature enabled and proper input,
177 // CanShowCreditCardAssist() behaves as expected.
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn)178 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn) {
179   EnableAutofillCreditCardAssist();
180 
181   EXPECT_FALSE(autofill_assistant_->CanShowCreditCardAssist());
182 
183   // With valid input, the function extracts the credit card form properly.
184   std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
185   auto& form_structures = *autofill_manager_->mutable_form_structures();
186   auto signature = form_structure->form_signature();
187   form_structures[signature] = std::move(form_structure);
188   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
189 }
190 
191 // Tests that with the feature enabled and proper input,
192 // CanShowCreditCardAssist() behaves as expected for secure contexts.
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn_Secure)193 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_Secure) {
194   EnableAutofillCreditCardAssist();
195 
196   // Can be shown if the context is secure.
197   FormData form = CreateValidCreditCardFormData();
198   auto form_structure = std::make_unique<FormStructure>(form);
199   form_structure->DetermineHeuristicTypes();
200 
201   auto& form_structures = *autofill_manager_->mutable_form_structures();
202   auto signature = form_structure->form_signature();
203   form_structures[signature] = std::move(form_structure);
204   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
205 }
206 
207 // Tests that with the feature enabled and proper input,
208 // CanShowCreditCardAssist() behaves as expected for insecure contexts.
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn_NotSecure)209 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_NotSecure) {
210   EnableAutofillCreditCardAssist();
211 
212   // Cannot be shown if the context is not secure.
213   FormData form = CreateValidCreditCardFormData();
214   form.url = GURL("http://myform.com");
215   form.action = GURL("http://myform.com/submit");
216   auto form_structure = std::make_unique<FormStructure>(form);
217   form_structure->DetermineHeuristicTypes();
218 
219   auto& form_structures = *autofill_manager_->mutable_form_structures();
220   auto signature = form_structure->form_signature();
221   form_structures[signature] = std::move(form_structure);
222   EXPECT_FALSE(autofill_assistant_->CanShowCreditCardAssist());
223 }
224 
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn_Javascript)225 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_Javascript) {
226   EnableAutofillCreditCardAssist();
227 
228   // Can be shown if the context is secure and the form action is a javascript
229   // function (which is a valid url).
230   FormData form = CreateValidCreditCardFormData();
231   form.action = GURL("javascript:alert('hello');");
232   auto form_structure = std::make_unique<FormStructure>(form);
233   form_structure->DetermineHeuristicTypes();
234 
235   auto& form_structures = *autofill_manager_->mutable_form_structures();
236   auto signature = form_structure->form_signature();
237   form_structures[signature] = std::move(form_structure);
238   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
239 }
240 
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn_WeirdJs)241 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_WeirdJs) {
242   EnableAutofillCreditCardAssist();
243 
244   // Can be shown if the context is secure and the form action is a javascript
245   // function that may or may not be valid.
246   FormData form = CreateValidCreditCardFormData();
247   form.action = GURL("javascript:myFunc");
248   auto form_structure = std::make_unique<FormStructure>(form);
249   form_structure->DetermineHeuristicTypes();
250 
251   auto& form_structures = *autofill_manager_->mutable_form_structures();
252   auto signature = form_structure->form_signature();
253   form_structures[signature] = std::move(form_structure);
254   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
255 }
256 
TEST_F(AutofillAssistantTest,CanShowCreditCardAssist_FeatureOn_EmptyAction)257 TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_EmptyAction) {
258   EnableAutofillCreditCardAssist();
259 
260   // Can be shown if the context is secure and the form action is empty.
261   FormData form = CreateValidCreditCardFormData();
262   form.action = GURL();
263   auto form_structure = std::make_unique<FormStructure>(form);
264   form_structure->DetermineHeuristicTypes();
265 
266   auto& form_structures = *autofill_manager_->mutable_form_structures();
267   auto signature = form_structure->form_signature();
268   form_structures[signature] = std::move(form_structure);
269   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
270 }
271 
TEST_F(AutofillAssistantTest,ShowAssistForCreditCard_ValidCard_CancelCvc)272 TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard_CancelCvc) {
273   EnableAutofillCreditCardAssist();
274   std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
275 
276   // Will extract the credit card form data.
277   auto& form_structures = *autofill_manager_->mutable_form_structures();
278   auto signature = form_structure->form_signature();
279   form_structures[signature] = std::move(form_structure);
280   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
281 
282   // Create a valid card for the assist.
283   CreditCard card;
284   test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999",
285                           "1");
286 
287   // FillCreditCardForm should not be called if the user cancelled the CVC.
288   EXPECT_CALL(*autofill_manager_, FillCreditCardForm(_, _, _, _, _)).Times(0);
289 
290   autofill_assistant_->ShowAssistForCreditCard(card);
291   full_card_unmask_delegate()->OnUnmaskPromptClosed();
292 }
293 
TEST_F(AutofillAssistantTest,ShowAssistForCreditCard_ValidCard_SubmitCvc)294 TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard_SubmitCvc) {
295   EnableAutofillCreditCardAssist();
296   std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
297 
298   // Will extract the credit card form data.
299   auto& form_structures = *autofill_manager_->mutable_form_structures();
300   auto signature = form_structure->form_signature();
301   form_structures[signature] = std::move(form_structure);
302   EXPECT_TRUE(autofill_assistant_->CanShowCreditCardAssist());
303 
304   // Create a valid card for the assist.
305   CreditCard card;
306   test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999",
307                           "1");
308 
309   // FillCreditCardForm ends up being called after user has accepted the
310   // prompt.
311   EXPECT_CALL(
312       *autofill_manager_,
313       FillCreditCardForm(kNoQueryId, _, _, CreditCardMatches(card.guid()),
314                          base::ASCIIToUTF16("123")));
315 
316   autofill_assistant_->ShowAssistForCreditCard(card);
317 
318   CardUnmaskDelegate::UserProvidedUnmaskDetails unmask_details;
319   unmask_details.cvc = base::ASCIIToUTF16("123");
320   full_card_unmask_delegate()->OnUnmaskPromptAccepted(unmask_details);
321 }
322 
323 }  // namespace autofill
324