1 // Copyright 2013 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 <string> 6 #include <vector> 7 8 #include "base/memory/scoped_ptr.h" 9 #include "base/metrics/field_trial.h" 10 #include "base/strings/string_util.h" 11 #include "chrome/browser/search/instant_service.h" 12 #include "chrome/browser/search/instant_service_observer.h" 13 #include "chrome/browser/search/instant_unittest_base.h" 14 #include "chrome/browser/search/search.h" 15 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser_window.h" 17 #include "chrome/browser/ui/host_desktop.h" 18 #include "chrome/browser/ui/search/instant_search_prerenderer.h" 19 #include "chrome/common/render_messages.h" 20 #include "components/variations/entropy_provider.h" 21 #include "content/public/browser/notification_service.h" 22 #include "content/public/browser/notification_types.h" 23 #include "content/public/test/mock_render_process_host.h" 24 #include "ipc/ipc_message.h" 25 #include "ipc/ipc_test_sink.h" 26 #include "testing/gmock/include/gmock/gmock.h" 27 #include "url/gurl.h" 28 29 class MockInstantServiceObserver : public InstantServiceObserver { 30 public: 31 MOCK_METHOD0(DefaultSearchProviderChanged, void()); 32 MOCK_METHOD1(OmniboxStartMarginChanged, void(int)); 33 }; 34 35 class InstantServiceTest : public InstantUnitTestBase { 36 protected: 37 virtual void SetUp() OVERRIDE { 38 InstantUnitTestBase::SetUp(); 39 40 instant_service_observer_.reset(new MockInstantServiceObserver()); 41 instant_service_->AddObserver(instant_service_observer_.get()); 42 } 43 44 virtual void TearDown() OVERRIDE { 45 instant_service_->RemoveObserver(instant_service_observer_.get()); 46 InstantUnitTestBase::TearDown(); 47 } 48 49 InstantSearchPrerenderer* GetInstantSearchPrerenderer() { 50 return instant_service_->instant_search_prerenderer(); 51 } 52 53 void UpdateOmniboxStartMargin(int start_margin) { 54 instant_service_->OnOmniboxStartMarginChanged(start_margin); 55 } 56 57 scoped_ptr<MockInstantServiceObserver> instant_service_observer_; 58 }; 59 60 class InstantServiceEnabledTest : public InstantServiceTest { 61 protected: 62 virtual void SetUp() OVERRIDE { 63 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 64 "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1")); 65 InstantServiceTest::SetUp(); 66 } 67 }; 68 69 TEST_F(InstantServiceEnabledTest, DispatchDefaultSearchProviderChanged) { 70 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 71 .Times(1); 72 73 const std::string new_base_url = "https://bar.com/"; 74 SetUserSelectedDefaultSearchProvider(new_base_url); 75 } 76 77 TEST_F(InstantServiceTest, DontDispatchGoogleURLUpdatedForNonGoogleURLs) { 78 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 79 .Times(1); 80 const std::string new_dsp_url = "https://bar.com/"; 81 SetUserSelectedDefaultSearchProvider(new_dsp_url); 82 testing::Mock::VerifyAndClearExpectations(instant_service_observer_.get()); 83 84 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 85 .Times(0); 86 const std::string new_base_url = "https://www.google.es/"; 87 NotifyGoogleBaseURLUpdate(new_base_url); 88 } 89 90 TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) { 91 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 92 .Times(1); 93 94 const std::string new_base_url = "https://www.google.es/"; 95 NotifyGoogleBaseURLUpdate(new_base_url); 96 } 97 98 TEST_F(InstantServiceEnabledTest, SendsSearchURLsToRenderer) { 99 scoped_ptr<content::MockRenderProcessHost> rph( 100 new content::MockRenderProcessHost(profile())); 101 rph->sink().ClearMessages(); 102 instant_service_->Observe( 103 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 104 content::Source<content::MockRenderProcessHost>(rph.get()), 105 content::NotificationService::NoDetails()); 106 EXPECT_EQ(1U, rph->sink().message_count()); 107 const IPC::Message* msg = rph->sink().GetMessageAt(0); 108 ASSERT_TRUE(msg); 109 ChromeViewMsg_SetSearchURLs::Param params; 110 ChromeViewMsg_SetSearchURLs::Read(msg, ¶ms); 111 std::vector<GURL> search_urls = params.a; 112 GURL new_tab_page_url = params.b; 113 EXPECT_EQ(2U, search_urls.size()); 114 EXPECT_EQ("https://www.google.com/alt#quux=", search_urls[0].spec()); 115 EXPECT_EQ("https://www.google.com/url?bar=", search_urls[1].spec()); 116 EXPECT_EQ("https://www.google.com/newtab", new_tab_page_url.spec()); 117 } 118 119 TEST_F(InstantServiceTest, InstantSearchDisabled) { 120 // 'prefetch_results' flag is not enabled in field trials. Make sure 121 // InstantSearchPrerenderer is not initialized. 122 EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL), 123 GetInstantSearchPrerenderer()); 124 } 125 126 TEST_F(InstantServiceEnabledTest, 127 ResetInstantSearchPrerenderer_DefaultProviderChanged) { 128 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 129 .Times(2); 130 131 // Set a default search provider that doesn't support Instant. 132 TemplateURLData data; 133 data.SetURL("https://foobar.com/url?bar={searchTerms}"); 134 TemplateURL* template_url = new TemplateURL(data); 135 // Takes ownership of |template_url|. 136 template_url_service_->Add(template_url); 137 template_url_service_->SetUserSelectedDefaultSearchProvider(template_url); 138 139 EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL), 140 GetInstantSearchPrerenderer()); 141 142 // Set a default search provider that supports Instant and make sure 143 // InstantSearchPrerenderer is valid. 144 SetUserSelectedDefaultSearchProvider("https://google.com/"); 145 EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL), 146 GetInstantSearchPrerenderer()); 147 } 148 149 TEST_F(InstantServiceEnabledTest, 150 ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) { 151 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 152 .Times(1); 153 154 InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer(); 155 EXPECT_TRUE(old_prerenderer != NULL); 156 157 const std::string new_base_url = "https://www.google.es/"; 158 NotifyGoogleBaseURLUpdate(new_base_url); 159 EXPECT_NE(old_prerenderer, GetInstantSearchPrerenderer()); 160 } 161 162 TEST_F(InstantServiceTest, OmniboxStartMarginChanged) { 163 int new_start_margin = 92; 164 EXPECT_CALL(*instant_service_observer_.get(), 165 OmniboxStartMarginChanged(new_start_margin)).Times(1); 166 UpdateOmniboxStartMargin(new_start_margin); 167 } 168