Home | History | Annotate | Download | only in search
      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