Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / browser / search / search_unittest.cc
blob0307b3cd4998a486e7be7cd4bac16c14ca484739
1 // Copyright (c) 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 "base/command_line.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/metrics/histogram_base.h"
8 #include "base/metrics/histogram_samples.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/search/instant_service.h"
12 #include "chrome/browser/search/instant_service_factory.h"
13 #include "chrome/browser/search/search.h"
14 #include "chrome/browser/search_engines/template_url_service_factory.h"
15 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h"
20 #include "chrome/test/base/browser_with_test_window_test.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "components/google/core/browser/google_switches.h"
23 #include "components/search/search.h"
24 #include "components/search_engines/search_engines_switches.h"
25 #include "components/search_engines/template_url_service.h"
26 #include "components/variations/entropy_provider.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/site_instance.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/renderer_preferences.h"
32 #include "url/gurl.h"
34 #if defined(ENABLE_SUPERVISED_USERS)
35 #include "chrome/browser/supervised_user/supervised_user_service.h"
36 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
37 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
38 #endif
40 namespace chrome {
42 class SearchTest : public BrowserWithTestWindowTest {
43 protected:
44 void SetUp() override {
45 BrowserWithTestWindowTest::SetUp();
46 field_trial_list_.reset(new base::FieldTrialList(
47 new metrics::SHA1EntropyProvider("42")));
48 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
49 profile(), &TemplateURLServiceFactory::BuildInstanceFor);
50 TemplateURLService* template_url_service =
51 TemplateURLServiceFactory::GetForProfile(profile());
52 ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
53 SetSearchProvider(true, false);
56 virtual void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url) {
57 TemplateURLService* template_url_service =
58 TemplateURLServiceFactory::GetForProfile(profile());
59 TemplateURLData data;
60 data.SetURL("http://foo.com/url?bar={searchTerms}");
61 data.instant_url = "http://foo.com/instant?"
62 "{google:forceInstantResults}foo=foo#foo=foo&strk";
63 if (set_ntp_url) {
64 data.new_tab_url = (insecure_ntp_url ? "http" : "https") +
65 std::string("://foo.com/newtab?strk");
67 data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}");
68 data.search_terms_replacement_key = "strk";
70 TemplateURL* template_url = new TemplateURL(data);
71 // Takes ownership of |template_url|.
72 template_url_service->Add(template_url);
73 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
76 // Build an Instant URL with or without a valid search terms replacement key
77 // as per |has_search_term_replacement_key|. Set that URL as the instant URL
78 // for the default search provider.
79 void SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key) {
80 TemplateURLService* template_url_service =
81 TemplateURLServiceFactory::GetForProfile(profile());
83 static const char kInstantURLWithStrk[] =
84 "http://foo.com/instant?foo=foo#foo=foo&strk";
85 static const char kInstantURLNoStrk[] =
86 "http://foo.com/instant?foo=foo#foo=foo";
88 TemplateURLData data;
89 data.SetURL("http://foo.com/url?bar={searchTerms}");
90 data.instant_url = (has_search_term_replacement_key ?
91 kInstantURLWithStrk : kInstantURLNoStrk);
92 data.search_terms_replacement_key = "strk";
94 TemplateURL* template_url = new TemplateURL(data);
95 // Takes ownership of |template_url|.
96 template_url_service->Add(template_url);
97 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
100 bool InInstantProcess(const content::WebContents* contents) {
101 InstantService* instant_service =
102 InstantServiceFactory::GetForProfile(profile());
103 return instant_service->IsInstantProcess(
104 contents->GetRenderProcessHost()->GetID());
107 scoped_ptr<base::FieldTrialList> field_trial_list_;
110 struct SearchTestCase {
111 const char* url;
112 bool expected_result;
113 const char* comment;
116 TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) {
117 EnableQueryExtractionForTesting();
119 const SearchTestCase kTestCases[] = {
120 {chrome::kChromeSearchLocalNtpUrl, true, ""},
121 {"https://foo.com/instant?strk", true, ""},
122 {"https://foo.com/instant#strk", true, ""},
123 {"https://foo.com/instant?strk=0", true, ""},
124 {"https://foo.com/url?strk", true, ""},
125 {"https://foo.com/alt?strk", true, ""},
126 {"http://foo.com/instant", false, "Non-HTTPS"},
127 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
128 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
129 {"https://foo.com/instant", false, "No search terms replacement"},
130 {"https://foo.com/?strk", false, "Non-exact path"},
133 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
134 const SearchTestCase& test = kTestCases[i];
135 EXPECT_EQ(test.expected_result,
136 ShouldAssignURLToInstantRenderer(GURL(test.url), profile()))
137 << test.url << " " << test.comment;
141 TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabledNotOnSRP) {
142 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
143 "EmbeddedSearch", "Group1 espv:2 suppress_on_srp:1"));
145 const SearchTestCase kTestCases[] = {
146 {chrome::kChromeSearchLocalNtpUrl, true, ""},
147 {"https://foo.com/instant?strk", true, ""},
148 {"https://foo.com/instant#strk", true, ""},
149 {"https://foo.com/instant?strk=0", true, ""},
150 {"https://foo.com/url?strk", false, "Disabled on SRP"},
151 {"https://foo.com/alt?strk", false, "Disabled ON SRP"},
152 {"http://foo.com/instant", false, "Non-HTTPS"},
153 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
154 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
155 {"https://foo.com/instant", false, "No search terms replacement"},
156 {"https://foo.com/?strk", false, "Non-exact path"},
159 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
160 const SearchTestCase& test = kTestCases[i];
161 EXPECT_EQ(test.expected_result,
162 ShouldAssignURLToInstantRenderer(GURL(test.url), profile()))
163 << test.url << " " << test.comment;
167 TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) {
168 EnableQueryExtractionForTesting();
170 const SearchTestCase kTestCases[] = {
171 {"chrome-search://local-ntp", true, "Local NTP"},
172 {"chrome-search://remote-ntp", true, "Remote NTP"},
173 {"invalid-scheme://local-ntp", false, "Invalid Local NTP URL"},
174 {"invalid-scheme://online-ntp", false, "Invalid Online NTP URL"},
175 {"chrome-search://foo.com", false, "Search result page"},
176 {"https://foo.com/instant?strk", false, ""},
177 {"https://foo.com/instant#strk", false, ""},
178 {"https://foo.com/instant?strk=0", false, ""},
179 {"https://foo.com/url?strk", false, ""},
180 {"https://foo.com/alt?strk", false, ""},
181 {"http://foo.com/instant", false, "Non-HTTPS"},
182 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
183 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
184 {"https://foo.com/instant", false, "No search terms replacement"},
185 {"https://foo.com/?strk", false, "Non-exact path"},
188 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
189 const SearchTestCase& test = kTestCases[i];
190 EXPECT_EQ(test.expected_result,
191 ShouldUseProcessPerSiteForInstantURL(GURL(test.url), profile()))
192 << test.url << " " << test.comment;
196 // Each test case represents a navigation to |start_url| followed by a
197 // navigation to |end_url|. We will check whether each navigation lands in an
198 // Instant process, and also whether the navigation from start to end re-uses
199 // the same SiteInstance (and hence the same RenderViewHost, etc.).
200 const struct ProcessIsolationTestCase {
201 const char* description;
202 const char* start_url;
203 bool start_in_instant_process;
204 const char* end_url;
205 bool end_in_instant_process;
206 bool same_site_instance;
207 } kProcessIsolationTestCases[] = {
208 {"Local NTP -> SRP",
209 "chrome-search://local-ntp", true,
210 "https://foo.com/url?strk", true, false },
211 {"Local NTP -> Regular",
212 "chrome-search://local-ntp", true,
213 "https://foo.com/other", false, false },
214 {"Remote NTP -> SRP",
215 "https://foo.com/newtab?strk", true,
216 "https://foo.com/url?strk", true, false },
217 {"Remote NTP -> Regular",
218 "https://foo.com/newtab?strk", true,
219 "https://foo.com/other", false, false },
220 {"SRP -> SRP",
221 "https://foo.com/url?strk", true,
222 "https://foo.com/url?strk", true, true },
223 {"SRP -> Regular",
224 "https://foo.com/url?strk", true,
225 "https://foo.com/other", false, false },
226 {"Regular -> SRP",
227 "https://foo.com/other", false,
228 "https://foo.com/url?strk", true, false },
231 TEST_F(SearchTest, ProcessIsolation) {
232 EnableQueryExtractionForTesting();
234 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) {
235 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
236 AddTab(browser(), GURL("chrome://blank"));
237 const content::WebContents* contents =
238 browser()->tab_strip_model()->GetActiveWebContents();
240 // Navigate to start URL.
241 NavigateAndCommitActiveTab(GURL(test.start_url));
242 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents))
243 << test.description;
245 // Save state.
246 const scoped_refptr<content::SiteInstance> start_site_instance =
247 contents->GetSiteInstance();
248 const content::RenderProcessHost* start_rph =
249 contents->GetRenderProcessHost();
250 const content::RenderViewHost* start_rvh =
251 contents->GetRenderViewHost();
253 // Navigate to end URL.
254 NavigateAndCommitActiveTab(GURL(test.end_url));
255 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents))
256 << test.description;
258 EXPECT_EQ(test.same_site_instance,
259 start_site_instance.get() == contents->GetSiteInstance())
260 << test.description;
261 EXPECT_EQ(test.same_site_instance,
262 start_rvh == contents->GetRenderViewHost())
263 << test.description;
264 EXPECT_EQ(test.same_site_instance,
265 start_rph == contents->GetRenderProcessHost())
266 << test.description;
270 TEST_F(SearchTest, ProcessIsolation_RendererInitiated) {
271 EnableQueryExtractionForTesting();
273 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) {
274 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
275 AddTab(browser(), GURL("chrome://blank"));
276 content::WebContents* contents =
277 browser()->tab_strip_model()->GetActiveWebContents();
279 // Navigate to start URL.
280 NavigateAndCommitActiveTab(GURL(test.start_url));
281 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents))
282 << test.description;
284 // Save state.
285 const scoped_refptr<content::SiteInstance> start_site_instance =
286 contents->GetSiteInstance();
287 const content::RenderProcessHost* start_rph =
288 contents->GetRenderProcessHost();
289 const content::RenderViewHost* start_rvh =
290 contents->GetRenderViewHost();
292 // Navigate to end URL via a renderer-initiated navigation.
293 content::NavigationController* controller = &contents->GetController();
294 content::NavigationController::LoadURLParams load_params(
295 GURL(test.end_url));
296 load_params.is_renderer_initiated = true;
297 load_params.transition_type = ui::PAGE_TRANSITION_LINK;
299 controller->LoadURLWithParams(load_params);
300 CommitPendingLoad(controller);
301 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents))
302 << test.description;
304 EXPECT_EQ(test.same_site_instance,
305 start_site_instance.get() == contents->GetSiteInstance())
306 << test.description;
307 EXPECT_EQ(test.same_site_instance,
308 start_rvh == contents->GetRenderViewHost())
309 << test.description;
310 EXPECT_EQ(test.same_site_instance,
311 start_rph == contents->GetRenderProcessHost())
312 << test.description;
316 const SearchTestCase kInstantNTPTestCases[] = {
317 {"https://foo.com/instant?strk", false, "Valid Instant URL"},
318 {"https://foo.com/instant#strk", false, "Valid Instant URL"},
319 {"https://foo.com/url?strk", false, "Valid search URL"},
320 {"https://foo.com/url#strk", false, "Valid search URL"},
321 {"https://foo.com/alt?strk", false, "Valid alternative URL"},
322 {"https://foo.com/alt#strk", false, "Valid alternative URL"},
323 {"https://foo.com/url?strk&bar=", false, "No query terms"},
324 {"https://foo.com/url?strk&q=abc", false, "No query terms key"},
325 {"https://foo.com/url?strk#bar=abc", false, "Query terms key in ref"},
326 {"https://foo.com/url?strk&bar=abc", false, "Has query terms"},
327 {"http://foo.com/instant?strk=1", false, "Insecure URL"},
328 {"https://foo.com/instant", false, "No search term replacement"},
329 {"chrome://blank/", false, "Chrome scheme"},
330 {"chrome-search://foo", false, "Chrome-search scheme"},
331 {"https://bar.com/instant?strk=1", false, "Random non-search page"},
332 {chrome::kChromeSearchLocalNtpUrl, true, "Local new tab page"},
333 {"https://foo.com/newtab?strk", true, "New tab URL"},
334 {"http://foo.com/newtab?strk", false, "Insecure New tab URL"},
337 TEST_F(SearchTest, InstantNTPExtendedEnabled) {
338 EnableQueryExtractionForTesting();
339 AddTab(browser(), GURL("chrome://blank"));
340 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) {
341 const SearchTestCase& test = kInstantNTPTestCases[i];
342 NavigateAndCommitActiveTab(GURL(test.url));
343 const content::WebContents* contents =
344 browser()->tab_strip_model()->GetWebContentsAt(0);
345 EXPECT_EQ(test.expected_result, IsInstantNTP(contents))
346 << test.url << " " << test.comment;
350 TEST_F(SearchTest, InstantNTPCustomNavigationEntry) {
351 EnableQueryExtractionForTesting();
352 AddTab(browser(), GURL("chrome://blank"));
353 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) {
354 const SearchTestCase& test = kInstantNTPTestCases[i];
355 NavigateAndCommitActiveTab(GURL(test.url));
356 content::WebContents* contents =
357 browser()->tab_strip_model()->GetWebContentsAt(0);
358 content::NavigationController& controller = contents->GetController();
359 controller.SetTransientEntry(
360 controller.CreateNavigationEntry(GURL("chrome://blank"),
361 content::Referrer(),
362 ui::PAGE_TRANSITION_LINK,
363 false,
364 std::string(),
365 contents->GetBrowserContext()));
366 // The active entry is chrome://blank and not an NTP.
367 EXPECT_FALSE(IsInstantNTP(contents));
368 EXPECT_EQ(test.expected_result,
369 NavEntryIsInstantNTP(contents,
370 controller.GetLastCommittedEntry()))
371 << test.url << " " << test.comment;
375 TEST_F(SearchTest, InstantCacheableNTPNavigationEntry) {
376 AddTab(browser(), GURL("chrome://blank"));
377 content::WebContents* contents =
378 browser()->tab_strip_model()->GetWebContentsAt(0);
379 content::NavigationController& controller = contents->GetController();
380 // Local NTP.
381 NavigateAndCommitActiveTab(GURL(chrome::kChromeSearchLocalNtpUrl));
382 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
383 controller.GetLastCommittedEntry()));
384 // Instant page is not cacheable NTP.
385 NavigateAndCommitActiveTab(GetInstantURL(profile(), false));
386 EXPECT_FALSE(NavEntryIsInstantNTP(contents,
387 controller.GetLastCommittedEntry()));
388 // Test Cacheable NTP
389 NavigateAndCommitActiveTab(chrome::GetNewTabPageURL(profile()));
390 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
391 controller.GetLastCommittedEntry()));
394 TEST_F(SearchTest, InstantCacheableNTPNavigationEntryNewProfile) {
395 SetSearchProvider(false, false);
396 AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
397 content::WebContents* contents =
398 browser()->tab_strip_model()->GetWebContentsAt(0);
399 content::NavigationController& controller = contents->GetController();
400 // Test virtual url chrome://newtab for first NTP of a new profile
401 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
402 controller.GetLastCommittedEntry()));
403 // The new_tab_url gets set after the first NTP is visible.
404 SetSearchProvider(true, false);
405 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
406 controller.GetLastCommittedEntry()));
409 TEST_F(SearchTest, NoRewriteInIncognito) {
410 profile()->ForceIncognito(true);
411 EXPECT_EQ(GURL(), chrome::GetNewTabPageURL(profile()));
412 GURL new_tab_url(chrome::kChromeUINewTabURL);
413 EXPECT_FALSE(HandleNewTabURLRewrite(&new_tab_url, profile()));
414 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), new_tab_url);
417 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsInsecure) {
418 // Set an insecure new tab page URL and verify that it's ignored.
419 SetSearchProvider(true, true);
420 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
421 chrome::GetNewTabPageURL(profile()));
422 GURL new_tab_url(chrome::kChromeUINewTabURL);
423 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
424 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
427 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsNotSet) {
428 // Set an insecure new tab page URL and verify that it's ignored.
429 SetSearchProvider(false, true);
430 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
431 chrome::GetNewTabPageURL(profile()));
432 GURL new_tab_url(chrome::kChromeUINewTabURL);
433 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
434 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
437 #if defined(ENABLE_SUPERVISED_USERS)
438 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsBlockedForSupervisedUser) {
439 // Block access to foo.com in the URL filter.
440 SupervisedUserService* supervised_user_service =
441 SupervisedUserServiceFactory::GetForProfile(profile());
442 SupervisedUserURLFilter* url_filter =
443 supervised_user_service->GetURLFilterForUIThread();
444 std::map<std::string, bool> hosts;
445 hosts["foo.com"] = false;
446 url_filter->SetManualHosts(&hosts);
448 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
449 chrome::GetNewTabPageURL(profile()));
450 GURL new_tab_url(chrome::kChromeUINewTabURL);
451 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
452 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
453 EXPECT_EQ(GURL(), GetInstantURL(profile(), false));
455 #endif
457 TEST_F(SearchTest, GetInstantURL) {
458 // No Instant URL because "strk" is missing.
459 SetDefaultInstantTemplateUrl(false);
460 EXPECT_EQ(GURL(), GetInstantURL(profile(), false));
462 // Set an Instant URL with a valid search terms replacement key.
463 SetDefaultInstantTemplateUrl(true);
465 // Now there should be a valid Instant URL. Note the HTTPS "upgrade".
466 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
467 GetInstantURL(profile(), false));
469 // Enable suggest. No difference.
470 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
471 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
472 GetInstantURL(profile(), false));
474 // Disable suggest. No Instant URL.
475 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
476 EXPECT_EQ(GURL(), GetInstantURL(profile(), false));
478 // Use alternate Instant search base URL.
479 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
480 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
481 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:1"));
482 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo&qbp=1#foo=foo&strk"),
483 GetInstantURL(profile(), false));
486 TEST_F(SearchTest, UseSearchPathForInstant) {
487 // Use alternate Instant search base URL path.
488 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
489 "EmbeddedSearch",
490 "Group1 use_alternate_instant_url:1 use_search_path_for_instant:1"));
491 EXPECT_EQ(GURL("https://foo.com/search?foo=foo&qbp=1#foo=foo&strk"),
492 GetInstantURL(profile(), false));
495 TEST_F(SearchTest, InstantSearchEnabledCGI) {
496 // Disable Instant Search.
497 // Make sure {google:forceInstantResults} is not set in the Instant URL.
498 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
499 GetInstantURL(profile(), false));
501 // Enable Instant Search.
502 // Make sure {google:forceInstantResults} is set in the Instant URL.
503 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"),
504 GetInstantURL(profile(), true));
507 TEST_F(SearchTest, CommandLineOverrides) {
508 GURL local_instant_url(GetLocalInstantURL(profile()));
509 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url);
511 TemplateURLService* template_url_service =
512 TemplateURLServiceFactory::GetForProfile(profile());
513 TemplateURLData data;
514 data.SetURL("{google:baseURL}search?q={searchTerms}");
515 data.instant_url = "{google:baseURL}webhp?strk";
516 data.search_terms_replacement_key = "strk";
517 TemplateURL* template_url = new TemplateURL(data);
518 // Takes ownership of |template_url|.
519 template_url_service->Add(template_url);
520 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
522 // By default, Instant Extended forces the instant URL to be HTTPS, so even if
523 // we set a Google base URL that is HTTP, we should get an HTTPS URL.
524 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/");
525 GURL instant_url(GetInstantURL(profile(), false));
526 ASSERT_TRUE(instant_url.is_valid());
527 EXPECT_EQ("https://www.foo.com/webhp?strk", instant_url.spec());
529 // However, if the Google base URL is specified on the command line, the
530 // instant URL should just use it, even if it's HTTP.
531 UIThreadSearchTermsData::SetGoogleBaseURL(std::string());
532 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
533 switches::kGoogleBaseURL, "http://www.bar.com/");
534 instant_url = GetInstantURL(profile(), false);
535 ASSERT_TRUE(instant_url.is_valid());
536 EXPECT_EQ("http://www.bar.com/webhp?strk", instant_url.spec());
538 // Similarly, setting a Google base URL on the command line should allow you
539 // to get the Google version of the local NTP, even though search provider's
540 // URL doesn't contain "google".
541 local_instant_url = GetLocalInstantURL(profile());
542 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url);
544 // If we specify extra search query params, they should be inserted into the
545 // query portion of the instant URL.
546 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
547 switches::kExtraSearchQueryParams, "a=b");
548 instant_url = GetInstantURL(profile(), false);
549 ASSERT_TRUE(instant_url.is_valid());
550 EXPECT_EQ("http://www.bar.com/webhp?a=b&strk", instant_url.spec());
553 TEST_F(SearchTest, ShouldPrefetchSearchResults_InstantExtendedAPIEnabled) {
554 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
555 "EmbeddedSearch", "Group1 espv:2"));
556 #if defined(OS_IOS)
557 EXPECT_EQ(1ul, EmbeddedSearchPageVersion());
558 EXPECT_TRUE(ShouldPrefetchSearchResults());
559 #else
560 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
561 EXPECT_TRUE(ShouldPrefetchSearchResults());
562 #endif
565 TEST_F(SearchTest, ShouldPrefetchSearchResults_Default) {
566 #if defined(OS_IOS)
567 EXPECT_FALSE(ShouldPrefetchSearchResults());
568 #else
569 EXPECT_TRUE(ShouldPrefetchSearchResults());
570 #endif
573 TEST_F(SearchTest, ShouldReuseInstantSearchBasePage_Default) {
574 #if defined(OS_IOS)
575 EXPECT_FALSE(ShouldReuseInstantSearchBasePage());
576 #else
577 EXPECT_TRUE(ShouldReuseInstantSearchBasePage());
578 #endif
581 TEST_F(SearchTest, ShouldAllowPrefetchNonDefaultMatch_DisabledViaFieldTrial) {
582 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
583 "EmbeddedSearch", "Group1 espv:89 allow_prefetch_non_default_match:0"));
584 EXPECT_FALSE(ShouldAllowPrefetchNonDefaultMatch());
585 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
588 TEST_F(SearchTest, ShouldAllowPrefetchNonDefaultMatch_EnabledViaFieldTrial) {
589 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
590 "EmbeddedSearch", "Group1 espv:80 allow_prefetch_non_default_match:1"));
591 EXPECT_TRUE(ShouldAllowPrefetchNonDefaultMatch());
592 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
595 TEST_F(SearchTest, ShouldUseAltInstantURL_DisabledViaFieldTrial) {
596 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
597 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:0"));
598 EXPECT_FALSE(ShouldUseAltInstantURL());
601 TEST_F(SearchTest, ShouldUseAltInstantURL_EnabledViaFieldTrial) {
602 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
603 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:1"));
604 EXPECT_TRUE(ShouldUseAltInstantURL());
607 TEST_F(SearchTest, ShouldUseSearchPathForInstant_DisabledViaFieldTrial) {
608 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
609 "EmbeddedSearch",
610 "Group1 use_alternate_instant_url:1 use_search_path_for_instant:0"));
611 EXPECT_FALSE(ShouldUseSearchPathForInstant());
614 TEST_F(SearchTest, ShouldUseSearchPathForInstant_EnabledViaFieldTrial) {
615 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
616 "EmbeddedSearch",
617 "Group1 use_alternate_instant_url:1 use_search_path_for_instant:1"));
618 EXPECT_TRUE(ShouldUseSearchPathForInstant());
621 TEST_F(SearchTest,
622 ShouldPrerenderInstantUrlOnOmniboxFocus_DisabledViaFieldTrial) {
623 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
624 "EmbeddedSearch",
625 "Group1 espv:89 prerender_instant_url_on_omnibox_focus:0"));
626 EXPECT_FALSE(ShouldPrerenderInstantUrlOnOmniboxFocus());
627 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
630 TEST_F(SearchTest,
631 ShouldPrerenderInstantUrlOnOmniboxFocus_EnabledViaFieldTrial) {
632 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
633 "EmbeddedSearch",
634 "Group1 espv:80 prerender_instant_url_on_omnibox_focus:1"));
635 EXPECT_TRUE(ShouldPrerenderInstantUrlOnOmniboxFocus());
636 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
641 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_Default) {
642 EXPECT_TRUE(ShouldShowGoogleLocalNTP());
645 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_EnabledViaFinch) {
646 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
647 "EmbeddedSearch", "Group1 espv:2 google_local_ntp:1"));
648 EXPECT_TRUE(ShouldShowGoogleLocalNTP());
651 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_DisabledViaFinch) {
652 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
653 "EmbeddedSearch", "Group1 espv:2 google_local_ntp:0"));
654 EXPECT_FALSE(ShouldShowGoogleLocalNTP());
658 TEST_F(SearchTest, IsNTPURL) {
659 GURL invalid_url;
660 GURL ntp_url(chrome::kChromeUINewTabURL);
661 GURL local_ntp_url(GetLocalInstantURL(profile()));
663 EXPECT_FALSE(chrome::IsNTPURL(invalid_url, profile()));
664 // No margin.
665 EnableQueryExtractionForTesting();
666 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
667 GURL remote_ntp_url(GetInstantURL(profile(), false));
668 GURL search_url_with_search_terms("https://foo.com/url?strk&bar=abc");
669 GURL search_url_without_search_terms("https://foo.com/url?strk&bar");
671 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, profile()));
672 EXPECT_TRUE(chrome::IsNTPURL(local_ntp_url, profile()));
673 EXPECT_TRUE(chrome::IsNTPURL(remote_ntp_url, profile()));
674 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, profile()));
675 EXPECT_TRUE(chrome::IsNTPURL(search_url_without_search_terms, profile()));
677 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, NULL));
678 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, NULL));
679 EXPECT_FALSE(chrome::IsNTPURL(remote_ntp_url, NULL));
680 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, NULL));
681 EXPECT_FALSE(chrome::IsNTPURL(search_url_without_search_terms, NULL));
684 TEST_F(SearchTest, GetSearchURLs) {
685 std::vector<GURL> search_urls = GetSearchURLs(profile());
686 EXPECT_EQ(2U, search_urls.size());
687 EXPECT_EQ("http://foo.com/alt#quux=", search_urls[0].spec());
688 EXPECT_EQ("http://foo.com/url?bar=", search_urls[1].spec());
691 TEST_F(SearchTest, GetSearchResultPrefetchBaseURL) {
692 #if defined(OS_IOS)
693 EXPECT_FALSE(ShouldPrefetchSearchResults());
694 EXPECT_EQ(GURL(), GetSearchResultPrefetchBaseURL(profile()));
695 #else
696 EXPECT_TRUE(ShouldPrefetchSearchResults());
697 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"),
698 GetSearchResultPrefetchBaseURL(profile()));
699 #endif
702 TEST_F(SearchTest, ForceInstantResultsParam) {
703 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
704 "Group1 espv:2"));
705 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
706 EXPECT_EQ("ion=1&", ForceInstantResultsParam(true));
707 EXPECT_EQ(std::string(), ForceInstantResultsParam(false));
710 struct ExtractSearchTermsTestCase {
711 const char* url;
712 const char* expected_result;
713 const char* comment;
716 TEST_F(SearchTest, ExtractSearchTermsFromURL) {
717 const ExtractSearchTermsTestCase kTestCases[] = {
718 {chrome::kChromeSearchLocalNtpUrl, "", "NTP url"},
719 {"https://foo.com/instant?strk", "", "Invalid search url"},
720 {"https://foo.com/instant#strk", "", "Invalid search url"},
721 {"https://foo.com/alt#quux=foo", "foo", "Valid search url"},
722 {"https://foo.com/alt#quux=foo&strk", "foo", "Valid search url"}
725 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
726 const ExtractSearchTermsTestCase& test = kTestCases[i];
727 EXPECT_EQ(
728 test.expected_result,
729 base::UTF16ToASCII(chrome::ExtractSearchTermsFromURL(profile(),
730 GURL(test.url))))
731 << test.url << " " << test.comment;
735 struct QueryExtractionAllowedTestCase {
736 const char* url;
737 bool expected_result;
738 const char* comment;
741 TEST_F(SearchTest, IsQueryExtractionAllowedForURL) {
742 const QueryExtractionAllowedTestCase kTestCases[] = {
743 {"http://foo.com/instant?strk", false, "HTTP URL"},
744 {"https://foo.com/instant?strk", true, "Valid URL"},
745 {"https://foo.com/instant?", false,
746 "No search terms replacement key"},
747 {"https://foo.com/alt#quux=foo", false,
748 "No search terms replacement key"},
749 {"https://foo.com/alt#quux=foo&strk", true, "Valid search url"}
752 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
753 const QueryExtractionAllowedTestCase& test = kTestCases[i];
754 EXPECT_EQ(test.expected_result,
755 chrome::IsQueryExtractionAllowedForURL(profile(), GURL(test.url)))
756 << test.url << " " << test.comment;
760 class SearchURLTest : public SearchTest {
761 protected:
762 void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url) override {
763 TemplateURLService* template_url_service =
764 TemplateURLServiceFactory::GetForProfile(profile());
765 TemplateURLData data;
766 data.SetURL("{google:baseURL}search?"
767 "{google:instantExtendedEnabledParameter}q={searchTerms}");
768 data.search_terms_replacement_key = "espv";
769 template_url_ = new TemplateURL(data);
770 // |template_url_service| takes ownership of |template_url_|.
771 template_url_service->Add(template_url_);
772 template_url_service->SetUserSelectedDefaultSearchProvider(template_url_);
775 TemplateURL* template_url_;
778 TEST_F(SearchURLTest, QueryExtractionEnabled) {
779 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
780 EnableQueryExtractionForTesting();
781 EXPECT_TRUE(IsQueryExtractionEnabled());
782 TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
783 GURL result(template_url_->url_ref().ReplaceSearchTerms(
784 search_terms_args, UIThreadSearchTermsData(profile())));
785 ASSERT_TRUE(result.is_valid());
786 // Query extraction is enabled. Make sure
787 // {google:instantExtendedEnabledParameter} is set in the search URL.
788 EXPECT_EQ("http://www.google.com/search?espv=2&q=foo", result.spec());
791 TEST_F(SearchURLTest, QueryExtractionDisabled) {
792 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
793 EXPECT_FALSE(IsQueryExtractionEnabled());
794 TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
795 GURL result(template_url_->url_ref().ReplaceSearchTerms(
796 search_terms_args, UIThreadSearchTermsData(profile())));
797 ASSERT_TRUE(result.is_valid());
798 // Query extraction is disabled. Make sure
799 // {google:instantExtendedEnabledParameter} is not set in the search URL.
800 EXPECT_EQ("http://www.google.com/search?q=foo", result.spec());
803 typedef SearchTest InstantExtendedEnabledParamTest;
805 TEST_F(InstantExtendedEnabledParamTest, QueryExtractionDisabled) {
806 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
807 "Group1 espv:12"));
808 // Make sure InstantExtendedEnabledParam() returns an empty string for search
809 // requests.
810 #if defined(OS_IOS)
811 // Query extraction is always enabled on mobile.
812 EXPECT_TRUE(IsQueryExtractionEnabled());
813 EXPECT_EQ("espv=12&", InstantExtendedEnabledParam(true));
814 #else
815 EXPECT_FALSE(IsQueryExtractionEnabled());
816 EXPECT_EQ("", InstantExtendedEnabledParam(true));
817 #endif
818 EXPECT_EQ("espv=12&", InstantExtendedEnabledParam(false));
821 TEST_F(InstantExtendedEnabledParamTest, QueryExtractionEnabled) {
822 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
823 "EmbeddedSearch", "Group1 espv:10 query_extraction:1"));
824 EXPECT_TRUE(IsQueryExtractionEnabled());
825 // Make sure InstantExtendedEnabledParam() returns a non-empty param string
826 // for search requests.
827 EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(true));
828 EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(false));
831 TEST_F(InstantExtendedEnabledParamTest, UseDefaultEmbeddedSearchPageVersion) {
832 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
833 "EmbeddedSearch", "Group1 espv:-1 query_extraction:1"));
834 EXPECT_TRUE(IsQueryExtractionEnabled());
835 #if defined(OS_IOS)
836 EXPECT_EQ("espv=1&", InstantExtendedEnabledParam(true));
837 EXPECT_EQ("espv=1&", InstantExtendedEnabledParam(false));
838 #else
839 EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(true));
840 EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(false));
841 #endif
844 typedef SearchTest IsQueryExtractionEnabledTest;
846 TEST_F(IsQueryExtractionEnabledTest, NotSet) {
847 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
848 "EmbeddedSearch", "Group1 espv:2"));
849 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
850 EXPECT_FALSE(IsQueryExtractionEnabled());
851 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
854 TEST_F(IsQueryExtractionEnabledTest, EnabledViaFieldTrial) {
855 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
856 "EmbeddedSearch", "Group1 espv:2 query_extraction:1"));
857 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
858 EXPECT_TRUE(IsQueryExtractionEnabled());
859 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
862 TEST_F(IsQueryExtractionEnabledTest, DisabledViaFieldTrial) {
863 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
864 "EmbeddedSearch", "Group1 espv:2 query_extraction:0"));
865 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
866 EXPECT_FALSE(IsQueryExtractionEnabled());
867 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
870 TEST_F(IsQueryExtractionEnabledTest, EnabledViaCommandLine) {
871 EnableQueryExtractionForTesting();
872 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
873 "EmbeddedSearch", "Group1 espv:2 query_extraction:0"));
874 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
875 EXPECT_TRUE(IsQueryExtractionEnabled());
876 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
879 } // namespace chrome