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.
5 #include "chrome/browser/ui/search/instant_page.h"
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"
27 class FakePageDelegate
: public InstantPage::Delegate
{
29 virtual ~FakePageDelegate() {
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
,
40 MOCK_METHOD5(NavigateToURL
,
41 void(const content::WebContents
* contents
,
43 content::PageTransition transition
,
44 WindowOpenDisposition disposition
,
45 bool is_search_type
));
50 class InstantPageTest
: public ChromeRenderViewHostTestHarness
{
52 virtual void SetUp() OVERRIDE
;
54 bool MessageWasSent(uint32 id
) {
55 return process()->sink().GetFirstMessageMatching(id
) != NULL
;
58 scoped_ptr
<InstantPage
> page
;
59 FakePageDelegate delegate
;
62 void InstantPageTest::SetUp() {
63 ChromeRenderViewHostTestHarness::SetUp();
64 SearchTabHelper::CreateForWebContents(web_contents());
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());
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))
86 SearchTabHelper::FromWebContents(web_contents())->
87 DetermineIfPageSupportsInstant();
88 EXPECT_TRUE(page
->supports_instant());
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());
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());
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))
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());
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());
144 EXPECT_CALL(delegate
, InstantSupportDetermined(web_contents(), true))
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();
152 SearchTabHelper::FromWebContents(web_contents())->InstantSupportChanged(true);
153 EXPECT_TRUE(page
->supports_instant());
156 TEST_F(InstantPageTest
, AppropriateMessagesSentToIncognitoPages
) {
157 page
.reset(new InstantPage(&delegate
, "", NULL
, true));
158 page
->SetContents(web_contents());
159 NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl
));
160 process()->sink().ClearMessages();
162 // Incognito pages should get these messages.
163 page
->sender()->SetOmniboxBounds(gfx::Rect());
164 EXPECT_TRUE(MessageWasSent(ChromeViewMsg_SearchBoxMarginChange::ID
));
166 // Incognito pages should not get any others.
167 page
->sender()->FocusChanged(
168 OMNIBOX_FOCUS_NONE
, OMNIBOX_FOCUS_CHANGE_EXPLICIT
);
169 EXPECT_FALSE(MessageWasSent(ChromeViewMsg_SearchBoxFocusChanged::ID
));
171 page
->sender()->SetInputInProgress(false);
172 EXPECT_FALSE(MessageWasSent(ChromeViewMsg_SearchBoxSetInputInProgress::ID
));