search_unittest.cc revision 3551c9c881056c480085172ff9840cab31610854
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/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/search_terms_data.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/ui/tabs/tab_strip_model.h" 18#include "chrome/common/chrome_switches.h" 19#include "chrome/common/metrics/entropy_provider.h" 20#include "chrome/common/pref_names.h" 21#include "chrome/common/url_constants.h" 22#include "chrome/test/base/browser_with_test_window_test.h" 23#include "chrome/test/base/ui_test_utils.h" 24#include "content/public/browser/render_process_host.h" 25#include "content/public/browser/render_view_host.h" 26#include "content/public/browser/site_instance.h" 27#include "content/public/browser/web_contents.h" 28#include "content/public/common/renderer_preferences.h" 29 30namespace chrome { 31 32TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) { 33 FieldTrialFlags flags; 34 uint64 group_number = 0; 35 36 EXPECT_TRUE(GetFieldTrialInfo(std::string(), &flags, &group_number)); 37 EXPECT_EQ(0ul, group_number); 38 EXPECT_EQ(0ul, flags.size()); 39 40 EXPECT_TRUE(GetFieldTrialInfo("Group77", &flags, &group_number)); 41 EXPECT_EQ(77ul, group_number); 42 EXPECT_EQ(0ul, flags.size()); 43} 44 45TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidThenValid) { 46 FieldTrialFlags flags; 47 uint64 group_number = 0; 48 49 EXPECT_FALSE(GetFieldTrialInfo("Group77.2", &flags, &group_number)); 50 EXPECT_EQ(0ul, group_number); 51 EXPECT_EQ(0ul, flags.size()); 52 53 EXPECT_TRUE(GetFieldTrialInfo("Invalid77", &flags, &group_number)); 54 EXPECT_EQ(0ul, group_number); 55 EXPECT_EQ(0ul, flags.size()); 56 57 EXPECT_TRUE(GetFieldTrialInfo("Group77 ", &flags, &group_number)); 58 EXPECT_EQ(77ul, group_number); 59 EXPECT_EQ(0ul, flags.size()); 60} 61 62TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) { 63 FieldTrialFlags flags; 64 uint64 group_number = 0; 65 66 EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 67 EXPECT_TRUE(GetFieldTrialInfo("Group77 foo:6", &flags, &group_number)); 68 EXPECT_EQ(77ul, group_number); 69 EXPECT_EQ(1ul, flags.size()); 70 EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 71} 72 73TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) { 74 FieldTrialFlags flags; 75 uint64 group_number = 0; 76 77 EXPECT_TRUE(GetFieldTrialInfo( 78 "Group77 bar:1 baz:7 cat:dogs", &flags, &group_number)); 79 EXPECT_EQ(77ul, group_number); 80 EXPECT_EQ(3ul, flags.size()); 81 EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags)); 82 EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags)); 83 EXPECT_EQ("dogs", 84 GetStringValueForFlagWithDefault("cat", std::string(), flags)); 85 EXPECT_EQ("default", 86 GetStringValueForFlagWithDefault("moose", "default", flags)); 87} 88 89TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) { 90 FieldTrialFlags flags; 91 uint64 group_number = 0; 92 93 EXPECT_FALSE(GetFieldTrialInfo( 94 "Group77 bar:1 baz:7 cat:dogs DISABLED", &flags, &group_number)); 95 EXPECT_EQ(0ul, group_number); 96 EXPECT_EQ(0ul, flags.size()); 97} 98 99TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) { 100 FieldTrialFlags flags; 101 uint64 group_number = 0; 102 103 EXPECT_TRUE(GetFieldTrialInfo( 104 "Control77 bar:1 baz:7 cat:dogs", &flags, &group_number)); 105 EXPECT_EQ(0ul, group_number); 106 EXPECT_EQ(3ul, flags.size()); 107} 108 109class InstantExtendedAPIEnabledTest : public testing::Test { 110 public: 111 InstantExtendedAPIEnabledTest() : histogram_(NULL) { 112 } 113 protected: 114 virtual void SetUp() { 115 field_trial_list_.reset(new base::FieldTrialList( 116 new metrics::SHA1EntropyProvider("42"))); 117 base::StatisticsRecorder::Initialize(); 118 ResetInstantExtendedOptInStateGateForTest(); 119 previous_metrics_count_.resize(INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT, 0); 120 base::HistogramBase* histogram = GetHistogram(); 121 if (histogram) { 122 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); 123 if (samples.get()) { 124 for (int state = INSTANT_EXTENDED_NOT_SET; 125 state < INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT; ++state) { 126 previous_metrics_count_[state] = samples->GetCount(state); 127 } 128 } 129 } 130 } 131 132 virtual CommandLine* GetCommandLine() const { 133 return CommandLine::ForCurrentProcess(); 134 } 135 136 void ValidateMetrics(base::HistogramBase::Sample value) { 137 base::HistogramBase* histogram = GetHistogram(); 138 if (histogram) { 139 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); 140 if (samples.get()) { 141 for (int state = INSTANT_EXTENDED_NOT_SET; 142 state < INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT; ++state) { 143 if (state == value) { 144 EXPECT_EQ(previous_metrics_count_[state] + 1, 145 samples->GetCount(state)); 146 } else { 147 EXPECT_EQ(previous_metrics_count_[state], samples->GetCount(state)); 148 } 149 } 150 } 151 } 152 } 153 154 private: 155 base::HistogramBase* GetHistogram() { 156 if (!histogram_) { 157 histogram_ = base::StatisticsRecorder::FindHistogram( 158 "InstantExtended.OptInState"); 159 } 160 return histogram_; 161 } 162 base::HistogramBase* histogram_; 163 scoped_ptr<base::FieldTrialList> field_trial_list_; 164 std::vector<int> previous_metrics_count_; 165}; 166 167TEST_F(InstantExtendedAPIEnabledTest, EnabledViaCommandLineFlag) { 168 GetCommandLine()->AppendSwitch(switches::kEnableInstantExtendedAPI); 169 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 170#if defined(OS_IOS) || defined(OS_ANDROID) 171 EXPECT_EQ(1ul, EmbeddedSearchPageVersion()); 172#else 173 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 174#endif 175 ValidateMetrics(INSTANT_EXTENDED_OPT_IN); 176} 177 178TEST_F(InstantExtendedAPIEnabledTest, EnabledViaFinchFlag) { 179 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 180 "Group1 espv:42")); 181 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 182 EXPECT_EQ(42ul, EmbeddedSearchPageVersion()); 183 ValidateMetrics(INSTANT_EXTENDED_NOT_SET); 184} 185 186TEST_F(InstantExtendedAPIEnabledTest, DisabledViaCommandLineFlag) { 187 GetCommandLine()->AppendSwitch(switches::kDisableInstantExtendedAPI); 188 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 189 "Group1 espv:2")); 190 EXPECT_FALSE(IsInstantExtendedAPIEnabled()); 191 EXPECT_EQ(0ul, EmbeddedSearchPageVersion()); 192 ValidateMetrics(INSTANT_EXTENDED_OPT_OUT); 193} 194 195typedef InstantExtendedAPIEnabledTest ShouldHideTopVerbatimTest; 196 197TEST_F(ShouldHideTopVerbatimTest, DoNotHideByDefault) { 198 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 199 "InstantExtended", "Control")); 200 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 201} 202 203TEST_F(ShouldHideTopVerbatimTest, DoNotHideInInstantExtended) { 204 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 205 "InstantExtended", "Group1")); 206 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 207} 208 209TEST_F(ShouldHideTopVerbatimTest, EnableByFlagInInstantExtended) { 210 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 211 "InstantExtended", "Group1 hide_verbatim:1")); 212 EXPECT_TRUE(ShouldHideTopVerbatimMatch()); 213} 214 215TEST_F(ShouldHideTopVerbatimTest, EnableByFlagOutsideInstantExtended) { 216 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 217 "InstantExtended", "Controll1 hide_verbatim:1")); 218 EXPECT_TRUE(ShouldHideTopVerbatimMatch()); 219} 220 221TEST_F(ShouldHideTopVerbatimTest, DisableByFlag) { 222 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 223 "InstantExtended", "Group1 hide_verbatim:0")); 224 EXPECT_FALSE(ShouldHideTopVerbatimMatch()); 225} 226 227class SearchTest : public BrowserWithTestWindowTest { 228 protected: 229 virtual void SetUp() OVERRIDE { 230 BrowserWithTestWindowTest::SetUp(); 231 field_trial_list_.reset(new base::FieldTrialList( 232 new metrics::SHA1EntropyProvider("42"))); 233 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 234 profile(), &TemplateURLServiceFactory::BuildInstanceFor); 235 TemplateURLService* template_url_service = 236 TemplateURLServiceFactory::GetForProfile(profile()); 237 ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service); 238 SetSearchProvider(); 239 } 240 241 void SetSearchProvider() { 242 TemplateURLService* template_url_service = 243 TemplateURLServiceFactory::GetForProfile(profile()); 244 TemplateURLData data; 245 data.SetURL("http://foo.com/url?bar={searchTerms}"); 246 data.instant_url = "http://foo.com/instant?" 247 "{google:omniboxStartMarginParameter}foo=foo#foo=foo&strk"; 248 data.new_tab_url = "http://foo.com/newtab?strk"; 249 data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}"); 250 data.search_terms_replacement_key = "strk"; 251 252 TemplateURL* template_url = new TemplateURL(profile(), data); 253 // Takes ownership of |template_url|. 254 template_url_service->Add(template_url); 255 template_url_service->SetDefaultSearchProvider(template_url); 256 } 257 258 // Build an Instant URL with or without a valid search terms replacement key 259 // as per |has_search_term_replacement_key|. Set that URL as the instant URL 260 // for the default search provider. 261 void SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key) { 262 TemplateURLService* template_url_service = 263 TemplateURLServiceFactory::GetForProfile(profile()); 264 265 static const char kInstantURLWithStrk[] = 266 "http://foo.com/instant?foo=foo#foo=foo&strk"; 267 static const char kInstantURLNoStrk[] = 268 "http://foo.com/instant?foo=foo#foo=foo"; 269 270 TemplateURLData data; 271 data.SetURL("http://foo.com/url?bar={searchTerms}"); 272 data.instant_url = (has_search_term_replacement_key ? 273 kInstantURLWithStrk : kInstantURLNoStrk); 274 data.search_terms_replacement_key = "strk"; 275 276 TemplateURL* template_url = new TemplateURL(profile(), data); 277 // Takes ownership of |template_url|. 278 template_url_service->Add(template_url); 279 template_url_service->SetDefaultSearchProvider(template_url); 280 } 281 282 bool InInstantProcess(const content::WebContents* contents) { 283 InstantService* instant_service = 284 InstantServiceFactory::GetForProfile(profile()); 285 return instant_service->IsInstantProcess( 286 contents->GetRenderProcessHost()->GetID()); 287 } 288 289 scoped_ptr<base::FieldTrialList> field_trial_list_; 290}; 291 292struct SearchTestCase { 293 const char* url; 294 bool expected_result; 295 const char* comment; 296}; 297 298TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedDisabled) { 299 DisableInstantExtendedAPIForTesting(); 300 301 const SearchTestCase kTestCases[] = { 302 {"chrome-search://foo/bar", false, ""}, 303 {"http://foo.com/instant", false, ""}, 304 {"http://foo.com/instant?foo=bar", false, ""}, 305 {"https://foo.com/instant", false, ""}, 306 {"https://foo.com/instant#foo=bar", false, ""}, 307 {"HtTpS://fOo.CoM/instant", false, ""}, 308 {"http://foo.com:80/instant", false, ""}, 309 {"invalid URL", false, "Invalid URL"}, 310 {"unknown://scheme/path", false, "Unknown scheme"}, 311 {"ftp://foo.com/instant", false, "Non-HTTP scheme"}, 312 {"http://sub.foo.com/instant", false, "Non-exact host"}, 313 {"http://foo.com:26/instant", false, "Non-default port"}, 314 {"http://foo.com/instant/bar", false, "Non-exact path"}, 315 {"http://foo.com/Instant", false, "Case sensitive path"}, 316 {"http://foo.com/", false, "Non-exact path"}, 317 {"https://foo.com/", false, "Non-exact path"}, 318 {"https://foo.com/url?strk", false, "Non-extended mode"}, 319 {"https://foo.com/alt?strk", false, "Non-extended mode"}, 320 }; 321 322 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 323 const SearchTestCase& test = kTestCases[i]; 324 EXPECT_EQ(test.expected_result, 325 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 326 << test.url << " " << test.comment; 327 } 328} 329 330TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) { 331 EnableInstantExtendedAPIForTesting(); 332 333 const SearchTestCase kTestCases[] = { 334 {chrome::kChromeSearchLocalNtpUrl, true, ""}, 335 {"https://foo.com/instant?strk", true, ""}, 336 {"https://foo.com/instant#strk", true, ""}, 337 {"https://foo.com/instant?strk=0", true, ""}, 338 {"https://foo.com/url?strk", true, ""}, 339 {"https://foo.com/alt?strk", true, ""}, 340 {"http://foo.com/instant", false, "Non-HTTPS"}, 341 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 342 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 343 {"https://foo.com/instant", false, "No search terms replacement"}, 344 {"https://foo.com/?strk", false, "Non-exact path"}, 345 }; 346 347 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 348 const SearchTestCase& test = kTestCases[i]; 349 EXPECT_EQ(test.expected_result, 350 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 351 << test.url << " " << test.comment; 352 } 353} 354 355TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) { 356 EnableInstantExtendedAPIForTesting(); 357 358 const SearchTestCase kTestCases[] = { 359 {"chrome-search://local-ntp", true, "Local NTP"}, 360 {"chrome-search://online-ntp", true, "Online NTP"}, 361 {"invalid-scheme://local-ntp", false, "Invalid Local NTP URL"}, 362 {"invalid-scheme://online-ntp", false, "Invalid Online NTP URL"}, 363 {"chrome-search://foo.com", false, "Search result page"}, 364 {"https://foo.com/instant?strk", false, ""}, 365 {"https://foo.com/instant#strk", false, ""}, 366 {"https://foo.com/instant?strk=0", false, ""}, 367 {"https://foo.com/url?strk", false, ""}, 368 {"https://foo.com/alt?strk", false, ""}, 369 {"http://foo.com/instant", false, "Non-HTTPS"}, 370 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 371 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 372 {"https://foo.com/instant", false, "No search terms replacement"}, 373 {"https://foo.com/?strk", false, "Non-exact path"}, 374 }; 375 376 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 377 const SearchTestCase& test = kTestCases[i]; 378 EXPECT_EQ(test.expected_result, 379 ShouldUseProcessPerSiteForInstantURL(GURL(test.url), profile())) 380 << test.url << " " << test.comment; 381 } 382} 383 384// Each test case represents a navigation to |start_url| followed by a 385// navigation to |end_url|. We will check whether each navigation lands in an 386// Instant process, and also whether the navigation from start to end re-uses 387// the same SiteInstance (and hence the same RenderViewHost, etc.). 388const struct ProcessIsolationTestCase { 389 const char* description; 390 const char* start_url; 391 bool start_in_instant_process; 392 const char* end_url; 393 bool end_in_instant_process; 394 bool same_site_instance; 395} kProcessIsolationTestCases[] = { 396 {"Local NTP -> SRP", 397 "chrome-search://local-ntp", true, 398 "https://foo.com/url?strk", true, false }, 399 {"Local NTP -> Regular", 400 "chrome-search://local-ntp", true, 401 "https://foo.com/other", false, false }, 402 {"Remote NTP -> SRP", 403 "https://foo.com/instant?strk", true, 404 "https://foo.com/url?strk", true, false }, 405 {"Remote NTP -> Regular", 406 "https://foo.com/instant?strk", true, 407 "https://foo.com/other", false, false }, 408 {"SRP -> SRP", 409 "https://foo.com/url?strk", true, 410 "https://foo.com/url?strk", true, true }, 411 {"SRP -> Regular", 412 "https://foo.com/url?strk", true, 413 "https://foo.com/other", false, false }, 414 {"Regular -> SRP", 415 "https://foo.com/other", false, 416 "https://foo.com/url?strk", true, false }, 417}; 418 419TEST_F(SearchTest, ProcessIsolation) { 420 EnableInstantExtendedAPIForTesting(); 421 422 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { 423 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; 424 AddTab(browser(), GURL("chrome://blank")); 425 const content::WebContents* contents = 426 browser()->tab_strip_model()->GetActiveWebContents(); 427 428 // Navigate to start URL. 429 NavigateAndCommitActiveTab(GURL(test.start_url)); 430 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents)) 431 << test.description; 432 433 // Save state. 434 const scoped_refptr<content::SiteInstance> start_site_instance = 435 contents->GetSiteInstance(); 436 const content::RenderProcessHost* start_rph = 437 contents->GetRenderProcessHost(); 438 const content::RenderViewHost* start_rvh = 439 contents->GetRenderViewHost(); 440 441 // Navigate to end URL. 442 NavigateAndCommitActiveTab(GURL(test.end_url)); 443 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents)) 444 << test.description; 445 446 EXPECT_EQ(test.same_site_instance, 447 start_site_instance == contents->GetSiteInstance()) 448 << test.description; 449 EXPECT_EQ(test.same_site_instance, 450 start_rvh == contents->GetRenderViewHost()) 451 << test.description; 452 EXPECT_EQ(test.same_site_instance, 453 start_rph == contents->GetRenderProcessHost()) 454 << test.description; 455 } 456} 457 458TEST_F(SearchTest, ProcessIsolation_RendererInitiated) { 459 EnableInstantExtendedAPIForTesting(); 460 461 for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { 462 const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; 463 AddTab(browser(), GURL("chrome://blank")); 464 content::WebContents* contents = 465 browser()->tab_strip_model()->GetActiveWebContents(); 466 467 // Navigate to start URL. 468 NavigateAndCommitActiveTab(GURL(test.start_url)); 469 EXPECT_EQ(test.start_in_instant_process, InInstantProcess(contents)) 470 << test.description; 471 472 // Save state. 473 const scoped_refptr<content::SiteInstance> start_site_instance = 474 contents->GetSiteInstance(); 475 const content::RenderProcessHost* start_rph = 476 contents->GetRenderProcessHost(); 477 const content::RenderViewHost* start_rvh = 478 contents->GetRenderViewHost(); 479 480 // Navigate to end URL via a renderer-initiated navigation. 481 content::NavigationController* controller = &contents->GetController(); 482 content::NavigationController::LoadURLParams load_params( 483 GURL(test.end_url)); 484 load_params.is_renderer_initiated = true; 485 load_params.transition_type = content::PAGE_TRANSITION_LINK; 486 487 controller->LoadURLWithParams(load_params); 488 CommitPendingLoad(controller); 489 EXPECT_EQ(test.end_in_instant_process, InInstantProcess(contents)) 490 << test.description; 491 492 EXPECT_EQ(test.same_site_instance, 493 start_site_instance == contents->GetSiteInstance()) 494 << test.description; 495 EXPECT_EQ(test.same_site_instance, 496 start_rvh == contents->GetRenderViewHost()) 497 << test.description; 498 EXPECT_EQ(test.same_site_instance, 499 start_rph == contents->GetRenderProcessHost()) 500 << test.description; 501 } 502} 503 504const SearchTestCase kInstantNTPTestCases[] = { 505 {"https://foo.com/instant?strk", true, "Valid Instant URL"}, 506 {"https://foo.com/instant#strk", true, "Valid Instant URL"}, 507 {"https://foo.com/url?strk", true, "Valid search URL"}, 508 {"https://foo.com/url#strk", true, "Valid search URL"}, 509 {"https://foo.com/alt?strk", true, "Valid alternative URL"}, 510 {"https://foo.com/alt#strk", true, "Valid alternative URL"}, 511 {"https://foo.com/url?strk&bar=", true, "No query terms"}, 512 {"https://foo.com/url?strk&q=abc", true, "No query terms key"}, 513 {"https://foo.com/url?strk#bar=abc", true, "Query terms key in ref"}, 514 {"https://foo.com/url?strk&bar=abc", false, "Has query terms"}, 515 {"http://foo.com/instant?strk=1", false, "Insecure URL"}, 516 {"https://foo.com/instant", false, "No search term replacement"}, 517 {"chrome://blank/", false, "Chrome scheme"}, 518 {"chrome-search://foo", false, "Chrome-search scheme"}, 519 {chrome::kChromeSearchLocalNtpUrl, true, "Local new tab page"}, 520 {"https://bar.com/instant?strk=1", false, "Random non-search page"}, 521}; 522 523TEST_F(SearchTest, InstantNTPExtendedEnabled) { 524 EnableInstantExtendedAPIForTesting(); 525 AddTab(browser(), GURL("chrome://blank")); 526 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 527 const SearchTestCase& test = kInstantNTPTestCases[i]; 528 NavigateAndCommitActiveTab(GURL(test.url)); 529 const content::WebContents* contents = 530 browser()->tab_strip_model()->GetWebContentsAt(0); 531 EXPECT_EQ(test.expected_result, IsInstantNTP(contents)) 532 << test.url << " " << test.comment; 533 } 534} 535 536TEST_F(SearchTest, InstantNTPExtendedDisabled) { 537 AddTab(browser(), GURL("chrome://blank")); 538 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 539 const SearchTestCase& test = kInstantNTPTestCases[i]; 540 NavigateAndCommitActiveTab(GURL(test.url)); 541 const content::WebContents* contents = 542 browser()->tab_strip_model()->GetWebContentsAt(0); 543 EXPECT_FALSE(IsInstantNTP(contents)) << test.url << " " << test.comment; 544 } 545} 546 547TEST_F(SearchTest, InstantNTPCustomNavigationEntry) { 548 EnableInstantExtendedAPIForTesting(); 549 AddTab(browser(), GURL("chrome://blank")); 550 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 551 const SearchTestCase& test = kInstantNTPTestCases[i]; 552 NavigateAndCommitActiveTab(GURL(test.url)); 553 content::WebContents* contents = 554 browser()->tab_strip_model()->GetWebContentsAt(0); 555 content::NavigationController& controller = contents->GetController(); 556 controller.SetTransientEntry( 557 controller.CreateNavigationEntry(GURL("chrome://blank"), 558 content::Referrer(), 559 content::PAGE_TRANSITION_LINK, 560 false, 561 std::string(), 562 contents->GetBrowserContext())); 563 // The active entry is chrome://blank and not an NTP. 564 EXPECT_FALSE(IsInstantNTP(contents)); 565 EXPECT_EQ(test.expected_result, 566 NavEntryIsInstantNTP(contents, 567 controller.GetLastCommittedEntry())) 568 << test.url << " " << test.comment; 569 } 570} 571 572TEST_F(SearchTest, GetInstantURLExtendedEnabled) { 573 // Instant is disabled, so no Instant URL. 574 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 575 576 // Enable Instant. Still no Instant URL because "strk" is missing. 577 EnableInstantExtendedAPIForTesting(); 578 SetDefaultInstantTemplateUrl(false); 579 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 580 581 // Set an Instant URL with a valid search terms replacement key. 582 SetDefaultInstantTemplateUrl(true); 583 584 // Now there should be a valid Instant URL. Note the HTTPS "upgrade". 585 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 586 GetInstantURL(profile(), kDisableStartMargin)); 587 588 // Enable suggest. No difference. 589 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 590 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 591 GetInstantURL(profile(), kDisableStartMargin)); 592 593 // Disable suggest. No Instant URL. 594 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false); 595 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 596} 597 598TEST_F(SearchTest, StartMarginCGI) { 599 // Instant is disabled, so no Instant URL. 600 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 601 602 // Enable Instant. No margin. 603 EnableInstantExtendedAPIForTesting(); 604 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 605 606 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 607 GetInstantURL(profile(), kDisableStartMargin)); 608 609 // With start margin. 610 EXPECT_EQ(GURL("https://foo.com/instant?es_sm=10&foo=foo#foo=foo&strk"), 611 GetInstantURL(profile(), 10)); 612} 613 614TEST_F(SearchTest, CommandLineOverrides) { 615 EnableInstantExtendedAPIForTesting(); 616 617 GURL local_instant_url(GetLocalInstantURL(profile())); 618 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 619 620 TemplateURLService* template_url_service = 621 TemplateURLServiceFactory::GetForProfile(profile()); 622 TemplateURLData data; 623 data.SetURL("{google:baseURL}search?q={searchTerms}"); 624 data.instant_url = "{google:baseURL}webhp?strk"; 625 data.search_terms_replacement_key = "strk"; 626 TemplateURL* template_url = new TemplateURL(profile(), data); 627 // Takes ownership of |template_url|. 628 template_url_service->Add(template_url); 629 template_url_service->SetDefaultSearchProvider(template_url); 630 631 // By default, Instant Extended forces the instant URL to be HTTPS, so even if 632 // we set a Google base URL that is HTTP, we should get an HTTPS URL. 633 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/"); 634 GURL instant_url(GetInstantURL(profile(), kDisableStartMargin)); 635 ASSERT_TRUE(instant_url.is_valid()); 636 EXPECT_EQ("https://www.foo.com/webhp?strk", instant_url.spec()); 637 638 // However, if the Google base URL is specified on the command line, the 639 // instant URL should just use it, even if it's HTTP. 640 UIThreadSearchTermsData::SetGoogleBaseURL(std::string()); 641 CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL, 642 "http://www.bar.com/"); 643 instant_url = GetInstantURL(profile(), kDisableStartMargin); 644 ASSERT_TRUE(instant_url.is_valid()); 645 EXPECT_EQ("http://www.bar.com/webhp?strk", instant_url.spec()); 646 647 // Similarly, setting a Google base URL on the command line should allow you 648 // to get the Google version of the local NTP, even though search provider's 649 // URL doesn't contain "google". 650 local_instant_url = GetLocalInstantURL(profile()); 651 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 652 653 // If we specify extra search query params, they should be inserted into the 654 // query portion of the instant URL. 655 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 656 switches::kExtraSearchQueryParams, "a=b"); 657 instant_url = GetInstantURL(profile(), kDisableStartMargin); 658 ASSERT_TRUE(instant_url.is_valid()); 659 EXPECT_EQ("http://www.bar.com/webhp?a=b&strk", instant_url.spec()); 660} 661 662TEST_F(SearchTest, ShouldShowInstantNTP_Default) { 663 EnableInstantExtendedAPIForTesting(); 664 EXPECT_TRUE(ShouldShowInstantNTP()); 665} 666 667TEST_F(SearchTest, ShouldShowInstantNTP_DisabledViaFinch) { 668 EnableInstantExtendedAPIForTesting(); 669 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 670 "Group1 show_ntp:0")); 671 EXPECT_FALSE(ShouldShowInstantNTP()); 672} 673 674TEST_F(SearchTest, ShouldShowInstantNTP_DisabledByUseCacheableNTPFinchFlag) { 675 EnableInstantExtendedAPIForTesting(); 676 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 677 "Group1 use_cacheable_ntp:1")); 678 EXPECT_FALSE(ShouldShowInstantNTP()); 679} 680 681TEST_F(SearchTest, ShouldUseCacheableNTP_Default) { 682 EnableInstantExtendedAPIForTesting(); 683 EXPECT_FALSE(ShouldUseCacheableNTP()); 684} 685 686TEST_F(SearchTest, ShouldUseCacheableNTP_EnabledViaFinch) { 687 EnableInstantExtendedAPIForTesting(); 688 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 689 "Group1 use_cacheable_ntp:1")); 690 EXPECT_TRUE(ShouldUseCacheableNTP()); 691} 692 693TEST_F(SearchTest, IsNTPURL) { 694 GURL invalid_url; 695 GURL ntp_url(chrome::kChromeUINewTabURL); 696 GURL local_ntp_url(GetLocalInstantURL(profile())); 697 698 EXPECT_FALSE(chrome::IsNTPURL(invalid_url, profile())); 699 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, profile())); 700 701 EXPECT_TRUE(chrome::IsNTPURL(ntp_url, NULL)); 702 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, NULL)); 703 704 // Enable Instant. No margin. 705 EnableInstantExtendedAPIForTesting(); 706 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 707 GURL remote_ntp_url(GetInstantURL(profile(), kDisableStartMargin)); 708 GURL search_url_with_search_terms("https://foo.com/url?strk&bar=abc"); 709 GURL search_url_without_search_terms("https://foo.com/url?strk&bar"); 710 711 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, profile())); 712 EXPECT_TRUE(chrome::IsNTPURL(local_ntp_url, profile())); 713 EXPECT_TRUE(chrome::IsNTPURL(remote_ntp_url, profile())); 714 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, profile())); 715 EXPECT_TRUE(chrome::IsNTPURL(search_url_without_search_terms, profile())); 716 717 EXPECT_FALSE(chrome::IsNTPURL(ntp_url, NULL)); 718 EXPECT_FALSE(chrome::IsNTPURL(local_ntp_url, NULL)); 719 EXPECT_FALSE(chrome::IsNTPURL(remote_ntp_url, NULL)); 720 EXPECT_FALSE(chrome::IsNTPURL(search_url_with_search_terms, NULL)); 721 EXPECT_FALSE(chrome::IsNTPURL(search_url_without_search_terms, NULL)); 722} 723 724} // namespace chrome 725