• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "chrome/browser/ui/toolbar/toolbar_model.h"
6 
7 #include <vector>
8 
9 #include "base/command_line.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
13 #include "chrome/browser/search/search.h"
14 #include "chrome/browser/search_engines/search_terms_data.h"
15 #include "chrome/browser/search_engines/template_url.h"
16 #include "chrome/browser/search_engines/template_url_service.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/browser/ui/toolbar/toolbar_model.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/test/base/browser_with_test_window_test.h"
23 #include "components/variations/entropy_provider.h"
24 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/ssl_status.h"
28 #include "content/public/common/url_constants.h"
29 #include "net/base/escape.h"
30 
31 
32 // Test data ------------------------------------------------------------------
33 
34 namespace {
35 
36 struct TestItem {
37   GURL url;
38   // The expected text to display when both forms of URL replacement are
39   // inactive.
40   base::string16 expected_text_url_replacement_inactive;
41   // The expected text to display when query extraction is active.
42   base::string16 expected_text_query_extraction;
43   // The expected text to display when the origin chip (URL removal) is active.
44   base::string16 expected_text_origin_chip;
45   // The expected text to display when both query extraction and URL removal are
46   // active.
47   base::string16 expected_text_both;
48   bool would_perform_search_term_replacement;
49   bool should_display_url;
50 } test_items[] = {
51   {
52     GURL("view-source:http://www.google.com"),
53     ASCIIToUTF16("view-source:www.google.com"),
54     ASCIIToUTF16("view-source:www.google.com"),
55     base::string16(),
56     base::string16(),
57     false,
58     true
59   },
60   {
61     GURL("view-source:chrome://newtab/"),
62     ASCIIToUTF16("view-source:chrome://newtab"),
63     ASCIIToUTF16("view-source:chrome://newtab"),
64     base::string16(),
65     base::string16(),
66     false,
67     true
68   },
69   {
70     GURL("chrome-extension://monkey/balls.html"),
71     ASCIIToUTF16("chrome-extension://monkey/balls.html"),
72     ASCIIToUTF16("chrome-extension://monkey/balls.html"),
73     base::string16(),
74     base::string16(),
75     false,
76     true
77   },
78   {
79     GURL(content::kAboutBlankURL),
80     ASCIIToUTF16(content::kAboutBlankURL),
81     ASCIIToUTF16(content::kAboutBlankURL),
82     base::string16(),
83     base::string16(),
84     false,
85     true
86   },
87   {
88     GURL("http://searchurl/?q=tractor+supply"),
89     ASCIIToUTF16("searchurl/?q=tractor+supply"),
90     ASCIIToUTF16("searchurl/?q=tractor+supply"),
91     base::string16(),
92     base::string16(),
93     false,
94     true
95   },
96   {
97     GURL("http://google.com/search?q=tractor+supply&espv=1"),
98     ASCIIToUTF16("google.com/search?q=tractor+supply&espv=1"),
99     ASCIIToUTF16("google.com/search?q=tractor+supply&espv=1"),
100     base::string16(),
101     base::string16(),
102     false,
103     true
104   },
105   {
106     GURL("https://google.ca/search?q=tractor+supply"),
107     ASCIIToUTF16("https://google.ca/search?q=tractor+supply"),
108     ASCIIToUTF16("https://google.ca/search?q=tractor+supply"),
109     base::string16(),
110     base::string16(),
111     false,
112     true
113   },
114   {
115     GURL("https://google.com/search?q=tractor+supply"),
116     ASCIIToUTF16("https://google.com/search?q=tractor+supply"),
117     ASCIIToUTF16("https://google.com/search?q=tractor+supply"),
118     base::string16(),
119     base::string16(),
120     false,
121     true
122   },
123   {
124     GURL("https://google.com/search?q=tractor+supply&espv=1"),
125     ASCIIToUTF16("https://google.com/search?q=tractor+supply&espv=1"),
126     ASCIIToUTF16("tractor supply"),
127     base::string16(),
128     ASCIIToUTF16("tractor supply"),
129     true,
130     true
131   },
132   {
133     GURL("https://google.com/search?q=tractorsupply.com&espv=1"),
134     ASCIIToUTF16("https://google.com/search?q=tractorsupply.com&espv=1"),
135     ASCIIToUTF16("tractorsupply.com"),
136     base::string16(),
137     ASCIIToUTF16("tractorsupply.com"),
138     true,
139     true
140   },
141   {
142     GURL("https://google.com/search?q=ftp://tractorsupply.ie&espv=1"),
143     ASCIIToUTF16("https://google.com/search?q=ftp://tractorsupply.ie&espv=1"),
144     ASCIIToUTF16("ftp://tractorsupply.ie"),
145     base::string16(),
146     ASCIIToUTF16("ftp://tractorsupply.ie"),
147     true,
148     true
149   },
150 };
151 
152 }  // namespace
153 
154 
155 // ToolbarModelTest -----------------------------------------------------------
156 
157 class ToolbarModelTest : public BrowserWithTestWindowTest {
158  public:
159   ToolbarModelTest();
160   virtual ~ToolbarModelTest();
161 
162   // BrowserWithTestWindowTest:
163   virtual void SetUp() OVERRIDE;
164 
165  protected:
166   void NavigateAndCheckText(const GURL& url,
167                             const base::string16& expected_text,
168                             bool would_perform_search_term_replacement,
169                             bool should_display_url);
170   void EnableOriginChipFieldTrial();
171 
172  private:
173   scoped_ptr<base::FieldTrialList> field_trial_list_;
174 
175   DISALLOW_COPY_AND_ASSIGN(ToolbarModelTest);
176 };
177 
ToolbarModelTest()178 ToolbarModelTest::ToolbarModelTest() {
179 }
180 
~ToolbarModelTest()181 ToolbarModelTest::~ToolbarModelTest() {
182 }
183 
SetUp()184 void ToolbarModelTest::SetUp() {
185   BrowserWithTestWindowTest::SetUp();
186   TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
187       profile(), &TemplateURLServiceFactory::BuildInstanceFor);
188   AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse(
189       profile(), &AutocompleteClassifierFactory::BuildInstanceFor);
190   UIThreadSearchTermsData::SetGoogleBaseURL("http://google.com/");
191 }
192 
EnableOriginChipFieldTrial()193 void ToolbarModelTest::EnableOriginChipFieldTrial() {
194   field_trial_list_.reset(new base::FieldTrialList(
195       new metrics::SHA1EntropyProvider("platypus")));
196   base::FieldTrialList::CreateFieldTrial(
197             "EmbeddedSearch", "Group1 espv:2 origin_chip:1");
198 }
199 
NavigateAndCheckText(const GURL & url,const base::string16 & expected_text,bool would_perform_search_term_replacement,bool should_display_url)200 void ToolbarModelTest::NavigateAndCheckText(
201     const GURL& url,
202     const base::string16& expected_text,
203     bool would_perform_search_term_replacement,
204     bool should_display_url) {
205   // Check while loading.
206   content::NavigationController* controller =
207       &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
208   controller->LoadURL(url, content::Referrer(), content::PAGE_TRANSITION_LINK,
209                       std::string());
210   ToolbarModel* toolbar_model = browser()->toolbar_model();
211   EXPECT_EQ(expected_text, toolbar_model->GetText());
212   EXPECT_EQ(would_perform_search_term_replacement,
213             toolbar_model->WouldPerformSearchTermReplacement(false));
214   EXPECT_EQ(should_display_url, toolbar_model->ShouldDisplayURL());
215 
216   // Check after commit.
217   CommitPendingLoad(controller);
218   // Fake a secure connection for HTTPS URLs, or the toolbar will refuse to
219   // extract search terms.
220   if (url.SchemeIsSecure()) {
221     controller->GetVisibleEntry()->GetSSL().security_style =
222         content::SECURITY_STYLE_AUTHENTICATED;
223   }
224   EXPECT_EQ(expected_text, toolbar_model->GetText());
225   EXPECT_EQ(would_perform_search_term_replacement,
226             toolbar_model->WouldPerformSearchTermReplacement(false));
227   EXPECT_EQ(should_display_url, toolbar_model->ShouldDisplayURL());
228 
229   // Now pretend the user started modifying the omnibox.
230   toolbar_model->set_input_in_progress(true);
231   EXPECT_FALSE(toolbar_model->WouldPerformSearchTermReplacement(false));
232   EXPECT_EQ(would_perform_search_term_replacement,
233             toolbar_model->WouldPerformSearchTermReplacement(true));
234 
235   // Tell the ToolbarModel that the user has stopped editing.  This prevents
236   // this function from having side effects.
237   toolbar_model->set_input_in_progress(false);
238 }
239 
240 
241 // Actual tests ---------------------------------------------------------------
242 
243 // Test that we only replace URLs when query extraction and URL replacement
244 // are enabled.
TEST_F(ToolbarModelTest,ShouldDisplayURL_QueryExtraction)245 TEST_F(ToolbarModelTest, ShouldDisplayURL_QueryExtraction) {
246   AddTab(browser(), GURL(content::kAboutBlankURL));
247 
248   // Before we enable instant extended, query extraction is disabled.
249   EXPECT_FALSE(chrome::IsQueryExtractionEnabled())
250       << "This test expects query extraction to be disabled.";
251   for (size_t i = 0; i < arraysize(test_items); ++i) {
252     const TestItem& test_item = test_items[i];
253     NavigateAndCheckText(test_item.url,
254                          test_item.expected_text_url_replacement_inactive,
255                          false, test_item.should_display_url);
256   }
257 
258   chrome::EnableQueryExtractionForTesting();
259   EXPECT_TRUE(chrome::IsQueryExtractionEnabled());
260   EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled());
261   for (size_t i = 0; i < arraysize(test_items); ++i) {
262     const TestItem& test_item = test_items[i];
263     NavigateAndCheckText(test_item.url,
264                          test_item.expected_text_query_extraction,
265                          test_item.would_perform_search_term_replacement,
266                          test_item.should_display_url);
267   }
268 
269   // Disabling URL replacement should reset to only showing URLs.
270   browser()->toolbar_model()->set_url_replacement_enabled(false);
271   for (size_t i = 0; i < arraysize(test_items); ++i) {
272     const TestItem& test_item = test_items[i];
273     NavigateAndCheckText(test_item.url,
274                          test_item.expected_text_url_replacement_inactive,
275                          false, test_item.should_display_url);
276   }
277 }
278 
279 // Test that we remove or replace URLs appropriately when the origin chip is
280 // enabled.
TEST_F(ToolbarModelTest,ShouldDisplayURL_OriginChip)281 TEST_F(ToolbarModelTest, ShouldDisplayURL_OriginChip) {
282   EnableOriginChipFieldTrial();
283   AddTab(browser(), GURL(content::kAboutBlankURL));
284 
285   // Check each case with the origin chip enabled but query extraction disabled.
286   EXPECT_TRUE(chrome::ShouldDisplayOriginChip());
287   EXPECT_FALSE(chrome::IsQueryExtractionEnabled());
288   for (size_t i = 0; i < arraysize(test_items); ++i) {
289     const TestItem& test_item = test_items[i];
290     NavigateAndCheckText(test_item.url, test_item.expected_text_origin_chip,
291                          false, test_item.should_display_url);
292   }
293 
294   // Check with both enabled.
295   chrome::EnableQueryExtractionForTesting();
296   EXPECT_TRUE(chrome::IsQueryExtractionEnabled());
297   EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled());
298   for (size_t i = 0; i < arraysize(test_items); ++i) {
299     const TestItem& test_item = test_items[i];
300     NavigateAndCheckText(test_item.url, test_item.expected_text_both,
301                          test_item.would_perform_search_term_replacement,
302                          test_item.should_display_url);
303   }
304 
305   // Disabling URL replacement should reset to only showing URLs.
306   browser()->toolbar_model()->set_url_replacement_enabled(false);
307   for (size_t i = 0; i < arraysize(test_items); ++i) {
308     const TestItem& test_item = test_items[i];
309     NavigateAndCheckText(test_item.url,
310                          test_item.expected_text_url_replacement_inactive,
311                          false, test_item.should_display_url);
312   }
313 }
314 
315 // Verify that search terms are extracted while the page is loading.
TEST_F(ToolbarModelTest,SearchTermsWhileLoading)316 TEST_F(ToolbarModelTest, SearchTermsWhileLoading) {
317   chrome::EnableQueryExtractionForTesting();
318   AddTab(browser(), GURL(content::kAboutBlankURL));
319 
320   // While loading, we should be willing to extract search terms.
321   content::NavigationController* controller =
322       &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
323   controller->LoadURL(GURL("https://google.com/search?q=tractor+supply&espv=1"),
324                       content::Referrer(), content::PAGE_TRANSITION_LINK,
325                       std::string());
326   ToolbarModel* toolbar_model = browser()->toolbar_model();
327   controller->GetVisibleEntry()->GetSSL().security_style =
328       content::SECURITY_STYLE_UNKNOWN;
329   EXPECT_TRUE(toolbar_model->WouldPerformSearchTermReplacement(false));
330 
331   // When done loading, we shouldn't extract search terms if we didn't get an
332   // authenticated connection.
333   CommitPendingLoad(controller);
334   controller->GetVisibleEntry()->GetSSL().security_style =
335       content::SECURITY_STYLE_UNKNOWN;
336   EXPECT_FALSE(toolbar_model->WouldPerformSearchTermReplacement(false));
337 }
338 
339 // When the Google base URL is overridden on the command line, we should extract
340 // search terms from URLs that start with that base URL even when they're not
341 // secure.
TEST_F(ToolbarModelTest,GoogleBaseURL)342 TEST_F(ToolbarModelTest, GoogleBaseURL) {
343   chrome::EnableQueryExtractionForTesting();
344   AddTab(browser(), GURL(content::kAboutBlankURL));
345 
346   // If the Google base URL wasn't specified on the command line, then if it's
347   // HTTP, we should not extract search terms.
348   UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/");
349   NavigateAndCheckText(
350       GURL("http://www.foo.com/search?q=tractor+supply&espv=1"),
351       ASCIIToUTF16("www.foo.com/search?q=tractor+supply&espv=1"), false, true);
352 
353   // The same URL, when specified on the command line, should allow search term
354   // extraction.
355   UIThreadSearchTermsData::SetGoogleBaseURL(std::string());
356   CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL,
357                                                       "http://www.foo.com/");
358   NavigateAndCheckText(
359       GURL("http://www.foo.com/search?q=tractor+supply&espv=1"),
360       ASCIIToUTF16("tractor supply"), true, true);
361 }
362