search_unittest.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
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
586TEST_F(SearchTest, ShouldShowInstantNTP_Default) {
587  EnableInstantExtendedAPIForTesting();
588  EXPECT_TRUE(ShouldShowInstantNTP());
589}
590
591TEST_F(SearchTest, ShouldShowInstantNTP_DisabledViaFinch) {
592  EnableInstantExtendedAPIForTesting();
593  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
594                                                     "Group1 show_ntp:0"));
595  EXPECT_FALSE(ShouldShowInstantNTP());
596}
597
598TEST_F(SearchTest, ShouldShowInstantNTP_DisabledByInstantNewTabURLSwitch) {
599  EnableInstantExtendedAPIForTesting();
600  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
601      switches::kInstantNewTabURL, "http://example.com/newtab");
602  EXPECT_FALSE(ShouldShowInstantNTP());
603}
604
605}  // namespace chrome
606