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