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