| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/tuple.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/autofill/browser/autocheckout_manager.h" |
| #include "components/autofill/browser/autofill_common_test.h" |
| #include "components/autofill/browser/autofill_manager.h" |
| #include "components/autofill/browser/autofill_metrics.h" |
| #include "components/autofill/browser/form_structure.h" |
| #include "components/autofill/browser/test_autofill_manager_delegate.h" |
| #include "components/autofill/common/autofill_messages.h" |
| #include "components/autofill/common/form_data.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/test/mock_render_process_host.h" |
| #include "content/public/test/test_browser_thread.h" |
| #include "ipc/ipc_test_sink.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| |
| using content::BrowserThread; |
| |
| namespace autofill { |
| |
| namespace { |
| |
| typedef Tuple2<std::vector<FormData>, WebElementDescriptor> AutofillParam; |
| |
| FormFieldData BuildFieldWithValue( |
| const std::string& autocomplete_attribute, |
| const std::string& value) { |
| FormFieldData field; |
| field.name = ASCIIToUTF16(autocomplete_attribute); |
| field.value = ASCIIToUTF16(value); |
| field.autocomplete_attribute = autocomplete_attribute; |
| field.form_control_type = "text"; |
| return field; |
| } |
| |
| FormFieldData BuildField(const std::string& autocomplete_attribute) { |
| return BuildFieldWithValue(autocomplete_attribute, autocomplete_attribute); |
| } |
| |
| scoped_ptr<FormStructure> CreateTestFormStructure( |
| const std::vector<AutofillFieldType>& autofill_types) { |
| FormData form; |
| form.name = ASCIIToUTF16("MyForm"); |
| form.method = ASCIIToUTF16("POST"); |
| form.origin = GURL("https://myform.com/form.html"); |
| form.action = GURL("https://myform.com/submit.html"); |
| form.user_submitted = true; |
| |
| // Add some fields, autocomplete_attribute is not important and we |
| // fake that server sends authoritative field mappings. |
| for (size_t i = 0; i < autofill_types.size(); ++i) |
| form.fields.push_back(BuildField("SomeField")); |
| |
| scoped_ptr<FormStructure> form_structure( |
| new FormStructure(form, std::string())); |
| |
| // Set mocked Autofill server field types. |
| for (size_t i = 0; i < autofill_types.size(); ++i) { |
| form_structure->field(i)->set_server_type(autofill_types[i]); |
| // Set heuristic type to make sure that server_types are used and not |
| // heuritic type. |
| form_structure->field(i)->set_heuristic_type(CREDIT_CARD_NUMBER); |
| } |
| |
| return form_structure.Pass(); |
| } |
| |
| scoped_ptr<FormStructure> CreateTestAddressFormStructure() { |
| std::vector<AutofillFieldType> autofill_types; |
| autofill_types.push_back(NAME_FULL); |
| autofill_types.push_back(PHONE_HOME_WHOLE_NUMBER); |
| autofill_types.push_back(EMAIL_ADDRESS); |
| autofill_types.push_back(ADDRESS_HOME_LINE1); |
| autofill_types.push_back(ADDRESS_HOME_CITY); |
| autofill_types.push_back(ADDRESS_HOME_STATE); |
| autofill_types.push_back(ADDRESS_HOME_COUNTRY); |
| autofill_types.push_back(ADDRESS_HOME_ZIP); |
| autofill_types.push_back(NO_SERVER_DATA); |
| return CreateTestFormStructure(autofill_types); |
| } |
| |
| scoped_ptr<FormStructure> CreateTestCreditCardFormStructure() { |
| std::vector<AutofillFieldType> autofill_types; |
| autofill_types.push_back(CREDIT_CARD_NAME); |
| autofill_types.push_back(CREDIT_CARD_NUMBER); |
| autofill_types.push_back(CREDIT_CARD_EXP_MONTH); |
| autofill_types.push_back(CREDIT_CARD_EXP_4_DIGIT_YEAR); |
| autofill_types.push_back(CREDIT_CARD_VERIFICATION_CODE); |
| autofill_types.push_back(ADDRESS_BILLING_LINE1); |
| autofill_types.push_back(ADDRESS_BILLING_CITY); |
| autofill_types.push_back(ADDRESS_BILLING_STATE); |
| autofill_types.push_back(ADDRESS_BILLING_COUNTRY); |
| autofill_types.push_back(ADDRESS_BILLING_ZIP); |
| return CreateTestFormStructure(autofill_types); |
| } |
| |
| scoped_ptr<FormStructure> CreateTestFormStructureWithDefaultValues() { |
| FormData form; |
| form.name = ASCIIToUTF16("MyForm"); |
| form.method = ASCIIToUTF16("POST"); |
| form.origin = GURL("https://myform.com/form.html"); |
| form.action = GURL("https://myform.com/submit.html"); |
| form.user_submitted = true; |
| |
| // Add two radio button fields. |
| FormFieldData male = BuildFieldWithValue("sex", "male"); |
| male.is_checkable = true; |
| form.fields.push_back(male); |
| FormFieldData female = BuildFieldWithValue("sex", "female"); |
| female.is_checkable = true; |
| form.fields.push_back(female); |
| |
| scoped_ptr<FormStructure> form_structure( |
| new FormStructure(form, std::string())); |
| |
| // Fake server response. Set all fields as fields with default value. |
| form_structure->field(0)->set_server_type(FIELD_WITH_DEFAULT_VALUE); |
| form_structure->field(0)->set_default_value("female"); |
| form_structure->field(1)->set_server_type(FIELD_WITH_DEFAULT_VALUE); |
| form_structure->field(1)->set_default_value("female"); |
| |
| return form_structure.Pass(); |
| } |
| |
| scoped_ptr<WebElementDescriptor> CreateProceedElement() { |
| scoped_ptr<WebElementDescriptor> proceed_element(new WebElementDescriptor()); |
| proceed_element->descriptor = "#foo"; |
| proceed_element->retrieval_method = WebElementDescriptor::ID; |
| return proceed_element.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateStartOfFlowMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> start_of_flow( |
| new AutocheckoutPageMetaData()); |
| start_of_flow->current_page_number = 0; |
| start_of_flow->total_pages = 3; |
| start_of_flow->proceed_element_descriptor = CreateProceedElement().Pass(); |
| return start_of_flow.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateInFlowMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> in_flow(new AutocheckoutPageMetaData()); |
| in_flow->current_page_number = 1; |
| in_flow->total_pages = 3; |
| in_flow->proceed_element_descriptor = CreateProceedElement().Pass(); |
| return in_flow.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateNotInFlowMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> not_in_flow( |
| new AutocheckoutPageMetaData()); |
| not_in_flow->proceed_element_descriptor = CreateProceedElement().Pass(); |
| return not_in_flow.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateEndOfFlowMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> end_of_flow( |
| new AutocheckoutPageMetaData()); |
| end_of_flow->current_page_number = 2; |
| end_of_flow->total_pages = 3; |
| end_of_flow->proceed_element_descriptor = CreateProceedElement().Pass(); |
| return end_of_flow.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateOnePageFlowMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> one_page_flow( |
| new AutocheckoutPageMetaData()); |
| one_page_flow->current_page_number = 0; |
| one_page_flow->total_pages = 1; |
| one_page_flow->proceed_element_descriptor = CreateProceedElement().Pass(); |
| return one_page_flow.Pass(); |
| } |
| |
| scoped_ptr<AutocheckoutPageMetaData> CreateMissingProceedMetaData() { |
| scoped_ptr<AutocheckoutPageMetaData> missing_proceed( |
| new AutocheckoutPageMetaData()); |
| missing_proceed->current_page_number = 1; |
| missing_proceed->total_pages = 3; |
| return missing_proceed.Pass(); |
| } |
| |
| struct TestField { |
| const char* const field_type; |
| const char* const field_value; |
| AutofillFieldType autofill_type; |
| }; |
| |
| const TestField kTestFields[] = { |
| {"name", "Test User", NAME_FULL}, |
| {"tel", "650-123-9909", PHONE_HOME_WHOLE_NUMBER}, |
| {"email", "[email protected]", EMAIL_ADDRESS}, |
| {"cc-name", "Test User", CREDIT_CARD_NAME}, |
| {"cc-number", "4444444444444448", CREDIT_CARD_NUMBER}, |
| {"cc-exp-month", "10", CREDIT_CARD_EXP_MONTH}, |
| {"cc-exp-year", "2020", CREDIT_CARD_EXP_4_DIGIT_YEAR}, |
| {"cc-csc", "123", CREDIT_CARD_VERIFICATION_CODE}, |
| {"street-address", "Fake Street", ADDRESS_HOME_LINE1}, |
| {"locality", "Mocked City", ADDRESS_HOME_CITY}, |
| {"region", "California", ADDRESS_HOME_STATE}, |
| {"country", "USA", ADDRESS_HOME_COUNTRY}, |
| {"postal-code", "49012", ADDRESS_HOME_ZIP}, |
| {"billing-street-address", "Billing Street", ADDRESS_BILLING_LINE1}, |
| {"billing-locality", "Billing City", ADDRESS_BILLING_CITY}, |
| {"billing-region", "BillingState", ADDRESS_BILLING_STATE}, |
| {"billing-country", "Canada", ADDRESS_BILLING_COUNTRY}, |
| {"billing-postal-code", "11111", ADDRESS_BILLING_ZIP} |
| }; |
| |
| // Build Autocheckout specific form data to be consumed by |
| // AutofillDialogController to show the Autocheckout specific UI. |
| scoped_ptr<FormStructure> FakeUserSubmittedFormStructure() { |
| FormData formdata; |
| for (size_t i = 0; i < arraysize(kTestFields); i++) { |
| formdata.fields.push_back( |
| BuildFieldWithValue(kTestFields[i].field_type, |
| kTestFields[i].field_value)); |
| } |
| scoped_ptr<FormStructure> form_structure; |
| form_structure.reset(new FormStructure(formdata, std::string())); |
| for (size_t i = 0; i < arraysize(kTestFields); ++i) |
| form_structure->field(i)->set_server_type(kTestFields[i].autofill_type); |
| |
| return form_structure.Pass(); |
| } |
| |
| class MockAutofillManagerDelegate : public TestAutofillManagerDelegate { |
| public: |
| MockAutofillManagerDelegate() |
| : request_autocomplete_dialog_open_(false), |
| autocheckout_bubble_shown_(false) {} |
| |
| virtual ~MockAutofillManagerDelegate() {} |
| |
| virtual void HideRequestAutocompleteDialog() OVERRIDE { |
| request_autocomplete_dialog_open_ = false; |
| } |
| |
| MOCK_METHOD0(OnAutocheckoutError, void()); |
| |
| virtual void ShowAutocheckoutBubble( |
| const gfx::RectF& bounds, |
| const base::Callback<void(bool)>& callback) OVERRIDE { |
| autocheckout_bubble_shown_ = true; |
| callback.Run(true); |
| } |
| |
| virtual void HideAutocheckoutBubble() OVERRIDE {} |
| |
| virtual void ShowRequestAutocompleteDialog( |
| const FormData& form, |
| const GURL& source_url, |
| DialogType dialog_type, |
| const base::Callback<void(const FormStructure*, |
| const std::string&)>& callback) OVERRIDE { |
| request_autocomplete_dialog_open_ = true; |
| callback.Run(user_supplied_data_.get(), "google_transaction_id"); |
| } |
| |
| MOCK_METHOD1(UpdateProgressBar, void(double value)); |
| |
| void SetUserSuppliedData(scoped_ptr<FormStructure> user_supplied_data) { |
| user_supplied_data_.reset(user_supplied_data.release()); |
| } |
| |
| bool autocheckout_bubble_shown() const { |
| return autocheckout_bubble_shown_; |
| } |
| |
| void set_autocheckout_bubble_shown(bool autocheckout_bubble_shown) { |
| autocheckout_bubble_shown_ = autocheckout_bubble_shown; |
| } |
| |
| bool request_autocomplete_dialog_open() const { |
| return request_autocomplete_dialog_open_; |
| } |
| |
| private: |
| bool request_autocomplete_dialog_open_; |
| bool autocheckout_bubble_shown_; |
| scoped_ptr<FormStructure> user_supplied_data_; |
| }; |
| |
| class TestAutofillManager : public AutofillManager { |
| public: |
| explicit TestAutofillManager(content::WebContents* contents, |
| AutofillManagerDelegate* delegate) |
| : AutofillManager(contents, delegate, NULL) { |
| } |
| virtual ~TestAutofillManager() {} |
| |
| void SetFormStructure(scoped_ptr<FormStructure> form_structure) { |
| form_structures()->clear(); |
| form_structures()->push_back(form_structure.release()); |
| } |
| }; |
| |
| class MockAutofillMetrics : public AutofillMetrics { |
| public: |
| MockAutofillMetrics() {} |
| MOCK_CONST_METHOD1(LogAutocheckoutBubbleMetric, void(BubbleMetric)); |
| MOCK_CONST_METHOD1(LogAutocheckoutBuyFlowMetric, |
| void(AutocheckoutBuyFlowMetric)); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics); |
| }; |
| |
| class TestAutocheckoutManager: public AutocheckoutManager { |
| public: |
| explicit TestAutocheckoutManager(AutofillManager* autofill_manager) |
| : AutocheckoutManager(autofill_manager) { |
| set_metric_logger(scoped_ptr<AutofillMetrics>(new MockAutofillMetrics)); |
| } |
| |
| const MockAutofillMetrics& metric_logger() const { |
| return static_cast<const MockAutofillMetrics&>( |
| AutocheckoutManager::metric_logger()); |
| } |
| |
| using AutocheckoutManager::in_autocheckout_flow; |
| using AutocheckoutManager::autocheckout_offered; |
| using AutocheckoutManager::MaybeShowAutocheckoutDialog; |
| }; |
| |
| } // namespace |
| |
| class AutocheckoutManagerTest : public ChromeRenderViewHostTestHarness { |
| public: |
| AutocheckoutManagerTest() |
| : ChromeRenderViewHostTestHarness(), |
| ui_thread_(BrowserThread::UI, &message_loop_), |
| io_thread_(BrowserThread::IO) { |
| } |
| |
| std::vector<FormData> ReadFilledForms() { |
| uint32 kMsgID = AutofillMsg_FillFormsAndClick::ID; |
| const IPC::Message* message = |
| process()->sink().GetFirstMessageMatching(kMsgID); |
| AutofillParam autofill_param; |
| AutofillMsg_FillFormsAndClick::Read(message, &autofill_param); |
| return autofill_param.a; |
| } |
| |
| void CheckFillFormsAndClickIpc() { |
| EXPECT_EQ(1U, process()->sink().message_count()); |
| uint32 kMsgID = AutofillMsg_FillFormsAndClick::ID; |
| const IPC::Message* message = |
| process()->sink().GetFirstMessageMatching(kMsgID); |
| EXPECT_TRUE(message); |
| AutofillParam autofill_param; |
| AutofillMsg_FillFormsAndClick::Read(message, &autofill_param); |
| EXPECT_EQ(WebElementDescriptor::ID, autofill_param.b.retrieval_method); |
| ClearIpcSink(); |
| } |
| |
| void ClearIpcSink() { |
| process()->sink().ClearMessages(); |
| } |
| |
| void OpenRequestAutocompleteDialog() { |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_FALSE( |
| autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBubbleMetric( |
| AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); |
| // Simulate the user submitting some data via the requestAutocomplete UI. |
| autofill_manager_delegate_->SetUserSuppliedData( |
| FakeUserSubmittedFormStructure()); |
| GURL frame_url; |
| content::SSLStatus ssl_status; |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::DoubleEq(1.0/3.0))).Times(1); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_STARTED)).Times(1); |
| autocheckout_manager_->MaybeShowAutocheckoutDialog(frame_url, |
| ssl_status, |
| true); |
| CheckFillFormsAndClickIpc(); |
| EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_TRUE(autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| } |
| |
| void HideRequestAutocompleteDialog() { |
| EXPECT_TRUE( |
| autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| autofill_manager_delegate_->HideRequestAutocompleteDialog(); |
| EXPECT_FALSE( |
| autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| } |
| |
| protected: |
| content::TestBrowserThread ui_thread_; |
| content::TestBrowserThread io_thread_; |
| scoped_ptr<TestAutofillManager> autofill_manager_; |
| scoped_ptr<TestAutocheckoutManager> autocheckout_manager_; |
| scoped_ptr<MockAutofillManagerDelegate> autofill_manager_delegate_; |
| |
| private: |
| virtual void SetUp() OVERRIDE { |
| ChromeRenderViewHostTestHarness::SetUp(); |
| io_thread_.StartIOThread(); |
| profile()->CreateRequestContext(); |
| autofill_manager_delegate_.reset(new MockAutofillManagerDelegate()); |
| autofill_manager_.reset(new TestAutofillManager( |
| web_contents(), |
| autofill_manager_delegate_.get())); |
| autocheckout_manager_.reset( |
| new TestAutocheckoutManager(autofill_manager_.get())); |
| } |
| |
| virtual void TearDown() OVERRIDE { |
| autocheckout_manager_.reset(); |
| autofill_manager_delegate_.reset(); |
| autofill_manager_.reset(); |
| profile()->ResetRequestContext(); |
| ChromeRenderViewHostTestHarness::TearDown(); |
| io_thread_.Stop(); |
| } |
| |
| DISALLOW_COPY_AND_ASSIGN(AutocheckoutManagerTest); |
| }; |
| |
| TEST_F(AutocheckoutManagerTest, TestFillForms) { |
| OpenRequestAutocompleteDialog(); |
| |
| // Test if autocheckout manager can fill the first page. |
| autofill_manager_->SetFormStructure(CreateTestAddressFormStructure()); |
| |
| autocheckout_manager_->FillForms(); |
| |
| std::vector<FormData> filled_forms = ReadFilledForms(); |
| ASSERT_EQ(1U, filled_forms.size()); |
| ASSERT_EQ(9U, filled_forms[0].fields.size()); |
| EXPECT_EQ(ASCIIToUTF16("Test User"), filled_forms[0].fields[0].value); |
| EXPECT_EQ(ASCIIToUTF16("650-123-9909"), filled_forms[0].fields[1].value); |
| EXPECT_EQ(ASCIIToUTF16("[email protected]"), filled_forms[0].fields[2].value); |
| EXPECT_EQ(ASCIIToUTF16("Fake Street"), filled_forms[0].fields[3].value); |
| EXPECT_EQ(ASCIIToUTF16("Mocked City"), filled_forms[0].fields[4].value); |
| EXPECT_EQ(ASCIIToUTF16("California"), filled_forms[0].fields[5].value); |
| EXPECT_EQ(ASCIIToUTF16("United States"), filled_forms[0].fields[6].value); |
| EXPECT_EQ(ASCIIToUTF16("49012"), filled_forms[0].fields[7].value); |
| // Last field should not be filled, because there is no server mapping |
| // available for it. |
| EXPECT_EQ(ASCIIToUTF16("SomeField"), filled_forms[0].fields[8].value); |
| |
| filled_forms.clear(); |
| ClearIpcSink(); |
| |
| // Test if autocheckout manager can fill form on second page. |
| autofill_manager_->SetFormStructure(CreateTestCreditCardFormStructure()); |
| |
| autocheckout_manager_->FillForms(); |
| |
| filled_forms = ReadFilledForms(); |
| ASSERT_EQ(1U, filled_forms.size()); |
| ASSERT_EQ(10U, filled_forms[0].fields.size()); |
| EXPECT_EQ(ASCIIToUTF16("Test User"), filled_forms[0].fields[0].value); |
| EXPECT_EQ(ASCIIToUTF16("4444444444444448"), filled_forms[0].fields[1].value); |
| EXPECT_EQ(ASCIIToUTF16("10"), filled_forms[0].fields[2].value); |
| EXPECT_EQ(ASCIIToUTF16("2020"), filled_forms[0].fields[3].value); |
| EXPECT_EQ(ASCIIToUTF16("123"), filled_forms[0].fields[4].value); |
| EXPECT_EQ(ASCIIToUTF16("Billing Street"), filled_forms[0].fields[5].value); |
| EXPECT_EQ(ASCIIToUTF16("Billing City"), filled_forms[0].fields[6].value); |
| EXPECT_EQ(ASCIIToUTF16("BillingState"), filled_forms[0].fields[7].value); |
| EXPECT_EQ(ASCIIToUTF16("Canada"), filled_forms[0].fields[8].value); |
| EXPECT_EQ(ASCIIToUTF16("11111"), filled_forms[0].fields[9].value); |
| |
| filled_forms.clear(); |
| ClearIpcSink(); |
| |
| // Test form with default values. |
| autofill_manager_->SetFormStructure( |
| CreateTestFormStructureWithDefaultValues()); |
| |
| autocheckout_manager_->FillForms(); |
| |
| filled_forms = ReadFilledForms(); |
| ASSERT_EQ(1U, filled_forms.size()); |
| ASSERT_EQ(2U, filled_forms[0].fields.size()); |
| EXPECT_FALSE(filled_forms[0].fields[0].is_checked); |
| EXPECT_EQ(ASCIIToUTF16("male"), filled_forms[0].fields[0].value); |
| EXPECT_TRUE(filled_forms[0].fields[1].is_checked); |
| EXPECT_EQ(ASCIIToUTF16("female"), filled_forms[0].fields[1].value); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnFormsSeenTest) { |
| GURL frame_url; |
| content::SSLStatus ssl_status; |
| gfx::RectF bounding_box; |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBubbleMetric( |
| AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); |
| autocheckout_manager_->MaybeShowAutocheckoutBubble(frame_url, |
| ssl_status, |
| bounding_box); |
| EXPECT_TRUE(autocheckout_manager_->autocheckout_offered()); |
| // OnFormsSeen resets whether or not the bubble was shown. |
| autocheckout_manager_->OnFormsSeen(); |
| EXPECT_FALSE(autocheckout_manager_->autocheckout_offered()); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnClickFailedTest) { |
| OpenRequestAutocompleteDialog(); |
| |
| EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); |
| EXPECT_CALL( |
| autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_ADVANCE_ELEMENT)) |
| .Times(1); |
| autocheckout_manager_->OnClickFailed(MISSING_ADVANCE); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| HideRequestAutocompleteDialog(); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, MaybeShowAutocheckoutBubbleTest) { |
| GURL frame_url; |
| content::SSLStatus ssl_status; |
| gfx::RectF bounding_box; |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBubbleMetric( |
| AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); |
| // MaybeShowAutocheckoutBubble shows bubble if it has not been shown. |
| autocheckout_manager_->MaybeShowAutocheckoutBubble(frame_url, |
| ssl_status, |
| bounding_box); |
| EXPECT_TRUE(autocheckout_manager_->autocheckout_offered()); |
| EXPECT_TRUE(autofill_manager_delegate_->autocheckout_bubble_shown()); |
| |
| // Reset |autofill_manager_delegate_|. |
| HideRequestAutocompleteDialog(); |
| autofill_manager_delegate_->set_autocheckout_bubble_shown(false); |
| |
| // MaybeShowAutocheckoutBubble does nothing if the bubble was already shown |
| // for the current page. |
| autocheckout_manager_->MaybeShowAutocheckoutBubble(frame_url, |
| ssl_status, |
| bounding_box); |
| EXPECT_TRUE(autocheckout_manager_->autocheckout_offered()); |
| EXPECT_FALSE(autofill_manager_delegate_->autocheckout_bubble_shown()); |
| EXPECT_FALSE(autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataMissingMetaData) { |
| // Gettting no meta data after any autocheckout page is an error. |
| OpenRequestAutocompleteDialog(); |
| EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); |
| EXPECT_CALL( |
| autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING)) |
| .Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData( |
| scoped_ptr<AutocheckoutPageMetaData>()); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_EQ(0U, process()->sink().message_count()); |
| HideRequestAutocompleteDialog(); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataRepeatedStartPage) { |
| // Getting start page twice in a row is an error. |
| OpenRequestAutocompleteDialog(); |
| EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); |
| EXPECT_CALL( |
| autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_EQ(0U, process()->sink().message_count()); |
| HideRequestAutocompleteDialog(); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataRepeatedPage) { |
| // Repeating a page is an error. |
| OpenRequestAutocompleteDialog(); |
| // Go to second page. |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::DoubleEq(2.0/3.0))).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); |
| EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); |
| CheckFillFormsAndClickIpc(); |
| EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); |
| EXPECT_CALL( |
| autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_EQ(0U, process()->sink().message_count()); |
| HideRequestAutocompleteDialog(); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataNotInFlow) { |
| // Repeating a page is an error. |
| OpenRequestAutocompleteDialog(); |
| // Go to second page. |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::DoubleEq(2.0/3.0))).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); |
| EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); |
| CheckFillFormsAndClickIpc(); |
| EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); |
| EXPECT_CALL( |
| autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING)) |
| .Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateNotInFlowMetaData()); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_EQ(0U, process()->sink().message_count()); |
| HideRequestAutocompleteDialog(); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, |
| OnLoadedPageMetaDataShouldNotFillFormsIfNotInFlow) { |
| // If not in flow, OnLoadedPageMetaData does not fill forms. |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBubbleMetric( |
| AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); |
| // Go to second page. |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::_)).Times(0); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); |
| EXPECT_EQ(0U, process()->sink().message_count()); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, FullAutocheckoutFlow) { |
| // Test for progression through last page. |
| OpenRequestAutocompleteDialog(); |
| // Go to second page. |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::DoubleEq(2.0/3.0))).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); |
| EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); |
| CheckFillFormsAndClickIpc(); |
| // Go to third page. |
| EXPECT_CALL(*autofill_manager_delegate_, UpdateProgressBar(1)).Times(1); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_SUCCESS)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateEndOfFlowMetaData()); |
| CheckFillFormsAndClickIpc(); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_FALSE(autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| } |
| |
| TEST_F(AutocheckoutManagerTest, SinglePageFlow) { |
| // Test one page flow. |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_FALSE( |
| autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBubbleMetric( |
| AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); |
| autocheckout_manager_->OnLoadedPageMetaData(CreateOnePageFlowMetaData()); |
| // Simulate the user submitting some data via the requestAutocomplete UI. |
| autofill_manager_delegate_->SetUserSuppliedData( |
| FakeUserSubmittedFormStructure()); |
| GURL frame_url; |
| content::SSLStatus ssl_status; |
| EXPECT_CALL(*autofill_manager_delegate_, |
| UpdateProgressBar(testing::DoubleEq(1))).Times(1); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_STARTED)).Times(1); |
| EXPECT_CALL(autocheckout_manager_->metric_logger(), |
| LogAutocheckoutBuyFlowMetric( |
| AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_SUCCESS)).Times(1); |
| autocheckout_manager_->MaybeShowAutocheckoutDialog(frame_url, |
| ssl_status, |
| true); |
| CheckFillFormsAndClickIpc(); |
| EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); |
| EXPECT_FALSE(autofill_manager_delegate_->request_autocomplete_dialog_open()); |
| } |
| |
| } // namespace autofill |