Home | History | Annotate | Download | only in autocomplete
      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/autocomplete/builtin_provider.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/autocomplete/autocomplete_input.h"
     10 #include "chrome/browser/autocomplete/autocomplete_match.h"
     11 #include "chrome/browser/autocomplete/autocomplete_provider.h"
     12 #include "chrome/common/url_constants.h"
     13 #include "chrome/test/base/testing_browser_process.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "url/gurl.h"
     16 
     17 class BuiltinProviderTest : public testing::Test {
     18  protected:
     19   template<class ResultType>
     20   struct test_data {
     21     const base::string16 input;
     22     const size_t num_results;
     23     const ResultType output[3];
     24   };
     25 
     26   BuiltinProviderTest() : builtin_provider_(NULL) {}
     27   virtual ~BuiltinProviderTest() {}
     28 
     29   virtual void SetUp();
     30   virtual void TearDown();
     31 
     32   template<class ResultType>
     33   void RunTest(test_data<ResultType>* builtin_cases,
     34                int num_cases,
     35                ResultType AutocompleteMatch::* member);
     36 
     37  protected:
     38   scoped_refptr<BuiltinProvider> builtin_provider_;
     39 };
     40 
     41 void BuiltinProviderTest::SetUp() {
     42   builtin_provider_ = new BuiltinProvider(NULL, NULL);
     43 }
     44 
     45 void BuiltinProviderTest::TearDown() {
     46   builtin_provider_ = NULL;
     47 }
     48 
     49 template<class ResultType>
     50 void BuiltinProviderTest::RunTest(test_data<ResultType>* builtin_cases,
     51                                   int num_cases,
     52                                   ResultType AutocompleteMatch::* member) {
     53   ACMatches matches;
     54   for (int i = 0; i < num_cases; ++i) {
     55     AutocompleteInput input(builtin_cases[i].input, base::string16::npos,
     56                             base::string16(), GURL(),
     57                             AutocompleteInput::INVALID_SPEC, true,
     58                             false, true, AutocompleteInput::ALL_MATCHES);
     59     builtin_provider_->Start(input, false);
     60     EXPECT_TRUE(builtin_provider_->done());
     61     matches = builtin_provider_->matches();
     62     EXPECT_EQ(builtin_cases[i].num_results, matches.size()) <<
     63                 ASCIIToUTF16("Input was: ") << builtin_cases[i].input;
     64     if (matches.size() == builtin_cases[i].num_results) {
     65       for (size_t j = 0; j < builtin_cases[i].num_results; ++j) {
     66         EXPECT_EQ(builtin_cases[i].output[j], matches[j].*member) <<
     67                 ASCIIToUTF16("Input was: ") << builtin_cases[i].input;
     68         EXPECT_FALSE(matches[j].allowed_to_be_default_match);
     69       }
     70     }
     71   }
     72 }
     73 
     74 TEST_F(BuiltinProviderTest, TypingScheme) {
     75   const base::string16 kAbout = ASCIIToUTF16(chrome::kAboutScheme);
     76   const base::string16 kChrome = ASCIIToUTF16(chrome::kChromeUIScheme);
     77   const base::string16 kSeparator1 = ASCIIToUTF16(":");
     78   const base::string16 kSeparator2 = ASCIIToUTF16(":/");
     79   const base::string16 kSeparator3 =
     80       ASCIIToUTF16(content::kStandardSchemeSeparator);
     81 
     82   // These default URLs should correspond with those in BuiltinProvider::Start.
     83   const GURL kURL1 = GURL(chrome::kChromeUIChromeURLsURL);
     84   const GURL kURL2 = GURL(chrome::kChromeUISettingsURL);
     85   const GURL kURL3 = GURL(chrome::kChromeUIVersionURL);
     86 
     87   test_data<GURL> typing_scheme_cases[] = {
     88     // Typing an unrelated scheme should give nothing.
     89     {ASCIIToUTF16("h"),        0, {}},
     90     {ASCIIToUTF16("http"),     0, {}},
     91     {ASCIIToUTF16("file"),     0, {}},
     92     {ASCIIToUTF16("abouz"),    0, {}},
     93     {ASCIIToUTF16("aboutt"),   0, {}},
     94     {ASCIIToUTF16("aboutt:"),  0, {}},
     95     {ASCIIToUTF16("chroma"),   0, {}},
     96     {ASCIIToUTF16("chromee"),  0, {}},
     97     {ASCIIToUTF16("chromee:"), 0, {}},
     98 
     99     // Typing a portion of about:// should give the default urls.
    100     {kAbout.substr(0, 1),      3, {kURL1, kURL2, kURL3}},
    101     {ASCIIToUTF16("A"),        3, {kURL1, kURL2, kURL3}},
    102     {kAbout,                   3, {kURL1, kURL2, kURL3}},
    103     {kAbout + kSeparator1,     3, {kURL1, kURL2, kURL3}},
    104     {kAbout + kSeparator2,     3, {kURL1, kURL2, kURL3}},
    105     {kAbout + kSeparator3,     3, {kURL1, kURL2, kURL3}},
    106     {ASCIIToUTF16("aBoUT://"), 3, {kURL1, kURL2, kURL3}},
    107 
    108     // Typing a portion of chrome:// should give the default urls.
    109     {kChrome.substr(0, 1),      3, {kURL1, kURL2, kURL3}},
    110     {ASCIIToUTF16("C"),         3, {kURL1, kURL2, kURL3}},
    111     {kChrome,                   3, {kURL1, kURL2, kURL3}},
    112     {kChrome + kSeparator1,     3, {kURL1, kURL2, kURL3}},
    113     {kChrome + kSeparator2,     3, {kURL1, kURL2, kURL3}},
    114     {kChrome + kSeparator3,     3, {kURL1, kURL2, kURL3}},
    115     {ASCIIToUTF16("ChRoMe://"), 3, {kURL1, kURL2, kURL3}},
    116   };
    117 
    118   RunTest<GURL>(typing_scheme_cases, arraysize(typing_scheme_cases),
    119                 &AutocompleteMatch::destination_url);
    120 }
    121 
    122 TEST_F(BuiltinProviderTest, NonChromeURLs) {
    123   test_data<GURL> non_chrome_url_cases[] = {
    124     // Typing an unrelated scheme should give nothing.
    125     {ASCIIToUTF16("g@rb@g3"),                      0, {}},
    126     {ASCIIToUTF16("www.google.com"),               0, {}},
    127     {ASCIIToUTF16("http:www.google.com"),          0, {}},
    128     {ASCIIToUTF16("http://www.google.com"),        0, {}},
    129     {ASCIIToUTF16("file:filename"),                0, {}},
    130     {ASCIIToUTF16("scheme:"),                      0, {}},
    131     {ASCIIToUTF16("scheme://"),                    0, {}},
    132     {ASCIIToUTF16("scheme://host"),                0, {}},
    133     {ASCIIToUTF16("scheme:host/path?query#ref"),   0, {}},
    134     {ASCIIToUTF16("scheme://host/path?query#ref"), 0, {}},
    135   };
    136 
    137   RunTest<GURL>(non_chrome_url_cases, arraysize(non_chrome_url_cases),
    138                 &AutocompleteMatch::destination_url);
    139 }
    140 
    141 TEST_F(BuiltinProviderTest, ChromeURLs) {
    142   const base::string16 kAbout = ASCIIToUTF16(chrome::kAboutScheme);
    143   const base::string16 kChrome = ASCIIToUTF16(chrome::kChromeUIScheme);
    144   const base::string16 kSeparator1 = ASCIIToUTF16(":");
    145   const base::string16 kSeparator2 = ASCIIToUTF16(":/");
    146   const base::string16 kSeparator3 =
    147       ASCIIToUTF16(content::kStandardSchemeSeparator);
    148 
    149   // This makes assumptions about the chrome URLs listed by the BuiltinProvider.
    150   // Currently they are derived from chrome::kChromeHostURLs[].
    151   const base::string16 kHostM1 =
    152       ASCIIToUTF16(content::kChromeUIMediaInternalsHost);
    153   const base::string16 kHostM2 =
    154       ASCIIToUTF16(chrome::kChromeUIMemoryHost);
    155   const base::string16 kHostM3 =
    156       ASCIIToUTF16(chrome::kChromeUIMemoryInternalsHost);
    157   const GURL kURLM1 = GURL(kChrome + kSeparator3 + kHostM1);
    158   const GURL kURLM2 = GURL(kChrome + kSeparator3 + kHostM2);
    159   const GURL kURLM3 = GURL(kChrome + kSeparator3 + kHostM3);
    160 
    161   test_data<GURL> chrome_url_cases[] = {
    162     // Typing an about URL with an unknown host should give nothing.
    163     {kAbout + kSeparator1 + ASCIIToUTF16("host"), 0, {}},
    164     {kAbout + kSeparator2 + ASCIIToUTF16("host"), 0, {}},
    165     {kAbout + kSeparator3 + ASCIIToUTF16("host"), 0, {}},
    166 
    167     // Typing a chrome URL with an unknown host should give nothing.
    168     {kChrome + kSeparator1 + ASCIIToUTF16("host"), 0, {}},
    169     {kChrome + kSeparator2 + ASCIIToUTF16("host"), 0, {}},
    170     {kChrome + kSeparator3 + ASCIIToUTF16("host"), 0, {}},
    171 
    172     // Typing an about URL should provide matching URLs.
    173     {kAbout + kSeparator1 + kHostM1.substr(0, 1), 3, {kURLM1, kURLM2, kURLM3}},
    174     {kAbout + kSeparator2 + kHostM1.substr(0, 2), 3, {kURLM1, kURLM2, kURLM3}},
    175     {kAbout + kSeparator3 + kHostM1.substr(0, 3), 1, {kURLM1}},
    176     {kAbout + kSeparator3 + kHostM2.substr(0, 3), 2, {kURLM2, kURLM3}},
    177     {kAbout + kSeparator3 + kHostM1,              1, {kURLM1}},
    178     {kAbout + kSeparator2 + kHostM2,              2, {kURLM2, kURLM3}},
    179     {kAbout + kSeparator2 + kHostM3,              1, {kURLM3}},
    180 
    181     // Typing a chrome URL should provide matching URLs.
    182     {kChrome + kSeparator1 + kHostM1.substr(0, 1), 3, {kURLM1, kURLM2, kURLM3}},
    183     {kChrome + kSeparator2 + kHostM1.substr(0, 2), 3, {kURLM1, kURLM2, kURLM3}},
    184     {kChrome + kSeparator3 + kHostM1.substr(0, 3), 1, {kURLM1}},
    185     {kChrome + kSeparator3 + kHostM2.substr(0, 3), 2, {kURLM2, kURLM3}},
    186     {kChrome + kSeparator3 + kHostM1,              1, {kURLM1}},
    187     {kChrome + kSeparator2 + kHostM2,              2, {kURLM2, kURLM3}},
    188     {kChrome + kSeparator2 + kHostM3,              1, {kURLM3}},
    189   };
    190 
    191   RunTest<GURL>(chrome_url_cases, arraysize(chrome_url_cases),
    192                 &AutocompleteMatch::destination_url);
    193 }
    194 
    195 #if !defined(OS_ANDROID)
    196 // Disabled on Android where we use native UI instead of chrome://settings.
    197 TEST_F(BuiltinProviderTest, ChromeSettingsSubpages) {
    198   // This makes assumptions about the chrome URLs listed by the BuiltinProvider.
    199   // Currently they are derived from chrome::kChromeHostURLs[].
    200   const base::string16 kSettings = ASCIIToUTF16(chrome::kChromeUISettingsURL);
    201   const base::string16 kDefaultPage1 = ASCIIToUTF16(chrome::kAutofillSubPage);
    202   const base::string16 kDefaultPage2 =
    203       ASCIIToUTF16(chrome::kClearBrowserDataSubPage);
    204   const GURL kDefaultURL1 = GURL(kSettings + kDefaultPage1);
    205   const GURL kDefaultURL2 = GURL(kSettings + kDefaultPage2);
    206   const base::string16 kPage1 = ASCIIToUTF16(chrome::kSearchEnginesSubPage);
    207   const base::string16 kPage2 = ASCIIToUTF16(chrome::kSyncSetupSubPage);
    208   const GURL kURL1 = GURL(kSettings + kPage1);
    209   const GURL kURL2 = GURL(kSettings + kPage2);
    210 
    211   test_data<GURL> settings_subpage_cases[] = {
    212     // Typing the settings path should show settings and the first two subpages.
    213     {kSettings, 3, {GURL(kSettings), kDefaultURL1, kDefaultURL2}},
    214 
    215     // Typing a subpage path should return the appropriate results.
    216     {kSettings + kPage1.substr(0, 1),                   2, {kURL1, kURL2}},
    217     {kSettings + kPage1.substr(0, 2),                   1, {kURL1}},
    218     {kSettings + kPage1.substr(0, kPage1.length() - 1), 1, {kURL1}},
    219     {kSettings + kPage1,                                1, {kURL1}},
    220     {kSettings + kPage2,                                1, {kURL2}},
    221   };
    222 
    223   RunTest<GURL>(settings_subpage_cases, arraysize(settings_subpage_cases),
    224                 &AutocompleteMatch::destination_url);
    225 }
    226 #endif
    227