Upstream version 10.39.225.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/metrics/field_trial.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/prerender/prerender_manager.h"
12 #include "chrome/browser/prerender/prerender_manager_factory.h"
13 #include "chrome/browser/search/instant_unittest_base.h"
14 #include "chrome/browser/search/search.h"
15 #include "chrome/browser/search_engines/template_url_service_factory.h"
16 #include "chrome/browser/signin/fake_signin_manager.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/browser/sync/profile_sync_service.h"
19 #include "chrome/browser/sync/profile_sync_service_factory.h"
20 #include "chrome/browser/sync/profile_sync_service_mock.h"
21 #include "chrome/browser/ui/search/search_ipc_router.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/common/ntp_logging_events.h"
25 #include "chrome/common/omnibox_focus_state.h"
26 #include "chrome/common/render_messages.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/grit/generated_resources.h"
29 #include "chrome/test/base/browser_with_test_window_test.h"
30 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
31 #include "chrome/test/base/testing_profile.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "components/search_engines/template_url_service.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/test/mock_render_process_host.h"
38 #include "ipc/ipc_message.h"
39 #include "ipc/ipc_test_sink.h"
40 #include "net/base/net_errors.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43 #include "ui/base/l10n/l10n_util.h"
44 #include "url/gurl.h"
45
46 class OmniboxView;
47
48 using testing::Return;
49
50 namespace {
51
52 class MockSearchIPCRouterDelegate : public SearchIPCRouter::Delegate {
53  public:
54   virtual ~MockSearchIPCRouterDelegate() {}
55
56   MOCK_METHOD1(OnInstantSupportDetermined, void(bool supports_instant));
57   MOCK_METHOD1(OnSetVoiceSearchSupport, void(bool supports_voice_search));
58   MOCK_METHOD1(FocusOmnibox, void(OmniboxFocusState state));
59   MOCK_METHOD3(NavigateToURL, void(const GURL&, WindowOpenDisposition, bool));
60   MOCK_METHOD1(OnDeleteMostVisitedItem, void(const GURL& url));
61   MOCK_METHOD1(OnUndoMostVisitedDeletion, void(const GURL& url));
62   MOCK_METHOD0(OnUndoAllMostVisitedDeletions, void());
63   MOCK_METHOD1(OnLogEvent, void(NTPLoggingEventType event));
64   MOCK_METHOD2(OnLogMostVisitedImpression,
65                void(int position, const base::string16& provider));
66   MOCK_METHOD2(OnLogMostVisitedNavigation,
67                void(int position, const base::string16& provider));
68   MOCK_METHOD1(PasteIntoOmnibox, void(const base::string16&));
69   MOCK_METHOD1(OnChromeIdentityCheck, void(const base::string16& identity));
70 };
71
72 }  // namespace
73
74 class SearchTabHelperTest : public ChromeRenderViewHostTestHarness {
75  public:
76   virtual void SetUp() {
77     ChromeRenderViewHostTestHarness::SetUp();
78     SearchTabHelper::CreateForWebContents(web_contents());
79   }
80
81   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
82     TestingProfile::Builder builder;
83     builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
84                               FakeSigninManagerBase::Build);
85     builder.AddTestingFactory(
86         ProfileSyncServiceFactory::GetInstance(),
87         ProfileSyncServiceMock::BuildMockProfileSyncService);
88     return builder.Build().release();
89   }
90
91   // Creates a sign-in manager for tests.  If |username| is not empty, the
92   // testing profile of the WebContents will be connected to the given account.
93   // The account can be configured to |sync_history| or not.
94   void CreateSigninManager(const std::string& username, bool sync_history) {
95     SigninManagerBase* signin_manager = static_cast<SigninManagerBase*>(
96         SigninManagerFactory::GetForProfile(profile()));
97
98     if (!username.empty()) {
99       ASSERT_TRUE(signin_manager);
100       signin_manager->SetAuthenticatedUsername(username);
101     }
102
103     ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>(
104         ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile()));
105
106     EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true));
107     syncer::ModelTypeSet result;
108     if (sync_history) {
109       result.Put(syncer::HISTORY_DELETE_DIRECTIVES);
110     }
111     EXPECT_CALL(*sync_service, GetActiveDataTypes())
112         .WillRepeatedly(Return(result));
113   }
114
115   bool MessageWasSent(uint32 id) {
116     return process()->sink().GetFirstMessageMatching(id) != NULL;
117   }
118
119   MockSearchIPCRouterDelegate* mock_delegate() { return &delegate_; }
120
121  private:
122   MockSearchIPCRouterDelegate delegate_;
123 };
124
125 TEST_F(SearchTabHelperTest, DetermineIfPageSupportsInstant_Local) {
126   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
127   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(true)).Times(0);
128
129   SearchTabHelper* search_tab_helper =
130       SearchTabHelper::FromWebContents(web_contents());
131   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
132   search_tab_helper->ipc_router().set_delegate_for_testing(mock_delegate());
133   search_tab_helper->DetermineIfPageSupportsInstant();
134 }
135
136 TEST_F(SearchTabHelperTest, DetermineIfPageSupportsInstant_NonLocal) {
137   NavigateAndCommit(GURL("chrome-search://foo/bar"));
138   process()->sink().ClearMessages();
139   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(true)).Times(1);
140
141   SearchTabHelper* search_tab_helper =
142       SearchTabHelper::FromWebContents(web_contents());
143   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
144   search_tab_helper->ipc_router().set_delegate_for_testing(mock_delegate());
145   search_tab_helper->DetermineIfPageSupportsInstant();
146   ASSERT_TRUE(MessageWasSent(ChromeViewMsg_DetermineIfPageSupportsInstant::ID));
147
148   scoped_ptr<IPC::Message> response(
149       new ChromeViewHostMsg_InstantSupportDetermined(
150           web_contents()->GetRoutingID(),
151           search_tab_helper->ipc_router().page_seq_no_for_testing(),
152           true));
153   search_tab_helper->ipc_router().OnMessageReceived(*response);
154 }
155
156 TEST_F(SearchTabHelperTest, PageURLDoesntBelongToInstantRenderer) {
157   // Navigate to a page URL that doesn't belong to Instant renderer.
158   // SearchTabHelper::DeterminerIfPageSupportsInstant() should return
159   // immediately without dispatching any message to the renderer.
160   NavigateAndCommit(GURL("http://www.example.com"));
161   process()->sink().ClearMessages();
162   EXPECT_CALL(*mock_delegate(), OnInstantSupportDetermined(false)).Times(0);
163
164   SearchTabHelper* search_tab_helper =
165       SearchTabHelper::FromWebContents(web_contents());
166   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
167   search_tab_helper->ipc_router().set_delegate_for_testing(mock_delegate());
168   search_tab_helper->DetermineIfPageSupportsInstant();
169   ASSERT_FALSE(MessageWasSent(
170       ChromeViewMsg_DetermineIfPageSupportsInstant::ID));
171 }
172
173 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckMatch) {
174   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
175   CreateSigninManager(std::string("foo@bar.com"), true);
176   SearchTabHelper* search_tab_helper =
177       SearchTabHelper::FromWebContents(web_contents());
178   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
179
180   const base::string16 test_identity = base::ASCIIToUTF16("foo@bar.com");
181   search_tab_helper->OnChromeIdentityCheck(test_identity);
182
183   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
184       ChromeViewMsg_ChromeIdentityCheckResult::ID);
185   ASSERT_TRUE(message != NULL);
186
187   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
188   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
189   EXPECT_EQ(test_identity, params.a);
190   ASSERT_TRUE(params.b);
191 }
192
193 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckMismatch) {
194   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
195   CreateSigninManager(std::string("foo@bar.com"), true);
196   SearchTabHelper* search_tab_helper =
197       SearchTabHelper::FromWebContents(web_contents());
198   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
199
200   const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com");
201   search_tab_helper->OnChromeIdentityCheck(test_identity);
202
203   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
204       ChromeViewMsg_ChromeIdentityCheckResult::ID);
205   ASSERT_TRUE(message != NULL);
206
207   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
208   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
209   EXPECT_EQ(test_identity, params.a);
210   ASSERT_FALSE(params.b);
211 }
212
213 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMatch) {
214   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
215   // This test does not sign in.
216   ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>(
217       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile()));
218   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(false));
219   SearchTabHelper* search_tab_helper =
220       SearchTabHelper::FromWebContents(web_contents());
221   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
222
223   const base::string16 test_identity;
224   search_tab_helper->OnChromeIdentityCheck(test_identity);
225
226   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
227       ChromeViewMsg_ChromeIdentityCheckResult::ID);
228   ASSERT_TRUE(message != NULL);
229
230   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
231   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
232   EXPECT_EQ(test_identity, params.a);
233   ASSERT_FALSE(params.b);
234 }
235
236 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckSignedOutMismatch) {
237   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
238   // This test does not sign in.
239   ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>(
240       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile()));
241   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(false));
242   SearchTabHelper* search_tab_helper =
243       SearchTabHelper::FromWebContents(web_contents());
244   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
245
246   const base::string16 test_identity = base::ASCIIToUTF16("bar@foo.com");
247   search_tab_helper->OnChromeIdentityCheck(test_identity);
248
249   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
250       ChromeViewMsg_ChromeIdentityCheckResult::ID);
251   ASSERT_TRUE(message != NULL);
252
253   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
254   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
255   EXPECT_EQ(test_identity, params.a);
256   ASSERT_FALSE(params.b);
257 }
258
259 TEST_F(SearchTabHelperTest, OnChromeIdentityCheckMatchNotSyncing) {
260   NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
261   CreateSigninManager(std::string("foo@bar.com"), false);
262   SearchTabHelper* search_tab_helper =
263       SearchTabHelper::FromWebContents(web_contents());
264   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
265
266   const base::string16 test_identity = base::ASCIIToUTF16("foo@bar.com");
267   search_tab_helper->OnChromeIdentityCheck(test_identity);
268
269   const IPC::Message* message = process()->sink().GetUniqueMessageMatching(
270       ChromeViewMsg_ChromeIdentityCheckResult::ID);
271   ASSERT_TRUE(message != NULL);
272
273   ChromeViewMsg_ChromeIdentityCheckResult::Param params;
274   ChromeViewMsg_ChromeIdentityCheckResult::Read(message, &params);
275   EXPECT_EQ(test_identity, params.a);
276   ASSERT_FALSE(params.b);
277 }
278
279 class TabTitleObserver : public content::WebContentsObserver {
280  public:
281   explicit TabTitleObserver(content::WebContents* contents)
282       : WebContentsObserver(contents) {}
283
284   base::string16 title_on_start() { return title_on_start_; }
285   base::string16 title_on_commit() { return title_on_commit_; }
286
287  private:
288   virtual void DidStartProvisionalLoadForFrame(
289       content::RenderFrameHost* /* render_frame_host */,
290       const GURL& /* validated_url */,
291       bool /* is_error_page */,
292       bool /* is_iframe_srcdoc */) OVERRIDE {
293     title_on_start_ = web_contents()->GetTitle();
294   }
295
296   virtual void DidNavigateMainFrame(
297       const content::LoadCommittedDetails& /* details */,
298       const content::FrameNavigateParams& /* params */) OVERRIDE {
299     title_on_commit_ = web_contents()->GetTitle();
300   }
301
302   base::string16 title_on_start_;
303   base::string16 title_on_commit_;
304 };
305
306 TEST_F(SearchTabHelperTest, TitleIsSetForNTP) {
307   TabTitleObserver title_observer(web_contents());
308   NavigateAndCommit(GURL(chrome::kChromeUINewTabURL));
309   const base::string16 title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
310   EXPECT_EQ(title, title_observer.title_on_start());
311   EXPECT_EQ(title, title_observer.title_on_commit());
312   EXPECT_EQ(title, web_contents()->GetTitle());
313 }
314
315 class SearchTabHelperWindowTest : public BrowserWithTestWindowTest {
316  protected:
317   virtual void SetUp() OVERRIDE {
318     BrowserWithTestWindowTest::SetUp();
319     TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
320         profile(), &TemplateURLServiceFactory::BuildInstanceFor);
321     TemplateURLService* template_url_service =
322         TemplateURLServiceFactory::GetForProfile(profile());
323     ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
324
325     TemplateURLData data;
326     data.SetURL("http://foo.com/url?bar={searchTerms}");
327     data.instant_url = "http://foo.com/instant?"
328         "{google:omniboxStartMarginParameter}{google:forceInstantResults}"
329         "foo=foo#foo=foo&strk";
330     data.new_tab_url = std::string("https://foo.com/newtab?strk");
331     data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}");
332     data.search_terms_replacement_key = "strk";
333
334     TemplateURL* template_url = new TemplateURL(data);
335     template_url_service->Add(template_url);
336     template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
337   }
338 };
339
340 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailRedirectNTPToLocal) {
341   AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
342   content::WebContents* contents =
343         browser()->tab_strip_model()->GetWebContentsAt(0);
344   content::NavigationController* controller = &contents->GetController();
345
346   SearchTabHelper* search_tab_helper =
347       SearchTabHelper::FromWebContents(contents);
348   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
349
350   // A failed provisional load of a cacheable NTP should be redirected to local
351   // NTP.
352   const GURL cacheableNTPURL = chrome::GetNewTabPageURL(profile());
353   search_tab_helper->DidFailProvisionalLoad(
354       contents->GetMainFrame(), cacheableNTPURL, 1, base::string16());
355   CommitPendingLoad(controller);
356   EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
357                  controller->GetLastCommittedEntry()->GetURL());
358 }
359
360 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailDontRedirectIfAborted) {
361   AddTab(browser(), GURL("chrome://blank"));
362   content::WebContents* contents =
363         browser()->tab_strip_model()->GetWebContentsAt(0);
364   content::NavigationController* controller = &contents->GetController();
365
366   SearchTabHelper* search_tab_helper =
367       SearchTabHelper::FromWebContents(contents);
368   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
369
370   // A failed provisional load of a cacheable NTP should be redirected to local
371   // NTP.
372   const GURL cacheableNTPURL = chrome::GetNewTabPageURL(profile());
373   search_tab_helper->DidFailProvisionalLoad(contents->GetMainFrame(),
374                                             cacheableNTPURL,
375                                             net::ERR_ABORTED,
376                                             base::string16());
377   CommitPendingLoad(controller);
378   EXPECT_EQ(GURL("chrome://blank"),
379                  controller->GetLastCommittedEntry()->GetURL());
380 }
381
382 TEST_F(SearchTabHelperWindowTest, OnProvisionalLoadFailDontRedirectNonNTP) {
383   AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
384   content::WebContents* contents =
385         browser()->tab_strip_model()->GetWebContentsAt(0);
386   content::NavigationController* controller = &contents->GetController();
387
388   SearchTabHelper* search_tab_helper =
389       SearchTabHelper::FromWebContents(contents);
390   ASSERT_NE(static_cast<SearchTabHelper*>(NULL), search_tab_helper);
391
392   // Any other web page shouldn't be redirected when provisional load fails.
393   search_tab_helper->DidFailProvisionalLoad(contents->GetMainFrame(),
394                                             GURL("http://www.example.com"),
395                                             1,
396                                             base::string16());
397   CommitPendingLoad(controller);
398   EXPECT_NE(GURL(chrome::kChromeSearchLocalNtpUrl),
399                  controller->GetLastCommittedEntry()->GetURL());
400 }
401
402 class SearchTabHelperPrerenderTest : public InstantUnitTestBase {
403  public:
404   virtual ~SearchTabHelperPrerenderTest() {}
405
406  protected:
407   virtual void SetUp() OVERRIDE {
408     ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
409         "EmbeddedSearch",
410         "Group1 espv:89 prefetch_results:1 "
411         "prerender_instant_url_on_omnibox_focus:1"));
412     InstantUnitTestBase::SetUp();
413
414     AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
415     prerender::PrerenderManagerFactory::GetForProfile(browser()->profile())->
416         OnCookieStoreLoaded();
417     SearchTabHelper::FromWebContents(web_contents())->set_omnibox_has_focus_fn(
418         omnibox_has_focus);
419     SearchTabHelperPrerenderTest::omnibox_has_focus_ = true;
420   }
421
422   content::WebContents* web_contents() {
423     return browser()->tab_strip_model()->GetActiveWebContents();
424   }
425
426   bool IsInstantURLMarkedForPrerendering() {
427     GURL instant_url(chrome::GetSearchResultPrefetchBaseURL(profile()));
428     prerender::PrerenderManager* prerender_manager =
429         prerender::PrerenderManagerFactory::GetForProfile(profile());
430     return prerender_manager->HasPrerenderedUrl(instant_url, web_contents());
431   }
432
433   static bool omnibox_has_focus(OmniboxView* omnibox) {
434     return omnibox_has_focus_;
435   }
436
437   static bool omnibox_has_focus_;
438 };
439
440 bool SearchTabHelperPrerenderTest::omnibox_has_focus_ = true;
441
442 TEST_F(SearchTabHelperPrerenderTest, OnOmniboxFocusPrerenderInstantURL) {
443   SearchTabHelper* search_tab_helper =
444       SearchTabHelper::FromWebContents(web_contents());
445   search_tab_helper->OmniboxFocusChanged(OMNIBOX_FOCUS_VISIBLE,
446                                          OMNIBOX_FOCUS_CHANGE_EXPLICIT);
447   ASSERT_TRUE(IsInstantURLMarkedForPrerendering());
448   search_tab_helper->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE,
449                                          OMNIBOX_FOCUS_CHANGE_EXPLICIT);
450   ASSERT_FALSE(IsInstantURLMarkedForPrerendering());
451 }
452
453 TEST_F(SearchTabHelperPrerenderTest, OnTabActivatedPrerenderInstantURL) {
454   SearchTabHelper* search_tab_helper =
455       SearchTabHelper::FromWebContents(web_contents());
456   search_tab_helper->OnTabActivated();
457   ASSERT_TRUE(IsInstantURLMarkedForPrerendering());
458 }
459
460 TEST_F(SearchTabHelperPrerenderTest,
461     OnTabActivatedNoPrerenderIfOmniboxBlurred) {
462   SearchTabHelperPrerenderTest::omnibox_has_focus_ = false;
463   SearchTabHelper* search_tab_helper =
464       SearchTabHelper::FromWebContents(web_contents());
465   search_tab_helper->OnTabActivated();
466   ASSERT_FALSE(IsInstantURLMarkedForPrerendering());
467 }