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.
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/autofill_dialog_view_tester.h"
21 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
22 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
23 #include "chrome/browser/ui/autofill/mock_address_validator.h"
24 #include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_tabstrip.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
34 #include "components/autofill/content/browser/wallet/gaia_account.h"
35 #include "components/autofill/content/browser/wallet/mock_wallet_client.h"
36 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
37 #include "components/autofill/content/browser/wallet/wallet_test_util.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_switches.h"
43 #include "components/autofill/core/common/form_data.h"
44 #include "components/autofill/core/common/form_field_data.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "content/public/browser/interstitial_page.h"
47 #include "content/public/browser/navigation_details.h"
48 #include "content/public/browser/navigation_entry.h"
49 #include "content/public/browser/notification_service.h"
50 #include "content/public/browser/notification_types.h"
51 #include "content/public/browser/page_navigator.h"
52 #include "content/public/browser/web_contents.h"
53 #include "content/public/browser/web_contents_delegate.h"
54 #include "content/public/common/content_switches.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/page_transition_types.h"
65 #include "ui/base/window_open_disposition.h"
69 #include "base/win/windows_version.h"
70 #elif defined(OS_MACOSX)
71 #include "base/mac/mac_util.h"
72 #include "base/mac/scoped_nsautorelease_pool.h"
73 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
76 using base::ASCIIToUTF16;
82 using testing::Return;
85 void MockCallback(AutofillClient::RequestAutocompleteResult,
86 const base::string16& message,
87 const FormStructure*) {
90 class MockAutofillMetrics : public AutofillMetrics {
93 : dialog_dismissal_action_(static_cast<DialogDismissalAction>(-1)) {}
94 virtual ~MockAutofillMetrics() {}
96 virtual void LogDialogUiDuration(
97 const base::TimeDelta& duration,
98 DialogDismissalAction dismissal_action) const OVERRIDE {
99 // Ignore constness for testing.
100 MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this);
101 mutable_this->dialog_dismissal_action_ = dismissal_action;
104 AutofillMetrics::DialogDismissalAction dialog_dismissal_action() const {
105 return dialog_dismissal_action_;
108 MOCK_CONST_METHOD1(LogDialogDismissalState,
109 void(DialogDismissalState state));
112 DialogDismissalAction dialog_dismissal_action_;
114 DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics);
117 class TestAutofillDialogController : public AutofillDialogControllerImpl {
119 TestAutofillDialogController(
120 content::WebContents* contents,
121 const FormData& form_data,
122 const AutofillMetrics& metric_logger,
123 scoped_refptr<content::MessageLoopRunner> runner)
124 : AutofillDialogControllerImpl(contents,
127 base::Bind(&MockCallback)),
128 metric_logger_(metric_logger),
130 Profile::FromBrowserContext(contents->GetBrowserContext())->
131 GetRequestContext(), this, form_data.origin),
132 message_loop_runner_(runner),
133 use_validation_(false),
134 sign_in_user_index_(0U),
135 weak_ptr_factory_(this) {
138 Profile::FromBrowserContext(contents->GetBrowserContext())->GetPrefs(),
142 virtual ~TestAutofillDialogController() {}
144 virtual GURL SignInUrl() const OVERRIDE {
145 return GURL(chrome::kChromeUIVersionURL);
148 virtual void ViewClosed() OVERRIDE {
149 message_loop_runner_->Quit();
150 AutofillDialogControllerImpl::ViewClosed();
153 virtual base::string16 InputValidityMessage(
154 DialogSection section,
155 ServerFieldType type,
156 const base::string16& value) OVERRIDE {
157 if (!use_validation_)
158 return base::string16();
159 return AutofillDialogControllerImpl::InputValidityMessage(
160 section, type, value);
163 virtual ValidityMessages InputsAreValid(
164 DialogSection section,
165 const FieldValueMap& inputs) OVERRIDE {
166 if (!use_validation_)
167 return ValidityMessages();
168 return AutofillDialogControllerImpl::InputsAreValid(section, inputs);
171 // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
172 // TODO(estade): test that the view defaults to saving to Chrome.
173 virtual bool ShouldOfferToSaveInChrome() const OVERRIDE {
177 void ForceFinishSubmit() {
181 // Increase visibility for testing.
182 using AutofillDialogControllerImpl::view;
183 using AutofillDialogControllerImpl::popup_input_type;
185 MOCK_METHOD0(LoadRiskFingerprintData, void());
187 virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE {
188 return notifications_;
191 void set_notifications(const std::vector<DialogNotification>& notifications) {
192 notifications_ = notifications;
195 TestPersonalDataManager* GetTestingManager() {
196 return &test_manager_;
199 MockAddressValidator* GetMockValidator() {
200 return &mock_validator_;
203 using AutofillDialogControllerImpl::IsEditingExistingData;
204 using AutofillDialogControllerImpl::IsManuallyEditingSection;
205 using AutofillDialogControllerImpl::IsPayingWithWallet;
206 using AutofillDialogControllerImpl::IsSubmitPausedOn;
207 using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
208 using AutofillDialogControllerImpl::AccountChooserModelForTesting;
209 using AutofillDialogControllerImpl::
210 ClearLastWalletItemsFetchTimestampForTesting;
212 void set_use_validation(bool use_validation) {
213 use_validation_ = use_validation;
216 base::WeakPtr<TestAutofillDialogController> AsWeakPtr() {
217 return weak_ptr_factory_.GetWeakPtr();
220 wallet::MockWalletClient* GetTestingWalletClient() {
221 return &mock_wallet_client_;
224 void set_sign_in_user_index(size_t sign_in_user_index) {
225 sign_in_user_index_ = sign_in_user_index;
229 virtual PersonalDataManager* GetManager() const OVERRIDE {
230 return &const_cast<TestAutofillDialogController*>(this)->test_manager_;
233 virtual AddressValidator* GetValidator() OVERRIDE {
234 return &mock_validator_;
237 virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
238 return &mock_wallet_client_;
241 virtual bool IsSignInContinueUrl(const GURL& url, size_t* user_index) const
243 *user_index = sign_in_user_index_;
244 return url == wallet::GetSignInContinueUrl();
248 // To specify our own metric logger.
249 virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
250 return metric_logger_;
253 const AutofillMetrics& metric_logger_;
254 TestPersonalDataManager test_manager_;
255 testing::NiceMock<MockAddressValidator> mock_validator_;
256 testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
257 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
258 bool use_validation_;
260 // A list of notifications to show in the notification area of the dialog.
261 // This is used to control what |CurrentNotifications()| returns for testing.
262 std::vector<DialogNotification> notifications_;
264 // The user index that is assigned in IsSignInContinueUrl().
265 size_t sign_in_user_index_;
267 // Allows generation of WeakPtrs, so controller liveness can be tested.
268 base::WeakPtrFactory<TestAutofillDialogController> weak_ptr_factory_;
270 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
273 // This is a copy of ui_test_utils::UrlLoadObserver, except it observes
274 // NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
275 // that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
276 // before LOAD_STOP, and the controller deletes the web contents after receiving
277 // the former, we will sometimes fail to observe a LOAD_STOP.
278 // TODO(estade): Should the controller observe LOAD_STOP instead?
279 class NavEntryCommittedObserver : public content::WindowedNotificationObserver {
281 NavEntryCommittedObserver(const GURL& url,
282 const content::NotificationSource& source)
283 : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED,
287 virtual ~NavEntryCommittedObserver() {}
289 // content::NotificationObserver:
290 virtual void Observe(int type,
291 const content::NotificationSource& source,
292 const content::NotificationDetails& details) OVERRIDE {
293 content::LoadCommittedDetails* load_details =
294 content::Details<content::LoadCommittedDetails>(details).ptr();
295 if (load_details->entry->GetVirtualURL() != url_)
298 WindowedNotificationObserver::Observe(type, source, details);
304 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
309 class AutofillDialogControllerTest : public InProcessBrowserTest {
311 AutofillDialogControllerTest() : controller_(NULL) {}
312 virtual ~AutofillDialogControllerTest() {}
314 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
315 command_line->AppendSwitch(::switches::kReduceSecurityForTesting);
318 virtual void SetUpOnMainThread() OVERRIDE {
319 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
320 InitializeController();
324 bool SectionHasField(DialogSection section, ServerFieldType type) {
325 const DetailInputs& fields =
326 controller()->RequestedFieldsForSection(section);
327 for (size_t i = 0; i < fields.size(); ++i) {
328 if (type == fields[i].type)
334 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
335 // loop. It also drains the NSAutoreleasePool.
336 void CycleRunLoops() {
337 content::RunAllPendingInMessageLoop();
338 #if defined(OS_MACOSX)
339 chrome::testing::NSRunLoopRunAllPending();
340 AutoreleasePool()->Recycle();
344 void InitializeControllerWithoutShowing() {
349 form.name = ASCIIToUTF16("TestForm");
350 form.user_submitted = true;
353 field.autocomplete_attribute = "shipping tel";
354 form.fields.push_back(field);
357 cc.autocomplete_attribute = "cc-number";
358 form.fields.push_back(cc);
360 test_generated_bubble_controller_ =
361 new testing::NiceMock<TestGeneratedCreditCardBubbleController>(
362 GetActiveWebContents());
363 ASSERT_TRUE(test_generated_bubble_controller_->IsInstalled());
365 message_loop_runner_ = new content::MessageLoopRunner;
366 controller_ = new TestAutofillDialogController(
367 GetActiveWebContents(),
370 message_loop_runner_);
373 void InitializeController() {
374 InitializeControllerWithoutShowing();
376 CycleRunLoops(); // Ensures dialog is fully visible.
379 content::WebContents* GetActiveWebContents() {
380 return browser()->tab_strip_model()->GetActiveWebContents();
383 content::RenderViewHost* GetRenderViewHost() {
384 return GetActiveWebContents()->GetRenderViewHost();
387 scoped_ptr<AutofillDialogViewTester> GetViewTester() {
388 return AutofillDialogViewTester::For(controller()->view()).Pass();
391 const MockAutofillMetrics& metric_logger() { return metric_logger_; }
392 TestAutofillDialogController* controller() { return controller_; }
394 void RunMessageLoop() {
395 message_loop_runner_->Run();
398 // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
399 // <form>|form_inner_html|</form>. After loading, emulates a click event on
400 // the page as requestAutocomplete() must be in response to a user gesture.
401 // Returns the |AutofillDialogControllerImpl| created by this invocation.
402 AutofillDialogControllerImpl* SetUpHtmlAndInvoke(
403 const std::string& form_inner_html) {
404 content::WebContents* contents = GetActiveWebContents();
405 ChromeAutofillClient* client =
406 ChromeAutofillClient::FromWebContents(contents);
407 CHECK(!client->GetDialogControllerForTesting());
409 ui_test_utils::NavigateToURL(
410 browser(), GURL(std::string("data:text/html,") +
414 "<form>" + form_inner_html + "</form>"
416 "var invalidEvents = [];"
417 "function recordInvalid(e) {"
418 "if (e.type != 'invalid') throw 'only invalid events allowed';"
419 "invalidEvents.push(e);"
421 "function send(msg) {"
422 "domAutomationController.setAutomationId(0);"
423 "domAutomationController.send(msg);"
425 "document.forms[0].onautocompleteerror = function(e) {"
426 "send('error: ' + e.reason);"
428 "document.forms[0].onautocomplete = function() {"
431 "window.onclick = function() {"
432 "var inputs = document.forms[0].querySelectorAll('input');"
433 "for (var i = 0; i < inputs.length; ++i) {"
434 "inputs[i].oninvalid = recordInvalid;"
436 "document.forms[0].requestAutocomplete();"
439 "function loadIframe() {"
440 " var iframe = document.createElement('iframe');"
441 " iframe.onload = function() {"
442 " send('iframe loaded');"
444 " iframe.src = 'about:blank';"
445 " document.body.appendChild(iframe);"
447 "function getValueForFieldOfType(type) {"
448 " var fields = document.getElementsByTagName('input');"
449 " for (var i = 0; i < fields.length; i++) {"
450 " if (fields[i].autocomplete == type) {"
451 " send(fields[i].value);"
462 AutofillDialogControllerImpl* controller =
463 static_cast<AutofillDialogControllerImpl*>(
464 client->GetDialogControllerForTesting());
468 // Loads an html page on a provided server, the causes it to launch rAc.
469 // Returns whether rAc succesfully launched.
470 bool RunTestPage(const net::SpawnedTestServer& server) {
471 GURL url = server.GetURL(
472 "files/request_autocomplete/test_page.html");
473 ui_test_utils::NavigateToURL(browser(), url);
475 // Pass through the broken SSL interstitial, if any.
476 content::WebContents* contents = GetActiveWebContents();
477 content::InterstitialPage* interstitial_page =
478 contents->GetInterstitialPage();
479 if (interstitial_page) {
480 ui_test_utils::UrlLoadObserver observer(
482 content::Source<content::NavigationController>(
483 &contents->GetController()));
484 interstitial_page->Proceed();
490 ChromeAutofillClient* client =
491 ChromeAutofillClient::FromWebContents(contents);
492 AutofillDialogControllerImpl* controller =
493 static_cast<AutofillDialogControllerImpl*>(
494 client->GetDialogControllerForTesting());
498 // Wait for a message from the DOM automation controller (from JS in the
499 // page). Requires |SetUpHtmlAndInvoke()| be called first.
500 void ExpectDomMessage(const std::string& expected) {
502 ASSERT_TRUE(dom_message_queue_->WaitForMessage(&message));
503 dom_message_queue_->ClearQueue();
504 EXPECT_EQ("\"" + expected + "\"", message);
507 void InitiateDialog() {
508 dom_message_queue_.reset(new content::DOMMessageQueue);
510 // Triggers the onclick handler which invokes requestAutocomplete().
511 content::WebContents* contents = GetActiveWebContents();
512 content::SimulateMouseClick(contents, 0, blink::WebMouseEvent::ButtonLeft);
513 ExpectDomMessage("clicked");
516 // Returns the value filled into the first field with autocomplete attribute
517 // equal to |autocomplete_type|, or an empty string if there is no such field.
518 std::string GetValueForHTMLFieldOfType(const std::string& autocomplete_type) {
519 std::string script = "getValueForFieldOfType('" + autocomplete_type + "');";
521 EXPECT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
527 void AddCreditcardToProfile(Profile* profile, const CreditCard& card) {
528 PersonalDataManagerFactory::GetForProfile(profile)->AddCreditCard(card);
532 void AddAutofillProfileToProfile(Profile* profile,
533 const AutofillProfile& autofill_profile) {
534 PersonalDataManagerFactory::GetForProfile(profile)->AddProfile(
539 TestGeneratedCreditCardBubbleController* test_generated_bubble_controller() {
540 return test_generated_bubble_controller_;
544 void WaitForWebDB() {
545 content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
548 testing::NiceMock<MockAutofillMetrics> metric_logger_;
549 TestAutofillDialogController* controller_; // Weak reference.
550 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
551 scoped_ptr<content::DOMMessageQueue> dom_message_queue_;
553 // Weak; owned by the active web contents.
554 TestGeneratedCreditCardBubbleController* test_generated_bubble_controller_;
556 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
559 // Submit the form data.
560 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
561 GetViewTester()->SubmitForTesting();
564 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
565 metric_logger().dialog_dismissal_action());
568 // Cancel out of the dialog.
569 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) {
570 EXPECT_CALL(metric_logger(),
571 LogDialogDismissalState(
572 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS));
574 GetViewTester()->CancelForTesting();
577 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
578 metric_logger().dialog_dismissal_action());
581 // Take some other action that dismisses the dialog.
582 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) {
583 EXPECT_CALL(metric_logger(),
584 LogDialogDismissalState(
585 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS));
586 controller()->Hide();
590 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
591 metric_logger().dialog_dismissal_action());
594 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CancelWithSuggestions) {
595 EXPECT_CALL(metric_logger(),
596 LogDialogDismissalState(
597 AutofillMetrics::DIALOG_CANCELED_NO_EDITS));
599 CreditCard card(test::GetVerifiedCreditCard());
600 controller()->GetTestingManager()->AddTestingCreditCard(&card);
601 AutofillProfile profile(test::GetVerifiedProfile());
602 controller()->GetTestingManager()->AddTestingProfile(&profile);
604 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
605 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
606 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
608 GetViewTester()->CancelForTesting();
611 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
612 metric_logger().dialog_dismissal_action());
615 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AcceptWithSuggestions) {
616 EXPECT_CALL(metric_logger(),
617 LogDialogDismissalState(
618 AutofillMetrics::DIALOG_ACCEPTED_EXISTING_AUTOFILL_DATA));
620 CreditCard card(test::GetVerifiedCreditCard());
621 controller()->GetTestingManager()->AddTestingCreditCard(&card);
622 AutofillProfile profile(test::GetVerifiedProfile());
623 controller()->GetTestingManager()->AddTestingProfile(&profile);
625 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
626 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
627 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
629 GetViewTester()->SubmitForTesting();
632 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
633 metric_logger().dialog_dismissal_action());
636 // Ensure that Hide() will only destroy the controller object after the
637 // message loop has run. Otherwise, there may be read-after-free issues
638 // during some tests.
639 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, DeferredDestruction) {
640 base::WeakPtr<TestAutofillDialogController> weak_ptr =
641 controller()->AsWeakPtr();
642 EXPECT_TRUE(weak_ptr.get());
644 controller()->Hide();
645 EXPECT_TRUE(weak_ptr.get());
648 EXPECT_FALSE(weak_ptr.get());
651 // Ensure that the expected metric is logged when the dialog is closed during
653 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CloseDuringSignin) {
654 controller()->SignInLinkClicked();
656 EXPECT_CALL(metric_logger(),
657 LogDialogDismissalState(
658 AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN));
659 GetViewTester()->CancelForTesting();
663 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
664 metric_logger().dialog_dismissal_action());
667 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
668 AutofillProfile full_profile(test::GetFullProfile());
669 const base::string16 formatted_phone(ASCIIToUTF16("+1 (310) 555 1234"));
670 full_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, formatted_phone);
671 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
673 // Dialog is already asking for a new billing address.
674 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
676 // Select "Add new shipping address...".
677 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_SHIPPING);
678 model->ActivatedAt(model->GetItemCount() - 2);
679 ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
681 // Enter something in a shipping input.
682 const DetailInputs& inputs =
683 controller()->RequestedFieldsForSection(SECTION_SHIPPING);
684 const ServerFieldType triggering_type = inputs[0].type;
685 base::string16 value = full_profile.GetRawInfo(triggering_type);
686 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
687 view->SetTextContentsOfInput(triggering_type,
688 value.substr(0, value.size() / 2));
689 view->ActivateInput(triggering_type);
691 ASSERT_EQ(triggering_type, controller()->popup_input_type());
692 controller()->DidAcceptSuggestion(base::string16(), 0);
694 // All inputs should be filled.
695 AutofillProfileWrapper wrapper(&full_profile);
696 for (size_t i = 0; i < inputs.size(); ++i) {
697 EXPECT_EQ(wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)),
698 view->GetTextContentsOfInput(inputs[i].type));
700 // Double check the correct formatting is used for the phone number.
701 if (inputs[i].type == PHONE_HOME_WHOLE_NUMBER)
702 EXPECT_EQ(formatted_phone, view->GetTextContentsOfInput(inputs[i].type));
705 // Inputs from the other section (billing) should be left alone.
706 const DetailInputs& other_section_inputs =
707 controller()->RequestedFieldsForSection(SECTION_BILLING);
708 for (size_t i = 0; i < inputs.size(); ++i) {
709 base::string16 input_value =
710 view->GetTextContentsOfInput(other_section_inputs[i].type);
711 // If there's a combobox, the string should be non-empty.
712 if (controller()->ComboboxModelForAutofillType(
713 other_section_inputs[i].type)) {
714 EXPECT_NE(base::string16(), input_value);
716 EXPECT_EQ(base::string16(), input_value);
720 // Now simulate some user edits and try again.
721 std::vector<base::string16> expectations;
722 for (size_t i = 0; i < inputs.size(); ++i) {
723 if (controller()->ComboboxModelForAutofillType(inputs[i].type)) {
724 expectations.push_back(base::string16());
727 base::string16 users_input = i % 2 == 0 ? base::string16()
728 : ASCIIToUTF16("dummy");
729 view->SetTextContentsOfInput(inputs[i].type, users_input);
730 // Empty inputs should be filled, others should be left alone.
731 base::string16 expectation =
732 inputs[i].type == triggering_type || users_input.empty() ?
733 wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)) :
735 expectations.push_back(expectation);
738 view->SetTextContentsOfInput(triggering_type,
739 value.substr(0, value.size() / 2));
740 view->ActivateInput(triggering_type);
741 ASSERT_EQ(triggering_type, controller()->popup_input_type());
742 controller()->DidAcceptSuggestion(base::string16(), 0);
744 for (size_t i = 0; i < inputs.size(); ++i) {
745 if (controller()->ComboboxModelForAutofillType(inputs[i].type))
747 EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i].type));
750 EXPECT_CALL(metric_logger(),
751 LogDialogDismissalState(
752 AutofillMetrics::DIALOG_ACCEPTED_SAVE_TO_AUTOFILL));
753 view->SubmitForTesting();
756 // This test makes sure that picking a profile variant in the Autofill
757 // popup works as expected.
758 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
759 FillInputFromAutofillVariant) {
760 AutofillProfile full_profile(test::GetFullProfile());
762 // Set up some variant data.
763 std::vector<base::string16> names;
764 names.push_back(ASCIIToUTF16("John Doe"));
765 names.push_back(ASCIIToUTF16("Jane Doe"));
766 full_profile.SetRawMultiInfo(NAME_FULL, names);
767 std::vector<base::string16> emails;
768 emails.push_back(ASCIIToUTF16("user@example.com"));
769 emails.push_back(ASCIIToUTF16("admin@example.com"));
770 full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
771 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
773 const DetailInputs& inputs =
774 controller()->RequestedFieldsForSection(SECTION_BILLING);
775 const ServerFieldType triggering_type = inputs[0].type;
776 EXPECT_EQ(NAME_BILLING_FULL, triggering_type);
777 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
778 view->ActivateInput(triggering_type);
780 ASSERT_EQ(triggering_type, controller()->popup_input_type());
782 // Choose the variant suggestion.
783 controller()->DidAcceptSuggestion(base::string16(), 1);
785 // All inputs should be filled.
786 AutofillProfileWrapper wrapper(
787 &full_profile, AutofillType(NAME_BILLING_FULL), 1);
788 for (size_t i = 0; i < inputs.size(); ++i) {
789 EXPECT_EQ(wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)),
790 view->GetTextContentsOfInput(inputs[i].type));
793 // Make sure the wrapper applies the variant index to the right group.
794 EXPECT_EQ(names[1], wrapper.GetInfo(AutofillType(NAME_BILLING_FULL)));
795 // Make sure the wrapper doesn't apply the variant index to the wrong group.
796 EXPECT_EQ(emails[0], wrapper.GetInfo(AutofillType(EMAIL_ADDRESS)));
799 // Tests that changing the value of a CC expiration date combobox works as
800 // expected when Autofill is used to fill text inputs.
802 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
804 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
806 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
808 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
809 MAYBE_FillComboboxFromAutofill) {
811 test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
812 controller()->GetTestingManager()->AddTestingCreditCard(&card1);
814 test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017");
815 controller()->GetTestingManager()->AddTestingCreditCard(&card2);
816 AutofillProfile full_profile(test::GetFullProfile());
817 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
819 const DetailInputs& inputs =
820 controller()->RequestedFieldsForSection(SECTION_CC);
821 const ServerFieldType triggering_type = inputs[0].type;
822 base::string16 value = card1.GetRawInfo(triggering_type);
823 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
824 view->SetTextContentsOfInput(triggering_type,
825 value.substr(0, value.size() / 2));
826 view->ActivateInput(triggering_type);
828 ASSERT_EQ(triggering_type, controller()->popup_input_type());
829 controller()->DidAcceptSuggestion(base::string16(), 0);
831 // All inputs should be filled.
832 AutofillCreditCardWrapper wrapper1(&card1);
833 for (size_t i = 0; i < inputs.size(); ++i) {
834 EXPECT_EQ(wrapper1.GetInfo(AutofillType(inputs[i].type)),
835 view->GetTextContentsOfInput(inputs[i].type));
838 // Try again with different data. Only expiration date and the triggering
839 // input should be overwritten.
840 value = card2.GetRawInfo(triggering_type);
841 view->SetTextContentsOfInput(triggering_type,
842 value.substr(0, value.size() / 2));
843 view->ActivateInput(triggering_type);
844 ASSERT_EQ(triggering_type, controller()->popup_input_type());
845 controller()->DidAcceptSuggestion(base::string16(), 0);
847 AutofillCreditCardWrapper wrapper2(&card2);
848 for (size_t i = 0; i < inputs.size(); ++i) {
849 const ServerFieldType type = inputs[i].type;
850 if (type == triggering_type ||
851 type == CREDIT_CARD_EXP_MONTH ||
852 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
853 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
854 view->GetTextContentsOfInput(type));
855 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
856 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
858 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
859 view->GetTextContentsOfInput(type));
863 // Now fill from a profile. It should not overwrite any CC info.
864 const DetailInputs& billing_inputs =
865 controller()->RequestedFieldsForSection(SECTION_BILLING);
866 const ServerFieldType billing_triggering_type = billing_inputs[0].type;
867 value = full_profile.GetRawInfo(triggering_type);
868 view->SetTextContentsOfInput(billing_triggering_type,
869 value.substr(0, value.size() / 2));
870 view->ActivateInput(billing_triggering_type);
872 ASSERT_EQ(billing_triggering_type, controller()->popup_input_type());
873 controller()->DidAcceptSuggestion(base::string16(), 0);
875 for (size_t i = 0; i < inputs.size(); ++i) {
876 const ServerFieldType type = inputs[i].type;
877 if (type == triggering_type ||
878 type == CREDIT_CARD_EXP_MONTH ||
879 type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
880 EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
881 view->GetTextContentsOfInput(type));
882 } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
883 EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
885 EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
886 view->GetTextContentsOfInput(type));
891 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
892 controller()->set_use_validation(true);
893 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
895 CreditCard card(test::GetCreditCard());
896 ASSERT_FALSE(card.IsVerified());
897 controller()->GetTestingManager()->AddTestingCreditCard(&card);
899 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC));
900 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
901 view->SetTextContentsOfInput(
903 card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
905 view->ActivateInput(CREDIT_CARD_NUMBER);
906 EXPECT_FALSE(controller()->ShouldShowErrorBubble());
908 controller()->FocusMoved();
909 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
911 EXPECT_CALL(metric_logger(),
912 LogDialogDismissalState(
913 AutofillMetrics::DIALOG_CANCELED_WITH_INVALID_FIELDS));
914 controller()->Hide();
917 // Ensure that expired cards trigger invalid suggestions.
918 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
919 CreditCard verified_card(test::GetCreditCard());
920 verified_card.set_origin("Chrome settings");
921 ASSERT_TRUE(verified_card.IsVerified());
922 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
924 CreditCard expired_card(test::GetCreditCard());
925 expired_card.set_origin("Chrome settings");
926 expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
927 ASSERT_TRUE(expired_card.IsVerified());
929 autofill::IsValidCreditCardExpirationDate(
930 expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR),
931 expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH),
933 controller()->GetTestingManager()->AddTestingCreditCard(&expired_card);
935 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC);
936 ASSERT_EQ(4, model->GetItemCount());
938 ASSERT_TRUE(model->IsItemCheckedAt(0));
939 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
941 model->ActivatedAt(1);
942 ASSERT_TRUE(model->IsItemCheckedAt(1));
943 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
946 // Notifications with long message text should not make the dialog bigger.
947 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) {
948 const gfx::Size no_notification_size = GetViewTester()->GetSize();
949 ASSERT_GT(no_notification_size.width(), 0);
951 std::vector<DialogNotification> notifications;
952 notifications.push_back(
953 DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16(
954 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
955 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
956 "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
957 "aliquip ex ea commodo consequat. Duis aute irure dolor in "
958 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
959 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
960 "culpa qui officia deserunt mollit anim id est laborum.")));
961 controller()->set_notifications(notifications);
962 controller()->view()->UpdateNotificationArea();
964 EXPECT_EQ(no_notification_size.width(),
965 GetViewTester()->GetSize().width());
968 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocompleteEvent) {
969 AutofillDialogControllerImpl* controller =
970 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
971 ASSERT_TRUE(controller);
973 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
974 AddAutofillProfileToProfile(controller->profile(),
975 test::GetVerifiedProfile());
977 scoped_ptr<AutofillDialogViewTester> view =
978 AutofillDialogViewTester::For(
979 static_cast<TestAutofillDialogController*>(controller)->view());
980 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
981 view->SubmitForTesting();
982 ExpectDomMessage("success");
985 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
986 AutocompleteErrorEventReasonInvalid) {
987 AutofillDialogControllerImpl* controller =
988 SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
989 ASSERT_TRUE(controller);
991 const CreditCard& credit_card = test::GetVerifiedCreditCard();
993 credit_card.GetRawInfo(CREDIT_CARD_NAME).find(ASCIIToUTF16("zebra")) ==
994 base::string16::npos);
995 AddCreditcardToProfile(controller->profile(), credit_card);
996 AddAutofillProfileToProfile(controller->profile(),
997 test::GetVerifiedProfile());
999 scoped_ptr<AutofillDialogViewTester> view =
1000 AutofillDialogViewTester::For(
1001 static_cast<TestAutofillDialogController*>(controller)->view());
1002 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1003 view->SubmitForTesting();
1004 ExpectDomMessage("error: invalid");
1006 int invalid_count = -1;
1007 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1008 GetRenderViewHost(), "send(invalidEvents.length);", &invalid_count));
1009 EXPECT_EQ(1, invalid_count);
1011 std::string invalid_type;
1012 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1013 GetRenderViewHost(),
1014 "send(invalidEvents[0].target.autocomplete);",
1016 EXPECT_EQ("cc-name", invalid_type);
1019 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1020 AutocompleteErrorEventReasonCancel) {
1021 AutofillDialogControllerImpl* controller =
1022 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
1023 ASSERT_TRUE(controller);
1024 AutofillDialogViewTester::For(
1025 static_cast<TestAutofillDialogController*>(controller)->view())->
1027 ExpectDomMessage("error: cancel");
1030 // http://crbug.com/318526
1031 #if defined(OS_MACOSX)
1032 #define MAYBE_ErrorWithFrameNavigation DISABLED_ErrorWithFrameNavigation
1034 #define MAYBE_ErrorWithFrameNavigation ErrorWithFrameNavigation
1036 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1037 MAYBE_ErrorWithFrameNavigation) {
1038 AutofillDialogControllerImpl* controller =
1039 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
1040 ASSERT_TRUE(controller);
1043 ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
1046 ExpectDomMessage("iframe loaded");
1048 AutofillDialogViewTester::For(
1049 static_cast<TestAutofillDialogController*>(controller)->view())->
1051 ExpectDomMessage("error: cancel");
1054 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
1055 controller()->set_use_validation(true);
1057 CreditCard credit_card(test::GetVerifiedCreditCard());
1058 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1059 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1061 ASSERT_NO_FATAL_FAILURE(GetViewTester()->SubmitForTesting());
1064 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
1066 #define MAYBE_PreservedSections DISABLED_PreservedSections
1068 #define MAYBE_PreservedSections PreservedSections
1070 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_PreservedSections) {
1071 controller()->set_use_validation(true);
1073 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1074 view->SetTextContentsOfInput(CREDIT_CARD_NUMBER,
1075 ASCIIToUTF16("4111111111111111"));
1077 // Create some invalid, manually inputted shipping data.
1078 view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("shipping zip"));
1080 // Switch to Wallet by simulating a successful server response.
1081 controller()->OnDidFetchWalletCookieValue(std::string());
1082 controller()->OnDidGetWalletItems(
1083 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1084 ASSERT_TRUE(controller()->IsPayingWithWallet());
1086 // The valid data should be preserved.
1087 EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
1088 view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
1090 // The invalid data should be dropped.
1091 EXPECT_TRUE(view->GetTextContentsOfInput(ADDRESS_HOME_ZIP).empty());
1093 // Switch back to Autofill.
1094 ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1095 account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1096 ASSERT_FALSE(controller()->IsPayingWithWallet());
1098 // The valid data should still be preserved when switched back.
1099 EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
1100 view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
1103 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1104 GeneratedCardLastFourAfterVerifyCvv) {
1105 controller()->OnDidFetchWalletCookieValue(std::string());
1107 scoped_ptr<wallet::WalletItems> wallet_items =
1108 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1109 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1110 wallet_items->AddAddress(wallet::GetTestShippingAddress());
1112 base::string16 last_four =
1113 wallet_items->instruments()[0]->TypeAndLastFourDigits();
1114 controller()->OnDidGetWalletItems(wallet_items.Pass());
1116 scoped_ptr<AutofillDialogViewTester> test_view = GetViewTester();
1117 EXPECT_FALSE(test_view->IsShowingOverlay());
1118 EXPECT_CALL(*controller(), LoadRiskFingerprintData());
1119 controller()->OnAccept();
1120 EXPECT_TRUE(test_view->IsShowingOverlay());
1122 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1123 scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
1124 fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
1126 controller()->OnDidLoadRiskFingerprintData(fingerprint.Pass());
1128 controller()->OnDidGetFullWallet(
1129 wallet::GetTestFullWalletWithRequiredActions(
1130 std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
1132 ASSERT_TRUE(controller()->IsSubmitPausedOn(wallet::VERIFY_CVV));
1134 std::string fake_cvc("123");
1135 test_view->SetTextContentsOfSuggestionInput(SECTION_CC_BILLING,
1136 ASCIIToUTF16(fake_cvc));
1138 EXPECT_FALSE(test_view->IsShowingOverlay());
1139 EXPECT_CALL(*controller()->GetTestingWalletClient(),
1140 AuthenticateInstrument(_, fake_cvc));
1141 controller()->OnAccept();
1142 EXPECT_TRUE(test_view->IsShowingOverlay());
1144 EXPECT_CALL(metric_logger(),
1145 LogDialogDismissalState(
1146 AutofillMetrics::DIALOG_ACCEPTED_EXISTING_WALLET_DATA));
1148 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1149 controller()->OnDidAuthenticateInstrument(true);
1150 controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1151 controller()->ForceFinishSubmit();
1155 EXPECT_EQ(1, test_generated_bubble_controller()->bubbles_shown());
1156 EXPECT_EQ(last_four, test_generated_bubble_controller()->backing_card_name());
1159 // Simulates the user signing in to the dialog from the inline web contents.
1160 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, SimulateSuccessfulSignIn) {
1162 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1163 if (base::win::GetVersion() <= base::win::VERSION_XP)
1166 browser()->profile()->GetPrefs()->SetBoolean(
1167 ::prefs::kAutofillDialogPayWithoutWallet,
1170 InitializeController();
1172 controller()->OnDidFetchWalletCookieValue(std::string());
1173 controller()->OnDidGetWalletItems(
1174 wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1176 NavEntryCommittedObserver sign_in_page_observer(
1177 controller()->SignInUrl(),
1178 content::NotificationService::AllSources());
1180 // Simulate a user clicking "Sign In" (which loads dialog's web contents).
1181 controller()->SignInLinkClicked();
1182 EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1184 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1185 content::WebContents* sign_in_contents = view->GetSignInWebContents();
1186 ASSERT_TRUE(sign_in_contents);
1188 sign_in_page_observer.Wait();
1190 NavEntryCommittedObserver continue_page_observer(
1191 wallet::GetSignInContinueUrl(),
1192 content::NotificationService::AllSources());
1194 EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1196 AccountChooserModel* account_chooser_model =
1197 controller()->AccountChooserModelForTesting();
1198 EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1200 content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1201 content::Referrer(),
1203 ui::PAGE_TRANSITION_LINK,
1206 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1208 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1209 continue_page_observer.Wait();
1210 content::RunAllPendingInMessageLoop();
1212 EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1214 scoped_ptr<wallet::WalletItems> wallet_items =
1215 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1216 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1217 controller()->OnDidGetWalletItems(wallet_items.Pass());
1219 // Wallet should now be selected and Chrome shouldn't have crashed (which can
1220 // happen if the WebContents is deleted while proccessing a nav entry commit).
1221 EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1222 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC_BILLING));
1223 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1225 EXPECT_CALL(metric_logger(),
1226 LogDialogDismissalState(
1227 AutofillMetrics::DIALOG_ACCEPTED_EXISTING_WALLET_DATA));
1228 view->SubmitForTesting();
1229 controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1230 controller()->ForceFinishSubmit();
1233 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddAccount) {
1235 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1236 if (base::win::GetVersion() <= base::win::VERSION_XP)
1240 controller()->OnDidFetchWalletCookieValue(std::string());
1241 std::vector<std::string> usernames;
1242 usernames.push_back("user_0@example.com");
1243 controller()->OnDidGetWalletItems(
1244 wallet::GetTestWalletItemsWithUsers(usernames, 0));
1246 // Switch to Autofill.
1247 AccountChooserModel* account_chooser_model =
1248 controller()->AccountChooserModelForTesting();
1249 account_chooser_model->ActivatedAt(
1250 account_chooser_model->GetItemCount() - 1);
1252 NavEntryCommittedObserver sign_in_page_observer(
1253 controller()->SignInUrl(),
1254 content::NotificationService::AllSources());
1256 // Simulate a user clicking "add account".
1257 account_chooser_model->ActivatedAt(
1258 account_chooser_model->GetItemCount() - 2);
1259 EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1261 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1262 content::WebContents* sign_in_contents = view->GetSignInWebContents();
1263 ASSERT_TRUE(sign_in_contents);
1265 sign_in_page_observer.Wait();
1267 NavEntryCommittedObserver continue_page_observer(
1268 wallet::GetSignInContinueUrl(),
1269 content::NotificationService::AllSources());
1271 EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1273 EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1275 // User signs into new account, account 3.
1276 controller()->set_sign_in_user_index(3U);
1277 content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1278 content::Referrer(),
1280 ui::PAGE_TRANSITION_LINK,
1282 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1284 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1285 continue_page_observer.Wait();
1286 content::RunAllPendingInMessageLoop();
1288 EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1289 EXPECT_EQ(3U, controller()->GetTestingWalletClient()->user_index());
1291 usernames.push_back("user_1@example.com");
1292 usernames.push_back("user_2@example.com");
1293 usernames.push_back("user_3@example.com");
1294 usernames.push_back("user_4@example.com");
1295 // Curveball: wallet items comes back with user 4 selected.
1296 controller()->OnDidGetWalletItems(
1297 wallet::GetTestWalletItemsWithUsers(usernames, 4U));
1299 EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1300 EXPECT_EQ(4U, account_chooser_model->GetActiveWalletAccountIndex());
1301 EXPECT_EQ(4U, controller()->GetTestingWalletClient()->user_index());
1304 // Verify that filling a form works correctly, including filling the CVC when
1305 // that is requested separately.
1306 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1307 FillFormIncludesCVC) {
1308 AutofillDialogControllerImpl* controller =
1309 SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
1310 ASSERT_TRUE(controller);
1312 AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
1313 AddAutofillProfileToProfile(controller->profile(),
1314 test::GetVerifiedProfile());
1316 scoped_ptr<AutofillDialogViewTester> view =
1317 AutofillDialogViewTester::For(
1318 static_cast<TestAutofillDialogController*>(controller)->view());
1319 view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1320 view->SubmitForTesting();
1321 ExpectDomMessage("success");
1322 EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
1325 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewClearsComboboxes) {
1326 // Ensure the input under test is a combobox.
1328 controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH));
1330 // Set up an expired card.
1332 test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
1333 card.set_origin("Chrome settings");
1334 ASSERT_TRUE(card.IsVerified());
1336 // Add the card and check that there's a menu for that section.
1337 controller()->GetTestingManager()->AddTestingCreditCard(&card);
1338 ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC));
1340 // Select the invalid, suggested card from the menu.
1341 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(0);
1342 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
1344 // Get the contents of the combobox of the credit card's expiration month.
1345 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1346 base::string16 cc_exp_month_text =
1347 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH);
1349 // Select "New X..." from the suggestion menu to clear the section's inputs.
1350 controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(1);
1351 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1353 // Ensure that the credit card expiration month has changed.
1354 EXPECT_NE(cc_exp_month_text,
1355 view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH));
1358 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, TabOpensToJustRight) {
1359 ASSERT_TRUE(browser()->is_type_tabbed());
1361 // Tabs should currently be: / rAc() \.
1362 content::WebContents* dialog_invoker = controller()->GetWebContents();
1363 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1365 TabStripModel* tab_strip = browser()->tab_strip_model();
1366 ASSERT_EQ(1, tab_strip->count());
1367 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1369 // Open a tab to about:blank in the background at the end of the tab strip.
1370 chrome::AddTabAt(browser(), GURL(), -1, false);
1371 // Tabs should now be: / rAc() \/ blank \.
1372 EXPECT_EQ(2, tab_strip->count());
1373 EXPECT_EQ(0, tab_strip->active_index());
1374 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1376 content::WebContents* blank_tab = tab_strip->GetWebContentsAt(1);
1378 // Simulate clicking "Manage X...".
1379 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1380 // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1381 EXPECT_EQ(3, tab_strip->count());
1382 int dialog_index = tab_strip->GetIndexOfWebContents(dialog_invoker);
1383 EXPECT_EQ(0, dialog_index);
1384 EXPECT_EQ(1, tab_strip->active_index());
1385 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(blank_tab));
1387 content::WebContents* first_manage_tab = tab_strip->GetWebContentsAt(1);
1389 // Re-activate the dialog's tab (like a user would have to).
1390 tab_strip->ActivateTabAt(dialog_index, true);
1391 EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1393 // Simulate clicking "Manage X...".
1394 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1395 // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1396 EXPECT_EQ(4, tab_strip->count());
1397 EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1398 EXPECT_EQ(1, tab_strip->active_index());
1399 EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(first_manage_tab));
1400 EXPECT_EQ(3, tab_strip->GetIndexOfWebContents(blank_tab));
1403 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1404 SignInWebViewOpensLinksInNewTab) {
1405 controller()->OnDidFetchWalletCookieValue(std::string());
1406 controller()->OnDidGetWalletItems(
1407 wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1409 NavEntryCommittedObserver sign_in_page_observer(
1410 controller()->SignInUrl(),
1411 content::NotificationService::AllSources());
1413 controller()->SignInLinkClicked();
1415 content::WebContents* sign_in_contents =
1416 GetViewTester()->GetSignInWebContents();
1417 ASSERT_TRUE(sign_in_contents);
1419 sign_in_page_observer.Wait();
1421 content::OpenURLParams params(GURL("http://google.com"),
1422 content::Referrer(),
1424 ui::PAGE_TRANSITION_LINK,
1426 params.user_gesture = true;
1428 int num_tabs = browser()->tab_strip_model()->count();
1429 sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1430 EXPECT_EQ(num_tabs + 1, browser()->tab_strip_model()->count());
1433 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RefreshOnManageTabClose) {
1434 ASSERT_TRUE(browser()->is_type_tabbed());
1436 // GetWalletItems(_, _) is called when controller() is created in SetUp().
1437 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1438 controller()->OnDidFetchWalletCookieValue(std::string());
1439 controller()->OnDidGetWalletItems(
1440 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1442 content::WebContents* dialog_invoker = controller()->GetWebContents();
1443 ChromeAutofillClient::FromWebContents(dialog_invoker)
1444 ->SetDialogControllerForTesting(controller()->AsWeakPtr());
1446 // Open a new tab by selecting "Manage my shipping details..." in Wallet mode.
1447 EXPECT_EQ(1, browser()->tab_strip_model()->count());
1448 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1449 EXPECT_EQ(2, browser()->tab_strip_model()->count());
1450 ASSERT_NE(dialog_invoker, GetActiveWebContents());
1452 // Closing the tab opened by "Manage my shipping details..." should refresh
1454 controller()->ClearLastWalletItemsFetchTimestampForTesting();
1455 EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1456 GetActiveWebContents()->Close();
1459 // Changes from Wallet to Autofill and verifies that the combined billing/cc
1460 // sections are showing (or not) at the correct times.
1461 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1462 ChangingDataSourceShowsCorrectSections) {
1463 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1464 EXPECT_TRUE(view->IsShowingSection(SECTION_CC));
1465 EXPECT_TRUE(view->IsShowingSection(SECTION_BILLING));
1466 EXPECT_FALSE(view->IsShowingSection(SECTION_CC_BILLING));
1468 // Switch the dialog to paying with Wallet.
1469 controller()->OnDidFetchWalletCookieValue(std::string());
1470 controller()->OnDidGetWalletItems(
1471 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1472 ASSERT_TRUE(controller()->IsPayingWithWallet());
1474 EXPECT_FALSE(view->IsShowingSection(SECTION_CC));
1475 EXPECT_FALSE(view->IsShowingSection(SECTION_BILLING));
1476 EXPECT_TRUE(view->IsShowingSection(SECTION_CC_BILLING));
1478 // Now switch back to Autofill to ensure this direction works as well.
1479 ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1480 account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1482 EXPECT_TRUE(view->IsShowingSection(SECTION_CC));
1483 EXPECT_TRUE(view->IsShowingSection(SECTION_BILLING));
1484 EXPECT_FALSE(view->IsShowingSection(SECTION_CC_BILLING));
1487 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1488 DoesWorkOnHttpWithFlag) {
1489 net::SpawnedTestServer http_server(
1490 net::SpawnedTestServer::TYPE_HTTP,
1491 net::SpawnedTestServer::kLocalhost,
1492 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1493 ASSERT_TRUE(http_server.Start());
1494 EXPECT_TRUE(RunTestPage(http_server));
1497 // Like the parent test, but doesn't add the --reduce-security-for-testing flag.
1498 class AutofillDialogControllerSecurityTest :
1499 public AutofillDialogControllerTest {
1501 AutofillDialogControllerSecurityTest() {}
1502 virtual ~AutofillDialogControllerSecurityTest() {}
1504 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1505 CHECK(!command_line->HasSwitch(::switches::kReduceSecurityForTesting));
1508 typedef net::BaseTestServer::SSLOptions SSLOptions;
1511 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest);
1514 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1516 net::SpawnedTestServer http_server(
1517 net::SpawnedTestServer::TYPE_HTTP,
1518 net::SpawnedTestServer::kLocalhost,
1519 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1520 ASSERT_TRUE(http_server.Start());
1521 EXPECT_FALSE(RunTestPage(http_server));
1524 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1525 DoesWorkOnHttpWithFlags) {
1526 net::SpawnedTestServer https_server(
1527 net::SpawnedTestServer::TYPE_HTTPS,
1528 SSLOptions(SSLOptions::CERT_OK),
1529 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1530 ASSERT_TRUE(https_server.Start());
1531 EXPECT_TRUE(RunTestPage(https_server));
1534 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1535 DoesntWorkOnBrokenHttps) {
1536 net::SpawnedTestServer https_server(
1537 net::SpawnedTestServer::TYPE_HTTPS,
1538 SSLOptions(SSLOptions::CERT_EXPIRED),
1539 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1540 ASSERT_TRUE(https_server.Start());
1541 EXPECT_FALSE(RunTestPage(https_server));
1544 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1545 CountryChangeRebuildsSection) {
1546 EXPECT_FALSE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1547 EXPECT_FALSE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1549 // Select "Add new shipping address...".
1550 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1552 // Add some valid user input that should be preserved when country changes.
1553 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1554 view->SetTextContentsOfInput(NAME_FULL, ASCIIToUTF16("B. Loblaw"));
1556 // Change both sections' countries.
1557 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1558 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1559 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1560 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1562 // Verify the name is still there.
1563 EXPECT_EQ(ASCIIToUTF16("B. Loblaw"), view->GetTextContentsOfInput(NAME_FULL));
1565 EXPECT_TRUE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1566 EXPECT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1569 // Changing the data source to or from Wallet preserves the shipping country,
1570 // but not the billing country because Wallet only supports US billing
1572 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1573 ChangingDataSourcePreservesCountry) {
1574 InitializeControllerWithoutShowing();
1575 controller()->GetTestingManager()->set_default_country_code("CA");
1576 controller()->Show();
1579 AutofillProfile verified_profile(test::GetVerifiedProfile());
1580 controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1582 CreditCard verified_card(test::GetVerifiedCreditCard());
1583 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
1584 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1586 controller()->OnDidFetchWalletCookieValue(std::string());
1587 scoped_ptr<wallet::WalletItems> items =
1588 wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1589 items->AddAccount(wallet::GetTestGaiaAccount());
1590 items->AddInstrument(wallet::GetTestMaskedInstrument());
1591 items->AddAddress(wallet::GetTestShippingAddress());
1592 controller()->OnDidGetWalletItems(items.Pass());
1594 EXPECT_TRUE(controller()->IsPayingWithWallet());
1596 // Select "Add new shipping address...".
1597 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1598 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1600 // Default shipping country matches PDM's default, but default billing is
1601 // always US in Wallet mode.
1602 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1603 ASSERT_EQ(ASCIIToUTF16("Canada"),
1604 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1605 ASSERT_EQ(ASCIIToUTF16("United States"),
1606 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1608 // Switch the shipping country.
1609 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1610 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1611 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1612 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1614 // Switch to using Autofill instead of Wallet.
1615 ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1616 account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1618 EXPECT_FALSE(controller()->IsPayingWithWallet());
1620 // Shipping country should have stayed the same.
1621 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1622 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1623 ASSERT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1625 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1626 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY,
1627 ASCIIToUTF16("Belarus"));
1628 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1629 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1630 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1631 ASSERT_TRUE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1633 // Switch back to Wallet. Country should go back to US.
1634 account_chooser->ActivatedAt(0);
1635 EXPECT_EQ(ASCIIToUTF16("United States"),
1636 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1638 SectionHasField(SECTION_CC_BILLING, ADDRESS_BILLING_SORTING_CODE));
1640 // Make sure shipping is still on Belarus.
1641 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1642 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1643 ASSERT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1646 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewResetsCountry) {
1647 AutofillProfile verified_profile(test::GetVerifiedProfile());
1648 controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1650 // Select "Add new billing/shipping address...".
1651 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1652 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1654 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1655 ASSERT_EQ(ASCIIToUTF16("United States"),
1656 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1657 ASSERT_EQ(ASCIIToUTF16("United States"),
1658 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1660 // Switch both billing and shipping countries.
1661 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("Brazil"));
1662 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1663 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1664 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1666 // Select "Add new billing/shipping address...".
1667 controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1668 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1670 EXPECT_EQ(ASCIIToUTF16("United States"),
1671 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1672 EXPECT_EQ(ASCIIToUTF16("United States"),
1673 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1676 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1677 FillingFormRebuildsInputs) {
1678 AutofillProfile full_profile(test::GetFullProfile());
1679 full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1680 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1682 // Select "Add new shipping address...".
1683 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1685 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1686 ASSERT_EQ(ASCIIToUTF16("United States"),
1687 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1688 ASSERT_EQ(ASCIIToUTF16("United States"),
1689 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1691 const ServerFieldType input_type = EMAIL_ADDRESS;
1692 base::string16 name = full_profile.GetRawInfo(input_type);
1693 view->SetTextContentsOfInput(input_type, name.substr(0, name.size() / 2));
1694 view->ActivateInput(input_type);
1695 ASSERT_EQ(input_type, controller()->popup_input_type());
1696 controller()->DidAcceptSuggestion(base::string16(), 0);
1698 EXPECT_EQ(ASCIIToUTF16("Germany"),
1699 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1700 EXPECT_EQ(ASCIIToUTF16("United States"),
1701 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1704 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1705 FillingFormPreservesChangedCountry) {
1706 AutofillProfile full_profile(test::GetFullProfile());
1707 full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1708 controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1710 // Select "Add new shipping address...".
1711 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1713 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1714 view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1715 view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1716 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1717 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1719 base::string16 name = full_profile.GetRawInfo(NAME_FULL);
1720 view->SetTextContentsOfInput(NAME_FULL, name.substr(0, name.size() / 2));
1721 view->ActivateInput(NAME_FULL);
1722 ASSERT_EQ(NAME_FULL, controller()->popup_input_type());
1723 controller()->DidAcceptSuggestion(base::string16(), 0);
1725 EXPECT_EQ(ASCIIToUTF16("France"),
1726 view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1727 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1728 view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1731 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RulesLoaded) {
1732 // Select "Add new shipping address...".
1733 controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1734 controller()->set_use_validation(true);
1736 EXPECT_CALL(*controller()->GetMockValidator(),
1737 ValidateAddress(CountryCodeMatcher("DE"), _, _)).Times(2).
1738 WillOnce(Return(AddressValidator::RULES_NOT_READY));
1740 // Validation should occur on country change and see the rules haven't loaded.
1741 scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1742 view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("123"));
1743 view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Germany"));
1744 view->ActivateInput(ADDRESS_HOME_COUNTRY);
1746 // Different country loaded, validation should not occur.
1747 controller()->OnAddressValidationRulesLoaded("FR", true);
1749 // Relevant country loaded, validation should occur.
1750 controller()->OnAddressValidationRulesLoaded("DE", true);
1752 // Relevant country loaded but revalidation already happened, no further
1753 // validation should occur.
1754 controller()->OnAddressValidationRulesLoaded("DE", false);
1756 // Cancelling the dialog causes additional validation to see if the user
1757 // cancelled with invalid fields, so verify and clear here.
1758 testing::Mock::VerifyAndClearExpectations(controller()->GetMockValidator());
1761 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1762 TransactionAmount) {
1764 "<input type='number' step='0.01'"
1765 " autocomplete='transaction-amount' value='24'>"
1766 "<input autocomplete='transaction-currency' value='USD'>"
1767 "<input autocomplete='cc-csc'>");
1768 AutofillDialogControllerImpl* controller = SetUpHtmlAndInvoke(html);
1769 ASSERT_TRUE(controller);
1771 EXPECT_EQ(ASCIIToUTF16("24"), controller->transaction_amount_);
1772 EXPECT_EQ(ASCIIToUTF16("USD"), controller->transaction_currency_);
1775 } // namespace autofill