Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc

Issue 1931043002: Remove requestAutocomplete (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 <stddef.h>
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/test/histogram_tester.h"
16 #include "base/time/time.h"
17 #include "build/build_config.h"
18 #include "chrome/browser/autofill/personal_data_manager_factory.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/signin/account_tracker_service_factory.h"
21 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
23 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
24 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
25 #include "chrome/browser/ui/autofill/autofill_dialog_view_tester.h"
26 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
27 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
28 #include "chrome/browser/ui/autofill/mock_address_validator.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_tabstrip.h"
31 #include "chrome/browser/ui/tabs/tab_strip_model.h"
32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "chrome/test/base/in_process_browser_test.h"
36 #include "chrome/test/base/ui_test_utils.h"
37 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
38 #include "components/autofill/core/browser/autofill_metrics.h"
39 #include "components/autofill/core/browser/autofill_test_utils.h"
40 #include "components/autofill/core/browser/test_personal_data_manager.h"
41 #include "components/autofill/core/browser/validation.h"
42 #include "components/autofill/core/common/autofill_constants.h"
43 #include "components/autofill/core/common/autofill_switches.h"
44 #include "components/autofill/core/common/form_data.h"
45 #include "components/autofill/core/common/form_field_data.h"
46 #include "components/prefs/pref_service.h"
47 #include "components/signin/core/browser/account_tracker_service.h"
48 #include "components/signin/core/browser/signin_manager.h"
49 #include "content/public/browser/browser_thread.h"
50 #include "content/public/browser/interstitial_page.h"
51 #include "content/public/browser/navigation_details.h"
52 #include "content/public/browser/navigation_entry.h"
53 #include "content/public/browser/notification_service.h"
54 #include "content/public/browser/notification_types.h"
55 #include "content/public/browser/page_navigator.h"
56 #include "content/public/browser/web_contents.h"
57 #include "content/public/browser/web_contents_delegate.h"
58 #include "content/public/common/content_switches.h"
59 #include "content/public/common/referrer.h"
60 #include "content/public/common/url_constants.h"
61 #include "content/public/test/browser_test_utils.h"
62 #include "content/public/test/test_utils.h"
63 #include "google_apis/gaia/google_service_auth_error.h"
64 #include "net/test/embedded_test_server/embedded_test_server.h"
65 #include "testing/gmock/include/gmock/gmock.h"
66 #include "testing/gtest/include/gtest/gtest.h"
67 #include "third_party/WebKit/public/web/WebInputEvent.h"
68 #include "ui/base/page_transition_types.h"
69 #include "ui/base/window_open_disposition.h"
70 #include "url/gurl.h"
71
72 #if defined(OS_WIN)
73 #include "base/win/windows_version.h"
74 #elif defined(OS_MACOSX)
75 #include "base/mac/scoped_nsautorelease_pool.h"
76 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
77 #endif
78
79 using base::ASCIIToUTF16;
80
81 namespace autofill {
82
83 namespace {
84
85 using testing::Return;
86 using testing::_;
87
88 void MockCallback(AutofillClient::RequestAutocompleteResult,
89 const base::string16& message,
90 const FormStructure*) {
91 }
92
93 class TestAutofillDialogController : public AutofillDialogControllerImpl {
94 public:
95 TestAutofillDialogController(
96 content::WebContents* contents,
97 const FormData& form_data,
98 scoped_refptr<content::MessageLoopRunner> runner)
99 : AutofillDialogControllerImpl(contents,
100 form_data,
101 form_data.origin,
102 base::Bind(&MockCallback)),
103 message_loop_runner_(runner),
104 use_validation_(false),
105 weak_ptr_factory_(this) {
106 Profile* profile =
107 Profile::FromBrowserContext(contents->GetBrowserContext());
108 test_manager_.Init(
109 NULL,
110 profile->GetPrefs(),
111 AccountTrackerServiceFactory::GetForProfile(profile),
112 SigninManagerFactory::GetForProfile(profile),
113 false);
114 }
115
116 ~TestAutofillDialogController() override {}
117
118 GURL FakeSignInUrl() const {
119 return GURL(chrome::kChromeUIVersionURL);
120 }
121
122 void ViewClosed() override {
123 message_loop_runner_->Quit();
124 AutofillDialogControllerImpl::ViewClosed();
125 }
126
127 base::string16 InputValidityMessage(
128 DialogSection section,
129 ServerFieldType type,
130 const base::string16& value) override {
131 if (!use_validation_)
132 return base::string16();
133 return AutofillDialogControllerImpl::InputValidityMessage(
134 section, type, value);
135 }
136
137 ValidityMessages InputsAreValid(
138 DialogSection section,
139 const FieldValueMap& inputs) override {
140 if (!use_validation_)
141 return ValidityMessages();
142 return AutofillDialogControllerImpl::InputsAreValid(section, inputs);
143 }
144
145 // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
146 // TODO(estade): test that the view defaults to saving to Chrome.
147 bool ShouldOfferToSaveInChrome() const override {
148 return true;
149 }
150
151 // Increase visibility for testing.
152 using AutofillDialogControllerImpl::view;
153 using AutofillDialogControllerImpl::popup_input_type;
154
155 MOCK_METHOD0(LoadRiskFingerprintData, void());
156
157 std::vector<DialogNotification> CurrentNotifications() override {
158 return notifications_;
159 }
160
161 void set_notifications(const std::vector<DialogNotification>& notifications) {
162 notifications_ = notifications;
163 }
164
165 TestPersonalDataManager* GetTestingManager() {
166 return &test_manager_;
167 }
168
169 MockAddressValidator* GetMockValidator() {
170 return &mock_validator_;
171 }
172
173 using AutofillDialogControllerImpl::IsEditingExistingData;
174 using AutofillDialogControllerImpl::IsManuallyEditingSection;
175
176 void set_use_validation(bool use_validation) {
177 use_validation_ = use_validation;
178 }
179
180 base::WeakPtr<TestAutofillDialogController> AsWeakPtr() {
181 return weak_ptr_factory_.GetWeakPtr();
182 }
183
184 protected:
185 PersonalDataManager* GetManager() const override {
186 return &const_cast<TestAutofillDialogController*>(this)->test_manager_;
187 }
188
189 AddressValidator* GetValidator() override {
190 return &mock_validator_;
191 }
192
193 private:
194 TestPersonalDataManager test_manager_;
195 testing::NiceMock<MockAddressValidator> mock_validator_;
196 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
197 bool use_validation_;
198
199 // A list of notifications to show in the notification area of the dialog.
200 // This is used to control what |CurrentNotifications()| returns for testing.
201 std::vector<DialogNotification> notifications_;
202
203 // Allows generation of WeakPtrs, so controller liveness can be tested.
204 base::WeakPtrFactory<TestAutofillDialogController> weak_ptr_factory_;
205
206 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
207 };
208
209 // This is a copy of ui_test_utils::UrlLoadObserver, except it observes
210 // NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
211 // that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
212 // before LOAD_STOP, and the controller deletes the web contents after receiving
213 // the former, we will sometimes fail to observe a LOAD_STOP.
214 // TODO(estade): Should the controller observe LOAD_STOP instead?
215 class NavEntryCommittedObserver : public content::WindowedNotificationObserver {
216 public:
217 NavEntryCommittedObserver(const GURL& url,
218 const content::NotificationSource& source)
219 : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED,
220 source),
221 url_(url) {}
222
223 ~NavEntryCommittedObserver() override {}
224
225 // content::NotificationObserver:
226 void Observe(int type,
227 const content::NotificationSource& source,
228 const content::NotificationDetails& details) override {
229 content::LoadCommittedDetails* load_details =
230 content::Details<content::LoadCommittedDetails>(details).ptr();
231 if (load_details->entry->GetVirtualURL() != url_)
232 return;
233
234 WindowedNotificationObserver::Observe(type, source, details);
235 }
236
237 private:
238 GURL url_;
239
240 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
241 };
242
243 } // namespace
244
245 class AutofillDialogControllerTest : public InProcessBrowserTest {
246 public:
247 AutofillDialogControllerTest() : controller_(NULL) {}
248 ~AutofillDialogControllerTest() override {}
249
250 void SetUpCommandLine(base::CommandLine* command_line) override {
251 command_line->AppendSwitch(::switches::kReduceSecurityForTesting);
252 }
253
254 void SetUpOnMainThread() override {
255 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
256 InitializeController();
257 }
258
259 protected:
260 bool SectionHasField(DialogSection section, ServerFieldType type) {
261 const DetailInputs& fields =
262 controller()->RequestedFieldsForSection(section);
263 for (size_t i = 0; i < fields.size(); ++i) {
264 if (type == fields[i].type)
265 return true;
266 }
267 return false;
268 }
269
270 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
271 // loop. It also drains the NSAutoreleasePool.
272 void CycleRunLoops() {
273 content::RunAllPendingInMessageLoop();
274 #if defined(OS_MACOSX)
275 chrome::testing::NSRunLoopRunAllPending();
276 AutoreleasePool()->Recycle();
277 #endif
278 }
279
280 void InitializeControllerWithoutShowing() {
281 if (controller_)
282 controller_->Hide();
283
284 FormData form;
285 form.name = ASCIIToUTF16("TestForm");
286
287 FormFieldData field;
288 field.autocomplete_attribute = "shipping tel";
289 form.fields.push_back(field);
290
291 FormFieldData cc;
292 cc.autocomplete_attribute = "cc-number";
293 form.fields.push_back(cc);
294
295 message_loop_runner_ = new content::MessageLoopRunner;
296 controller_ = new TestAutofillDialogController(
297 GetActiveWebContents(),
298 form,
299 message_loop_runner_);
300 }
301
302 void InitializeController() {
303 InitializeControllerWithoutShowing();
304 controller_->Show();
305 CycleRunLoops(); // Ensures dialog is fully visible.
306 }
307
308 content::WebContents* GetActiveWebContents() {
309 return browser()->tab_strip_model()->GetActiveWebContents();
310 }
311
312 content::RenderViewHost* GetRenderViewHost() {
313 return GetActiveWebContents()->GetRenderViewHost();
314 }
315
316 std::unique_ptr<AutofillDialogViewTester> GetViewTester() {
317 return AutofillDialogViewTester::For(controller()->view());
318 }
319
320 TestAutofillDialogController* controller() { return controller_; }
321
322 void RunMessageLoop() {
323 message_loop_runner_->Run();
324 }
325
326 // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
327 // <form>|form_inner_html|</form>. After loading, emulates a click event on
328 // the page as requestAutocomplete() must be in response to a user gesture.
329 // Returns the |AutofillDialogControllerImpl| created by this invocation.
330 AutofillDialogControllerImpl* SetUpHtmlAndInvoke(
331 const std::string& form_inner_html) {
332 content::WebContents* contents = GetActiveWebContents();
333 ChromeAutofillClient* client =
334 ChromeAutofillClient::FromWebContents(contents);
335 CHECK(!client->GetDialogControllerForTesting());
336
337 ui_test_utils::NavigateToURL(
338 browser(), GURL(std::string("data:text/html,") +
339 "<!doctype html>"
340 "<html>"
341 "<body>"
342 "<form>" + form_inner_html + "</form>"
343 "<script>"
344 "var invalidEvents = [];"
345 "function recordInvalid(e) {"
346 "if (e.type != 'invalid') throw 'only invalid events allowed';"
347 "invalidEvents.push(e);"
348 "}"
349 "function send(msg) {"
350 "domAutomationController.setAutomationId(0);"
351 "domAutomationController.send(msg);"
352 "}"
353 "document.forms[0].onautocompleteerror = function(e) {"
354 "send('error: ' + e.reason);"
355 "};"
356 "document.forms[0].onautocomplete = function() {"
357 "send('success');"
358 "};"
359 "window.onclick = function() {"
360 "var inputs = document.forms[0].querySelectorAll('input');"
361 "for (var i = 0; i < inputs.length; ++i) {"
362 "inputs[i].oninvalid = recordInvalid;"
363 "}"
364 "document.forms[0].requestAutocomplete();"
365 "send('clicked');"
366 "};"
367 "function loadIframe() {"
368 " var iframe = document.createElement('iframe');"
369 " iframe.onload = function() {"
370 " send('iframe loaded');"
371 " };"
372 " iframe.src = 'about:blank';"
373 " document.body.appendChild(iframe);"
374 "}"
375 "function getValueForFieldOfType(type) {"
376 " var fields = document.getElementsByTagName('input');"
377 " for (var i = 0; i < fields.length; i++) {"
378 " if (fields[i].autocomplete == type) {"
379 " send(fields[i].value);"
380 " return;"
381 " }"
382 " }"
383 " send('');"
384 "};"
385 "</script>"
386 "</body>"
387 "</html>"));
388
389 InitiateDialog();
390 AutofillDialogControllerImpl* controller =
391 static_cast<AutofillDialogControllerImpl*>(
392 client->GetDialogControllerForTesting());
393 return controller;
394 }
395
396 // Loads an html page on a provided server, the causes it to launch rAc.
397 // Returns whether rAc succesfully launched.
398 bool RunTestPage(const net::EmbeddedTestServer& server) {
399 GURL url = server.GetURL("/request_autocomplete/test_page.html");
400 ui_test_utils::NavigateToURL(browser(), url);
401
402 // Pass through the broken SSL interstitial, if any.
403 content::WebContents* contents = GetActiveWebContents();
404 content::InterstitialPage* interstitial_page =
405 contents->GetInterstitialPage();
406 if (interstitial_page) {
407 ui_test_utils::UrlLoadObserver observer(
408 url,
409 content::Source<content::NavigationController>(
410 &contents->GetController()));
411 interstitial_page->Proceed();
412 observer.Wait();
413 }
414
415 InitiateDialog();
416
417 ChromeAutofillClient* client =
418 ChromeAutofillClient::FromWebContents(contents);
419 AutofillDialogControllerImpl* controller =
420 static_cast<AutofillDialogControllerImpl*>(
421 client->GetDialogControllerForTesting());
422 return !!controller;
423 }
424
425 void RunTestPageInIframe(const net::EmbeddedTestServer& server) {
426 InitializeDOMMessageQueue();
427 GURL iframe_url = server.GetURL("/request_autocomplete/test_page.html");
428
429 ui_test_utils::NavigateToURL(
430 browser(), GURL(std::string("data:text/html,") +
431 "<!doctype html>"
432 "<html>"
433 "<body>"
434 "<iframe style='position: fixed;"
435 "height: 100%;"
436 "width: 100%;'"
437 "id='racFrame'></iframe>"
438 "<script>"
439 "function send(msg) {"
440 "domAutomationController.setAutomationId(0);"
441 "domAutomationController.send(msg);"
442 "}"
443 "var racFrame = document.getElementById('racFrame');"
444 "racFrame.onload = function() {"
445 "send('iframe loaded');"
446 "};"
447 "racFrame.src = \"" + iframe_url.spec() + "\";"
448 "function navigateFrame() {"
449 "racFrame.src = 'about:blank';"
450 "}"
451 "</script>"
452 "</body>"
453 "</html>"));
454
455 ChromeAutofillClient* client =
456 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
457 ExpectDomMessage("iframe loaded");
458 EXPECT_FALSE(client->GetDialogControllerForTesting());
459 InitiateDialog();
460 EXPECT_TRUE(client->GetDialogControllerForTesting());
461 }
462
463 // Wait for a message from the DOM automation controller (from JS in the
464 // page). Requires |SetUpHtmlAndInvoke()| be called first.
465 void ExpectDomMessage(const std::string& expected) {
466 std::string message;
467 ASSERT_TRUE(dom_message_queue_->WaitForMessage(&message));
468 dom_message_queue_->ClearQueue();
469 EXPECT_EQ("\"" + expected + "\"", message);
470 }
471
472 void InitiateDialog() {
473 InitializeDOMMessageQueue();
474 // Triggers the onclick handler which invokes requestAutocomplete().
475 content::WebContents* contents = GetActiveWebContents();
476 content::SimulateMouseClick(contents, 0, blink::WebMouseEvent::ButtonLeft);
477 ExpectDomMessage("clicked");
478 }
479
480 void InitializeDOMMessageQueue() {
481 dom_message_queue_.reset(new content::DOMMessageQueue);
482 }
483
484 // Returns the value filled into the first field with autocomplete attribute
485 // equal to |autocomplete_type|, or an empty string if there is no such field.
486 std::string GetValueForHTMLFieldOfType(const std::string& autocomplete_type) {
487 std::string script = "getValueForFieldOfType('" + autocomplete_type + "');";
488 std::string result;
489 EXPECT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
490 script,
491 &result));
492 return result;
493 }
494
495 void AddCreditcardToProfile(Profile* profile, const CreditCard& card) {
496 PersonalDataManagerFactory::GetForProfile(profile)->AddCreditCard(card);
497 WaitForWebDB();
498 }
499
500 void AddAutofillProfileToProfile(Profile* profile,
501 const AutofillProfile& autofill_profile) {
502 PersonalDataManagerFactory::GetForProfile(profile)->AddProfile(
503 autofill_profile);
504 WaitForWebDB();
505 }
506
507 private:
508 void WaitForWebDB() {
509 content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
510 }
511
512 TestAutofillDialogController* controller_; // Weak reference.
513 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
514 std::unique_ptr<content::DOMMessageQueue> dom_message_queue_;
515
516 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
517 };
518
519 // Submit the form data.
520 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
521 base::HistogramTester histogram;
522 AddCreditcardToProfile(controller()->profile(),
523 test::GetVerifiedCreditCard());
524 AddAutofillProfileToProfile(controller()->profile(),
525 test::GetVerifiedProfile());
526 std::unique_ptr<AutofillDialogViewTester> view =
527 AutofillDialogViewTester::For(controller()->view());
528 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
529 GetViewTester()->SubmitForTesting();
530 RunMessageLoop();
531
532 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 1);
533 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 0);
534 }
535
536 // Cancel out of the dialog.
537 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) {
538 base::HistogramTester histogram;
539 GetViewTester()->CancelForTesting();
540 RunMessageLoop();
541
542 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
543 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
544 histogram.ExpectUniqueSample(
545 "RequestAutocomplete.DismissalState",
546 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS, 1);
547 }
548
549 // Take some other action that dismisses the dialog.
550 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) {
551 base::HistogramTester histogram;
552 controller()->Hide();
553
554 RunMessageLoop();
555
556 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
557 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
558 histogram.ExpectUniqueSample(
559 "RequestAutocomplete.DismissalState",
560 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS, 1);
561 }
562
563 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CancelWithSuggestions) {
564 base::HistogramTester histogram;
565
566 CreditCard card(test::GetVerifiedCreditCard());
567 controller()->GetTestingManager()->AddTestingCreditCard(&card);
568 AutofillProfile profile(test::GetVerifiedProfile());
569 controller()->GetTestingManager()->AddTestingProfile(&profile);
570
571 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
572 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
573 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
574
575 GetViewTester()->CancelForTesting();
576 RunMessageLoop();
577
578 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
579 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
580 histogram.ExpectUniqueSample("RequestAutocomplete.DismissalState",
581 AutofillMetrics::DIALOG_CANCELED_NO_EDITS, 1);
582 }
583
584 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AcceptWithSuggestions) {
585 base::HistogramTester histogram;
586 CreditCard card(test::GetVerifiedCreditCard());
587 controller()->GetTestingManager()->AddTestingCreditCard(&card);
588 AutofillProfile profile(test::GetVerifiedProfile());
589 controller()->GetTestingManager()->AddTestingProfile(&profile);
590
591 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
592 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
593 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
594
595 GetViewTester()->SubmitForTesting();
596 RunMessageLoop();
597
598 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 1);
599 histogram.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 0);
600 histogram.ExpectUniqueSample(
601 "RequestAutocomplete.DismissalState",
602 AutofillMetrics::DIALOG_ACCEPTED_EXISTING_AUTOFILL_DATA, 1);
603 }
604
605 // Ensure that Hide() will only destroy the controller object after the
606 // message loop has run. Otherwise, there may be read-after-free issues
607 // during some tests.
608 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, DeferredDestruction) {
609 base::WeakPtr<TestAutofillDialogController> weak_ptr =
610 controller()->AsWeakPtr();
611 EXPECT_TRUE(weak_ptr.get());
612
613 controller()->Hide();
614 EXPECT_TRUE(weak_ptr.get());
615
616 RunMessageLoop();
617 EXPECT_FALSE(weak_ptr.get());
618 }
619
620 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
621 AutofillProfile full_profile(test::GetFullProfile());
622 const base::string16 formatted_phone(ASCIIToUTF16("+1 (310) 555 1234"));
623 full_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, formatted_phone);
624 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
625
626 // Dialog is already asking for a new billing address.
627 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
628
629 // Select "Add new shipping address...".
630 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_SHIPPING);
631 model->ActivatedAt(model->GetItemCount() - 2);
632 ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
633
634 // Enter something in a shipping input.
635 const DetailInputs& inputs =
636 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
637 const ServerFieldType triggering_type = inputs[0].type;
638 base::string16 value = full_profile.GetRawInfo(triggering_type);
639 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
640 view->SetTextContentsOfInput(triggering_type,
641 value.substr(0, value.size() / 2));
642 view->ActivateInput(triggering_type);
643
644 ASSERT_EQ(triggering_type, controller()->popup_input_type());
645 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
646
647 // All inputs should be filled.
648 AutofillProfileWrapper wrapper(&full_profile);
649 for (size_t i = 0; i < inputs.size(); ++i) {
650 EXPECT_EQ(wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)),
651 view->GetTextContentsOfInput(inputs[i].type));
652
653 // Double check the correct formatting is used for the phone number.
654 if (inputs[i].type == PHONE_HOME_WHOLE_NUMBER)
655 EXPECT_EQ(formatted_phone, view->GetTextContentsOfInput(inputs[i].type));
656 }
657
658 // Inputs from the other section (billing) should be left alone.
659 const DetailInputs& other_section_inputs =
660 controller()->RequestedFieldsForSection(SECTION_BILLING);
661 for (size_t i = 0; i < inputs.size(); ++i) {
662 base::string16 input_value =
663 view->GetTextContentsOfInput(other_section_inputs[i].type);
664 // If there's a combobox, the string should be non-empty.
665 if (controller()->ComboboxModelForAutofillType(
666 other_section_inputs[i].type)) {
667 EXPECT_NE(base::string16(), input_value);
668 } else {
669 EXPECT_EQ(base::string16(), input_value);
670 }
671 }
672
673 // Now simulate some user edits and try again.
674 std::vector<base::string16> expectations;
675 for (size_t i = 0; i < inputs.size(); ++i) {
676 if (controller()->ComboboxModelForAutofillType(inputs[i].type)) {
677 expectations.push_back(base::string16());
678 continue;
679 }
680 base::string16 users_input = i % 2 == 0 ? base::string16()
681 : ASCIIToUTF16("dummy");
682 view->SetTextContentsOfInput(inputs[i].type, users_input);
683 // Empty inputs should be filled, others should be left alone.
684 base::string16 expectation =
685 inputs[i].type == triggering_type || users_input.empty() ?
686 wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)) :
687 users_input;
688 expectations.push_back(expectation);
689 }
690
691 view->SetTextContentsOfInput(triggering_type,
692 value.substr(0, value.size() / 2));
693 view->ActivateInput(triggering_type);
694 ASSERT_EQ(triggering_type, controller()->popup_input_type());
695 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
696
697 for (size_t i = 0; i < inputs.size(); ++i) {
698 if (controller()->ComboboxModelForAutofillType(inputs[i].type))
699 continue;
700 EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i].type));
701 }
702
703 base::HistogramTester histogram;
704 view->SubmitForTesting();
705 histogram.ExpectUniqueSample(
706 "RequestAutocomplete.DismissalState",
707 AutofillMetrics::DIALOG_ACCEPTED_SAVE_TO_AUTOFILL, 1);
708 }
709
710 // Tests that changing the value of a CC expiration date combobox works as
711 // expected when Autofill is used to fill text inputs.
712 //
713 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
714 #if defined(OS_WIN)
715 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
716 #else
717 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
718 #endif
719 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
720 MAYBE_FillComboboxFromAutofill) {
721 CreditCard card1;
722 test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
723 controller()->GetTestingManager()->AddTestingCreditCard(&card1);
724 CreditCard card2;
725 test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017");
726 controller()->GetTestingManager()->AddTestingCreditCard(&card2);
727 AutofillProfile full_profile(test::GetFullProfile());
728 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
729
730 const DetailInputs& inputs =
731 controller()->RequestedFieldsForSection(SECTION_CC);
732 const ServerFieldType triggering_type = inputs[0].type;
733 base::string16 value = card1.GetRawInfo(triggering_type);
734 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
735 view->SetTextContentsOfInput(triggering_type,
736 value.substr(0, value.size() / 2));
737 view->ActivateInput(triggering_type);
738
739 ASSERT_EQ(triggering_type, controller()->popup_input_type());
740 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
741
742 // All inputs should be filled.
743 AutofillCreditCardWrapper wrapper1(&card1);
744 for (size_t i = 0; i < inputs.size(); ++i) {
745 EXPECT_EQ(wrapper1.GetInfo(AutofillType(inputs[i].type)),
746 view->GetTextContentsOfInput(inputs[i].type));
747 }
748
749 // Try again with different data. Only expiration date and the triggering
750 // input should be overwritten.
751 value = card2.GetRawInfo(triggering_type);
752 view->SetTextContentsOfInput(triggering_type,
753 value.substr(0, value.size() / 2));
754 view->ActivateInput(triggering_type);
755 ASSERT_EQ(triggering_type, controller()->popup_input_type());
756 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
757
758 AutofillCreditCardWrapper wrapper2(&card2);
759 for (size_t i = 0; i < inputs.size(); ++i) {
760 const ServerFieldType type = inputs[i].type;
761 if (type == triggering_type ||
762 type == CREDIT_CARD_EXP_MONTH ||
763 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
764 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
765 view->GetTextContentsOfInput(type));
766 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
767 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
768 } else {
769 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
770 view->GetTextContentsOfInput(type));
771 }
772 }
773
774 // Now fill from a profile. It should not overwrite any CC info.
775 const DetailInputs& billing_inputs =
776 controller()->RequestedFieldsForSection(SECTION_BILLING);
777 const ServerFieldType billing_triggering_type = billing_inputs[0].type;
778 value = full_profile.GetRawInfo(triggering_type);
779 view->SetTextContentsOfInput(billing_triggering_type,
780 value.substr(0, value.size() / 2));
781 view->ActivateInput(billing_triggering_type);
782
783 ASSERT_EQ(billing_triggering_type, controller()->popup_input_type());
784 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
785
786 for (size_t i = 0; i < inputs.size(); ++i) {
787 const ServerFieldType type = inputs[i].type;
788 if (type == triggering_type ||
789 type == CREDIT_CARD_EXP_MONTH ||
790 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
791 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
792 view->GetTextContentsOfInput(type));
793 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
794 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
795 } else {
796 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
797 view->GetTextContentsOfInput(type));
798 }
799 }
800 }
801
802 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
803 controller()->set_use_validation(true);
804 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
805
806 CreditCard card(test::GetCreditCard());
807 ASSERT_FALSE(card.IsVerified());
808 controller()->GetTestingManager()->AddTestingCreditCard(&card);
809
810 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC));
811 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
812 view->SetTextContentsOfInput(
813 CREDIT_CARD_NUMBER,
814 card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
815
816 view->ActivateInput(CREDIT_CARD_NUMBER);
817 EXPECT_FALSE(controller()->ShouldShowErrorBubble());
818
819 controller()->FocusMoved();
820 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
821
822 base::HistogramTester histogram;
823 controller()->Hide();
824 histogram.ExpectUniqueSample(
825 "RequestAutocomplete.DismissalState",
826 AutofillMetrics::DIALOG_CANCELED_WITH_INVALID_FIELDS, 1);
827 }
828
829 // Ensure that expired cards trigger invalid suggestions.
830 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
831 CreditCard verified_card(test::GetCreditCard());
832 verified_card.set_origin(kSettingsOrigin);
833 ASSERT_TRUE(verified_card.IsVerified());
834 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
835
836 CreditCard expired_card(test::GetCreditCard());
837 expired_card.set_origin(kSettingsOrigin);
838 expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
839 ASSERT_TRUE(expired_card.IsVerified());
840 ASSERT_FALSE(
841 autofill::IsValidCreditCardExpirationDate(
842 expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR),
843 expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH),
844 base::Time::Now()));
845 controller()->GetTestingManager()->AddTestingCreditCard(&expired_card);
846
847 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC);
848 ASSERT_EQ(4, model->GetItemCount());
849
850 ASSERT_TRUE(model->IsItemCheckedAt(0));
851 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
852
853 model->ActivatedAt(1);
854 ASSERT_TRUE(model->IsItemCheckedAt(1));
855 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
856 }
857
858 // Notifications with long message text should not make the dialog bigger.
859 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) {
860 const gfx::Size no_notification_size = GetViewTester()->GetSize();
861 ASSERT_GT(no_notification_size.width(), 0);
862
863 std::vector<DialogNotification> notifications;
864 notifications.push_back(
865 DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16(
866 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
867 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
868 "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
869 "aliquip ex ea commodo consequat. Duis aute irure dolor in "
870 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
871 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
872 "culpa qui officia deserunt mollit anim id est laborum.")));
873 controller()->set_notifications(notifications);
874 controller()->view()->UpdateNotificationArea();
875
876 EXPECT_EQ(no_notification_size.width(),
877 GetViewTester()->GetSize().width());
878 }
879
880 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocompleteEvent) {
881 AutofillDialogControllerImpl* controller =
882 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
883 ASSERT_TRUE(controller);
884
885 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
886 AddAutofillProfileToProfile(controller->profile(),
887 test::GetVerifiedProfile());
888
889 std::unique_ptr<AutofillDialogViewTester> view =
890 AutofillDialogViewTester::For(controller->view());
891 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
892 view->SubmitForTesting();
893 ExpectDomMessage("success");
894 }
895
896 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
897 AutocompleteErrorEventReasonInvalid) {
898 AutofillDialogControllerImpl* controller =
899 SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
900 ASSERT_TRUE(controller);
901
902 const CreditCard& credit_card = test::GetVerifiedCreditCard();
903 ASSERT_TRUE(credit_card.GetRawInfo(CREDIT_CARD_NAME_FULL)
904 .find(ASCIIToUTF16("zebra")) == base::string16::npos);
905 AddCreditcardToProfile(controller->profile(), credit_card);
906 AddAutofillProfileToProfile(controller->profile(),
907 test::GetVerifiedProfile());
908
909 std::unique_ptr<AutofillDialogViewTester> view =
910 AutofillDialogViewTester::For(controller->view());
911 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
912 view->SubmitForTesting();
913 ExpectDomMessage("error: invalid");
914
915 int invalid_count = -1;
916 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
917 GetRenderViewHost(), "send(invalidEvents.length);", &invalid_count));
918 EXPECT_EQ(1, invalid_count);
919
920 std::string invalid_type;
921 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
922 GetRenderViewHost(),
923 "send(invalidEvents[0].target.autocomplete);",
924 &invalid_type));
925 EXPECT_EQ("cc-name", invalid_type);
926 }
927
928 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
929 AutocompleteErrorEventReasonCancel) {
930 AutofillDialogControllerImpl* controller =
931 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
932 ASSERT_TRUE(controller);
933 AutofillDialogViewTester::For(controller->view())->
934 CancelForTesting();
935 ExpectDomMessage("error: cancel");
936 }
937
938 // http://crbug.com/318526
939 #if defined(OS_MACOSX)
940 #define MAYBE_ErrorWithFrameNavigation DISABLED_ErrorWithFrameNavigation
941 #else
942 #define MAYBE_ErrorWithFrameNavigation ErrorWithFrameNavigation
943 #endif
944 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
945 MAYBE_ErrorWithFrameNavigation) {
946 AutofillDialogControllerImpl* controller =
947 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
948 ASSERT_TRUE(controller);
949
950 std::string unused;
951 ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
952 "loadIframe();",
953 &unused));
954 ExpectDomMessage("iframe loaded");
955
956 AutofillDialogViewTester::For(controller->view())->
957 CancelForTesting();
958 ExpectDomMessage("error: cancel");
959 }
960
961 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
962 controller()->set_use_validation(true);
963
964 CreditCard credit_card(test::GetVerifiedCreditCard());
965 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
966 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
967
968 ASSERT_NO_FATAL_FAILURE(GetViewTester()->SubmitForTesting());
969 }
970
971 // Verify that filling a form works correctly, including filling the CVC when
972 // that is requested separately.
973 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
974 FillFormIncludesCVC) {
975 AutofillDialogControllerImpl* controller =
976 SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
977 ASSERT_TRUE(controller);
978
979 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
980 AddAutofillProfileToProfile(controller->profile(),
981 test::GetVerifiedProfile());
982
983 std::unique_ptr<AutofillDialogViewTester> view =
984 AutofillDialogViewTester::For(controller->view());
985 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
986 view->SubmitForTesting();
987 ExpectDomMessage("success");
988 EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
989 }
990
991 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewClearsComboboxes) {
992 // Ensure the input under test is a combobox.
993 ASSERT_TRUE(
994 controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH));
995
996 // Set up an expired card.
997 CreditCard card;
998 test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
999 card.set_origin(kSettingsOrigin);
1000 ASSERT_TRUE(card.IsVerified());
1001
1002 // Add the card and check that there's a menu for that section.
1003 controller()->GetTestingManager()->AddTestingCreditCard(&card);
1004 ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC));
1005
1006 // Select the invalid, suggested card from the menu.
1007 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(0);
1008 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
1009
1010 // Get the contents of the combobox of the credit card's expiration month.
1011 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1012 base::string16 cc_exp_month_text =
1013 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH);
1014
1015 // Select "New X..." from the suggestion menu to clear the section's inputs.
1016 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(1);
1017 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1018
1019 // Ensure that the credit card expiration month has changed.
1020 EXPECT_NE(cc_exp_month_text,
1021 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH));
1022 }
1023
1024 // Flaky on Win7 (http://crbug.com/446432)
1025 #if defined(OS_WIN)
1026 #define MAYBE_TabOpensToJustRight DISABLED_TabOpensToJustRight
1027 #else
1028 #define MAYBE_TabOpensToJustRight TabOpensToJustRight
1029 #endif
1030 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1031 MAYBE_TabOpensToJustRight) {
1032 ASSERT_TRUE(browser()->is_type_tabbed());
1033
1034 // Tabs should currently be: / rAc() \.
1035 content::WebContents* dialog_invoker = controller()->GetWebContents();
1036 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1037
1038 TabStripModel* tab_strip = browser()->tab_strip_model();
1039 ASSERT_EQ(1, tab_strip->count());
1040 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1041
1042 // Open a tab to about:blank in the background at the end of the tab strip.
1043 chrome::AddTabAt(browser(), GURL(), -1, false);
1044 // Tabs should now be: / rAc() \/ blank \.
1045 EXPECT_EQ(2, tab_strip->count());
1046 EXPECT_EQ(0, tab_strip->active_index());
1047 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1048
1049 content::WebContents* blank_tab = tab_strip->GetWebContentsAt(1);
1050
1051 // Simulate clicking "Manage X...".
1052 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1053 // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1054 EXPECT_EQ(3, tab_strip->count());
1055 int dialog_index = tab_strip->GetIndexOfWebContents(dialog_invoker);
1056 EXPECT_EQ(0, dialog_index);
1057 EXPECT_EQ(1, tab_strip->active_index());
1058 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(blank_tab));
1059
1060 content::WebContents* first_manage_tab = tab_strip->GetWebContentsAt(1);
1061
1062 // Re-activate the dialog's tab (like a user would have to).
1063 tab_strip->ActivateTabAt(dialog_index, true);
1064 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1065
1066 // Simulate clicking "Manage X...".
1067 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1068 // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1069 EXPECT_EQ(4, tab_strip->count());
1070 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1071 EXPECT_EQ(1, tab_strip->active_index());
1072 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(first_manage_tab));
1073 EXPECT_EQ(3, tab_strip->GetIndexOfWebContents(blank_tab));
1074 }
1075
1076 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1077 DoesWorkOnHttpWithFlag) {
1078 net::EmbeddedTestServer http_server;
1079 http_server.ServeFilesFromSourceDirectory("chrome/test/data");
1080 ASSERT_TRUE(http_server.Start());
1081 EXPECT_TRUE(RunTestPage(http_server));
1082 }
1083
1084 // Like the parent test, but doesn't add the --reduce-security-for-testing flag.
1085 class AutofillDialogControllerSecurityTest :
1086 public AutofillDialogControllerTest {
1087 public:
1088 AutofillDialogControllerSecurityTest() {}
1089 ~AutofillDialogControllerSecurityTest() override {}
1090
1091 void SetUpCommandLine(base::CommandLine* command_line) override {
1092 CHECK(!command_line->HasSwitch(::switches::kReduceSecurityForTesting));
1093 }
1094
1095 typedef net::BaseTestServer::SSLOptions SSLOptions;
1096
1097 private:
1098 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest);
1099 };
1100
1101 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1102 DoesntWorkOnHttp) {
1103 net::EmbeddedTestServer http_server;
1104 http_server.ServeFilesFromSourceDirectory("chrome/test/data");
1105 ASSERT_TRUE(http_server.Start());
1106 EXPECT_FALSE(RunTestPage(http_server));
1107 }
1108
1109 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1110 DoesWorkOnHttpWithFlags) {
1111 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
1112 https_server.ServeFilesFromSourceDirectory("chrome/test/data");
1113 ASSERT_TRUE(https_server.Start());
1114 EXPECT_TRUE(RunTestPage(https_server));
1115 }
1116
1117 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1118 DISABLED_DoesntWorkOnBrokenHttps) {
1119 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
1120 https_server.ServeFilesFromSourceDirectory("chrome/test/data");
1121 ASSERT_TRUE(https_server.Start());
1122 EXPECT_FALSE(RunTestPage(https_server));
1123 }
1124
1125 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1126 CountryChangeRebuildsSection) {
1127 EXPECT_FALSE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1128 EXPECT_FALSE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1129
1130 // Select "Add new shipping address...".
1131 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1132
1133 // Add some valid user input that should be preserved when country changes.
1134 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1135 view->SetTextContentsOfInput(NAME_FULL, ASCIIToUTF16("B. Loblaw"));
1136
1137 // Change both sections' countries.
1138 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1139 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1140 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1141 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1142
1143 // Verify the name is still there.
1144 EXPECT_EQ(ASCIIToUTF16("B. Loblaw"), view->GetTextContentsOfInput(NAME_FULL));
1145
1146 EXPECT_TRUE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1147 EXPECT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1148 }
1149
1150 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewResetsCountry) {
1151 AutofillProfile verified_profile(test::GetVerifiedProfile());
1152 controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1153
1154 // Select "Add new billing/shipping address...".
1155 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1156 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1157
1158 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1159 ASSERT_EQ(ASCIIToUTF16("United States"),
1160 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1161 ASSERT_EQ(ASCIIToUTF16("United States"),
1162 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1163
1164 // Switch both billing and shipping countries.
1165 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("Brazil"));
1166 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1167 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1168 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1169
1170 // Select "Add new billing/shipping address...".
1171 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1172 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1173
1174 EXPECT_EQ(ASCIIToUTF16("United States"),
1175 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1176 EXPECT_EQ(ASCIIToUTF16("United States"),
1177 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1178 }
1179
1180 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1181 FillingFormRebuildsInputs) {
1182 AutofillProfile full_profile(test::GetFullProfile());
1183 full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1184 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1185
1186 // Select "Add new shipping address...".
1187 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1188
1189 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1190 ASSERT_EQ(ASCIIToUTF16("United States"),
1191 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1192 ASSERT_EQ(ASCIIToUTF16("United States"),
1193 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1194
1195 const ServerFieldType input_type = EMAIL_ADDRESS;
1196 base::string16 name = full_profile.GetRawInfo(input_type);
1197 view->SetTextContentsOfInput(input_type, name.substr(0, name.size() / 2));
1198 view->ActivateInput(input_type);
1199 ASSERT_EQ(input_type, controller()->popup_input_type());
1200 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
1201
1202 EXPECT_EQ(ASCIIToUTF16("Germany"),
1203 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1204 EXPECT_EQ(ASCIIToUTF16("United States"),
1205 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1206 }
1207
1208 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1209 FillingFormPreservesChangedCountry) {
1210 AutofillProfile full_profile(test::GetFullProfile());
1211 full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1212 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1213
1214 // Select "Add new shipping address...".
1215 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1216
1217 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1218 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1219 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1220 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1221 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1222
1223 base::string16 name = full_profile.GetRawInfo(NAME_FULL);
1224 view->SetTextContentsOfInput(NAME_FULL, name.substr(0, name.size() / 2));
1225 view->ActivateInput(NAME_FULL);
1226 ASSERT_EQ(NAME_FULL, controller()->popup_input_type());
1227 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
1228
1229 EXPECT_EQ(ASCIIToUTF16("France"),
1230 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1231 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1232 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1233 }
1234
1235 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RulesLoaded) {
1236 // Select "Add new shipping address...".
1237 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1238 controller()->set_use_validation(true);
1239
1240 EXPECT_CALL(*controller()->GetMockValidator(),
1241 ValidateAddress(CountryCodeMatcher("DE"), _, _)).Times(2).
1242 WillOnce(Return(AddressValidator::RULES_NOT_READY));
1243
1244 // Validation should occur on country change and see the rules haven't loaded.
1245 std::unique_ptr<AutofillDialogViewTester> view = GetViewTester();
1246 view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("123"));
1247 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Germany"));
1248 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1249
1250 // Different country loaded, validation should not occur.
1251 controller()->OnAddressValidationRulesLoaded("FR", true);
1252
1253 // Relevant country loaded, validation should occur.
1254 controller()->OnAddressValidationRulesLoaded("DE", true);
1255
1256 // Relevant country loaded but revalidation already happened, no further
1257 // validation should occur.
1258 controller()->OnAddressValidationRulesLoaded("DE", false);
1259
1260 // Cancelling the dialog causes additional validation to see if the user
1261 // cancelled with invalid fields, so verify and clear here.
1262 testing::Mock::VerifyAndClearExpectations(controller()->GetMockValidator());
1263 }
1264
1265 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1266 TransactionAmount) {
1267 std::string html(
1268 "<input type='number' step='0.01'"
1269 " autocomplete='transaction-amount' value='24'>"
1270 "<input autocomplete='transaction-currency' value='USD'>"
1271 "<input autocomplete='cc-csc'>");
1272 AutofillDialogControllerImpl* controller = SetUpHtmlAndInvoke(html);
1273 ASSERT_TRUE(controller);
1274
1275 EXPECT_EQ(ASCIIToUTF16("24"), controller->transaction_amount_);
1276 EXPECT_EQ(ASCIIToUTF16("USD"), controller->transaction_currency_);
1277 }
1278
1279 // Same as above, plus readonly attribute.
1280 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1281 TransactionAmountReadonly) {
1282 std::string html(
1283 "<input type='number' step='0.01'"
1284 " autocomplete='transaction-amount' value='24' readonly>"
1285 "<input autocomplete='transaction-currency' value='USD' readonly>"
1286 "<input autocomplete='cc-csc'>");
1287 AutofillDialogControllerImpl* controller = SetUpHtmlAndInvoke(html);
1288 ASSERT_TRUE(controller);
1289
1290 EXPECT_EQ(ASCIIToUTF16("24"), controller->transaction_amount_);
1291 EXPECT_EQ(ASCIIToUTF16("USD"), controller->transaction_currency_);
1292 }
1293
1294 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, HideOnNavigate) {
1295 base::WeakPtr<TestAutofillDialogController> weak_ptr =
1296 controller()->AsWeakPtr();
1297 EXPECT_TRUE(weak_ptr.get());
1298
1299 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
1300 EXPECT_FALSE(weak_ptr.get());
1301 }
1302
1303 // Tests that the rAc dialog hides when the main frame is navigated, even if
1304 // it was invoked from a child frame.
1305 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, HideOnNavigateMainFrame) {
1306 net::EmbeddedTestServer http_server;
1307 http_server.ServeFilesFromSourceDirectory("chrome/test/data");
1308 ASSERT_TRUE(http_server.Start());
1309 RunTestPageInIframe(http_server);
1310
1311 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
1312 ChromeAutofillClient* client =
1313 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
1314 EXPECT_FALSE(client->GetDialogControllerForTesting());
1315 }
1316
1317 // Tests that the rAc dialog hides when the iframe it's in is navigated.
1318 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, HideOnNavigateIframe) {
1319 net::EmbeddedTestServer http_server;
1320 http_server.ServeFilesFromSourceDirectory("chrome/test/data");
1321 ASSERT_TRUE(http_server.Start());
1322 RunTestPageInIframe(http_server);
1323
1324 std::string unused;
1325 ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
1326 "navigateFrame();",
1327 &unused));
1328 ExpectDomMessage("iframe loaded");
1329 ChromeAutofillClient* client =
1330 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
1331 EXPECT_FALSE(client->GetDialogControllerForTesting());
1332 }
1333
1334 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/ui/autofill/autofill_dialog_controller.cc ('k') | chrome/browser/ui/autofill/autofill_dialog_controller_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698