autofill_dialog_controller_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <map>
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/callback.h"
10#include "base/command_line.h"
11#include "base/guid.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/message_loop/message_loop.h"
14#include "base/prefs/pref_service.h"
15#include "base/run_loop.h"
16#include "base/strings/string_number_conversions.h"
17#include "base/strings/string_piece.h"
18#include "base/strings/utf_string_conversions.h"
19#include "base/tuple.h"
20#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
21#include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
22#include "chrome/browser/ui/autofill/autofill_dialog_view.h"
23#include "chrome/browser/ui/autofill/generated_credit_card_bubble_controller.h"
24#include "chrome/browser/ui/autofill/mock_address_validator.h"
25#include "chrome/browser/ui/autofill/mock_new_credit_card_bubble_controller.h"
26#include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
27#include "chrome/browser/webdata/web_data_service_factory.h"
28#include "chrome/common/chrome_switches.h"
29#include "chrome/common/pref_names.h"
30#include "chrome/common/render_messages.h"
31#include "chrome/test/base/chrome_render_view_host_test_harness.h"
32#include "chrome/test/base/scoped_testing_local_state.h"
33#include "chrome/test/base/testing_browser_process.h"
34#include "chrome/test/base/testing_profile.h"
35#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
36#include "components/autofill/content/browser/wallet/full_wallet.h"
37#include "components/autofill/content/browser/wallet/gaia_account.h"
38#include "components/autofill/content/browser/wallet/instrument.h"
39#include "components/autofill/content/browser/wallet/mock_wallet_client.h"
40#include "components/autofill/content/browser/wallet/wallet_address.h"
41#include "components/autofill/content/browser/wallet/wallet_service_url.h"
42#include "components/autofill/content/browser/wallet/wallet_test_util.h"
43#include "components/autofill/core/browser/autofill_metrics.h"
44#include "components/autofill/core/browser/autofill_test_utils.h"
45#include "components/autofill/core/browser/test_personal_data_manager.h"
46#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
47#include "components/autofill/core/common/autofill_switches.h"
48#include "components/autofill/core/common/form_data.h"
49#include "components/user_prefs/user_prefs.h"
50#include "content/public/browser/web_contents.h"
51#include "content/public/test/mock_render_process_host.h"
52#include "google_apis/gaia/google_service_auth_error.h"
53#include "grit/component_scaled_resources.h"
54#include "grit/generated_resources.h"
55#include "testing/gmock/include/gmock/gmock.h"
56#include "testing/gtest/include/gtest/gtest.h"
57#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h"
58#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_validator.h"
59#include "ui/base/resource/resource_bundle.h"
60
61#if defined(OS_WIN)
62#include "ui/base/win/scoped_ole_initializer.h"
63#endif
64
65using base::ASCIIToUTF16;
66using base::UTF8ToUTF16;
67
68namespace autofill {
69
70namespace {
71
72using ::i18n::addressinput::AddressData;
73using ::i18n::addressinput::AddressProblemFilter;
74using ::i18n::addressinput::AddressProblem;
75using ::i18n::addressinput::AddressProblems;
76using ::i18n::addressinput::AddressValidator;
77using testing::AtLeast;
78using testing::DoAll;
79using testing::Return;
80using testing::SetArgPointee;
81using testing::_;
82
83const char kSourceUrl[] = "http://localbike.shop";
84const char kFakeEmail[] = "user@chromium.org";
85const char kFakeFingerprintEncoded[] = "CgVaAwiACA==";
86const char kEditedBillingAddress[] = "123 edited billing address";
87const char* kFieldsFromPage[] =
88    { "email",
89      "cc-name",
90      "cc-number",
91      "cc-exp-month",
92      "cc-exp-year",
93      "cc-csc",
94      "billing name",
95      "billing address-line1",
96      "billing locality",
97      "billing region",
98      "billing postal-code",
99      "billing country",
100      "billing tel",
101      "shipping name",
102      "shipping address-line1",
103      "shipping locality",
104      "shipping region",
105      "shipping postal-code",
106      "shipping country",
107      "shipping tel",
108    };
109const char kSettingsOrigin[] = "Chrome settings";
110const char kTestCCNumberAmex[] = "376200000000002";
111const char kTestCCNumberVisa[] = "4111111111111111";
112const char kTestCCNumberMaster[] = "5555555555554444";
113const char kTestCCNumberDiscover[] = "6011111111111117";
114const char kTestCCNumberIncomplete[] = "4111111111";
115// Credit card number fails Luhn check.
116const char kTestCCNumberInvalid[] = "4111111111111112";
117
118// Copies the initial values from |inputs| into |outputs|.
119void CopyInitialValues(const DetailInputs& inputs, FieldValueMap* outputs) {
120  for (size_t i = 0; i < inputs.size(); ++i) {
121    const DetailInput& input = inputs[i];
122    (*outputs)[input.type] = input.initial_value;
123  }
124}
125
126scoped_ptr<wallet::WalletItems> CompleteAndValidWalletItems() {
127  scoped_ptr<wallet::WalletItems> items =
128      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
129  items->AddAccount(wallet::GetTestGaiaAccount());
130  items->AddInstrument(wallet::GetTestMaskedInstrument());
131  items->AddAddress(wallet::GetTestShippingAddress());
132  return items.Pass();
133}
134
135scoped_ptr<risk::Fingerprint> GetFakeFingerprint() {
136  scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
137  // Add some data to the proto, else the encoded content is empty.
138  fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
139      set_width(1024);
140  return fingerprint.Pass();
141}
142
143bool HasAnyError(const ValidityMessages& messages, ServerFieldType field) {
144  return !messages.GetMessageOrDefault(field).text.empty();
145}
146
147bool HasUnsureError(const ValidityMessages& messages, ServerFieldType field) {
148  const ValidityMessage& message = messages.GetMessageOrDefault(field);
149  return !message.text.empty() && !message.sure;
150}
151
152class TestAutofillDialogView : public AutofillDialogView {
153 public:
154  TestAutofillDialogView()
155      : updates_started_(0), save_details_locally_checked_(true) {}
156  virtual ~TestAutofillDialogView() {}
157
158  virtual void Show() OVERRIDE {}
159  virtual void Hide() OVERRIDE {}
160
161  virtual void UpdatesStarted() OVERRIDE {
162    updates_started_++;
163  }
164
165  virtual void UpdatesFinished() OVERRIDE {
166    updates_started_--;
167    EXPECT_GE(updates_started_, 0);
168  }
169
170  virtual void UpdateNotificationArea() OVERRIDE {
171    EXPECT_GE(updates_started_, 1);
172  }
173
174  virtual void UpdateAccountChooser() OVERRIDE {
175    EXPECT_GE(updates_started_, 1);
176  }
177
178  virtual void UpdateButtonStrip() OVERRIDE {
179    EXPECT_GE(updates_started_, 1);
180  }
181
182  virtual void UpdateOverlay() OVERRIDE {
183    EXPECT_GE(updates_started_, 1);
184  }
185
186  virtual void UpdateDetailArea() OVERRIDE {
187    EXPECT_GE(updates_started_, 1);
188  }
189
190  virtual void UpdateSection(DialogSection section) OVERRIDE {
191    section_updates_[section]++;
192    EXPECT_GE(updates_started_, 1);
193  }
194
195  virtual void UpdateErrorBubble() OVERRIDE {
196    EXPECT_GE(updates_started_, 1);
197  }
198
199  virtual void FillSection(DialogSection section,
200                           ServerFieldType originating_type) OVERRIDE {}
201  virtual void GetUserInput(DialogSection section, FieldValueMap* output)
202      OVERRIDE {
203    *output = outputs_[section];
204  }
205
206  virtual base::string16 GetCvc() OVERRIDE { return base::string16(); }
207  virtual bool HitTestInput(ServerFieldType type,
208                            const gfx::Point& screen_point) OVERRIDE {
209    return false;
210  }
211
212  virtual bool SaveDetailsLocally() OVERRIDE {
213    return save_details_locally_checked_;
214  }
215
216  virtual const content::NavigationController* ShowSignIn() OVERRIDE {
217    return NULL;
218  }
219  virtual void HideSignIn() OVERRIDE {}
220
221  MOCK_METHOD0(ModelChanged, void());
222  MOCK_METHOD0(UpdateForErrors, void());
223
224  virtual void OnSignInResize(const gfx::Size& pref_size) OVERRIDE {}
225  virtual void ValidateSection(DialogSection) OVERRIDE {}
226
227  void SetUserInput(DialogSection section, const FieldValueMap& map) {
228    outputs_[section] = map;
229  }
230
231  void CheckSaveDetailsLocallyCheckbox(bool checked) {
232    save_details_locally_checked_ = checked;
233  }
234
235  void ClearSectionUpdates() {
236    section_updates_.clear();
237  }
238
239  std::map<DialogSection, size_t> section_updates() const {
240    return section_updates_;
241  }
242
243 private:
244  std::map<DialogSection, FieldValueMap> outputs_;
245  std::map<DialogSection, size_t> section_updates_;
246
247  int updates_started_;
248  bool save_details_locally_checked_;
249
250  DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogView);
251};
252
253class TestAutofillDialogController
254    : public AutofillDialogControllerImpl,
255      public base::SupportsWeakPtr<TestAutofillDialogController> {
256 public:
257  TestAutofillDialogController(
258      content::WebContents* contents,
259      const FormData& form_structure,
260      const GURL& source_url,
261      const AutofillMetrics& metric_logger,
262      const base::Callback<void(const FormStructure*)>& callback,
263      MockNewCreditCardBubbleController* mock_new_card_bubble_controller)
264      : AutofillDialogControllerImpl(contents,
265                                     form_structure,
266                                     source_url,
267                                     callback),
268        metric_logger_(metric_logger),
269        mock_wallet_client_(
270            Profile::FromBrowserContext(contents->GetBrowserContext())->
271                GetRequestContext(), this, source_url),
272        mock_new_card_bubble_controller_(mock_new_card_bubble_controller),
273        submit_button_delay_count_(0) {}
274
275  virtual ~TestAutofillDialogController() {}
276
277  virtual AutofillDialogView* CreateView() OVERRIDE {
278    return new testing::NiceMock<TestAutofillDialogView>();
279  }
280
281  void Init(content::BrowserContext* browser_context) {
282    test_manager_.Init(
283        WebDataServiceFactory::GetAutofillWebDataForProfile(
284            Profile::FromBrowserContext(browser_context),
285            Profile::EXPLICIT_ACCESS),
286        user_prefs::UserPrefs::Get(browser_context),
287        browser_context->IsOffTheRecord());
288  }
289
290  TestAutofillDialogView* GetView() {
291    return static_cast<TestAutofillDialogView*>(view());
292  }
293
294  TestPersonalDataManager* GetTestingManager() {
295    return &test_manager_;
296  }
297
298  MockAddressValidator* GetMockValidator() {
299    return &mock_validator_;
300  }
301
302  wallet::MockWalletClient* GetTestingWalletClient() {
303    return &mock_wallet_client_;
304  }
305
306  const GURL& open_tab_url() { return open_tab_url_; }
307
308  void SimulateSigninError() {
309    OnWalletSigninError();
310  }
311
312  // Skips past the 2 second wait between FinishSubmit and DoFinishSubmit.
313  void ForceFinishSubmit() {
314    DoFinishSubmit();
315  }
316
317  void SimulateSubmitButtonDelayBegin() {
318    AutofillDialogControllerImpl::SubmitButtonDelayBegin();
319  }
320
321  void SimulateSubmitButtonDelayEnd() {
322    AutofillDialogControllerImpl::SubmitButtonDelayEndForTesting();
323  }
324
325  using AutofillDialogControllerImpl::
326      ClearLastWalletItemsFetchTimestampForTesting;
327
328  // Returns the number of times that the submit button was delayed.
329  int get_submit_button_delay_count() const {
330    return submit_button_delay_count_;
331  }
332
333  MOCK_METHOD0(LoadRiskFingerprintData, void());
334  using AutofillDialogControllerImpl::AccountChooserModelForTesting;
335  using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
336  using AutofillDialogControllerImpl::IsEditingExistingData;
337  using AutofillDialogControllerImpl::IsManuallyEditingSection;
338  using AutofillDialogControllerImpl::IsPayingWithWallet;
339  using AutofillDialogControllerImpl::IsSubmitPausedOn;
340  using AutofillDialogControllerImpl::NOT_CHECKED;
341  using AutofillDialogControllerImpl::popup_input_type;
342  using AutofillDialogControllerImpl::SignedInState;
343
344 protected:
345  virtual PersonalDataManager* GetManager() const OVERRIDE {
346    return const_cast<TestAutofillDialogController*>(this)->
347        GetTestingManager();
348  }
349
350  virtual AddressValidator* GetValidator() OVERRIDE {
351    return &mock_validator_;
352  }
353
354  virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
355    return &mock_wallet_client_;
356  }
357
358  virtual void OpenTabWithUrl(const GURL& url) OVERRIDE {
359    open_tab_url_ = url;
360  }
361
362  virtual void ShowNewCreditCardBubble(
363      scoped_ptr<CreditCard> new_card,
364      scoped_ptr<AutofillProfile> billing_profile) OVERRIDE {
365    mock_new_card_bubble_controller_->Show(new_card.Pass(),
366                                           billing_profile.Pass());
367  }
368
369  // AutofillDialogControllerImpl calls this method before showing the dialog
370  // window.
371  virtual void SubmitButtonDelayBegin() OVERRIDE {
372    // Do not delay enabling the submit button in testing.
373    submit_button_delay_count_++;
374  }
375
376 private:
377  // To specify our own metric logger.
378  virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
379    return metric_logger_;
380  }
381
382  const AutofillMetrics& metric_logger_;
383  TestPersonalDataManager test_manager_;
384  testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
385
386  // A mock validator object to prevent network requests and track when
387  // validation rules are loaded or validation attempts occur.
388  testing::NiceMock<MockAddressValidator> mock_validator_;
389
390  GURL open_tab_url_;
391  MockNewCreditCardBubbleController* mock_new_card_bubble_controller_;
392
393  // The number of times that the submit button was delayed.
394  int submit_button_delay_count_;
395
396  DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
397};
398
399class AutofillDialogControllerTest : public ChromeRenderViewHostTestHarness {
400 protected:
401  AutofillDialogControllerTest(): form_structure_(NULL) {}
402
403  // testing::Test implementation:
404  virtual void SetUp() OVERRIDE {
405    ChromeRenderViewHostTestHarness::SetUp();
406    Reset();
407  }
408
409  virtual void TearDown() OVERRIDE {
410    if (controller_)
411      controller_->ViewClosed();
412    ChromeRenderViewHostTestHarness::TearDown();
413  }
414
415  void Reset() {
416    if (controller_)
417      controller_->ViewClosed();
418
419    test_generated_bubble_controller_ =
420        new testing::NiceMock<TestGeneratedCreditCardBubbleController>(
421            web_contents());
422    ASSERT_TRUE(test_generated_bubble_controller_->IsInstalled());
423
424    mock_new_card_bubble_controller_.reset(
425        new MockNewCreditCardBubbleController);
426
427    profile()->GetPrefs()->ClearPref(::prefs::kAutofillDialogSaveData);
428
429    // We have to clear the old local state before creating a new one.
430    scoped_local_state_.reset();
431    scoped_local_state_.reset(new ScopedTestingLocalState(
432        TestingBrowserProcess::GetGlobal()));
433
434    SetUpControllerWithFormData(DefaultFormData());
435  }
436
437  FormData DefaultFormData() {
438    FormData form_data;
439    for (size_t i = 0; i < arraysize(kFieldsFromPage); ++i) {
440      FormFieldData field;
441      field.autocomplete_attribute = kFieldsFromPage[i];
442      form_data.fields.push_back(field);
443    }
444    return form_data;
445  }
446
447  // Creates a new controller for |form_data|.
448  void ResetControllerWithFormData(const FormData& form_data) {
449    if (controller_)
450      controller_->ViewClosed();
451
452    base::Callback<void(const FormStructure*)> callback =
453        base::Bind(&AutofillDialogControllerTest::FinishedCallback,
454                   base::Unretained(this));
455    controller_ = (new testing::NiceMock<TestAutofillDialogController>(
456        web_contents(),
457        form_data,
458        GURL(kSourceUrl),
459        metric_logger_,
460        callback,
461        mock_new_card_bubble_controller_.get()))->AsWeakPtr();
462    controller_->Init(profile());
463  }
464
465  // Creates a new controller for |form_data| and sets up some initial wallet
466  // data for it.
467  void SetUpControllerWithFormData(const FormData& form_data) {
468    ResetControllerWithFormData(form_data);
469    controller()->Show();
470    if (!profile()->GetPrefs()->GetBoolean(
471            ::prefs::kAutofillDialogPayWithoutWallet)) {
472      EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
473      controller()->OnDidFetchWalletCookieValue(std::string());
474      controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
475    }
476  }
477
478  // Fills the inputs in SECTION_CC with data.
479  void FillCreditCardInputs() {
480    FieldValueMap cc_outputs;
481    const DetailInputs& cc_inputs =
482        controller()->RequestedFieldsForSection(SECTION_CC);
483    for (size_t i = 0; i < cc_inputs.size(); ++i) {
484      cc_outputs[cc_inputs[i].type] = cc_inputs[i].type == CREDIT_CARD_NUMBER ?
485          ASCIIToUTF16(kTestCCNumberVisa) : ASCIIToUTF16("11");
486    }
487    controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs);
488  }
489
490  // Fills the inputs in SECTION_CC_BILLING with valid data.
491  void FillCCBillingInputs() {
492    FieldValueMap outputs;
493    const DetailInputs& inputs =
494        controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
495    AutofillProfile full_profile(test::GetVerifiedProfile());
496    CreditCard full_card(test::GetCreditCard());
497    for (size_t i = 0; i < inputs.size(); ++i) {
498      const ServerFieldType type = inputs[i].type;
499      outputs[type] = full_profile.GetInfo(AutofillType(type), "en-US");
500
501      if (outputs[type].empty())
502        outputs[type] = full_card.GetInfo(AutofillType(type), "en-US");
503    }
504    controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
505  }
506
507  // Activates the 'Add new foo' option from the |section|'s suggestions
508  // dropdown and fills the |section|'s inputs with the data from the
509  // |data_model|.  If |section| is SECTION_CC, also fills in '123' for the CVC.
510  void FillInputs(DialogSection section, const AutofillDataModel& data_model) {
511    // Select the 'Add new foo' option.
512    ui::MenuModel* model = GetMenuModelForSection(section);
513    if (model)
514      model->ActivatedAt(model->GetItemCount() - 2);
515
516    // Fill the inputs.
517    FieldValueMap outputs;
518    const DetailInputs& inputs =
519        controller()->RequestedFieldsForSection(section);
520    for (size_t i = 0; i < inputs.size(); ++i) {
521      ServerFieldType type = inputs[i].type;
522      base::string16 output;
523      if (type == CREDIT_CARD_VERIFICATION_CODE)
524        output = ASCIIToUTF16("123");
525      else
526        output = data_model.GetInfo(AutofillType(type), "en-US");
527      outputs[inputs[i].type] = output;
528    }
529    controller()->GetView()->SetUserInput(section, outputs);
530  }
531
532  std::vector<DialogNotification> NotificationsOfType(
533      DialogNotification::Type type) {
534    std::vector<DialogNotification> right_type;
535    const std::vector<DialogNotification>& notifications =
536        controller()->CurrentNotifications();
537    for (size_t i = 0; i < notifications.size(); ++i) {
538      if (notifications[i].type() == type)
539        right_type.push_back(notifications[i]);
540    }
541    return right_type;
542  }
543
544  void SwitchToAutofill() {
545    ui::MenuModel* model = controller_->MenuModelForAccountChooser();
546    model->ActivatedAt(model->GetItemCount() - 1);
547  }
548
549  void SwitchToWallet() {
550    controller_->MenuModelForAccountChooser()->ActivatedAt(0);
551  }
552
553  void SimulateSigninError() {
554    controller_->SimulateSigninError();
555  }
556
557  void UseBillingForShipping() {
558    controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(0);
559  }
560
561  void ValidateCCNumber(DialogSection section,
562                        const std::string& cc_number,
563                        bool should_pass) {
564    FieldValueMap outputs;
565    outputs[ADDRESS_BILLING_COUNTRY] = ASCIIToUTF16("United States");
566    outputs[CREDIT_CARD_NUMBER] = UTF8ToUTF16(cc_number);
567    ValidityMessages messages =
568        controller()->InputsAreValid(section, outputs);
569    EXPECT_EQ(should_pass, !messages.HasSureError(CREDIT_CARD_NUMBER));
570  }
571
572  void SubmitWithWalletItems(scoped_ptr<wallet::WalletItems> wallet_items) {
573    controller()->OnDidGetWalletItems(wallet_items.Pass());
574    AcceptAndLoadFakeFingerprint();
575  }
576
577  void AcceptAndLoadFakeFingerprint() {
578    controller()->OnAccept();
579    controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
580  }
581
582  // Returns true if the given |section| contains a field of the given |type|.
583  bool SectionContainsField(DialogSection section, ServerFieldType type) {
584    const DetailInputs& inputs =
585        controller()->RequestedFieldsForSection(section);
586    for (DetailInputs::const_iterator it = inputs.begin(); it != inputs.end();
587         ++it) {
588      if (it->type == type)
589        return true;
590    }
591    return false;
592  }
593
594  SuggestionsMenuModel* GetMenuModelForSection(DialogSection section) {
595    ui::MenuModel* model = controller()->MenuModelForSection(section);
596    return static_cast<SuggestionsMenuModel*>(model);
597  }
598
599  void SubmitAndVerifyShippingAndBillingResults() {
600    // Test after setting use billing for shipping.
601    UseBillingForShipping();
602
603    controller()->OnAccept();
604
605    ASSERT_EQ(20U, form_structure()->field_count());
606    EXPECT_EQ(ADDRESS_HOME_COUNTRY,
607              form_structure()->field(11)->Type().GetStorableType());
608    EXPECT_EQ(ADDRESS_BILLING, form_structure()->field(11)->Type().group());
609    EXPECT_EQ(ADDRESS_HOME_COUNTRY,
610              form_structure()->field(18)->Type().GetStorableType());
611    EXPECT_EQ(ADDRESS_HOME, form_structure()->field(18)->Type().group());
612    base::string16 billing_country = form_structure()->field(11)->value;
613    EXPECT_EQ(2U, billing_country.size());
614    base::string16 shipping_country = form_structure()->field(18)->value;
615    EXPECT_EQ(2U, shipping_country.size());
616    EXPECT_FALSE(billing_country.empty());
617    EXPECT_FALSE(shipping_country.empty());
618    EXPECT_EQ(billing_country, shipping_country);
619
620    EXPECT_EQ(CREDIT_CARD_NAME,
621              form_structure()->field(1)->Type().GetStorableType());
622    base::string16 cc_name = form_structure()->field(1)->value;
623    EXPECT_EQ(NAME_FULL, form_structure()->field(6)->Type().GetStorableType());
624    EXPECT_EQ(NAME_BILLING, form_structure()->field(6)->Type().group());
625    base::string16 billing_name = form_structure()->field(6)->value;
626    EXPECT_EQ(NAME_FULL, form_structure()->field(13)->Type().GetStorableType());
627    EXPECT_EQ(NAME, form_structure()->field(13)->Type().group());
628    base::string16 shipping_name = form_structure()->field(13)->value;
629
630    EXPECT_FALSE(cc_name.empty());
631    EXPECT_FALSE(billing_name.empty());
632    EXPECT_FALSE(shipping_name.empty());
633    EXPECT_EQ(cc_name, billing_name);
634    EXPECT_EQ(cc_name, shipping_name);
635  }
636
637  TestAutofillDialogController* controller() { return controller_.get(); }
638
639  const FormStructure* form_structure() { return form_structure_; }
640
641  TestGeneratedCreditCardBubbleController* test_generated_bubble_controller() {
642    return test_generated_bubble_controller_;
643  }
644
645  const MockNewCreditCardBubbleController* mock_new_card_bubble_controller() {
646    return mock_new_card_bubble_controller_.get();
647  }
648
649 private:
650  void FinishedCallback(const FormStructure* form_structure) {
651    form_structure_ = form_structure;
652  }
653
654#if defined(OS_WIN)
655   // http://crbug.com/227221
656   ui::ScopedOleInitializer ole_initializer_;
657#endif
658
659  // The controller owns itself.
660  base::WeakPtr<TestAutofillDialogController> controller_;
661
662  // Must outlive the controller.
663  AutofillMetrics metric_logger_;
664
665  // Returned when the dialog closes successfully.
666  const FormStructure* form_structure_;
667
668  // Used to monitor if the Autofill credit card bubble is shown. Owned by
669  // |web_contents()|.
670  TestGeneratedCreditCardBubbleController* test_generated_bubble_controller_;
671
672  // Used to record when new card bubbles would show. Created in |Reset()|.
673  scoped_ptr<MockNewCreditCardBubbleController>
674      mock_new_card_bubble_controller_;
675
676  scoped_ptr<ScopedTestingLocalState> scoped_local_state_;
677};
678
679}  // namespace
680
681// Ensure the default ValidityMessage has the expected values.
682TEST_F(AutofillDialogControllerTest, DefaultValidityMessage) {
683  ValidityMessages messages;
684  ValidityMessage message = messages.GetMessageOrDefault(UNKNOWN_TYPE);
685  EXPECT_FALSE(message.sure);
686  EXPECT_TRUE(message.text.empty());
687}
688
689// This test makes sure nothing falls over when fields are being validity-
690// checked.
691TEST_F(AutofillDialogControllerTest, ValidityCheck) {
692  for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) {
693    DialogSection section = static_cast<DialogSection>(i);
694    const DetailInputs& shipping_inputs =
695        controller()->RequestedFieldsForSection(section);
696    for (DetailInputs::const_iterator iter = shipping_inputs.begin();
697         iter != shipping_inputs.end(); ++iter) {
698      controller()->InputValidityMessage(section, iter->type, base::string16());
699    }
700  }
701}
702
703// Test for phone number validation.
704TEST_F(AutofillDialogControllerTest, PhoneNumberValidation) {
705  // Construct FieldValueMap from existing data.
706  SwitchToAutofill();
707
708  for (size_t i = 0; i < 2; ++i) {
709    ServerFieldType phone = i == 0 ? PHONE_HOME_WHOLE_NUMBER :
710                                     PHONE_BILLING_WHOLE_NUMBER;
711    ServerFieldType address = i == 0 ? ADDRESS_HOME_COUNTRY :
712                                       ADDRESS_BILLING_COUNTRY;
713    DialogSection section = i == 0 ? SECTION_SHIPPING : SECTION_BILLING;
714
715    FieldValueMap outputs;
716    const DetailInputs& inputs =
717        controller()->RequestedFieldsForSection(section);
718    AutofillProfile full_profile(test::GetVerifiedProfile());
719    for (size_t i = 0; i < inputs.size(); ++i) {
720      const ServerFieldType type = inputs[i].type;
721      outputs[type] = full_profile.GetInfo(AutofillType(type), "en-US");
722    }
723
724    // Make sure country is United States.
725    outputs[address] = ASCIIToUTF16("United States");
726
727    // Existing data should have no errors.
728    ValidityMessages messages = controller()->InputsAreValid(section, outputs);
729    EXPECT_FALSE(HasAnyError(messages, phone));
730
731    // Input an empty phone number.
732    outputs[phone] = base::string16();
733    messages = controller()->InputsAreValid(section, outputs);
734    EXPECT_TRUE(HasUnsureError(messages, phone));
735
736    // Input an invalid phone number.
737    outputs[phone] = ASCIIToUTF16("ABC");
738    messages = controller()->InputsAreValid(section, outputs);
739    EXPECT_TRUE(messages.HasSureError(phone));
740
741    // Input a local phone number.
742    outputs[phone] = ASCIIToUTF16("2155546699");
743    messages = controller()->InputsAreValid(section, outputs);
744    EXPECT_FALSE(HasAnyError(messages, phone));
745
746    // Input an invalid local phone number.
747    outputs[phone] = ASCIIToUTF16("215554669");
748    messages = controller()->InputsAreValid(section, outputs);
749    EXPECT_TRUE(messages.HasSureError(phone));
750
751    // Input an international phone number.
752    outputs[phone] = ASCIIToUTF16("+33 892 70 12 39");
753    messages = controller()->InputsAreValid(section, outputs);
754    EXPECT_FALSE(HasAnyError(messages, phone));
755
756    // Input an invalid international phone number.
757    outputs[phone] = ASCIIToUTF16("+112333 892 70 12 39");
758    messages = controller()->InputsAreValid(section, outputs);
759    EXPECT_TRUE(messages.HasSureError(phone));
760  }
761}
762
763TEST_F(AutofillDialogControllerTest, ExpirationDateValidity) {
764  ui::ComboboxModel* exp_year_model =
765      controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR);
766  ui::ComboboxModel* exp_month_model =
767      controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH);
768
769  base::string16 default_year_value =
770      exp_year_model->GetItemAt(exp_year_model->GetDefaultIndex());
771  base::string16 default_month_value =
772      exp_month_model->GetItemAt(exp_month_model->GetDefaultIndex());
773
774  base::string16 other_year_value =
775      exp_year_model->GetItemAt(exp_year_model->GetItemCount() - 1);
776  base::string16 other_month_value =
777      exp_month_model->GetItemAt(exp_month_model->GetItemCount() - 1);
778
779  FieldValueMap outputs;
780  outputs[ADDRESS_BILLING_COUNTRY] = ASCIIToUTF16("United States");
781  outputs[CREDIT_CARD_EXP_MONTH] = default_month_value;
782  outputs[CREDIT_CARD_EXP_4_DIGIT_YEAR] = default_year_value;
783
784  // Expiration default values generate unsure validation errors (but not sure).
785  ValidityMessages messages = controller()->InputsAreValid(SECTION_CC_BILLING,
786                                                           outputs);
787  EXPECT_TRUE(HasUnsureError(messages, CREDIT_CARD_EXP_4_DIGIT_YEAR));
788  EXPECT_TRUE(HasUnsureError(messages, CREDIT_CARD_EXP_MONTH));
789
790  // Expiration date with default month fails.
791  outputs[CREDIT_CARD_EXP_4_DIGIT_YEAR] = other_year_value;
792  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
793  EXPECT_FALSE(HasUnsureError(messages, CREDIT_CARD_EXP_4_DIGIT_YEAR));
794  EXPECT_TRUE(HasUnsureError(messages, CREDIT_CARD_EXP_MONTH));
795
796  // Expiration date with default year fails.
797  outputs[CREDIT_CARD_EXP_MONTH] = other_month_value;
798  outputs[CREDIT_CARD_EXP_4_DIGIT_YEAR] = default_year_value;
799  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
800  EXPECT_TRUE(HasUnsureError(messages, CREDIT_CARD_EXP_4_DIGIT_YEAR));
801  EXPECT_FALSE(HasUnsureError(messages, CREDIT_CARD_EXP_MONTH));
802}
803
804TEST_F(AutofillDialogControllerTest, BillingNameValidation) {
805  // Construct FieldValueMap from AutofillProfile data.
806  SwitchToAutofill();
807
808  FieldValueMap outputs;
809  outputs[ADDRESS_BILLING_COUNTRY] = ASCIIToUTF16("United States");
810
811  // Input an empty billing name.
812  outputs[NAME_BILLING_FULL] = base::string16();
813  ValidityMessages messages = controller()->InputsAreValid(SECTION_BILLING,
814                                                           outputs);
815  EXPECT_TRUE(HasUnsureError(messages, NAME_BILLING_FULL));
816
817  // Input a non-empty billing name.
818  outputs[NAME_BILLING_FULL] = ASCIIToUTF16("Bob");
819  messages = controller()->InputsAreValid(SECTION_BILLING, outputs);
820  EXPECT_FALSE(HasAnyError(messages, NAME_BILLING_FULL));
821
822  // Switch to Wallet which only considers names with with at least two names to
823  // be valid.
824  SwitchToWallet();
825
826  // Setup some wallet state.
827  scoped_ptr<wallet::WalletItems> wallet_items =
828      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
829  controller()->OnDidGetWalletItems(wallet_items.Pass());
830
831  // Input an empty billing name. Data source should not change this behavior.
832  outputs[NAME_BILLING_FULL] = base::string16();
833  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
834  EXPECT_TRUE(HasUnsureError(messages, NAME_BILLING_FULL));
835
836  // Input a one name billing name. Wallet does not currently support this.
837  outputs[NAME_BILLING_FULL] = ASCIIToUTF16("Bob");
838  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
839  EXPECT_TRUE(messages.HasSureError(NAME_BILLING_FULL));
840
841  // Input a two name billing name.
842  outputs[NAME_BILLING_FULL] = ASCIIToUTF16("Bob Barker");
843  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
844  EXPECT_FALSE(HasAnyError(messages, NAME_BILLING_FULL));
845
846  // Input a more than two name billing name.
847  outputs[NAME_BILLING_FULL] = ASCIIToUTF16("John Jacob Jingleheimer Schmidt"),
848  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
849  EXPECT_FALSE(HasAnyError(messages, NAME_BILLING_FULL));
850
851  // Input a billing name with lots of crazy whitespace.
852  outputs[NAME_BILLING_FULL] =
853      ASCIIToUTF16("     \\n\\r John \\n  Jacob Jingleheimer \\t Schmidt  "),
854  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
855  EXPECT_FALSE(HasAnyError(messages, NAME_BILLING_FULL));
856}
857
858TEST_F(AutofillDialogControllerTest, CreditCardNumberValidation) {
859  // Construct FieldValueMap from AutofillProfile data.
860  SwitchToAutofill();
861
862  // Should accept AMEX, Visa, Master and Discover.
863  ValidateCCNumber(SECTION_CC, kTestCCNumberVisa, true);
864  ValidateCCNumber(SECTION_CC, kTestCCNumberMaster, true);
865  ValidateCCNumber(SECTION_CC, kTestCCNumberDiscover, true);
866  ValidateCCNumber(SECTION_CC, kTestCCNumberAmex, true);
867  ValidateCCNumber(SECTION_CC, kTestCCNumberIncomplete, false);
868  ValidateCCNumber(SECTION_CC, kTestCCNumberInvalid, false);
869
870  // Switch to Wallet which will not accept AMEX.
871  SwitchToWallet();
872
873  // Setup some wallet state on a merchant for which Wallet doesn't
874  // support AMEX.
875  controller()->OnDidGetWalletItems(
876      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
877
878  // Should accept Visa, Master and Discover, but not AMEX.
879  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberVisa, true);
880  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberMaster, true);
881  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberDiscover, true);
882  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberAmex, false);
883  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberIncomplete, false);
884  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberInvalid, false);
885
886  // Setup some wallet state on a merchant for which Wallet supports AMEX.
887  controller()->OnDidGetWalletItems(
888      wallet::GetTestWalletItems(wallet::AMEX_ALLOWED));
889
890  // Should accept Visa, Master, Discover, and AMEX.
891  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberVisa, true);
892  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberMaster, true);
893  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberDiscover, true);
894  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberAmex, true);
895  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberIncomplete, false);
896  ValidateCCNumber(SECTION_CC_BILLING, kTestCCNumberInvalid, false);
897}
898
899TEST_F(AutofillDialogControllerTest, AutofillProfiles) {
900  SwitchToAutofill();
901  ui::MenuModel* shipping_model =
902      controller()->MenuModelForSection(SECTION_SHIPPING);
903  // Since the PersonalDataManager is empty, this should only have the
904  // "use billing", "add new" and "manage" menu items.
905  ASSERT_TRUE(shipping_model);
906  EXPECT_EQ(3, shipping_model->GetItemCount());
907  // On the other hand, the other models should be NULL when there's no
908  // suggestion.
909  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
910  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_BILLING));
911
912  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(3);
913
914  // Empty profiles are ignored.
915  AutofillProfile empty_profile(base::GenerateGUID(), kSettingsOrigin);
916  empty_profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
917  controller()->GetTestingManager()->AddTestingProfile(&empty_profile);
918  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
919  ASSERT_TRUE(shipping_model);
920  EXPECT_EQ(3, shipping_model->GetItemCount());
921
922  // An otherwise full but unverified profile should be ignored.
923  AutofillProfile full_profile(test::GetFullProfile());
924  full_profile.set_origin("https://www.example.com");
925  full_profile.SetRawInfo(ADDRESS_HOME_LINE2, base::string16());
926  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
927  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
928  ASSERT_TRUE(shipping_model);
929  EXPECT_EQ(3, shipping_model->GetItemCount());
930
931  // A full, verified profile should be picked up.
932  AutofillProfile verified_profile(test::GetVerifiedProfile());
933  verified_profile.SetRawInfo(ADDRESS_HOME_LINE2, base::string16());
934  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
935  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
936  ASSERT_TRUE(shipping_model);
937  EXPECT_EQ(4, shipping_model->GetItemCount());
938}
939
940// Checks that a valid profile is selected by default, but if invalid is
941// popped into edit mode.
942TEST_F(AutofillDialogControllerTest, AutofillProfilesPopInvalidIntoEdit) {
943  SwitchToAutofill();
944  SuggestionsMenuModel* shipping_model =
945      GetMenuModelForSection(SECTION_SHIPPING);
946  EXPECT_EQ(3, shipping_model->GetItemCount());
947  // "Same as billing" is selected.
948  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
949  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
950
951  AutofillProfile verified_profile(test::GetVerifiedProfile());
952  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
953  EXPECT_EQ(4, shipping_model->GetItemCount());
954  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
955  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
956
957  // Now make up a problem and make sure the profile isn't in the list.
958  Reset();
959  SwitchToAutofill();
960  AddressProblems problems;
961  problems.push_back(
962      AddressProblem(::i18n::addressinput::POSTAL_CODE,
963                     AddressProblem::MISMATCHING_VALUE,
964                     IDS_LEARN_MORE));
965  EXPECT_CALL(*controller()->GetMockValidator(),
966              ValidateAddress(CountryCodeMatcher("US"), _, _)).
967      WillRepeatedly(DoAll(SetArgPointee<2>(problems),
968                           Return(AddressValidator::SUCCESS)));
969
970  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
971  shipping_model = GetMenuModelForSection(SECTION_SHIPPING);
972  EXPECT_EQ(4, shipping_model->GetItemCount());
973  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
974  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
975}
976
977// Makes sure suggestion profiles are re-validated when validation rules load.
978TEST_F(AutofillDialogControllerTest, AutofillProfilesRevalidateAfterRulesLoad) {
979  SwitchToAutofill();
980  SuggestionsMenuModel* shipping_model =
981      GetMenuModelForSection(SECTION_SHIPPING);
982  EXPECT_EQ(3, shipping_model->GetItemCount());
983  // "Same as billing" is selected.
984  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
985  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
986  AutofillProfile verified_profile(test::GetVerifiedProfile());
987  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
988  EXPECT_EQ(4, shipping_model->GetItemCount());
989  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
990  EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
991
992  AddressProblems problems;
993  problems.push_back(
994      AddressProblem(::i18n::addressinput::POSTAL_CODE,
995                     AddressProblem::MISMATCHING_VALUE,
996                     IDS_LEARN_MORE));
997  EXPECT_CALL(*controller()->GetMockValidator(),
998              ValidateAddress(CountryCodeMatcher("US"), _, _)).
999      WillRepeatedly(DoAll(SetArgPointee<2>(problems),
1000                           Return(AddressValidator::SUCCESS)));
1001
1002  controller()->OnAddressValidationRulesLoaded("US", true);
1003  EXPECT_EQ(4, shipping_model->GetItemCount());
1004  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1005  EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
1006}
1007
1008// Makes sure that the choice of which Autofill profile to use for each section
1009// is sticky.
1010TEST_F(AutofillDialogControllerTest, AutofillProfileDefaults) {
1011  SwitchToAutofill();
1012  AutofillProfile profile(test::GetVerifiedProfile());
1013  AutofillProfile profile2(test::GetVerifiedProfile2());
1014  controller()->GetTestingManager()->AddTestingProfile(&profile);
1015  controller()->GetTestingManager()->AddTestingProfile(&profile2);
1016
1017  // Until a selection has been made, the default shipping suggestion is the
1018  // first one (after "use billing").
1019  SuggestionsMenuModel* shipping_model =
1020      GetMenuModelForSection(SECTION_SHIPPING);
1021  EXPECT_EQ(1, shipping_model->checked_item());
1022
1023  for (int i = 2; i >= 0; --i) {
1024    shipping_model = GetMenuModelForSection(SECTION_SHIPPING);
1025    shipping_model->ExecuteCommand(i, 0);
1026    FillCreditCardInputs();
1027    controller()->OnAccept();
1028
1029    Reset();
1030    controller()->GetTestingManager()->AddTestingProfile(&profile);
1031    controller()->GetTestingManager()->AddTestingProfile(&profile2);
1032    shipping_model = GetMenuModelForSection(SECTION_SHIPPING);
1033    EXPECT_EQ(i, shipping_model->checked_item());
1034  }
1035
1036  // Try again, but don't add the default profile to the PDM. The dialog
1037  // should fall back to the first profile.
1038  shipping_model->ExecuteCommand(2, 0);
1039  FillCreditCardInputs();
1040  controller()->OnAccept();
1041  Reset();
1042  controller()->GetTestingManager()->AddTestingProfile(&profile);
1043  shipping_model = GetMenuModelForSection(SECTION_SHIPPING);
1044  EXPECT_EQ(1, shipping_model->checked_item());
1045}
1046
1047// Makes sure that a newly added Autofill profile becomes set as the default
1048// choice for the next run.
1049TEST_F(AutofillDialogControllerTest, NewAutofillProfileIsDefault) {
1050  SwitchToAutofill();
1051
1052  AutofillProfile profile(test::GetVerifiedProfile());
1053  CreditCard credit_card(test::GetVerifiedCreditCard());
1054  controller()->GetTestingManager()->AddTestingProfile(&profile);
1055  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1056
1057  // Until a selection has been made, the default suggestion is the first one.
1058  // For the shipping section, this follows the "use billing" suggestion.
1059  EXPECT_EQ(0, GetMenuModelForSection(SECTION_CC)->checked_item());
1060  EXPECT_EQ(1, GetMenuModelForSection(SECTION_SHIPPING)->checked_item());
1061
1062  // Fill in the shipping and credit card sections with new data.
1063  AutofillProfile new_profile(test::GetVerifiedProfile2());
1064  CreditCard new_credit_card(test::GetVerifiedCreditCard2());
1065  FillInputs(SECTION_SHIPPING, new_profile);
1066  FillInputs(SECTION_CC, new_credit_card);
1067  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(true);
1068  controller()->OnAccept();
1069
1070  // Update the |new_profile| and |new_credit_card|'s guids to the saved ones.
1071  new_profile.set_guid(
1072      controller()->GetTestingManager()->imported_profile().guid());
1073  new_credit_card.set_guid(
1074      controller()->GetTestingManager()->imported_credit_card().guid());
1075
1076  // Reload the dialog. The newly added address and credit card should now be
1077  // set as the defaults.
1078  Reset();
1079  controller()->GetTestingManager()->AddTestingProfile(&profile);
1080  controller()->GetTestingManager()->AddTestingProfile(&new_profile);
1081  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1082  controller()->GetTestingManager()->AddTestingCreditCard(&new_credit_card);
1083
1084  // Until a selection has been made, the default suggestion is the first one.
1085  // For the shipping section, this follows the "use billing" suggestion.
1086  EXPECT_EQ(1, GetMenuModelForSection(SECTION_CC)->checked_item());
1087  EXPECT_EQ(2, GetMenuModelForSection(SECTION_SHIPPING)->checked_item());
1088}
1089
1090TEST_F(AutofillDialogControllerTest, AutofillProfileVariants) {
1091  SwitchToAutofill();
1092  EXPECT_CALL(*controller()->GetView(), ModelChanged());
1093  ui::MenuModel* shipping_model =
1094      controller()->MenuModelForSection(SECTION_SHIPPING);
1095  ASSERT_TRUE(!!shipping_model);
1096  EXPECT_EQ(3, shipping_model->GetItemCount());
1097
1098  // Set up some variant data.
1099  AutofillProfile full_profile(test::GetVerifiedProfile());
1100  std::vector<base::string16> names;
1101  names.push_back(ASCIIToUTF16("John Doe"));
1102  names.push_back(ASCIIToUTF16("Jane Doe"));
1103  full_profile.SetRawMultiInfo(NAME_FULL, names);
1104  std::vector<base::string16> emails;
1105  emails.push_back(ASCIIToUTF16(kFakeEmail));
1106  emails.push_back(ASCIIToUTF16("admin@example.com"));
1107  full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
1108
1109  // Non-default variants are ignored by the dialog.
1110  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1111  EXPECT_EQ(4, shipping_model->GetItemCount());
1112}
1113
1114TEST_F(AutofillDialogControllerTest, SuggestValidEmail) {
1115  SwitchToAutofill();
1116  AutofillProfile profile(test::GetVerifiedProfile());
1117  const base::string16 kValidEmail = ASCIIToUTF16(kFakeEmail);
1118  profile.SetRawInfo(EMAIL_ADDRESS, kValidEmail);
1119  controller()->GetTestingManager()->AddTestingProfile(&profile);
1120
1121  // "add", "manage", and 1 suggestion.
1122  EXPECT_EQ(
1123      3, controller()->MenuModelForSection(SECTION_BILLING)->GetItemCount());
1124  // "add", "manage", 1 suggestion, and "same as billing".
1125  EXPECT_EQ(
1126      4, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1127}
1128
1129TEST_F(AutofillDialogControllerTest, DoNotSuggestInvalidEmail) {
1130  SwitchToAutofill();
1131  AutofillProfile profile(test::GetVerifiedProfile());
1132  profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16(".!#$%&'*+/=?^_`-@-.."));
1133  controller()->GetTestingManager()->AddTestingProfile(&profile);
1134
1135  EXPECT_FALSE(!!controller()->MenuModelForSection(SECTION_BILLING));
1136  // "add", "manage", 1 suggestion, and "same as billing".
1137  EXPECT_EQ(
1138      4, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1139}
1140
1141TEST_F(AutofillDialogControllerTest, SuggestValidAddress) {
1142  SwitchToAutofill();
1143  AutofillProfile full_profile(test::GetVerifiedProfile());
1144  full_profile.set_origin(kSettingsOrigin);
1145  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1146  // "add", "manage", and 1 suggestion.
1147  EXPECT_EQ(
1148      3, controller()->MenuModelForSection(SECTION_BILLING)->GetItemCount());
1149}
1150
1151TEST_F(AutofillDialogControllerTest, DoNotSuggestInvalidAddress) {
1152  SwitchToAutofill();
1153  AutofillProfile full_profile(test::GetVerifiedProfile());
1154  full_profile.set_origin(kSettingsOrigin);
1155  full_profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("C"));
1156  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1157}
1158
1159TEST_F(AutofillDialogControllerTest, DoNotSuggestIncompleteAddress) {
1160  SwitchToAutofill();
1161  AutofillProfile profile(test::GetVerifiedProfile());
1162  profile.SetRawInfo(ADDRESS_HOME_STATE, base::string16());
1163  controller()->GetTestingManager()->AddTestingProfile(&profile);
1164
1165  // Same as shipping, manage, add new.
1166  EXPECT_EQ(3,
1167      controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1168  EXPECT_FALSE(!!controller()->MenuModelForSection(SECTION_BILLING));
1169}
1170
1171TEST_F(AutofillDialogControllerTest, DoSuggestShippingAddressWithoutEmail) {
1172  SwitchToAutofill();
1173  AutofillProfile profile(test::GetVerifiedProfile());
1174  profile.SetRawInfo(EMAIL_ADDRESS, base::string16());
1175  controller()->GetTestingManager()->AddTestingProfile(&profile);
1176
1177  // Same as shipping, manage, add new, profile with missing email.
1178  EXPECT_EQ(4,
1179      controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1180  // Billing addresses require email.
1181  EXPECT_FALSE(!!controller()->MenuModelForSection(SECTION_BILLING));
1182}
1183
1184TEST_F(AutofillDialogControllerTest, AutofillCreditCards) {
1185  SwitchToAutofill();
1186  // Since the PersonalDataManager is empty, this should only have the
1187  // default menu items.
1188  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
1189
1190  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(3);
1191
1192  // Empty cards are ignored.
1193  CreditCard empty_card(base::GenerateGUID(), kSettingsOrigin);
1194  empty_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("John Doe"));
1195  controller()->GetTestingManager()->AddTestingCreditCard(&empty_card);
1196  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
1197
1198  // An otherwise full but unverified card should be ignored.
1199  CreditCard full_card(test::GetCreditCard());
1200  full_card.set_origin("https://www.example.com");
1201  controller()->GetTestingManager()->AddTestingCreditCard(&full_card);
1202  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
1203
1204  // A full, verified card should be picked up.
1205  CreditCard verified_card(test::GetCreditCard());
1206  verified_card.set_origin(kSettingsOrigin);
1207  controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
1208  ui::MenuModel* credit_card_model =
1209      controller()->MenuModelForSection(SECTION_CC);
1210  ASSERT_TRUE(credit_card_model);
1211  EXPECT_EQ(3, credit_card_model->GetItemCount());
1212}
1213
1214// Test selecting a shipping address different from billing as address.
1215TEST_F(AutofillDialogControllerTest, DontUseBillingAsShipping) {
1216  SwitchToAutofill();
1217  AutofillProfile full_profile(test::GetVerifiedProfile());
1218  AutofillProfile full_profile2(test::GetVerifiedProfile2());
1219  CreditCard credit_card(test::GetVerifiedCreditCard());
1220  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1221  controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
1222  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1223  ui::MenuModel* shipping_model =
1224      controller()->MenuModelForSection(SECTION_SHIPPING);
1225  shipping_model->ActivatedAt(2);
1226
1227  controller()->OnAccept();
1228  ASSERT_EQ(20U, form_structure()->field_count());
1229  EXPECT_EQ(ADDRESS_HOME_STATE,
1230            form_structure()->field(9)->Type().GetStorableType());
1231  EXPECT_EQ(ADDRESS_BILLING, form_structure()->field(9)->Type().group());
1232  EXPECT_EQ(ADDRESS_HOME_STATE,
1233            form_structure()->field(16)->Type().GetStorableType());
1234  EXPECT_EQ(ADDRESS_HOME, form_structure()->field(16)->Type().group());
1235  base::string16 billing_state = form_structure()->field(9)->value;
1236  base::string16 shipping_state = form_structure()->field(16)->value;
1237  EXPECT_FALSE(billing_state.empty());
1238  EXPECT_FALSE(shipping_state.empty());
1239  EXPECT_NE(billing_state, shipping_state);
1240
1241  EXPECT_EQ(CREDIT_CARD_NAME,
1242            form_structure()->field(1)->Type().GetStorableType());
1243  base::string16 cc_name = form_structure()->field(1)->value;
1244  EXPECT_EQ(NAME_FULL, form_structure()->field(6)->Type().GetStorableType());
1245  EXPECT_EQ(NAME_BILLING, form_structure()->field(6)->Type().group());
1246  base::string16 billing_name = form_structure()->field(6)->value;
1247  EXPECT_EQ(NAME_FULL, form_structure()->field(13)->Type().GetStorableType());
1248  EXPECT_EQ(NAME, form_structure()->field(13)->Type().group());
1249  base::string16 shipping_name = form_structure()->field(13)->value;
1250
1251  EXPECT_FALSE(cc_name.empty());
1252  EXPECT_FALSE(billing_name.empty());
1253  EXPECT_FALSE(shipping_name.empty());
1254  // Billing name should always be the same as cardholder name.
1255  EXPECT_EQ(cc_name, billing_name);
1256  EXPECT_NE(cc_name, shipping_name);
1257}
1258
1259// Test selecting UseBillingForShipping.
1260TEST_F(AutofillDialogControllerTest, UseBillingAsShipping) {
1261  SwitchToAutofill();
1262
1263  AutofillProfile full_profile(test::GetVerifiedProfile());
1264  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1265
1266  AutofillProfile full_profile2(test::GetVerifiedProfile2());
1267  controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
1268
1269  CreditCard credit_card(test::GetVerifiedCreditCard());
1270  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1271
1272  ASSERT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
1273  ASSERT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
1274
1275  SubmitAndVerifyShippingAndBillingResults();
1276}
1277
1278TEST_F(AutofillDialogControllerTest, UseBillingAsShippingManualInput) {
1279  SwitchToAutofill();
1280
1281  ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC));
1282  ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
1283
1284  CreditCard credit_card(test::GetVerifiedCreditCard());
1285  FillInputs(SECTION_CC, credit_card);
1286
1287  AutofillProfile full_profile(test::GetVerifiedProfile());
1288  FillInputs(SECTION_BILLING, full_profile);
1289
1290  SubmitAndVerifyShippingAndBillingResults();
1291}
1292
1293// Tests that shipping and billing telephone fields are supported, and filled
1294// in by their respective profiles. http://crbug.com/244515
1295TEST_F(AutofillDialogControllerTest, BillingVsShippingPhoneNumber) {
1296  FormFieldData shipping_tel;
1297  shipping_tel.autocomplete_attribute = "shipping tel";
1298  FormFieldData billing_tel;
1299  billing_tel.autocomplete_attribute = "billing tel";
1300
1301  FormData form_data;
1302  form_data.fields.push_back(shipping_tel);
1303  form_data.fields.push_back(billing_tel);
1304  SetUpControllerWithFormData(form_data);
1305
1306  SwitchToAutofill();
1307
1308  // The profile that will be chosen for the shipping section.
1309  AutofillProfile shipping_profile(test::GetVerifiedProfile());
1310  // The profile that will be chosen for the billing section.
1311  AutofillProfile billing_profile(test::GetVerifiedProfile2());
1312  CreditCard credit_card(test::GetVerifiedCreditCard());
1313  controller()->GetTestingManager()->AddTestingProfile(&shipping_profile);
1314  controller()->GetTestingManager()->AddTestingProfile(&billing_profile);
1315  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1316  ui::MenuModel* billing_model =
1317      controller()->MenuModelForSection(SECTION_BILLING);
1318  billing_model->ActivatedAt(1);
1319
1320  controller()->OnAccept();
1321  ASSERT_EQ(2U, form_structure()->field_count());
1322  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
1323            form_structure()->field(0)->Type().GetStorableType());
1324  EXPECT_EQ(PHONE_HOME, form_structure()->field(0)->Type().group());
1325  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
1326            form_structure()->field(1)->Type().GetStorableType());
1327  EXPECT_EQ(PHONE_BILLING, form_structure()->field(1)->Type().group());
1328  EXPECT_EQ(shipping_profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
1329            form_structure()->field(0)->value);
1330  EXPECT_EQ(billing_profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
1331            form_structure()->field(1)->value);
1332  EXPECT_NE(form_structure()->field(1)->value,
1333            form_structure()->field(0)->value);
1334}
1335
1336// Similar to the above, but tests that street-address (i.e. all lines of the
1337// street address) is successfully filled for both shipping and billing
1338// sections.
1339TEST_F(AutofillDialogControllerTest, BillingVsShippingStreetAddress) {
1340  FormFieldData shipping_address;
1341  shipping_address.autocomplete_attribute = "shipping street-address";
1342  FormFieldData billing_address;
1343  billing_address.autocomplete_attribute = "billing street-address";
1344  FormFieldData shipping_address_textarea;
1345  shipping_address_textarea.autocomplete_attribute = "shipping street-address";
1346  shipping_address_textarea.form_control_type = "textarea";
1347  FormFieldData billing_address_textarea;
1348  billing_address_textarea.autocomplete_attribute = "billing street-address";
1349  billing_address_textarea.form_control_type = "textarea";
1350
1351  FormData form_data;
1352  form_data.fields.push_back(shipping_address);
1353  form_data.fields.push_back(billing_address);
1354  form_data.fields.push_back(shipping_address_textarea);
1355  form_data.fields.push_back(billing_address_textarea);
1356  SetUpControllerWithFormData(form_data);
1357
1358  SwitchToAutofill();
1359
1360  // The profile that will be chosen for the shipping section.
1361  AutofillProfile shipping_profile(test::GetVerifiedProfile());
1362  // The profile that will be chosen for the billing section.
1363  AutofillProfile billing_profile(test::GetVerifiedProfile2());
1364  CreditCard credit_card(test::GetVerifiedCreditCard());
1365  controller()->GetTestingManager()->AddTestingProfile(&shipping_profile);
1366  controller()->GetTestingManager()->AddTestingProfile(&billing_profile);
1367  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1368  ui::MenuModel* billing_model =
1369      controller()->MenuModelForSection(SECTION_BILLING);
1370  billing_model->ActivatedAt(1);
1371
1372  controller()->OnAccept();
1373  ASSERT_EQ(4U, form_structure()->field_count());
1374  EXPECT_EQ(ADDRESS_HOME_STREET_ADDRESS,
1375            form_structure()->field(0)->Type().GetStorableType());
1376  EXPECT_EQ(ADDRESS_HOME, form_structure()->field(0)->Type().group());
1377  EXPECT_EQ(ADDRESS_HOME_STREET_ADDRESS,
1378            form_structure()->field(1)->Type().GetStorableType());
1379  EXPECT_EQ(ADDRESS_BILLING, form_structure()->field(1)->Type().group());
1380  // Inexact matching; single-line inputs get the address data concatenated but
1381  // separated by commas.
1382  EXPECT_TRUE(StartsWith(form_structure()->field(0)->value,
1383                         shipping_profile.GetRawInfo(ADDRESS_HOME_LINE1),
1384                         true));
1385  EXPECT_TRUE(EndsWith(form_structure()->field(0)->value,
1386                       shipping_profile.GetRawInfo(ADDRESS_HOME_LINE2),
1387                       true));
1388  EXPECT_TRUE(StartsWith(form_structure()->field(1)->value,
1389                         billing_profile.GetRawInfo(ADDRESS_HOME_LINE1),
1390                         true));
1391  EXPECT_TRUE(EndsWith(form_structure()->field(1)->value,
1392                       billing_profile.GetRawInfo(ADDRESS_HOME_LINE2),
1393                       true));
1394  // The textareas should be an exact match.
1395  EXPECT_EQ(shipping_profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS),
1396            form_structure()->field(2)->value);
1397  EXPECT_EQ(billing_profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS),
1398            form_structure()->field(3)->value);
1399
1400  EXPECT_NE(form_structure()->field(1)->value,
1401            form_structure()->field(0)->value);
1402  EXPECT_NE(form_structure()->field(3)->value,
1403            form_structure()->field(2)->value);
1404}
1405
1406TEST_F(AutofillDialogControllerTest, AcceptLegalDocuments) {
1407  for (size_t i = 0; i < 2; ++i) {
1408    SCOPED_TRACE(testing::Message() << "Case " << i);
1409
1410    EXPECT_CALL(*controller()->GetTestingWalletClient(),
1411                AcceptLegalDocuments(_, _));
1412    EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1413    EXPECT_CALL(*controller(), LoadRiskFingerprintData());
1414
1415    EXPECT_TRUE(controller()->LegalDocumentLinks().empty());
1416    controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
1417    EXPECT_TRUE(controller()->LegalDocumentLinks().empty());
1418
1419    scoped_ptr<wallet::WalletItems> wallet_items =
1420        CompleteAndValidWalletItems();
1421    wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1422    wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1423    controller()->OnDidGetWalletItems(wallet_items.Pass());
1424    EXPECT_FALSE(controller()->LegalDocumentLinks().empty());
1425
1426    controller()->OnAccept();
1427    controller()->OnDidAcceptLegalDocuments();
1428    controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1429
1430    // Now try it all over again with the location disclosure already accepted.
1431    // Nothing should change.
1432    Reset();
1433    base::ListValue preexisting_list;
1434    preexisting_list.AppendString(kFakeEmail);
1435    g_browser_process->local_state()->Set(
1436        ::prefs::kAutofillDialogWalletLocationAcceptance,
1437        preexisting_list);
1438  }
1439}
1440
1441TEST_F(AutofillDialogControllerTest, RejectLegalDocuments) {
1442  for (size_t i = 0; i < 2; ++i) {
1443    SCOPED_TRACE(testing::Message() << "Case " << i);
1444
1445    EXPECT_CALL(*controller()->GetTestingWalletClient(),
1446                AcceptLegalDocuments(_, _)).Times(0);
1447
1448    scoped_ptr<wallet::WalletItems> wallet_items =
1449        CompleteAndValidWalletItems();
1450    wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1451    wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1452    controller()->OnDidGetWalletItems(wallet_items.Pass());
1453    EXPECT_FALSE(controller()->LegalDocumentLinks().empty());
1454
1455    controller()->OnCancel();
1456
1457    // Now try it all over again with the location disclosure already accepted.
1458    // Nothing should change.
1459    Reset();
1460    base::ListValue preexisting_list;
1461    preexisting_list.AppendString(kFakeEmail);
1462    g_browser_process->local_state()->Set(
1463        ::prefs::kAutofillDialogWalletLocationAcceptance,
1464        preexisting_list);
1465  }
1466}
1467
1468TEST_F(AutofillDialogControllerTest, AcceptLocationDisclosure) {
1469  // Check that accepting the dialog registers the user's name in the list
1470  // of users who have accepted the geolocation terms.
1471  EXPECT_TRUE(g_browser_process->local_state()->GetList(
1472      ::prefs::kAutofillDialogWalletLocationAcceptance)->empty());
1473
1474  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
1475  EXPECT_FALSE(controller()->LegalDocumentsText().empty());
1476  EXPECT_TRUE(controller()->LegalDocumentLinks().empty());
1477  controller()->OnAccept();
1478
1479  const base::ListValue* list = g_browser_process->local_state()->GetList(
1480      ::prefs::kAutofillDialogWalletLocationAcceptance);
1481  ASSERT_EQ(1U, list->GetSize());
1482  std::string accepted_username;
1483  EXPECT_TRUE(list->GetString(0, &accepted_username));
1484  EXPECT_EQ(kFakeEmail, accepted_username);
1485
1486  // Now check it still works if that list starts off with some other username
1487  // in it.
1488  Reset();
1489  list = g_browser_process->local_state()->GetList(
1490      ::prefs::kAutofillDialogWalletLocationAcceptance);
1491  ASSERT_TRUE(list->empty());
1492
1493  std::string kOtherUsername("spouse@example.com");
1494  base::ListValue preexisting_list;
1495  preexisting_list.AppendString(kOtherUsername);
1496  g_browser_process->local_state()->Set(
1497      ::prefs::kAutofillDialogWalletLocationAcceptance,
1498      preexisting_list);
1499
1500  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
1501  EXPECT_FALSE(controller()->LegalDocumentsText().empty());
1502  EXPECT_TRUE(controller()->LegalDocumentLinks().empty());
1503  controller()->OnAccept();
1504
1505  list = g_browser_process->local_state()->GetList(
1506      ::prefs::kAutofillDialogWalletLocationAcceptance);
1507  ASSERT_EQ(2U, list->GetSize());
1508  EXPECT_NE(list->end(), list->Find(base::StringValue(kFakeEmail)));
1509  EXPECT_NE(list->end(), list->Find(base::StringValue(kOtherUsername)));
1510
1511  // Now check the list doesn't change if the user cancels out of the dialog.
1512  Reset();
1513  list = g_browser_process->local_state()->GetList(
1514      ::prefs::kAutofillDialogWalletLocationAcceptance);
1515  ASSERT_TRUE(list->empty());
1516
1517  g_browser_process->local_state()->Set(
1518      ::prefs::kAutofillDialogWalletLocationAcceptance,
1519      preexisting_list);
1520
1521  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
1522  EXPECT_FALSE(controller()->LegalDocumentsText().empty());
1523  EXPECT_TRUE(controller()->LegalDocumentLinks().empty());
1524  controller()->OnCancel();
1525
1526  list = g_browser_process->local_state()->GetList(
1527      ::prefs::kAutofillDialogWalletLocationAcceptance);
1528  ASSERT_EQ(1U, list->GetSize());
1529  EXPECT_NE(list->end(), list->Find(base::StringValue(kOtherUsername)));
1530  EXPECT_EQ(list->end(), list->Find(base::StringValue(kFakeEmail)));
1531}
1532
1533TEST_F(AutofillDialogControllerTest, LegalDocumentOverflow) {
1534  for (size_t number_of_docs = 2; number_of_docs < 11; ++number_of_docs) {
1535    scoped_ptr<wallet::WalletItems> wallet_items =
1536        CompleteAndValidWalletItems();
1537    for (size_t i = 0; i < number_of_docs; ++i)
1538      wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1539
1540    Reset();
1541    controller()->OnDidGetWalletItems(wallet_items.Pass());
1542
1543    // The dialog is only equipped to handle 2-6 legal documents. More than
1544    // 6 errors out.
1545    if (number_of_docs <= 6U) {
1546      EXPECT_FALSE(controller()->LegalDocumentsText().empty());
1547    } else {
1548      EXPECT_TRUE(controller()->LegalDocumentsText().empty());
1549      EXPECT_EQ(1U, NotificationsOfType(
1550          DialogNotification::WALLET_ERROR).size());
1551    }
1552  }
1553
1554  controller()->OnCancel();
1555}
1556
1557// Makes sure the default object IDs are respected.
1558TEST_F(AutofillDialogControllerTest, WalletDefaultItems) {
1559  scoped_ptr<wallet::WalletItems> wallet_items =
1560      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1561  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1562  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1563  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1564  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1565
1566  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
1567  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
1568  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
1569  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1570  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
1571
1572  controller()->OnDidGetWalletItems(wallet_items.Pass());
1573  // "add", "manage", and 4 suggestions.
1574  EXPECT_EQ(6,
1575      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
1576  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
1577      IsItemCheckedAt(2));
1578  ASSERT_FALSE(controller()->IsEditingExistingData(SECTION_CC_BILLING));
1579  // "use billing", "add", "manage", and 5 suggestions.
1580  EXPECT_EQ(8,
1581      controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1582  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_SHIPPING)->
1583      IsItemCheckedAt(4));
1584  ASSERT_FALSE(controller()->IsEditingExistingData(SECTION_SHIPPING));
1585}
1586
1587// Tests that invalid and AMEX default instruments are ignored.
1588TEST_F(AutofillDialogControllerTest, SelectInstrument) {
1589  scoped_ptr<wallet::WalletItems> wallet_items =
1590      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1591  // Tests if default instrument is invalid, then, the first valid instrument is
1592  // selected instead of the default instrument.
1593  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1594  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1595  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
1596  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1597
1598  controller()->OnDidGetWalletItems(wallet_items.Pass());
1599  // 4 suggestions and "add", "manage".
1600  EXPECT_EQ(6,
1601      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
1602  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
1603      IsItemCheckedAt(0));
1604
1605  // Tests if default instrument is AMEX but Wallet doesn't support
1606  // AMEX on this merchant, then the first valid instrument is
1607  // selected instead of the default instrument.
1608  wallet_items = wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1609  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1610  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1611  wallet_items->AddInstrument(
1612      wallet::GetTestMaskedInstrumentAmex(wallet::AMEX_DISALLOWED));
1613  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1614
1615  controller()->OnDidGetWalletItems(wallet_items.Pass());
1616  // 4 suggestions and "add", "manage".
1617  EXPECT_EQ(6,
1618      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
1619  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
1620      IsItemCheckedAt(0));
1621
1622  // Tests if default instrument is AMEX and it is allowed on this merchant,
1623  // then it is selected.
1624  wallet_items = wallet::GetTestWalletItems(wallet::AMEX_ALLOWED);
1625  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1626  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1627  wallet_items->AddInstrument(
1628      wallet::GetTestMaskedInstrumentAmex(wallet::AMEX_ALLOWED));
1629  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
1630
1631  controller()->OnDidGetWalletItems(wallet_items.Pass());
1632  // 4 suggestions and "add", "manage".
1633  EXPECT_EQ(6,
1634      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
1635  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
1636      IsItemCheckedAt(2));
1637
1638  // Tests if only have AMEX and invalid instrument, then "add" is selected.
1639  wallet_items = wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1640  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
1641  wallet_items->AddInstrument(
1642      wallet::GetTestMaskedInstrumentAmex(wallet::AMEX_DISALLOWED));
1643
1644  controller()->OnDidGetWalletItems(wallet_items.Pass());
1645  // 2 suggestions and "add", "manage".
1646  EXPECT_EQ(4,
1647      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
1648  // "add"
1649  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
1650      IsItemCheckedAt(2));
1651}
1652
1653TEST_F(AutofillDialogControllerTest, SaveAddress) {
1654  EXPECT_CALL(*controller()->GetView(), ModelChanged());
1655  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1656              SaveToWalletMock(testing::IsNull(),
1657                               testing::NotNull(),
1658                               testing::IsNull(),
1659                               testing::IsNull()));
1660
1661  scoped_ptr<wallet::WalletItems> wallet_items =
1662      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1663  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1664  controller()->OnDidGetWalletItems(wallet_items.Pass());
1665  // If there is no shipping address in wallet, it will default to
1666  // "same-as-billing" instead of "add-new-item". "same-as-billing" is covered
1667  // by the following tests. The penultimate item in the menu is "add-new-item".
1668  ui::MenuModel* shipping_model =
1669      controller()->MenuModelForSection(SECTION_SHIPPING);
1670  shipping_model->ActivatedAt(shipping_model->GetItemCount() - 2);
1671
1672  AutofillProfile test_profile(test::GetVerifiedProfile());
1673  FillInputs(SECTION_SHIPPING, test_profile);
1674
1675  AcceptAndLoadFakeFingerprint();
1676}
1677
1678TEST_F(AutofillDialogControllerTest, SaveInstrument) {
1679  EXPECT_CALL(*controller()->GetView(), ModelChanged());
1680  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1681              SaveToWalletMock(testing::NotNull(),
1682                               testing::IsNull(),
1683                               testing::IsNull(),
1684                               testing::IsNull()));
1685
1686  FillCCBillingInputs();
1687  scoped_ptr<wallet::WalletItems> wallet_items =
1688      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1689  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1690  SubmitWithWalletItems(wallet_items.Pass());
1691}
1692
1693TEST_F(AutofillDialogControllerTest, SaveInstrumentWithInvalidInstruments) {
1694  EXPECT_CALL(*controller()->GetView(), ModelChanged());
1695  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1696              SaveToWalletMock(testing::NotNull(),
1697                               testing::IsNull(),
1698                               testing::IsNull(),
1699                               testing::IsNull()));
1700
1701  FillCCBillingInputs();
1702  scoped_ptr<wallet::WalletItems> wallet_items =
1703      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1704  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1705  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
1706  SubmitWithWalletItems(wallet_items.Pass());
1707}
1708
1709TEST_F(AutofillDialogControllerTest, SaveInstrumentAndAddress) {
1710  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1711              SaveToWalletMock(testing::NotNull(),
1712                               testing::NotNull(),
1713                               testing::IsNull(),
1714                               testing::IsNull()));
1715
1716  FillCCBillingInputs();
1717  scoped_ptr<wallet::WalletItems> wallet_items =
1718      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1719  SubmitWithWalletItems(wallet_items.Pass());
1720}
1721
1722MATCHER(IsUpdatingExistingData, "updating existing Wallet data") {
1723  return !arg->object_id().empty();
1724}
1725
1726MATCHER(UsesLocalBillingAddress, "uses the local billing address") {
1727  return arg->street_address()[0] == ASCIIToUTF16(kEditedBillingAddress);
1728}
1729
1730// Tests that when using billing address for shipping, and there is no exact
1731// matched shipping address, then a shipping address should be added.
1732TEST_F(AutofillDialogControllerTest, BillingForShipping) {
1733  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1734              SaveToWalletMock(testing::IsNull(),
1735                               testing::NotNull(),
1736                               testing::IsNull(),
1737                               testing::IsNull()));
1738
1739  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
1740  // Select "Same as billing" in the address menu.
1741  UseBillingForShipping();
1742
1743  AcceptAndLoadFakeFingerprint();
1744}
1745
1746// Tests that when using billing address for shipping, and there is an exact
1747// matched shipping address, then a shipping address should not be added.
1748TEST_F(AutofillDialogControllerTest, BillingForShippingHasMatch) {
1749  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1750              SaveToWalletMock(_, _, _, _)).Times(0);
1751
1752  scoped_ptr<wallet::WalletItems> wallet_items =
1753      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1754  scoped_ptr<wallet::WalletItems::MaskedInstrument> instrument =
1755      wallet::GetTestMaskedInstrument();
1756  // Copy billing address as shipping address, and assign an id to it.
1757  scoped_ptr<wallet::Address> shipping_address(
1758      new wallet::Address(instrument->address()));
1759  shipping_address->set_object_id("shipping_address_id");
1760  wallet_items->AddAddress(shipping_address.Pass());
1761  wallet_items->AddInstrument(instrument.Pass());
1762  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1763
1764  controller()->OnDidGetWalletItems(wallet_items.Pass());
1765  // Select "Same as billing" in the address menu.
1766  UseBillingForShipping();
1767
1768  AcceptAndLoadFakeFingerprint();
1769}
1770
1771// Test that the local view contents is used when saving a new instrument and
1772// the user has selected "Same as billing".
1773TEST_F(AutofillDialogControllerTest, SaveInstrumentSameAsBilling) {
1774  scoped_ptr<wallet::WalletItems> wallet_items =
1775      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1776  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1777  controller()->OnDidGetWalletItems(wallet_items.Pass());
1778
1779  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC_BILLING);
1780  model->ActivatedAt(model->GetItemCount() - 2);
1781
1782  FieldValueMap outputs;
1783  const DetailInputs& inputs =
1784      controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
1785  AutofillProfile full_profile(test::GetVerifiedProfile());
1786  CreditCard full_card(test::GetCreditCard());
1787  for (size_t i = 0; i < inputs.size(); ++i) {
1788    const ServerFieldType type = inputs[i].type;
1789    if (type == ADDRESS_BILLING_LINE1)
1790      outputs[type] = ASCIIToUTF16(kEditedBillingAddress);
1791    else
1792      outputs[type] = full_profile.GetInfo(AutofillType(type), "en-US");
1793
1794    if (outputs[type].empty())
1795      outputs[type] = full_card.GetInfo(AutofillType(type), "en-US");
1796  }
1797  controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
1798
1799  controller()->OnAccept();
1800
1801  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1802              SaveToWalletMock(testing::NotNull(),
1803                               UsesLocalBillingAddress(),
1804                               testing::IsNull(),
1805                               testing::IsNull()));
1806  AcceptAndLoadFakeFingerprint();
1807}
1808
1809TEST_F(AutofillDialogControllerTest, CancelNoSave) {
1810  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1811              SaveToWalletMock(_, _, _, _)).Times(0);
1812
1813  EXPECT_CALL(*controller()->GetView(), ModelChanged());
1814
1815  controller()->OnDidGetWalletItems(
1816      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1817  controller()->OnCancel();
1818}
1819
1820// Checks that clicking the Manage menu item opens a new tab with a different
1821// URL for Wallet and Autofill.
1822TEST_F(AutofillDialogControllerTest, ManageItem) {
1823  AutofillProfile full_profile(test::GetVerifiedProfile());
1824  full_profile.set_origin(kSettingsOrigin);
1825  full_profile.SetRawInfo(ADDRESS_HOME_LINE2, base::string16());
1826  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1827  SwitchToAutofill();
1828
1829  SuggestionsMenuModel* shipping = GetMenuModelForSection(SECTION_SHIPPING);
1830  shipping->ExecuteCommand(shipping->GetItemCount() - 1, 0);
1831  GURL autofill_manage_url = controller()->open_tab_url();
1832  EXPECT_EQ("chrome", autofill_manage_url.scheme());
1833
1834  SwitchToWallet();
1835  scoped_ptr<wallet::WalletItems> wallet_items =
1836      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1837  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1838  controller()->OnDidGetWalletItems(wallet_items.Pass());
1839
1840  controller()->SuggestionItemSelected(shipping, shipping->GetItemCount() - 1);
1841  GURL wallet_manage_addresses_url = controller()->open_tab_url();
1842  EXPECT_EQ("https", wallet_manage_addresses_url.scheme());
1843
1844  SuggestionsMenuModel* billing = GetMenuModelForSection(SECTION_CC_BILLING);
1845  controller()->SuggestionItemSelected(billing, billing->GetItemCount() - 1);
1846  GURL wallet_manage_instruments_url = controller()->open_tab_url();
1847  EXPECT_EQ("https", wallet_manage_instruments_url.scheme());
1848
1849  EXPECT_NE(autofill_manage_url, wallet_manage_instruments_url);
1850  EXPECT_NE(wallet_manage_instruments_url, wallet_manage_addresses_url);
1851}
1852
1853// Tests that adding an autofill profile and then submitting works.
1854TEST_F(AutofillDialogControllerTest, AddAutofillProfile) {
1855  SwitchToAutofill();
1856  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(2);
1857
1858  AutofillProfile full_profile(test::GetVerifiedProfile());
1859  CreditCard credit_card(test::GetVerifiedCreditCard());
1860  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1861  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1862
1863  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_BILLING);
1864  // Activate the "Add billing address" menu item.
1865  model->ActivatedAt(model->GetItemCount() - 2);
1866
1867  // Fill in the inputs from the profile.
1868  FieldValueMap outputs;
1869  const DetailInputs& inputs =
1870      controller()->RequestedFieldsForSection(SECTION_BILLING);
1871  AutofillProfile full_profile2(test::GetVerifiedProfile2());
1872  for (size_t i = 0; i < inputs.size(); ++i) {
1873    const ServerFieldType type = inputs[i].type;
1874    outputs[type] = full_profile2.GetInfo(AutofillType(type), "en-US");
1875  }
1876  controller()->GetView()->SetUserInput(SECTION_BILLING, outputs);
1877
1878  controller()->OnAccept();
1879  const AutofillProfile& added_profile =
1880      controller()->GetTestingManager()->imported_profile();
1881
1882  const DetailInputs& shipping_inputs =
1883      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
1884  for (size_t i = 0; i < shipping_inputs.size(); ++i) {
1885    const ServerFieldType type = shipping_inputs[i].type;
1886    EXPECT_EQ(full_profile2.GetInfo(AutofillType(type), "en-US"),
1887              added_profile.GetInfo(AutofillType(type), "en-US"));
1888  }
1889}
1890
1891TEST_F(AutofillDialogControllerTest, VerifyCvv) {
1892  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1893  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1894              AuthenticateInstrument(_, _));
1895
1896  SubmitWithWalletItems(CompleteAndValidWalletItems());
1897
1898  EXPECT_TRUE(NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty());
1899  EXPECT_TRUE(controller()->SectionIsActive(SECTION_SHIPPING));
1900  EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING));
1901  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1902  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1903
1904  SuggestionState suggestion_state =
1905      controller()->SuggestionStateForSection(SECTION_CC_BILLING);
1906  EXPECT_TRUE(suggestion_state.extra_text.empty());
1907
1908  controller()->OnDidGetFullWallet(
1909      wallet::GetTestFullWalletWithRequiredActions(
1910          std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
1911  ASSERT_TRUE(controller()->IsSubmitPausedOn(wallet::VERIFY_CVV));
1912
1913  EXPECT_FALSE(
1914      NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty());
1915  EXPECT_FALSE(controller()->SectionIsActive(SECTION_SHIPPING));
1916  EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING));
1917
1918  suggestion_state =
1919      controller()->SuggestionStateForSection(SECTION_CC_BILLING);
1920  EXPECT_FALSE(suggestion_state.extra_text.empty());
1921  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING));
1922
1923  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1924  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1925
1926  controller()->OnAccept();
1927
1928  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
1929}
1930
1931TEST_F(AutofillDialogControllerTest, ErrorDuringSubmit) {
1932  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1933
1934  SubmitWithWalletItems(CompleteAndValidWalletItems());
1935
1936  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1937  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1938
1939  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
1940
1941  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1942  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1943}
1944
1945TEST_F(AutofillDialogControllerTest, ErrorDuringVerifyCvv) {
1946  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1947
1948  SubmitWithWalletItems(CompleteAndValidWalletItems());
1949  controller()->OnDidGetFullWallet(
1950      wallet::GetTestFullWalletWithRequiredActions(
1951          std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
1952
1953  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1954  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1955
1956  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
1957
1958  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1959  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1960}
1961
1962// Simulates receiving an INVALID_FORM_FIELD required action while processing a
1963// |WalletClientDelegate::OnDid{Save,Update}*()| call. This can happen if Online
1964// Wallet's server validation differs from Chrome's local validation.
1965TEST_F(AutofillDialogControllerTest, WalletServerSideValidation) {
1966  scoped_ptr<wallet::WalletItems> wallet_items =
1967      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1968  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1969  controller()->OnDidGetWalletItems(wallet_items.Pass());
1970  controller()->OnAccept();
1971
1972  std::vector<wallet::RequiredAction> required_actions;
1973  required_actions.push_back(wallet::INVALID_FORM_FIELD);
1974
1975  std::vector<wallet::FormFieldError> form_errors;
1976  form_errors.push_back(
1977      wallet::FormFieldError(wallet::FormFieldError::INVALID_POSTAL_CODE,
1978                             wallet::FormFieldError::SHIPPING_ADDRESS));
1979
1980  EXPECT_CALL(*controller()->GetView(), UpdateForErrors());
1981  controller()->OnDidSaveToWallet(std::string(),
1982                                  std::string(),
1983                                  required_actions,
1984                                  form_errors);
1985}
1986
1987// Simulates receiving unrecoverable Wallet server validation errors.
1988TEST_F(AutofillDialogControllerTest, WalletServerSideValidationUnrecoverable) {
1989  scoped_ptr<wallet::WalletItems> wallet_items =
1990      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1991  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1992  controller()->OnDidGetWalletItems(wallet_items.Pass());
1993  controller()->OnAccept();
1994
1995  std::vector<wallet::RequiredAction> required_actions;
1996  required_actions.push_back(wallet::INVALID_FORM_FIELD);
1997
1998  std::vector<wallet::FormFieldError> form_errors;
1999  form_errors.push_back(
2000      wallet::FormFieldError(wallet::FormFieldError::UNKNOWN_ERROR,
2001                             wallet::FormFieldError::UNKNOWN_LOCATION));
2002
2003  controller()->OnDidSaveToWallet(std::string(),
2004                                  std::string(),
2005                                  required_actions,
2006                                  form_errors);
2007
2008  EXPECT_EQ(1U, NotificationsOfType(
2009      DialogNotification::REQUIRED_ACTION).size());
2010}
2011
2012// Test Wallet banners are show in the right situations. These banners promote
2013// saving details into Wallet (i.e. "[x] Save details to Wallet").
2014TEST_F(AutofillDialogControllerTest, WalletBanners) {
2015  // Simulate non-signed-in case.
2016  SetUpControllerWithFormData(DefaultFormData());
2017  GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
2018  controller()->OnPassiveSigninFailure(error);
2019  EXPECT_EQ(0U, NotificationsOfType(
2020      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2021
2022  // Sign in a user with a completed account.
2023  SetUpControllerWithFormData(DefaultFormData());
2024  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2025
2026  // Full account; should show "Details from Wallet" message.
2027  EXPECT_EQ(1U, NotificationsOfType(
2028      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2029  SwitchToAutofill();
2030  EXPECT_EQ(1U, NotificationsOfType(
2031      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2032
2033  // Start over and sign in a user with an incomplete account.
2034  SetUpControllerWithFormData(DefaultFormData());
2035  scoped_ptr<wallet::WalletItems> wallet_items =
2036      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2037  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2038  controller()->OnDidGetWalletItems(wallet_items.Pass());
2039
2040  // Partial account.
2041  EXPECT_EQ(1U, NotificationsOfType(
2042      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2043
2044  SwitchToAutofill();
2045  EXPECT_EQ(1U, NotificationsOfType(
2046      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2047
2048  // A Wallet error should kill any Wallet promos.
2049  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
2050
2051  EXPECT_EQ(1U, NotificationsOfType(
2052      DialogNotification::WALLET_ERROR).size());
2053  EXPECT_EQ(0U, NotificationsOfType(
2054      DialogNotification::WALLET_USAGE_CONFIRMATION).size());
2055}
2056
2057TEST_F(AutofillDialogControllerTest, ViewCancelDoesntSetPref) {
2058  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
2059      ::prefs::kAutofillDialogPayWithoutWallet));
2060
2061  SwitchToAutofill();
2062
2063  controller()->OnCancel();
2064  controller()->ViewClosed();
2065
2066  EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath(
2067      ::prefs::kAutofillDialogPayWithoutWallet));
2068}
2069
2070TEST_F(AutofillDialogControllerTest, SubmitWithSigninErrorDoesntSetPref) {
2071  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
2072      ::prefs::kAutofillDialogPayWithoutWallet));
2073
2074  SimulateSigninError();
2075  FillCreditCardInputs();
2076  controller()->OnAccept();
2077
2078  EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath(
2079      ::prefs::kAutofillDialogPayWithoutWallet));
2080}
2081
2082// Tests that there's an overlay shown while waiting for full wallet items.
2083TEST_F(AutofillDialogControllerTest, WalletFirstRun) {
2084  EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
2085
2086  SubmitWithWalletItems(CompleteAndValidWalletItems());
2087  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
2088
2089  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
2090  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
2091  EXPECT_FALSE(form_structure());
2092
2093  // Don't make the test wait for 2 seconds.
2094  controller()->ForceFinishSubmit();
2095  EXPECT_TRUE(form_structure());
2096}
2097
2098TEST_F(AutofillDialogControllerTest, ViewSubmitSetsPref) {
2099  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
2100      ::prefs::kAutofillDialogPayWithoutWallet));
2101
2102  SwitchToAutofill();
2103  FillCreditCardInputs();
2104  controller()->OnAccept();
2105
2106  EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(
2107      ::prefs::kAutofillDialogPayWithoutWallet));
2108  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
2109      ::prefs::kAutofillDialogPayWithoutWallet));
2110
2111  // Try again with a signin error (just leaves the pref alone).
2112  SetUpControllerWithFormData(DefaultFormData());
2113
2114  // Setting up the controller again should not change the pref.
2115  EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(
2116      ::prefs::kAutofillDialogPayWithoutWallet));
2117  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
2118      ::prefs::kAutofillDialogPayWithoutWallet));
2119
2120  SimulateSigninError();
2121  FillCreditCardInputs();
2122  controller()->OnAccept();
2123  EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(
2124      ::prefs::kAutofillDialogPayWithoutWallet));
2125  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
2126      ::prefs::kAutofillDialogPayWithoutWallet));
2127
2128  // Successfully choosing wallet does set the pref.
2129  // Note that OnDidGetWalletItems sets the account chooser to wallet mode.
2130  SetUpControllerWithFormData(DefaultFormData());
2131
2132  controller()->OnDidFetchWalletCookieValue(std::string());
2133  scoped_ptr<wallet::WalletItems> wallet_items =
2134      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2135  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2136  controller()->OnDidGetWalletItems(wallet_items.Pass());
2137  controller()->OnAccept();
2138  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
2139  controller()->ForceFinishSubmit();
2140
2141  EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(
2142      ::prefs::kAutofillDialogPayWithoutWallet));
2143  EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
2144      ::prefs::kAutofillDialogPayWithoutWallet));
2145}
2146
2147TEST_F(AutofillDialogControllerTest, HideWalletEmail) {
2148  SwitchToAutofill();
2149
2150  // Email field should be showing when using Autofill.
2151  EXPECT_TRUE(controller()->SectionIsActive(SECTION_BILLING));
2152  EXPECT_FALSE(controller()->SectionIsActive(SECTION_CC_BILLING));
2153  EXPECT_TRUE(SectionContainsField(SECTION_BILLING, EMAIL_ADDRESS));
2154
2155  SwitchToWallet();
2156
2157  // Reset the wallet state.
2158  controller()->OnDidGetWalletItems(scoped_ptr<wallet::WalletItems>());
2159
2160  // Setup some wallet state, submit, and get a full wallet to end the flow.
2161  scoped_ptr<wallet::WalletItems> wallet_items = CompleteAndValidWalletItems();
2162
2163  // Filling |form_structure()| depends on the current username and wallet items
2164  // being fetched. Until both of these have occurred, the user should not be
2165  // able to click Submit if using Wallet. The username fetch happened earlier.
2166  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2167  controller()->OnDidGetWalletItems(wallet_items.Pass());
2168  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2169
2170  // Email field should be absent when using Wallet.
2171  EXPECT_FALSE(controller()->SectionIsActive(SECTION_BILLING));
2172  EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING));
2173  EXPECT_FALSE(SectionContainsField(SECTION_CC_BILLING, EMAIL_ADDRESS));
2174
2175  controller()->OnAccept();
2176  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
2177  controller()->ForceFinishSubmit();
2178
2179  ASSERT_TRUE(form_structure());
2180  size_t i = 0;
2181  for (; i < form_structure()->field_count(); ++i) {
2182    if (form_structure()->field(i)->Type().GetStorableType() == EMAIL_ADDRESS) {
2183      EXPECT_EQ(ASCIIToUTF16(kFakeEmail), form_structure()->field(i)->value);
2184      break;
2185    }
2186  }
2187  EXPECT_LT(i, form_structure()->field_count());
2188}
2189
2190// Test if autofill types of returned form structure are correct for billing
2191// entries.
2192TEST_F(AutofillDialogControllerTest, AutofillTypes) {
2193  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2194  controller()->OnAccept();
2195  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
2196  controller()->ForceFinishSubmit();
2197  ASSERT_TRUE(form_structure());
2198  ASSERT_EQ(20U, form_structure()->field_count());
2199  EXPECT_EQ(EMAIL_ADDRESS,
2200            form_structure()->field(0)->Type().GetStorableType());
2201  EXPECT_EQ(CREDIT_CARD_NUMBER,
2202            form_structure()->field(2)->Type().GetStorableType());
2203  EXPECT_EQ(ADDRESS_HOME_STATE,
2204            form_structure()->field(9)->Type().GetStorableType());
2205  EXPECT_EQ(ADDRESS_BILLING, form_structure()->field(9)->Type().group());
2206  EXPECT_EQ(ADDRESS_HOME_STATE,
2207            form_structure()->field(16)->Type().GetStorableType());
2208  EXPECT_EQ(ADDRESS_HOME, form_structure()->field(16)->Type().group());
2209}
2210
2211TEST_F(AutofillDialogControllerTest, SaveDetailsInChrome) {
2212  SwitchToAutofill();
2213  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(4);
2214
2215  AutofillProfile full_profile(test::GetVerifiedProfile());
2216  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
2217
2218  CreditCard card(test::GetVerifiedCreditCard());
2219  controller()->GetTestingManager()->AddTestingCreditCard(&card);
2220  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
2221
2222  controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(0);
2223  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
2224
2225  controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
2226  EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome());
2227
2228  profile()->GetPrefs()->SetBoolean(prefs::kAutofillEnabled, false);
2229  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
2230
2231  profile()->GetPrefs()->SetBoolean(prefs::kAutofillEnabled, true);
2232  controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
2233  EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome());
2234
2235  profile()->ForceIncognito(true);
2236  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
2237}
2238
2239TEST_F(AutofillDialogControllerTest, DisabledAutofill) {
2240  SwitchToAutofill();
2241  ASSERT_TRUE(profile()->GetPrefs()->GetBoolean(prefs::kAutofillEnabled));
2242
2243  AutofillProfile verified_profile(test::GetVerifiedProfile());
2244  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
2245
2246  CreditCard credit_card(test::GetVerifiedCreditCard());
2247  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
2248
2249  // Verify suggestions menus should be showing when Autofill is enabled.
2250  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC));
2251  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_BILLING));
2252  EXPECT_EQ(
2253      4, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
2254
2255  EXPECT_CALL(*controller()->GetView(), ModelChanged());
2256  profile()->GetPrefs()->SetBoolean(prefs::kAutofillEnabled, false);
2257
2258  // Verify billing and credit card suggestions menus are hidden when Autofill
2259  // is disabled.
2260  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
2261  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_BILLING));
2262  // And that the shipping suggestions menu has less selections.
2263  EXPECT_EQ(
2264      2, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
2265
2266  // Additionally, editing fields should not show Autofill popups.
2267  ASSERT_NO_FATAL_FAILURE(controller()->UserEditedOrActivatedInput(
2268      SECTION_BILLING,
2269      NAME_BILLING_FULL,
2270      gfx::NativeView(),
2271      gfx::Rect(),
2272      verified_profile.GetRawInfo(NAME_FULL).substr(0, 1),
2273      true));
2274  EXPECT_EQ(UNKNOWN_TYPE, controller()->popup_input_type());
2275}
2276
2277// Tests that user is prompted when using instrument with minimal address.
2278TEST_F(AutofillDialogControllerTest, UpgradeMinimalAddress) {
2279  // A minimal address being selected should trigger error validation in the
2280  // view. Called once for each incomplete suggestion.
2281  EXPECT_CALL(*controller()->GetView(), UpdateForErrors());
2282
2283  scoped_ptr<wallet::WalletItems> wallet_items =
2284      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2285  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentWithIdAndAddress(
2286      "id", wallet::GetTestMinimalAddress()));
2287  scoped_ptr<wallet::Address> address(wallet::GetTestShippingAddress());
2288  address->set_is_complete_address(false);
2289  wallet_items->AddAddress(address.Pass());
2290  controller()->OnDidGetWalletItems(wallet_items.Pass());
2291
2292  // Assert that dialog's SECTION_CC_BILLING section is in edit mode.
2293  ASSERT_TRUE(controller()->IsEditingExistingData(SECTION_CC_BILLING));
2294  // Shipping section should be in edit mode because of
2295  // is_minimal_shipping_address.
2296  ASSERT_TRUE(controller()->IsEditingExistingData(SECTION_SHIPPING));
2297}
2298
2299TEST_F(AutofillDialogControllerTest, RiskNeverLoadsWithPendingLegalDocuments) {
2300  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(0);
2301
2302  scoped_ptr<wallet::WalletItems> wallet_items = CompleteAndValidWalletItems();
2303  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
2304  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
2305  controller()->OnDidGetWalletItems(wallet_items.Pass());
2306  controller()->OnAccept();
2307}
2308
2309TEST_F(AutofillDialogControllerTest, RiskLoadsAfterAcceptingLegalDocuments) {
2310  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(0);
2311
2312  scoped_ptr<wallet::WalletItems> wallet_items = CompleteAndValidWalletItems();
2313  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
2314  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
2315  controller()->OnDidGetWalletItems(wallet_items.Pass());
2316
2317  testing::Mock::VerifyAndClear(controller());
2318  EXPECT_CALL(*controller(), LoadRiskFingerprintData());
2319
2320  controller()->OnAccept();
2321
2322  // Simulate a risk load and verify |GetRiskData()| matches the encoded value.
2323  controller()->OnDidAcceptLegalDocuments();
2324  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
2325  EXPECT_EQ(kFakeFingerprintEncoded, controller()->GetRiskData());
2326}
2327
2328TEST_F(AutofillDialogControllerTest, NoManageMenuItemForNewWalletUsers) {
2329  // Make sure the menu model item is created for a returning Wallet user.
2330  scoped_ptr<wallet::WalletItems> wallet_items =
2331      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2332  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2333  wallet_items->AddAddress(wallet::GetTestShippingAddress());
2334  controller()->OnDidGetWalletItems(wallet_items.Pass());
2335
2336  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING));
2337  // "Same as billing", "123 address", "Add address...", and "Manage addresses".
2338  EXPECT_EQ(
2339      4, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
2340
2341  // Make sure the menu model item is not created for new Wallet users.
2342  base::DictionaryValue dict;
2343  scoped_ptr<base::ListValue> required_actions(new base::ListValue);
2344  required_actions->AppendString("setup_wallet");
2345  dict.Set("required_action", required_actions.release());
2346  controller()->OnDidGetWalletItems(
2347      wallet::WalletItems::CreateWalletItems(dict).Pass());
2348
2349  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING));
2350  // "Same as billing" and "Add address...".
2351  EXPECT_EQ(
2352      2, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
2353}
2354
2355TEST_F(AutofillDialogControllerTest, ShippingSectionCanBeHidden) {
2356  FormFieldData email_field;
2357  email_field.autocomplete_attribute = "email";
2358  FormFieldData cc_field;
2359  cc_field.autocomplete_attribute = "cc-number";
2360  FormFieldData billing_field;
2361  billing_field.autocomplete_attribute = "billing region";
2362
2363  FormData form_data;
2364  form_data.fields.push_back(email_field);
2365  form_data.fields.push_back(cc_field);
2366  form_data.fields.push_back(billing_field);
2367
2368  AutofillProfile full_profile(test::GetVerifiedProfile());
2369  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
2370  SetUpControllerWithFormData(form_data);
2371
2372  SwitchToAutofill();
2373
2374  EXPECT_FALSE(controller()->SectionIsActive(SECTION_SHIPPING));
2375
2376  FillCreditCardInputs();
2377  controller()->OnAccept();
2378  EXPECT_TRUE(form_structure());
2379}
2380
2381TEST_F(AutofillDialogControllerTest, ShippingSectionCanBeHiddenForWallet) {
2382  FormFieldData email_field;
2383  email_field.autocomplete_attribute = "email";
2384  FormFieldData cc_field;
2385  cc_field.autocomplete_attribute = "cc-number";
2386  FormFieldData billing_field;
2387  billing_field.autocomplete_attribute = "billing region";
2388
2389  FormData form_data;
2390  form_data.fields.push_back(email_field);
2391  form_data.fields.push_back(cc_field);
2392  form_data.fields.push_back(billing_field);
2393
2394  SetUpControllerWithFormData(form_data);
2395  EXPECT_FALSE(controller()->SectionIsActive(SECTION_SHIPPING));
2396  EXPECT_FALSE(controller()->IsShippingAddressRequired());
2397
2398  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
2399  scoped_ptr<wallet::WalletItems> wallet_items =
2400      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2401  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2402  SubmitWithWalletItems(wallet_items.Pass());
2403  controller()->OnDidGetFullWallet(wallet::GetTestFullWalletInstrumentOnly());
2404  controller()->ForceFinishSubmit();
2405  EXPECT_TRUE(form_structure());
2406}
2407
2408TEST_F(AutofillDialogControllerTest, NotProdNotification) {
2409  // To make IsPayingWithWallet() true.
2410  controller()->OnDidGetWalletItems(
2411      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
2412
2413  CommandLine* command_line = CommandLine::ForCurrentProcess();
2414  ASSERT_EQ(
2415      "",
2416      command_line->GetSwitchValueASCII(switches::kWalletServiceUseSandbox));
2417
2418  command_line->AppendSwitchASCII(switches::kWalletServiceUseSandbox, "1");
2419  EXPECT_EQ(1U,
2420            NotificationsOfType(DialogNotification::DEVELOPER_WARNING).size());
2421}
2422
2423TEST_F(AutofillDialogControllerTest, NoNotProdNotification) {
2424  // To make IsPayingWithWallet() true.
2425  controller()->OnDidGetWalletItems(
2426      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
2427
2428  CommandLine* command_line = CommandLine::ForCurrentProcess();
2429  ASSERT_EQ(
2430      "",
2431      command_line->GetSwitchValueASCII(switches::kWalletServiceUseSandbox));
2432
2433  command_line->AppendSwitchASCII(switches::kWalletServiceUseSandbox, "0");
2434  EXPECT_EQ(0U,
2435            NotificationsOfType(DialogNotification::DEVELOPER_WARNING).size());
2436}
2437
2438// Ensure Wallet instruments marked expired by the server are shown as invalid.
2439TEST_F(AutofillDialogControllerTest, WalletExpiredCard) {
2440  scoped_ptr<wallet::WalletItems> wallet_items =
2441      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2442  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentExpired());
2443  controller()->OnDidGetWalletItems(wallet_items.Pass());
2444
2445  EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC_BILLING));
2446
2447  const DetailInputs& inputs =
2448      controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
2449  FieldValueMap outputs;
2450  CopyInitialValues(inputs, &outputs);
2451
2452  // The local inputs are invalid because the server said so. They'll
2453  // stay invalid until they differ from the remotely fetched model.
2454  ValidityMessages messages = controller()->InputsAreValid(SECTION_CC_BILLING,
2455                                                           outputs);
2456  EXPECT_TRUE(messages.HasSureError(CREDIT_CARD_EXP_MONTH));
2457  EXPECT_TRUE(messages.HasSureError(CREDIT_CARD_EXP_4_DIGIT_YEAR));
2458
2459  // Make the local input year differ from the instrument.
2460  CopyInitialValues(inputs, &outputs);
2461  outputs[CREDIT_CARD_EXP_4_DIGIT_YEAR] = ASCIIToUTF16("3002");
2462  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
2463  EXPECT_FALSE(HasAnyError(messages, CREDIT_CARD_EXP_MONTH));
2464  EXPECT_FALSE(HasAnyError(messages, CREDIT_CARD_EXP_4_DIGIT_YEAR));
2465
2466  // Make the local input month differ from the instrument.
2467  CopyInitialValues(inputs, &outputs);
2468  outputs[CREDIT_CARD_EXP_MONTH] = ASCIIToUTF16("06");
2469  messages = controller()->InputsAreValid(SECTION_CC_BILLING, outputs);
2470  EXPECT_FALSE(HasAnyError(messages, CREDIT_CARD_EXP_MONTH));
2471  EXPECT_FALSE(HasAnyError(messages, CREDIT_CARD_EXP_4_DIGIT_YEAR));
2472}
2473
2474TEST_F(AutofillDialogControllerTest, ChooseAnotherInstrumentOrAddress) {
2475  SubmitWithWalletItems(CompleteAndValidWalletItems());
2476
2477  EXPECT_EQ(0U, NotificationsOfType(
2478      DialogNotification::REQUIRED_ACTION).size());
2479  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
2480  controller()->OnDidGetFullWallet(
2481      wallet::GetTestFullWalletWithRequiredActions(
2482          std::vector<wallet::RequiredAction>(
2483              1, wallet::CHOOSE_ANOTHER_INSTRUMENT_OR_ADDRESS)));
2484  EXPECT_EQ(1U, NotificationsOfType(
2485      DialogNotification::REQUIRED_ACTION).size());
2486  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2487
2488  controller()->OnAccept();
2489  EXPECT_EQ(0U, NotificationsOfType(
2490      DialogNotification::REQUIRED_ACTION).size());
2491}
2492
2493TEST_F(AutofillDialogControllerTest, NewCardBubbleShown) {
2494  SwitchToAutofill();
2495  FillCreditCardInputs();
2496  controller()->OnAccept();
2497  controller()->ViewClosed();
2498
2499  EXPECT_EQ(1, mock_new_card_bubble_controller()->bubbles_shown());
2500  EXPECT_EQ(0, test_generated_bubble_controller()->bubbles_shown());
2501}
2502
2503TEST_F(AutofillDialogControllerTest, GeneratedCardBubbleShown) {
2504  SubmitWithWalletItems(CompleteAndValidWalletItems());
2505  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
2506  controller()->ForceFinishSubmit();
2507  controller()->ViewClosed();
2508
2509  EXPECT_EQ(0, mock_new_card_bubble_controller()->bubbles_shown());
2510  EXPECT_EQ(1, test_generated_bubble_controller()->bubbles_shown());
2511}
2512
2513// Verify that new Wallet data is fetched when the user switches away from the
2514// tab hosting the Autofill dialog and back. Also verify that the user's
2515// selection is preserved across this re-fetch.
2516TEST_F(AutofillDialogControllerTest, ReloadWalletItemsOnActivation) {
2517  // Initialize some Wallet data.
2518  scoped_ptr<wallet::WalletItems> wallet_items =
2519      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2520  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2521  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
2522  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
2523  wallet_items->AddAddress(wallet::GetTestShippingAddress());
2524  controller()->OnDidGetWalletItems(wallet_items.Pass());
2525
2526  // Initially, the default entries should be selected.
2527  ui::MenuModel* cc_billing_model =
2528      controller()->MenuModelForSection(SECTION_CC_BILLING);
2529  ui::MenuModel* shipping_model =
2530      controller()->MenuModelForSection(SECTION_SHIPPING);
2531  // "add", "manage", and 2 suggestions.
2532  ASSERT_EQ(4, cc_billing_model->GetItemCount());
2533  EXPECT_TRUE(cc_billing_model->IsItemCheckedAt(0));
2534  // "use billing", "add", "manage", and 2 suggestions.
2535  ASSERT_EQ(5, shipping_model->GetItemCount());
2536  EXPECT_TRUE(shipping_model->IsItemCheckedAt(2));
2537
2538  // Select entries other than the defaults.
2539  cc_billing_model->ActivatedAt(1);
2540  shipping_model->ActivatedAt(1);
2541  // 2 suggestions, "add", and "manage".
2542  ASSERT_EQ(4, cc_billing_model->GetItemCount());
2543  EXPECT_TRUE(cc_billing_model->IsItemCheckedAt(1));
2544  // "use billing", 2 suggestions, "add", "manage".
2545  ASSERT_EQ(5, shipping_model->GetItemCount());
2546  EXPECT_TRUE(shipping_model-> IsItemCheckedAt(1));
2547
2548  // Simulate switching away from the tab and back.  This should issue a request
2549  // for wallet items.
2550  controller()->ClearLastWalletItemsFetchTimestampForTesting();
2551  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
2552  controller()->TabActivated();
2553
2554  // Simulate a response that includes different items.
2555  wallet_items = wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2556  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentExpired());
2557  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2558  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
2559  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
2560  controller()->OnDidGetWalletItems(wallet_items.Pass());
2561
2562  // The previously selected entries should still be selected.
2563  // 3 suggestions, "add", and "manage".
2564  ASSERT_EQ(5, cc_billing_model->GetItemCount());
2565  EXPECT_TRUE(cc_billing_model->IsItemCheckedAt(2));
2566  // "use billing", 1 suggestion, "add", and "manage".
2567  ASSERT_EQ(4, shipping_model->GetItemCount());
2568  EXPECT_TRUE(shipping_model->IsItemCheckedAt(1));
2569}
2570
2571// Verify that if the default values change when re-fetching Wallet data, these
2572// new default values are selected in the dialog.
2573TEST_F(AutofillDialogControllerTest,
2574       ReloadWalletItemsOnActivationWithNewDefaults) {
2575  // Initialize some Wallet data.
2576  scoped_ptr<wallet::WalletItems> wallet_items =
2577      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2578  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
2579  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
2580  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
2581  wallet_items->AddAddress(wallet::GetTestShippingAddress());
2582  controller()->OnDidGetWalletItems(wallet_items.Pass());
2583
2584  // Initially, the default entries should be selected.
2585  ui::MenuModel* cc_billing_model =
2586      controller()->MenuModelForSection(SECTION_CC_BILLING);
2587  ui::MenuModel* shipping_model =
2588      controller()->MenuModelForSection(SECTION_SHIPPING);
2589  // 2 suggestions, "add", and "manage".
2590  ASSERT_EQ(4, cc_billing_model->GetItemCount());
2591  EXPECT_TRUE(cc_billing_model->IsItemCheckedAt(0));
2592  // "use billing", 2 suggestions, "add", and "manage".
2593  ASSERT_EQ(5, shipping_model->GetItemCount());
2594  EXPECT_TRUE(shipping_model->IsItemCheckedAt(2));
2595
2596  // Simulate switching away from the tab and back.  This should issue a request
2597  // for wallet items.
2598  controller()->ClearLastWalletItemsFetchTimestampForTesting();
2599  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
2600  controller()->TabActivated();
2601
2602  // Simulate a response that includes different default values.
2603  wallet_items =
2604      wallet::GetTestWalletItemsWithDefaultIds("new_default_instrument_id",
2605                                               "new_default_address_id",
2606                                               wallet::AMEX_DISALLOWED);
2607  scoped_ptr<wallet::Address> other_address = wallet::GetTestShippingAddress();
2608  other_address->set_object_id("other_address_id");
2609  scoped_ptr<wallet::Address> new_default_address =
2610      wallet::GetTestNonDefaultShippingAddress();
2611  new_default_address->set_object_id("new_default_address_id");
2612
2613  wallet_items->AddInstrument(
2614      wallet::GetTestMaskedInstrumentWithId("other_instrument_id"));
2615  wallet_items->AddInstrument(
2616      wallet::GetTestMaskedInstrumentWithId("new_default_instrument_id"));
2617  wallet_items->AddAddress(new_default_address.Pass());
2618  wallet_items->AddAddress(other_address.Pass());
2619  controller()->OnDidGetWalletItems(wallet_items.Pass());
2620
2621  // The new default entries should be selected.
2622  // 2 suggestions, "add", and "manage".
2623  ASSERT_EQ(4, cc_billing_model->GetItemCount());
2624  EXPECT_TRUE(cc_billing_model->IsItemCheckedAt(1));
2625  // "use billing", 2 suggestions, "add", and "manage".
2626  ASSERT_EQ(5, shipping_model->GetItemCount());
2627  EXPECT_TRUE(shipping_model->IsItemCheckedAt(1));
2628}
2629
2630TEST_F(AutofillDialogControllerTest, ReloadWithEmptyWalletItems) {
2631  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2632  controller()->MenuModelForSection(SECTION_CC_BILLING)->ActivatedAt(1);
2633  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
2634
2635  controller()->ClearLastWalletItemsFetchTimestampForTesting();
2636  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
2637  controller()->TabActivated();
2638
2639  controller()->OnDidGetWalletItems(
2640      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
2641
2642  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING));
2643  EXPECT_EQ(
2644      3, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
2645}
2646
2647TEST_F(AutofillDialogControllerTest, SaveInChromeByDefault) {
2648  EXPECT_TRUE(controller()->ShouldSaveInChrome());
2649  SwitchToAutofill();
2650  FillCreditCardInputs();
2651  controller()->OnAccept();
2652  EXPECT_TRUE(controller()->ShouldSaveInChrome());
2653}
2654
2655TEST_F(AutofillDialogControllerTest,
2656       SaveInChromePreferenceNotRememberedOnCancel) {
2657  EXPECT_TRUE(controller()->ShouldSaveInChrome());
2658  SwitchToAutofill();
2659  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(false);
2660  controller()->OnCancel();
2661  EXPECT_TRUE(controller()->ShouldSaveInChrome());
2662}
2663
2664TEST_F(AutofillDialogControllerTest,
2665       SaveInChromePreferenceRememberedOnSuccess) {
2666  EXPECT_TRUE(controller()->ShouldSaveInChrome());
2667  SwitchToAutofill();
2668  FillCreditCardInputs();
2669  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(false);
2670  controller()->OnAccept();
2671  EXPECT_FALSE(controller()->ShouldSaveInChrome());
2672}
2673
2674TEST_F(AutofillDialogControllerTest,
2675       SubmitButtonIsDisabled_SpinnerFinishesBeforeDelay) {
2676  // Reset Wallet state.
2677  controller()->OnDidGetWalletItems(scoped_ptr<wallet::WalletItems>());
2678
2679  EXPECT_EQ(1, controller()->get_submit_button_delay_count());
2680
2681  // Begin the submit button delay.
2682  controller()->SimulateSubmitButtonDelayBegin();
2683
2684  EXPECT_TRUE(controller()->ShouldShowSpinner());
2685  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2686
2687  // Stop the spinner.
2688  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2689
2690  EXPECT_FALSE(controller()->ShouldShowSpinner());
2691  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2692
2693  // End the submit button delay.
2694  controller()->SimulateSubmitButtonDelayEnd();
2695
2696  EXPECT_FALSE(controller()->ShouldShowSpinner());
2697  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2698}
2699
2700TEST_F(AutofillDialogControllerTest,
2701       SubmitButtonIsDisabled_SpinnerFinishesAfterDelay) {
2702  // Reset Wallet state.
2703  controller()->OnDidGetWalletItems(scoped_ptr<wallet::WalletItems>());
2704
2705  EXPECT_EQ(1, controller()->get_submit_button_delay_count());
2706
2707  // Begin the submit button delay.
2708  controller()->SimulateSubmitButtonDelayBegin();
2709
2710  EXPECT_TRUE(controller()->ShouldShowSpinner());
2711  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2712
2713  // End the submit button delay.
2714  controller()->SimulateSubmitButtonDelayEnd();
2715
2716  EXPECT_TRUE(controller()->ShouldShowSpinner());
2717  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2718
2719  // Stop the spinner.
2720  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2721
2722  EXPECT_FALSE(controller()->ShouldShowSpinner());
2723  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2724}
2725
2726TEST_F(AutofillDialogControllerTest, SubmitButtonIsDisabled_NoSpinner) {
2727  SwitchToAutofill();
2728
2729  EXPECT_EQ(1, controller()->get_submit_button_delay_count());
2730
2731  // Begin the submit button delay.
2732  controller()->SimulateSubmitButtonDelayBegin();
2733
2734  EXPECT_FALSE(controller()->ShouldShowSpinner());
2735  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2736
2737  // End the submit button delay.
2738  controller()->SimulateSubmitButtonDelayEnd();
2739
2740  EXPECT_FALSE(controller()->ShouldShowSpinner());
2741  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
2742}
2743
2744TEST_F(AutofillDialogControllerTest, IconsForFields_NoCreditCard) {
2745  FieldValueMap values;
2746  values[EMAIL_ADDRESS] = ASCIIToUTF16(kFakeEmail);
2747  FieldIconMap icons = controller()->IconsForFields(values);
2748  EXPECT_TRUE(icons.empty());
2749}
2750
2751TEST_F(AutofillDialogControllerTest, IconsForFields_CreditCardNumberOnly) {
2752  FieldValueMap values;
2753  values[EMAIL_ADDRESS] = ASCIIToUTF16(kFakeEmail);
2754  values[CREDIT_CARD_NUMBER] = ASCIIToUTF16(kTestCCNumberVisa);
2755  FieldIconMap icons = controller()->IconsForFields(values);
2756  EXPECT_EQ(1UL, icons.size());
2757  EXPECT_EQ(1UL, icons.count(CREDIT_CARD_NUMBER));
2758}
2759
2760TEST_F(AutofillDialogControllerTest, IconsForFields_CvcOnly) {
2761  FieldValueMap values;
2762  values[EMAIL_ADDRESS] = ASCIIToUTF16(kFakeEmail);
2763  values[CREDIT_CARD_VERIFICATION_CODE] = ASCIIToUTF16("123");
2764  FieldIconMap icons = controller()->IconsForFields(values);
2765  EXPECT_EQ(1UL, icons.size());
2766  EXPECT_EQ(1UL, icons.count(CREDIT_CARD_VERIFICATION_CODE));
2767}
2768
2769TEST_F(AutofillDialogControllerTest, IconsForFields_BothCreditCardAndCvc) {
2770  FieldValueMap values;
2771  values[EMAIL_ADDRESS] = ASCIIToUTF16(kFakeEmail);
2772  values[CREDIT_CARD_NUMBER] = ASCIIToUTF16(kTestCCNumberVisa);
2773  values[CREDIT_CARD_VERIFICATION_CODE] = ASCIIToUTF16("123");
2774  FieldIconMap icons = controller()->IconsForFields(values);
2775  EXPECT_EQ(2UL, icons.size());
2776  EXPECT_EQ(1UL, icons.count(CREDIT_CARD_VERIFICATION_CODE));
2777  EXPECT_EQ(1UL, icons.count(CREDIT_CARD_NUMBER));
2778}
2779
2780TEST_F(AutofillDialogControllerTest, FieldControlsIcons) {
2781  EXPECT_TRUE(controller()->FieldControlsIcons(CREDIT_CARD_NUMBER));
2782  EXPECT_FALSE(controller()->FieldControlsIcons(CREDIT_CARD_VERIFICATION_CODE));
2783  EXPECT_FALSE(controller()->FieldControlsIcons(EMAIL_ADDRESS));
2784}
2785
2786TEST_F(AutofillDialogControllerTest, SaveCreditCardIncludesName_NoBilling) {
2787  SwitchToAutofill();
2788
2789  CreditCard test_credit_card(test::GetVerifiedCreditCard());
2790  FillInputs(SECTION_CC, test_credit_card);
2791
2792  AutofillProfile test_profile(test::GetVerifiedProfile());
2793  FillInputs(SECTION_BILLING, test_profile);
2794
2795  UseBillingForShipping();
2796
2797  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(true);
2798  controller()->OnAccept();
2799
2800  TestPersonalDataManager* test_pdm = controller()->GetTestingManager();
2801  const CreditCard& imported_card = test_pdm->imported_credit_card();
2802  EXPECT_EQ(test_profile.GetRawInfo(NAME_FULL),
2803            imported_card.GetRawInfo(CREDIT_CARD_NAME));
2804}
2805
2806TEST_F(AutofillDialogControllerTest, SaveCreditCardIncludesName_WithBilling) {
2807  SwitchToAutofill();
2808
2809  TestPersonalDataManager* test_pdm = controller()->GetTestingManager();
2810  AutofillProfile test_profile(test::GetVerifiedProfile());
2811
2812  EXPECT_CALL(*controller()->GetView(), ModelChanged());
2813  test_pdm->AddTestingProfile(&test_profile);
2814  ASSERT_TRUE(controller()->MenuModelForSection(SECTION_BILLING));
2815
2816  CreditCard test_credit_card(test::GetVerifiedCreditCard());
2817  FillInputs(SECTION_CC, test_credit_card);
2818
2819  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(true);
2820  controller()->OnAccept();
2821
2822  const CreditCard& imported_card = test_pdm->imported_credit_card();
2823  EXPECT_EQ(test_profile.GetRawInfo(NAME_FULL),
2824            imported_card.GetRawInfo(CREDIT_CARD_NAME));
2825
2826  controller()->ViewClosed();
2827}
2828
2829TEST_F(AutofillDialogControllerTest, InputEditability) {
2830  // Empty wallet items: all fields are editable.
2831  scoped_ptr<wallet::WalletItems> items =
2832      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2833  controller()->OnDidGetWalletItems(items.Pass());
2834
2835  DialogSection sections[] = { SECTION_CC_BILLING, SECTION_SHIPPING };
2836  for (size_t i = 0; i < arraysize(sections); ++i) {
2837    const DetailInputs& inputs =
2838        controller()->RequestedFieldsForSection(sections[i]);
2839    for (size_t j = 0; j < inputs.size(); ++j) {
2840      EXPECT_TRUE(controller()->InputIsEditable(inputs[j], sections[i]));
2841    }
2842  }
2843
2844  // Expired instrument: CC number + CVV are not editable.
2845  items = wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
2846  scoped_ptr<wallet::WalletItems::MaskedInstrument> expired_instrument =
2847      wallet::GetTestMaskedInstrumentExpired();
2848  items->AddInstrument(expired_instrument.Pass());
2849  controller()->OnDidGetWalletItems(items.Pass());
2850  EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC_BILLING));
2851
2852  const DetailInputs& inputs =
2853      controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
2854  FieldValueMap outputs;
2855  CopyInitialValues(inputs, &outputs);
2856  controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
2857
2858  for (size_t i = 0; i < arraysize(sections); ++i) {
2859    const DetailInputs& inputs =
2860        controller()->RequestedFieldsForSection(sections[i]);
2861    for (size_t j = 0; j < inputs.size(); ++j) {
2862      if (inputs[j].type == CREDIT_CARD_NUMBER ||
2863          inputs[j].type == CREDIT_CARD_VERIFICATION_CODE) {
2864        EXPECT_FALSE(controller()->InputIsEditable(inputs[j], sections[i]));
2865      } else {
2866        EXPECT_TRUE(controller()->InputIsEditable(inputs[j], sections[i]));
2867      }
2868    }
2869  }
2870
2871  // User changes the billing address; same story.
2872  outputs[ADDRESS_BILLING_ZIP] = ASCIIToUTF16("77025");
2873  controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
2874  for (size_t i = 0; i < arraysize(sections); ++i) {
2875    const DetailInputs& inputs =
2876        controller()->RequestedFieldsForSection(sections[i]);
2877    for (size_t j = 0; j < inputs.size(); ++j) {
2878      if (inputs[j].type == CREDIT_CARD_NUMBER ||
2879          inputs[j].type == CREDIT_CARD_VERIFICATION_CODE) {
2880        EXPECT_FALSE(controller()->InputIsEditable(inputs[j], sections[i]));
2881      } else {
2882        EXPECT_TRUE(controller()->InputIsEditable(inputs[j], sections[i]));
2883      }
2884    }
2885  }
2886
2887  // User changes a detail of the CC itself (expiration date), CVV is now
2888  // editable (and mandatory).
2889  outputs[CREDIT_CARD_EXP_MONTH] = ASCIIToUTF16("06");
2890  controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
2891  for (size_t i = 0; i < arraysize(sections); ++i) {
2892    const DetailInputs& inputs =
2893        controller()->RequestedFieldsForSection(sections[i]);
2894    for (size_t j = 0; j < inputs.size(); ++j) {
2895      if (inputs[j].type == CREDIT_CARD_NUMBER)
2896        EXPECT_FALSE(controller()->InputIsEditable(inputs[j], sections[i]));
2897      else
2898        EXPECT_TRUE(controller()->InputIsEditable(inputs[j], sections[i]));
2899    }
2900  }
2901}
2902
2903// When the default country is something besides US, wallet is not selected
2904// and the account chooser shouldn't be visible.
2905TEST_F(AutofillDialogControllerTest, HideWalletInOtherCountries) {
2906  // Addresses from different countries.
2907  AutofillProfile us_profile(base::GenerateGUID(), kSettingsOrigin),
2908      es_profile(base::GenerateGUID(), kSettingsOrigin),
2909      es_profile2(base::GenerateGUID(), kSettingsOrigin);
2910  us_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
2911  es_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("ES"));
2912  es_profile2.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("ES"));
2913
2914  // If US is indicated (via timezone), show Wallet.
2915  ResetControllerWithFormData(DefaultFormData());
2916  controller()->GetTestingManager()->set_timezone_country_code("US");
2917  controller()->Show();
2918  EXPECT_TRUE(
2919      controller()->AccountChooserModelForTesting()->WalletIsSelected());
2920  controller()->OnDidFetchWalletCookieValue(std::string());
2921  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2922  EXPECT_TRUE(controller()->ShouldShowAccountChooser());
2923  EXPECT_TRUE(
2924      controller()->AccountChooserModelForTesting()->WalletIsSelected());
2925
2926  // If US is not indicated, don't show Wallet.
2927  ResetControllerWithFormData(DefaultFormData());
2928  controller()->GetTestingManager()->set_timezone_country_code("ES");
2929  controller()->Show();
2930  controller()->OnDidFetchWalletCookieValue(std::string());
2931  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2932  EXPECT_FALSE(controller()->ShouldShowAccountChooser());
2933
2934  // If US is indicated (via a profile), show Wallet.
2935  ResetControllerWithFormData(DefaultFormData());
2936  controller()->GetTestingManager()->set_timezone_country_code("ES");
2937  controller()->GetTestingManager()->AddTestingProfile(&us_profile);
2938  controller()->Show();
2939  controller()->OnDidFetchWalletCookieValue(std::string());
2940  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2941  EXPECT_TRUE(controller()->ShouldShowAccountChooser());
2942  EXPECT_TRUE(
2943      controller()->AccountChooserModelForTesting()->WalletIsSelected());
2944
2945  // Make sure the profile doesn't just override the timezone.
2946  ResetControllerWithFormData(DefaultFormData());
2947  controller()->GetTestingManager()->set_timezone_country_code("US");
2948  controller()->GetTestingManager()->AddTestingProfile(&es_profile);
2949  controller()->Show();
2950  controller()->OnDidFetchWalletCookieValue(std::string());
2951  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2952  EXPECT_TRUE(controller()->ShouldShowAccountChooser());
2953  EXPECT_TRUE(
2954      controller()->AccountChooserModelForTesting()->WalletIsSelected());
2955
2956  // Only takes one US address to enable Wallet.
2957  ResetControllerWithFormData(DefaultFormData());
2958  controller()->GetTestingManager()->set_timezone_country_code("FR");
2959  controller()->GetTestingManager()->AddTestingProfile(&es_profile);
2960  controller()->GetTestingManager()->AddTestingProfile(&es_profile2);
2961  controller()->GetTestingManager()->AddTestingProfile(&us_profile);
2962  controller()->Show();
2963  controller()->OnDidFetchWalletCookieValue(std::string());
2964  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2965  EXPECT_TRUE(controller()->ShouldShowAccountChooser());
2966  EXPECT_TRUE(
2967      controller()->AccountChooserModelForTesting()->WalletIsSelected());
2968}
2969
2970TEST_F(AutofillDialogControllerTest, DontGetWalletTillNecessary) {
2971  // When starting on local data mode, the dialog will provide a "Use Google
2972  // Wallet" link.
2973  profile()->GetPrefs()->SetBoolean(
2974      ::prefs::kAutofillDialogPayWithoutWallet, true);
2975  ResetControllerWithFormData(DefaultFormData());
2976  controller()->Show();
2977  base::string16 use_wallet_text = controller()->SignInLinkText();
2978  EXPECT_EQ(TestAutofillDialogController::NOT_CHECKED,
2979            controller()->SignedInState());
2980
2981  // When clicked, this link will ask for wallet items. If there's a signin
2982  // failure, the link will switch to "Sign in to use Google Wallet".
2983  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
2984  controller()->SignInLinkClicked();
2985  EXPECT_NE(TestAutofillDialogController::NOT_CHECKED,
2986            controller()->SignedInState());
2987  controller()->OnDidFetchWalletCookieValue(std::string());
2988  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
2989  controller()->OnPassiveSigninFailure(GoogleServiceAuthError(
2990      GoogleServiceAuthError::CONNECTION_FAILED));
2991  EXPECT_NE(use_wallet_text, controller()->SignInLinkText());
2992}
2993
2994TEST_F(AutofillDialogControllerTest, MultiAccountSwitch) {
2995  std::vector<std::string> users;
2996  users.push_back("user_1@example.com");
2997  users.push_back("user_2@example.com");
2998  controller()->OnDidGetWalletItems(
2999      wallet::GetTestWalletItemsWithUsers(users, 0));
3000
3001  // Items should be: Account 1, account 2, add account, disable wallet.
3002  EXPECT_EQ(4, controller()->MenuModelForAccountChooser()->GetItemCount());
3003  EXPECT_EQ(0U, controller()->GetTestingWalletClient()->user_index());
3004
3005  // GetWalletItems should be called when the user switches accounts.
3006  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
3007  controller()->MenuModelForAccountChooser()->ActivatedAt(1);
3008  // The wallet client should be updated to the new user index.
3009  EXPECT_EQ(1U, controller()->GetTestingWalletClient()->user_index());
3010}
3011
3012TEST_F(AutofillDialogControllerTest, PassiveAuthFailure) {
3013  controller()->OnDidGetWalletItems(
3014      wallet::GetTestWalletItemsWithRequiredAction(
3015           wallet::PASSIVE_GAIA_AUTH));
3016  EXPECT_TRUE(controller()->ShouldShowSpinner());
3017  controller()->OnPassiveSigninFailure(GoogleServiceAuthError(
3018      GoogleServiceAuthError::NONE));
3019  EXPECT_FALSE(controller()->ShouldShowSpinner());
3020}
3021
3022TEST_F(AutofillDialogControllerTest, WalletShippingSameAsBilling) {
3023  // Assert initial state.
3024  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
3025      ::prefs::kAutofillDialogWalletShippingSameAsBilling));
3026
3027  // Verify that false pref defaults to wallet defaults.
3028  scoped_ptr<wallet::WalletItems> wallet_items =
3029      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
3030  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
3031  wallet_items->AddAddress(wallet::GetTestShippingAddress());
3032  controller()->OnDidGetWalletItems(wallet_items.Pass());
3033  ASSERT_FALSE(profile()->GetPrefs()->GetBoolean(
3034      ::prefs::kAutofillDialogWalletShippingSameAsBilling));
3035  EXPECT_EQ(2, GetMenuModelForSection(SECTION_SHIPPING)->checked_item());
3036
3037  // Set "Same as Billing" for the shipping address and verify it sets the pref
3038  // and selects the appropriate menu item.
3039  UseBillingForShipping();
3040  ASSERT_EQ(0, GetMenuModelForSection(SECTION_SHIPPING)->checked_item());
3041  controller()->ForceFinishSubmit();
3042  ASSERT_TRUE(profile()->GetPrefs()->GetBoolean(
3043      ::prefs::kAutofillDialogWalletShippingSameAsBilling));
3044
3045  // Getting new wallet info shouldn't disrupt the preference and menu should be
3046  // set accordingly.
3047  Reset();
3048  wallet_items = wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
3049  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
3050  wallet_items->AddAddress(wallet::GetTestShippingAddress());
3051  controller()->OnDidGetWalletItems(wallet_items.Pass());
3052  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
3053      ::prefs::kAutofillDialogWalletShippingSameAsBilling));
3054  EXPECT_EQ(0, GetMenuModelForSection(SECTION_SHIPPING)->checked_item());
3055
3056  // Choose a different address and ensure pref gets set to false.
3057  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
3058  controller()->ForceFinishSubmit();
3059  EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
3060      ::prefs::kAutofillDialogWalletShippingSameAsBilling));
3061}
3062
3063// Verifies that a call to the IconsForFields() method before the card type is
3064// known returns a placeholder image that is at least as large as the icons for
3065// all of the supported major credit card issuers.
3066TEST_F(AutofillDialogControllerTest, IconReservedForCreditCardField) {
3067  FieldValueMap inputs;
3068  inputs[CREDIT_CARD_NUMBER] = base::string16();
3069
3070  FieldIconMap icons = controller()->IconsForFields(inputs);
3071  EXPECT_EQ(1U, icons.size());
3072
3073  ASSERT_EQ(1U, icons.count(CREDIT_CARD_NUMBER));
3074  gfx::Image placeholder_icon = icons[CREDIT_CARD_NUMBER];
3075
3076  // Verify that the placeholder icon is at least as large as the icons for the
3077  // supported credit card issuers.
3078  const int kSupportedCardIdrs[] = {
3079    IDR_AUTOFILL_CC_AMEX,
3080    IDR_AUTOFILL_CC_DINERS,
3081    IDR_AUTOFILL_CC_DISCOVER,
3082    IDR_AUTOFILL_CC_GENERIC,
3083    IDR_AUTOFILL_CC_JCB,
3084    IDR_AUTOFILL_CC_MASTERCARD,
3085    IDR_AUTOFILL_CC_VISA,
3086  };
3087  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
3088  for (size_t i = 0; i < arraysize(kSupportedCardIdrs); ++i) {
3089    SCOPED_TRACE(base::IntToString(i));
3090    gfx::Image supported_card_icon = rb.GetImageNamed(kSupportedCardIdrs[i]);
3091    EXPECT_GE(placeholder_icon.Width(), supported_card_icon.Width());
3092    EXPECT_GE(placeholder_icon.Height(), supported_card_icon.Height());
3093  }
3094}
3095
3096TEST_F(AutofillDialogControllerTest, NoPartiallySupportedCountriesSuggested) {
3097  SwitchToAutofill();
3098
3099  std::string partially_supported_country = "KR";
3100  ASSERT_FALSE(i18ninput::CountryIsFullySupported(partially_supported_country));
3101  ASSERT_FALSE(controller()->MenuModelForSection(SECTION_BILLING));
3102
3103  AutofillProfile verified_profile(test::GetVerifiedProfile());
3104  verified_profile.SetRawInfo(ADDRESS_HOME_COUNTRY,
3105                              ASCIIToUTF16(partially_supported_country));
3106  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
3107
3108  EXPECT_FALSE(
3109      controller()->SuggestionStateForSection(SECTION_BILLING).visible);
3110}
3111
3112TEST_F(AutofillDialogControllerTest, CountryChangeUpdatesSection) {
3113  TestAutofillDialogView* view = controller()->GetView();
3114  view->ClearSectionUpdates();
3115
3116  controller()->UserEditedOrActivatedInput(SECTION_SHIPPING,
3117                                           ADDRESS_HOME_COUNTRY,
3118                                           gfx::NativeView(),
3119                                           gfx::Rect(),
3120                                           ASCIIToUTF16("Belarus"),
3121                                           true);
3122  std::map<DialogSection, size_t> updates = view->section_updates();
3123  EXPECT_EQ(1U, updates[SECTION_SHIPPING]);
3124  EXPECT_EQ(1U, updates.size());
3125
3126  view->ClearSectionUpdates();
3127
3128  controller()->UserEditedOrActivatedInput(SECTION_CC_BILLING,
3129                                           ADDRESS_BILLING_COUNTRY,
3130                                           gfx::NativeView(),
3131                                           gfx::Rect(),
3132                                           ASCIIToUTF16("France"),
3133                                           true);
3134  updates = view->section_updates();
3135  EXPECT_EQ(1U, updates[SECTION_CC_BILLING]);
3136  EXPECT_EQ(1U, updates.size());
3137
3138  SwitchToAutofill();
3139  view->ClearSectionUpdates();
3140
3141  controller()->UserEditedOrActivatedInput(SECTION_BILLING,
3142                                           ADDRESS_BILLING_COUNTRY,
3143                                           gfx::NativeView(),
3144                                           gfx::Rect(),
3145                                           ASCIIToUTF16("Italy"),
3146                                           true);
3147  updates = view->section_updates();
3148  EXPECT_EQ(1U, updates[SECTION_BILLING]);
3149  EXPECT_EQ(1U, updates.size());
3150}
3151
3152TEST_F(AutofillDialogControllerTest, CorrectCountryFromInputs) {
3153  EXPECT_CALL(*controller()->GetMockValidator(),
3154              ValidateAddress(CountryCodeMatcher("DE"), _, _));
3155
3156  FieldValueMap billing_inputs;
3157  billing_inputs[ADDRESS_BILLING_COUNTRY] = ASCIIToUTF16("Germany");
3158  controller()->InputsAreValid(SECTION_BILLING, billing_inputs);
3159
3160  EXPECT_CALL(*controller()->GetMockValidator(),
3161              ValidateAddress(CountryCodeMatcher("FR"), _, _));
3162
3163  FieldValueMap shipping_inputs;
3164  shipping_inputs[ADDRESS_HOME_COUNTRY] = ASCIIToUTF16("France");
3165  controller()->InputsAreValid(SECTION_SHIPPING, shipping_inputs);
3166}
3167
3168TEST_F(AutofillDialogControllerTest, ValidationRulesLoadedOnCountryChange) {
3169  ResetControllerWithFormData(DefaultFormData());
3170  EXPECT_CALL(*controller()->GetMockValidator(), LoadRules("US"));
3171  controller()->Show();
3172
3173  EXPECT_CALL(*controller()->GetMockValidator(), LoadRules("FR"));
3174  controller()->UserEditedOrActivatedInput(SECTION_CC_BILLING,
3175                                           ADDRESS_BILLING_COUNTRY,
3176                                           gfx::NativeView(),
3177                                           gfx::Rect(),
3178                                           ASCIIToUTF16("France"),
3179                                           true);
3180}
3181
3182TEST_F(AutofillDialogControllerTest, InvalidWhenRulesNotReady) {
3183  // Select "Add new shipping address...".
3184  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
3185
3186  // If the rules haven't loaded yet, validation errors should show on submit.
3187  EXPECT_CALL(*controller()->GetMockValidator(),
3188              ValidateAddress(CountryCodeMatcher("US"), _, _)).
3189              WillRepeatedly(Return(AddressValidator::RULES_NOT_READY));
3190
3191  FieldValueMap inputs;
3192  inputs[ADDRESS_HOME_ZIP] = ASCIIToUTF16("1234");
3193  inputs[ADDRESS_HOME_COUNTRY] = ASCIIToUTF16("United States");
3194
3195  ValidityMessages messages =
3196      controller()->InputsAreValid(SECTION_SHIPPING, inputs);
3197  EXPECT_FALSE(messages.GetMessageOrDefault(ADDRESS_HOME_ZIP).text.empty());
3198  EXPECT_FALSE(messages.HasSureError(ADDRESS_HOME_ZIP));
3199  // Country should never show an error message as it's always valid.
3200  EXPECT_TRUE(messages.GetMessageOrDefault(ADDRESS_HOME_COUNTRY).text.empty());
3201}
3202
3203TEST_F(AutofillDialogControllerTest, ValidButUnverifiedWhenRulesFail) {
3204  SwitchToAutofill();
3205
3206  // Add suggestions so the credit card and billing sections aren't showing
3207  // their manual inputs (to isolate to just shipping).
3208  AutofillProfile verified_profile(test::GetVerifiedProfile());
3209  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
3210  CreditCard verified_card(test::GetVerifiedCreditCard());
3211  controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
3212
3213  // Select "Add new shipping address...".
3214  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
3215
3216  // If the rules are unavailable, validation errors should not show.
3217  EXPECT_CALL(*controller()->GetMockValidator(),
3218              ValidateAddress(CountryCodeMatcher("US"), _, _)).
3219              WillRepeatedly(Return(AddressValidator::RULES_UNAVAILABLE));
3220
3221  FieldValueMap outputs;
3222  AutofillProfile full_profile(test::GetFullProfile());
3223  const DetailInputs& inputs =
3224      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
3225  for (size_t i = 0; i < inputs.size(); ++i) {
3226    const ServerFieldType type = inputs[i].type;
3227    outputs[type] = full_profile.GetInfo(AutofillType(type), "en-US");
3228  }
3229  controller()->GetView()->SetUserInput(SECTION_SHIPPING, outputs);
3230  controller()->GetView()->CheckSaveDetailsLocallyCheckbox(true);
3231  controller()->OnAccept();
3232
3233  // Profiles saved while rules are unavailable shouldn't be verified.
3234  const AutofillProfile& imported_profile =
3235      controller()->GetTestingManager()->imported_profile();
3236  ASSERT_EQ(imported_profile.GetRawInfo(NAME_FULL),
3237            full_profile.GetRawInfo(NAME_FULL));
3238  EXPECT_EQ(imported_profile.origin(), GURL(kSourceUrl).GetOrigin().spec());
3239  EXPECT_FALSE(imported_profile.IsVerified());
3240}
3241
3242TEST_F(AutofillDialogControllerTest, LimitedCountryChoices) {
3243  ui::ComboboxModel* shipping_country_model =
3244      controller()->ComboboxModelForAutofillType(ADDRESS_HOME_COUNTRY);
3245  const int default_number_of_countries =
3246      shipping_country_model->GetItemCount();
3247  // We show a lot of countries by default, but the exact number doesn't matter.
3248  EXPECT_GT(default_number_of_countries, 50);
3249
3250  // Create a form data that simulates:
3251  //   <select autocomplete="billing country">
3252  //     <option value="AU">Down Under</option>
3253  //     <option value="">fR</option>  <!-- Case doesn't matter -->
3254  //     <option value="GRMNY">Germany</option>
3255  //   </select>
3256  // Only country codes are respected, whether they're in value or the option's
3257  // text content. Thus the first two options should be recognized.
3258  FormData form_data;
3259  FormFieldData field;
3260  field.autocomplete_attribute = "billing country";
3261  field.option_contents.push_back(ASCIIToUTF16("Down Under"));
3262  field.option_values.push_back(ASCIIToUTF16("AU"));
3263  field.option_contents.push_back(ASCIIToUTF16("Fr"));
3264  field.option_values.push_back(ASCIIToUTF16(""));
3265  field.option_contents.push_back(ASCIIToUTF16("Germany"));
3266  field.option_values.push_back(ASCIIToUTF16("GRMNY"));
3267  form_data.fields.push_back(field);
3268  ResetControllerWithFormData(form_data);
3269  controller()->Show();
3270
3271  // Shipping model shouldn't have changed.
3272  shipping_country_model =
3273      controller()->ComboboxModelForAutofillType(ADDRESS_HOME_COUNTRY);
3274  EXPECT_EQ(default_number_of_countries,
3275            shipping_country_model->GetItemCount());
3276  // Billing model now only has two items.
3277  ui::ComboboxModel* billing_country_model =
3278      controller()->ComboboxModelForAutofillType(ADDRESS_BILLING_COUNTRY);
3279  ASSERT_EQ(2, billing_country_model->GetItemCount());
3280  EXPECT_EQ(billing_country_model->GetItemAt(0), ASCIIToUTF16("Australia"));
3281  EXPECT_EQ(billing_country_model->GetItemAt(1), ASCIIToUTF16("France"));
3282
3283  // Make sure it also applies to profile suggestions.
3284  AutofillProfile us_profile(test::GetVerifiedProfile());
3285  us_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
3286  controller()->GetTestingManager()->AddTestingProfile(&us_profile);
3287  // Don't show a suggestion if the only one that exists is disabled.
3288  EXPECT_FALSE(
3289      controller()->SuggestionStateForSection(SECTION_BILLING).visible);
3290
3291  // Add a profile with an acceptable country; suggestion should be shown.
3292  ResetControllerWithFormData(form_data);
3293  controller()->Show();
3294  AutofillProfile au_profile(test::GetVerifiedProfile2());
3295  au_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("AU"));
3296  controller()->GetTestingManager()->AddTestingProfile(&us_profile);
3297  controller()->GetTestingManager()->AddTestingProfile(&au_profile);
3298  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_BILLING);
3299  ASSERT_TRUE(model);
3300  EXPECT_EQ(4, model->GetItemCount());
3301  EXPECT_FALSE(model->IsEnabledAt(0));
3302  EXPECT_TRUE(model->IsEnabledAt(1));
3303
3304  // Add <input type="text" autocomplete="billing country"></input>
3305  // This should open up selection of all countries again.
3306  FormFieldData field2;
3307  field2.autocomplete_attribute = "billing country";
3308  form_data.fields.push_back(field2);
3309  ResetControllerWithFormData(form_data);
3310  controller()->Show();
3311
3312  billing_country_model =
3313      controller()->ComboboxModelForAutofillType(ADDRESS_BILLING_COUNTRY);
3314  EXPECT_EQ(default_number_of_countries,
3315            billing_country_model->GetItemCount());
3316}
3317
3318TEST_F(AutofillDialogControllerTest, CountriesWithDependentLocalityHidden) {
3319  ui::ComboboxModel* model =
3320      controller()->ComboboxModelForAutofillType(ADDRESS_BILLING_COUNTRY);
3321  for (int i = 0; i < model->GetItemCount(); ++i) {
3322    EXPECT_NE(base::ASCIIToUTF16("China"), model->GetItemAt(i));
3323    EXPECT_NE(base::ASCIIToUTF16("South Korea"), model->GetItemAt(i));
3324  }
3325
3326  model = controller()->ComboboxModelForAutofillType(ADDRESS_HOME_COUNTRY);
3327  for (int i = 0; i < model->GetItemCount(); ++i) {
3328    EXPECT_NE(base::ASCIIToUTF16("China"), model->GetItemAt(i));
3329    EXPECT_NE(base::ASCIIToUTF16("South Korea"), model->GetItemAt(i));
3330  }
3331}
3332
3333TEST_F(AutofillDialogControllerTest, DontSuggestHiddenCountries) {
3334  SwitchToAutofill();
3335
3336  AutofillProfile cn_profile(test::GetVerifiedProfile());
3337  cn_profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("Chinese User"));
3338  cn_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("CN"));
3339  controller()->GetTestingManager()->AddTestingProfile(&cn_profile);
3340
3341  AutofillProfile us_profile(test::GetVerifiedProfile());
3342  us_profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("American User"));
3343  controller()->GetTestingManager()->AddTestingProfile(&us_profile);
3344
3345  controller()->UserEditedOrActivatedInput(
3346      SECTION_SHIPPING,
3347      NAME_FULL,
3348      gfx::NativeView(),
3349      gfx::Rect(),
3350      cn_profile.GetRawInfo(NAME_FULL).substr(0, 1),
3351      true);
3352  EXPECT_EQ(UNKNOWN_TYPE, controller()->popup_input_type());
3353
3354  controller()->UserEditedOrActivatedInput(
3355      SECTION_SHIPPING,
3356      NAME_FULL,
3357      gfx::NativeView(),
3358      gfx::Rect(),
3359      us_profile.GetRawInfo(NAME_FULL).substr(0, 1),
3360      true);
3361  EXPECT_EQ(NAME_FULL, controller()->popup_input_type());
3362}
3363
3364}  // namespace autofill
3365