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   MOCK_METHOD1(InstantPageLoadFailed, void(content::WebContents* contents));
     47 };
     48 
     49 }  // namespace
     50 
     51 class InstantPageTest : public ChromeRenderViewHostTestHarness {
     52  public:
     53   virtual void SetUp() OVERRIDE;
     54 
     55   bool MessageWasSent(uint32 id) {
     56     return process()->sink().GetFirstMessageMatching(id) != NULL;
     57   }
     58 
     59   scoped_ptr<InstantPage> page;
     60   FakePageDelegate delegate;
     61 };
     62 
     63 void InstantPageTest::SetUp() {
     64   ChromeRenderViewHostTestHarness::SetUp();
     65   SearchTabHelper::CreateForWebContents(web_contents());
     66 }
     67 
     68 TEST_F(InstantPageTest, IsLocal) {
     69   page.reset(new InstantPage(&delegate, "", NULL, false));
     70   EXPECT_FALSE(page->supports_instant());
     71   EXPECT_FALSE(page->IsLocal());
     72   page->SetContents(web_contents());
     73   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
     74   EXPECT_TRUE(page->IsLocal());
     75   NavigateAndCommit(GURL("http://example.com"));
     76   EXPECT_FALSE(page->IsLocal());
     77 }
     78 
     79 TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_Local) {
     80   page.reset(new InstantPage(&delegate, "", NULL, false));
     81   EXPECT_FALSE(page->supports_instant());
     82   page->SetContents(web_contents());
     83   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
     84   EXPECT_TRUE(page->IsLocal());
     85   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), true))
     86       .Times(1);
     87   SearchTabHelper::FromWebContents(web_contents())->
     88       DetermineIfPageSupportsInstant();
     89   EXPECT_TRUE(page->supports_instant());
     90 }
     91 
     92 TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_NonLocal) {
     93   page.reset(new InstantPage(&delegate, "", NULL, false));
     94   EXPECT_FALSE(page->supports_instant());
     95   page->SetContents(web_contents());
     96   NavigateAndCommit(GURL("chrome-search://foo/bar"));
     97   EXPECT_FALSE(page->IsLocal());
     98   process()->sink().ClearMessages();
     99   SearchTabHelper::FromWebContents(web_contents())->
    100       DetermineIfPageSupportsInstant();
    101   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    102       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    103   ASSERT_TRUE(message != NULL);
    104   EXPECT_EQ(web_contents()->GetRoutingID(), message->routing_id());
    105 }
    106 
    107 TEST_F(InstantPageTest, PageURLDoesntBelongToInstantRenderer) {
    108   page.reset(new InstantPage(&delegate, "", NULL, false));
    109   EXPECT_FALSE(page->supports_instant());
    110   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
    111   page->SetContents(web_contents());
    112 
    113   // Navigate to a page URL that doesn't belong to Instant renderer.
    114   // SearchTabHelper::DeterminerIfPageSupportsInstant() should return
    115   // immediately without dispatching any message to the renderer.
    116   NavigateAndCommit(GURL("http://www.example.com"));
    117   EXPECT_FALSE(page->IsLocal());
    118   process()->sink().ClearMessages();
    119   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), false))
    120       .Times(1);
    121 
    122   SearchTabHelper::FromWebContents(web_contents())->
    123       DetermineIfPageSupportsInstant();
    124   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    125       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    126   ASSERT_TRUE(message == NULL);
    127   EXPECT_FALSE(page->supports_instant());
    128 }
    129 
    130 // Test to verify that ChromeViewMsg_DetermineIfPageSupportsInstant message
    131 // reply handler updates the instant support state in InstantPage.
    132 TEST_F(InstantPageTest, PageSupportsInstant) {
    133   page.reset(new InstantPage(&delegate, "", NULL, false));
    134   EXPECT_FALSE(page->supports_instant());
    135   page->SetContents(web_contents());
    136   NavigateAndCommit(GURL("chrome-search://foo/bar"));
    137   process()->sink().ClearMessages();
    138   SearchTabHelper::FromWebContents(web_contents())->
    139       DetermineIfPageSupportsInstant();
    140   const IPC::Message* message = process()->sink().GetFirstMessageMatching(
    141       ChromeViewMsg_DetermineIfPageSupportsInstant::ID);
    142   ASSERT_TRUE(message != NULL);
    143   EXPECT_EQ(web_contents()->GetRoutingID(), message->routing_id());
    144 
    145   EXPECT_CALL(delegate, InstantSupportDetermined(web_contents(), true))
    146       .Times(1);
    147 
    148   // Assume the page supports instant. Invoke the message reply handler to make
    149   // sure the InstantPage is notified about the instant support state.
    150   const content::NavigationEntry* entry =
    151       web_contents()->GetController().GetLastCommittedEntry();
    152   EXPECT_TRUE(entry);
    153   SearchTabHelper::FromWebContents(web_contents())->InstantSupportChanged(true);
    154   EXPECT_TRUE(page->supports_instant());
    155 }
    156 
    157 TEST_F(InstantPageTest, AppropriateMessagesSentToIncognitoPages) {
    158   page.reset(new InstantPage(&delegate, "", NULL, true));
    159   page->SetContents(web_contents());
    160   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
    161   process()->sink().ClearMessages();
    162 
    163   // Incognito pages should get these messages.
    164   page->sender()->SetOmniboxBounds(gfx::Rect());
    165   EXPECT_TRUE(MessageWasSent(ChromeViewMsg_SearchBoxMarginChange::ID));
    166 
    167   // Incognito pages should not get any others.
    168   page->sender()->FocusChanged(
    169       OMNIBOX_FOCUS_NONE, OMNIBOX_FOCUS_CHANGE_EXPLICIT);
    170   EXPECT_FALSE(MessageWasSent(ChromeViewMsg_SearchBoxFocusChanged::ID));
    171 
    172   page->sender()->SetInputInProgress(false);
    173   EXPECT_FALSE(MessageWasSent(ChromeViewMsg_SearchBoxSetInputInProgress::ID));
    174 }
    175