1 // 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 "chrome/browser/autofill/address_accessory_controller_impl.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <ostream>
10 #include <string>
11 #include <vector>
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/mock_callback.h"
14 #include "chrome/browser/autofill/mock_manual_filling_controller.h"
15 #include "chrome/browser/autofill/personal_data_manager_factory.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/autofill/core/browser/autofill_test_utils.h"
20 #include "components/autofill/core/browser/test_personal_data_manager.h"
21 #include "components/strings/grit/components_strings.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/base/l10n/l10n_util.h"
25 
26 namespace autofill {
27 namespace {
28 using autofill::UserInfo;
29 using base::ASCIIToUTF16;
30 using testing::_;
31 using testing::ByMove;
32 using testing::Mock;
33 using testing::NiceMock;
34 using testing::Return;
35 using testing::SaveArg;
36 using testing::StrictMock;
37 using FillingSource = ManualFillingController::FillingSource;
38 
addresses_empty_str()39 base::string16 addresses_empty_str() {
40   return l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SHEET_EMPTY_MESSAGE);
41 }
42 
manage_addresses_str()43 base::string16 manage_addresses_str() {
44   return l10n_util::GetStringUTF16(
45       IDS_AUTOFILL_ADDRESS_SHEET_ALL_ADDRESSES_LINK);
46 }
47 
48 // Creates a AccessorySheetData::Builder with a "Manage Addresses" footer.
AddressAccessorySheetDataBuilder(const base::string16 & title)49 AccessorySheetData::Builder AddressAccessorySheetDataBuilder(
50     const base::string16& title) {
51   return AccessorySheetData::Builder(AccessoryTabType::ADDRESSES, title)
52       .AppendFooterCommand(manage_addresses_str(),
53                            AccessoryAction::MANAGE_ADDRESSES);
54 }
55 
BuildTestPersonalDataManager(content::BrowserContext * context)56 std::unique_ptr<KeyedService> BuildTestPersonalDataManager(
57     content::BrowserContext* context) {
58   auto personal_data_manager = std::make_unique<TestPersonalDataManager>();
59   personal_data_manager->SetAutofillProfileEnabled(true);
60   return personal_data_manager;
61 }
62 
63 }  // namespace
64 
65 class AddressAccessoryControllerTest : public ChromeRenderViewHostTestHarness {
66  public:
AddressAccessoryControllerTest()67   AddressAccessoryControllerTest() {}
68 
SetUp()69   void SetUp() override {
70     ChromeRenderViewHostTestHarness::SetUp();
71     PersonalDataManagerFactory::GetInstance()->SetTestingFactory(
72         GetBrowserContext(),
73         base::BindRepeating(&BuildTestPersonalDataManager));
74 
75     AddressAccessoryControllerImpl::CreateForWebContentsForTesting(
76         web_contents(), mock_manual_filling_controller_.AsWeakPtr());
77   }
78 
TearDown()79   void TearDown() override { personal_data_manager()->ClearProfiles(); }
80 
controller()81   AddressAccessoryController* controller() {
82     return AddressAccessoryControllerImpl::FromWebContents(web_contents());
83   }
84 
personal_data_manager()85   TestPersonalDataManager* personal_data_manager() {
86     return static_cast<TestPersonalDataManager*>(
87         PersonalDataManagerFactory::GetForProfile(profile()));
88   }
89 
90  protected:
91   StrictMock<MockManualFillingController> mock_manual_filling_controller_;
92 };
93 
TEST_F(AddressAccessoryControllerTest,IsNotRecreatedForSameWebContents)94 TEST_F(AddressAccessoryControllerTest, IsNotRecreatedForSameWebContents) {
95   AddressAccessoryControllerImpl* initial_controller =
96       AddressAccessoryControllerImpl::FromWebContents(web_contents());
97   EXPECT_NE(nullptr, initial_controller);
98   AddressAccessoryControllerImpl::CreateForWebContents(web_contents());
99   EXPECT_EQ(AddressAccessoryControllerImpl::FromWebContents(web_contents()),
100             initial_controller);
101 }
102 
TEST_F(AddressAccessoryControllerTest,RefreshSuggestionsCallsUI)103 TEST_F(AddressAccessoryControllerTest, RefreshSuggestionsCallsUI) {
104   AutofillProfile canadian = test::GetFullValidProfileForCanada();
105   personal_data_manager()->AddProfile(canadian);
106 
107   AccessorySheetData result(AccessoryTabType::PASSWORDS, base::string16());
108   EXPECT_CALL(mock_manual_filling_controller_, RefreshSuggestions(_))
109       .WillOnce(SaveArg<0>(&result));
110 
111   controller()->RefreshSuggestions();
112 
113   ASSERT_EQ(
114       result,
115       AddressAccessorySheetDataBuilder(base::string16())
116           .AddUserInfo()
117           .AppendSimpleField(canadian.GetRawInfo(ServerFieldType::NAME_FULL))
118           .AppendSimpleField(canadian.GetRawInfo(ServerFieldType::COMPANY_NAME))
119           .AppendSimpleField(
120               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_LINE1))
121           .AppendSimpleField(
122               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_LINE2))
123           .AppendSimpleField(
124               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_ZIP))
125           .AppendSimpleField(
126               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_CITY))
127           .AppendSimpleField(
128               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_STATE))
129           .AppendSimpleField(
130               canadian.GetRawInfo(ServerFieldType::ADDRESS_HOME_COUNTRY))
131           .AppendSimpleField(
132               canadian.GetRawInfo(ServerFieldType::PHONE_HOME_WHOLE_NUMBER))
133           .AppendSimpleField(
134               canadian.GetRawInfo(ServerFieldType::EMAIL_ADDRESS))
135           .Build());
136 }
137 
TEST_F(AddressAccessoryControllerTest,ProvidesEmptySuggestionsMessage)138 TEST_F(AddressAccessoryControllerTest, ProvidesEmptySuggestionsMessage) {
139   AccessorySheetData result(AccessoryTabType::PASSWORDS, base::string16());
140   EXPECT_CALL(mock_manual_filling_controller_, RefreshSuggestions(_))
141       .WillOnce(SaveArg<0>(&result));
142 
143   controller()->RefreshSuggestions();
144 
145   ASSERT_EQ(result,
146             AddressAccessorySheetDataBuilder(addresses_empty_str()).Build());
147 }
148 
TEST_F(AddressAccessoryControllerTest,TriggersRefreshWhenDataChanges)149 TEST_F(AddressAccessoryControllerTest, TriggersRefreshWhenDataChanges) {
150   AccessorySheetData result(AccessoryTabType::PASSWORDS, base::string16());
151   EXPECT_CALL(mock_manual_filling_controller_, RefreshSuggestions(_))
152       .WillRepeatedly(SaveArg<0>(&result));
153 
154   // A refresh without data stores an empty sheet and registers an observer.
155   controller()->RefreshSuggestions();
156   ASSERT_EQ(result,
157             AddressAccessorySheetDataBuilder(addresses_empty_str()).Build());
158 
159   // When new data is added, a refresh is automatically triggered.
160   AutofillProfile email = test::GetIncompleteProfile2();
161   personal_data_manager()->AddProfile(email);
162   ASSERT_EQ(result, AddressAccessorySheetDataBuilder(base::string16())
163                         .AddUserInfo()
164                         /*name full:*/
165                         .AppendSimpleField(base::string16())
166                         /*company name:*/
167                         .AppendSimpleField(base::string16())
168                         /*address line1:*/
169                         .AppendSimpleField(base::string16())
170                         /*address line2:*/
171                         .AppendSimpleField(base::string16())
172                         /*address zip:*/
173                         .AppendSimpleField(base::string16())
174                         /*address city:*/
175                         .AppendSimpleField(base::string16())
176                         /*address state:*/
177                         .AppendSimpleField(base::string16())
178                         /*address country:*/
179                         .AppendSimpleField(base::string16())
180                         /*phone number:*/.AppendSimpleField(base::string16())
181                         .AppendSimpleField(
182                             email.GetRawInfo(ServerFieldType::EMAIL_ADDRESS))
183                         .Build());
184 }
185 
186 }  // namespace autofill
187