Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / search / search_tab_helper_unittest.cc
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/search_tab_helper.h"
6
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/search/search.h"
11 #include "chrome/browser/search_engines/template_url_service.h"
12 #include "chrome/browser/search_engines/template_url_service_factory.h"
13 #include "chrome/browser/signin/fake_signin_manager.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/browser/ui/search/search_ipc_router.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/ntp_logging_events.h"
19 #include "chrome/common/omnibox_focus_state.h"
20 #include "chrome/common/render_messages.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/browser_with_test_window_test.h"
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "chrome/test/base/ui_test_utils.h"
26 #include "content/public/browser/navigation_controller.h"
27 #include "content/public/browser/navigation_entry.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/test/mock_render_process_host.h"
30 #include "grit/generated_resources.h"
31 #include "ipc/ipc_message.h"
32 #include "ipc/ipc_test_sink.h"
33 #include "net/base/net_errors.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36 #include "ui/base/l10n/l10n_util.h"
37 #include "url/gurl.h"
38
39 namespace {
40
41 class MockSearchIPCRouterDelegate : public SearchIPCRouter::Delegate {
42  public:
43   virtual ~MockSearchIPCRouterDelegate() {}
44
45   MOCK_METHOD1(OnInstantSupportDetermined, void(bool supports_instant));
46   MOCK_METHOD1(OnSetVoiceSearchSupport, void(bool supports_voice_search));
47   MOCK_METHOD1(FocusOmnibox, void(OmniboxFocusState state));
48   MOCK_METHOD3(NavigateToURL, void(const GURL&, WindowOpenDisposition, bool));
49   MOCK_METHOD1(OnDeleteMostVisitedItem, void(const GURL& url));
50   MOCK_METHOD1(OnUndoMostVisitedDeletion, void(const GURL& url));
51   MOCK_METHOD0(OnUndoAllMostVisitedDeletions, void());
52   MOCK_METHOD1(OnLogEvent, void(NTPLoggingEventType event));
53   MOCK_METHOD2(OnLogMostVisitedImpression,
54                void(int position, const base::string16& provider));
55   MOCK_METHOD2(OnLogMostVisitedNavigation,
56                void(int position, const base::string16& provider));
57   MOCK_METHOD1(PasteIntoOmnibox, void(const base::string16&));
58   MOCK_METHOD1(OnChromeIdentityCheck, void(const base::string16& identity));
59 };
60
61 }  // namespace
62
63 class SearchTabHelperTest : public ChromeRenderViewHostTestHarness {
64  public:
65   virtual void SetUp() {
66     ChromeRenderViewHostTestHarness::SetUp();
67     SearchTabHelper::CreateForWebContents(web_contents());
68   }
69
70   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
71     TestingProfile::Builder builder;
72     builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
73                               FakeSigninManagerBase::Build);
74     return builder.Build().release();
75   }
76
77   // Creates a sign-in manager for tests.  If |username| is not empty, the
78   // testing profile of the WebContents will be connected to the given account.
79   void CreateSigninManager(const std::string& username) {
80     SigninManagerBase* signin_manager = static_cast<SigninManagerBase*>(
81         SigninManagerFactory::GetForProfile(profile()));
82
83     if (!username.empty()) {
84       ASSERT_TRUE(signin_manager);
85       signin_manager->SetAuthenticatedUsername(username);
86     }
87   }
88
89   bool MessageWasSent(uint32 id) {
90     return process()->sink().GetFirstMessageMatching(id) != NULL;
91   }
92
93   MockSearchIPCRouterDelegate* mock_delegate() { return &delegate_; }
94
95  private:
96   MockSearchIPCRouterDelegate delegate_;
97 };
98
99 TEST_F(SearchTabHelperTest, DetermineIfPageSupportsInstant_Local) {
100   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
101   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(true)).Times(0);
102
103   SearchTabHelper* search_tab_helper =
104       SearchTabHelper::FromWebContents(web_contents());
105   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
106   search_tab_helper->ipc_router().set_delegate(mock_delegate());
107   search_tab_helper->DetermineIfPageSupportsInstant();
108 }
109
110 TEST_F(SearchTabHelperTest, DetermineIfPageSupportsInstant_NonLocal) {
111   NavigateAndCommit(GURL("chrome-search://foo/bar"));
112   process()->sink().ClearMessages();
113   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(true)).Times(1);
114
115   SearchTabHelper* search_tab_helper =
116       SearchTabHelper::FromWebContents(web_contents());
117   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
118   search_tab_helper->ipc_router().set_delegate(mock_delegate());
119   search_tab_helper->DetermineIfPageSupportsInstant();
120   ASSERT_TRUE(MessageWasSent(ChromeViewMsg_DetermineIfPageSupportsInstant::ID));
121
122   scoped_ptr<IPC::Message> response(
123       new ChromeViewHostMsg_InstantSupportDetermined(
124           web_contents()->GetRoutingID(),
125           web_contents()->GetController().GetVisibleEntry()->GetPageID(),
126           true));
127   search_tab_helper->ipc_router().OnMessageReceived(*response);
128 }
129
130 TEST_F(SearchTabHelperTest, PageURLDoesntBelongToInstantRenderer) {
131   // Navigate to a page URL that doesn't belong to Instant renderer.
132   // SearchTabHelper::DeterminerIfPageSupportsInstant() should return
133   // immediately without dispatching any message to the renderer.
134   NavigateAndCommit(GURL("http://www.example.com"));
135   process()->sink().ClearMessages();
136   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(false)).Times(0);
137
138   SearchTabHelper* search_tab_helper =
139       SearchTabHelper::FromWebContents(web_contents());
140   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
141   search_tab_helper->ipc_router().set_delegate(mock_delegate());
142   search_tab_helper->DetermineIfPageSupportsInstant();
143   ASSERT_FALSE(MessageWasSent(
144       ChromeViewMsg_DetermineIfPageSupportsInstant::ID));
145 }
146
147 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckMatch) {
148   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
149   CreateSigninManager(std::string("foo@bar.com"));
150   SearchTabHelper* search_tab_helper =
151       SearchTabHelper::FromWebContents(web_contents());
152   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
153
154   const base::string16 test_identity = base::ASCIIToUTF16("foo@bar.com");
155   search_tab_helper->OnChromeIdentityCheck(test_identity);
156
157   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
158       ChromeViewMsg_ChromeIdentityCheckResult::ID);
159   ASSERT_TRUE(message != NULL);
160
161   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
162   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
163   EXPECT_EQ(test_identity, params.a);
164   ASSERT_TRUE(params.b);
165 }
166
167 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckMismatch) {
168   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
169   CreateSigninManager(std::string("foo@bar.com"));
170   SearchTabHelper* search_tab_helper =
171       SearchTabHelper::FromWebContents(web_contents());
172   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
173
174   const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com");
175   search_tab_helper->OnChromeIdentityCheck(test_identity);
176
177   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
178       ChromeViewMsg_ChromeIdentityCheckResult::ID);
179   ASSERT_TRUE(message != NULL);
180
181   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
182   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
183   EXPECT_EQ(test_identity, params.a);
184   ASSERT_FALSE(params.b);
185 }
186
187 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMatch) {
188   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
189   // This test does not sign in.
190   SearchTabHelper* search_tab_helper =
191       SearchTabHelper::FromWebContents(web_contents());
192   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
193
194   const base::string16 test_identity;
195   search_tab_helper->OnChromeIdentityCheck(test_identity);
196
197   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
198       ChromeViewMsg_ChromeIdentityCheckResult::ID);
199   ASSERT_TRUE(message != NULL);
200
201   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
202   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
203   EXPECT_EQ(test_identity, params.a);
204   ASSERT_TRUE(params.b);
205 }
206
207 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMismatch) {
208   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
209   // This test does not sign in.
210   SearchTabHelper* search_tab_helper =
211       SearchTabHelper::FromWebContents(web_contents());
212   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
213
214   const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com");
215   search_tab_helper->OnChromeIdentityCheck(test_identity);
216
217   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
218       ChromeViewMsg_ChromeIdentityCheckResult::ID);
219   ASSERT_TRUE(message != NULL);
220
221   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
222   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
223   EXPECT_EQ(test_identity, params.a);
224   ASSERT_FALSE(params.b);
225 }
226
227 class TabTitleObserver : public content::WebContentsObserver {
228  public:
229   explicit TabTitleObserver(content::WebContents* contents)
230       : WebContentsObserver(contents) {}
231
232   base::string16 title_on_start() { return title_on_start_; }
233   base::string16 title_on_commit() { return title_on_commit_; }
234
235  private:
236   virtual void DidStartProvisionalLoadForFrame(
237       int64 /* frame_id */,
238       int64 /* parent_frame_id */,
239       bool /* is_main_frame */,
240       const GURL& /* validated_url */,
241       bool /* is_error_page */,
242       bool /* is_iframe_srcdoc */,
243       content::RenderViewHost* /* render_view_host */) OVERRIDE {
244     title_on_start_ = web_contents()->GetTitle();
245   }
246
247   virtual void DidNavigateMainFrame(
248       const content::LoadCommittedDetails& /* details */,
249       const content::FrameNavigateParams& /* params */) OVERRIDE {
250     title_on_commit_ = web_contents()->GetTitle();
251   }
252
253   base::string16 title_on_start_;
254   base::string16 title_on_commit_;
255 };
256
257 TEST_F(SearchTabHelperTest, TitleIsSetForNTP) {
258   TabTitleObserver title_observer(web_contents());
259   NavigateAndCommit(GURL(chrome::kChromeUINewTabURL));
260   const base::string16 title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
261   EXPECT_EQ(title, title_observer.title_on_start());
262   EXPECT_EQ(title, title_observer.title_on_commit());
263   EXPECT_EQ(title, web_contents()->GetTitle());
264 }
265
266 class SearchTabHelperWindowTest : public BrowserWithTestWindowTest {
267  protected:
268   virtual void SetUp() OVERRIDE {
269     BrowserWithTestWindowTest::SetUp();
270     TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
271         profile(), &TemplateURLServiceFactory::BuildInstanceFor);
272     TemplateURLService* template_url_service =
273         TemplateURLServiceFactory::GetForProfile(profile());
274     ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
275
276     TemplateURLData data;
277     data.SetURL("http://foo.com/url?bar={searchTerms}");
278     data.instant_url = "http://foo.com/instant?"
279         "{google:omniboxStartMarginParameter}{google:forceInstantResults}"
280         "foo=foo#foo=foo&strk";
281     data.new_tab_url = std::string("https://foo.com/newtab?strk");
282     data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}");
283     data.search_terms_replacement_key = "strk";
284
285     TemplateURL* template_url = new TemplateURL(profile(), data);
286     template_url_service->Add(template_url);
287     template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
288   }
289 };
290
291 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailRedirectNTPToLocal) {
292   AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
293   content::WebContents* contents =
294         browser()->tab_strip_model()->GetWebContentsAt(0);
295   content::NavigationController* controller = &contents->GetController();
296
297   SearchTabHelper* search_tab_helper =
298       SearchTabHelper::FromWebContents(contents);
299   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
300
301   // A failed provisional load of a cacheable NTP should be redirected to local
302   // NTP.
303   const GURL cacheableNTPURL = chrome::GetNewTabPageURL(profile());
304   search_tab_helper->DidFailProvisionalLoad(1, base::string16(), true,
305       cacheableNTPURL, 1, base::string16(), NULL);
306   CommitPendingLoad(controller);
307   EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
308                  controller->GetLastCommittedEntry()->GetURL());
309 }
310
311 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailDontRedirectIfAborted) {
312   AddTab(browser(), GURL("chrome://blank"));
313   content::WebContents* contents =
314         browser()->tab_strip_model()->GetWebContentsAt(0);
315   content::NavigationController* controller = &contents->GetController();
316
317   SearchTabHelper* search_tab_helper =
318       SearchTabHelper::FromWebContents(contents);
319   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
320
321   // A failed provisional load of a cacheable NTP should be redirected to local
322   // NTP.
323   const GURL cacheableNTPURL = chrome::GetNewTabPageURL(profile());
324   search_tab_helper->DidFailProvisionalLoad(1, base::string16(), true,
325       cacheableNTPURL, net::ERR_ABORTED, base::string16(), NULL);
326   CommitPendingLoad(controller);
327   EXPECT_EQ(GURL("chrome://blank"),
328                  controller->GetLastCommittedEntry()->GetURL());
329 }
330
331 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailDontRedirectNonNTP) {
332   AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
333   content::WebContents* contents =
334         browser()->tab_strip_model()->GetWebContentsAt(0);
335   content::NavigationController* controller = &contents->GetController();
336
337   SearchTabHelper* search_tab_helper =
338       SearchTabHelper::FromWebContents(contents);
339   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
340
341   // Any other web page shouldn't be redirected when provisional load fails.
342   search_tab_helper->DidFailProvisionalLoad(1, base::string16(), true,
343       GURL("http://www.example.com"), 1, base::string16(), NULL);
344   CommitPendingLoad(controller);
345   EXPECT_NE(GURL(chrome::kChromeSearchLocalNtpUrl),
346                  controller->GetLastCommittedEntry()->GetURL());
347 }