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