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/browser/web_contents.h" 24 #include "content/public/browser/web_contents_observer.h" 25 #include "content/public/test/mock_render_process_host.h" 26 #include "ipc/ipc_message.h" 27 #include "ipc/ipc_test_sink.h" 28 #include "testing/gmock/include/gmock/gmock.h" 29 #include "url/gurl.h" 30 31 class MockInstantServiceObserver : public InstantServiceObserver { 32 public: 33 MOCK_METHOD0(DefaultSearchProviderChanged, void()); 34 MOCK_METHOD0(GoogleURLUpdated, void()); 35 }; 36 37 class MockWebContentsObserver : public content::WebContentsObserver { 38 public: 39 MOCK_METHOD1(WebContentsDestroyed, void(content::WebContents*)); 40 41 // Dumb override to make MSVC happy. 42 void Observe_(content::WebContents* contents) { 43 content::WebContentsObserver::Observe(contents); 44 } 45 46 protected: 47 friend class InstantServiceTest; 48 FRIEND_TEST_ALL_PREFIXES(InstantServiceTest, 49 DispatchDefaultSearchProviderChanged); 50 FRIEND_TEST_ALL_PREFIXES(InstantServiceTest, DispatchGoogleURLUpdated); 51 }; 52 53 class InstantServiceTest : public InstantUnitTestBase { 54 protected: 55 virtual void SetUp() OVERRIDE { 56 InstantUnitTestBase::SetUpWithoutCacheableNTP(); 57 58 instant_service_observer_.reset(new MockInstantServiceObserver()); 59 instant_service_->AddObserver(instant_service_observer_.get()); 60 61 instant_ntp_contents_observer_.reset(new MockWebContentsObserver()); 62 instant_ntp_contents_observer_->Observe_( 63 instant_service_->GetNTPContents()); 64 } 65 66 virtual void TearDown() OVERRIDE { 67 instant_service_->RemoveObserver(instant_service_observer_.get()); 68 instant_ntp_contents_observer_->Observe_(NULL); 69 InstantUnitTestBase::TearDown(); 70 } 71 72 InstantSearchPrerenderer* GetInstantSearchPrerenderer() { 73 return instant_service_->instant_search_prerenderer(); 74 } 75 76 scoped_ptr<MockInstantServiceObserver> instant_service_observer_; 77 scoped_ptr<MockWebContentsObserver> instant_ntp_contents_observer_; 78 }; 79 80 TEST_F(InstantServiceTest, DispatchDefaultSearchProviderChanged) { 81 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 82 .Times(1); 83 EXPECT_CALL(*instant_ntp_contents_observer_.get(), 84 WebContentsDestroyed(instant_service_->GetNTPContents())) 85 .Times(1); 86 87 GURL ntp_url = instant_service_->GetNTPContents()->GetURL(); 88 const std::string& new_base_url = "https://bar.com/"; 89 SetDefaultSearchProvider(new_base_url); 90 GURL new_ntp_url = instant_service_->GetNTPContents()->GetURL(); 91 EXPECT_NE(ntp_url, new_ntp_url); 92 EXPECT_TRUE(StartsWithASCII(new_ntp_url.spec(), new_base_url, true)); 93 } 94 95 TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) { 96 EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1); 97 EXPECT_CALL(*instant_ntp_contents_observer_.get(), 98 WebContentsDestroyed(instant_service_->GetNTPContents())) 99 .Times(1); 100 101 GURL ntp_url = instant_service_->GetNTPContents()->GetURL(); 102 const std::string& new_base_url = "https://www.google.es/"; 103 NotifyGoogleBaseURLUpdate(new_base_url); 104 GURL new_ntp_url = instant_service_->GetNTPContents()->GetURL(); 105 EXPECT_NE(ntp_url, new_ntp_url); 106 EXPECT_TRUE(StartsWithASCII(new_ntp_url.spec(), new_base_url, true)); 107 } 108 109 TEST_F(InstantServiceTest, SendsSearchURLsToRenderer) { 110 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 111 "Group1 use_cacheable_ntp:1")); 112 scoped_ptr<content::MockRenderProcessHost> rph( 113 new content::MockRenderProcessHost(profile())); 114 rph->sink().ClearMessages(); 115 instant_service_->Observe( 116 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 117 content::Source<content::MockRenderProcessHost>(rph.get()), 118 content::NotificationService::NoDetails()); 119 EXPECT_EQ(1U, rph->sink().message_count()); 120 const IPC::Message* msg = rph->sink().GetMessageAt(0); 121 ASSERT_TRUE(msg); 122 std::vector<GURL> search_urls; 123 GURL new_tab_page_url; 124 ChromeViewMsg_SetSearchURLs::Read(msg, &search_urls, &new_tab_page_url); 125 EXPECT_EQ(2U, search_urls.size()); 126 EXPECT_EQ("https://www.google.com/alt#quux=", search_urls[0].spec()); 127 EXPECT_EQ("https://www.google.com/url?bar=", search_urls[1].spec()); 128 EXPECT_EQ("https://www.google.com/newtab", new_tab_page_url.spec()); 129 } 130 131 TEST_F(InstantServiceTest, InstantSearchDisabled) { 132 // 'prefetch_results' flag is not enabled in field trials. Make sure 133 // InstantSearchPrerenderer is not initialized. 134 EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL), 135 GetInstantSearchPrerenderer()); 136 } 137 138 TEST_F(InstantServiceTest, 139 ResetInstantSearchPrerenderer_DefaultProviderChanged) { 140 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 141 "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1")); 142 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 143 .Times(2); 144 145 // Set a default search provider that doesn't support Instant. 146 TemplateURLData data; 147 data.SetURL("https://foobar.com/url?bar={searchTerms}"); 148 TemplateURL* template_url = new TemplateURL(profile(), data); 149 // Takes ownership of |template_url|. 150 template_url_service_->Add(template_url); 151 template_url_service_->SetDefaultSearchProvider(template_url); 152 153 EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL), 154 GetInstantSearchPrerenderer()); 155 156 // Set a default search provider that supports Instant and make sure 157 // InstantSearchPrerenderer is valid. 158 SetDefaultSearchProvider("https://google.com/"); 159 EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL), 160 GetInstantSearchPrerenderer()); 161 } 162 163 TEST_F(InstantServiceTest, ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) { 164 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 165 "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1")); 166 EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged()) 167 .Times(1); 168 EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1); 169 170 SetDefaultSearchProvider("https://google.com/"); 171 InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer(); 172 EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL), old_prerenderer); 173 174 const std::string& new_base_url = "https://www.google.es/"; 175 NotifyGoogleBaseURLUpdate(new_base_url); 176 EXPECT_NE(old_prerenderer, GetInstantSearchPrerenderer()); 177 } 178