autofill_dialog_controller_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 "base/guid.h"
6#include "base/memory/scoped_ptr.h"
7#include "base/message_loop.h"
8#include "base/prefs/pref_service.h"
9#include "base/utf_string_conversions.h"
10#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
11#include "chrome/browser/ui/autofill/autofill_dialog_view.h"
12#include "chrome/common/pref_names.h"
13#include "chrome/test/base/testing_profile.h"
14#include "components/autofill/browser/autofill_common_test.h"
15#include "components/autofill/browser/autofill_metrics.h"
16#include "components/autofill/browser/risk/proto/fingerprint.pb.h"
17#include "components/autofill/browser/test_personal_data_manager.h"
18#include "components/autofill/browser/wallet/full_wallet.h"
19#include "components/autofill/browser/wallet/instrument.h"
20#include "components/autofill/browser/wallet/wallet_address.h"
21#include "components/autofill/browser/wallet/wallet_client.h"
22#include "components/autofill/browser/wallet/wallet_test_util.h"
23#include "components/autofill/common/form_data.h"
24#include "content/public/browser/web_contents.h"
25#include "content/public/test/test_browser_thread.h"
26#include "content/public/test/web_contents_tester.h"
27#include "testing/gmock/include/gmock/gmock.h"
28#include "testing/gtest/include/gtest/gtest.h"
29
30#if defined(OS_WIN)
31#include "ui/base/win/scoped_ole_initializer.h"
32#endif
33
34using testing::_;
35
36namespace autofill {
37
38namespace {
39
40const char kFakeEmail[] = "user@example.com";
41const char kFakeFingerprintEncoded[] = "CgVaAwiACA==";
42const char kEditedBillingAddress[] = "123 edited billing address";
43const char* kFieldsFromPage[] =
44    { "email", "cc-number", "billing region", "shipping region" };
45const char kSettingsOrigin[] = "Chrome settings";
46
47using content::BrowserThread;
48
49void SetOutputValue(const DetailInputs& inputs,
50                    DetailOutputMap* outputs,
51                    AutofillFieldType type,
52                    const std::string& value) {
53  for (size_t i = 0; i < inputs.size(); ++i) {
54    const DetailInput& input = inputs[i];
55    (*outputs)[&input] = input.type == type ?
56        ASCIIToUTF16(value) :
57        input.initial_value;
58  }
59}
60
61scoped_ptr<wallet::FullWallet> CreateFullWalletWithVerifyCvv() {
62  base::DictionaryValue dict;
63  scoped_ptr<base::ListValue> list(new base::ListValue());
64  list->AppendString("verify_cvv");
65  dict.Set("required_action", list.release());
66  return wallet::FullWallet::CreateFullWallet(dict);
67}
68
69scoped_ptr<risk::Fingerprint> GetFakeFingerprint() {
70  scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
71  // Add some data to the proto, else the encoded content is empty.
72  fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
73      set_width(1024);
74  return fingerprint.Pass();
75}
76
77class TestAutofillDialogView : public AutofillDialogView {
78 public:
79  TestAutofillDialogView() {}
80  virtual ~TestAutofillDialogView() {}
81
82  virtual void Show() OVERRIDE {}
83  virtual void Hide() OVERRIDE {}
84  virtual void UpdateNotificationArea() OVERRIDE {}
85  virtual void UpdateAccountChooser() OVERRIDE {}
86  virtual void UpdateButtonStrip() OVERRIDE {}
87  virtual void UpdateDetailArea() OVERRIDE {}
88  virtual void UpdateSection(DialogSection section) OVERRIDE {}
89  virtual void FillSection(DialogSection section,
90                           const DetailInput& originating_input) OVERRIDE {};
91  virtual void GetUserInput(DialogSection section, DetailOutputMap* output)
92      OVERRIDE {
93    *output = outputs_[section];
94  }
95
96  virtual string16 GetCvc() OVERRIDE { return string16(); }
97  virtual bool SaveDetailsLocally() OVERRIDE { return true; }
98  virtual const content::NavigationController* ShowSignIn() OVERRIDE {
99    return NULL;
100  }
101  virtual void HideSignIn() OVERRIDE {}
102  virtual void UpdateProgressBar(double value) OVERRIDE {}
103
104  MOCK_METHOD0(ModelChanged, void());
105
106  virtual void OnSignInResize(const gfx::Size& pref_size) OVERRIDE {}
107
108  void SetUserInput(DialogSection section, const DetailOutputMap& map) {
109    outputs_[section] = map;
110  }
111
112 private:
113  std::map<DialogSection, DetailOutputMap> outputs_;
114
115  DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogView);
116};
117
118class TestWalletClient : public wallet::WalletClient {
119 public:
120  TestWalletClient(net::URLRequestContextGetter* context,
121                   wallet::WalletClientDelegate* delegate)
122      : wallet::WalletClient(context, delegate) {}
123  virtual ~TestWalletClient() {}
124
125  MOCK_METHOD3(AcceptLegalDocuments,
126      void(const std::vector<wallet::WalletItems::LegalDocument*>& documents,
127           const std::string& google_transaction_id,
128           const GURL& source_url));
129
130  MOCK_METHOD3(AuthenticateInstrument,
131      void(const std::string& instrument_id,
132           const std::string& card_verification_number,
133           const std::string& obfuscated_gaia_id));
134
135  MOCK_METHOD1(GetFullWallet,
136      void(const wallet::WalletClient::FullWalletRequest& request));
137
138  MOCK_METHOD2(SaveAddress,
139      void(const wallet::Address& address, const GURL& source_url));
140
141  MOCK_METHOD3(SaveInstrument,
142      void(const wallet::Instrument& instrument,
143           const std::string& obfuscated_gaia_id,
144           const GURL& source_url));
145
146  MOCK_METHOD4(SaveInstrumentAndAddress,
147      void(const wallet::Instrument& instrument,
148           const wallet::Address& address,
149           const std::string& obfuscated_gaia_id,
150           const GURL& source_url));
151
152  MOCK_METHOD2(UpdateAddress,
153      void(const wallet::Address& address, const GURL& source_url));
154
155  virtual void UpdateInstrument(
156      const wallet::WalletClient::UpdateInstrumentRequest& update_request,
157      scoped_ptr<wallet::Address> billing_address) {
158    updated_billing_address_ = billing_address.Pass();
159  }
160
161  const wallet::Address* updated_billing_address() {
162    return updated_billing_address_.get();
163  }
164
165 private:
166  scoped_ptr<wallet::Address> updated_billing_address_;
167
168  DISALLOW_COPY_AND_ASSIGN(TestWalletClient);
169};
170
171// Bring over command-ids from AccountChooserModel.
172class TestAccountChooserModel : public AccountChooserModel {
173 public:
174  TestAccountChooserModel(AccountChooserModelDelegate* delegate,
175                          PrefService* prefs,
176                          const AutofillMetrics& metric_logger)
177      : AccountChooserModel(delegate, prefs, metric_logger,
178                            DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {}
179  virtual ~TestAccountChooserModel() {}
180
181  using AccountChooserModel::kActiveWalletItemId;
182  using AccountChooserModel::kAutofillItemId;
183
184 private:
185  DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel);
186};
187
188class TestAutofillDialogController
189    : public AutofillDialogControllerImpl,
190      public base::SupportsWeakPtr<TestAutofillDialogController> {
191 public:
192  TestAutofillDialogController(
193      content::WebContents* contents,
194      const FormData& form_structure,
195      const GURL& source_url,
196      const AutofillMetrics& metric_logger,
197      const DialogType dialog_type,
198      const base::Callback<void(const FormStructure*,
199                                const std::string&)>& callback)
200      : AutofillDialogControllerImpl(contents,
201                                     form_structure,
202                                     source_url,
203                                     dialog_type,
204                                     callback),
205        metric_logger_(metric_logger),
206        test_wallet_client_(
207            Profile::FromBrowserContext(contents->GetBrowserContext())->
208                GetRequestContext(), this),
209        is_first_run_(true),
210        dialog_type_(dialog_type) {}
211  virtual ~TestAutofillDialogController() {}
212
213  virtual AutofillDialogView* CreateView() OVERRIDE {
214    return new testing::NiceMock<TestAutofillDialogView>();
215  }
216
217  void Init(content::BrowserContext* browser_context) {
218    test_manager_.Init(browser_context);
219  }
220
221  TestAutofillDialogView* GetView() {
222    return static_cast<TestAutofillDialogView*>(view());
223  }
224
225  TestPersonalDataManager* GetTestingManager() {
226    return &test_manager_;
227  }
228
229  TestWalletClient* GetTestingWalletClient() {
230    return &test_wallet_client_;
231  }
232
233  void set_is_first_run(bool is_first_run) { is_first_run_ = is_first_run; }
234
235  const GURL& open_tab_url() { return open_tab_url_; }
236
237  virtual DialogType GetDialogType() const OVERRIDE {
238    return dialog_type_;
239  }
240
241  void set_dialog_type(DialogType dialog_type) { dialog_type_ = dialog_type; }
242
243  bool IsSectionInEditState(DialogSection section) {
244    std::map<DialogSection, bool> state = section_editing_state();
245    return state[section];
246  }
247
248  MOCK_METHOD0(LoadRiskFingerprintData, void());
249  using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
250
251 protected:
252  virtual PersonalDataManager* GetManager() OVERRIDE {
253    return &test_manager_;
254  }
255
256  virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
257    return &test_wallet_client_;
258  }
259
260  virtual bool IsFirstRun() const OVERRIDE {
261    return is_first_run_;
262  }
263
264  virtual void OpenTabWithUrl(const GURL& url) OVERRIDE {
265    open_tab_url_ = url;
266  }
267
268 private:
269  // To specify our own metric logger.
270  virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
271    return metric_logger_;
272  }
273
274  const AutofillMetrics& metric_logger_;
275  TestPersonalDataManager test_manager_;
276  testing::NiceMock<TestWalletClient> test_wallet_client_;
277  bool is_first_run_;
278  GURL open_tab_url_;
279  DialogType dialog_type_;
280
281  DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
282};
283
284class AutofillDialogControllerTest : public testing::Test {
285 public:
286  AutofillDialogControllerTest()
287    : ui_thread_(BrowserThread::UI, &loop_),
288      file_thread_(BrowserThread::FILE),
289      file_blocking_thread_(BrowserThread::FILE_USER_BLOCKING),
290      io_thread_(BrowserThread::IO) {
291    file_thread_.Start();
292    file_blocking_thread_.Start();
293    io_thread_.StartIOThread();
294  }
295
296  virtual ~AutofillDialogControllerTest() {}
297
298  // testing::Test implementation:
299  virtual void SetUp() OVERRIDE {
300    FormData form_data;
301    for (size_t i = 0; i < arraysize(kFieldsFromPage); ++i) {
302      FormFieldData field;
303      field.autocomplete_attribute = kFieldsFromPage[i];
304      form_data.fields.push_back(field);
305    }
306
307    profile()->CreateRequestContext();
308    test_web_contents_.reset(
309        content::WebContentsTester::CreateTestWebContents(profile(), NULL));
310
311    SetUpControllerWithFormData(form_data);
312  }
313
314  virtual void TearDown() OVERRIDE {
315    if (controller_)
316      controller_->ViewClosed();
317  }
318
319 protected:
320  void SetUpControllerWithFormData(const FormData& form_data) {
321    if (controller_)
322      controller_->ViewClosed();
323
324    base::Callback<void(const FormStructure*, const std::string&)> callback =
325        base::Bind(&AutofillDialogControllerTest::FinishedCallback,
326                   base::Unretained(this));
327    controller_ = (new testing::NiceMock<TestAutofillDialogController>(
328        test_web_contents_.get(),
329        form_data,
330        GURL(),
331        metric_logger_,
332        DIALOG_TYPE_REQUEST_AUTOCOMPLETE,
333        callback))->AsWeakPtr();
334    controller_->Init(profile());
335    controller_->Show();
336    controller_->OnUserNameFetchSuccess(kFakeEmail);
337  }
338
339  void FillCreditCardInputs() {
340    DetailOutputMap cc_outputs;
341    const DetailInputs& cc_inputs =
342        controller()->RequestedFieldsForSection(SECTION_CC);
343    for (size_t i = 0; i < cc_inputs.size(); ++i) {
344      cc_outputs[&cc_inputs[i]] = ASCIIToUTF16("11");
345    }
346    controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs);
347  }
348
349  std::vector<DialogNotification> NotificationsOfType(
350      DialogNotification::Type type) {
351    std::vector<DialogNotification> right_type;
352    const std::vector<DialogNotification>& notifications =
353        controller()->CurrentNotifications();
354    for (size_t i = 0; i < notifications.size(); ++i) {
355      if (notifications[i].type() == type)
356        right_type.push_back(notifications[i]);
357    }
358    return right_type;
359  }
360
361  void SwitchToAutofill() {
362    controller_->MenuModelForAccountChooser()->ActivatedAt(
363        TestAccountChooserModel::kAutofillItemId);
364  }
365
366  void SwitchToWallet() {
367    controller_->MenuModelForAccountChooser()->ActivatedAt(
368        TestAccountChooserModel::kActiveWalletItemId);
369  }
370
371  void UseBillingForShipping() {
372    controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(0);
373  }
374
375  TestAutofillDialogController* controller() { return controller_; }
376
377  TestingProfile* profile() { return &profile_; }
378
379  const FormStructure* form_structure() { return form_structure_; }
380
381 private:
382  void FinishedCallback(const FormStructure* form_structure,
383                        const std::string& google_transaction_id) {
384    form_structure_ = form_structure;
385  }
386
387#if defined(OS_WIN)
388   // http://crbug.com/227221
389   ui::ScopedOleInitializer ole_initializer_;
390#endif
391
392  // A bunch of threads are necessary for classes like TestWebContents and
393  // URLRequestContextGetter not to fall over.
394  base::MessageLoopForUI loop_;
395  content::TestBrowserThread ui_thread_;
396  content::TestBrowserThread file_thread_;
397  content::TestBrowserThread file_blocking_thread_;
398  content::TestBrowserThread io_thread_;
399  TestingProfile profile_;
400
401  // The controller owns itself.
402  base::WeakPtr<TestAutofillDialogController> controller_;
403
404  scoped_ptr<content::WebContents> test_web_contents_;
405
406  // Must outlive the controller.
407  AutofillMetrics metric_logger_;
408
409  // Returned when the dialog closes successfully.
410  const FormStructure* form_structure_;
411
412  DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
413};
414
415}  // namespace
416
417// This test makes sure nothing falls over when fields are being validity-
418// checked.
419TEST_F(AutofillDialogControllerTest, ValidityCheck) {
420  const DialogSection sections[] = {
421    SECTION_EMAIL,
422    SECTION_CC,
423    SECTION_BILLING,
424    SECTION_CC_BILLING,
425    SECTION_SHIPPING
426  };
427
428  for (size_t i = 0; i < arraysize(sections); ++i) {
429    DialogSection section = sections[i];
430    const DetailInputs& shipping_inputs =
431        controller()->RequestedFieldsForSection(section);
432    for (DetailInputs::const_iterator iter = shipping_inputs.begin();
433         iter != shipping_inputs.end(); ++iter) {
434      controller()->InputValidityMessage(iter->type, string16());
435    }
436  }
437}
438
439// Test for phone number validation.
440TEST_F(AutofillDialogControllerTest, PhoneNumberValidation) {
441  // Construct DetailOutputMap from existing data.
442  SwitchToAutofill();
443
444  AutofillProfile full_profile(test::GetVerifiedProfile());
445  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
446  controller()->EditClickedForSection(SECTION_SHIPPING);
447
448  DetailOutputMap outputs;
449  const DetailInputs& inputs =
450      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
451
452  // Make sure country is United States.
453  SetOutputValue(inputs, &outputs, ADDRESS_HOME_COUNTRY, "United States");
454
455  // Existing data should have no errors.
456  ValidityData validity_data =
457      controller()->InputsAreValid(outputs,
458                                   AutofillDialogController::VALIDATE_FINAL);
459  EXPECT_EQ(0U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
460
461  // Input an empty phone number with VALIDATE_FINAL.
462  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER, "");
463  validity_data =
464      controller()->InputsAreValid(outputs,
465                                   AutofillDialogController::VALIDATE_FINAL);
466  EXPECT_EQ(1U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
467
468  // Input an empty phone number with VALIDATE_EDIT.
469  validity_data =
470      controller()->InputsAreValid(outputs,
471                                   AutofillDialogController::VALIDATE_EDIT);
472  EXPECT_EQ(0U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
473
474  // Input an invalid phone number.
475  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER, "ABC");
476  validity_data =
477      controller()->InputsAreValid(outputs,
478                                   AutofillDialogController::VALIDATE_EDIT);
479  EXPECT_EQ(1U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
480
481  // Input a local phone number.
482  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER, "2155546699");
483  validity_data =
484      controller()->InputsAreValid(outputs,
485                                   AutofillDialogController::VALIDATE_EDIT);
486  EXPECT_EQ(0U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
487
488  // Input an invalid local phone number.
489  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER, "215554669");
490  validity_data =
491      controller()->InputsAreValid(outputs,
492                                   AutofillDialogController::VALIDATE_EDIT);
493  EXPECT_EQ(1U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
494
495  // Input an international phone number.
496  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER, "+33 892 70 12 39");
497  validity_data =
498      controller()->InputsAreValid(outputs,
499                                   AutofillDialogController::VALIDATE_EDIT);
500  EXPECT_EQ(0U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
501
502  // Input an invalid international phone number.
503  SetOutputValue(inputs, &outputs, PHONE_HOME_WHOLE_NUMBER,
504                 "+112333 892 70 12 39");
505  validity_data =
506      controller()->InputsAreValid(outputs,
507                                   AutofillDialogController::VALIDATE_EDIT);
508  EXPECT_EQ(1U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
509}
510
511TEST_F(AutofillDialogControllerTest, CardHolderNameValidation) {
512  // Construct DetailOutputMap from AutofillProfile data.
513  SwitchToAutofill();
514
515  AutofillProfile full_profile(test::GetVerifiedProfile());
516  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
517  controller()->EditClickedForSection(SECTION_SHIPPING);
518
519  DetailOutputMap outputs;
520  const DetailInputs& inputs =
521      controller()->RequestedFieldsForSection(SECTION_CC);
522
523  // Input an empty card holder name with VALIDATE_FINAL.
524  SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "");
525  ValidityData validity_data =
526      controller()->InputsAreValid(outputs,
527                                   AutofillDialogController::VALIDATE_FINAL);
528  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
529
530  // Input an empty card holder name with VALIDATE_EDIT.
531  validity_data =
532      controller()->InputsAreValid(outputs,
533                                   AutofillDialogController::VALIDATE_EDIT);
534  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
535
536  // Input a non-empty card holder name.
537  SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "Bob");
538  validity_data =
539      controller()->InputsAreValid(outputs,
540                                   AutofillDialogController::VALIDATE_FINAL);
541  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
542
543  // Switch to Wallet which only considers names with with at least two names to
544  // be valid.
545  SwitchToWallet();
546
547  // Setup some wallet state.
548  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
549  wallet_items->AddAddress(wallet::GetTestShippingAddress());
550  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
551  controller()->OnDidGetWalletItems(wallet_items.Pass());
552
553  controller()->EditClickedForSection(SECTION_CC_BILLING);
554
555  DetailOutputMap wallet_outputs;
556  const DetailInputs& wallet_inputs =
557      controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
558
559  // Input an empty card holder name with VALIDATE_FINAL. Data source should not
560  // change this behavior.
561  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "");
562  validity_data =
563      controller()->InputsAreValid(wallet_outputs,
564                                   AutofillDialogController::VALIDATE_FINAL);
565  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
566
567  // Input an empty card holder name with VALIDATE_EDIT. Data source should not
568  // change this behavior.
569  validity_data =
570      controller()->InputsAreValid(wallet_outputs,
571                                   AutofillDialogController::VALIDATE_EDIT);
572  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
573
574  // Input a one name card holder name. Wallet does not currently support this.
575  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "Bob");
576  validity_data =
577      controller()->InputsAreValid(wallet_outputs,
578                                   AutofillDialogController::VALIDATE_FINAL);
579  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
580
581  // Input a two name card holder name.
582  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
583                 "Bob Barker");
584  validity_data =
585      controller()->InputsAreValid(wallet_outputs,
586                                   AutofillDialogController::VALIDATE_FINAL);
587  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
588
589  // Input a more than two name card holder name.
590  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
591                 "John Jacob Jingleheimer Schmidt");
592  validity_data =
593      controller()->InputsAreValid(wallet_outputs,
594                                   AutofillDialogController::VALIDATE_FINAL);
595  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
596
597  // Input a card holder name with lots of crazy whitespace.
598  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
599                 "     \\n\\r John \\n  Jacob Jingleheimer \\t Schmidt  ");
600  validity_data =
601      controller()->InputsAreValid(wallet_outputs,
602                                   AutofillDialogController::VALIDATE_FINAL);
603  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
604}
605
606TEST_F(AutofillDialogControllerTest, AutofillProfiles) {
607  ui::MenuModel* shipping_model =
608      controller()->MenuModelForSection(SECTION_SHIPPING);
609  // Since the PersonalDataManager is empty, this should only have the
610  // "use billing", "add new" and "manage" menu items.
611  ASSERT_TRUE(shipping_model);
612  EXPECT_EQ(3, shipping_model->GetItemCount());
613  // On the other hand, the other models should be NULL when there's no
614  // suggestion.
615  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
616  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_BILLING));
617  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_EMAIL));
618
619  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(3);
620
621  // Empty profiles are ignored.
622  AutofillProfile empty_profile(base::GenerateGUID(), kSettingsOrigin);
623  empty_profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
624  controller()->GetTestingManager()->AddTestingProfile(&empty_profile);
625  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
626  ASSERT_TRUE(shipping_model);
627  EXPECT_EQ(3, shipping_model->GetItemCount());
628  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_EMAIL));
629
630  // An otherwise full but unverified profile should be ignored.
631  AutofillProfile full_profile(test::GetFullProfile());
632  full_profile.set_origin("https://www.example.com");
633  full_profile.SetRawInfo(ADDRESS_HOME_LINE2, string16());
634  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
635  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
636  ASSERT_TRUE(shipping_model);
637  EXPECT_EQ(3, shipping_model->GetItemCount());
638  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_EMAIL));
639
640  // A full, verified profile should be picked up.
641  AutofillProfile verified_profile(test::GetVerifiedProfile());
642  verified_profile.SetRawInfo(ADDRESS_HOME_LINE2, string16());
643  controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
644  shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING);
645  ASSERT_TRUE(shipping_model);
646  EXPECT_EQ(4, shipping_model->GetItemCount());
647  EXPECT_TRUE(!!controller()->MenuModelForSection(SECTION_EMAIL));
648}
649
650// Makes sure that the choice of which Autofill profile to use for each section
651// is sticky.
652TEST_F(AutofillDialogControllerTest, AutofillProfileDefaults) {
653  AutofillProfile full_profile(test::GetFullProfile());
654  full_profile.set_origin(kSettingsOrigin);
655  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
656  AutofillProfile full_profile2(test::GetFullProfile2());
657  full_profile2.set_origin(kSettingsOrigin);
658  controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
659
660  // Until a selection has been made, the default shipping suggestion is the
661  // first one (after "use billing").
662  SuggestionsMenuModel* shipping_model = static_cast<SuggestionsMenuModel*>(
663      controller()->MenuModelForSection(SECTION_SHIPPING));
664  EXPECT_EQ(1, shipping_model->checked_item());
665
666  for (int i = 2; i >= 0; --i) {
667    shipping_model = static_cast<SuggestionsMenuModel*>(
668        controller()->MenuModelForSection(SECTION_SHIPPING));
669    shipping_model->ExecuteCommand(i, 0);
670    FillCreditCardInputs();
671    controller()->OnAccept();
672
673    TearDown();
674    SetUp();
675    controller()->GetTestingManager()->AddTestingProfile(&full_profile);
676    controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
677    shipping_model = static_cast<SuggestionsMenuModel*>(
678        controller()->MenuModelForSection(SECTION_SHIPPING));
679    EXPECT_EQ(i, shipping_model->checked_item());
680  }
681
682  // Try again, but don't add the default profile to the PDM. The dialog
683  // should fall back to the first profile.
684  shipping_model->ExecuteCommand(2, 0);
685  FillCreditCardInputs();
686  controller()->OnAccept();
687  TearDown();
688  SetUp();
689  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
690  shipping_model = static_cast<SuggestionsMenuModel*>(
691      controller()->MenuModelForSection(SECTION_SHIPPING));
692  EXPECT_EQ(1, shipping_model->checked_item());
693}
694
695TEST_F(AutofillDialogControllerTest, AutofillProfileVariants) {
696  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
697  ui::MenuModel* email_model =
698      controller()->MenuModelForSection(SECTION_EMAIL);
699  EXPECT_FALSE(email_model);
700
701  // Set up some variant data.
702  AutofillProfile full_profile(test::GetVerifiedProfile());
703  std::vector<string16> names;
704  names.push_back(ASCIIToUTF16("John Doe"));
705  names.push_back(ASCIIToUTF16("Jane Doe"));
706  full_profile.SetRawMultiInfo(EMAIL_ADDRESS, names);
707  const string16 kEmail1 = ASCIIToUTF16(kFakeEmail);
708  const string16 kEmail2 = ASCIIToUTF16("admin@example.com");
709  std::vector<string16> emails;
710  emails.push_back(kEmail1);
711  emails.push_back(kEmail2);
712  full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
713
714  // Respect variants for the email address field only.
715  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
716  ui::MenuModel* shipping_model =
717      controller()->MenuModelForSection(SECTION_SHIPPING);
718  EXPECT_EQ(4, shipping_model->GetItemCount());
719  email_model = controller()->MenuModelForSection(SECTION_EMAIL);
720  ASSERT_TRUE(!!email_model);
721  EXPECT_EQ(4, email_model->GetItemCount());
722
723  // The first one is the default.
724  SuggestionsMenuModel* email_suggestions = static_cast<SuggestionsMenuModel*>(
725      controller()->MenuModelForSection(SECTION_EMAIL));
726  EXPECT_EQ(0, email_suggestions->checked_item());
727
728  email_model->ActivatedAt(0);
729  EXPECT_EQ(kEmail1,
730            controller()->SuggestionStateForSection(SECTION_EMAIL).text);
731  email_model->ActivatedAt(1);
732  EXPECT_EQ(kEmail2,
733            controller()->SuggestionStateForSection(SECTION_EMAIL).text);
734
735  controller()->EditClickedForSection(SECTION_EMAIL);
736  const DetailInputs& inputs =
737      controller()->RequestedFieldsForSection(SECTION_EMAIL);
738  EXPECT_EQ(kEmail2, inputs[0].initial_value);
739
740  // The choice of variant is persisted across runs of the dialog.
741  email_model->ActivatedAt(0);
742  email_model->ActivatedAt(1);
743  FillCreditCardInputs();
744  controller()->OnAccept();
745
746  TearDown();
747  SetUp();
748  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
749  email_suggestions = static_cast<SuggestionsMenuModel*>(
750      controller()->MenuModelForSection(SECTION_EMAIL));
751  EXPECT_EQ(1, email_suggestions->checked_item());
752}
753
754TEST_F(AutofillDialogControllerTest, AutofillCreditCards) {
755  // Since the PersonalDataManager is empty, this should only have the
756  // default menu items.
757  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
758
759  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(3);
760
761  // Empty cards are ignored.
762  CreditCard empty_card(base::GenerateGUID(), kSettingsOrigin);
763  empty_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("John Doe"));
764  controller()->GetTestingManager()->AddTestingCreditCard(&empty_card);
765  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
766
767  // An otherwise full but unverified card should be ignored.
768  CreditCard full_card(test::GetCreditCard());
769  full_card.set_origin("https://www.example.com");
770  controller()->GetTestingManager()->AddTestingCreditCard(&full_card);
771  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC));
772
773  // A full, verified card should be picked up.
774  CreditCard verified_card(test::GetCreditCard());
775  verified_card.set_origin(kSettingsOrigin);
776  controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
777  ui::MenuModel* credit_card_model =
778      controller()->MenuModelForSection(SECTION_CC);
779  ASSERT_TRUE(credit_card_model);
780  EXPECT_EQ(3, credit_card_model->GetItemCount());
781}
782
783// Test selecting a shipping address different from billing as address.
784TEST_F(AutofillDialogControllerTest, DontUseBillingAsShipping) {
785  AutofillProfile full_profile(test::GetVerifiedProfile());
786  AutofillProfile full_profile2(test::GetVerifiedProfile2());
787  CreditCard credit_card(test::GetVerifiedCreditCard());
788  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
789  controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
790  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
791  ui::MenuModel* shipping_model =
792      controller()->MenuModelForSection(SECTION_SHIPPING);
793  shipping_model->ActivatedAt(2);
794
795  controller()->OnAccept();
796  ASSERT_EQ(4U, form_structure()->field_count());
797  EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(2)->value));
798  EXPECT_EQ("MI", UTF16ToUTF8(form_structure()->field(3)->value));
799  EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type());
800  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type());
801}
802
803// Test selecting UseBillingForShipping.
804TEST_F(AutofillDialogControllerTest, UseBillingAsShipping) {
805  AutofillProfile full_profile(test::GetVerifiedProfile());
806  AutofillProfile full_profile2(test::GetVerifiedProfile2());
807  CreditCard credit_card(test::GetVerifiedCreditCard());
808  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
809  controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
810  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
811
812  // Test after setting use billing for shipping.
813  UseBillingForShipping();
814
815  controller()->OnAccept();
816  ASSERT_EQ(4U, form_structure()->field_count());
817  EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(2)->value));
818  EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(3)->value));
819  EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type());
820  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type());
821}
822
823// Tests that shipping and billing telephone fields are supported, and filled
824// in by their respective profiles. http://crbug.com/244515
825TEST_F(AutofillDialogControllerTest, DISABLED_BillingVsShippingPhoneNumber) {
826  FormFieldData shipping_tel;
827  shipping_tel.autocomplete_attribute = "shipping tel";
828  FormFieldData billing_tel;
829  billing_tel.autocomplete_attribute = "billing tel";
830
831  FormData form_data;
832  form_data.fields.push_back(shipping_tel);
833  form_data.fields.push_back(billing_tel);
834  SetUpControllerWithFormData(form_data);
835
836  // The profile that will be chosen for the shipping section.
837  AutofillProfile shipping_profile(test::GetVerifiedProfile());
838  // The profile that will be chosen for the billing section.
839  AutofillProfile billing_profile(test::GetVerifiedProfile2());
840  CreditCard credit_card(test::GetVerifiedCreditCard());
841  controller()->GetTestingManager()->AddTestingProfile(&shipping_profile);
842  controller()->GetTestingManager()->AddTestingProfile(&billing_profile);
843  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
844  ui::MenuModel* billing_model =
845      controller()->MenuModelForSection(SECTION_BILLING);
846  billing_model->ActivatedAt(1);
847
848  controller()->OnAccept();
849  ASSERT_EQ(2U, form_structure()->field_count());
850  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, form_structure()->field(0)->type());
851  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, form_structure()->field(1)->type());
852  EXPECT_EQ(shipping_profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
853            form_structure()->field(0)->value);
854  EXPECT_EQ(billing_profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
855            form_structure()->field(1)->value);
856  EXPECT_NE(form_structure()->field(1)->value,
857            form_structure()->field(0)->value);
858}
859
860TEST_F(AutofillDialogControllerTest, AcceptLegalDocuments) {
861  EXPECT_CALL(*controller()->GetTestingWalletClient(),
862              AcceptLegalDocuments(_, _, _)).Times(1);
863  EXPECT_CALL(*controller()->GetTestingWalletClient(),
864              GetFullWallet(_)).Times(1);
865  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(1);
866
867  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
868  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
869  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
870  wallet_items->AddAddress(wallet::GetTestShippingAddress());
871  controller()->OnDidGetWalletItems(wallet_items.Pass());
872  controller()->OnAccept();
873  controller()->OnDidAcceptLegalDocuments();
874  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
875}
876
877// Makes sure the default object IDs are respected.
878TEST_F(AutofillDialogControllerTest, WalletDefaultItems) {
879  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
880  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
881  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
882  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
883  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
884
885  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
886  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
887  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
888  wallet_items->AddAddress(wallet::GetTestShippingAddress());
889  wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress());
890
891  controller()->OnDidGetWalletItems(wallet_items.Pass());
892  // "add", "manage", and 4 suggestions.
893  EXPECT_EQ(6,
894      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
895  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
896      IsItemCheckedAt(2));
897  ASSERT_FALSE(controller()->IsSectionInEditState(SECTION_CC_BILLING));
898  // "use billing", "add", "manage", and 5 suggestions.
899  EXPECT_EQ(8,
900      controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
901  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_SHIPPING)->
902      IsItemCheckedAt(4));
903  ASSERT_FALSE(controller()->IsSectionInEditState(SECTION_SHIPPING));
904}
905
906// Tests that invalid and AMEX default instruments are ignored.
907TEST_F(AutofillDialogControllerTest, SelectInstrument) {
908  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
909  // Tests if default instrument is invalid, then, the first valid instrument is
910  // selected instead of the default instrument.
911  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
912  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
913  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
914  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
915
916  controller()->OnDidGetWalletItems(wallet_items.Pass());
917  // 4 suggestions and "add", "manage".
918  EXPECT_EQ(6,
919      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
920  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
921      IsItemCheckedAt(0));
922
923  // Tests if default instrument is AMEX, then, the first valid instrument is
924  // selected instead of the default instrument.
925  wallet_items = wallet::GetTestWalletItems();
926  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
927  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
928  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentAmex());
929  wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument());
930
931  controller()->OnDidGetWalletItems(wallet_items.Pass());
932  // 4 suggestions and "add", "manage".
933  EXPECT_EQ(6,
934      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
935  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
936      IsItemCheckedAt(0));
937
938  // Tests if only have AMEX and invalid instrument, then "add" is selected.
939  wallet_items = wallet::GetTestWalletItems();
940  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
941  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentAmex());
942
943  controller()->OnDidGetWalletItems(wallet_items.Pass());
944  // 2 suggestions and "add", "manage".
945  EXPECT_EQ(4,
946      controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount());
947  // "add"
948  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)->
949      IsItemCheckedAt(2));
950}
951
952TEST_F(AutofillDialogControllerTest, SaveAddress) {
953  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
954  EXPECT_CALL(*controller()->GetTestingWalletClient(),
955              SaveAddress(_, _)).Times(1);
956
957  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
958  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
959  controller()->OnDidGetWalletItems(wallet_items.Pass());
960  // If there is no shipping address in wallet, it will default to
961  // "same-as-billing" instead of "add-new-item". "same-as-billing" is covered
962  // by the following tests. The last item in the menu is "add-new-item".
963  ui::MenuModel* shipping_model =
964      controller()->MenuModelForSection(SECTION_SHIPPING);
965  shipping_model->ActivatedAt(shipping_model->GetItemCount() - 1);
966  controller()->OnAccept();
967}
968
969TEST_F(AutofillDialogControllerTest, SaveInstrument) {
970  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
971  EXPECT_CALL(*controller()->GetTestingWalletClient(),
972              SaveInstrument(_, _, _)).Times(1);
973
974  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
975  wallet_items->AddAddress(wallet::GetTestShippingAddress());
976  controller()->OnDidGetWalletItems(wallet_items.Pass());
977  controller()->OnAccept();
978}
979
980TEST_F(AutofillDialogControllerTest, SaveInstrumentWithInvalidInstruments) {
981  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
982  EXPECT_CALL(*controller()->GetTestingWalletClient(),
983              SaveInstrument(_, _, _)).Times(1);
984
985  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
986  wallet_items->AddAddress(wallet::GetTestShippingAddress());
987  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentInvalid());
988  controller()->OnDidGetWalletItems(wallet_items.Pass());
989  controller()->OnAccept();
990}
991
992TEST_F(AutofillDialogControllerTest, SaveInstrumentAndAddress) {
993  EXPECT_CALL(*controller()->GetTestingWalletClient(),
994              SaveInstrumentAndAddress(_, _, _, _)).Times(1);
995
996  controller()->OnDidGetWalletItems(wallet::GetTestWalletItems());
997  controller()->OnAccept();
998}
999
1000// Tests that editing an address (in wallet mode0 and submitting the dialog
1001// should update the existing address on the server via WalletClient.
1002TEST_F(AutofillDialogControllerTest, UpdateAddress) {
1003  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1004              UpdateAddress(_, _)).Times(1);
1005
1006  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1007  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1008  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1009  controller()->OnDidGetWalletItems(wallet_items.Pass());
1010
1011  controller()->EditClickedForSection(SECTION_SHIPPING);
1012  controller()->OnAccept();
1013}
1014
1015// Tests that editing an instrument (CC + address) in wallet mode updates an
1016// existing instrument on the server via WalletClient.
1017TEST_F(AutofillDialogControllerTest, UpdateInstrument) {
1018  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1019  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1020  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1021  controller()->OnDidGetWalletItems(wallet_items.Pass());
1022
1023  controller()->EditClickedForSection(SECTION_CC_BILLING);
1024  controller()->OnAccept();
1025
1026  EXPECT_TRUE(
1027      controller()->GetTestingWalletClient()->updated_billing_address());
1028}
1029
1030// Test that a user is able to edit their instrument and add a new address in
1031// the same submission.
1032TEST_F(AutofillDialogControllerTest, UpdateInstrumentSaveAddress) {
1033  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1034              SaveAddress(_, _)).Times(1);
1035
1036  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1037  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1038  controller()->OnDidGetWalletItems(wallet_items.Pass());
1039
1040  controller()->EditClickedForSection(SECTION_CC_BILLING);
1041  controller()->OnAccept();
1042
1043  EXPECT_TRUE(
1044      controller()->GetTestingWalletClient()->updated_billing_address());
1045}
1046
1047// Test that saving a new instrument and editing an address works.
1048TEST_F(AutofillDialogControllerTest, SaveInstrumentUpdateAddress) {
1049  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1050              SaveInstrument(_, _, _)).Times(1);
1051  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1052              UpdateAddress(_, _)).Times(1);
1053
1054  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1055  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1056
1057  controller()->OnDidGetWalletItems(wallet_items.Pass());
1058
1059  controller()->EditClickedForSection(SECTION_SHIPPING);
1060  controller()->OnAccept();
1061}
1062
1063MATCHER(UsesLocalBillingAddress, "uses the local billing address") {
1064  return arg.address_line_1() == ASCIIToUTF16(kEditedBillingAddress);
1065}
1066
1067// Tests that when using billing address for shipping, and there is no exact
1068// matched shipping address, then a shipping address should be added.
1069TEST_F(AutofillDialogControllerTest, BillingForShipping) {
1070  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1071              SaveAddress(_, _)).Times(1);
1072
1073  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1074  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1075  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1076
1077  controller()->OnDidGetWalletItems(wallet_items.Pass());
1078  // Select "Same as billing" in the address menu.
1079  UseBillingForShipping();
1080
1081  controller()->OnAccept();
1082}
1083
1084// Tests that when using billing address for shipping, and there is an exact
1085// matched shipping address, then a shipping address should not be added.
1086TEST_F(AutofillDialogControllerTest, BillingForShippingHasMatch) {
1087  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1088              SaveAddress(_, _)).Times(0);
1089
1090  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1091  scoped_ptr<wallet::WalletItems::MaskedInstrument> instrument =
1092      wallet::GetTestMaskedInstrument();
1093  // Copy billing address as shipping address, and assign an id to it.
1094  scoped_ptr<wallet::Address> shipping_address(
1095      new wallet::Address(instrument->address()));
1096  shipping_address->set_object_id("shipping_address_id");
1097  wallet_items->AddAddress(shipping_address.Pass());
1098  wallet_items->AddInstrument(instrument.Pass());
1099  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1100
1101  controller()->OnDidGetWalletItems(wallet_items.Pass());
1102  // Select "Same as billing" in the address menu.
1103  UseBillingForShipping();
1104
1105  controller()->OnAccept();
1106}
1107
1108// Tests that adding new instrument and also using billing address for shipping,
1109// then a shipping address should not be added.
1110TEST_F(AutofillDialogControllerTest, BillingForShippingNewInstrument) {
1111  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1112              SaveInstrumentAndAddress(_, _, _, _)).Times(1);
1113
1114  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1115  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1116
1117  controller()->OnDidGetWalletItems(wallet_items.Pass());
1118  // Select "Same as billing" in the address menu.
1119  UseBillingForShipping();
1120
1121  controller()->OnAccept();
1122}
1123
1124// Test that the local view contents is used when saving a new instrument and
1125// the user has selected "Same as billing".
1126TEST_F(AutofillDialogControllerTest, SaveInstrumentSameAsBilling) {
1127  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1128  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1129  controller()->OnDidGetWalletItems(wallet_items.Pass());
1130
1131  controller()->EditClickedForSection(SECTION_CC_BILLING);
1132  controller()->OnAccept();
1133
1134  DetailOutputMap outputs;
1135  const DetailInputs& inputs =
1136      controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
1137  for (size_t i = 0; i < inputs.size(); ++i) {
1138    const DetailInput& input = inputs[i];
1139    outputs[&input] = input.type == ADDRESS_BILLING_LINE1 ?
1140        ASCIIToUTF16(kEditedBillingAddress) : input.initial_value;
1141  }
1142  controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
1143
1144  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1145              SaveAddress(UsesLocalBillingAddress(), _)).Times(1);
1146  controller()->OnAccept();
1147
1148  EXPECT_TRUE(
1149      controller()->GetTestingWalletClient()->updated_billing_address());
1150}
1151
1152TEST_F(AutofillDialogControllerTest, CancelNoSave) {
1153  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1154              SaveInstrumentAndAddress(_, _, _, _)).Times(0);
1155
1156  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
1157
1158  controller()->OnDidGetWalletItems(wallet::GetTestWalletItems());
1159  controller()->OnCancel();
1160}
1161
1162// Checks that clicking the Manage menu item opens a new tab with a different
1163// URL for Wallet and Autofill.
1164TEST_F(AutofillDialogControllerTest, ManageItem) {
1165  AutofillProfile full_profile(test::GetVerifiedProfile());
1166  full_profile.set_origin(kSettingsOrigin);
1167  full_profile.SetRawInfo(ADDRESS_HOME_LINE2, string16());
1168  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1169  SwitchToAutofill();
1170
1171  SuggestionsMenuModel* shipping = static_cast<SuggestionsMenuModel*>(
1172      controller()->MenuModelForSection(SECTION_SHIPPING));
1173  shipping->ExecuteCommand(shipping->GetItemCount() - 1, 0);
1174  GURL autofill_manage_url = controller()->open_tab_url();
1175  EXPECT_EQ("chrome", autofill_manage_url.scheme());
1176
1177  SwitchToWallet();
1178  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1179  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1180  controller()->OnDidGetWalletItems(wallet_items.Pass());
1181
1182  controller()->SuggestionItemSelected(shipping, shipping->GetItemCount() - 1);
1183  GURL wallet_manage_addresses_url = controller()->open_tab_url();
1184  EXPECT_EQ("https", wallet_manage_addresses_url.scheme());
1185
1186  SuggestionsMenuModel* billing = static_cast<SuggestionsMenuModel*>(
1187      controller()->MenuModelForSection(SECTION_CC_BILLING));
1188  controller()->SuggestionItemSelected(billing, billing->GetItemCount() - 1);
1189  GURL wallet_manage_instruments_url = controller()->open_tab_url();
1190  EXPECT_EQ("https", wallet_manage_instruments_url.scheme());
1191
1192  EXPECT_NE(autofill_manage_url, wallet_manage_instruments_url);
1193  EXPECT_NE(wallet_manage_instruments_url, wallet_manage_addresses_url);
1194}
1195
1196TEST_F(AutofillDialogControllerTest, EditClickedCancelled) {
1197  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
1198
1199  AutofillProfile full_profile(test::GetVerifiedProfile());
1200  const string16 kEmail = ASCIIToUTF16("first@johndoe.com");
1201  full_profile.SetRawInfo(EMAIL_ADDRESS, kEmail);
1202  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1203
1204  ui::MenuModel* email_model =
1205      controller()->MenuModelForSection(SECTION_EMAIL);
1206  EXPECT_EQ(3, email_model->GetItemCount());
1207
1208  // When unedited, the initial_value should be empty.
1209  email_model->ActivatedAt(0);
1210  const DetailInputs& inputs0 =
1211      controller()->RequestedFieldsForSection(SECTION_EMAIL);
1212  EXPECT_EQ(string16(), inputs0[0].initial_value);
1213  EXPECT_EQ(kEmail,
1214            controller()->SuggestionStateForSection(SECTION_EMAIL).text);
1215
1216  // When edited, the initial_value should contain the value.
1217  controller()->EditClickedForSection(SECTION_EMAIL);
1218  const DetailInputs& inputs1 =
1219      controller()->RequestedFieldsForSection(SECTION_EMAIL);
1220  EXPECT_EQ(kEmail, inputs1[0].initial_value);
1221  EXPECT_EQ(string16(),
1222            controller()->SuggestionStateForSection(SECTION_EMAIL).text);
1223
1224  // When edit is cancelled, the initial_value should be empty.
1225  controller()->EditCancelledForSection(SECTION_EMAIL);
1226  const DetailInputs& inputs2 =
1227      controller()->RequestedFieldsForSection(SECTION_EMAIL);
1228  EXPECT_EQ(kEmail,
1229            controller()->SuggestionStateForSection(SECTION_EMAIL).text);
1230  EXPECT_EQ(string16(), inputs2[0].initial_value);
1231}
1232
1233// Tests that editing an autofill profile and then submitting works.
1234TEST_F(AutofillDialogControllerTest, EditAutofillProfile) {
1235  SwitchToAutofill();
1236
1237  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
1238
1239  AutofillProfile full_profile(test::GetVerifiedProfile());
1240  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1241  controller()->EditClickedForSection(SECTION_SHIPPING);
1242
1243  DetailOutputMap outputs;
1244  const DetailInputs& inputs =
1245      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
1246  for (size_t i = 0; i < inputs.size(); ++i) {
1247    const DetailInput& input = inputs[i];
1248    outputs[&input] = input.type == NAME_FULL ? ASCIIToUTF16("Edited Name") :
1249                                                input.initial_value;
1250  }
1251  controller()->GetView()->SetUserInput(SECTION_SHIPPING, outputs);
1252
1253  // We also have to simulate CC inputs to keep the controller happy.
1254  FillCreditCardInputs();
1255
1256  controller()->OnAccept();
1257  const AutofillProfile& edited_profile =
1258      controller()->GetTestingManager()->imported_profile();
1259
1260  for (size_t i = 0; i < inputs.size(); ++i) {
1261    const DetailInput& input = inputs[i];
1262    EXPECT_EQ(input.type == NAME_FULL ? ASCIIToUTF16("Edited Name") :
1263                                        input.initial_value,
1264              edited_profile.GetInfo(input.type, "en-US"));
1265  }
1266}
1267
1268// Tests that adding an autofill profile and then submitting works.
1269TEST_F(AutofillDialogControllerTest, AddAutofillProfile) {
1270  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
1271
1272  AutofillProfile full_profile(test::GetVerifiedProfile());
1273  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1274
1275  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_BILLING);
1276  // Activate the "Add billing address" menu item.
1277  model->ActivatedAt(model->GetItemCount() - 2);
1278
1279  // Fill in the inputs from the profile.
1280  DetailOutputMap outputs;
1281  const DetailInputs& inputs =
1282      controller()->RequestedFieldsForSection(SECTION_BILLING);
1283  AutofillProfile full_profile2(test::GetVerifiedProfile2());
1284  for (size_t i = 0; i < inputs.size(); ++i) {
1285    const DetailInput& input = inputs[i];
1286    outputs[&input] = full_profile2.GetInfo(input.type, "en-US");
1287  }
1288  controller()->GetView()->SetUserInput(SECTION_BILLING, outputs);
1289
1290  // Fill in some CC info. The name field will be used to fill in the billing
1291  // address name in the newly minted AutofillProfile.
1292  DetailOutputMap cc_outputs;
1293  const DetailInputs& cc_inputs =
1294      controller()->RequestedFieldsForSection(SECTION_CC);
1295  for (size_t i = 0; i < cc_inputs.size(); ++i) {
1296    cc_outputs[&cc_inputs[i]] = cc_inputs[i].type == CREDIT_CARD_NAME ?
1297        ASCIIToUTF16("Bill Money") : ASCIIToUTF16("111");
1298  }
1299  controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs);
1300
1301  controller()->OnAccept();
1302  const AutofillProfile& added_profile =
1303      controller()->GetTestingManager()->imported_profile();
1304
1305  const DetailInputs& shipping_inputs =
1306      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
1307  for (size_t i = 0; i < shipping_inputs.size(); ++i) {
1308    const DetailInput& input = shipping_inputs[i];
1309    string16 expected = input.type == NAME_FULL ?
1310        ASCIIToUTF16("Bill Money") :
1311        full_profile2.GetInfo(input.type, "en-US");
1312    EXPECT_EQ(expected, added_profile.GetInfo(input.type, "en-US"));
1313  }
1314
1315  // Also, the currently selected email address should get added to the new
1316  // profile.
1317  string16 original_email = full_profile.GetInfo(EMAIL_ADDRESS, "en-US");
1318  EXPECT_FALSE(original_email.empty());
1319  EXPECT_EQ(original_email,
1320            added_profile.GetInfo(EMAIL_ADDRESS, "en-US"));
1321}
1322
1323// Makes sure that a newly added email address gets added to an existing profile
1324// (as opposed to creating its own profile). http://crbug.com/240926
1325TEST_F(AutofillDialogControllerTest, AddEmail) {
1326  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
1327
1328  AutofillProfile full_profile(test::GetVerifiedProfile());
1329  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1330
1331  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_EMAIL);
1332  ASSERT_TRUE(model);
1333  // Activate the "Add email address" menu item.
1334  model->ActivatedAt(model->GetItemCount() - 2);
1335
1336  // Fill in the inputs from the profile.
1337  DetailOutputMap outputs;
1338  const DetailInputs& inputs =
1339      controller()->RequestedFieldsForSection(SECTION_EMAIL);
1340  const DetailInput& input = inputs[0];
1341  string16 new_email = ASCIIToUTF16("addemailtest@example.com");
1342  outputs[&input] = new_email;
1343  controller()->GetView()->SetUserInput(SECTION_EMAIL, outputs);
1344
1345  FillCreditCardInputs();
1346  controller()->OnAccept();
1347  std::vector<base::string16> email_values;
1348  full_profile.GetMultiInfo(EMAIL_ADDRESS, "en-US", &email_values);
1349  ASSERT_EQ(2U, email_values.size());
1350  EXPECT_EQ(new_email, email_values[1]);
1351}
1352
1353TEST_F(AutofillDialogControllerTest, VerifyCvv) {
1354  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1355              GetFullWallet(_)).Times(1);
1356  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1357              AuthenticateInstrument(_, _, _)).Times(1);
1358
1359  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1360  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1361  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1362  controller()->OnDidGetWalletItems(wallet_items.Pass());
1363  controller()->OnAccept();
1364  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1365
1366  EXPECT_TRUE(NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty());
1367  EXPECT_TRUE(controller()->SectionIsActive(SECTION_SHIPPING));
1368  EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING));
1369  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1370  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1371
1372  SuggestionState suggestion_state =
1373      controller()->SuggestionStateForSection(SECTION_CC_BILLING);
1374  EXPECT_TRUE(suggestion_state.extra_text.empty());
1375
1376  controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv());
1377
1378  EXPECT_FALSE(
1379      NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty());
1380  EXPECT_FALSE(controller()->SectionIsActive(SECTION_SHIPPING));
1381  EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING));
1382
1383  suggestion_state =
1384      controller()->SuggestionStateForSection(SECTION_CC_BILLING);
1385  EXPECT_FALSE(suggestion_state.extra_text.empty());
1386  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING));
1387
1388  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1389  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1390
1391  controller()->OnAccept();
1392}
1393
1394TEST_F(AutofillDialogControllerTest, ErrorDuringSubmit) {
1395  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1396              GetFullWallet(_)).Times(1);
1397
1398  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1399  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1400  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1401  controller()->OnDidGetWalletItems(wallet_items.Pass());
1402  controller()->OnAccept();
1403  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1404
1405  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1406  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1407
1408  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
1409
1410  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1411  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1412}
1413
1414// TODO(dbeam): disallow changing accounts instead and remove this test.
1415TEST_F(AutofillDialogControllerTest, ChangeAccountDuringSubmit) {
1416  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1417              GetFullWallet(_)).Times(1);
1418
1419  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1420  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1421  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1422  controller()->OnDidGetWalletItems(wallet_items.Pass());
1423  controller()->OnAccept();
1424  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1425
1426  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1427  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1428
1429  SwitchToWallet();
1430  SwitchToAutofill();
1431
1432  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1433  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1434}
1435
1436TEST_F(AutofillDialogControllerTest, ErrorDuringVerifyCvv) {
1437  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1438              GetFullWallet(_)).Times(1);
1439
1440  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1441  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1442  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1443  controller()->OnDidGetWalletItems(wallet_items.Pass());
1444  controller()->OnAccept();
1445  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1446  controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv());
1447
1448  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1449  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1450
1451  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
1452
1453  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1454  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1455}
1456
1457// TODO(dbeam): disallow changing accounts instead and remove this test.
1458TEST_F(AutofillDialogControllerTest, ChangeAccountDuringVerifyCvv) {
1459  EXPECT_CALL(*controller()->GetTestingWalletClient(),
1460              GetFullWallet(_)).Times(1);
1461
1462  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1463  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1464  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1465  controller()->OnDidGetWalletItems(wallet_items.Pass());
1466  controller()->OnAccept();
1467  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1468  controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv());
1469
1470  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1471  ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1472
1473  SwitchToWallet();
1474  SwitchToAutofill();
1475
1476  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1477  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1478}
1479
1480// Test that when a wallet error happens only an error is shown (and no other
1481// Wallet-related notifications).
1482TEST_F(AutofillDialogControllerTest, WalletErrorNotification) {
1483  controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR);
1484
1485  EXPECT_EQ(1U, NotificationsOfType(
1486      DialogNotification::WALLET_ERROR).size());
1487
1488  // No other wallet notifications should show on Wallet error.
1489  EXPECT_TRUE(NotificationsOfType(
1490      DialogNotification::WALLET_SIGNIN_PROMO).empty());
1491  EXPECT_TRUE(NotificationsOfType(
1492      DialogNotification::WALLET_USAGE_CONFIRMATION).empty());
1493  EXPECT_TRUE(NotificationsOfType(
1494      DialogNotification::EXPLANATORY_MESSAGE).empty());
1495}
1496
1497// Simulates receiving an INVALID_FORM_FIELD required action while processing a
1498// |WalletClientDelegate::OnDid{Save,Update}*()| call. This can happen if Online
1499// Wallet's server validation differs from Chrome's local validation.
1500TEST_F(AutofillDialogControllerTest, WalletServerSideValidationNotification) {
1501  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1502  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1503  controller()->OnDidGetWalletItems(wallet_items.Pass());
1504  controller()->OnAccept();
1505
1506  std::vector<wallet::RequiredAction> required_actions;
1507  required_actions.push_back(wallet::INVALID_FORM_FIELD);
1508  controller()->OnDidSaveAddress(std::string(), required_actions);
1509
1510  EXPECT_EQ(1U, NotificationsOfType(
1511      DialogNotification::REQUIRED_ACTION).size());
1512}
1513
1514// Test that only on first run an explanation of where Chrome got the user's
1515// data is shown (i.e. "Got these details from Wallet").
1516TEST_F(AutofillDialogControllerTest, WalletDetailsExplanation) {
1517  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1518  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1519  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1520  controller()->OnDidGetWalletItems(wallet_items.Pass());
1521
1522  EXPECT_EQ(1U, NotificationsOfType(
1523      DialogNotification::EXPLANATORY_MESSAGE).size());
1524
1525  // Wallet notifications are mutually exclusive.
1526  EXPECT_TRUE(NotificationsOfType(
1527      DialogNotification::WALLET_USAGE_CONFIRMATION).empty());
1528  EXPECT_TRUE(NotificationsOfType(
1529      DialogNotification::WALLET_SIGNIN_PROMO).empty());
1530
1531  // Switch to using Autofill, no explanatory message should show.
1532  SwitchToAutofill();
1533  EXPECT_TRUE(NotificationsOfType(
1534      DialogNotification::EXPLANATORY_MESSAGE).empty());
1535
1536  // Switch to Wallet, pretend this isn't first run. No message should show.
1537  SwitchToWallet();
1538  controller()->set_is_first_run(false);
1539  EXPECT_TRUE(NotificationsOfType(
1540      DialogNotification::EXPLANATORY_MESSAGE).empty());
1541}
1542
1543// Verifies that the "[X] Save details in wallet" notification shows on first
1544// run with an incomplete profile, stays showing when switching to Autofill in
1545// the account chooser, and continues to show on second+ run when a user's
1546// wallet is incomplete. This also tests that submitting disables interactivity.
1547TEST_F(AutofillDialogControllerTest, SaveDetailsInWallet) {
1548  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1549  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1550  controller()->OnDidGetWalletItems(wallet_items.Pass());
1551
1552  std::vector<DialogNotification> notifications =
1553      NotificationsOfType(DialogNotification::WALLET_USAGE_CONFIRMATION);
1554  EXPECT_EQ(1U, notifications.size());
1555  EXPECT_TRUE(notifications.front().checked());
1556  EXPECT_TRUE(notifications.front().interactive());
1557
1558  // Wallet notifications are mutually exclusive.
1559  EXPECT_TRUE(NotificationsOfType(
1560      DialogNotification::WALLET_SIGNIN_PROMO).empty());
1561  EXPECT_TRUE(NotificationsOfType(
1562      DialogNotification::EXPLANATORY_MESSAGE).empty());
1563
1564  // Using Autofill on second run, show an interactive, unchecked checkbox.
1565  SwitchToAutofill();
1566  controller()->set_is_first_run(false);
1567
1568  notifications =
1569      NotificationsOfType(DialogNotification::WALLET_USAGE_CONFIRMATION);
1570  EXPECT_EQ(1U, notifications.size());
1571  EXPECT_FALSE(notifications.front().checked());
1572  EXPECT_TRUE(notifications.front().interactive());
1573
1574  // Notifications shouldn't be interactive while submitting.
1575  SwitchToWallet();
1576  controller()->OnAccept();
1577  EXPECT_FALSE(NotificationsOfType(
1578      DialogNotification::WALLET_USAGE_CONFIRMATION).front().interactive());
1579}
1580
1581// Verifies that no Wallet notifications are shown after first run (i.e. no
1582// "[X] Save details to wallet" or "These details are from your Wallet") when
1583// the user has a complete wallet.
1584TEST_F(AutofillDialogControllerTest, NoWalletNotifications) {
1585  controller()->set_is_first_run(false);
1586
1587  // Simulate a complete wallet.
1588  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1589  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1590  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1591  controller()->OnDidGetWalletItems(wallet_items.Pass());
1592
1593  EXPECT_TRUE(NotificationsOfType(
1594      DialogNotification::EXPLANATORY_MESSAGE).empty());
1595  EXPECT_TRUE(NotificationsOfType(
1596      DialogNotification::WALLET_USAGE_CONFIRMATION).empty());
1597}
1598
1599TEST_F(AutofillDialogControllerTest, OnAutocheckoutError) {
1600  SwitchToAutofill();
1601  controller()->set_dialog_type(DIALOG_TYPE_AUTOCHECKOUT);
1602
1603  // We also have to simulate CC inputs to keep the controller happy.
1604  FillCreditCardInputs();
1605
1606  controller()->OnAccept();
1607  controller()->OnAutocheckoutError();
1608
1609  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1610  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1611  EXPECT_EQ(0U, NotificationsOfType(
1612      DialogNotification::AUTOCHECKOUT_SUCCESS).size());
1613  EXPECT_EQ(1U, NotificationsOfType(
1614      DialogNotification::AUTOCHECKOUT_ERROR).size());
1615}
1616
1617TEST_F(AutofillDialogControllerTest, OnAutocheckoutSuccess) {
1618  SwitchToAutofill();
1619  controller()->set_dialog_type(DIALOG_TYPE_AUTOCHECKOUT);
1620
1621  // We also have to simulate CC inputs to keep the controller happy.
1622  FillCreditCardInputs();
1623
1624  controller()->OnAccept();
1625  controller()->OnAutocheckoutSuccess();
1626
1627  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
1628  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1629  EXPECT_EQ(1U, NotificationsOfType(
1630      DialogNotification::AUTOCHECKOUT_SUCCESS).size());
1631  EXPECT_EQ(0U, NotificationsOfType(
1632      DialogNotification::AUTOCHECKOUT_ERROR).size());
1633}
1634
1635TEST_F(AutofillDialogControllerTest, ViewCancelDoesntSetPref) {
1636  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
1637      ::prefs::kAutofillDialogPayWithoutWallet));
1638
1639  SwitchToAutofill();
1640
1641  controller()->OnCancel();
1642  controller()->ViewClosed();
1643
1644  EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath(
1645      ::prefs::kAutofillDialogPayWithoutWallet));
1646}
1647
1648TEST_F(AutofillDialogControllerTest, ViewSubmitSetsPref) {
1649  ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
1650      ::prefs::kAutofillDialogPayWithoutWallet));
1651
1652  SwitchToAutofill();
1653
1654  // We also have to simulate CC inputs to keep the controller happy.
1655  FillCreditCardInputs();
1656
1657  controller()->OnAccept();
1658
1659  EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(
1660      ::prefs::kAutofillDialogPayWithoutWallet));
1661  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
1662      ::prefs::kAutofillDialogPayWithoutWallet));
1663}
1664
1665TEST_F(AutofillDialogControllerTest, HideWalletEmail) {
1666  SwitchToAutofill();
1667
1668  // Email section should be showing when using Autofill.
1669  EXPECT_TRUE(controller()->SectionIsActive(SECTION_EMAIL));
1670
1671  SwitchToWallet();
1672
1673  // Setup some wallet state, submit, and get a full wallet to end the flow.
1674  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1675  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1676  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1677
1678  // Filling |form_structure()| depends on the current username and wallet items
1679  // being fetched. Until both of these have occurred, the user should not be
1680  // able to click Submit if using Wallet. The username fetch happened earlier.
1681  EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1682  controller()->OnDidGetWalletItems(wallet_items.Pass());
1683  EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
1684
1685  // Email section should be hidden when using Wallet.
1686  EXPECT_FALSE(controller()->SectionIsActive(SECTION_EMAIL));
1687
1688  controller()->OnAccept();
1689  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1690
1691  size_t i = 0;
1692  for (; i < form_structure()->field_count(); ++i) {
1693    if (form_structure()->field(i)->type() == EMAIL_ADDRESS) {
1694      EXPECT_EQ(ASCIIToUTF16(kFakeEmail), form_structure()->field(i)->value);
1695      break;
1696    }
1697  }
1698  ASSERT_LT(i, form_structure()->field_count());
1699}
1700
1701// Test if autofill types of returned form structure are correct for billing
1702// entries.
1703TEST_F(AutofillDialogControllerTest, AutofillTypes) {
1704  controller()->OnDidGetWalletItems(wallet::GetTestWalletItems());
1705  controller()->OnAccept();
1706  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1707  ASSERT_EQ(4U, form_structure()->field_count());
1708  EXPECT_EQ(EMAIL_ADDRESS, form_structure()->field(0)->type());
1709  EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure()->field(1)->type());
1710  EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type());
1711  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type());
1712}
1713
1714TEST_F(AutofillDialogControllerTest, SaveDetailsInChrome) {
1715  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(2);
1716
1717  AutofillProfile full_profile(test::GetVerifiedProfile());
1718  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1719
1720  CreditCard card(test::GetVerifiedCreditCard());
1721  controller()->GetTestingManager()->AddTestingCreditCard(&card);
1722  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
1723
1724  controller()->EditClickedForSection(SECTION_EMAIL);
1725  EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome());
1726
1727  controller()->EditCancelledForSection(SECTION_EMAIL);
1728  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
1729
1730  controller()->MenuModelForSection(SECTION_EMAIL)->ActivatedAt(1);
1731  EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome());
1732
1733  profile()->set_incognito(true);
1734  EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome());
1735}
1736
1737// Tests that user is prompted when using instrument with minimal address.
1738TEST_F(AutofillDialogControllerTest, UpgradeMinimalAddress) {
1739  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1740  wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentWithIdAndAddress(
1741      "id", wallet::GetTestMinimalAddress()));
1742  scoped_ptr<wallet::Address> address(wallet::GetTestShippingAddress());
1743  address->set_is_complete_address(false);
1744  wallet_items->AddAddress(address.Pass());
1745  controller()->OnDidGetWalletItems(wallet_items.Pass());
1746
1747  // Assert that dialog's SECTION_CC_BILLING section is in edit mode.
1748  ASSERT_TRUE(controller()->IsSectionInEditState(SECTION_CC_BILLING));
1749  // Shipping section should be in edit mode because of
1750  // is_minimal_shipping_address.
1751  ASSERT_TRUE(controller()->IsSectionInEditState(SECTION_SHIPPING));
1752}
1753
1754TEST_F(AutofillDialogControllerTest, RiskNeverLoadsWithPendingLegalDocuments) {
1755  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(0);
1756
1757  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1758  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1759  controller()->OnDidGetWalletItems(wallet_items.Pass());
1760  controller()->OnAccept();
1761
1762  EXPECT_TRUE(controller()->GetRiskData().empty());
1763}
1764
1765TEST_F(AutofillDialogControllerTest, RiskLoadsWithoutPendingLegalDocuments) {
1766  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(1);
1767
1768  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1769  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1770  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1771  controller()->OnDidGetWalletItems(wallet_items.Pass());
1772  controller()->OnAccept();
1773
1774  EXPECT_TRUE(controller()->GetRiskData().empty());
1775
1776  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1777  EXPECT_EQ(kFakeFingerprintEncoded, controller()->GetRiskData());
1778}
1779
1780TEST_F(AutofillDialogControllerTest, RiskLoadsAfterAcceptingLegalDocuments) {
1781  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(0);
1782
1783  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1784  wallet_items->AddLegalDocument(wallet::GetTestLegalDocument());
1785  controller()->OnDidGetWalletItems(wallet_items.Pass());
1786
1787  testing::Mock::VerifyAndClear(controller());
1788  EXPECT_CALL(*controller(), LoadRiskFingerprintData()).Times(1);
1789
1790  controller()->OnAccept();
1791  EXPECT_TRUE(controller()->GetRiskData().empty());
1792
1793  // Simulate a risk load and verify |GetRiskData()| matches the encoded value.
1794  controller()->OnDidAcceptLegalDocuments();
1795  controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
1796  EXPECT_EQ(kFakeFingerprintEncoded, controller()->GetRiskData());
1797}
1798
1799TEST_F(AutofillDialogControllerTest, NoManageMenuItemForNewWalletUsers) {
1800  // Make sure the menu model item is created for a returning Wallet user.
1801  scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
1802  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1803  wallet_items->AddAddress(wallet::GetTestShippingAddress());
1804  controller()->OnDidGetWalletItems(wallet_items.Pass());
1805
1806  EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING));
1807  // "Same as billing", "123 address", "Add address...", and "Manage addresses".
1808  EXPECT_EQ(
1809      4, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1810
1811  // Make sure the menu model item is not created for new Wallet users.
1812  base::DictionaryValue dict;
1813  scoped_ptr<base::ListValue> required_actions(new base::ListValue);
1814  required_actions->AppendString("setup_wallet");
1815  dict.Set("required_action", required_actions.release());
1816  controller()->OnDidGetWalletItems(
1817      wallet::WalletItems::CreateWalletItems(dict).Pass());
1818
1819  EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING));
1820  // "Same as billing" and "Add address...".
1821  EXPECT_EQ(
1822      2, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount());
1823}
1824
1825}  // namespace autofill
1826