autofill_dialog_controller_browsertest.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// found in the LICENSE file. 4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/bind.h" 6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/command_line.h" 7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/memory/ref_counted.h" 8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/message_loop.h" 9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/strings/utf_string_conversions.h" 10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/time.h" 11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h" 12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/autofill/autofill_dialog_view.h" 13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/autofill/data_model_wrapper.h" 14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/autofill/testable_autofill_dialog_view.h" 15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/browser.h" 16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/browser/ui/tabs/tab_strip_model.h" 17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "chrome/test/base/in_process_browser_test.h" 18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/browser/autofill_common_test.h" 19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/browser/autofill_metrics.h" 20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/browser/test_personal_data_manager.h" 21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/browser/validation.h" 22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/content/browser/wallet/wallet_test_util.h" 23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/core/common/autofill_switches.h" 24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/core/common/form_data.h" 25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "components/autofill/core/common/form_field_data.h" 26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "content/public/test/test_utils.h" 27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "testing/gtest/include/gtest/gtest.h" 28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectnamespace autofill { 30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectnamespace { 32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectvoid MockCallback(const FormStructure*, const std::string&) {} 34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectclass MockAutofillMetrics : public AutofillMetrics { 36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public: 37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project MockAutofillMetrics() 38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project : dialog_type_(static_cast<DialogType>(-1)), 39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project dialog_dismissal_action_( 40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project static_cast<AutofillMetrics::DialogDismissalAction>(-1)), 41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project autocheckout_status_( 42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project static_cast<AutofillMetrics::AutocheckoutCompletionStatus>(-1)) {} 43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual ~MockAutofillMetrics() {} 44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // AutofillMetrics: 46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void LogAutocheckoutDuration( 47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const base::TimeDelta& duration, 48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutocheckoutCompletionStatus status) const OVERRIDE { 49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // Ignore constness for testing. 50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this); 51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project mutable_this->autocheckout_status_ = status; 52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void LogDialogUiDuration( 55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const base::TimeDelta& duration, 56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogType dialog_type, 57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogDismissalAction dismissal_action) const OVERRIDE { 58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // Ignore constness for testing. 59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this); 60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project mutable_this->dialog_type_ = dialog_type; 61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project mutable_this->dialog_dismissal_action_ = dismissal_action; 62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogType dialog_type() const { return dialog_type_; } 65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillMetrics::DialogDismissalAction dialog_dismissal_action() const { 66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return dialog_dismissal_action_; 67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillMetrics::AutocheckoutCompletionStatus autocheckout_status() const { 70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return autocheckout_status_; 71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private: 74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogType dialog_type_; 75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillMetrics::DialogDismissalAction dialog_dismissal_action_; 76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillMetrics::AutocheckoutCompletionStatus autocheckout_status_; 77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics); 79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project}; 80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectclass TestAutofillDialogController : public AutofillDialogControllerImpl { 82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public: 83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project TestAutofillDialogController(content::WebContents* contents, 84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const FormData& form_data, 85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const AutofillMetrics& metric_logger, 86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project scoped_refptr<content::MessageLoopRunner> runner, 87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const DialogType dialog_type) 88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project : AutofillDialogControllerImpl(contents, 89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form_data, 90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project GURL(), 91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project dialog_type, 92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project base::Bind(&MockCallback)), 93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project metric_logger_(metric_logger), 94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project message_loop_runner_(runner) {} 95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual ~TestAutofillDialogController() {} 97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void ViewClosed() OVERRIDE { 99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project message_loop_runner_->Quit(); 100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillDialogControllerImpl::ViewClosed(); 101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual string16 InputValidityMessage( 104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogSection section, 105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillFieldType type, 106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const string16& value) OVERRIDE { 107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return string16(); 108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual ValidityData InputsAreValid( 111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DialogSection section, 112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const DetailOutputMap& inputs, 113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ValidationType validation_type) OVERRIDE { 114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return ValidityData(); 115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // Saving to Chrome is tested in AutofillDialogController unit tests. 118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO(estade): test that the view defaults to saving to Chrome. 119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual bool ShouldOfferToSaveInChrome() const OVERRIDE { 120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return false; 121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // Increase visibility for testing. 124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project using AutofillDialogControllerImpl::view; 125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project using AutofillDialogControllerImpl::input_showing_popup; 126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE { 128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return notifications_; 129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project void set_notifications(const std::vector<DialogNotification>& notifications) { 132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project notifications_ = notifications; 133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project TestPersonalDataManager* GetTestingManager() { 136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return &test_manager_; 137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project using AutofillDialogControllerImpl::DisableWallet; 140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project using AutofillDialogControllerImpl::IsEditingExistingData; 141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project protected: 143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual PersonalDataManager* GetManager() OVERRIDE { 144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return &test_manager_; 145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private: 148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // To specify our own metric logger. 149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE { 150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return metric_logger_; 151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const AutofillMetrics& metric_logger_; 154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project TestPersonalDataManager test_manager_; 155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // A list of notifications to show in the notification area of the dialog. 158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // This is used to control what |CurrentNotifications()| returns for testing. 159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project std::vector<DialogNotification> notifications_; 160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController); 162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project}; 163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // namespace 165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectclass AutofillDialogControllerTest : public InProcessBrowserTest { 167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public: 168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project AutofillDialogControllerTest() {} 169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual ~AutofillDialogControllerTest() {} 170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project void InitializeControllerOfType(DialogType dialog_type) { 172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project FormData form; 173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.name = ASCIIToUTF16("TestForm"); 174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.method = ASCIIToUTF16("POST"); 175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.origin = GURL("http://example.com/form.html"); 176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.action = GURL("http://example.com/submit.html"); 177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.user_submitted = true; 178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project FormFieldData field; 180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project field.autocomplete_attribute = "email"; 181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form.fields.push_back(field); 182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project message_loop_runner_ = new content::MessageLoopRunner; 184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project controller_ = new TestAutofillDialogController( 185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project GetActiveWebContents(), 186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project form, 187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project metric_logger_, 188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project message_loop_runner_, 189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project dialog_type); 190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project controller_->Show(); 191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project content::WebContents* GetActiveWebContents() { 194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return browser()->tab_strip_model()->GetActiveWebContents(); 195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project const MockAutofillMetrics& metric_logger() { return metric_logger_; } 198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project TestAutofillDialogController* controller() { return controller_; } 199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project void RunMessageLoop() { 201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project message_loop_runner_->Run(); 202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private: 205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project MockAutofillMetrics metric_logger_; 206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project TestAutofillDialogController* controller_; // Weak reference. 207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest); 209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project}; 210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// TODO(isherman): Enable these tests on other platforms once the UI is 212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// implemented on those platforms. 213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#if defined(TOOLKIT_VIEWS) 214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Submit the form data. 215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source ProjectIN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) { 216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project controller()->view()->GetTestableView()->SubmitForTesting(); 218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project RunMessageLoop(); 220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project metric_logger().dialog_dismissal_action()); 223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project EXPECT_EQ(DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric_logger().dialog_type()); 224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} 225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Cancel out of the dialog. 227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source ProjectIN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) { 228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project controller()->view()->GetTestableView()->CancelForTesting(); 230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 231 RunMessageLoop(); 232 233 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED, 234 metric_logger().dialog_dismissal_action()); 235 EXPECT_EQ(DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric_logger().dialog_type()); 236} 237 238// Take some other action that dismisses the dialog. 239IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) { 240 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 241 controller()->Hide(); 242 243 RunMessageLoop(); 244 245 EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED, 246 metric_logger().dialog_dismissal_action()); 247 EXPECT_EQ(DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric_logger().dialog_type()); 248} 249 250// Test Autocheckout success metrics. 251IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocheckoutSuccess) { 252 InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT); 253 controller()->view()->GetTestableView()->SubmitForTesting(); 254 255 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 256 metric_logger().dialog_dismissal_action()); 257 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 258 259 controller()->OnAutocheckoutSuccess(); 260 controller()->view()->GetTestableView()->CancelForTesting(); 261 RunMessageLoop(); 262 263 EXPECT_EQ(AutofillMetrics::AUTOCHECKOUT_SUCCEEDED, 264 metric_logger().autocheckout_status()); 265 266 // Ensure closing the dialog doesn't fire any new metrics. 267 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 268 metric_logger().dialog_dismissal_action()); 269 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 270} 271 272// Test Autocheckout failure metric. 273IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocheckoutError) { 274 InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT); 275 controller()->view()->GetTestableView()->SubmitForTesting(); 276 277 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 278 metric_logger().dialog_dismissal_action()); 279 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 280 281 controller()->OnAutocheckoutError(); 282 controller()->view()->GetTestableView()->CancelForTesting(); 283 RunMessageLoop(); 284 285 EXPECT_EQ(AutofillMetrics::AUTOCHECKOUT_FAILED, 286 metric_logger().autocheckout_status()); 287 288 // Ensure closing the dialog doesn't fire any new metrics. 289 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 290 metric_logger().dialog_dismissal_action()); 291 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 292} 293 294IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocheckoutCancelled) { 295 InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT); 296 controller()->view()->GetTestableView()->SubmitForTesting(); 297 298 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 299 metric_logger().dialog_dismissal_action()); 300 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 301 302 controller()->view()->GetTestableView()->CancelForTesting(); 303 RunMessageLoop(); 304 305 EXPECT_EQ(AutofillMetrics::AUTOCHECKOUT_CANCELLED, 306 metric_logger().autocheckout_status()); 307 308 // Ensure closing the dialog doesn't fire any new metrics. 309 EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED, 310 metric_logger().dialog_dismissal_action()); 311 EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type()); 312} 313 314IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) { 315 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 316 controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR); 317 318 AutofillProfile full_profile(test::GetFullProfile()); 319 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 320 321 const DetailInputs& inputs = 322 controller()->RequestedFieldsForSection(SECTION_SHIPPING); 323 const DetailInput& triggering_input = inputs[0]; 324 string16 value = full_profile.GetRawInfo(triggering_input.type); 325 TestableAutofillDialogView* view = controller()->view()->GetTestableView(); 326 view->SetTextContentsOfInput(triggering_input, 327 value.substr(0, value.size() / 2)); 328 view->ActivateInput(triggering_input); 329 330 ASSERT_EQ(&triggering_input, controller()->input_showing_popup()); 331 controller()->DidAcceptSuggestion(string16(), 0); 332 333 // All inputs should be filled. 334 AutofillProfileWrapper wrapper(&full_profile, 0); 335 for (size_t i = 0; i < inputs.size(); ++i) { 336 EXPECT_EQ(wrapper.GetInfo(inputs[i].type), 337 view->GetTextContentsOfInput(inputs[i])); 338 } 339 340 // Now simulate some user edits and try again. 341 std::vector<string16> expectations; 342 for (size_t i = 0; i < inputs.size(); ++i) { 343 string16 users_input = i % 2 == 0 ? string16() : ASCIIToUTF16("dummy"); 344 view->SetTextContentsOfInput(inputs[i], users_input); 345 // Empty inputs should be filled, others should be left alone. 346 string16 expectation = 347 &inputs[i] == &triggering_input || users_input.empty() ? 348 wrapper.GetInfo(inputs[i].type) : 349 users_input; 350 expectations.push_back(expectation); 351 } 352 353 view->SetTextContentsOfInput(triggering_input, 354 value.substr(0, value.size() / 2)); 355 view->ActivateInput(triggering_input); 356 ASSERT_EQ(&triggering_input, controller()->input_showing_popup()); 357 controller()->DidAcceptSuggestion(string16(), 0); 358 359 for (size_t i = 0; i < inputs.size(); ++i) { 360 EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i])); 361 } 362} 363 364// Test that the Autocheckout progress bar is showing after submitting the 365// dialog for controller with type DIALOG_TYPE_AUTOCHECKOUT. 366IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, 367 AutocheckoutShowsProgressBar) { 368 InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT); 369 EXPECT_TRUE(controller()->ShouldShowDetailArea()); 370 EXPECT_FALSE(controller()->ShouldShowProgressBar()); 371 372 controller()->view()->GetTestableView()->SubmitForTesting(); 373 EXPECT_FALSE(controller()->ShouldShowDetailArea()); 374 EXPECT_TRUE(controller()->ShouldShowProgressBar()); 375} 376 377// Test that the Autocheckout progress bar is not showing after submitting the 378// dialog for controller with type DIALOG_TYPE_REQUEST_AUTOCOMPLETE. 379IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, 380 RequestAutocompleteDoesntShowProgressBar) { 381 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 382 EXPECT_TRUE(controller()->ShouldShowDetailArea()); 383 EXPECT_FALSE(controller()->ShouldShowProgressBar()); 384 385 controller()->view()->GetTestableView()->SubmitForTesting(); 386 EXPECT_TRUE(controller()->ShouldShowDetailArea()); 387 EXPECT_FALSE(controller()->ShouldShowProgressBar()); 388} 389 390// Tests that changing the value of a CC expiration date combobox works as 391// expected when Autofill is used to fill text inputs. 392IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillComboboxFromAutofill) { 393 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 394 controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR); 395 396 CreditCard card1; 397 test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018"); 398 controller()->GetTestingManager()->AddTestingCreditCard(&card1); 399 CreditCard card2; 400 test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017"); 401 controller()->GetTestingManager()->AddTestingCreditCard(&card2); 402 AutofillProfile full_profile(test::GetFullProfile()); 403 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 404 405 const DetailInputs& inputs = 406 controller()->RequestedFieldsForSection(SECTION_CC); 407 const DetailInput& triggering_input = inputs[0]; 408 string16 value = card1.GetRawInfo(triggering_input.type); 409 TestableAutofillDialogView* view = controller()->view()->GetTestableView(); 410 view->SetTextContentsOfInput(triggering_input, 411 value.substr(0, value.size() / 2)); 412 view->ActivateInput(triggering_input); 413 414 ASSERT_EQ(&triggering_input, controller()->input_showing_popup()); 415 controller()->DidAcceptSuggestion(string16(), 0); 416 417 // All inputs should be filled. 418 AutofillCreditCardWrapper wrapper1(&card1); 419 for (size_t i = 0; i < inputs.size(); ++i) { 420 EXPECT_EQ(wrapper1.GetInfo(inputs[i].type), 421 view->GetTextContentsOfInput(inputs[i])); 422 } 423 424 // Try again with different data. Only expiration date and the triggering 425 // input should be overwritten. 426 value = card2.GetRawInfo(triggering_input.type); 427 view->SetTextContentsOfInput(triggering_input, 428 value.substr(0, value.size() / 2)); 429 view->ActivateInput(triggering_input); 430 ASSERT_EQ(&triggering_input, controller()->input_showing_popup()); 431 controller()->DidAcceptSuggestion(string16(), 0); 432 433 AutofillCreditCardWrapper wrapper2(&card2); 434 for (size_t i = 0; i < inputs.size(); ++i) { 435 const DetailInput& input = inputs[i]; 436 if (&input == &triggering_input || 437 input.type == CREDIT_CARD_EXP_MONTH || 438 input.type == CREDIT_CARD_EXP_4_DIGIT_YEAR) { 439 EXPECT_EQ(wrapper2.GetInfo(input.type), 440 view->GetTextContentsOfInput(input)); 441 } else if (input.type == CREDIT_CARD_VERIFICATION_CODE) { 442 EXPECT_TRUE(view->GetTextContentsOfInput(input).empty()); 443 } else { 444 EXPECT_EQ(wrapper1.GetInfo(input.type), 445 view->GetTextContentsOfInput(input)); 446 } 447 } 448 449 // Now fill from a profile. It should not overwrite any CC info. 450 const DetailInputs& billing_inputs = 451 controller()->RequestedFieldsForSection(SECTION_BILLING); 452 const DetailInput& billing_triggering_input = billing_inputs[0]; 453 value = full_profile.GetRawInfo(triggering_input.type); 454 view->SetTextContentsOfInput(billing_triggering_input, 455 value.substr(0, value.size() / 2)); 456 view->ActivateInput(billing_triggering_input); 457 458 ASSERT_EQ(&billing_triggering_input, controller()->input_showing_popup()); 459 controller()->DidAcceptSuggestion(string16(), 0); 460 461 for (size_t i = 0; i < inputs.size(); ++i) { 462 const DetailInput& input = inputs[i]; 463 if (&input == &triggering_input || 464 input.type == CREDIT_CARD_EXP_MONTH || 465 input.type == CREDIT_CARD_EXP_4_DIGIT_YEAR) { 466 EXPECT_EQ(wrapper2.GetInfo(input.type), 467 view->GetTextContentsOfInput(input)); 468 } else if (input.type == CREDIT_CARD_VERIFICATION_CODE) { 469 EXPECT_TRUE(view->GetTextContentsOfInput(input).empty()); 470 } else { 471 EXPECT_EQ(wrapper1.GetInfo(input.type), 472 view->GetTextContentsOfInput(input)); 473 } 474 } 475} 476 477// Tests that credit card number is disabled while editing a Wallet instrument. 478IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, WalletCreditCardDisabled) { 479 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 480 controller()->OnUserNameFetchSuccess("user@example.com"); 481 482 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 483 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 484 controller()->OnDidGetWalletItems(wallet_items.Pass()); 485 486 // Click "Edit" in the billing section (while using Wallet). 487 controller()->EditClickedForSection(SECTION_CC_BILLING); 488 489 const DetailInputs& edit_inputs = 490 controller()->RequestedFieldsForSection(SECTION_CC_BILLING); 491 size_t i; 492 for (i = 0; i < edit_inputs.size(); ++i) { 493 if (edit_inputs[i].type == CREDIT_CARD_NUMBER) { 494 EXPECT_FALSE(edit_inputs[i].editable); 495 break; 496 } 497 } 498 ASSERT_LT(i, edit_inputs.size()); 499 500 // Select "Add new billing info..." while using Wallet. 501 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC_BILLING); 502 model->ActivatedAt(model->GetItemCount() - 2); 503 504 const DetailInputs& add_inputs = 505 controller()->RequestedFieldsForSection(SECTION_CC_BILLING); 506 for (i = 0; i < add_inputs.size(); ++i) { 507 if (add_inputs[i].type == CREDIT_CARD_NUMBER) { 508 EXPECT_TRUE(add_inputs[i].editable); 509 break; 510 } 511 } 512 ASSERT_LT(i, add_inputs.size()); 513} 514 515// Ensure that expired cards trigger invalid suggestions. 516IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) { 517 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 518 controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR); 519 520 CreditCard verified_card(test::GetCreditCard()); 521 verified_card.set_origin("Chrome settings"); 522 ASSERT_TRUE(verified_card.IsVerified()); 523 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card); 524 525 CreditCard expired_card(test::GetCreditCard()); 526 expired_card.set_origin("Chrome settings"); 527 expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007")); 528 ASSERT_TRUE(expired_card.IsVerified()); 529 ASSERT_FALSE( 530 autofill::IsValidCreditCardExpirationDate( 531 expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR), 532 expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH), 533 base::Time::Now())); 534 controller()->GetTestingManager()->AddTestingCreditCard(&expired_card); 535 536 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC); 537 ASSERT_EQ(4, model->GetItemCount()); 538 539 ASSERT_TRUE(model->IsItemCheckedAt(0)); 540 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC)); 541 542 model->ActivatedAt(1); 543 ASSERT_TRUE(model->IsItemCheckedAt(1)); 544 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC)); 545} 546 547// Notifications with long message text should not make the dialog bigger. 548IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) { 549 InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE); 550 551 const gfx::Size no_notification_size = 552 controller()->view()->GetTestableView()->GetSize(); 553 ASSERT_GT(no_notification_size.width(), 0); 554 555 std::vector<DialogNotification> notifications; 556 notifications.push_back( 557 DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16( 558 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do " 559 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim " 560 "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " 561 "aliquip ex ea commodo consequat. Duis aute irure dolor in " 562 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla " 563 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in " 564 "culpa qui officia deserunt mollit anim id est laborum."))); 565 controller()->set_notifications(notifications); 566 controller()->view()->UpdateNotificationArea(); 567 568 EXPECT_EQ(no_notification_size.width(), 569 controller()->view()->GetTestableView()->GetSize().width()); 570} 571#endif // defined(TOOLKIT_VIEWS) 572 573} // namespace autofill 574