OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 <vector> | |
6 | |
7 #include "base/compiler_specific.h" | |
8 #include "base/string16.h" | |
9 #include "chrome/browser/autofill/autofill_manager.h" | |
10 #include "chrome/browser/autofill/test_autofill_external_delegate.h" | |
11 #include "chrome/browser/autofill/test_autofill_manager_delegate.h" | |
12 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | |
13 #include "chrome/test/base/testing_profile.h" | |
14 #include "components/autofill/common/form_data.h" | |
15 #include "components/autofill/common/form_field_data.h" | |
16 #include "content/public/test/test_browser_thread.h" | |
17 #include "testing/gmock/include/gmock/gmock.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" | |
20 #include "ui/gfx/rect.h" | |
21 | |
22 using content::BrowserThread; | |
23 using testing::_; | |
24 using WebKit::WebAutofillClient; | |
25 | |
26 namespace { | |
27 | |
28 // A constant value to use as the Autofill query ID. | |
29 const int kQueryId = 5; | |
30 | |
31 // A constant value to use as an Autofill profile ID. | |
32 const int kAutofillProfileId = 1; | |
33 | |
34 class MockAutofillExternalDelegate : public AutofillExternalDelegate { | |
35 public: | |
36 MockAutofillExternalDelegate(content::WebContents* web_contents, | |
37 AutofillManager* autofill_manger) | |
38 : AutofillExternalDelegate(web_contents, autofill_manger) {} | |
39 | |
40 ~MockAutofillExternalDelegate() {} | |
41 | |
42 MOCK_METHOD0(ClearPreviewedForm, void()); | |
43 | |
44 private: | |
45 DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate); | |
46 }; | |
47 | |
48 class MockAutofillManagerDelegate | |
49 : public autofill::TestAutofillManagerDelegate { | |
50 public: | |
51 MockAutofillManagerDelegate() {} | |
52 | |
53 MOCK_METHOD6(ShowAutofillPopup, | |
54 void(const gfx::RectF& element_bounds, | |
55 const std::vector<string16>& values, | |
56 const std::vector<string16>& labels, | |
57 const std::vector<string16>& icons, | |
58 const std::vector<int>& identifiers, | |
59 AutofillPopupDelegate* delegate)); | |
60 | |
61 MOCK_METHOD0(HideAutofillPopup, void()); | |
62 | |
63 private: | |
64 DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate); | |
65 }; | |
66 | |
67 class MockAutofillManager : public AutofillManager { | |
68 public: | |
69 MockAutofillManager(content::WebContents* web_contents, | |
70 MockAutofillManagerDelegate* delegate) | |
71 // Force to use the constructor designated for unit test, but we don't | |
72 // really need personal_data in this test so we pass a NULL pointer. | |
73 : AutofillManager(web_contents, delegate, NULL) { | |
74 } | |
75 virtual ~MockAutofillManager() {} | |
76 | |
77 MOCK_METHOD4(OnFillAutofillFormData, | |
78 void(int query_id, | |
79 const FormData& form, | |
80 const FormFieldData& field, | |
81 int unique_id)); | |
82 | |
83 private: | |
84 DISALLOW_COPY_AND_ASSIGN(MockAutofillManager); | |
85 }; | |
86 | |
87 } // namespace | |
88 | |
89 class AutofillExternalDelegateUnitTest | |
90 : public ChromeRenderViewHostTestHarness { | |
91 public: | |
92 AutofillExternalDelegateUnitTest() | |
93 : ui_thread_(BrowserThread::UI, &message_loop_) {} | |
94 virtual ~AutofillExternalDelegateUnitTest() {} | |
95 | |
96 protected: | |
97 // Issue an OnQuery call with the given |query_id|. | |
98 void IssueOnQuery(int query_id) { | |
99 const FormData form; | |
100 FormFieldData field; | |
101 field.is_focusable = true; | |
102 field.should_autocomplete = true; | |
103 const gfx::RectF element_bounds; | |
104 | |
105 external_delegate_->OnQuery(query_id, form, field, element_bounds, false); | |
106 } | |
107 | |
108 MockAutofillManagerDelegate manager_delegate_; | |
109 scoped_ptr<MockAutofillManager> autofill_manager_; | |
110 scoped_ptr<testing::NiceMock<MockAutofillExternalDelegate> > | |
111 external_delegate_; | |
112 | |
113 private: | |
114 virtual void SetUp() OVERRIDE { | |
115 ChromeRenderViewHostTestHarness::SetUp(); | |
116 autofill_manager_.reset( | |
117 new MockAutofillManager(web_contents(), &manager_delegate_)); | |
118 external_delegate_.reset( | |
119 new testing::NiceMock<MockAutofillExternalDelegate>( | |
120 web_contents(), | |
121 autofill_manager_.get())); | |
122 } | |
123 | |
124 virtual void TearDown() OVERRIDE { | |
125 // Order of destruction is important as AutofillManager relies on | |
126 // PersonalDataManager to be around when it gets destroyed. Also, a real | |
127 // AutofillManager is tied to the lifetime of the WebContents, so it must | |
128 // be destroyed at the destruction of the WebContents. | |
129 autofill_manager_.reset(); | |
130 external_delegate_.reset(); | |
131 ChromeRenderViewHostTestHarness::TearDown(); | |
132 } | |
133 | |
134 content::TestBrowserThread ui_thread_; | |
135 | |
136 DISALLOW_COPY_AND_ASSIGN(AutofillExternalDelegateUnitTest); | |
137 }; | |
138 | |
139 // Test that our external delegate called the virtual methods at the right time. | |
140 TEST_F(AutofillExternalDelegateUnitTest, TestExternalDelegateVirtualCalls) { | |
141 IssueOnQuery(kQueryId); | |
142 | |
143 // The enums must be cast to ints to prevent compile errors on linux_rel. | |
144 EXPECT_CALL(manager_delegate_, | |
145 ShowAutofillPopup( | |
146 _, _, _, _, | |
147 testing::ElementsAre( | |
148 kAutofillProfileId, | |
149 static_cast<int>(WebAutofillClient::MenuItemIDSeparator), | |
150 static_cast<int>( | |
151 WebAutofillClient::MenuItemIDAutofillOptions)), | |
152 external_delegate_.get())); | |
153 | |
154 // This should call ShowAutofillPopup. | |
155 std::vector<string16> autofill_item; | |
156 autofill_item.push_back(string16()); | |
157 std::vector<int> autofill_ids; | |
158 autofill_ids.push_back(kAutofillProfileId); | |
159 external_delegate_->OnSuggestionsReturned(kQueryId, | |
160 autofill_item, | |
161 autofill_item, | |
162 autofill_item, | |
163 autofill_ids); | |
164 | |
165 // Called by DidAutofillSuggestions, add expectation to remove warning. | |
166 EXPECT_CALL(*autofill_manager_, OnFillAutofillFormData(_, _, _, _)); | |
167 | |
168 EXPECT_CALL(manager_delegate_, HideAutofillPopup()); | |
169 | |
170 // This should trigger a call to hide the popup since we've selected an | |
171 // option. | |
172 external_delegate_->DidAcceptSuggestion(autofill_item[0], autofill_ids[0]); | |
173 } | |
174 | |
175 // Test that data list elements for a node will appear in the Autofill popup. | |
176 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateDataList) { | |
177 IssueOnQuery(kQueryId); | |
178 | |
179 std::vector<string16> data_list_items; | |
180 data_list_items.push_back(string16()); | |
181 std::vector<int> data_list_ids; | |
182 data_list_ids.push_back(WebAutofillClient::MenuItemIDDataListEntry); | |
183 | |
184 external_delegate_->SetCurrentDataListValues(data_list_items, | |
185 data_list_items, | |
186 data_list_items, | |
187 data_list_ids); | |
188 | |
189 // The enums must be cast to ints to prevent compile errors on linux_rel. | |
190 EXPECT_CALL(manager_delegate_, | |
191 ShowAutofillPopup( | |
192 _, _, _, _, | |
193 testing::ElementsAre( | |
194 static_cast<int>( | |
195 WebAutofillClient::MenuItemIDDataListEntry), | |
196 static_cast<int>(WebAutofillClient::MenuItemIDSeparator), | |
197 kAutofillProfileId, | |
198 static_cast<int>(WebAutofillClient::MenuItemIDSeparator), | |
199 static_cast<int>( | |
200 WebAutofillClient::MenuItemIDAutofillOptions)), | |
201 external_delegate_.get())); | |
202 | |
203 // This should call ShowAutofillPopup. | |
204 std::vector<string16> autofill_item; | |
205 autofill_item.push_back(string16()); | |
206 std::vector<int> autofill_ids; | |
207 autofill_ids.push_back(kAutofillProfileId); | |
208 external_delegate_->OnSuggestionsReturned(kQueryId, | |
209 autofill_item, | |
210 autofill_item, | |
211 autofill_item, | |
212 autofill_ids); | |
213 | |
214 // Try calling OnSuggestionsReturned with no Autofill values and ensure | |
215 // the datalist items are still shown. | |
216 // The enum must be cast to an int to prevent compile errors on linux_rel. | |
217 EXPECT_CALL(manager_delegate_, | |
218 ShowAutofillPopup( | |
219 _, _, _, _, | |
220 testing::ElementsAre( | |
221 static_cast<int>( | |
222 WebAutofillClient::MenuItemIDDataListEntry)), | |
223 external_delegate_.get())); | |
224 | |
225 autofill_item = std::vector<string16>(); | |
226 autofill_ids = std::vector<int>(); | |
227 external_delegate_->OnSuggestionsReturned(kQueryId, | |
228 autofill_item, | |
229 autofill_item, | |
230 autofill_item, | |
231 autofill_ids); | |
232 } | |
233 | |
234 // Test that the Autofill delegate doesn't try and fill a form with a | |
235 // negative unique id. | |
236 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateInvalidUniqueId) { | |
237 // Ensure it doesn't try to preview the negative id. | |
238 EXPECT_CALL(*autofill_manager_, OnFillAutofillFormData(_, _, _, _)).Times(0); | |
239 EXPECT_CALL(*external_delegate_, ClearPreviewedForm()).Times(1); | |
240 external_delegate_->DidSelectSuggestion(-1); | |
241 | |
242 // Ensure it doesn't try to fill the form in with the negative id. | |
243 EXPECT_CALL(manager_delegate_, HideAutofillPopup()); | |
244 EXPECT_CALL(*autofill_manager_, OnFillAutofillFormData(_, _, _, _)).Times(0); | |
245 external_delegate_->DidAcceptSuggestion(string16(), -1); | |
246 } | |
247 | |
248 // Test that the ClearPreview IPC is only sent the form was being previewed | |
249 // (i.e. it isn't autofilling a password). | |
250 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearPreviewedForm) { | |
251 // Called by DidSelectSuggestion, add expectation to remove warning. | |
252 EXPECT_CALL(*autofill_manager_, OnFillAutofillFormData(_, _, _, _)); | |
253 | |
254 // Ensure selecting a new password entries or Autofill entries will | |
255 // cause any previews to get cleared. | |
256 EXPECT_CALL(*external_delegate_, ClearPreviewedForm()).Times(1); | |
257 external_delegate_->DidSelectSuggestion( | |
258 WebAutofillClient::MenuItemIDPasswordEntry); | |
259 | |
260 EXPECT_CALL(*external_delegate_, ClearPreviewedForm()).Times(1); | |
261 external_delegate_->DidSelectSuggestion(1); | |
262 } | |
263 | |
264 // Test that the popup is hidden once we are done editing the autofill field. | |
265 TEST_F(AutofillExternalDelegateUnitTest, | |
266 ExternalDelegateHidePopupAfterEditing) { | |
267 EXPECT_CALL(manager_delegate_, ShowAutofillPopup(_, _, _, _, _, _)); | |
268 autofill::GenerateTestAutofillPopup(external_delegate_.get()); | |
269 | |
270 EXPECT_CALL(manager_delegate_, HideAutofillPopup()); | |
271 external_delegate_->DidEndTextFieldEditing(); | |
272 } | |
273 | |
274 // Test that the popup is marked as visible after recieving password | |
275 // suggestions. | |
276 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegatePasswordSuggestions) { | |
277 std::vector<string16> suggestions; | |
278 suggestions.push_back(string16()); | |
279 | |
280 FormFieldData field; | |
281 field.is_focusable = true; | |
282 field.should_autocomplete = true; | |
283 const gfx::RectF element_bounds; | |
284 | |
285 // The enums must be cast to ints to prevent compile errors on linux_rel. | |
286 EXPECT_CALL(manager_delegate_, | |
287 ShowAutofillPopup( | |
288 _, _, _, _, | |
289 testing::ElementsAre( | |
290 static_cast<int>( | |
291 WebAutofillClient::MenuItemIDPasswordEntry)), | |
292 external_delegate_.get())); | |
293 | |
294 external_delegate_->OnShowPasswordSuggestions(suggestions, | |
295 field, | |
296 element_bounds); | |
297 | |
298 // Called by DidAutofillSuggestions, add expectation to remove warning. | |
299 EXPECT_CALL(*autofill_manager_, OnFillAutofillFormData(_, _, _, _)); | |
300 | |
301 EXPECT_CALL(manager_delegate_, HideAutofillPopup()); | |
302 | |
303 // This should trigger a call to hide the popup since | |
304 // we've selected an option. | |
305 external_delegate_->DidAcceptSuggestion( | |
306 suggestions[0], | |
307 WebAutofillClient::MenuItemIDPasswordEntry); | |
308 } | |
OLD | NEW |