search_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 "chrome/browser/managed_mode/managed_mode_url_filter.h" 12#include "chrome/browser/managed_mode/managed_user_service.h" 13#include "chrome/browser/managed_mode/managed_user_service_factory.h" 14#include "chrome/browser/search/instant_service.h" 15#include "chrome/browser/search/instant_service_factory.h" 16#include "chrome/browser/search/search.h" 17#include "chrome/browser/search_engines/search_terms_data.h" 18#include "chrome/browser/search_engines/template_url_service.h" 19#include "chrome/browser/search_engines/template_url_service_factory.h" 20#include "chrome/browser/ui/tabs/tab_strip_model.h" 21#include "chrome/common/chrome_switches.h" 22#include "chrome/common/pref_names.h" 23#include "chrome/common/url_constants.h" 24#include "chrome/test/base/browser_with_test_window_test.h" 25#include "chrome/test/base/ui_test_utils.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" 33 34namespace chrome { 35 36class EmbeddedSearchFieldTrialTest : public testing::Test { 37 protected: 38 virtual void SetUp() { 39 field_trial_list_.reset(new base::FieldTrialList( 40 new metrics::SHA1EntropyProvider("42"))); 41 base::StatisticsRecorder::Initialize(); 42 } 43 44 private: 45 scoped_ptr<base::FieldTrialList> field_trial_list_; 46}; 47 48TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) { 49 FieldTrialFlags flags; 50 51 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 52 EXPECT_EQ(0ul, flags.size()); 53 54 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 55 "Group77")); 56 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 57 EXPECT_EQ(0ul, flags.size()); 58} 59 60TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidNumber) { 61 FieldTrialFlags flags; 62 63 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 64 "Group77.2")); 65 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 66 EXPECT_EQ(0ul, flags.size()); 67} 68 69TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidName) { 70 FieldTrialFlags flags; 71 72 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 73 "Invalid77")); 74 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 75 EXPECT_EQ(0ul, flags.size()); 76} 77 78TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidGroup) { 79 FieldTrialFlags flags; 80 81 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 82 "Group77")); 83 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 84 EXPECT_EQ(0ul, flags.size()); 85} 86 87TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) { 88 FieldTrialFlags flags; 89 90 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 91 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 92 "Group77 foo:6")); 93 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 94 EXPECT_EQ(1ul, flags.size()); 95 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 96} 97 98TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewName) { 99 FieldTrialFlags flags; 100 101 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 102 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 103 "Group77 foo:6")); 104 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 105 EXPECT_EQ(1ul, flags.size()); 106 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 107} 108 109TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewNameOverridesOld) { 110 FieldTrialFlags flags; 111 112 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 113 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 114 "Group77 foo:6")); 115 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 116 "Group78 foo:5")); 117 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 118 EXPECT_EQ(1ul, flags.size()); 119 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 120} 121 122TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) { 123 FieldTrialFlags flags; 124 125 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 126 "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs")); 127 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 128 EXPECT_EQ(3ul, flags.size()); 129 EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags)); 130 EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags)); 131 EXPECT_EQ("dogs", 132 GetStringValueForFlagWithDefault("cat", std::string(), flags)); 133 EXPECT_EQ("default", 134 GetStringValueForFlagWithDefault("moose", "default", flags)); 135} 136 137TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) { 138 FieldTrialFlags flags; 139 140 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 141 "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs DISABLED")); 142 EXPECT_FALSE(GetFieldTrialInfo(&flags)); 143 EXPECT_EQ(0ul, flags.size()); 144} 145 146TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) { 147 FieldTrialFlags flags; 148 149 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 150 "EmbeddedSearch", "Control77 bar:1 baz:7 cat:dogs")); 151 EXPECT_TRUE(GetFieldTrialInfo(&flags)); 152 EXPECT_EQ(3ul, flags.size()); 153} 154 155class SearchTest : public BrowserWithTestWindowTest { 156 protected: 157 virtual void SetUp() OVERRIDE { 158 BrowserWithTestWindowTest::SetUp(); 159 field_trial_list_.reset(new base::FieldTrialList( 160 new metrics::SHA1EntropyProvider("42"))); 161 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 162 profile(), &TemplateURLServiceFactory::BuildInstanceFor); 163 TemplateURLService* template_url_service = 164 TemplateURLServiceFactory::GetForProfile(profile()); 165 ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service); 166 SetSearchProvider(true, false); 167 } 168 169 void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url) { 170 TemplateURLService* template_url_service = 171 TemplateURLServiceFactory::GetForProfile(profile()); 172 TemplateURLData data; 173 data.SetURL("http://foo.com/url?bar={searchTerms}"); 174 data.instant_url = "http://foo.com/instant?" 175 "{google:omniboxStartMarginParameter}{google:forceInstantResults}" 176 "foo=foo#foo=foo&strk"; 177 if (set_ntp_url) { 178 data.new_tab_url = (insecure_ntp_url ? "http" : "https") + 179 std::string("://foo.com/newtab?strk"); 180 } 181 data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}"); 182 data.search_terms_replacement_key = "strk"; 183 184 TemplateURL* template_url = new TemplateURL(profile(), data); 185 // Takes ownership of |template_url|. 186 template_url_service->Add(template_url); 187 template_url_service->SetDefaultSearchProvider(template_url); 188 } 189 190 // Build an Instant URL with or without a valid search terms replacement key 191 // as per |has_search_term_replacement_key|. Set that URL as the instant URL 192 // for the default search provider. 193 void SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key) { 194 TemplateURLService* template_url_service = 195 TemplateURLServiceFactory::GetForProfile(profile()); 196 197 static const char kInstantURLWithStrk[] = 198 "http://foo.com/instant?foo=foo#foo=foo&strk"; 199 static const char kInstantURLNoStrk[] = 200 "http://foo.com/instant?foo=foo#foo=foo"; 201 202 TemplateURLData data; 203 data.SetURL("http://foo.com/url?bar={searchTerms}"); 204 data.instant_url = (has_search_term_replacement_key ? 205 kInstantURLWithStrk : kInstantURLNoStrk); 206 data.search_terms_replacement_key = "strk"; 207 208 TemplateURL* template_url = new TemplateURL(profile(), data); 209 // Takes ownership of |template_url|. 210 template_url_service->Add(template_url); 211 template_url_service->SetDefaultSearchProvider(template_url); 212 } 213 214 bool InInstantProcess(const content::WebContents* contents) { 215 InstantService* instant_service = 216 InstantServiceFactory::GetForProfile(profile()); 217 return instant_service->IsInstantProcess( 218 contents->GetRenderProcessHost()->GetID()); 219 } 220 221 scoped_ptr<base::FieldTrialList> field_trial_list_; 222}; 223 224struct SearchTestCase { 225 const char* url; 226 bool expected_result; 227 const char* comment; 228}; 229 230TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) { 231 EnableQueryExtractionForTesting(); 232 233 const SearchTestCase kTestCases[] = { 234 {chrome::kChromeSearchLocalNtpUrl, true, ""}, 235 {"https://foo.com/instant?strk", true, ""}, 236 {"https://foo.com/instant#strk", true, ""}, 237 {"https://foo.com/instant?strk=0", true, ""}, 238 {"https://foo.com/url?strk", true, ""}, 239 {"https://foo.com/alt?strk", true, ""}, 240 {"http://foo.com/instant", false, "Non-HTTPS"}, 241 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 242 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 243 {"https://foo.com/instant", false, "No search terms replacement"}, 244 {"https://foo.com/?strk", false, "Non-exact path"}, 245 }; 246 247 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 248 const SearchTestCase& test = kTestCases[i]; 249 EXPECT_EQ(test.expected_result, 250 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 251 << test.url << " " << test.comment; 252 } 253} 254 255TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabledNotOnSRP) { 256 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 257 "EmbeddedSearch", "Group1 espv:2 suppress_on_srp:1")); 258 259 const SearchTestCase kTestCases[] = { 260 {chrome::kChromeSearchLocalNtpUrl, true, ""}, 261 {"https://foo.com/instant?strk", true, ""}, 262 {"https://foo.com/instant#strk", true, ""}, 263 {"https://foo.com/instant?strk=0", true, ""}, 264 {"https://foo.com/url?strk", false, "Disabled on SRP"}, 265 {"https://foo.com/alt?strk", false, "Disabled ON SRP"}, 266 {"http://foo.com/instant", false, "Non-HTTPS"}, 267 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 268 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 269 {"https://foo.com/instant", false, "No search terms replacement"}, 270 {"https://foo.com/?strk", false, "Non-exact path"}, 271 }; 272 273 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 274 const SearchTestCase& test = kTestCases[i]; 275 EXPECT_EQ(test.expected_result, 276 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 277 << test.url << " " << test.comment; 278 } 279} 280 281TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) { 282 EnableQueryExtractionForTesting(); 283 284 const SearchTestCase kTestCases[] = { 285 {"chrome-search://local-ntp", true, "Local NTP"}, 286 {"chrome-search://online-ntp", true, "Online NTP"}, 287 {"invalid-scheme://local-ntp", false, "Invalid Local NTP URL"}, 288 {"invalid-scheme://online-ntp", false, "Invalid Online NTP URL"}, 289 {"chrome-search://foo.com", false, "Search result page"}, 290 {"https://foo.com/instant?strk", false, ""}, 291 {"https://foo.com/instant#strk", false, ""}, 292 {"https://foo.com/instant?strk=0", false, ""}, 293 {"https://foo.com/url?strk", false, ""}, 294 {"https://foo.com/alt?strk", false, ""}, 295 {"http://foo.com/instant", false, "Non-HTTPS"}, 296 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 297 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 298 {"https://foo.com/instant", false, "No search terms replacement"}, 299 {"https://foo.com/?strk", false, "Non-exact path"}, 300 }; 301 302 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 303 const SearchTestCase& test = kTestCases[i]; 304 EXPECT_EQ(test.expected_result, 305 ShouldUseProcessPerSiteForInstantURL(GURL(test.url), profile())) 306 << test.url << " " << test.comment; 307 } 308} 309 310// Each test case represents a navigation to |start_url| followed by a 311// navigation to |end_url|. We will check whether each navigation lands in an 312// Instant process, and also whether the navigation from start to end re-uses 313// the same SiteInstance (and hence the same RenderViewHost, etc.). 314const struct ProcessIsolationTestCase { 315 const char* description; 316 const char* start_url; 317 bool start_in_instant_process; 318 const char* end_url; 319 bool end_in_instant_process; 320 bool same_site_instance; 321} kProcessIsolationTestCases[] = { 322 {"Local NTP -> SRP", 323 "chrome-search://local-ntp", true, 324 "https://foo.com/url?strk", true, false }, 325 {"Local NTP -> Regular", 326 "chrome-search://local-ntp", true, 327 "https://foo.com/other", false, false }, 328 {"Remote NTP -> SRP", 329 "https://foo.com/instant?strk", true, 330 "https://foo.com/url?strk", true, false }, 331 {"Remote NTP -> Regular", 332 "https://foo.com/instant?strk", true, 333 "https://foo.com/other", false, false }, 334 {"SRP -> SRP", 335 "https://foo.com/url?strk", true, 336 "https://foo.com/url?strk", true, true }, 337 {"SRP -> Regular", 338 "https://foo.com/url?strk", true, 339 "https://foo.com/other", false, false }, 340 {"Regular -> SRP", 341 "https://foo.com/other", false, 342 "https://foo.com/url?strk", true, false }, 343}; 344 345TEST_F(SearchTest, ProcessIsolation) { 346 EnableQueryExtractionForTesting(); 347 348 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { 349 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; 350 AddTab(browser(), GURL("chrome://blank")); 351 const content::WebContents* contents = 352 browser()->tab_strip_model()->GetActiveWebContents(); 353 354 // Navigate to start URL. 355 NavigateAndCommitActiveTab(GURL(test.start_url)); 356 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents)) 357 << test.description; 358 359 // Save state. 360 const scoped_refptr<content::SiteInstance> start_site_instance = 361 contents->GetSiteInstance(); 362 const content::RenderProcessHost* start_rph = 363 contents->GetRenderProcessHost(); 364 const content::RenderViewHost* start_rvh = 365 contents->GetRenderViewHost(); 366 367 // Navigate to end URL. 368 NavigateAndCommitActiveTab(GURL(test.end_url)); 369 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents)) 370 << test.description; 371 372 EXPECT_EQ(test.same_site_instance, 373 start_site_instance == contents->GetSiteInstance()) 374 << test.description; 375 EXPECT_EQ(test.same_site_instance, 376 start_rvh == contents->GetRenderViewHost()) 377 << test.description; 378 EXPECT_EQ(test.same_site_instance, 379 start_rph == contents->GetRenderProcessHost()) 380 << test.description; 381 } 382} 383 384TEST_F(SearchTest, ProcessIsolation_RendererInitiated) { 385 EnableQueryExtractionForTesting(); 386 387 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { 388 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; 389 AddTab(browser(), GURL("chrome://blank")); 390 content::WebContents* contents = 391 browser()->tab_strip_model()->GetActiveWebContents(); 392 393 // Navigate to start URL. 394 NavigateAndCommitActiveTab(GURL(test.start_url)); 395 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents)) 396 << test.description; 397 398 // Save state. 399 const scoped_refptr<content::SiteInstance> start_site_instance = 400 contents->GetSiteInstance(); 401 const content::RenderProcessHost* start_rph = 402 contents->GetRenderProcessHost(); 403 const content::RenderViewHost* start_rvh = 404 contents->GetRenderViewHost(); 405 406 // Navigate to end URL via a renderer-initiated navigation. 407 content::NavigationController* controller = &contents->GetController(); 408 content::NavigationController::LoadURLParams load_params( 409 GURL(test.end_url)); 410 load_params.is_renderer_initiated = true; 411 load_params.transition_type = content::PAGE_TRANSITION_LINK; 412 413 controller->LoadURLWithParams(load_params); 414 CommitPendingLoad(controller); 415 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents)) 416 << test.description; 417 418 EXPECT_EQ(test.same_site_instance, 419 start_site_instance == contents->GetSiteInstance()) 420 << test.description; 421 EXPECT_EQ(test.same_site_instance, 422 start_rvh == contents->GetRenderViewHost()) 423 << test.description; 424 EXPECT_EQ(test.same_site_instance, 425 start_rph == contents->GetRenderProcessHost()) 426 << test.description; 427 } 428} 429 430const SearchTestCase kInstantNTPTestCases[] = { 431 {"https://foo.com/instant?strk", true, "Valid Instant URL"}, 432 {"https://foo.com/instant#strk", true, "Valid Instant URL"}, 433 {"https://foo.com/url?strk", true, "Valid search URL"}, 434 {"https://foo.com/url#strk", true, "Valid search URL"}, 435 {"https://foo.com/alt?strk", true, "Valid alternative URL"}, 436 {"https://foo.com/alt#strk", true, "Valid alternative URL"}, 437 {"https://foo.com/url?strk&bar=", true, "No query terms"}, 438 {"https://foo.com/url?strk&q=abc", true, "No query terms key"}, 439 {"https://foo.com/url?strk#bar=abc", true, "Query terms key in ref"}, 440 {"https://foo.com/url?strk&bar=abc", false, "Has query terms"}, 441 {"http://foo.com/instant?strk=1", false, "Insecure URL"}, 442 {"https://foo.com/instant", false, "No search term replacement"}, 443 {"chrome://blank/", false, "Chrome scheme"}, 444 {"chrome-search://foo", false, "Chrome-search scheme"}, 445 {chrome::kChromeSearchLocalNtpUrl, true, "Local new tab page"}, 446 {"https://bar.com/instant?strk=1", false, "Random non-search page"}, 447}; 448 449TEST_F(SearchTest, InstantNTPExtendedEnabled) { 450 EnableQueryExtractionForTesting(); 451 // TODO(samarth): update test cases to use cacheable NTP URLs and remove this. 452 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 453 "InstantExtended", "Group1 use_cacheable_ntp:0")); 454 AddTab(browser(), GURL("chrome://blank")); 455 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 456 const SearchTestCase& test = kInstantNTPTestCases[i]; 457 NavigateAndCommitActiveTab(GURL(test.url)); 458 const content::WebContents* contents = 459 browser()->tab_strip_model()->GetWebContentsAt(0); 460 EXPECT_EQ(test.expected_result, IsInstantNTP(contents)) 461 << test.url << " " << test.comment; 462 } 463} 464 465TEST_F(SearchTest, InstantNTPCustomNavigationEntry) { 466 EnableQueryExtractionForTesting(); 467 // TODO(samarth): update test cases to use cacheable NTP URLs and remove this. 468 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 469 "InstantExtended", "Group1 use_cacheable_ntp:0")); 470 AddTab(browser(), GURL("chrome://blank")); 471 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 472 const SearchTestCase& test = kInstantNTPTestCases[i]; 473 NavigateAndCommitActiveTab(GURL(test.url)); 474 content::WebContents* contents = 475 browser()->tab_strip_model()->GetWebContentsAt(0); 476 content::NavigationController& controller = contents->GetController(); 477 controller.SetTransientEntry( 478 controller.CreateNavigationEntry(GURL("chrome://blank"), 479 content::Referrer(), 480 content::PAGE_TRANSITION_LINK, 481 false, 482 std::string(), 483 contents->GetBrowserContext())); 484 // The active entry is chrome://blank and not an NTP. 485 EXPECT_FALSE(IsInstantNTP(contents)); 486 EXPECT_EQ(test.expected_result, 487 NavEntryIsInstantNTP(contents, 488 controller.GetLastCommittedEntry())) 489 << test.url << " " << test.comment; 490 } 491} 492 493TEST_F(SearchTest, InstantCacheableNTPNavigationEntry) { 494 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 495 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 496 497 AddTab(browser(), GURL("chrome://blank")); 498 content::WebContents* contents = 499 browser()->tab_strip_model()->GetWebContentsAt(0); 500 content::NavigationController& controller = contents->GetController(); 501 // Local NTP. 502 NavigateAndCommitActiveTab(GURL(chrome::kChromeSearchLocalNtpUrl)); 503 EXPECT_TRUE(NavEntryIsInstantNTP(contents, 504 controller.GetLastCommittedEntry())); 505 // Instant page is not cacheable NTP. 506 NavigateAndCommitActiveTab(GetInstantURL(profile(), kDisableStartMargin, 507 false)); 508 EXPECT_FALSE(NavEntryIsInstantNTP(contents, 509 controller.GetLastCommittedEntry())); 510 // Test Cacheable NTP 511 NavigateAndCommitActiveTab(chrome::GetNewTabPageURL(profile())); 512 EXPECT_TRUE(NavEntryIsInstantNTP(contents, 513 controller.GetLastCommittedEntry())); 514} 515 516TEST_F(SearchTest, UseLocalNTPInIncognito) { 517 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 518 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 519 EXPECT_EQ(GURL(), chrome::GetNewTabPageURL( 520 profile()->GetOffTheRecordProfile())); 521} 522 523TEST_F(SearchTest, UseLocalNTPIfNTPURLIsInsecure) { 524 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 525 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 526 // Set an insecure new tab page URL and verify that it's ignored. 527 SetSearchProvider(true, true); 528 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), 529 chrome::GetNewTabPageURL(profile())); 530} 531 532TEST_F(SearchTest, UseLocalNTPIfNTPURLIsNotSet) { 533 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 534 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 535 // Set an insecure new tab page URL and verify that it's ignored. 536 SetSearchProvider(false, true); 537 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), 538 chrome::GetNewTabPageURL(profile())); 539} 540 541TEST_F(SearchTest, UseLocalNTPIfNTPURLIsBlockedForSupervisedUser) { 542 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 543 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 544 545 // Block access to foo.com in the URL filter. 546 ManagedUserService* managed_user_service = 547 ManagedUserServiceFactory::GetForProfile(profile()); 548 ManagedModeURLFilter* url_filter = 549 managed_user_service->GetURLFilterForUIThread(); 550 std::map<std::string, bool> hosts; 551 hosts["foo.com"] = false; 552 url_filter->SetManualHosts(&hosts); 553 554 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), 555 chrome::GetNewTabPageURL(profile())); 556 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false)); 557} 558 559TEST_F(SearchTest, GetInstantURL) { 560 // No Instant URL because "strk" is missing. 561 SetDefaultInstantTemplateUrl(false); 562 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false)); 563 564 // Set an Instant URL with a valid search terms replacement key. 565 SetDefaultInstantTemplateUrl(true); 566 567 // Now there should be a valid Instant URL. Note the HTTPS "upgrade". 568 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 569 GetInstantURL(profile(), kDisableStartMargin, false)); 570 571 // Enable suggest. No difference. 572 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 573 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 574 GetInstantURL(profile(), kDisableStartMargin, false)); 575 576 // Disable suggest. No Instant URL. 577 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false); 578 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin, false)); 579} 580 581TEST_F(SearchTest, StartMarginCGI) { 582 // No margin. 583 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 584 585 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 586 GetInstantURL(profile(), kDisableStartMargin, false)); 587 588 // With start margin. 589 EXPECT_EQ(GURL("https://foo.com/instant?es_sm=10&foo=foo#foo=foo&strk"), 590 GetInstantURL(profile(), 10, false)); 591} 592 593TEST_F(SearchTest, InstantSearchEnabledCGI) { 594 // Disable Instant Search. 595 // Make sure {google:forceInstantResults} is not set in the Instant URL. 596 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 597 GetInstantURL(profile(), kDisableStartMargin, false)); 598 599 // Enable Instant Search. 600 // Make sure {google:forceInstantResults} is set in the Instant URL. 601 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"), 602 GetInstantURL(profile(), kDisableStartMargin, true)); 603} 604 605TEST_F(SearchTest, CommandLineOverrides) { 606 GURL local_instant_url(GetLocalInstantURL(profile())); 607 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 608 609 TemplateURLService* template_url_service = 610 TemplateURLServiceFactory::GetForProfile(profile()); 611 TemplateURLData data; 612 data.SetURL("{google:baseURL}search?q={searchTerms}"); 613 data.instant_url = "{google:baseURL}webhp?strk"; 614 data.search_terms_replacement_key = "strk"; 615 TemplateURL* template_url = new TemplateURL(profile(), data); 616 // Takes ownership of |template_url|. 617 template_url_service->Add(template_url); 618 template_url_service->SetDefaultSearchProvider(template_url); 619 620 // By default, Instant Extended forces the instant URL to be HTTPS, so even if 621 // we set a Google base URL that is HTTP, we should get an HTTPS URL. 622 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/"); 623 GURL instant_url(GetInstantURL(profile(), kDisableStartMargin, false)); 624 ASSERT_TRUE(instant_url.is_valid()); 625 EXPECT_EQ("https://www.foo.com/webhp?strk", instant_url.spec()); 626 627 // However, if the Google base URL is specified on the command line, the 628 // instant URL should just use it, even if it's HTTP. 629 UIThreadSearchTermsData::SetGoogleBaseURL(std::string()); 630 CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL, 631 "http://www.bar.com/"); 632 instant_url = GetInstantURL(profile(), kDisableStartMargin, false); 633 ASSERT_TRUE(instant_url.is_valid()); 634 EXPECT_EQ("http://www.bar.com/webhp?strk", instant_url.spec()); 635 636 // Similarly, setting a Google base URL on the command line should allow you 637 // to get the Google version of the local NTP, even though search provider's 638 // URL doesn't contain "google". 639 local_instant_url = GetLocalInstantURL(profile()); 640 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 641 642 // If we specify extra search query params, they should be inserted into the 643 // query portion of the instant URL. 644 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 645 switches::kExtraSearchQueryParams, "a=b"); 646 instant_url = GetInstantURL(profile(), kDisableStartMargin, false); 647 ASSERT_TRUE(instant_url.is_valid()); 648 EXPECT_EQ("http://www.bar.com/webhp?a=b&strk", instant_url.spec()); 649} 650 651TEST_F(SearchTest, ShouldShowInstantNTP_Default) { 652 EXPECT_FALSE(ShouldShowInstantNTP()); 653} 654 655TEST_F(SearchTest, ShouldShowInstantNTP_DisabledViaFinch) { 656 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 657 "EmbeddedSearch", "Group1 show_ntp:0")); 658 EXPECT_FALSE(ShouldShowInstantNTP()); 659} 660 661TEST_F(SearchTest, ShouldShowInstantNTP_DisabledByUseCacheableNTPFinchFlag) { 662 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 663 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 664 EXPECT_FALSE(ShouldShowInstantNTP()); 665} 666 667TEST_F(SearchTest, ShouldUseCacheableNTP_Default) { 668 EXPECT_TRUE(ShouldUseCacheableNTP()); 669} 670 671TEST_F(SearchTest, ShouldUseCacheableNTP_EnabledViaFinch) { 672 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 673 "EmbeddedSearch", "Group1 use_cacheable_ntp:1")); 674 EXPECT_TRUE(ShouldUseCacheableNTP()); 675} 676 677TEST_F(SearchTest, ShouldPrefetchSearchResults_Default) { 678 EXPECT_FALSE(ShouldPrefetchSearchResults()); 679} 680 681TEST_F(SearchTest, ShouldPrefetchSearchResults_InstantExtendedAPIEnabled) { 682 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 683 "EmbeddedSearch", 684 "Group1 espv:2 use_cacheable_ntp:1 prefetch_results:1")); 685 EXPECT_TRUE(ShouldPrefetchSearchResults()); 686#if defined(OS_IOS) || defined(OS_ANDROID) 687 EXPECT_EQ(1ul, EmbeddedSearchPageVersion()); 688#else 689 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 690#endif 691} 692 693TEST_F(SearchTest, ShouldPrefetchSearchResults_DisabledViaFinch) { 694 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 695 "EmbeddedSearch", 696 "Group1 use_cacheable_ntp:1 espv:89 prefetch_results:0")); 697 EXPECT_FALSE(ShouldPrefetchSearchResults()); 698 EXPECT_EQ(89ul, EmbeddedSearchPageVersion()); 699} 700 701TEST_F(SearchTest, ShouldPrefetchSearchResults_EnabledViaFinch) { 702 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 703 "EmbeddedSearch", 704 "Group1 espv:80 use_cacheable_ntp:1 prefetch_results:1")); 705 EXPECT_TRUE(ShouldPrefetchSearchResults()); 706 EXPECT_EQ(80ul, EmbeddedSearchPageVersion()); 707} 708 709TEST_F(SearchTest, IsNTPURL) { 710 GURL invalid_url; 711 GURL ntp_url(chrome::kChromeUINewTabURL); 712 GURL local_ntp_url(GetLocalInstantURL(profile())); 713 714 EXPECT_FALSE(chrome::IsNTPURL(invalid_url, profile())); 715 // No margin. 716 EnableQueryExtractionForTesting(); 717 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 718 GURL remote_ntp_url(GetInstantURL(profile(), kDisableStartMargin, false)); 719 GURL search_url_with_search_terms("https://foo.com/url?strk&bar=abc"); 720 GURL search_url_without_search_terms("https://foo.com/url?strk&bar"); 721 722 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, profile())); 723 EXPECT_TRUE(chrome::IsNTPURL(local_ntp_url, profile())); 724 EXPECT_TRUE(chrome::IsNTPURL(remote_ntp_url, profile())); 725 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, profile())); 726 EXPECT_TRUE(chrome::IsNTPURL(search_url_without_search_terms, profile())); 727 728 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, NULL)); 729 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, NULL)); 730 EXPECT_FALSE(chrome::IsNTPURL(remote_ntp_url, NULL)); 731 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, NULL)); 732 EXPECT_FALSE(chrome::IsNTPURL(search_url_without_search_terms, NULL)); 733} 734 735TEST_F(SearchTest, GetSearchURLs) { 736 std::vector<GURL> search_urls = GetSearchURLs(profile()); 737 EXPECT_EQ(2U, search_urls.size()); 738 EXPECT_EQ("http://foo.com/alt#quux=", search_urls[0].spec()); 739 EXPECT_EQ("http://foo.com/url?bar=", search_urls[1].spec()); 740} 741 742TEST_F(SearchTest, GetSearchResultPrefetchBaseURL) { 743 // "prefetch_results" flag is disabled. 744 EXPECT_EQ(GURL(), GetSearchResultPrefetchBaseURL(profile())); 745 746 // "prefetch_results" flag is enabled via field trials. 747 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 748 "EmbeddedSearch", 749 "Group1 espv:80 use_cacheable_ntp:1 prefetch_results:1")); 750 EXPECT_TRUE(ShouldPrefetchSearchResults()); 751 752 EXPECT_EQ(GURL("https://foo.com/instant?ion=1&foo=foo#foo=foo&strk"), 753 GetSearchResultPrefetchBaseURL(profile())); 754} 755 756typedef SearchTest IsQueryExtractionEnabledTest; 757 758TEST_F(IsQueryExtractionEnabledTest, NotSet) { 759 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 760 "EmbeddedSearch", "Group1 espv:2")); 761 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 762 EXPECT_FALSE(IsQueryExtractionEnabled()); 763 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 764} 765 766TEST_F(IsQueryExtractionEnabledTest, EnabledViaFinch) { 767 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 768 "EmbeddedSearch", "Group1 espv:2 query_extraction:1")); 769 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 770 EXPECT_TRUE(IsQueryExtractionEnabled()); 771 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 772} 773 774TEST_F(IsQueryExtractionEnabledTest, DisabledViaFinch) { 775 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 776 "EmbeddedSearch", "Group1 espv:2 query_extraction:0")); 777 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 778 EXPECT_FALSE(IsQueryExtractionEnabled()); 779 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 780} 781 782TEST_F(IsQueryExtractionEnabledTest, EnabledViaCommandLine) { 783 EnableQueryExtractionForTesting(); 784 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 785 "EmbeddedSearch", "Group1 espv:2 query_extraction:0")); 786 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 787 EXPECT_TRUE(IsQueryExtractionEnabled()); 788 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 789} 790 791typedef SearchTest ShouldHideTopVerbatimTest; 792 793TEST_F(ShouldHideTopVerbatimTest, DoNotHideByDefault) { 794 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 795 "Control")); 796 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 797} 798 799TEST_F(ShouldHideTopVerbatimTest, DoNotHideInInstantExtended) { 800 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 801 "Group1")); 802 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 803} 804 805TEST_F(ShouldHideTopVerbatimTest, EnableByFlagInInstantExtended) { 806 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 807 "Group1 hide_verbatim:1")); 808 EXPECT_TRUE(ShouldHideTopVerbatimMatch()); 809} 810 811TEST_F(ShouldHideTopVerbatimTest, EnableByFlagOutsideInstantExtended) { 812 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 813 "EmbeddedSearch", "Controll1 hide_verbatim:1")); 814 EXPECT_TRUE(ShouldHideTopVerbatimMatch()); 815} 816 817TEST_F(ShouldHideTopVerbatimTest, DisableByFlag) { 818 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", 819 "Group1 hide_verbatim:0")); 820 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 821} 822 823typedef SearchTest DisplaySearchButtonTest; 824 825TEST_F(DisplaySearchButtonTest, NotSet) { 826 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 827 "EmbeddedSearch", "Group1 espv:2")); 828 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions()); 829} 830 831TEST_F(DisplaySearchButtonTest, Never) { 832 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 833 "EmbeddedSearch", "Group1 espv:2 display_search_button:0")); 834 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions()); 835} 836 837TEST_F(DisplaySearchButtonTest, ForSearchTermReplacement) { 838 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 839 "EmbeddedSearch", "Group1 espv:2 display_search_button:1")); 840 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR, GetDisplaySearchButtonConditions()); 841} 842 843TEST_F(DisplaySearchButtonTest, ForSearchTermReplacementOrInputInProgress) { 844 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 845 "EmbeddedSearch", "Group1 espv:2 display_search_button:2")); 846 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP, 847 GetDisplaySearchButtonConditions()); 848} 849 850TEST_F(DisplaySearchButtonTest, Always) { 851 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 852 "EmbeddedSearch", "Group1 espv:2 display_search_button:3")); 853 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_ALWAYS, GetDisplaySearchButtonConditions()); 854} 855 856TEST_F(DisplaySearchButtonTest, InvalidValue) { 857 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 858 "EmbeddedSearch", "Group1 espv:2 display_search_button:4")); 859 EXPECT_EQ(DISPLAY_SEARCH_BUTTON_NEVER, GetDisplaySearchButtonConditions()); 860} 861 862typedef SearchTest OriginChipTest; 863 864TEST_F(OriginChipTest, NotSet) { 865 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 866 "EmbeddedSearch", "Group1 espv:2")); 867 EXPECT_FALSE(ShouldDisplayOriginChip()); 868} 869 870TEST_F(OriginChipTest, NoOriginChip) { 871 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 872 "EmbeddedSearch", "Group1 espv:2 origin_chip:0")); 873 EXPECT_FALSE(ShouldDisplayOriginChip()); 874} 875 876TEST_F(OriginChipTest, OriginChip) { 877 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 878 "EmbeddedSearch", "Group1 espv:2 origin_chip:1")); 879 EXPECT_TRUE(ShouldDisplayOriginChip()); 880} 881 882} // namespace chrome 883