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/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"
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"
75 using base::ASCIIToUTF16
;
83 void MockCallback(const FormStructure
*) {}
85 class MockAutofillMetrics
: public AutofillMetrics
{
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
));
108 AutofillMetrics::DialogDismissalAction dialog_dismissal_action_
;
110 DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics
);
113 class TestAutofillDialogController
: public AutofillDialogControllerImpl
{
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
,
123 base::Bind(&MockCallback
)),
124 metric_logger_(metric_logger
),
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
{
168 void ForceFinishSubmit() {
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
;
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
226 *user_index
= sign_in_user_index_
;
227 return url
== wallet::GetSignInContinueUrl();
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
{
263 NavEntryCommittedObserver(const GURL
& url
,
264 const content::NotificationSource
& source
)
265 : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
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_
)
280 WindowedNotificationObserver::Observe(type
, source
, details
);
286 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver
);
291 class AutofillDialogControllerTest
: public InProcessBrowserTest
{
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();
315 void InitializeController() {
317 form
.name
= ASCIIToUTF16("TestForm");
318 form
.method
= ASCIIToUTF16("POST");
319 form
.user_submitted
= true;
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(),
335 message_loop_runner_
);
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,") +
367 "<form>" + form_inner_html
+ "</form>"
369 "function send(msg) {"
370 "domAutomationController.setAutomationId(0);"
371 "domAutomationController.send(msg);"
373 "document.forms[0].onautocompleteerror = function(e) {"
374 "send('error: ' + e.reason);"
376 "document.forms[0].onautocomplete = function() {"
379 "window.onclick = function() {"
380 "document.forms[0].requestAutocomplete();"
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);"
398 AutofillDialogControllerImpl
* controller
=
399 static_cast<AutofillDialogControllerImpl
*>(
400 delegate
->GetDialogControllerForTesting());
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(
418 content::Source
<content::NavigationController
>(
419 &contents
->GetController()));
420 interstitial_page
->Proceed();
426 TabAutofillManagerDelegate
* delegate
=
427 TabAutofillManagerDelegate::FromWebContents(contents
);
428 AutofillDialogControllerImpl
* controller
=
429 static_cast<AutofillDialogControllerImpl
*>(
430 delegate
->GetDialogControllerForTesting());
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
) {
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()->
458 std::string script
= "getValueForFieldOfType('" + autocomplete_type
+ "');";
460 EXPECT_TRUE(content::ExecuteScriptAndExtractString(render_view_host
, script
,
465 void AddCreditcardToProfile(Profile
* profile
, const CreditCard
& card
) {
466 PersonalDataManagerFactory::GetForProfile(profile
)->AddCreditCard(card
);
470 void AddAutofillProfileToProfile(Profile
* profile
,
471 const AutofillProfile
& autofill_profile
) {
472 PersonalDataManagerFactory::GetForProfile(profile
)->AddProfile(
477 TestGeneratedCreditCardBubbleController
* test_generated_bubble_controller() {
478 return test_generated_bubble_controller_
;
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();
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();
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();
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());
540 EXPECT_FALSE(weak_ptr
.get());
543 // Ensure that the expected metric is logged when the dialog is closed during
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();
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());
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
)) :
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
))
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());
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
)) :
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
))
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.
736 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
738 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
740 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
741 MAYBE_FillComboboxFromAutofill
) {
743 test::SetCreditCardInfo(&card1
, "JJ Smith", "4111111111111111", "12", "2018");
744 controller()->GetTestingManager()->AddTestingCreditCard(&card1
);
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());
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());
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(
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());
854 autofill::IsValidCreditCardExpirationDate(
855 expired_card
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
),
856 expired_card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
),
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
898 #define MAYBE_AutocompleteEvent AutocompleteEvent
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
920 #define MAYBE_AutocompleteErrorEventReasonInvalid \
921 AutocompleteErrorEventReasonInvalid
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();
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
948 #define MAYBE_AutocompleteErrorEventReasonCancel \
949 AutocompleteErrorEventReasonCancel
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.
973 #define MAYBE_PreservedSections DISABLED_PreservedSections
975 #define MAYBE_PreservedSections PreservedSections
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()->
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();
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
) {
1066 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1067 if (base::win::GetVersion() <= base::win::VERSION_XP
)
1070 browser()->profile()->GetPrefs()->SetBoolean(
1071 ::prefs::kAutofillDialogPayWithoutWallet
,
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(),
1107 content::PAGE_TRANSITION_LINK
,
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
) {
1127 // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1128 if (base::win::GetVersion() <= base::win::VERSION_XP
)
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(),
1172 content::PAGE_TRANSITION_LINK
,
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
1200 #define MAYBE_FillFormIncludesCVC FillFormIncludesCVC
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.
1224 controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH
));
1226 // Set up an expired 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(),
1320 content::PAGE_TRANSITION_LINK
,
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
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
1359 #define MAYBE_DoesWorkOnHttpWithFlag DoesWorkOnHttpWithFlag
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
{
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
;
1385 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest
);
1388 // http://crbug.com/318526
1389 #if defined(OS_MACOSX)
1390 #define MAYBE_DoesntWorkOnHttp DISABLED_DoesntWorkOnHttp
1392 #define MAYBE_DoesntWorkOnHttp DoesntWorkOnHttp
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
1408 #define MAYBE_DoesWorkOnHttpWithFlags DoesWorkOnHttpWithFlags
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
1424 #define MAYBE_DoesntWorkOnBrokenHttps DoesntWorkOnBrokenHttps
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
{
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.
1485 for (; i
< cn_billing_inputs
.size(); ++i
) {
1486 if (cn_billing_inputs
[i
].type
== ADDRESS_BILLING_DEPENDENT_LOCALITY
)
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
)
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