Home | History | Annotate | Download | only in toolbar
      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 
    178 ToolbarModelTest::ToolbarModelTest() {
    179 }
    180 
    181 ToolbarModelTest::~ToolbarModelTest() {
    182 }
    183 
    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 
    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 
    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.
    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.
    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.
    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.
    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