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 "chrome/browser/ui/search/instant_page.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "chrome/browser/ui/search/search_tab_helper.h"
     10 #include "chrome/common/chrome_switches.h"
     11 #include "chrome/common/render_messages.h"
     12 #include "chrome/common/url_constants.h"
     13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     14 #include "content/public/browser/navigation_controller.h"
     15 #include "content/public/browser/navigation_entry.h"
     16 #include "content/public/browser/web_contents.h"
     17 #include "content/public/test/mock_render_process_host.h"
     18 #include "ipc/ipc_test_sink.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "url/gurl.h"
     22 
     23 class Profile;
     24 
     25 namespace {
     26 
     27 class FakePageDelegate : public InstantPage::Delegate {
     28  public:
     29   virtual ~FakePageDelegate() {
     30   }
     31 
     32   MOCK_METHOD2(InstantSupportDetermined,
     33                void(const content::WebContents* contents,
     34                     bool supports_instant));
     35   MOCK_METHOD1(InstantPageRenderProcessGone,
     36                void(const content::WebContents* contents));
     37   MOCK_METHOD2(InstantPageAboutToNavigateMainFrame,
     38                void(const content::WebContents* contents,
     39                     const GURL& url));
     40   MOCK_METHOD5(NavigateToURL,
     41                void(const content::WebContents* contents,
     42                     const GURL& url,
     43                     content::PageTransition transition,
     44                     WindowOpenDisposition disposition,
     45                     bool is_search_type));
     46 };
     47 
     48 }  // namespace
     49 
     50 class InstantPageTest : public ChromeRenderViewHostTestHarness {
     51  public:
     52   virtual void SetUp() OVERRIDE;
     53 
     54   bool MessageWasSent(uint32 id) {
     55     return process()->sink().GetFirstMessageMatching(id) != NULL;
     56   }
     57 
     58   scoped_ptr<InstantPage> page;
     59   FakePageDelegate delegate;
     60 };
     61 
     62 void InstantPageTest::SetUp() {
     63   ChromeRenderViewHostTestHarness::SetUp();
     64   SearchTabHelper::CreateForWebContents(web_contents());
     65 }
     66 
     67 TEST_F(InstantPageTest, IsLocal) {
     68   page.reset(new InstantPage(&delegate, "", NULL, false));
     69   EXPECT_FALSE(page->supports_instant());
     70   EXPECT_FALSE(page->IsLocal());
     71   page->SetContents(web_contents());
     72   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
     73   EXPECT_TRUE(page->IsLocal());
     74   NavigateAndCommit(GURL("http://example.com"));
     75   EXPECT_FALSE(page->IsLocal());
     76 }
     77 
     78 TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_Local) {
     79   page.reset(new InstantPage(&delegate, "", NULL, false));
     80   EXPECT_FALSE(page->supports_instant());
     81   page->SetContents(web_contents());
     82   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
     83   EXPECT_TRUE(page->IsLocal());
     84   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), true))
     85       .Times(1);
     86   SearchTabHelper::FromWebContents(web_contents())->
     87       DetermineIfPageSupportsInstant();
     88   EXPECT_TRUE(page->supports_instant());
     89 }
     90 
     91 TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_NonLocal) {
     92   page.reset(new InstantPage(&delegate, "", NULL, false));
     93   EXPECT_FALSE(page->supports_instant());
     94   page->SetContents(web_contents());
     95   NavigateAndCommit(GURL("chrome-search://foo/bar"));
     96   EXPECT_FALSE(page->IsLocal());
     97   process()->sink().ClearMessages();
     98   SearchTabHelper::FromWebContents(web_contents())->
     99       DetermineIfPageSupportsInstant();
    100   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    101       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    102   ASSERT_TRUE(message != NULL);
    103   EXPECT_EQ(web_contents()->GetRoutingID(), message->routing_id());
    104 }
    105 
    106 TEST_F(InstantPageTest, PageURLDoesntBelongToInstantRenderer) {
    107   page.reset(new InstantPage(&delegate, "", NULL, false));
    108   EXPECT_FALSE(page->supports_instant());
    109   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
    110   page->SetContents(web_contents());
    111 
    112   // Navigate to a page URL that doesn't belong to Instant renderer.
    113   // SearchTabHelper::DeterminerIfPageSupportsInstant() should return
    114   // immediately without dispatching any message to the renderer.
    115   NavigateAndCommit(GURL("http://www.example.com"));
    116   EXPECT_FALSE(page->IsLocal());
    117   process()->sink().ClearMessages();
    118   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), false))
    119       .Times(1);
    120 
    121   SearchTabHelper::FromWebContents(web_contents())->
    122       DetermineIfPageSupportsInstant();
    123   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    124       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    125   ASSERT_TRUE(message == NULL);
    126   EXPECT_FALSE(page->supports_instant());
    127 }
    128 
    129 // Test to verify that ChromeViewMsg_DetermineIfPageSupportsInstant message
    130 // reply handler updates the instant support state in InstantPage.
    131 TEST_F(InstantPageTest, PageSupportsInstant) {
    132   page.reset(new InstantPage(&delegate, "", NULL, false));
    133   EXPECT_FALSE(page->supports_instant());
    134   page->SetContents(web_contents());
    135   NavigateAndCommit(GURL("chrome-search://foo/bar"));
    136   process()->sink().ClearMessages();
    137   SearchTabHelper::FromWebContents(web_contents())->
    138       DetermineIfPageSupportsInstant();
    139   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    140       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    141   ASSERT_TRUE(message != NULL);
    142   EXPECT_EQ(web_contents()->GetRoutingID(), message->routing_id());
    143 
    144   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), true))
    145       .Times(1);
    146 
    147   // Assume the page supports instant. Invoke the message reply handler to make
    148   // sure the InstantPage is notified about the instant support state.
    149   const content::NavigationEntry* entry =
    150       web_contents()->GetController().GetLastCommittedEntry();
    151   EXPECT_TRUE(entry);
    152   SearchTabHelper::FromWebContents(web_contents())->InstantSupportChanged(true);
    153   EXPECT_TRUE(page->supports_instant());
    154 }
    155