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