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