search_unittest.cc revision a3f7b4e666c476898878fa745f637129375cd889
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/search.h" 12#include "chrome/browser/search_engines/search_terms_data.h" 13#include "chrome/browser/search_engines/template_url_service.h" 14#include "chrome/browser/search_engines/template_url_service_factory.h" 15#include "chrome/browser/ui/tabs/tab_strip_model.h" 16#include "chrome/common/chrome_switches.h" 17#include "chrome/common/metrics/entropy_provider.h" 18#include "chrome/common/pref_names.h" 19#include "chrome/common/url_constants.h" 20#include "chrome/test/base/browser_with_test_window_test.h" 21#include "chrome/test/base/ui_test_utils.h" 22#include "content/public/browser/render_process_host.h" 23#include "content/public/browser/render_view_host.h" 24#include "content/public/browser/site_instance.h" 25#include "content/public/browser/web_contents.h" 26 27namespace chrome { 28 29TEST(EmbeddedSearchFieldTrialTest, GetFieldTrialInfo) { 30 FieldTrialFlags flags; 31 uint64 group_number = 0; 32 const uint64 ZERO = 0; 33 34 EXPECT_FALSE(GetFieldTrialInfo(std::string(), &flags, &group_number)); 35 EXPECT_EQ(ZERO, group_number); 36 EXPECT_EQ(ZERO, flags.size()); 37 38 EXPECT_TRUE(GetFieldTrialInfo("Group77", &flags, &group_number)); 39 EXPECT_EQ(uint64(77), group_number); 40 EXPECT_EQ(ZERO, flags.size()); 41 42 group_number = 0; 43 EXPECT_FALSE(GetFieldTrialInfo("Group77.2", &flags, &group_number)); 44 EXPECT_EQ(ZERO, group_number); 45 EXPECT_EQ(ZERO, flags.size()); 46 47 EXPECT_FALSE(GetFieldTrialInfo("Invalid77", &flags, &group_number)); 48 EXPECT_EQ(ZERO, group_number); 49 EXPECT_EQ(ZERO, flags.size()); 50 51 EXPECT_FALSE(GetFieldTrialInfo("Invalid77", &flags, NULL)); 52 EXPECT_EQ(ZERO, flags.size()); 53 54 EXPECT_TRUE(GetFieldTrialInfo("Group77 ", &flags, &group_number)); 55 EXPECT_EQ(uint64(77), group_number); 56 EXPECT_EQ(ZERO, flags.size()); 57 58 group_number = 0; 59 flags.clear(); 60 EXPECT_EQ(uint64(9999), GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 61 EXPECT_TRUE(GetFieldTrialInfo("Group77 foo:6", &flags, &group_number)); 62 EXPECT_EQ(uint64(77), group_number); 63 EXPECT_EQ(uint64(1), flags.size()); 64 EXPECT_EQ(uint64(6), GetUInt64ValueForFlagWithDefault("foo", 9999, flags)); 65 66 group_number = 0; 67 flags.clear(); 68 EXPECT_TRUE(GetFieldTrialInfo( 69 "Group77 bar:1 baz:7 cat:dogs", &flags, &group_number)); 70 EXPECT_EQ(uint64(77), group_number); 71 EXPECT_EQ(uint64(3), flags.size()); 72 EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags)); 73 EXPECT_EQ(uint64(7), GetUInt64ValueForFlagWithDefault("baz", 0, flags)); 74 EXPECT_EQ("dogs", 75 GetStringValueForFlagWithDefault("cat", std::string(), flags)); 76 EXPECT_EQ("default", 77 GetStringValueForFlagWithDefault("moose", "default", flags)); 78 79 group_number = 0; 80 flags.clear(); 81 EXPECT_FALSE(GetFieldTrialInfo( 82 "Group77 bar:1 baz:7 cat:dogs DISABLED", &flags, &group_number)); 83 EXPECT_EQ(ZERO, group_number); 84 EXPECT_EQ(ZERO, flags.size()); 85} 86 87class InstantExtendedAPIEnabledTest : public testing::Test { 88 public: 89 InstantExtendedAPIEnabledTest() : histogram_(NULL) { 90 } 91 protected: 92 virtual void SetUp() { 93 field_trial_list_.reset(new base::FieldTrialList( 94 new metrics::SHA1EntropyProvider("42"))); 95 base::StatisticsRecorder::Initialize(); 96 ResetInstantExtendedOptInStateGateForTest(); 97 previous_metrics_count_.resize(INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT, 0); 98 base::HistogramBase* histogram = GetHistogram(); 99 if (histogram) { 100 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); 101 if (samples.get()) { 102 for (int state = INSTANT_EXTENDED_NOT_SET; 103 state < INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT; ++state) { 104 previous_metrics_count_[state] = samples->GetCount(state); 105 } 106 } 107 } 108 } 109 110 virtual CommandLine* GetCommandLine() const { 111 return CommandLine::ForCurrentProcess(); 112 } 113 114 void ValidateMetrics(base::HistogramBase::Sample value) { 115 base::HistogramBase* histogram = GetHistogram(); 116 if (histogram) { 117 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); 118 if (samples.get()) { 119 for (int state = INSTANT_EXTENDED_NOT_SET; 120 state < INSTANT_EXTENDED_OPT_IN_STATE_ENUM_COUNT; ++state) { 121 if (state == value) { 122 EXPECT_EQ(previous_metrics_count_[state] + 1, 123 samples->GetCount(state)); 124 } else { 125 EXPECT_EQ(previous_metrics_count_[state], samples->GetCount(state)); 126 } 127 } 128 } 129 } 130 } 131 132 private: 133 base::HistogramBase* GetHistogram() { 134 if (!histogram_) { 135 histogram_ = base::StatisticsRecorder::FindHistogram( 136 "InstantExtended.OptInState"); 137 } 138 return histogram_; 139 } 140 base::HistogramBase* histogram_; 141 scoped_ptr<base::FieldTrialList> field_trial_list_; 142 std::vector<int> previous_metrics_count_; 143}; 144 145TEST_F(InstantExtendedAPIEnabledTest, EnabledViaCommandLineFlag) { 146 GetCommandLine()->AppendSwitch(switches::kEnableInstantExtendedAPI); 147 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 148#if defined(OS_IOS) || defined(OS_ANDROID) 149 EXPECT_EQ(1ul, EmbeddedSearchPageVersion()); 150#else 151 EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); 152#endif 153 ValidateMetrics(INSTANT_EXTENDED_OPT_IN); 154} 155 156TEST_F(InstantExtendedAPIEnabledTest, EnabledViaFinchFlag) { 157 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 158 "Group1 espv:42")); 159 EXPECT_TRUE(IsInstantExtendedAPIEnabled()); 160 EXPECT_EQ(42ul, EmbeddedSearchPageVersion()); 161 ValidateMetrics(INSTANT_EXTENDED_NOT_SET); 162} 163 164TEST_F(InstantExtendedAPIEnabledTest, DisabledViaCommandLineFlag) { 165 GetCommandLine()->AppendSwitch(switches::kDisableInstantExtendedAPI); 166 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended", 167 "Group1 espv:2")); 168 EXPECT_FALSE(IsInstantExtendedAPIEnabled()); 169 EXPECT_EQ(0ul, EmbeddedSearchPageVersion()); 170 ValidateMetrics(INSTANT_EXTENDED_OPT_OUT); 171} 172 173class SearchTest : public BrowserWithTestWindowTest { 174 protected: 175 virtual void SetUp() OVERRIDE { 176 BrowserWithTestWindowTest::SetUp(); 177 field_trial_list_.reset(new base::FieldTrialList( 178 new metrics::SHA1EntropyProvider("42"))); 179 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 180 profile(), &TemplateURLServiceFactory::BuildInstanceFor); 181 TemplateURLService* template_url_service = 182 TemplateURLServiceFactory::GetForProfile(profile()); 183 ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service); 184 SetSearchProvider(); 185 } 186 187 void SetSearchProvider() { 188 TemplateURLService* template_url_service = 189 TemplateURLServiceFactory::GetForProfile(profile()); 190 TemplateURLData data; 191 data.SetURL("http://foo.com/url?bar={searchTerms}"); 192 data.instant_url = "http://foo.com/instant?" 193 "{google:omniboxStartMarginParameter}foo=foo#foo=foo&strk"; 194 data.alternate_urls.push_back("http://foo.com/alt#quux={searchTerms}"); 195 data.search_terms_replacement_key = "strk"; 196 197 TemplateURL* template_url = new TemplateURL(profile(), data); 198 // Takes ownership of |template_url|. 199 template_url_service->Add(template_url); 200 template_url_service->SetDefaultSearchProvider(template_url); 201 } 202 203 // Build an Instant URL with or without a valid search terms replacement key 204 // as per |has_search_term_replacement_key|. Set that URL as the instant URL 205 // for the default search provider. 206 void SetDefaultInstantTemplateUrl(bool has_search_term_replacement_key) { 207 TemplateURLService* template_url_service = 208 TemplateURLServiceFactory::GetForProfile(profile()); 209 210 static const char kInstantURLWithStrk[] = 211 "http://foo.com/instant?foo=foo#foo=foo&strk"; 212 static const char kInstantURLNoStrk[] = 213 "http://foo.com/instant?foo=foo#foo=foo"; 214 215 TemplateURLData data; 216 data.SetURL("http://foo.com/url?bar={searchTerms}"); 217 data.instant_url = (has_search_term_replacement_key ? 218 kInstantURLWithStrk : kInstantURLNoStrk); 219 data.search_terms_replacement_key = "strk"; 220 221 TemplateURL* template_url = new TemplateURL(profile(), data); 222 // Takes ownership of |template_url|. 223 template_url_service->Add(template_url); 224 template_url_service->SetDefaultSearchProvider(template_url); 225 } 226 227 scoped_ptr<base::FieldTrialList> field_trial_list_; 228}; 229 230struct SearchTestCase { 231 const char* url; 232 bool expected_result; 233 const char* comment; 234}; 235 236TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedDisabled) { 237 DisableInstantExtendedAPIForTesting(); 238 239 const SearchTestCase kTestCases[] = { 240 {"chrome-search://foo/bar", false, ""}, 241 {"http://foo.com/instant", false, ""}, 242 {"http://foo.com/instant?foo=bar", false, ""}, 243 {"https://foo.com/instant", false, ""}, 244 {"https://foo.com/instant#foo=bar", false, ""}, 245 {"HtTpS://fOo.CoM/instant", false, ""}, 246 {"http://foo.com:80/instant", false, ""}, 247 {"invalid URL", false, "Invalid URL"}, 248 {"unknown://scheme/path", false, "Unknown scheme"}, 249 {"ftp://foo.com/instant", false, "Non-HTTP scheme"}, 250 {"http://sub.foo.com/instant", false, "Non-exact host"}, 251 {"http://foo.com:26/instant", false, "Non-default port"}, 252 {"http://foo.com/instant/bar", false, "Non-exact path"}, 253 {"http://foo.com/Instant", false, "Case sensitive path"}, 254 {"http://foo.com/", false, "Non-exact path"}, 255 {"https://foo.com/", false, "Non-exact path"}, 256 {"https://foo.com/url?strk", false, "Non-extended mode"}, 257 {"https://foo.com/alt?strk", false, "Non-extended mode"}, 258 }; 259 260 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 261 const SearchTestCase& test = kTestCases[i]; 262 EXPECT_EQ(test.expected_result, 263 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 264 << test.url << " " << test.comment; 265 } 266} 267 268TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) { 269 EnableInstantExtendedAPIForTesting(); 270 271 const SearchTestCase kTestCases[] = { 272 {chrome::kChromeSearchLocalNtpUrl, true, ""}, 273 {"https://foo.com/instant?strk", true, ""}, 274 {"https://foo.com/instant#strk", true, ""}, 275 {"https://foo.com/instant?strk=0", true, ""}, 276 {"https://foo.com/url?strk", true, ""}, 277 {"https://foo.com/alt?strk", true, ""}, 278 {"http://foo.com/instant", false, "Non-HTTPS"}, 279 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 280 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 281 {"https://foo.com/instant", false, "No search terms replacement"}, 282 {"https://foo.com/?strk", false, "Non-exact path"}, 283 }; 284 285 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 286 const SearchTestCase& test = kTestCases[i]; 287 EXPECT_EQ(test.expected_result, 288 ShouldAssignURLToInstantRenderer(GURL(test.url), profile())) 289 << test.url << " " << test.comment; 290 } 291} 292 293TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) { 294 EnableInstantExtendedAPIForTesting(); 295 296 const SearchTestCase kTestCases[] = { 297 {"chrome-search://local-ntp", true, "Local NTP"}, 298 {"chrome-search://online-ntp", true, "Online NTP"}, 299 {"invalid-scheme://local-ntp", false, "Invalid Local NTP URL"}, 300 {"invalid-scheme://online-ntp", false, "Invalid Online NTP URL"}, 301 {"chrome-search://foo.com", false, "Search result page"}, 302 {"https://foo.com/instant?strk", false, ""}, 303 {"https://foo.com/instant#strk", false, ""}, 304 {"https://foo.com/instant?strk=0", false, ""}, 305 {"https://foo.com/url?strk", false, ""}, 306 {"https://foo.com/alt?strk", false, ""}, 307 {"http://foo.com/instant", false, "Non-HTTPS"}, 308 {"http://foo.com/instant?strk", false, "Non-HTTPS"}, 309 {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, 310 {"https://foo.com/instant", false, "No search terms replacement"}, 311 {"https://foo.com/?strk", false, "Non-exact path"}, 312 }; 313 314 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 315 const SearchTestCase& test = kTestCases[i]; 316 EXPECT_EQ(test.expected_result, 317 ShouldUseProcessPerSiteForInstantURL(GURL(test.url), profile())) 318 << test.url << " " << test.comment; 319 } 320} 321 322struct PrivilegedURLTestCase { 323 bool add_as_alternate_url; 324 const char* input_url; 325 const char* privileged_url; 326 bool different_site_instance; 327 const char* comment; 328}; 329 330TEST_F(SearchTest, GetPrivilegedURLForInstant) { 331 EnableInstantExtendedAPIForTesting(); 332 333 const PrivilegedURLTestCase kTestCases[] = { 334 { false, // don't append input_url as alternate URL. 335 chrome::kChromeSearchLocalNtpUrl, // input URL. 336 chrome::kChromeSearchLocalNtpUrl, // expected privileged URL. 337 true, // expected different SiteInstance. 338 "local NTP" }, 339 { false, // don't append input_url as alternate URL. 340 "https://foo.com/instant?strk", 341 "chrome-search://online-ntp/instant?strk", 342 true, // expected different SiteInstance. 343 "Valid Instant NTP" }, 344 { false, // don't append input_url as alternate URL. 345 "https://foo.com/instant?strk&more=junk", 346 "chrome-search://online-ntp/instant?strk&more=junk", 347 true, // expected different SiteInstance. 348 "Valid Instant NTP with extra query" }, 349 { false, // don't append input_url as alternate URL. 350 "https://foo.com/url?strk", 351 "chrome-search://foo.com/url?strk", 352 false, // expected same SiteInstance. 353 "Search URL" }, 354 { true, // append input_url as alternate URL. 355 "https://notfoo.com/instant?strk", 356 "chrome-search://notfoo.com/instant?strk", 357 true, // expected different SiteInstance. 358 "Invalid host in URL" }, 359 { true, // append input_url as alternate URL. 360 "https://foo.com/webhp?strk", 361 "chrome-search://foo.com/webhp?strk", 362 false, // expected same SiteInstance. 363 "Invalid path in URL" }, 364 { true, // append input_url as alternate URL. 365 "https://foo.com/search?strk", 366 "chrome-search://foo.com/search?strk", 367 false, // expected same SiteInstance. 368 "Invalid path in URL" }, 369 }; 370 371 // GetPrivilegedURLForInstant expects ShouldAssignURLToInstantRenderer to 372 // be true, and the latter expects chrome-search: scheme or IsInstantURL to be 373 // true. To force IsInstantURL to return true, add the input_url of each 374 // PrivilegedURLTestCase as the alternate URL for the default template URL. 375 const char* kSearchURL = "https://foo.com/url?strk"; 376 TemplateURLService* template_url_service = 377 TemplateURLServiceFactory::GetForProfile(profile()); 378 TemplateURLData data; 379 data.SetURL(kSearchURL); 380 data.instant_url = "http://foo.com/instant?strk"; 381 data.search_terms_replacement_key = "strk"; 382 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 383 const PrivilegedURLTestCase& test = kTestCases[i]; 384 if (test.add_as_alternate_url) 385 data.alternate_urls.push_back(test.input_url); 386 } 387 TemplateURL* template_url = new TemplateURL(profile(), data); 388 // Takes ownership of |template_url|. 389 template_url_service->Add(template_url); 390 template_url_service->SetDefaultSearchProvider(template_url); 391 392 AddTab(browser(), GURL("chrome://blank")); 393 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 394 const PrivilegedURLTestCase& test = kTestCases[i]; 395 396 // Verify GetPrivilegedURLForInstant. 397 EXPECT_EQ(GURL(test.privileged_url), 398 GetPrivilegedURLForInstant(GURL(test.input_url), profile())) 399 << test.input_url << " " << test.comment; 400 401 // Verify that navigating from input_url to search URL results in same or 402 // different SiteInstance. 403 // First, navigate to input_url. 404 NavigateAndCommitActiveTab(GURL(test.input_url)); 405 content::WebContents* contents = 406 browser()->tab_strip_model()->GetWebContentsAt(0); 407 // Cache the SiteInstance, RenderViewHost and RenderProcessHost for 408 // input_url. 409 const scoped_refptr<content::SiteInstance> prev_site_instance = 410 contents->GetSiteInstance(); 411 const content::RenderViewHost* prev_rvh = contents->GetRenderViewHost(); 412 const content::RenderProcessHost* prev_rph = 413 contents->GetRenderProcessHost(); 414 // Then, navigate to search URL. 415 NavigateAndCommitActiveTab(GURL(kSearchURL)); 416 EXPECT_EQ(test.different_site_instance, 417 contents->GetSiteInstance() != prev_site_instance) 418 << test.input_url << " " << test.comment; 419 EXPECT_EQ(test.different_site_instance, 420 contents->GetRenderViewHost() != prev_rvh) 421 << test.input_url << " " << test.comment; 422 EXPECT_EQ(test.different_site_instance, 423 contents->GetRenderProcessHost() != prev_rph) 424 << test.input_url << " " << test.comment; 425 } 426} 427 428const SearchTestCase kInstantNTPTestCases[] = { 429 {"https://foo.com/instant?strk", true, "Valid Instant URL"}, 430 {"https://foo.com/instant#strk", true, "Valid Instant URL"}, 431 {"https://foo.com/url?strk", true, "Valid search URL"}, 432 {"https://foo.com/url#strk", true, "Valid search URL"}, 433 {"https://foo.com/alt?strk", true, "Valid alternative URL"}, 434 {"https://foo.com/alt#strk", true, "Valid alternative URL"}, 435 {"https://foo.com/url?strk&bar=", true, "No query terms"}, 436 {"https://foo.com/url?strk&q=abc", true, "No query terms key"}, 437 {"https://foo.com/url?strk#bar=abc", true, "Query terms key in ref"}, 438 {"https://foo.com/url?strk&bar=abc", false, "Has query terms"}, 439 {"http://foo.com/instant?strk=1", false, "Insecure URL"}, 440 {"https://foo.com/instant", false, "No search term replacement"}, 441 {"chrome://blank/", false, "Chrome scheme"}, 442 {"chrome-search://foo", false, "Chrome-search scheme"}, 443 {chrome::kChromeSearchLocalNtpUrl, true, "Local new tab page"}, 444 {"https://bar.com/instant?strk=1", false, "Random non-search page"}, 445}; 446 447TEST_F(SearchTest, InstantNTPExtendedEnabled) { 448 EnableInstantExtendedAPIForTesting(); 449 AddTab(browser(), GURL("chrome://blank")); 450 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 451 const SearchTestCase& test = kInstantNTPTestCases[i]; 452 NavigateAndCommitActiveTab(GURL(test.url)); 453 const content::WebContents* contents = 454 browser()->tab_strip_model()->GetWebContentsAt(0); 455 EXPECT_EQ(test.expected_result, IsInstantNTP(contents)) 456 << test.url << " " << test.comment; 457 } 458} 459 460TEST_F(SearchTest, InstantNTPExtendedDisabled) { 461 AddTab(browser(), GURL("chrome://blank")); 462 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 463 const SearchTestCase& test = kInstantNTPTestCases[i]; 464 NavigateAndCommitActiveTab(GURL(test.url)); 465 const content::WebContents* contents = 466 browser()->tab_strip_model()->GetWebContentsAt(0); 467 EXPECT_FALSE(IsInstantNTP(contents)) << test.url << " " << test.comment; 468 } 469} 470 471TEST_F(SearchTest, InstantNTPCustomNavigationEntry) { 472 EnableInstantExtendedAPIForTesting(); 473 AddTab(browser(), GURL("chrome://blank")); 474 for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { 475 const SearchTestCase& test = kInstantNTPTestCases[i]; 476 NavigateAndCommitActiveTab(GURL(test.url)); 477 content::WebContents* contents = 478 browser()->tab_strip_model()->GetWebContentsAt(0); 479 content::NavigationController& controller = contents->GetController(); 480 controller.SetTransientEntry( 481 controller.CreateNavigationEntry(GURL("chrome://blank"), 482 content::Referrer(), 483 content::PAGE_TRANSITION_LINK, 484 false, 485 std::string(), 486 contents->GetBrowserContext())); 487 // The active entry is chrome://blank and not an NTP. 488 EXPECT_FALSE(IsInstantNTP(contents)); 489 EXPECT_EQ(test.expected_result, 490 NavEntryIsInstantNTP(contents, 491 controller.GetLastCommittedEntry())) 492 << test.url << " " << test.comment; 493 } 494} 495 496TEST_F(SearchTest, GetInstantURLExtendedEnabled) { 497 // Instant is disabled, so no Instant URL. 498 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 499 500 // Enable Instant. Still no Instant URL because "strk" is missing. 501 EnableInstantExtendedAPIForTesting(); 502 SetDefaultInstantTemplateUrl(false); 503 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 504 505 // Set an Instant URL with a valid search terms replacement key. 506 SetDefaultInstantTemplateUrl(true); 507 508 // Now there should be a valid Instant URL. Note the HTTPS "upgrade". 509 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 510 GetInstantURL(profile(), kDisableStartMargin)); 511 512 // Enable suggest. No difference. 513 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 514 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 515 GetInstantURL(profile(), kDisableStartMargin)); 516 517 // Disable suggest. No Instant URL. 518 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false); 519 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 520} 521 522TEST_F(SearchTest, StartMarginCGI) { 523 // Instant is disabled, so no Instant URL. 524 EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin)); 525 526 // Enable Instant. No margin. 527 EnableInstantExtendedAPIForTesting(); 528 profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); 529 530 EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"), 531 GetInstantURL(profile(), kDisableStartMargin)); 532 533 // With start margin. 534 EXPECT_EQ(GURL("https://foo.com/instant?es_sm=10&foo=foo#foo=foo&strk"), 535 GetInstantURL(profile(), 10)); 536} 537 538TEST_F(SearchTest, CommandLineOverrides) { 539 EnableInstantExtendedAPIForTesting(); 540 541 GURL local_instant_url(GetLocalInstantURL(profile())); 542 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 543 544 TemplateURLService* template_url_service = 545 TemplateURLServiceFactory::GetForProfile(profile()); 546 TemplateURLData data; 547 data.SetURL("{google:baseURL}search?q={searchTerms}"); 548 data.instant_url = "{google:baseURL}webhp?strk"; 549 data.search_terms_replacement_key = "strk"; 550 TemplateURL* template_url = new TemplateURL(profile(), data); 551 // Takes ownership of |template_url|. 552 template_url_service->Add(template_url); 553 template_url_service->SetDefaultSearchProvider(template_url); 554 555 // By default, Instant Extended forces the instant URL to be HTTPS, so even if 556 // we set a Google base URL that is HTTP, we should get an HTTPS URL. 557 UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/"); 558 GURL instant_url(GetInstantURL(profile(), kDisableStartMargin)); 559 ASSERT_TRUE(instant_url.is_valid()); 560 EXPECT_EQ("https://www.foo.com/webhp?strk", instant_url.spec()); 561 562 // However, if the Google base URL is specified on the command line, the 563 // instant URL should just use it, even if it's HTTP. 564 UIThreadSearchTermsData::SetGoogleBaseURL(std::string()); 565 CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL, 566 "http://www.bar.com/"); 567 instant_url = GetInstantURL(profile(), kDisableStartMargin); 568 ASSERT_TRUE(instant_url.is_valid()); 569 EXPECT_EQ("http://www.bar.com/webhp?strk", instant_url.spec()); 570 571 // Similarly, setting a Google base URL on the command line should allow you 572 // to get the Google version of the local NTP, even though search provider's 573 // URL doesn't contain "google". 574 local_instant_url = GetLocalInstantURL(profile()); 575 EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), local_instant_url); 576 577 // If we specify extra search query params, they should be inserted into the 578 // query portion of the instant URL. 579 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 580 switches::kExtraSearchQueryParams, "a=b"); 581 instant_url = GetInstantURL(profile(), kDisableStartMargin); 582 ASSERT_TRUE(instant_url.is_valid()); 583 EXPECT_EQ("http://www.bar.com/webhp?a=b&strk", instant_url.spec()); 584} 585 586} // namespace chrome 587