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