Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / autofill / autofill_dialog_controller_browsertest.cc
blob0bbd6b0790acf92b159a2f4549b7c42520b9459b
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.
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/autofill/personal_data_manager_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/autofill/account_chooser_model.h"
17 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
18 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
19 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
20 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
21 #include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h"
22 #include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
23 #include "chrome/browser/ui/autofill/testable_autofill_dialog_view.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_tabstrip.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/common/url_constants.h"
30 #include "chrome/test/base/in_process_browser_test.h"
31 #include "chrome/test/base/ui_test_utils.h"
32 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
33 #include "components/autofill/content/browser/wallet/gaia_account.h"
34 #include "components/autofill/content/browser/wallet/mock_wallet_client.h"
35 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
36 #include "components/autofill/content/browser/wallet/wallet_test_util.h"
37 #include "components/autofill/core/browser/autofill_metrics.h"
38 #include "components/autofill/core/browser/autofill_test_utils.h"
39 #include "components/autofill/core/browser/test_personal_data_manager.h"
40 #include "components/autofill/core/browser/validation.h"
41 #include "components/autofill/core/common/autofill_switches.h"
42 #include "components/autofill/core/common/form_data.h"
43 #include "components/autofill/core/common/form_field_data.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/interstitial_page.h"
46 #include "content/public/browser/navigation_details.h"
47 #include "content/public/browser/navigation_entry.h"
48 #include "content/public/browser/notification_service.h"
49 #include "content/public/browser/notification_types.h"
50 #include "content/public/browser/page_navigator.h"
51 #include "content/public/browser/web_contents.h"
52 #include "content/public/browser/web_contents_delegate.h"
53 #include "content/public/common/content_switches.h"
54 #include "content/public/common/page_transition_types.h"
55 #include "content/public/common/referrer.h"
56 #include "content/public/common/url_constants.h"
57 #include "content/public/test/browser_test_utils.h"
58 #include "content/public/test/test_utils.h"
59 #include "google_apis/gaia/google_service_auth_error.h"
60 #include "net/test/spawned_test_server/spawned_test_server.h"
61 #include "testing/gmock/include/gmock/gmock.h"
62 #include "testing/gtest/include/gtest/gtest.h"
63 #include "third_party/WebKit/public/web/WebInputEvent.h"
64 #include "ui/base/window_open_disposition.h"
65 #include "url/gurl.h"
67 #if defined(OS_WIN)
68 #include "base/win/windows_version.h"
69 #elif defined(OS_MACOSX)
70 #include "base/mac/mac_util.h"
71 #include "base/mac/scoped_nsautorelease_pool.h"
72 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
73 #endif
75 using base::ASCIIToUTF16;
77 namespace autofill {
79 namespace {
81 using testing::_;
83 void MockCallback(const FormStructure*) {}
85 class MockAutofillMetrics : public AutofillMetrics {
86 public:
87 MockAutofillMetrics()
88 : dialog_dismissal_action_(
89 static_cast<AutofillMetrics::DialogDismissalAction>(-1)) {}
90 virtual ~MockAutofillMetrics() {}
92 virtual void LogDialogUiDuration(
93 const base::TimeDelta& duration,
94 DialogDismissalAction dismissal_action) const OVERRIDE {
95 // Ignore constness for testing.
96 MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this);
97 mutable_this->dialog_dismissal_action_ = dismissal_action;
100 AutofillMetrics::DialogDismissalAction dialog_dismissal_action() const {
101 return dialog_dismissal_action_;
104 MOCK_CONST_METHOD1(LogDialogDismissalState,
105 void(DialogDismissalState state));
107 private:
108 AutofillMetrics::DialogDismissalAction dialog_dismissal_action_;
110 DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics);
113 class TestAutofillDialogController : public AutofillDialogControllerImpl {
114 public:
115 TestAutofillDialogController(
116 content::WebContents* contents,
117 const FormData& form_data,
118 const AutofillMetrics& metric_logger,
119 scoped_refptr<content::MessageLoopRunner> runner)
120 : AutofillDialogControllerImpl(contents,
121 form_data,
122 form_data.origin,
123 base::Bind(&MockCallback)),
124 metric_logger_(metric_logger),
125 mock_wallet_client_(
126 Profile::FromBrowserContext(contents->GetBrowserContext())->
127 GetRequestContext(), this, form_data.origin),
128 message_loop_runner_(runner),
129 use_validation_(false),
130 weak_ptr_factory_(this),
131 sign_in_user_index_(0U) {}
133 virtual ~TestAutofillDialogController() {}
135 virtual GURL SignInUrl() const OVERRIDE {
136 return GURL(chrome::kChromeUIVersionURL);
139 virtual void ViewClosed() OVERRIDE {
140 message_loop_runner_->Quit();
141 AutofillDialogControllerImpl::ViewClosed();
144 virtual base::string16 InputValidityMessage(
145 DialogSection section,
146 ServerFieldType type,
147 const base::string16& value) OVERRIDE {
148 if (!use_validation_)
149 return base::string16();
150 return AutofillDialogControllerImpl::InputValidityMessage(
151 section, type, value);
154 virtual ValidityMessages InputsAreValid(
155 DialogSection section,
156 const FieldValueMap& inputs) OVERRIDE {
157 if (!use_validation_)
158 return ValidityMessages();
159 return AutofillDialogControllerImpl::InputsAreValid(section, inputs);
162 // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
163 // TODO(estade): test that the view defaults to saving to Chrome.
164 virtual bool ShouldOfferToSaveInChrome() const OVERRIDE {
165 return false;
168 void ForceFinishSubmit() {
169 DoFinishSubmit();
172 // Increase visibility for testing.
173 using AutofillDialogControllerImpl::view;
174 using AutofillDialogControllerImpl::popup_input_type;
176 MOCK_METHOD0(LoadRiskFingerprintData, void());
178 virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE {
179 return notifications_;
182 void set_notifications(const std::vector<DialogNotification>& notifications) {
183 notifications_ = notifications;
186 TestPersonalDataManager* GetTestingManager() {
187 return &test_manager_;
190 using AutofillDialogControllerImpl::IsEditingExistingData;
191 using AutofillDialogControllerImpl::IsManuallyEditingSection;
192 using AutofillDialogControllerImpl::IsPayingWithWallet;
193 using AutofillDialogControllerImpl::IsSubmitPausedOn;
194 using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
195 using AutofillDialogControllerImpl::AccountChooserModelForTesting;
196 using AutofillDialogControllerImpl::
197 ClearLastWalletItemsFetchTimestampForTesting;
199 void set_use_validation(bool use_validation) {
200 use_validation_ = use_validation;
203 base::WeakPtr<TestAutofillDialogController> AsWeakPtr() {
204 return weak_ptr_factory_.GetWeakPtr();
207 wallet::MockWalletClient* GetTestingWalletClient() {
208 return &mock_wallet_client_;
211 void set_sign_in_user_index(size_t sign_in_user_index) {
212 sign_in_user_index_ = sign_in_user_index;
215 protected:
216 virtual PersonalDataManager* GetManager() const OVERRIDE {
217 return &const_cast<TestAutofillDialogController*>(this)->test_manager_;
220 virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
221 return &mock_wallet_client_;
224 virtual bool IsSignInContinueUrl(const GURL& url, size_t* user_index) const
225 OVERRIDE {
226 *user_index = sign_in_user_index_;
227 return url == wallet::GetSignInContinueUrl();
230 private:
231 // To specify our own metric logger.
232 virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
233 return metric_logger_;
236 const AutofillMetrics& metric_logger_;
237 TestPersonalDataManager test_manager_;
238 testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
239 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
240 bool use_validation_;
242 // A list of notifications to show in the notification area of the dialog.
243 // This is used to control what |CurrentNotifications()| returns for testing.
244 std::vector<DialogNotification> notifications_;
246 // Allows generation of WeakPtrs, so controller liveness can be tested.
247 base::WeakPtrFactory<TestAutofillDialogController> weak_ptr_factory_;
249 // The user index that is assigned in IsSignInContinueUrl().
250 size_t sign_in_user_index_;
252 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
255 // This is a copy of ui_test_utils::UrlLoadObserver, except it observes
256 // NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
257 // that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
258 // before LOAD_STOP, and the controller deletes the web contents after receiving
259 // the former, we will sometimes fail to observe a LOAD_STOP.
260 // TODO(estade): Should the controller observe LOAD_STOP instead?
261 class NavEntryCommittedObserver : public content::WindowedNotificationObserver {
262 public:
263 NavEntryCommittedObserver(const GURL& url,
264 const content::NotificationSource& source)
265 : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED,
266 source),
267 url_(url) {}
269 virtual ~NavEntryCommittedObserver() {}
271 // content::NotificationObserver:
272 virtual void Observe(int type,
273 const content::NotificationSource& source,
274 const content::NotificationDetails& details) OVERRIDE {
275 content::LoadCommittedDetails* load_details =
276 content::Details<content::LoadCommittedDetails>(details).ptr();
277 if (load_details->entry->GetVirtualURL() != url_)
278 return;
280 WindowedNotificationObserver::Observe(type, source, details);
283 private:
284 GURL url_;
286 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
289 } // namespace
291 class AutofillDialogControllerTest : public InProcessBrowserTest {
292 public:
293 AutofillDialogControllerTest() {}
294 virtual ~AutofillDialogControllerTest() {}
296 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
297 command_line->AppendSwitch(::switches::kReduceSecurityForTesting);
300 virtual void SetUpOnMainThread() OVERRIDE {
301 autofill::test::DisableSystemServices(browser()->profile());
302 InitializeController();
305 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
306 // loop. It also drains the NSAutoreleasePool.
307 void CycleRunLoops() {
308 content::RunAllPendingInMessageLoop();
309 #if defined(OS_MACOSX)
310 chrome::testing::NSRunLoopRunAllPending();
311 AutoreleasePool()->Recycle();
312 #endif
315 void InitializeController() {
316 FormData form;
317 form.name = ASCIIToUTF16("TestForm");
318 form.method = ASCIIToUTF16("POST");
319 form.user_submitted = true;
321 FormFieldData field;
322 field.autocomplete_attribute = "shipping tel";
323 form.fields.push_back(field);
325 test_generated_bubble_controller_ =
326 new testing::NiceMock<TestGeneratedCreditCardBubbleController>(
327 GetActiveWebContents());
328 ASSERT_TRUE(test_generated_bubble_controller_->IsInstalled());
330 message_loop_runner_ = new content::MessageLoopRunner;
331 controller_ = new TestAutofillDialogController(
332 GetActiveWebContents(),
333 form,
334 metric_logger_,
335 message_loop_runner_);
336 controller_->Show();
337 CycleRunLoops(); // Ensures dialog is fully visible.
340 content::WebContents* GetActiveWebContents() {
341 return browser()->tab_strip_model()->GetActiveWebContents();
344 const MockAutofillMetrics& metric_logger() { return metric_logger_; }
345 TestAutofillDialogController* controller() { return controller_; }
347 void RunMessageLoop() {
348 message_loop_runner_->Run();
351 // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
352 // <form>|form_inner_html|</form>. After loading, emulates a click event on
353 // the page as requestAutocomplete() must be in response to a user gesture.
354 // Returns the |AutofillDialogControllerImpl| created by this invocation.
355 AutofillDialogControllerImpl* SetUpHtmlAndInvoke(
356 const std::string& form_inner_html) {
357 content::WebContents* contents = GetActiveWebContents();
358 TabAutofillManagerDelegate* delegate =
359 TabAutofillManagerDelegate::FromWebContents(contents);
360 CHECK(!delegate->GetDialogControllerForTesting());
362 ui_test_utils::NavigateToURL(
363 browser(), GURL(std::string("data:text/html,") +
364 "<!doctype html>"
365 "<html>"
366 "<body>"
367 "<form>" + form_inner_html + "</form>"
368 "<script>"
369 "function send(msg) {"
370 "domAutomationController.setAutomationId(0);"
371 "domAutomationController.send(msg);"
373 "document.forms[0].onautocompleteerror = function(e) {"
374 "send('error: ' + e.reason);"
375 "};"
376 "document.forms[0].onautocomplete = function() {"
377 "send('success');"
378 "};"
379 "window.onclick = function() {"
380 "document.forms[0].requestAutocomplete();"
381 "send('clicked');"
382 "};"
383 "function getValueForFieldOfType(type) {"
384 " var fields = document.getElementsByTagName('input');"
385 " for (var i = 0; i < fields.length; i++) {"
386 " if (fields[i].autocomplete == type) {"
387 " send(fields[i].value);"
388 " return;"
389 " }"
390 " }"
391 " send('');"
392 "};"
393 "</script>"
394 "</body>"
395 "</html>"));
397 InitiateDialog();
398 AutofillDialogControllerImpl* controller =
399 static_cast<AutofillDialogControllerImpl*>(
400 delegate->GetDialogControllerForTesting());
401 return controller;
404 // Loads an html page on a provided server, the causes it to launch rAc.
405 // Returns whether rAc succesfully launched.
406 bool RunTestPage(const net::SpawnedTestServer& server) {
407 GURL url = server.GetURL(
408 "files/request_autocomplete/test_page.html");
409 ui_test_utils::NavigateToURL(browser(), url);
411 // Pass through the broken SSL interstitial, if any.
412 content::WebContents* contents = GetActiveWebContents();
413 content::InterstitialPage* interstitial_page =
414 contents->GetInterstitialPage();
415 if (interstitial_page) {
416 ui_test_utils::UrlLoadObserver observer(
417 url,
418 content::Source<content::NavigationController>(
419 &contents->GetController()));
420 interstitial_page->Proceed();
421 observer.Wait();
424 InitiateDialog();
426 TabAutofillManagerDelegate* delegate =
427 TabAutofillManagerDelegate::FromWebContents(contents);
428 AutofillDialogControllerImpl* controller =
429 static_cast<AutofillDialogControllerImpl*>(
430 delegate->GetDialogControllerForTesting());
431 return !!controller;
434 // Wait for a message from the DOM automation controller (from JS in the
435 // page). Requires |SetUpHtmlAndInvoke()| be called first.
436 void ExpectDomMessage(const std::string& expected) {
437 std::string message;
438 ASSERT_TRUE(dom_message_queue_->WaitForMessage(&message));
439 dom_message_queue_->ClearQueue();
440 EXPECT_EQ("\"" + expected + "\"", message);
443 void InitiateDialog() {
444 dom_message_queue_.reset(new content::DOMMessageQueue);
446 // Triggers the onclick handler which invokes requestAutocomplete().
447 content::WebContents* contents = GetActiveWebContents();
448 content::SimulateMouseClick(contents, 0, blink::WebMouseEvent::ButtonLeft);
449 ExpectDomMessage("clicked");
452 // Returns the value filled into the first field with autocomplete attribute
453 // equal to |autocomplete_type|, or an empty string if there is no such field.
454 std::string GetValueForHTMLFieldOfType(const std::string& autocomplete_type) {
455 content::RenderViewHost* render_view_host =
456 browser()->tab_strip_model()->GetActiveWebContents()->
457 GetRenderViewHost();
458 std::string script = "getValueForFieldOfType('" + autocomplete_type + "');";
459 std::string result;
460 EXPECT_TRUE(content::ExecuteScriptAndExtractString(render_view_host, script,
461 &result));
462 return result;
465 void AddCreditcardToProfile(Profile* profile, const CreditCard& card) {
466 PersonalDataManagerFactory::GetForProfile(profile)->AddCreditCard(card);
467 WaitForWebDB();
470 void AddAutofillProfileToProfile(Profile* profile,
471 const AutofillProfile& autofill_profile) {
472 PersonalDataManagerFactory::GetForProfile(profile)->AddProfile(
473 autofill_profile);
474 WaitForWebDB();
477 TestGeneratedCreditCardBubbleController* test_generated_bubble_controller() {
478 return test_generated_bubble_controller_;
481 private:
482 void WaitForWebDB() {
483 content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
486 testing::NiceMock<MockAutofillMetrics> metric_logger_;
487 TestAutofillDialogController* controller_; // Weak reference.
488 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
489 scoped_ptr<content::DOMMessageQueue> dom_message_queue_;
491 // Weak; owned by the active web contents.
492 TestGeneratedCreditCardBubbleController* test_generated_bubble_controller_;
494 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
497 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
498 // Submit the form data.
499 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
500 controller()->GetTestableView()->SubmitForTesting();
502 RunMessageLoop();
504 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
505 metric_logger().dialog_dismissal_action());
508 // Cancel out of the dialog.
509 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) {
510 controller()->GetTestableView()->CancelForTesting();
512 RunMessageLoop();
514 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
515 metric_logger().dialog_dismissal_action());
518 // Take some other action that dismisses the dialog.
519 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) {
520 controller()->Hide();
522 RunMessageLoop();
524 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
525 metric_logger().dialog_dismissal_action());
528 // Ensure that Hide() will only destroy the controller object after the
529 // message loop has run. Otherwise, there may be read-after-free issues
530 // during some tests.
531 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, DeferredDestruction) {
532 base::WeakPtr<TestAutofillDialogController> weak_ptr =
533 controller()->AsWeakPtr();
534 EXPECT_TRUE(weak_ptr.get());
536 controller()->Hide();
537 EXPECT_TRUE(weak_ptr.get());
539 RunMessageLoop();
540 EXPECT_FALSE(weak_ptr.get());
543 // Ensure that the expected metric is logged when the dialog is closed during
544 // signin.
545 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CloseDuringSignin) {
546 controller()->SignInLinkClicked();
548 EXPECT_CALL(metric_logger(),
549 LogDialogDismissalState(
550 AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN));
551 controller()->GetTestableView()->CancelForTesting();
553 RunMessageLoop();
555 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
556 metric_logger().dialog_dismissal_action());
559 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
560 AutofillProfile full_profile(test::GetFullProfile());
561 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
563 // Select "Add new shipping address...".
564 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_SHIPPING);
565 model->ActivatedAt(model->GetItemCount() - 2);
566 ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
568 const DetailInputs& inputs =
569 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
570 const ServerFieldType triggering_type = inputs[0].type;
571 base::string16 value = full_profile.GetRawInfo(triggering_type);
572 TestableAutofillDialogView* view = controller()->GetTestableView();
573 view->SetTextContentsOfInput(triggering_type,
574 value.substr(0, value.size() / 2));
575 view->ActivateInput(triggering_type);
577 ASSERT_EQ(triggering_type, controller()->popup_input_type());
578 controller()->DidAcceptSuggestion(base::string16(), 0);
580 // All inputs should be filled.
581 AutofillProfileWrapper wrapper(&full_profile);
582 for (size_t i = 0; i < inputs.size(); ++i) {
583 EXPECT_EQ(wrapper.GetInfo(AutofillType(inputs[i].type)),
584 view->GetTextContentsOfInput(inputs[i].type));
587 // Now simulate some user edits and try again.
588 std::vector<base::string16> expectations;
589 for (size_t i = 0; i < inputs.size(); ++i) {
590 if (controller()->ComboboxModelForAutofillType(inputs[i].type)) {
591 expectations.push_back(base::string16());
592 continue;
594 base::string16 users_input = i % 2 == 0 ? base::string16()
595 : ASCIIToUTF16("dummy");
596 view->SetTextContentsOfInput(inputs[i].type, users_input);
597 // Empty inputs should be filled, others should be left alone.
598 base::string16 expectation =
599 inputs[i].type == triggering_type || users_input.empty() ?
600 wrapper.GetInfo(AutofillType(inputs[i].type)) :
601 users_input;
602 expectations.push_back(expectation);
605 view->SetTextContentsOfInput(triggering_type,
606 value.substr(0, value.size() / 2));
607 view->ActivateInput(triggering_type);
608 ASSERT_EQ(triggering_type, controller()->popup_input_type());
609 controller()->DidAcceptSuggestion(base::string16(), 0);
611 for (size_t i = 0; i < inputs.size(); ++i) {
612 if (controller()->ComboboxModelForAutofillType(inputs[i].type))
613 continue;
614 EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i].type));
618 // For now, no matter what, the country must always be US. See
619 // http://crbug.com/247518
620 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
621 FillInputFromForeignProfile) {
622 AutofillProfile full_profile(test::GetFullProfile());
623 full_profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
624 ASCIIToUTF16("France"), "en-US");
625 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
627 // Select "Add new shipping address...".
628 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_SHIPPING);
629 model->ActivatedAt(model->GetItemCount() - 2);
630 ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
632 const DetailInputs& inputs =
633 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
634 const ServerFieldType triggering_type = inputs[0].type;
635 base::string16 value = full_profile.GetRawInfo(triggering_type);
636 TestableAutofillDialogView* view = controller()->GetTestableView();
637 view->SetTextContentsOfInput(triggering_type,
638 value.substr(0, value.size() / 2));
639 view->ActivateInput(triggering_type);
641 ASSERT_EQ(triggering_type, controller()->popup_input_type());
642 controller()->DidAcceptSuggestion(base::string16(), 0);
644 // All inputs should be filled.
645 AutofillProfileWrapper wrapper(&full_profile);
646 for (size_t i = 0; i < inputs.size(); ++i) {
647 const ServerFieldType type = inputs[i].type;
648 base::string16 expectation =
649 AutofillType(type).GetStorableType() == ADDRESS_HOME_COUNTRY ?
650 ASCIIToUTF16("United States") : wrapper.GetInfo(AutofillType(type));
651 EXPECT_EQ(expectation, view->GetTextContentsOfInput(type));
654 // Now simulate some user edits and try again.
655 std::vector<base::string16> expectations;
656 for (size_t i = 0; i < inputs.size(); ++i) {
657 if (controller()->ComboboxModelForAutofillType(inputs[i].type)) {
658 expectations.push_back(base::string16());
659 continue;
661 base::string16 users_input = i % 2 == 0 ? base::string16()
662 : ASCIIToUTF16("dummy");
663 view->SetTextContentsOfInput(inputs[i].type, users_input);
664 // Empty inputs should be filled, others should be left alone.
665 base::string16 expectation =
666 inputs[i].type == triggering_type || users_input.empty() ?
667 wrapper.GetInfo(AutofillType(inputs[i].type)) :
668 users_input;
669 if (AutofillType(inputs[i].type).GetStorableType() == ADDRESS_HOME_COUNTRY)
670 expectation = ASCIIToUTF16("United States");
672 expectations.push_back(expectation);
675 view->SetTextContentsOfInput(triggering_type,
676 value.substr(0, value.size() / 2));
677 view->ActivateInput(triggering_type);
678 ASSERT_EQ(triggering_type, controller()->popup_input_type());
679 controller()->DidAcceptSuggestion(base::string16(), 0);
681 for (size_t i = 0; i < inputs.size(); ++i) {
682 if (controller()->ComboboxModelForAutofillType(inputs[i].type))
683 continue;
684 EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i].type));
688 // This test makes sure that picking a profile variant in the Autofill
689 // popup works as expected.
690 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
691 FillInputFromAutofillVariant) {
692 AutofillProfile full_profile(test::GetFullProfile());
694 // Set up some variant data.
695 std::vector<base::string16> names;
696 names.push_back(ASCIIToUTF16("John Doe"));
697 names.push_back(ASCIIToUTF16("Jane Doe"));
698 full_profile.SetRawMultiInfo(NAME_FULL, names);
699 std::vector<base::string16> emails;
700 emails.push_back(ASCIIToUTF16("user@example.com"));
701 emails.push_back(ASCIIToUTF16("admin@example.com"));
702 full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
703 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
705 const DetailInputs& inputs =
706 controller()->RequestedFieldsForSection(SECTION_BILLING);
707 const ServerFieldType triggering_type = inputs[0].type;
708 EXPECT_EQ(NAME_BILLING_FULL, triggering_type);
709 TestableAutofillDialogView* view = controller()->GetTestableView();
710 view->ActivateInput(triggering_type);
712 ASSERT_EQ(triggering_type, controller()->popup_input_type());
714 // Choose the variant suggestion.
715 controller()->DidAcceptSuggestion(base::string16(), 1);
717 // All inputs should be filled.
718 AutofillProfileWrapper wrapper(
719 &full_profile, AutofillType(NAME_BILLING_FULL), 1);
720 for (size_t i = 0; i < inputs.size(); ++i) {
721 EXPECT_EQ(wrapper.GetInfo(AutofillType(inputs[i].type)),
722 view->GetTextContentsOfInput(inputs[i].type));
725 // Make sure the wrapper applies the variant index to the right group.
726 EXPECT_EQ(names[1], wrapper.GetInfo(AutofillType(NAME_BILLING_FULL)));
727 // Make sure the wrapper doesn't apply the variant index to the wrong group.
728 EXPECT_EQ(emails[0], wrapper.GetInfo(AutofillType(EMAIL_ADDRESS)));
731 // Tests that changing the value of a CC expiration date combobox works as
732 // expected when Autofill is used to fill text inputs.
734 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
735 #if defined(OS_WIN)
736 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
737 #else
738 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
739 #endif
740 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
741 MAYBE_FillComboboxFromAutofill) {
742 CreditCard card1;
743 test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
744 controller()->GetTestingManager()->AddTestingCreditCard(&card1);
745 CreditCard card2;
746 test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017");
747 controller()->GetTestingManager()->AddTestingCreditCard(&card2);
748 AutofillProfile full_profile(test::GetFullProfile());
749 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
751 const DetailInputs& inputs =
752 controller()->RequestedFieldsForSection(SECTION_CC);
753 const ServerFieldType triggering_type = inputs[0].type;
754 base::string16 value = card1.GetRawInfo(triggering_type);
755 TestableAutofillDialogView* view = controller()->GetTestableView();
756 view->SetTextContentsOfInput(triggering_type,
757 value.substr(0, value.size() / 2));
758 view->ActivateInput(triggering_type);
760 ASSERT_EQ(triggering_type, controller()->popup_input_type());
761 controller()->DidAcceptSuggestion(base::string16(), 0);
763 // All inputs should be filled.
764 AutofillCreditCardWrapper wrapper1(&card1);
765 for (size_t i = 0; i < inputs.size(); ++i) {
766 EXPECT_EQ(wrapper1.GetInfo(AutofillType(inputs[i].type)),
767 view->GetTextContentsOfInput(inputs[i].type));
770 // Try again with different data. Only expiration date and the triggering
771 // input should be overwritten.
772 value = card2.GetRawInfo(triggering_type);
773 view->SetTextContentsOfInput(triggering_type,
774 value.substr(0, value.size() / 2));
775 view->ActivateInput(triggering_type);
776 ASSERT_EQ(triggering_type, controller()->popup_input_type());
777 controller()->DidAcceptSuggestion(base::string16(), 0);
779 AutofillCreditCardWrapper wrapper2(&card2);
780 for (size_t i = 0; i < inputs.size(); ++i) {
781 const ServerFieldType type = inputs[i].type;
782 if (type == triggering_type ||
783 type == CREDIT_CARD_EXP_MONTH ||
784 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
785 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
786 view->GetTextContentsOfInput(type));
787 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
788 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
789 } else {
790 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
791 view->GetTextContentsOfInput(type));
795 // Now fill from a profile. It should not overwrite any CC info.
796 const DetailInputs& billing_inputs =
797 controller()->RequestedFieldsForSection(SECTION_BILLING);
798 const ServerFieldType billing_triggering_type = billing_inputs[0].type;
799 value = full_profile.GetRawInfo(triggering_type);
800 view->SetTextContentsOfInput(billing_triggering_type,
801 value.substr(0, value.size() / 2));
802 view->ActivateInput(billing_triggering_type);
804 ASSERT_EQ(billing_triggering_type, controller()->popup_input_type());
805 controller()->DidAcceptSuggestion(base::string16(), 0);
807 for (size_t i = 0; i < inputs.size(); ++i) {
808 const ServerFieldType type = inputs[i].type;
809 if (type == triggering_type ||
810 type == CREDIT_CARD_EXP_MONTH ||
811 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
812 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
813 view->GetTextContentsOfInput(type));
814 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
815 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
816 } else {
817 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
818 view->GetTextContentsOfInput(type));
823 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
824 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
826 CreditCard card(test::GetCreditCard());
827 ASSERT_FALSE(card.IsVerified());
828 controller()->GetTestingManager()->AddTestingCreditCard(&card);
830 TestableAutofillDialogView* view = controller()->GetTestableView();
831 view->SetTextContentsOfInput(
832 CREDIT_CARD_NUMBER,
833 card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
835 view->ActivateInput(CREDIT_CARD_NUMBER);
836 EXPECT_FALSE(controller()->ShouldShowErrorBubble());
838 controller()->FocusMoved();
839 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
842 // Ensure that expired cards trigger invalid suggestions.
843 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
844 CreditCard verified_card(test::GetCreditCard());
845 verified_card.set_origin("Chrome settings");
846 ASSERT_TRUE(verified_card.IsVerified());
847 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
849 CreditCard expired_card(test::GetCreditCard());
850 expired_card.set_origin("Chrome settings");
851 expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
852 ASSERT_TRUE(expired_card.IsVerified());
853 ASSERT_FALSE(
854 autofill::IsValidCreditCardExpirationDate(
855 expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR),
856 expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH),
857 base::Time::Now()));
858 controller()->GetTestingManager()->AddTestingCreditCard(&expired_card);
860 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC);
861 ASSERT_EQ(4, model->GetItemCount());
863 ASSERT_TRUE(model->IsItemCheckedAt(0));
864 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
866 model->ActivatedAt(1);
867 ASSERT_TRUE(model->IsItemCheckedAt(1));
868 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
871 // Notifications with long message text should not make the dialog bigger.
872 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) {
873 const gfx::Size no_notification_size =
874 controller()->GetTestableView()->GetSize();
875 ASSERT_GT(no_notification_size.width(), 0);
877 std::vector<DialogNotification> notifications;
878 notifications.push_back(
879 DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16(
880 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
881 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
882 "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
883 "aliquip ex ea commodo consequat. Duis aute irure dolor in "
884 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
885 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
886 "culpa qui officia deserunt mollit anim id est laborum.")));
887 controller()->set_notifications(notifications);
888 controller()->view()->UpdateNotificationArea();
890 EXPECT_EQ(no_notification_size.width(),
891 controller()->GetTestableView()->GetSize().width());
894 // http://crbug.com/318526
895 #if defined(OS_MACOSX)
896 #define MAYBE_AutocompleteEvent DISABLED_AutocompleteEvent
897 #else
898 #define MAYBE_AutocompleteEvent AutocompleteEvent
899 #endif
900 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_AutocompleteEvent) {
901 AutofillDialogControllerImpl* controller =
902 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
903 ASSERT_TRUE(controller);
905 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
906 AddAutofillProfileToProfile(controller->profile(),
907 test::GetVerifiedProfile());
909 TestableAutofillDialogView* view = controller->GetTestableView();
910 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
911 view->SubmitForTesting();
912 ExpectDomMessage("success");
915 // http://crbug.com/318526
916 #if defined(OS_MACOSX)
917 #define MAYBE_AutocompleteErrorEventReasonInvalid \
918 DISABLED_AutocompleteErrorEventReasonInvalid
919 #else
920 #define MAYBE_AutocompleteErrorEventReasonInvalid \
921 AutocompleteErrorEventReasonInvalid
922 #endif
923 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
924 MAYBE_AutocompleteErrorEventReasonInvalid) {
925 AutofillDialogControllerImpl* controller =
926 SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
927 ASSERT_TRUE(controller);
929 const CreditCard& credit_card = test::GetVerifiedCreditCard();
930 ASSERT_TRUE(
931 credit_card.GetRawInfo(CREDIT_CARD_NAME).find(ASCIIToUTF16("zebra")) ==
932 base::string16::npos);
933 AddCreditcardToProfile(controller->profile(), credit_card);
934 AddAutofillProfileToProfile(controller->profile(),
935 test::GetVerifiedProfile());
937 TestableAutofillDialogView* view = controller->GetTestableView();
938 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
939 view->SubmitForTesting();
940 ExpectDomMessage("error: invalid");
943 // http://crbug.com/318526
944 #if defined(OS_MACOSX)
945 #define MAYBE_AutocompleteErrorEventReasonCancel \
946 DISABLED_AutocompleteErrorEventReasonCancel
947 #else
948 #define MAYBE_AutocompleteErrorEventReasonCancel \
949 AutocompleteErrorEventReasonCancel
950 #endif
951 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
952 MAYBE_AutocompleteErrorEventReasonCancel) {
953 AutofillDialogControllerImpl* controller =
954 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
955 ASSERT_TRUE(controller);
956 controller->GetTestableView()->CancelForTesting();
957 ExpectDomMessage("error: cancel");
960 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
961 controller()->set_use_validation(true);
963 CreditCard credit_card(test::GetVerifiedCreditCard());
964 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
965 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
967 ASSERT_NO_FATAL_FAILURE(
968 controller()->GetTestableView()->SubmitForTesting());
971 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
972 #if defined(OS_WIN)
973 #define MAYBE_PreservedSections DISABLED_PreservedSections
974 #else
975 #define MAYBE_PreservedSections PreservedSections
976 #endif
977 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_PreservedSections) {
978 controller()->set_use_validation(true);
980 TestableAutofillDialogView* view = controller()->GetTestableView();
981 view->SetTextContentsOfInput(CREDIT_CARD_NUMBER,
982 ASCIIToUTF16("4111111111111111"));
984 // Create some invalid, manually inputted shipping data.
985 view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("shipping zip"));
987 // Switch to Wallet by simulating a successful server response.
988 controller()->OnDidFetchWalletCookieValue(std::string());
989 controller()->OnDidGetWalletItems(
990 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
991 ASSERT_TRUE(controller()->IsPayingWithWallet());
993 // The valid data should be preserved.
994 EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
995 view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
997 // The invalid data should be dropped.
998 EXPECT_TRUE(view->GetTextContentsOfInput(ADDRESS_HOME_ZIP).empty());
1000 // Switch back to Autofill.
1001 ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1002 account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1003 ASSERT_FALSE(controller()->IsPayingWithWallet());
1005 // The valid data should still be preserved when switched back.
1006 EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
1007 view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
1009 #endif // defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
1011 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1012 GeneratedCardLastFourAfterVerifyCvv) {
1013 controller()->OnDidFetchWalletCookieValue(std::string());
1015 scoped_ptr<wallet::WalletItems> wallet_items =
1016 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1017 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1018 wallet_items->AddAddress(wallet::GetTestShippingAddress());
1020 base::string16 last_four =
1021 wallet_items->instruments()[0]->TypeAndLastFourDigits();
1022 controller()->OnDidGetWalletItems(wallet_items.Pass());
1024 TestableAutofillDialogView* test_view = controller()->GetTestableView();
1025 EXPECT_FALSE(test_view->IsShowingOverlay());
1026 EXPECT_CALL(*controller(), LoadRiskFingerprintData());
1027 controller()->OnAccept();
1028 EXPECT_TRUE(test_view->IsShowingOverlay());
1030 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1031 scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
1032 fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
1033 set_width(1024);
1034 controller()->OnDidLoadRiskFingerprintData(fingerprint.Pass());
1036 controller()->OnDidGetFullWallet(
1037 wallet::GetTestFullWalletWithRequiredActions(
1038 std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
1040 ASSERT_TRUE(controller()->IsSubmitPausedOn(wallet::VERIFY_CVV));
1042 std::string fake_cvc("123");
1043 test_view->SetTextContentsOfSuggestionInput(SECTION_CC_BILLING,
1044 ASCIIToUTF16(fake_cvc));
1046 EXPECT_FALSE(test_view->IsShowingOverlay());
1047 EXPECT_CALL(*controller()->GetTestingWalletClient(),
1048 AuthenticateInstrument(_, fake_cvc));
1049 controller()->OnAccept();
1050 EXPECT_TRUE(test_view->IsShowingOverlay());
1052 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1053 controller()->OnDidAuthenticateInstrument(true);
1054 controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1055 controller()->ForceFinishSubmit();
1057 RunMessageLoop();
1059 EXPECT_EQ(1, test_generated_bubble_controller()->bubbles_shown());
1060 EXPECT_EQ(last_four, test_generated_bubble_controller()->backing_card_name());
1063 // Simulates the user signing in to the dialog from the inline web contents.
1064 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, SimulateSuccessfulSignIn) {
1065 #if defined(OS_WIN)
1066 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1067 if (base::win::GetVersion() <= base::win::VERSION_XP)
1068 return;
1069 #endif
1070 browser()->profile()->GetPrefs()->SetBoolean(
1071 ::prefs::kAutofillDialogPayWithoutWallet,
1072 true);
1074 InitializeController();
1076 controller()->OnDidFetchWalletCookieValue(std::string());
1077 controller()->OnDidGetWalletItems(
1078 wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1080 NavEntryCommittedObserver sign_in_page_observer(
1081 controller()->SignInUrl(),
1082 content::NotificationService::AllSources());
1084 // Simulate a user clicking "Sign In" (which loads dialog's web contents).
1085 controller()->SignInLinkClicked();
1086 EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1088 TestableAutofillDialogView* view = controller()->GetTestableView();
1089 content::WebContents* sign_in_contents = view->GetSignInWebContents();
1090 ASSERT_TRUE(sign_in_contents);
1092 sign_in_page_observer.Wait();
1094 NavEntryCommittedObserver continue_page_observer(
1095 wallet::GetSignInContinueUrl(),
1096 content::NotificationService::AllSources());
1098 EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1100 AccountChooserModel* account_chooser_model =
1101 controller()->AccountChooserModelForTesting();
1102 EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1104 content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1105 content::Referrer(),
1106 CURRENT_TAB,
1107 content::PAGE_TRANSITION_LINK,
1108 true);
1109 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1111 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1112 continue_page_observer.Wait();
1113 content::RunAllPendingInMessageLoop();
1115 EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1117 controller()->OnDidGetWalletItems(
1118 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1120 // Wallet should now be selected and Chrome shouldn't have crashed (which can
1121 // happen if the WebContents is deleted while proccessing a nav entry commit).
1122 EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1125 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddAccount) {
1126 #if defined(OS_WIN)
1127 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1128 if (base::win::GetVersion() <= base::win::VERSION_XP)
1129 return;
1130 #endif
1132 controller()->OnDidFetchWalletCookieValue(std::string());
1133 std::vector<std::string> usernames;
1134 usernames.push_back("user_0@example.com");
1135 controller()->OnDidGetWalletItems(
1136 wallet::GetTestWalletItemsWithUsers(usernames, 0));
1138 // Switch to Autofill.
1139 AccountChooserModel* account_chooser_model =
1140 controller()->AccountChooserModelForTesting();
1141 account_chooser_model->ActivatedAt(
1142 account_chooser_model->GetItemCount() - 1);
1144 NavEntryCommittedObserver sign_in_page_observer(
1145 controller()->SignInUrl(),
1146 content::NotificationService::AllSources());
1148 // Simulate a user clicking "add account".
1149 account_chooser_model->ActivatedAt(
1150 account_chooser_model->GetItemCount() - 2);
1151 EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1153 TestableAutofillDialogView* view = controller()->GetTestableView();
1154 content::WebContents* sign_in_contents = view->GetSignInWebContents();
1155 ASSERT_TRUE(sign_in_contents);
1157 sign_in_page_observer.Wait();
1159 NavEntryCommittedObserver continue_page_observer(
1160 wallet::GetSignInContinueUrl(),
1161 content::NotificationService::AllSources());
1163 EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1165 EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1167 // User signs into new account, account 3.
1168 controller()->set_sign_in_user_index(3U);
1169 content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1170 content::Referrer(),
1171 CURRENT_TAB,
1172 content::PAGE_TRANSITION_LINK,
1173 true);
1174 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1176 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1177 continue_page_observer.Wait();
1178 content::RunAllPendingInMessageLoop();
1180 EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1181 EXPECT_EQ(3U, controller()->GetTestingWalletClient()->user_index());
1183 usernames.push_back("user_1@example.com");
1184 usernames.push_back("user_2@example.com");
1185 usernames.push_back("user_3@example.com");
1186 usernames.push_back("user_4@example.com");
1187 // Curveball: wallet items comes back with user 4 selected.
1188 controller()->OnDidGetWalletItems(
1189 wallet::GetTestWalletItemsWithUsers(usernames, 4U));
1191 EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1192 EXPECT_EQ(4U, account_chooser_model->GetActiveWalletAccountIndex());
1193 EXPECT_EQ(4U, controller()->GetTestingWalletClient()->user_index());
1196 // http://crbug.com/318526
1197 #if defined(OS_MACOSX)
1198 #define MAYBE_FillFormIncludesCVC DISABLED_FillFormIncludesCVC
1199 #else
1200 #define MAYBE_FillFormIncludesCVC FillFormIncludesCVC
1201 #endif
1202 // Verify that filling a form works correctly, including filling the CVC when
1203 // that is requested separately.
1204 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1205 MAYBE_FillFormIncludesCVC) {
1206 AutofillDialogControllerImpl* controller =
1207 SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
1208 ASSERT_TRUE(controller);
1210 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
1211 AddAutofillProfileToProfile(controller->profile(),
1212 test::GetVerifiedProfile());
1214 TestableAutofillDialogView* view = controller->GetTestableView();
1215 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1216 view->SubmitForTesting();
1217 ExpectDomMessage("success");
1218 EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
1221 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewClearsComboboxes) {
1222 // Ensure the input under test is a combobox.
1223 ASSERT_TRUE(
1224 controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH));
1226 // Set up an expired card.
1227 CreditCard card;
1228 test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
1229 card.set_origin("Chrome settings");
1230 ASSERT_TRUE(card.IsVerified());
1232 // Add the card and check that there's a menu for that section.
1233 controller()->GetTestingManager()->AddTestingCreditCard(&card);
1234 ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC));
1236 // Select the invalid, suggested card from the menu.
1237 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(0);
1238 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
1240 // Get the contents of the combobox of the credit card's expiration month.
1241 TestableAutofillDialogView* view = controller()->GetTestableView();
1242 base::string16 cc_exp_month_text =
1243 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH);
1245 // Select "New X..." from the suggestion menu to clear the section's inputs.
1246 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(1);
1247 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1249 // Ensure that the credit card expiration month has changed.
1250 EXPECT_NE(cc_exp_month_text,
1251 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH));
1254 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, TabOpensToJustRight) {
1255 ASSERT_TRUE(browser()->is_type_tabbed());
1257 // Tabs should currently be: / rAc() \.
1258 content::WebContents* dialog_invoker = controller()->GetWebContents();
1259 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1261 TabStripModel* tab_strip = browser()->tab_strip_model();
1262 ASSERT_EQ(1, tab_strip->count());
1263 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1265 // Open a tab to about:blank in the background at the end of the tab strip.
1266 chrome::AddTabAt(browser(), GURL(), -1, false);
1267 // Tabs should now be: / rAc() \/ blank \.
1268 EXPECT_EQ(2, tab_strip->count());
1269 EXPECT_EQ(0, tab_strip->active_index());
1270 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1272 content::WebContents* blank_tab = tab_strip->GetWebContentsAt(1);
1274 // Simulate clicking "Manage X...".
1275 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1276 // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1277 EXPECT_EQ(3, tab_strip->count());
1278 int dialog_index = tab_strip->GetIndexOfWebContents(dialog_invoker);
1279 EXPECT_EQ(0, dialog_index);
1280 EXPECT_EQ(1, tab_strip->active_index());
1281 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(blank_tab));
1283 content::WebContents* first_manage_tab = tab_strip->GetWebContentsAt(1);
1285 // Re-activate the dialog's tab (like a user would have to).
1286 tab_strip->ActivateTabAt(dialog_index, true);
1287 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1289 // Simulate clicking "Manage X...".
1290 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1291 // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1292 EXPECT_EQ(4, tab_strip->count());
1293 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1294 EXPECT_EQ(1, tab_strip->active_index());
1295 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(first_manage_tab));
1296 EXPECT_EQ(3, tab_strip->GetIndexOfWebContents(blank_tab));
1299 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1300 SignInWebViewOpensLinksInNewTab) {
1301 controller()->OnDidFetchWalletCookieValue(std::string());
1302 controller()->OnDidGetWalletItems(
1303 wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1305 NavEntryCommittedObserver sign_in_page_observer(
1306 controller()->SignInUrl(),
1307 content::NotificationService::AllSources());
1309 controller()->SignInLinkClicked();
1311 TestableAutofillDialogView* view = controller()->GetTestableView();
1312 content::WebContents* sign_in_contents = view->GetSignInWebContents();
1313 ASSERT_TRUE(sign_in_contents);
1315 sign_in_page_observer.Wait();
1317 content::OpenURLParams params(GURL("http://google.com"),
1318 content::Referrer(),
1319 CURRENT_TAB,
1320 content::PAGE_TRANSITION_LINK,
1321 true);
1322 params.user_gesture = true;
1324 int num_tabs = browser()->tab_strip_model()->count();
1325 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1326 EXPECT_EQ(num_tabs + 1, browser()->tab_strip_model()->count());
1329 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RefreshOnManageTabClose) {
1330 ASSERT_TRUE(browser()->is_type_tabbed());
1332 // GetWalletItems() is called when controller() is created in SetUp().
1333 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1334 controller()->OnDidFetchWalletCookieValue(std::string());
1335 controller()->OnDidGetWalletItems(
1336 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1338 content::WebContents* dialog_invoker = controller()->GetWebContents();
1339 TabAutofillManagerDelegate::FromWebContents(dialog_invoker)->
1340 SetDialogControllerForTesting(controller()->AsWeakPtr());
1342 // Open a new tab by selecting "Manage my shipping details..." in Wallet mode.
1343 EXPECT_EQ(1, browser()->tab_strip_model()->count());
1344 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1345 EXPECT_EQ(2, browser()->tab_strip_model()->count());
1346 ASSERT_NE(dialog_invoker, GetActiveWebContents());
1348 // Closing the tab opened by "Manage my shipping details..." should refresh
1349 // the dialog.
1350 controller()->ClearLastWalletItemsFetchTimestampForTesting();
1351 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1352 GetActiveWebContents()->Close();
1355 // http://crbug.com/318526
1356 #if defined(OS_MACOSX)
1357 #define MAYBE_DoesWorkOnHttpWithFlag DISABLED_DoesWorkOnHttpWithFlag
1358 #else
1359 #define MAYBE_DoesWorkOnHttpWithFlag DoesWorkOnHttpWithFlag
1360 #endif
1361 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1362 MAYBE_DoesWorkOnHttpWithFlag) {
1363 net::SpawnedTestServer http_server(
1364 net::SpawnedTestServer::TYPE_HTTP,
1365 net::SpawnedTestServer::kLocalhost,
1366 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1367 ASSERT_TRUE(http_server.Start());
1368 EXPECT_TRUE(RunTestPage(http_server));
1371 // Like the parent test, but doesn't add the --reduce-security-for-testing flag.
1372 class AutofillDialogControllerSecurityTest :
1373 public AutofillDialogControllerTest {
1374 public:
1375 AutofillDialogControllerSecurityTest() {}
1376 virtual ~AutofillDialogControllerSecurityTest() {}
1378 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1379 CHECK(!command_line->HasSwitch(::switches::kReduceSecurityForTesting));
1382 typedef net::BaseTestServer::SSLOptions SSLOptions;
1384 private:
1385 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest);
1388 // http://crbug.com/318526
1389 #if defined(OS_MACOSX)
1390 #define MAYBE_DoesntWorkOnHttp DISABLED_DoesntWorkOnHttp
1391 #else
1392 #define MAYBE_DoesntWorkOnHttp DoesntWorkOnHttp
1393 #endif
1394 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1395 MAYBE_DoesntWorkOnHttp) {
1396 net::SpawnedTestServer http_server(
1397 net::SpawnedTestServer::TYPE_HTTP,
1398 net::SpawnedTestServer::kLocalhost,
1399 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1400 ASSERT_TRUE(http_server.Start());
1401 EXPECT_FALSE(RunTestPage(http_server));
1404 // http://crbug.com/318526
1405 #if defined(OS_MACOSX)
1406 #define MAYBE_DoesWorkOnHttpWithFlags DISABLED_DoesWorkOnHttpWithFlags
1407 #else
1408 #define MAYBE_DoesWorkOnHttpWithFlags DoesWorkOnHttpWithFlags
1409 #endif
1410 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1411 MAYBE_DoesWorkOnHttpWithFlags) {
1412 net::SpawnedTestServer https_server(
1413 net::SpawnedTestServer::TYPE_HTTPS,
1414 SSLOptions(SSLOptions::CERT_OK),
1415 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1416 ASSERT_TRUE(https_server.Start());
1417 EXPECT_TRUE(RunTestPage(https_server));
1420 // http://crbug.com/318526
1421 #if defined(OS_MACOSX)
1422 #define MAYBE_DoesntWorkOnBrokenHttps DISABLED_DoesntWorkOnBrokenHttps
1423 #else
1424 #define MAYBE_DoesntWorkOnBrokenHttps DoesntWorkOnBrokenHttps
1425 #endif
1426 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1427 MAYBE_DoesntWorkOnBrokenHttps) {
1428 net::SpawnedTestServer https_server(
1429 net::SpawnedTestServer::TYPE_HTTPS,
1430 SSLOptions(SSLOptions::CERT_EXPIRED),
1431 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1432 ASSERT_TRUE(https_server.Start());
1433 EXPECT_FALSE(RunTestPage(https_server));
1436 class AutofillDialogControllerI18nTest : public AutofillDialogControllerTest {
1437 public:
1438 AutofillDialogControllerI18nTest() {}
1439 virtual ~AutofillDialogControllerI18nTest() {}
1441 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1442 command_line->AppendSwitch(::switches::kEnableAutofillAddressI18n);
1443 CHECK(i18ninput::Enabled());
1447 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerI18nTest,
1448 CountryChangeRebuildsSection) {
1449 const DetailInputs& us_billing_inputs =
1450 controller()->RequestedFieldsForSection(SECTION_BILLING);
1451 const DetailInputs& us_shipping_inputs =
1452 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
1454 // Check that there's no dependent locality for the US layout.
1455 for (size_t i = 0; i < us_billing_inputs.size(); ++i) {
1456 EXPECT_NE(us_billing_inputs[i].type, ADDRESS_BILLING_DEPENDENT_LOCALITY);
1458 for (size_t i = 0; i < us_shipping_inputs.size(); ++i) {
1459 EXPECT_NE(us_shipping_inputs[i].type, ADDRESS_HOME_DEPENDENT_LOCALITY);
1462 // Select "Add new shipping address...".
1463 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1465 // Add some valid user input that should be preserved when country changes.
1466 TestableAutofillDialogView* view = controller()->GetTestableView();
1467 view->SetTextContentsOfInput(NAME_FULL, ASCIIToUTF16("B. Loblaw"));
1469 // Change both sections' countries.
1470 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("China"));
1471 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1472 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1473 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1475 // Verify the name is still there.
1476 EXPECT_EQ(ASCIIToUTF16("B. Loblaw"), view->GetTextContentsOfInput(NAME_FULL));
1478 const DetailInputs& cn_billing_inputs =
1479 controller()->RequestedFieldsForSection(SECTION_BILLING);
1480 const DetailInputs& fr_shipping_inputs =
1481 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
1483 // Check that there is dependent locality for the Chinese layout.
1484 size_t i = 0;
1485 for (; i < cn_billing_inputs.size(); ++i) {
1486 if (cn_billing_inputs[i].type == ADDRESS_BILLING_DEPENDENT_LOCALITY)
1487 break;
1489 EXPECT_LT(i, cn_billing_inputs.size());
1491 // Check that there's a sorting code (CEDEX) for French layout.
1492 for (i = 0; i < fr_shipping_inputs.size(); ++i) {
1493 if (fr_shipping_inputs[i].type == ADDRESS_HOME_SORTING_CODE)
1494 break;
1496 EXPECT_LT(i, fr_shipping_inputs.size());
1499 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerI18nTest,
1500 ChangingDataSourcePreservesCountry) {
1501 AutofillProfile verified_profile(test::GetVerifiedProfile());
1502 controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1504 CreditCard verified_card(test::GetVerifiedCreditCard());
1505 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
1507 controller()->OnDidFetchWalletCookieValue(std::string());
1508 scoped_ptr<wallet::WalletItems> items =
1509 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1510 items->AddAccount(wallet::GetTestGaiaAccount());
1511 items->AddInstrument(wallet::GetTestMaskedInstrument());
1512 items->AddAddress(wallet::GetTestShippingAddress());
1513 controller()->OnDidGetWalletItems(items.Pass());
1515 EXPECT_TRUE(controller()->IsPayingWithWallet());
1517 // Select "Add new billing/shipping address...".
1518 controller()->MenuModelForSection(SECTION_CC_BILLING)->ActivatedAt(1);
1519 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1521 TestableAutofillDialogView* view = controller()->GetTestableView();
1522 ASSERT_EQ(ASCIIToUTF16("United States"),
1523 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1524 ASSERT_EQ(ASCIIToUTF16("United States"),
1525 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1527 // Switch both billing and shipping countries.
1528 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("China"));
1529 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1530 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1531 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1533 // Switch to using Autofill instead of Wallet.
1534 ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1535 account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1537 EXPECT_FALSE(controller()->IsPayingWithWallet());
1539 // Countries should have stayed the same.
1540 EXPECT_EQ(ASCIIToUTF16("China"),
1541 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1542 EXPECT_EQ(ASCIIToUTF16("France"),
1543 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1546 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerI18nTest, AddNewResetsCountry) {
1547 AutofillProfile verified_profile(test::GetVerifiedProfile());
1548 controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1550 // Select "Add new billing/shipping address...".
1551 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1552 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1554 TestableAutofillDialogView* view = controller()->GetTestableView();
1555 ASSERT_EQ(ASCIIToUTF16("United States"),
1556 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1557 ASSERT_EQ(ASCIIToUTF16("United States"),
1558 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1560 // Switch both billing and shipping countries.
1561 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("China"));
1562 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1563 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1564 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1566 // Select "Add new billing/shipping address...".
1567 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1568 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1570 EXPECT_EQ(ASCIIToUTF16("United States"),
1571 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1572 EXPECT_EQ(ASCIIToUTF16("United States"),
1573 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1576 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerI18nTest,
1577 FillingFormRebuildsInputs) {
1578 AutofillProfile full_profile(test::GetFullProfile());
1579 full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("CN"));
1580 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1582 // Select "Add new shipping address...".
1583 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1585 TestableAutofillDialogView* view = controller()->GetTestableView();
1586 ASSERT_EQ(ASCIIToUTF16("United States"),
1587 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1588 ASSERT_EQ(ASCIIToUTF16("United States"),
1589 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1591 base::string16 name = full_profile.GetRawInfo(NAME_FULL);
1592 view->SetTextContentsOfInput(NAME_FULL, name.substr(0, name.size() / 2));
1593 view->ActivateInput(NAME_FULL);
1594 ASSERT_EQ(NAME_FULL, controller()->popup_input_type());
1595 controller()->DidAcceptSuggestion(base::string16(), 0);
1597 EXPECT_EQ(ASCIIToUTF16("China"),
1598 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1599 EXPECT_EQ(ASCIIToUTF16("China"),
1600 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1603 } // namespace autofill