| // Copyright 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 "chrome/browser/ui/search/search_tab_helper.h" |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <string> |
| #include <tuple> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/signin/fake_signin_manager_builder.h" |
| #include "chrome/browser/signin/identity_manager_factory.h" |
| #include "chrome/browser/signin/signin_manager_factory.h" |
| #include "chrome/browser/sync/profile_sync_service_factory.h" |
| #include "chrome/browser/sync/profile_sync_test_util.h" |
| #include "chrome/browser/ui/search/search_ipc_router.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/common/render_messages.h" |
| #include "chrome/common/search/mock_embedded_search_client.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/test/base/browser_with_test_window_test.h" |
| #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/browser_sync/profile_sync_service.h" |
| #include "components/omnibox/common/omnibox_focus_state.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/mock_render_process_host.h" |
| #include "ipc/ipc_message.h" |
| #include "ipc/ipc_test_sink.h" |
| #include "net/base/net_errors.h" |
| #include "services/identity/public/cpp/identity_test_utils.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "url/gurl.h" |
| |
| class OmniboxView; |
| |
| using testing::Eq; |
| using testing::Return; |
| using testing::_; |
| |
| namespace { |
| |
| class MockSearchIPCRouterDelegate : public SearchIPCRouter::Delegate { |
| public: |
| virtual ~MockSearchIPCRouterDelegate() {} |
| |
| MOCK_METHOD1(FocusOmnibox, void(bool focus)); |
| MOCK_METHOD1(OnDeleteMostVisitedItem, void(const GURL& url)); |
| MOCK_METHOD1(OnUndoMostVisitedDeletion, void(const GURL& url)); |
| MOCK_METHOD0(OnUndoAllMostVisitedDeletions, void()); |
| MOCK_METHOD2(OnAddCustomLink, |
| bool(const GURL& url, const std::string& title)); |
| MOCK_METHOD3(OnUpdateCustomLink, |
| bool(const GURL& url, |
| const GURL& new_url, |
| const std::string& new_title)); |
| MOCK_METHOD1(OnDeleteCustomLink, bool(const GURL& url)); |
| MOCK_METHOD0(OnUndoCustomLinkAction, void()); |
| MOCK_METHOD0(OnResetCustomLinks, void()); |
| MOCK_METHOD2( |
| OnDoesUrlResolve, |
| void(const GURL& url, |
| chrome::mojom::EmbeddedSearch::DoesUrlResolveCallback callback)); |
| MOCK_METHOD2(OnLogEvent, void(NTPLoggingEventType event, |
| base::TimeDelta time)); |
| MOCK_METHOD1(OnLogMostVisitedImpression, |
| void(const ntp_tiles::NTPTileImpression& impression)); |
| MOCK_METHOD1(OnLogMostVisitedNavigation, |
| void(const ntp_tiles::NTPTileImpression& impression)); |
| MOCK_METHOD1(PasteIntoOmnibox, void(const base::string16&)); |
| MOCK_METHOD1(ChromeIdentityCheck, bool(const base::string16& identity)); |
| MOCK_METHOD0(HistorySyncCheck, bool()); |
| MOCK_METHOD1(OnSetCustomBackgroundURL, void(const GURL& url)); |
| MOCK_METHOD4(OnSetCustomBackgroundURLWithAttributions, |
| void(const GURL& background_url, |
| const std::string& attribution_line_1, |
| const std::string& attribution_line_2, |
| const GURL& action_url)); |
| MOCK_METHOD0(OnSelectLocalBackgroundImage, void()); |
| }; |
| |
| class MockEmbeddedSearchClientFactory |
| : public SearchIPCRouter::EmbeddedSearchClientFactory { |
| public: |
| MOCK_METHOD0(GetEmbeddedSearchClient, |
| chrome::mojom::EmbeddedSearchClient*(void)); |
| }; |
| |
| } // namespace |
| |
| class SearchTabHelperTest : public ChromeRenderViewHostTestHarness { |
| public: |
| SearchTabHelperTest() {} |
| |
| void SetUp() override { |
| ChromeRenderViewHostTestHarness::SetUp(); |
| SearchTabHelper::CreateForWebContents(web_contents()); |
| auto* search_tab = SearchTabHelper::FromWebContents(web_contents()); |
| auto factory = std::make_unique<MockEmbeddedSearchClientFactory>(); |
| ON_CALL(*factory, GetEmbeddedSearchClient()) |
| .WillByDefault(Return(&mock_embedded_search_client_)); |
| search_tab->ipc_router_for_testing() |
| .set_embedded_search_client_factory_for_testing(std::move(factory)); |
| } |
| |
| content::BrowserContext* CreateBrowserContext() override { |
| TestingProfile::Builder builder; |
| builder.AddTestingFactory( |
| SigninManagerFactory::GetInstance(), |
| base::BindRepeating(&BuildFakeSigninManagerForTesting)); |
| builder.AddTestingFactory( |
| ProfileSyncServiceFactory::GetInstance(), |
| base::BindRepeating(&BuildMockProfileSyncService)); |
| return builder.Build().release(); |
| } |
| |
| // Associates |email| with profile as the primary account. |email| |
| // should not be empty. |
| void SetUpAccount(const std::string& email) { |
| ASSERT_FALSE(email.empty()); |
| identity::SetPrimaryAccount( |
| SigninManagerFactory::GetForProfile(profile()), |
| IdentityManagerFactory::GetForProfile(profile()), email); |
| } |
| |
| // Configure the account to |sync_history| or not. |
| void SetHistorySync(bool sync_history) { |
| browser_sync::ProfileSyncServiceMock* sync_service = |
| static_cast<browser_sync::ProfileSyncServiceMock*>( |
| ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile())); |
| |
| syncer::ModelTypeSet result; |
| if (sync_history) { |
| result.Put(syncer::HISTORY_DELETE_DIRECTIVES); |
| } |
| EXPECT_CALL(*sync_service, GetPreferredDataTypes()) |
| .WillRepeatedly(Return(result)); |
| } |
| |
| MockSearchIPCRouterDelegate* mock_delegate() { return &delegate_; } |
| |
| MockEmbeddedSearchClient* mock_embedded_search_client() { |
| return &mock_embedded_search_client_; |
| } |
| |
| private: |
| MockSearchIPCRouterDelegate delegate_; |
| MockEmbeddedSearchClient mock_embedded_search_client_; |
| }; |
| |
| TEST_F(SearchTabHelperTest, ChromeIdentityCheckMatch) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetUpAccount("foo@bar.com"); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| const base::string16 test_identity = base::ASCIIToUTF16("foo@bar.com"); |
| EXPECT_TRUE(search_tab_helper->ChromeIdentityCheck(test_identity)); |
| } |
| |
| TEST_F(SearchTabHelperTest, ChromeIdentityCheckMatchSlightlyDifferentGmail) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetUpAccount("foobar123@gmail.com"); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| // For gmail, canonicalization is done so that email addresses have a |
| // standard form. |
| const base::string16 test_identity = |
| base::ASCIIToUTF16("Foo.Bar.123@gmail.com"); |
| EXPECT_TRUE(search_tab_helper->ChromeIdentityCheck(test_identity)); |
| } |
| |
| TEST_F(SearchTabHelperTest, ChromeIdentityCheckMatchSlightlyDifferentGmail2) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetUpAccount("chrome.user.7FOREVER"); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| // For gmail/googlemail, canonicalization is done so that email addresses have |
| // a standard form. |
| const base::string16 test_identity = |
| base::ASCIIToUTF16("chromeuser7forever@googlemail.com"); |
| EXPECT_TRUE(search_tab_helper->ChromeIdentityCheck(test_identity)); |
| } |
| |
| TEST_F(SearchTabHelperTest, ChromeIdentityCheckMismatch) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetUpAccount("foo@bar.com"); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com"); |
| EXPECT_FALSE(search_tab_helper->ChromeIdentityCheck(test_identity)); |
| } |
| |
| TEST_F(SearchTabHelperTest, ChromeIdentityCheckSignedOutMismatch) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| // This test does not sign in. |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com"); |
| EXPECT_FALSE(search_tab_helper->ChromeIdentityCheck(test_identity)); |
| } |
| |
| TEST_F(SearchTabHelperTest, HistorySyncCheckSyncing) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetHistorySync(true); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| EXPECT_TRUE(search_tab_helper->HistorySyncCheck()); |
| } |
| |
| TEST_F(SearchTabHelperTest, HistorySyncCheckNotSyncing) { |
| NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl)); |
| SetHistorySync(false); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| EXPECT_FALSE(search_tab_helper->HistorySyncCheck()); |
| } |
| |
| TEST_F(SearchTabHelperTest, FileSelectedUpdatesLastSelectedDirectory) { |
| NavigateAndCommit(GURL(chrome::kChromeUINewTabURL)); |
| SearchTabHelper* search_tab_helper = |
| SearchTabHelper::FromWebContents(web_contents()); |
| ASSERT_NE(nullptr, search_tab_helper); |
| |
| base::FilePath filePath = |
| base::FilePath::FromUTF8Unsafe("a/b/c/Picture/kitten.png"); |
| search_tab_helper->FileSelected(filePath, 0, {}); |
| Profile* profile = search_tab_helper->profile(); |
| EXPECT_EQ(filePath.DirName(), profile->last_selected_directory()); |
| } |
| |
| TEST_F(SearchTabHelperTest, TitleIsSetForNTP) { |
| NavigateAndCommit(GURL(chrome::kChromeUINewTabURL)); |
| EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE), |
| web_contents()->GetTitle()); |
| } |