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.
4
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/metrics/statistics_recorder.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/search/instant_service.h"
13 #include "chrome/browser/search/instant_service_factory.h"
14 #include "chrome/browser/search/search.h"
15 #include "chrome/browser/search_engines/template_url_service.h"
16 #include "chrome/browser/search_engines/template_url_service_factory.h"
17 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
18 #include "chrome/browser/supervised_user/supervised_user_service.h"
19 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
20 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/common/url_constants.h"
25 #include "chrome/test/base/browser_with_test_window_test.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/google/core/browser/google_switches.h"
28 #include "components/variations/entropy_provider.h"
29 #include "content/public/browser/render_process_host.h"
30 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/site_instance.h"
32 #include "content/public/browser/web_contents.h"
33 #include "content/public/common/renderer_preferences.h"
34 #include "url/gurl.h"
35
36 namespace chrome {
37
38 class EmbeddedSearchFieldTrialTest : public testing::Test {
39 protected:
SetUp()40 virtual void SetUp() {
41 field_trial_list_.reset(new base::FieldTrialList(
42 new metrics::SHA1EntropyProvider("42")));
43 base::StatisticsRecorder::Initialize();
44 }
45
46 private:
47 scoped_ptr<base::FieldTrialList> field_trial_list_;
48 };
49
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoEmptyAndValid)50 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) {
51 FieldTrialFlags flags;
52
53 EXPECT_TRUE(GetFieldTrialInfo(&flags));
54 EXPECT_EQ(0ul, flags.size());
55
56 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
57 "Group77"));
58 EXPECT_TRUE(GetFieldTrialInfo(&flags));
59 EXPECT_EQ(0ul, flags.size());
60 }
61
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoInvalidNumber)62 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidNumber) {
63 FieldTrialFlags flags;
64
65 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
66 "Group77.2"));
67 EXPECT_TRUE(GetFieldTrialInfo(&flags));
68 EXPECT_EQ(0ul, flags.size());
69 }
70
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoInvalidName)71 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidName) {
72 FieldTrialFlags flags;
73
74 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
75 "Invalid77"));
76 EXPECT_TRUE(GetFieldTrialInfo(&flags));
77 EXPECT_EQ(0ul, flags.size());
78 }
79
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoValidGroup)80 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidGroup) {
81 FieldTrialFlags flags;
82
83 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
84 "Group77"));
85 EXPECT_TRUE(GetFieldTrialInfo(&flags));
86 EXPECT_EQ(0ul, flags.size());
87 }
88
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoValidFlag)89 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) {
90 FieldTrialFlags flags;
91
92 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
93 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
94 "Group77 foo:6"));
95 EXPECT_TRUE(GetFieldTrialInfo(&flags));
96 EXPECT_EQ(1ul, flags.size());
97 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
98 }
99
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoNewName)100 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewName) {
101 FieldTrialFlags flags;
102
103 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
104 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
105 "Group77 foo:6"));
106 EXPECT_TRUE(GetFieldTrialInfo(&flags));
107 EXPECT_EQ(1ul, flags.size());
108 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
109 }
110
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoNewNameOverridesOld)111 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewNameOverridesOld) {
112 FieldTrialFlags flags;
113
114 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
115 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
116 "Group77 foo:6"));
117 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
118 "Group78 foo:5"));
119 EXPECT_TRUE(GetFieldTrialInfo(&flags));
120 EXPECT_EQ(1ul, flags.size());
121 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
122 }
123
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoLotsOfFlags)124 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) {
125 FieldTrialFlags flags;
126
127 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
128 "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs"));
129 EXPECT_TRUE(GetFieldTrialInfo(&flags));
130 EXPECT_EQ(3ul, flags.size());
131 EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags));
132 EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags));
133 EXPECT_EQ("dogs",
134 GetStringValueForFlagWithDefault("cat", std::string(), flags));
135 EXPECT_EQ("default",
136 GetStringValueForFlagWithDefault("moose", "default", flags));
137 }
138
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoDisabled)139 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) {
140 FieldTrialFlags flags;
141
142 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
143 "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs DISABLED"));
144 EXPECT_FALSE(GetFieldTrialInfo(&flags));
145 EXPECT_EQ(0ul, flags.size());
146 }
147
TEST_F(EmbeddedSearchFieldTrialTest,GetFieldTrialInfoControlFlags)148 TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) {
149 FieldTrialFlags flags;
150
151 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
152 "EmbeddedSearch", "Control77 bar:1 baz:7 cat:dogs"));
153 EXPECT_TRUE(GetFieldTrialInfo(&flags));
154 EXPECT_EQ(3ul, flags.size());
155 }
156
157 class SearchTest : public BrowserWithTestWindowTest {
158 protected:
SetUp()159 virtual void SetUp() OVERRIDE {
160 BrowserWithTestWindowTest::SetUp();
161 field_trial_list_.reset(new base::FieldTrialList(
162 new metrics::SHA1EntropyProvider("42")));
163 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
164 profile(), &TemplateURLServiceFactory::BuildInstanceFor);
165 TemplateURLService* template_url_service =
166 TemplateURLServiceFactory::GetForProfile(profile());
167 ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
168 SetSearchProvider(true, false);
169 }
170
SetSearchProvider(bool set_ntp_url,bool insecure_ntp_url)171 virtual void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url) {
172 TemplateURLService* template_url_service =
173 TemplateURLServiceFactory::GetForProfile(profile());
174 TemplateURLData data;
175 data.SetURL("http://foo.com/url?bar={searchTerms}");
176 data.instant_url = "http://foo.com/instant?"
177 "{google:omniboxStartMarginParameter}{google:forceInstantResults}"
178 "foo=foo#foo=foo&strk";
179 if (set_ntp_url) {
180 data.new_tab_url = (insecure_ntp_url ? "http" : "https") +
181 std::string("://foo.com/newtab?strk");
182 }
183 data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}");
184 data.search_terms_replacement_key = "strk";
185
186 TemplateURL* template_url = new TemplateURL(data);
187 // Takes ownership of |template_url|.
188 template_url_service->Add(template_url);
189 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
190 }
191
192 // Build an Instant URL with or without a valid search terms replacement key
193 // as per |has_search_term_replacement_key|. Set that URL as the instant URL
194 // for the default search provider.
SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key)195 void SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key) {
196 TemplateURLService* template_url_service =
197 TemplateURLServiceFactory::GetForProfile(profile());
198
199 static const char kInstantURLWithStrk[] =
200 "http://foo.com/instant?foo=foo#foo=foo&strk";
201 static const char kInstantURLNoStrk[] =
202 "http://foo.com/instant?foo=foo#foo=foo";
203
204 TemplateURLData data;
205 data.SetURL("http://foo.com/url?bar={searchTerms}");
206 data.instant_url = (has_search_term_replacement_key ?
207 kInstantURLWithStrk : kInstantURLNoStrk);
208 data.search_terms_replacement_key = "strk";
209
210 TemplateURL* template_url = new TemplateURL(data);
211 // Takes ownership of |template_url|.
212 template_url_service->Add(template_url);
213 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
214 }
215
InInstantProcess(const content::WebContents * contents)216 bool InInstantProcess(const content::WebContents* contents) {
217 InstantService* instant_service =
218 InstantServiceFactory::GetForProfile(profile());
219 return instant_service->IsInstantProcess(
220 contents->GetRenderProcessHost()->GetID());
221 }
222
223 scoped_ptr<base::FieldTrialList> field_trial_list_;
224 };
225
226 struct SearchTestCase {
227 const char* url;
228 bool expected_result;
229 const char* comment;
230 };
231
TEST_F(SearchTest,ShouldAssignURLToInstantRendererExtendedEnabled)232 TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) {
233 EnableQueryExtractionForTesting();
234
235 const SearchTestCase kTestCases[] = {
236 {chrome::kChromeSearchLocalNtpUrl, true, ""},
237 {"https://foo.com/instant?strk", true, ""},
238 {"https://foo.com/instant#strk", true, ""},
239 {"https://foo.com/instant?strk=0", true, ""},
240 {"https://foo.com/url?strk", true, ""},
241 {"https://foo.com/alt?strk", true, ""},
242 {"http://foo.com/instant", false, "Non-HTTPS"},
243 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
244 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
245 {"https://foo.com/instant", false, "No search terms replacement"},
246 {"https://foo.com/?strk", false, "Non-exact path"},
247 };
248
249 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
250 const SearchTestCase& test = kTestCases[i];
251 EXPECT_EQ(test.expected_result,
252 ShouldAssignURLToInstantRenderer(GURL(test.url), profile()))
253 << test.url << " " << test.comment;
254 }
255 }
256
TEST_F(SearchTest,ShouldAssignURLToInstantRendererExtendedEnabledNotOnSRP)257 TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabledNotOnSRP) {
258 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
259 "EmbeddedSearch", "Group1 espv:2 suppress_on_srp:1"));
260
261 const SearchTestCase kTestCases[] = {
262 {chrome::kChromeSearchLocalNtpUrl, true, ""},
263 {"https://foo.com/instant?strk", true, ""},
264 {"https://foo.com/instant#strk", true, ""},
265 {"https://foo.com/instant?strk=0", true, ""},
266 {"https://foo.com/url?strk", false, "Disabled on SRP"},
267 {"https://foo.com/alt?strk", false, "Disabled ON SRP"},
268 {"http://foo.com/instant", false, "Non-HTTPS"},
269 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
270 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
271 {"https://foo.com/instant", false, "No search terms replacement"},
272 {"https://foo.com/?strk", false, "Non-exact path"},
273 };
274
275 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
276 const SearchTestCase& test = kTestCases[i];
277 EXPECT_EQ(test.expected_result,
278 ShouldAssignURLToInstantRenderer(GURL(test.url), profile()))
279 << test.url << " " << test.comment;
280 }
281 }
282
TEST_F(SearchTest,ShouldUseProcessPerSiteForInstantURL)283 TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) {
284 EnableQueryExtractionForTesting();
285
286 const SearchTestCase kTestCases[] = {
287 {"chrome-search://local-ntp", true, "Local NTP"},
288 {"chrome-search://remote-ntp", true, "Remote NTP"},
289 {"invalid-scheme://local-ntp", false, "Invalid Local NTP URL"},
290 {"invalid-scheme://online-ntp", false, "Invalid Online NTP URL"},
291 {"chrome-search://foo.com", false, "Search result page"},
292 {"https://foo.com/instant?strk", false, ""},
293 {"https://foo.com/instant#strk", false, ""},
294 {"https://foo.com/instant?strk=0", false, ""},
295 {"https://foo.com/url?strk", false, ""},
296 {"https://foo.com/alt?strk", false, ""},
297 {"http://foo.com/instant", false, "Non-HTTPS"},
298 {"http://foo.com/instant?strk", false, "Non-HTTPS"},
299 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"},
300 {"https://foo.com/instant", false, "No search terms replacement"},
301 {"https://foo.com/?strk", false, "Non-exact path"},
302 };
303
304 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
305 const SearchTestCase& test = kTestCases[i];
306 EXPECT_EQ(test.expected_result,
307 ShouldUseProcessPerSiteForInstantURL(GURL(test.url), profile()))
308 << test.url << " " << test.comment;
309 }
310 }
311
312 // Each test case represents a navigation to |start_url| followed by a
313 // navigation to |end_url|. We will check whether each navigation lands in an
314 // Instant process, and also whether the navigation from start to end re-uses
315 // the same SiteInstance (and hence the same RenderViewHost, etc.).
316 const struct ProcessIsolationTestCase {
317 const char* description;
318 const char* start_url;
319 bool start_in_instant_process;
320 const char* end_url;
321 bool end_in_instant_process;
322 bool same_site_instance;
323 } kProcessIsolationTestCases[] = {
324 {"Local NTP -> SRP",
325 "chrome-search://local-ntp", true,
326 "https://foo.com/url?strk", true, false },
327 {"Local NTP -> Regular",
328 "chrome-search://local-ntp", true,
329 "https://foo.com/other", false, false },
330 {"Remote NTP -> SRP",
331 "https://foo.com/newtab?strk", true,
332 "https://foo.com/url?strk", true, false },
333 {"Remote NTP -> Regular",
334 "https://foo.com/newtab?strk", true,
335 "https://foo.com/other", false, false },
336 {"SRP -> SRP",
337 "https://foo.com/url?strk", true,
338 "https://foo.com/url?strk", true, true },
339 {"SRP -> Regular",
340 "https://foo.com/url?strk", true,
341 "https://foo.com/other", false, false },
342 {"Regular -> SRP",
343 "https://foo.com/other", false,
344 "https://foo.com/url?strk", true, false },
345 };
346
TEST_F(SearchTest,ProcessIsolation)347 TEST_F(SearchTest, ProcessIsolation) {
348 EnableQueryExtractionForTesting();
349
350 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) {
351 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
352 AddTab(browser(), GURL("chrome://blank"));
353 const content::WebContents* contents =
354 browser()->tab_strip_model()->GetActiveWebContents();
355
356 // Navigate to start URL.
357 NavigateAndCommitActiveTab(GURL(test.start_url));
358 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents))
359 << test.description;
360
361 // Save state.
362 const scoped_refptr<content::SiteInstance> start_site_instance =
363 contents->GetSiteInstance();
364 const content::RenderProcessHost* start_rph =
365 contents->GetRenderProcessHost();
366 const content::RenderViewHost* start_rvh =
367 contents->GetRenderViewHost();
368
369 // Navigate to end URL.
370 NavigateAndCommitActiveTab(GURL(test.end_url));
371 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents))
372 << test.description;
373
374 EXPECT_EQ(test.same_site_instance,
375 start_site_instance == contents->GetSiteInstance())
376 << test.description;
377 EXPECT_EQ(test.same_site_instance,
378 start_rvh == contents->GetRenderViewHost())
379 << test.description;
380 EXPECT_EQ(test.same_site_instance,
381 start_rph == contents->GetRenderProcessHost())
382 << test.description;
383 }
384 }
385
TEST_F(SearchTest,ProcessIsolation_RendererInitiated)386 TEST_F(SearchTest, ProcessIsolation_RendererInitiated) {
387 EnableQueryExtractionForTesting();
388
389 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) {
390 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
391 AddTab(browser(), GURL("chrome://blank"));
392 content::WebContents* contents =
393 browser()->tab_strip_model()->GetActiveWebContents();
394
395 // Navigate to start URL.
396 NavigateAndCommitActiveTab(GURL(test.start_url));
397 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents))
398 << test.description;
399
400 // Save state.
401 const scoped_refptr<content::SiteInstance> start_site_instance =
402 contents->GetSiteInstance();
403 const content::RenderProcessHost* start_rph =
404 contents->GetRenderProcessHost();
405 const content::RenderViewHost* start_rvh =
406 contents->GetRenderViewHost();
407
408 // Navigate to end URL via a renderer-initiated navigation.
409 content::NavigationController* controller = &contents->GetController();
410 content::NavigationController::LoadURLParams load_params(
411 GURL(test.end_url));
412 load_params.is_renderer_initiated = true;
413 load_params.transition_type = content::PAGE_TRANSITION_LINK;
414
415 controller->LoadURLWithParams(load_params);
416 CommitPendingLoad(controller);
417 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents))
418 << test.description;
419
420 EXPECT_EQ(test.same_site_instance,
421 start_site_instance == contents->GetSiteInstance())
422 << test.description;
423 EXPECT_EQ(test.same_site_instance,
424 start_rvh == contents->GetRenderViewHost())
425 << test.description;
426 EXPECT_EQ(test.same_site_instance,
427 start_rph == contents->GetRenderProcessHost())
428 << test.description;
429 }
430 }
431
432 const SearchTestCase kInstantNTPTestCases[] = {
433 {"https://foo.com/instant?strk", false, "Valid Instant URL"},
434 {"https://foo.com/instant#strk", false, "Valid Instant URL"},
435 {"https://foo.com/url?strk", false, "Valid search URL"},
436 {"https://foo.com/url#strk", false, "Valid search URL"},
437 {"https://foo.com/alt?strk", false, "Valid alternative URL"},
438 {"https://foo.com/alt#strk", false, "Valid alternative URL"},
439 {"https://foo.com/url?strk&bar=", false, "No query terms"},
440 {"https://foo.com/url?strk&q=abc", false, "No query terms key"},
441 {"https://foo.com/url?strk#bar=abc", false, "Query terms key in ref"},
442 {"https://foo.com/url?strk&bar=abc", false, "Has query terms"},
443 {"http://foo.com/instant?strk=1", false, "Insecure URL"},
444 {"https://foo.com/instant", false, "No search term replacement"},
445 {"chrome://blank/", false, "Chrome scheme"},
446 {"chrome-search://foo", false, "Chrome-search scheme"},
447 {"https://bar.com/instant?strk=1", false, "Random non-search page"},
448 {chrome::kChromeSearchLocalNtpUrl, true, "Local new tab page"},
449 {"https://foo.com/newtab?strk", true, "New tab URL"},
450 {"http://foo.com/newtab?strk", false, "Insecure New tab URL"},
451 };
452
TEST_F(SearchTest,InstantNTPExtendedEnabled)453 TEST_F(SearchTest, InstantNTPExtendedEnabled) {
454 EnableQueryExtractionForTesting();
455 AddTab(browser(), GURL("chrome://blank"));
456 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) {
457 const SearchTestCase& test = kInstantNTPTestCases[i];
458 NavigateAndCommitActiveTab(GURL(test.url));
459 const content::WebContents* contents =
460 browser()->tab_strip_model()->GetWebContentsAt(0);
461 EXPECT_EQ(test.expected_result, IsInstantNTP(contents))
462 << test.url << " " << test.comment;
463 }
464 }
465
TEST_F(SearchTest,InstantNTPCustomNavigationEntry)466 TEST_F(SearchTest, InstantNTPCustomNavigationEntry) {
467 EnableQueryExtractionForTesting();
468 AddTab(browser(), GURL("chrome://blank"));
469 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) {
470 const SearchTestCase& test = kInstantNTPTestCases[i];
471 NavigateAndCommitActiveTab(GURL(test.url));
472 content::WebContents* contents =
473 browser()->tab_strip_model()->GetWebContentsAt(0);
474 content::NavigationController& controller = contents->GetController();
475 controller.SetTransientEntry(
476 controller.CreateNavigationEntry(GURL("chrome://blank"),
477 content::Referrer(),
478 content::PAGE_TRANSITION_LINK,
479 false,
480 std::string(),
481 contents->GetBrowserContext()));
482 // The active entry is chrome://blank and not an NTP.
483 EXPECT_FALSE(IsInstantNTP(contents));
484 EXPECT_EQ(test.expected_result,
485 NavEntryIsInstantNTP(contents,
486 controller.GetLastCommittedEntry()))
487 << test.url << " " << test.comment;
488 }
489 }
490
TEST_F(SearchTest,InstantCacheableNTPNavigationEntry)491 TEST_F(SearchTest, InstantCacheableNTPNavigationEntry) {
492 AddTab(browser(), GURL("chrome://blank"));
493 content::WebContents* contents =
494 browser()->tab_strip_model()->GetWebContentsAt(0);
495 content::NavigationController& controller = contents->GetController();
496 // Local NTP.
497 NavigateAndCommitActiveTab(GURL(chrome::kChromeSearchLocalNtpUrl));
498 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
499 controller.GetLastCommittedEntry()));
500 // Instant page is not cacheable NTP.
501 NavigateAndCommitActiveTab(GetInstantURL(profile(), kDisableStartMargin,
502 false));
503 EXPECT_FALSE(NavEntryIsInstantNTP(contents,
504 controller.GetLastCommittedEntry()));
505 // Test Cacheable NTP
506 NavigateAndCommitActiveTab(chrome::GetNewTabPageURL(profile()));
507 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
508 controller.GetLastCommittedEntry()));
509 }
510
TEST_F(SearchTest,InstantCacheableNTPNavigationEntryNewProfile)511 TEST_F(SearchTest, InstantCacheableNTPNavigationEntryNewProfile) {
512 SetSearchProvider(false, false);
513 AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
514 content::WebContents* contents =
515 browser()->tab_strip_model()->GetWebContentsAt(0);
516 content::NavigationController& controller = contents->GetController();
517 // Test virtual url chrome://newtab for first NTP of a new profile
518 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
519 controller.GetLastCommittedEntry()));
520 // The new_tab_url gets set after the first NTP is visible.
521 SetSearchProvider(true, false);
522 EXPECT_TRUE(NavEntryIsInstantNTP(contents,
523 controller.GetLastCommittedEntry()));
524 }
525
TEST_F(SearchTest,NoRewriteInIncognito)526 TEST_F(SearchTest, NoRewriteInIncognito) {
527 profile()->ForceIncognito(true);
528 EXPECT_EQ(GURL(), chrome::GetNewTabPageURL(profile()));
529 GURL new_tab_url(chrome::kChromeUINewTabURL);
530 EXPECT_FALSE(HandleNewTabURLRewrite(&new_tab_url, profile()));
531 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), new_tab_url);
532 }
533
TEST_F(SearchTest,UseLocalNTPIfNTPURLIsInsecure)534 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsInsecure) {
535 // Set an insecure new tab page URL and verify that it's ignored.
536 SetSearchProvider(true, true);
537 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
538 chrome::GetNewTabPageURL(profile()));
539 GURL new_tab_url(chrome::kChromeUINewTabURL);
540 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
541 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
542 }
543
TEST_F(SearchTest,UseLocalNTPIfNTPURLIsNotSet)544 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsNotSet) {
545 // Set an insecure new tab page URL and verify that it's ignored.
546 SetSearchProvider(false, true);
547 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
548 chrome::GetNewTabPageURL(profile()));
549 GURL new_tab_url(chrome::kChromeUINewTabURL);
550 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
551 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
552 }
553
TEST_F(SearchTest,UseLocalNTPIfNTPURLIsBlockedForSupervisedUser)554 TEST_F(SearchTest, UseLocalNTPIfNTPURLIsBlockedForSupervisedUser) {
555 // Block access to foo.com in the URL filter.
556 SupervisedUserService* supervised_user_service =
557 SupervisedUserServiceFactory::GetForProfile(profile());
558 SupervisedUserURLFilter* url_filter =
559 supervised_user_service->GetURLFilterForUIThread();
560 std::map<std::string, bool> hosts;
561 hosts["foo.com"] = false;
562 url_filter->SetManualHosts(&hosts);
563
564 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
565 chrome::GetNewTabPageURL(profile()));
566 GURL new_tab_url(chrome::kChromeUINewTabURL);
567 EXPECT_TRUE(HandleNewTabURLRewrite(&new_tab_url, profile()));
568 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), new_tab_url);
569 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false));
570 }
571
TEST_F(SearchTest,GetInstantURL)572 TEST_F(SearchTest, GetInstantURL) {
573 // No Instant URL because "strk" is missing.
574 SetDefaultInstantTemplateUrl(false);
575 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false));
576
577 // Set an Instant URL with a valid search terms replacement key.
578 SetDefaultInstantTemplateUrl(true);
579
580 // Now there should be a valid Instant URL. Note the HTTPS "upgrade".
581 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
582 GetInstantURL(profile(), kDisableStartMargin, false));
583
584 // Enable suggest. No difference.
585 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
586 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
587 GetInstantURL(profile(), kDisableStartMargin, false));
588
589 // Disable suggest. No Instant URL.
590 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
591 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false));
592
593 // Use alternate Instant search base URL.
594 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
595 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
596 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:1"));
597 EXPECT_EQ(GURL("https://foo.com/search?foo=foo&qbp=1#foo=foo&strk"),
598 GetInstantURL(profile(), kDisableStartMargin, false));
599 }
600
TEST_F(SearchTest,StartMarginCGI)601 TEST_F(SearchTest, StartMarginCGI) {
602 // No margin.
603 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
604
605 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
606 GetInstantURL(profile(), kDisableStartMargin, false));
607
608 // With start margin.
609 EXPECT_EQ(GURL("https://foo.com/instant?es_sm=10&foo=foo#foo=foo&strk"),
610 GetInstantURL(profile(), 10, false));
611 }
612
TEST_F(SearchTest,InstantSearchEnabledCGI)613 TEST_F(SearchTest, InstantSearchEnabledCGI) {
614 // Disable Instant Search.
615 // Make sure {google:forceInstantResults} is not set in the Instant URL.
616 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
617 GetInstantURL(profile(), kDisableStartMargin, false));
618
619 // Enable Instant Search.
620 // Make sure {google:forceInstantResults} is set in the Instant URL.
621 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"),
622 GetInstantURL(profile(), kDisableStartMargin, true));
623 }
624
TEST_F(SearchTest,CommandLineOverrides)625 TEST_F(SearchTest, CommandLineOverrides) {
626 GURL local_instant_url(GetLocalInstantURL(profile()));
627 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url);
628
629 TemplateURLService* template_url_service =
630 TemplateURLServiceFactory::GetForProfile(profile());
631 TemplateURLData data;
632 data.SetURL("{google:baseURL}search?q={searchTerms}");
633 data.instant_url = "{google:baseURL}webhp?strk";
634 data.search_terms_replacement_key = "strk";
635 TemplateURL* template_url = new TemplateURL(data);
636 // Takes ownership of |template_url|.
637 template_url_service->Add(template_url);
638 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
639
640 // By default, Instant Extended forces the instant URL to be HTTPS, so even if
641 // we set a Google base URL that is HTTP, we should get an HTTPS URL.
642 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/");
643 GURL instant_url(GetInstantURL(profile(), kDisableStartMargin, false));
644 ASSERT_TRUE(instant_url.is_valid());
645 EXPECT_EQ("https://www.foo.com/webhp?strk", instant_url.spec());
646
647 // However, if the Google base URL is specified on the command line, the
648 // instant URL should just use it, even if it's HTTP.
649 UIThreadSearchTermsData::SetGoogleBaseURL(std::string());
650 CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL,
651 "http://www.bar.com/");
652 instant_url = GetInstantURL(profile(), kDisableStartMargin, false);
653 ASSERT_TRUE(instant_url.is_valid());
654 EXPECT_EQ("http://www.bar.com/webhp?strk", instant_url.spec());
655
656 // Similarly, setting a Google base URL on the command line should allow you
657 // to get the Google version of the local NTP, even though search provider's
658 // URL doesn't contain "google".
659 local_instant_url = GetLocalInstantURL(profile());
660 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url);
661
662 // If we specify extra search query params, they should be inserted into the
663 // query portion of the instant URL.
664 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
665 switches::kExtraSearchQueryParams, "a=b");
666 instant_url = GetInstantURL(profile(), kDisableStartMargin, false);
667 ASSERT_TRUE(instant_url.is_valid());
668 EXPECT_EQ("http://www.bar.com/webhp?a=b&strk", instant_url.spec());
669 }
670
TEST_F(SearchTest,ShouldPrefetchSearchResults_InstantExtendedAPIEnabled)671 TEST_F(SearchTest, ShouldPrefetchSearchResults_InstantExtendedAPIEnabled) {
672 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
673 "EmbeddedSearch",
674 "Group1 espv:2 prefetch_results:1"));
675 EXPECT_TRUE(ShouldPrefetchSearchResults());
676 #if defined(OS_IOS) || defined(OS_ANDROID)
677 EXPECT_EQ(1ul, EmbeddedSearchPageVersion());
678 #else
679 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
680 #endif
681 }
682
TEST_F(SearchTest,ShouldPrefetchSearchResults_DisabledViaFieldTrial)683 TEST_F(SearchTest, ShouldPrefetchSearchResults_DisabledViaFieldTrial) {
684 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
685 "EmbeddedSearch",
686 "Group1 espv:89 prefetch_results:0"));
687 EXPECT_FALSE(ShouldPrefetchSearchResults());
688 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
689 }
690
TEST_F(SearchTest,ShouldPrefetchSearchResults_EnabledViaFieldTrial)691 TEST_F(SearchTest, ShouldPrefetchSearchResults_EnabledViaFieldTrial) {
692 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
693 "EmbeddedSearch",
694 "Group1 espv:80 prefetch_results:1"));
695 EXPECT_TRUE(ShouldPrefetchSearchResults());
696 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
697 }
698
TEST_F(SearchTest,ShouldPrefetchSearchResults_EnabledViaCommandLine)699 TEST_F(SearchTest, ShouldPrefetchSearchResults_EnabledViaCommandLine) {
700 CommandLine::ForCurrentProcess()->AppendSwitch(
701 switches::kPrefetchSearchResults);
702 // Command-line enable should override Finch.
703 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
704 "EmbeddedSearch", "Group1 espv:80 prefetch_results:0"));
705 EXPECT_TRUE(ShouldPrefetchSearchResults());
706 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
707 }
708
TEST_F(SearchTest,ShouldAllowPrefetchNonDefaultMatch_PrefetchResultsFlagDisabled)709 TEST_F(SearchTest,
710 ShouldAllowPrefetchNonDefaultMatch_PrefetchResultsFlagDisabled) {
711 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
712 "EmbeddedSearch",
713 "Group1 espv:80 prefetch_results:0 allow_prefetch_non_default_match:1"));
714 EXPECT_FALSE(ShouldAllowPrefetchNonDefaultMatch());
715 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
716 }
717
TEST_F(SearchTest,ShouldAllowPrefetchNonDefaultMatch_DisabledViaFieldTrial)718 TEST_F(SearchTest, ShouldAllowPrefetchNonDefaultMatch_DisabledViaFieldTrial) {
719 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
720 "EmbeddedSearch",
721 "Group1 espv:89 prefetch_results:1 allow_prefetch_non_default_match:0"));
722 EXPECT_FALSE(ShouldAllowPrefetchNonDefaultMatch());
723 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
724 }
725
TEST_F(SearchTest,ShouldAllowPrefetchNonDefaultMatch_EnabledViaFieldTrial)726 TEST_F(SearchTest, ShouldAllowPrefetchNonDefaultMatch_EnabledViaFieldTrial) {
727 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
728 "EmbeddedSearch",
729 "Group1 espv:80 prefetch_results:1 allow_prefetch_non_default_match:1"));
730 EXPECT_TRUE(ShouldAllowPrefetchNonDefaultMatch());
731 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
732 }
733
TEST_F(SearchTest,ShouldUseAltInstantURL_DisabledViaFieldTrial)734 TEST_F(SearchTest, ShouldUseAltInstantURL_DisabledViaFieldTrial) {
735 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
736 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:0"));
737 EXPECT_FALSE(ShouldUseAltInstantURL());
738 }
739
TEST_F(SearchTest,ShouldUseAltInstantURL_EnabledViaFieldTrial)740 TEST_F(SearchTest, ShouldUseAltInstantURL_EnabledViaFieldTrial) {
741 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
742 "EmbeddedSearch", "Group1 espv:8 use_alternate_instant_url:1"));
743 EXPECT_TRUE(ShouldUseAltInstantURL());
744 }
745
TEST_F(SearchTest,ShouldPrerenderInstantUrlOnOmniboxFocus_PrefetchResultsFlagDisabled)746 TEST_F(SearchTest,
747 ShouldPrerenderInstantUrlOnOmniboxFocus_PrefetchResultsFlagDisabled) {
748 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
749 "EmbeddedSearch",
750 "Group1 espv:80 prefetch_results:0 "
751 "prerender_instant_url_on_omnibox_focus:1"));
752 EXPECT_FALSE(ShouldPrerenderInstantUrlOnOmniboxFocus());
753 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
754 }
755
TEST_F(SearchTest,ShouldPrerenderInstantUrlOnOmniboxFocus_DisabledViaFieldTrial)756 TEST_F(SearchTest,
757 ShouldPrerenderInstantUrlOnOmniboxFocus_DisabledViaFieldTrial) {
758 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
759 "EmbeddedSearch",
760 "Group1 espv:89 prefetch_results:1 "
761 "prerender_instant_url_on_omnibox_focus:0"));
762 EXPECT_FALSE(ShouldPrerenderInstantUrlOnOmniboxFocus());
763 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
764 }
765
TEST_F(SearchTest,ShouldPrerenderInstantUrlOnOmniboxFocus_EnabledViaFieldTrial)766 TEST_F(SearchTest,
767 ShouldPrerenderInstantUrlOnOmniboxFocus_EnabledViaFieldTrial) {
768 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
769 "EmbeddedSearch",
770 "Group1 espv:80 prefetch_results:1 "
771 "prerender_instant_url_on_omnibox_focus:1"));
772 EXPECT_TRUE(ShouldPrerenderInstantUrlOnOmniboxFocus());
773 EXPECT_EQ(80ul, EmbeddedSearchPageVersion());
774 }
775
TEST_F(SearchTest,ShouldReuseInstantSearchBasePage_PrefetchResultsFlagDisabled)776 TEST_F(SearchTest,
777 ShouldReuseInstantSearchBasePage_PrefetchResultsFlagDisabled) {
778 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
779 "EmbeddedSearch",
780 "Group1 espv:89 prefetch_results:0 reuse_instant_search_base_page:1"));
781 EXPECT_FALSE(ShouldPrefetchSearchResults());
782 EXPECT_FALSE(ShouldReuseInstantSearchBasePage());
783 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
784 }
785
TEST_F(SearchTest,ShouldReuseInstantSearchBasePage_EnabledViaFieldTrial)786 TEST_F(SearchTest, ShouldReuseInstantSearchBasePage_EnabledViaFieldTrial) {
787 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
788 "EmbeddedSearch",
789 "Group1 espv:89 prefetch_results:1 reuse_instant_search_base_page:1"));
790 EXPECT_TRUE(ShouldReuseInstantSearchBasePage());
791 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
792 }
793
TEST_F(SearchTest,ShouldReuseInstantSearchBasePage_DisabledViaFieldTrial)794 TEST_F(SearchTest, ShouldReuseInstantSearchBasePage_DisabledViaFieldTrial) {
795 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
796 "EmbeddedSearch",
797 "Group1 espv:89 prefetch_results:1 reuse_instant_search_base_page:0"));
798 EXPECT_FALSE(ShouldReuseInstantSearchBasePage());
799 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
800 }
801
TEST_F(SearchTest,ShouldShowGoogleLocalNTP_Default)802 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_Default) {
803 EXPECT_TRUE(ShouldShowGoogleLocalNTP());
804 }
805
TEST_F(SearchTest,ShouldShowGoogleLocalNTP_EnabledViaFinch)806 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_EnabledViaFinch) {
807 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
808 "EmbeddedSearch", "Group1 espv:2 google_local_ntp:1"));
809 EXPECT_TRUE(ShouldShowGoogleLocalNTP());
810 }
811
TEST_F(SearchTest,ShouldShowGoogleLocalNTP_DisabledViaFinch)812 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_DisabledViaFinch) {
813 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
814 "EmbeddedSearch", "Group1 espv:2 google_local_ntp:0"));
815 EXPECT_FALSE(ShouldShowGoogleLocalNTP());
816 }
817
TEST_F(SearchTest,ShouldReuseInstantSearchBasePage_EnabledViaCommandLine)818 TEST_F(SearchTest, ShouldReuseInstantSearchBasePage_EnabledViaCommandLine) {
819 CommandLine::ForCurrentProcess()->AppendSwitch(
820 switches::kPrefetchSearchResults);
821 // Command-line enable should override Finch.
822 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
823 "EmbeddedSearch",
824 "Group1 espv:89 prefetch_results:0 reuse_instant_search_base_page:1"));
825 EXPECT_TRUE(ShouldPrefetchSearchResults());
826 EXPECT_TRUE(ShouldReuseInstantSearchBasePage());
827 EXPECT_EQ(89ul, EmbeddedSearchPageVersion());
828 }
829
TEST_F(SearchTest,IsNTPURL)830 TEST_F(SearchTest, IsNTPURL) {
831 GURL invalid_url;
832 GURL ntp_url(chrome::kChromeUINewTabURL);
833 GURL local_ntp_url(GetLocalInstantURL(profile()));
834
835 EXPECT_FALSE(chrome::IsNTPURL(invalid_url, profile()));
836 // No margin.
837 EnableQueryExtractionForTesting();
838 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
839 GURL remote_ntp_url(GetInstantURL(profile(), kDisableStartMargin, false));
840 GURL search_url_with_search_terms("https://foo.com/url?strk&bar=abc");
841 GURL search_url_without_search_terms("https://foo.com/url?strk&bar");
842
843 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, profile()));
844 EXPECT_TRUE(chrome::IsNTPURL(local_ntp_url, profile()));
845 EXPECT_TRUE(chrome::IsNTPURL(remote_ntp_url, profile()));
846 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, profile()));
847 EXPECT_TRUE(chrome::IsNTPURL(search_url_without_search_terms, profile()));
848
849 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, NULL));
850 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, NULL));
851 EXPECT_FALSE(chrome::IsNTPURL(remote_ntp_url, NULL));
852 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, NULL));
853 EXPECT_FALSE(chrome::IsNTPURL(search_url_without_search_terms, NULL));
854 }
855
TEST_F(SearchTest,GetSearchURLs)856 TEST_F(SearchTest, GetSearchURLs) {
857 std::vector<GURL> search_urls = GetSearchURLs(profile());
858 EXPECT_EQ(2U, search_urls.size());
859 EXPECT_EQ("http://foo.com/alt#quux=", search_urls[0].spec());
860 EXPECT_EQ("http://foo.com/url?bar=", search_urls[1].spec());
861 }
862
TEST_F(SearchTest,GetSearchResultPrefetchBaseURL)863 TEST_F(SearchTest, GetSearchResultPrefetchBaseURL) {
864 // "prefetch_results" flag is disabled.
865 EXPECT_EQ(GURL(), GetSearchResultPrefetchBaseURL(profile()));
866
867 // "prefetch_results" flag is enabled via field trials.
868 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
869 "EmbeddedSearch",
870 "Group1 espv:80 prefetch_results:1"));
871 EXPECT_TRUE(ShouldPrefetchSearchResults());
872
873 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"),
874 GetSearchResultPrefetchBaseURL(profile()));
875 }
876
TEST_F(SearchTest,ForceInstantResultsParam)877 TEST_F(SearchTest, ForceInstantResultsParam) {
878 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
879 "Group1 espv:2"));
880 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
881 EXPECT_EQ("ion=1&", ForceInstantResultsParam(true));
882 EXPECT_EQ(std::string(), ForceInstantResultsParam(false));
883 }
884
885 struct ExtractSearchTermsTestCase {
886 const char* url;
887 const char* expected_result;
888 const char* comment;
889 };
890
TEST_F(SearchTest,ExtractSearchTermsFromURL)891 TEST_F(SearchTest, ExtractSearchTermsFromURL) {
892 const ExtractSearchTermsTestCase kTestCases[] = {
893 {chrome::kChromeSearchLocalNtpUrl, "", "NTP url"},
894 {"https://foo.com/instant?strk", "", "Invalid search url"},
895 {"https://foo.com/instant#strk", "", "Invalid search url"},
896 {"https://foo.com/alt#quux=foo", "foo", "Valid search url"},
897 {"https://foo.com/alt#quux=foo&strk", "foo", "Valid search url"}
898 };
899
900 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
901 const ExtractSearchTermsTestCase& test = kTestCases[i];
902 EXPECT_EQ(
903 test.expected_result,
904 base::UTF16ToASCII(chrome::ExtractSearchTermsFromURL(profile(),
905 GURL(test.url))))
906 << test.url << " " << test.comment;
907 }
908 }
909
910 struct QueryExtractionAllowedTestCase {
911 const char* url;
912 bool expected_result;
913 const char* comment;
914 };
915
TEST_F(SearchTest,IsQueryExtractionAllowedForURL)916 TEST_F(SearchTest, IsQueryExtractionAllowedForURL) {
917 const QueryExtractionAllowedTestCase kTestCases[] = {
918 {"http://foo.com/instant?strk", false, "HTTP URL"},
919 {"https://foo.com/instant?strk", true, "Valid URL"},
920 {"https://foo.com/instant?", false,
921 "No search terms replacement key"},
922 {"https://foo.com/alt#quux=foo", false,
923 "No search terms replacement key"},
924 {"https://foo.com/alt#quux=foo&strk", true, "Valid search url"}
925 };
926
927 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
928 const QueryExtractionAllowedTestCase& test = kTestCases[i];
929 EXPECT_EQ(test.expected_result,
930 chrome::IsQueryExtractionAllowedForURL(profile(), GURL(test.url)))
931 << test.url << " " << test.comment;
932 }
933 }
934
935 class SearchURLTest : public SearchTest {
936 protected:
SetSearchProvider(bool set_ntp_url,bool insecure_ntp_url)937 virtual void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url)
938 OVERRIDE {
939 TemplateURLService* template_url_service =
940 TemplateURLServiceFactory::GetForProfile(profile());
941 TemplateURLData data;
942 data.SetURL("{google:baseURL}search?"
943 "{google:instantExtendedEnabledParameter}q={searchTerms}");
944 data.search_terms_replacement_key = "espv";
945 template_url_ = new TemplateURL(data);
946 // |template_url_service| takes ownership of |template_url_|.
947 template_url_service->Add(template_url_);
948 template_url_service->SetUserSelectedDefaultSearchProvider(template_url_);
949 }
950
951 TemplateURL* template_url_;
952 };
953
TEST_F(SearchURLTest,QueryExtractionEnabled)954 TEST_F(SearchURLTest, QueryExtractionEnabled) {
955 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
956 EnableQueryExtractionForTesting();
957 EXPECT_TRUE(IsQueryExtractionEnabled());
958 TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
959 GURL result(template_url_->url_ref().ReplaceSearchTerms(
960 search_terms_args, UIThreadSearchTermsData(profile())));
961 ASSERT_TRUE(result.is_valid());
962 // Query extraction is enabled. Make sure
963 // {google:instantExtendedEnabledParameter} is set in the search URL.
964 EXPECT_EQ("http://www.google.com/search?espv=2&q=foo", result.spec());
965 }
966
TEST_F(SearchURLTest,QueryExtractionDisabled)967 TEST_F(SearchURLTest, QueryExtractionDisabled) {
968 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
969 EXPECT_FALSE(IsQueryExtractionEnabled());
970 TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
971 GURL result(template_url_->url_ref().ReplaceSearchTerms(
972 search_terms_args, UIThreadSearchTermsData(profile())));
973 ASSERT_TRUE(result.is_valid());
974 // Query extraction is disabled. Make sure
975 // {google:instantExtendedEnabledParameter} is not set in the search URL.
976 EXPECT_EQ("http://www.google.com/search?q=foo", result.spec());
977 }
978
979 typedef SearchTest InstantExtendedEnabledParamTest;
980
TEST_F(InstantExtendedEnabledParamTest,QueryExtractionDisabled)981 TEST_F(InstantExtendedEnabledParamTest, QueryExtractionDisabled) {
982 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
983 "Group1 espv:12"));
984 // Make sure InstantExtendedEnabledParam() returns an empty string for search
985 // requests.
986 #if defined(OS_IOS) || defined(OS_ANDROID)
987 // Query extraction is always enabled on mobile.
988 EXPECT_TRUE(IsQueryExtractionEnabled());
989 EXPECT_EQ("espv=12&", InstantExtendedEnabledParam(true));
990 #else
991 EXPECT_FALSE(IsQueryExtractionEnabled());
992 EXPECT_EQ("", InstantExtendedEnabledParam(true));
993 #endif
994 EXPECT_EQ("espv=12&", InstantExtendedEnabledParam(false));
995 }
996
TEST_F(InstantExtendedEnabledParamTest,QueryExtractionEnabled)997 TEST_F(InstantExtendedEnabledParamTest, QueryExtractionEnabled) {
998 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
999 "EmbeddedSearch", "Group1 espv:10 query_extraction:1"));
1000 EXPECT_TRUE(IsQueryExtractionEnabled());
1001 // Make sure InstantExtendedEnabledParam() returns a non-empty param string
1002 // for search requests.
1003 EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(true));
1004 EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(false));
1005 }
1006
TEST_F(InstantExtendedEnabledParamTest,UseDefaultEmbeddedSearchPageVersion)1007 TEST_F(InstantExtendedEnabledParamTest, UseDefaultEmbeddedSearchPageVersion) {
1008 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1009 "EmbeddedSearch", "Group1 espv:-1 query_extraction:1"));
1010 EXPECT_TRUE(IsQueryExtractionEnabled());
1011 #if defined(OS_IOS) || defined(OS_ANDROID)
1012 EXPECT_EQ("espv=1&", InstantExtendedEnabledParam(true));
1013 EXPECT_EQ("espv=1&", InstantExtendedEnabledParam(false));
1014 #else
1015 EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(true));
1016 EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(false));
1017 #endif
1018 }
1019
1020 typedef SearchTest IsQueryExtractionEnabledTest;
1021
TEST_F(IsQueryExtractionEnabledTest,NotSet)1022 TEST_F(IsQueryExtractionEnabledTest, NotSet) {
1023 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1024 "EmbeddedSearch", "Group1 espv:2"));
1025 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
1026 EXPECT_FALSE(IsQueryExtractionEnabled());
1027 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
1028 }
1029
TEST_F(IsQueryExtractionEnabledTest,EnabledViaFieldTrial)1030 TEST_F(IsQueryExtractionEnabledTest, EnabledViaFieldTrial) {
1031 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1032 "EmbeddedSearch", "Group1 espv:2 query_extraction:1"));
1033 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
1034 EXPECT_TRUE(IsQueryExtractionEnabled());
1035 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
1036 }
1037
TEST_F(IsQueryExtractionEnabledTest,DisabledViaFieldTrial)1038 TEST_F(IsQueryExtractionEnabledTest, DisabledViaFieldTrial) {
1039 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1040 "EmbeddedSearch", "Group1 espv:2 query_extraction:0"));
1041 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
1042 EXPECT_FALSE(IsQueryExtractionEnabled());
1043 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
1044 }
1045
TEST_F(IsQueryExtractionEnabledTest,EnabledViaCommandLine)1046 TEST_F(IsQueryExtractionEnabledTest, EnabledViaCommandLine) {
1047 EnableQueryExtractionForTesting();
1048 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1049 "EmbeddedSearch", "Group1 espv:2 query_extraction:0"));
1050 EXPECT_TRUE(IsInstantExtendedAPIEnabled());
1051 EXPECT_TRUE(IsQueryExtractionEnabled());
1052 EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
1053 }
1054
1055 typedef SearchTest ShouldHideTopVerbatimTest;
1056
TEST_F(ShouldHideTopVerbatimTest,DoNotHideByDefault)1057 TEST_F(ShouldHideTopVerbatimTest, DoNotHideByDefault) {
1058 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
1059 "Control"));
1060 EXPECT_FALSE(ShouldHideTopVerbatimMatch());
1061 }
1062
TEST_F(ShouldHideTopVerbatimTest,DoNotHideInInstantExtended)1063 TEST_F(ShouldHideTopVerbatimTest, DoNotHideInInstantExtended) {
1064 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
1065 "Group1"));
1066 EXPECT_FALSE(ShouldHideTopVerbatimMatch());
1067 }
1068
TEST_F(ShouldHideTopVerbatimTest,EnableByFlagInInstantExtended)1069 TEST_F(ShouldHideTopVerbatimTest, EnableByFlagInInstantExtended) {
1070 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
1071 "Group1 hide_verbatim:1"));
1072 EXPECT_TRUE(ShouldHideTopVerbatimMatch());
1073 }
1074
TEST_F(ShouldHideTopVerbatimTest,EnableByFlagOutsideInstantExtended)1075 TEST_F(ShouldHideTopVerbatimTest, EnableByFlagOutsideInstantExtended) {
1076 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1077 "EmbeddedSearch", "Controll1 hide_verbatim:1"));
1078 EXPECT_TRUE(ShouldHideTopVerbatimMatch());
1079 }
1080
TEST_F(ShouldHideTopVerbatimTest,DisableByFlag)1081 TEST_F(ShouldHideTopVerbatimTest, DisableByFlag) {
1082 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
1083 "Group1 hide_verbatim:0"));
1084 EXPECT_FALSE(ShouldHideTopVerbatimMatch());
1085 }
1086
1087 typedef SearchTest DisplaySearchButtonTest;
1088
TEST_F(DisplaySearchButtonTest,NotSet)1089 TEST_F(DisplaySearchButtonTest, NotSet) {
1090 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1091 "EmbeddedSearch", "Group1 espv:2"));
1092 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions());
1093 }
1094
TEST_F(DisplaySearchButtonTest,Never)1095 TEST_F(DisplaySearchButtonTest, Never) {
1096 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1097 "EmbeddedSearch", "Group1 espv:2 display_search_button:0"));
1098 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions());
1099 }
1100
TEST_F(DisplaySearchButtonTest,CommandLineNever)1101 TEST_F(DisplaySearchButtonTest, CommandLineNever) {
1102 CommandLine::ForCurrentProcess()->AppendSwitch(
1103 switches::kDisableSearchButtonInOmnibox);
1104 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions());
1105
1106 // Command-line disable should override the field trial.
1107 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1108 "EmbeddedSearch", "Group1 espv:2 display_search_button:1"));
1109 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions());
1110 }
1111
TEST_F(DisplaySearchButtonTest,ForSearchTermReplacement)1112 TEST_F(DisplaySearchButtonTest, ForSearchTermReplacement) {
1113 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1114 "EmbeddedSearch", "Group1 espv:2 display_search_button:1"));
1115 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR, GetDisplaySearchButtonConditions());
1116 }
1117
TEST_F(DisplaySearchButtonTest,CommandLineForSearchTermReplacement)1118 TEST_F(DisplaySearchButtonTest, CommandLineForSearchTermReplacement) {
1119 CommandLine::ForCurrentProcess()->AppendSwitch(
1120 switches::kEnableSearchButtonInOmniboxForStr);
1121 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR, GetDisplaySearchButtonConditions());
1122 }
1123
TEST_F(DisplaySearchButtonTest,ForSearchTermReplacementOrInputInProgress)1124 TEST_F(DisplaySearchButtonTest, ForSearchTermReplacementOrInputInProgress) {
1125 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1126 "EmbeddedSearch", "Group1 espv:2 display_search_button:2"));
1127 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP,
1128 GetDisplaySearchButtonConditions());
1129 }
1130
TEST_F(DisplaySearchButtonTest,CommandLineForSearchTermReplacementOrInputInProgress)1131 TEST_F(DisplaySearchButtonTest,
1132 CommandLineForSearchTermReplacementOrInputInProgress) {
1133 CommandLine::ForCurrentProcess()->AppendSwitch(
1134 switches::kEnableSearchButtonInOmniboxForStrOrIip);
1135 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP,
1136 GetDisplaySearchButtonConditions());
1137 }
1138
TEST_F(DisplaySearchButtonTest,Always)1139 TEST_F(DisplaySearchButtonTest, Always) {
1140 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1141 "EmbeddedSearch", "Group1 espv:2 display_search_button:3"));
1142 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_ALWAYS, GetDisplaySearchButtonConditions());
1143 }
1144
TEST_F(DisplaySearchButtonTest,CommandLineAlways)1145 TEST_F(DisplaySearchButtonTest, CommandLineAlways) {
1146 CommandLine::ForCurrentProcess()->AppendSwitch(
1147 switches::kEnableSearchButtonInOmniboxAlways);
1148 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_ALWAYS, GetDisplaySearchButtonConditions());
1149 }
1150
TEST_F(DisplaySearchButtonTest,InvalidValue)1151 TEST_F(DisplaySearchButtonTest, InvalidValue) {
1152 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1153 "EmbeddedSearch", "Group1 espv:2 display_search_button:4"));
1154 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions());
1155 }
1156
1157 typedef SearchTest OriginChipTest;
1158
TEST_F(OriginChipTest,NotSet)1159 TEST_F(OriginChipTest, NotSet) {
1160 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1161 "EmbeddedSearch", "Group1 espv:2"));
1162 EXPECT_FALSE(ShouldDisplayOriginChip());
1163 EXPECT_EQ(ORIGIN_CHIP_DISABLED, GetOriginChipCondition());
1164 }
1165
TEST_F(OriginChipTest,Disabled)1166 TEST_F(OriginChipTest, Disabled) {
1167 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1168 "EmbeddedSearch", "Group1 espv:2 origin_chip:0"));
1169 EXPECT_FALSE(ShouldDisplayOriginChip());
1170 EXPECT_EQ(ORIGIN_CHIP_DISABLED, GetOriginChipCondition());
1171 }
1172
TEST_F(OriginChipTest,Always)1173 TEST_F(OriginChipTest, Always) {
1174 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1175 "EmbeddedSearch", "Group1 espv:2 origin_chip:1"));
1176 EXPECT_TRUE(ShouldDisplayOriginChip());
1177 EXPECT_EQ(ORIGIN_CHIP_ALWAYS, GetOriginChipCondition());
1178 }
1179
TEST_F(OriginChipTest,OnSrp)1180 TEST_F(OriginChipTest, OnSrp) {
1181 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1182 "EmbeddedSearch", "Group1 espv:2 origin_chip:2"));
1183 EXPECT_TRUE(ShouldDisplayOriginChip());
1184 EXPECT_EQ(ORIGIN_CHIP_ON_SRP, GetOriginChipCondition());
1185 }
1186
TEST_F(OriginChipTest,InvalidValue)1187 TEST_F(OriginChipTest, InvalidValue) {
1188 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1189 "EmbeddedSearch", "Group1 espv:2 origin_chip:3"));
1190 EXPECT_FALSE(ShouldDisplayOriginChip());
1191 EXPECT_EQ(ORIGIN_CHIP_DISABLED, GetOriginChipCondition());
1192 }
1193
TEST_F(OriginChipTest,CommandLineDisabled)1194 TEST_F(OriginChipTest, CommandLineDisabled) {
1195 CommandLine::ForCurrentProcess()->AppendSwitch(
1196 switches::kDisableOriginChip);
1197 EXPECT_FALSE(ShouldDisplayOriginChip());
1198 EXPECT_EQ(ORIGIN_CHIP_DISABLED, GetOriginChipCondition());
1199
1200 // Command-line disable should override the field trial.
1201 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1202 "EmbeddedSearch", "Group1 espv:2 origin_chip:1"));
1203 EXPECT_FALSE(ShouldDisplayOriginChip());
1204 EXPECT_EQ(ORIGIN_CHIP_DISABLED, GetOriginChipCondition());
1205 }
1206
TEST_F(OriginChipTest,CommandLineAlways)1207 TEST_F(OriginChipTest, CommandLineAlways) {
1208 CommandLine::ForCurrentProcess()->AppendSwitch(
1209 switches::kEnableOriginChipAlways);
1210 EXPECT_TRUE(ShouldDisplayOriginChip());
1211 EXPECT_EQ(ORIGIN_CHIP_ALWAYS, GetOriginChipCondition());
1212 }
1213
TEST_F(OriginChipTest,CommandLineOnSrp)1214 TEST_F(OriginChipTest, CommandLineOnSrp) {
1215 CommandLine::ForCurrentProcess()->AppendSwitch(
1216 switches::kEnableOriginChipOnSrp);
1217 EXPECT_TRUE(ShouldDisplayOriginChip());
1218 EXPECT_EQ(ORIGIN_CHIP_ON_SRP, GetOriginChipCondition());
1219 }
1220
1221 } // namespace chrome
1222