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