OLD | NEW |
| (Empty) |
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 "components/omnibox/browser/shortcuts_provider.h" | |
6 | |
7 #include <math.h> | |
8 #include <stddef.h> | |
9 | |
10 #include <algorithm> | |
11 #include <functional> | |
12 #include <set> | |
13 #include <string> | |
14 #include <vector> | |
15 | |
16 #include "base/macros.h" | |
17 #include "base/memory/ref_counted.h" | |
18 #include "base/message_loop/message_loop.h" | |
19 #include "base/strings/stringprintf.h" | |
20 #include "base/strings/utf_string_conversions.h" | |
21 #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" | |
22 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" | |
23 #include "chrome/browser/autocomplete/shortcuts_backend_factory.h" | |
24 #include "chrome/test/base/testing_profile.h" | |
25 #include "components/history/core/browser/history_service.h" | |
26 #include "components/history/core/browser/url_database.h" | |
27 #include "components/metrics/proto/omnibox_event.pb.h" | |
28 #include "components/omnibox/browser/autocomplete_input.h" | |
29 #include "components/omnibox/browser/autocomplete_match.h" | |
30 #include "components/omnibox/browser/autocomplete_provider.h" | |
31 #include "components/omnibox/browser/autocomplete_result.h" | |
32 #include "components/omnibox/browser/in_memory_url_index.h" | |
33 #include "components/omnibox/browser/shortcuts_backend.h" | |
34 #include "components/prefs/pref_service.h" | |
35 #include "content/public/browser/notification_service.h" | |
36 #include "content/public/test/test_browser_thread.h" | |
37 #include "testing/gtest/include/gtest/gtest.h" | |
38 | |
39 #if defined(ENABLE_EXTENSIONS) | |
40 #include "extensions/browser/notification_types.h" | |
41 #include "extensions/common/extension.h" | |
42 #include "extensions/common/extension_builder.h" | |
43 #include "extensions/common/value_builder.h" | |
44 #endif | |
45 | |
46 using base::ASCIIToUTF16; | |
47 | |
48 // TestShortcutInfo ----------------------------------------------------------- | |
49 | |
50 namespace { | |
51 | |
52 struct TestShortcutInfo { | |
53 std::string guid; | |
54 std::string text; | |
55 std::string fill_into_edit; | |
56 std::string destination_url; | |
57 std::string contents; | |
58 std::string contents_class; | |
59 std::string description; | |
60 std::string description_class; | |
61 ui::PageTransition transition; | |
62 AutocompleteMatch::Type type; | |
63 std::string keyword; | |
64 int days_from_now; | |
65 int number_of_hits; | |
66 } shortcut_test_db[] = { | |
67 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", "goog", "www.google.com", | |
68 "http://www.google.com/", "Google", "0,1,4,0", "Google", "0,3,4,1", | |
69 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 1, | |
70 100 }, | |
71 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", "slash", "slashdot.org", | |
72 "http://slashdot.org/", "slashdot.org", "0,3,5,1", | |
73 "Slashdot - News for nerds, stuff that matters", "0,2,5,0", | |
74 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 0, | |
75 100 }, | |
76 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E2", "news", "slashdot.org", | |
77 "http://slashdot.org/", "slashdot.org", "0,1", | |
78 "Slashdot - News for nerds, stuff that matters", "0,0,11,2,15,0", | |
79 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_TITLE, "", 0, | |
80 5 }, | |
81 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E3", "news", "sports.yahoo.com", | |
82 "http://sports.yahoo.com/", "sports.yahoo.com", "0,1", | |
83 "Yahoo! Sports - Sports News, Scores, Rumors, Fantasy Games, and more", | |
84 "0,0,23,2,27,0", ui::PAGE_TRANSITION_TYPED, | |
85 AutocompleteMatchType::HISTORY_TITLE, "", 2, 5 }, | |
86 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E4", "news weather", | |
87 "www.cnn.com/index.html", "http://www.cnn.com/index.html", | |
88 "www.cnn.com/index.html", "0,1", | |
89 "CNN.com - Breaking News, U.S., World, Weather, Entertainment & Video", | |
90 "0,0,19,2,23,0,38,2,45,0", ui::PAGE_TRANSITION_TYPED, | |
91 AutocompleteMatchType::HISTORY_TITLE, "", 1, 10 }, | |
92 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E5", "nhl scores", "sports.yahoo.com", | |
93 "http://sports.yahoo.com/", "sports.yahoo.com", "0,1", | |
94 "Yahoo! Sports - Sports News, Scores, Rumors, Fantasy Games, and more", | |
95 "0,0,29,2,35,0", ui::PAGE_TRANSITION_TYPED, | |
96 AutocompleteMatchType::HISTORY_BODY, "", 1, 10 }, | |
97 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E6", "nhl scores", | |
98 "www.nhl.com/scores/index.html", "http://www.nhl.com/scores/index.html", | |
99 "www.nhl.com/scores/index.html", "0,1,4,3,7,1", | |
100 "January 13, 2010 - NHL.com - Scores", "0,0,19,2,22,0,29,2,35,0", | |
101 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 5, | |
102 1 }, | |
103 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E7", "just", "www.testsite.com/a.html", | |
104 "http://www.testsite.com/a.html", "www.testsite.com/a.html", "0,1", | |
105 "Test - site - just a test", "0,0,14,2,18,0", | |
106 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_TITLE, "", 5, | |
107 1 }, | |
108 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E8", "just", "www.testsite.com/b.html", | |
109 "http://www.testsite.com/b.html", "www.testsite.com/b.html", "0,1", | |
110 "Test - site - just a test", "0,0,14,2,18,0", | |
111 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_TITLE, "", 5, | |
112 2 }, | |
113 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E9", "just", "www.testsite.com/c.html", | |
114 "http://www.testsite.com/c.html", "www.testsite.com/c.html", "0,1", | |
115 "Test - site - just a test", "0,0,14,2,18,0", | |
116 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_TITLE, "", 8, | |
117 1 }, | |
118 { "BD85DBA2-8C29-49F9-84AE-48E1E90880EA", "just a", "www.testsite.com/d.html", | |
119 "http://www.testsite.com/d.html", "www.testsite.com/d.html", "0,1", | |
120 "Test - site - just a test", "0,0,14,2,18,0", | |
121 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_TITLE, "", | |
122 12, 1 }, | |
123 { "BD85DBA2-8C29-49F9-84AE-48E1E90880EB", "just a t", | |
124 "www.testsite.com/e.html", "http://www.testsite.com/e.html", | |
125 "www.testsite.com/e.html", "0,1", "Test - site - just a test", | |
126 "0,0,14,2,18,0", ui::PAGE_TRANSITION_TYPED, | |
127 AutocompleteMatchType::HISTORY_TITLE, "", 12, 1 }, | |
128 { "BD85DBA2-8C29-49F9-84AE-48E1E90880EC", "just a te", | |
129 "www.testsite.com/f.html", "http://www.testsite.com/f.html", | |
130 "www.testsite.com/f.html", "0,1", "Test - site - just a test", | |
131 "0,0,14,2,18,0", ui::PAGE_TRANSITION_TYPED, | |
132 AutocompleteMatchType::HISTORY_TITLE, "", 12, 1 }, | |
133 { "BD85DBA2-8C29-49F9-84AE-48E1E90880ED", "ago", "www.daysagotest.com/a.html", | |
134 "http://www.daysagotest.com/a.html", "www.daysagotest.com/a.html", | |
135 "0,1,8,3,11,1", "Test - site", "0,0", ui::PAGE_TRANSITION_TYPED, | |
136 AutocompleteMatchType::HISTORY_URL, "", 1, 1 }, | |
137 { "BD85DBA2-8C29-49F9-84AE-48E1E90880EE", "ago", "www.daysagotest.com/b.html", | |
138 "http://www.daysagotest.com/b.html", "www.daysagotest.com/b.html", | |
139 "0,1,8,3,11,1", "Test - site", "0,0", ui::PAGE_TRANSITION_TYPED, | |
140 AutocompleteMatchType::HISTORY_URL, "", 2, 1 }, | |
141 { "BD85DBA2-8C29-49F9-84AE-48E1E90880EF", "ago", "www.daysagotest.com/c.html", | |
142 "http://www.daysagotest.com/c.html", "www.daysagotest.com/c.html", | |
143 "0,1,8,3,11,1", "Test - site", "0,0", ui::PAGE_TRANSITION_TYPED, | |
144 AutocompleteMatchType::HISTORY_URL, "", 3, 1 }, | |
145 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F0", "ago", "www.daysagotest.com/d.html", | |
146 "http://www.daysagotest.com/d.html", "www.daysagotest.com/d.html", | |
147 "0,1,8,3,11,1", "Test - site", "0,0", ui::PAGE_TRANSITION_TYPED, | |
148 AutocompleteMatchType::HISTORY_URL, "", 4, 1 }, | |
149 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F1", "echo echo", "echo echo", | |
150 "chrome-extension://cedabbhfglmiikkmdgcpjdkocfcmbkee/?q=echo", | |
151 "Run Echo command: echo", "0,0", "Echo", "0,4", | |
152 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::EXTENSION_APP, | |
153 "echo", 1, 1 }, | |
154 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F2", "abcdef.com", "http://abcdef.com", | |
155 "http://abcdef.com/", "Abcdef", "0,1,4,0", "Abcdef", "0,3,4,1", | |
156 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 1, | |
157 100 }, | |
158 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F3", "query", "query", | |
159 "https://www.google.com/search?q=query", "query", "0,0", | |
160 "Google Search", "0,4", ui::PAGE_TRANSITION_GENERATED, | |
161 AutocompleteMatchType::SEARCH_HISTORY, "", 1, 100 }, | |
162 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F4", "word", "www.word", | |
163 "https://www.google.com/search?q=www.word", "www.word", "0,0", | |
164 "Google Search", "0,4", ui::PAGE_TRANSITION_GENERATED, | |
165 AutocompleteMatchType::SEARCH_HISTORY, "", 1, 100 }, | |
166 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F5", "about:o", "chrome://omnibox", | |
167 "chrome://omnibox/", "about:omnibox", "0,3,10,1", "", "", | |
168 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::NAVSUGGEST, "", | |
169 1, 100 }, | |
170 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F6", "www/real sp", | |
171 "http://www/real space/long-url-with-space.html", | |
172 "http://www/real%20space/long-url-with-space.html", | |
173 "www/real space/long-url-with-space.html", "0,3,11,1", | |
174 "Page With Space; Input with Space", "0,0", | |
175 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", | |
176 1, 100 }, | |
177 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F7", "duplicate", "http://duplicate.com", | |
178 "http://duplicate.com/", "Duplicate", "0,1", "Duplicate", "0,1", | |
179 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 1, | |
180 100 }, | |
181 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F8", "dupl", "http://duplicate.com", | |
182 "http://duplicate.com/", "Duplicate", "0,1", "Duplicate", "0,1", | |
183 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 1, | |
184 100 }, | |
185 { "BD85DBA2-8C29-49F9-84AE-48E1E90880F9", "notrailing.com/", | |
186 "http://notrailing.com", "http://notrailing.com/", "No Trailing Slash", | |
187 "0,1", "No Trailing Slash on fill_into_edit", "0,1", | |
188 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", | |
189 1, 100 }, | |
190 { "BD85DBA2-8C29-49F9-84AE-48E1E90880FA", "http:///foo.com", | |
191 "http://foo.com", "http://foo.com/", "Foo - Typo in Input", | |
192 "0,1", "Foo - Typo in Input Corrected in fill_into_edit", "0,1", | |
193 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", | |
194 1, 100 }, | |
195 { "BD85DBA2-8C29-49F9-84AE-48E1E90880FB", "trailing1 ", | |
196 "http://trailing1.com", "http://trailing1.com/", | |
197 "Trailing1 - Space in Shortcut", "0,1", | |
198 "Trailing1 - Space in Shortcut", "0,1", ui::PAGE_TRANSITION_TYPED, | |
199 AutocompleteMatchType::HISTORY_URL, "", 1, 100 }, | |
200 { "BD85DBA2-8C29-49F9-84AE-48E1E90880FC", "about:trailing2 ", | |
201 "chrome://trailing2blah", "chrome://trailing2blah/", | |
202 "Trailing2 - Space in Shortcut", "0,1", | |
203 "Trailing2 - Space in Shortcut", "0,1", ui::PAGE_TRANSITION_TYPED, | |
204 AutocompleteMatchType::HISTORY_URL, "", 1, 100 }, | |
205 }; | |
206 | |
207 } // namespace | |
208 | |
209 | |
210 // ClassifyTest --------------------------------------------------------------- | |
211 | |
212 // Helper class to make running tests of ClassifyAllMatchesInString() more | |
213 // convenient. | |
214 class ClassifyTest { | |
215 public: | |
216 ClassifyTest(const base::string16& text, ACMatchClassifications matches); | |
217 ~ClassifyTest(); | |
218 | |
219 ACMatchClassifications RunTest(const base::string16& find_text); | |
220 | |
221 private: | |
222 const base::string16 text_; | |
223 const ACMatchClassifications matches_; | |
224 }; | |
225 | |
226 ClassifyTest::ClassifyTest(const base::string16& text, | |
227 ACMatchClassifications matches) | |
228 : text_(text), | |
229 matches_(matches) { | |
230 } | |
231 | |
232 ClassifyTest::~ClassifyTest() { | |
233 } | |
234 | |
235 ACMatchClassifications ClassifyTest::RunTest(const base::string16& find_text) { | |
236 return ShortcutsProvider::ClassifyAllMatchesInString(find_text, | |
237 ShortcutsProvider::CreateWordMapForString(find_text), text_, matches_); | |
238 } | |
239 | |
240 | |
241 // ShortcutsProviderTest ------------------------------------------------------ | |
242 | |
243 class ShortcutsProviderTest : public testing::Test { | |
244 public: | |
245 ShortcutsProviderTest(); | |
246 | |
247 protected: | |
248 typedef std::pair<std::string, bool> ExpectedURLAndAllowedToBeDefault; | |
249 typedef std::vector<ExpectedURLAndAllowedToBeDefault> ExpectedURLs; | |
250 | |
251 class SetShouldContain | |
252 : public std::unary_function<const ExpectedURLAndAllowedToBeDefault&, | |
253 std::set<std::string> > { | |
254 public: | |
255 explicit SetShouldContain(const ACMatches& matched_urls); | |
256 | |
257 void operator()(const ExpectedURLAndAllowedToBeDefault& expected); | |
258 std::set<ExpectedURLAndAllowedToBeDefault> Leftovers() const { | |
259 return matches_; | |
260 } | |
261 | |
262 private: | |
263 std::set<ExpectedURLAndAllowedToBeDefault> matches_; | |
264 }; | |
265 | |
266 void SetUp() override; | |
267 void TearDown() override; | |
268 | |
269 // Fills test data into the provider. | |
270 void FillData(TestShortcutInfo* db, size_t db_size); | |
271 | |
272 // Runs an autocomplete query on |text| with the provided | |
273 // |prevent_inline_autocomplete| setting and checks to see that the returned | |
274 // results' destination URLs match those provided. |expected_urls| does not | |
275 // need to be in sorted order, but |expected_top_result| should be the top | |
276 // match, and it should have inline autocompletion | |
277 // |top_result_inline_autocompletion|. | |
278 void RunTest(const base::string16 text, | |
279 bool prevent_inline_autocomplete, | |
280 const ExpectedURLs& expected_urls, | |
281 std::string expected_top_result, | |
282 base::string16 top_result_inline_autocompletion); | |
283 | |
284 // Passthrough to the private function in provider_. | |
285 int CalculateScore(const std::string& terms, | |
286 const ShortcutsDatabase::Shortcut& shortcut, | |
287 int max_relevance); | |
288 | |
289 base::MessageLoopForUI message_loop_; | |
290 content::TestBrowserThread ui_thread_; | |
291 content::TestBrowserThread file_thread_; | |
292 | |
293 TestingProfile profile_; | |
294 ChromeAutocompleteProviderClient client_; | |
295 | |
296 ACMatches ac_matches_; // The resulting matches after running RunTest. | |
297 | |
298 scoped_refptr<ShortcutsBackend> backend_; | |
299 scoped_refptr<ShortcutsProvider> provider_; | |
300 }; | |
301 | |
302 ShortcutsProviderTest::ShortcutsProviderTest() | |
303 : ui_thread_(content::BrowserThread::UI, &message_loop_), | |
304 file_thread_(content::BrowserThread::FILE, &message_loop_), | |
305 client_(&profile_) { | |
306 } | |
307 | |
308 void ShortcutsProviderTest::SetUp() { | |
309 ShortcutsBackendFactory::GetInstance()->SetTestingFactoryAndUse( | |
310 &profile_, &ShortcutsBackendFactory::BuildProfileNoDatabaseForTesting); | |
311 backend_ = ShortcutsBackendFactory::GetForProfile(&profile_); | |
312 ASSERT_TRUE(backend_.get()); | |
313 ASSERT_TRUE(profile_.CreateHistoryService(true, false)); | |
314 provider_ = new ShortcutsProvider(&client_); | |
315 FillData(shortcut_test_db, arraysize(shortcut_test_db)); | |
316 } | |
317 | |
318 void ShortcutsProviderTest::TearDown() { | |
319 // Run all pending tasks or else some threads hold on to the message loop | |
320 // and prevent it from being deleted. | |
321 message_loop_.RunUntilIdle(); | |
322 profile_.DestroyHistoryService(); | |
323 provider_ = NULL; | |
324 } | |
325 | |
326 void ShortcutsProviderTest::FillData(TestShortcutInfo* db, size_t db_size) { | |
327 DCHECK(provider_.get()); | |
328 size_t expected_size = backend_->shortcuts_map().size() + db_size; | |
329 for (size_t i = 0; i < db_size; ++i) { | |
330 const TestShortcutInfo& cur = db[i]; | |
331 ShortcutsDatabase::Shortcut shortcut( | |
332 cur.guid, ASCIIToUTF16(cur.text), | |
333 ShortcutsDatabase::Shortcut::MatchCore( | |
334 ASCIIToUTF16(cur.fill_into_edit), GURL(cur.destination_url), | |
335 ASCIIToUTF16(cur.contents), cur.contents_class, | |
336 ASCIIToUTF16(cur.description), cur.description_class, | |
337 cur.transition, cur.type, ASCIIToUTF16(cur.keyword)), | |
338 base::Time::Now() - base::TimeDelta::FromDays(cur.days_from_now), | |
339 cur.number_of_hits); | |
340 backend_->AddShortcut(shortcut); | |
341 } | |
342 EXPECT_EQ(expected_size, backend_->shortcuts_map().size()); | |
343 } | |
344 | |
345 ShortcutsProviderTest::SetShouldContain::SetShouldContain( | |
346 const ACMatches& matched_urls) { | |
347 for (ACMatches::const_iterator iter = matched_urls.begin(); | |
348 iter != matched_urls.end(); ++iter) | |
349 matches_.insert(ExpectedURLAndAllowedToBeDefault( | |
350 iter->destination_url.spec(), iter->allowed_to_be_default_match)); | |
351 } | |
352 | |
353 void ShortcutsProviderTest::SetShouldContain::operator()( | |
354 const ExpectedURLAndAllowedToBeDefault& expected) { | |
355 EXPECT_EQ(1U, matches_.erase(expected)); | |
356 } | |
357 | |
358 void ShortcutsProviderTest::RunTest( | |
359 const base::string16 text, | |
360 bool prevent_inline_autocomplete, | |
361 const ExpectedURLs& expected_urls, | |
362 std::string expected_top_result, | |
363 base::string16 top_result_inline_autocompletion) { | |
364 base::MessageLoop::current()->RunUntilIdle(); | |
365 AutocompleteInput input(text, base::string16::npos, std::string(), GURL(), | |
366 metrics::OmniboxEventProto::INVALID_SPEC, | |
367 prevent_inline_autocomplete, false, true, true, false, | |
368 ChromeAutocompleteSchemeClassifier(&profile_)); | |
369 provider_->Start(input, false); | |
370 EXPECT_TRUE(provider_->done()); | |
371 | |
372 ac_matches_ = provider_->matches(); | |
373 | |
374 // We should have gotten back at most AutocompleteProvider::kMaxMatches. | |
375 EXPECT_LE(ac_matches_.size(), AutocompleteProvider::kMaxMatches); | |
376 | |
377 // If the number of expected and actual matches aren't equal then we need | |
378 // test no further, but let's do anyway so that we know which URLs failed. | |
379 EXPECT_EQ(expected_urls.size(), ac_matches_.size()); | |
380 | |
381 // Verify that all expected URLs were found and that all found URLs | |
382 // were expected. | |
383 std::set<ExpectedURLAndAllowedToBeDefault> Leftovers = | |
384 for_each(expected_urls.begin(), expected_urls.end(), | |
385 SetShouldContain(ac_matches_)).Leftovers(); | |
386 EXPECT_EQ(0U, Leftovers.size()); | |
387 | |
388 // See if we got the expected top scorer. | |
389 if (!ac_matches_.empty()) { | |
390 std::partial_sort(ac_matches_.begin(), ac_matches_.begin() + 1, | |
391 ac_matches_.end(), AutocompleteMatch::MoreRelevant); | |
392 EXPECT_EQ(expected_top_result, ac_matches_[0].destination_url.spec()); | |
393 EXPECT_EQ(top_result_inline_autocompletion, | |
394 ac_matches_[0].inline_autocompletion); | |
395 } | |
396 } | |
397 | |
398 int ShortcutsProviderTest::CalculateScore( | |
399 const std::string& terms, | |
400 const ShortcutsDatabase::Shortcut& shortcut, | |
401 int max_relevance) { | |
402 return provider_->CalculateScore(ASCIIToUTF16(terms), shortcut, | |
403 max_relevance); | |
404 } | |
405 | |
406 | |
407 // Actual tests --------------------------------------------------------------- | |
408 | |
409 TEST_F(ShortcutsProviderTest, SimpleSingleMatch) { | |
410 base::string16 text(ASCIIToUTF16("go")); | |
411 std::string expected_url("http://www.google.com/"); | |
412 ExpectedURLs expected_urls; | |
413 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
414 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16("ogle.com")); | |
415 | |
416 // Same test with prevent inline autocomplete. | |
417 expected_urls.clear(); | |
418 expected_urls.push_back( | |
419 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
420 // The match will have an |inline_autocompletion| set, but the value will not | |
421 // be used because |allowed_to_be_default_match| will be false. | |
422 RunTest(text, true, expected_urls, expected_url, ASCIIToUTF16("ogle.com")); | |
423 | |
424 // A pair of analogous tests where the shortcut ends at the end of | |
425 // |fill_into_edit|. This exercises the inline autocompletion and default | |
426 // match code. | |
427 text = ASCIIToUTF16("abcdef.com"); | |
428 expected_url = "http://abcdef.com/"; | |
429 expected_urls.clear(); | |
430 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
431 RunTest(text, false, expected_urls, expected_url, base::string16()); | |
432 // With prevent inline autocomplete, the suggestion should be the same | |
433 // (because there is no completion). | |
434 RunTest(text, true, expected_urls, expected_url, base::string16()); | |
435 | |
436 // Another test, simply for a query match type, not a navigation URL match | |
437 // type. | |
438 text = ASCIIToUTF16("que"); | |
439 expected_url = "https://www.google.com/search?q=query"; | |
440 expected_urls.clear(); | |
441 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
442 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16("ry")); | |
443 | |
444 // Same test with prevent inline autocomplete. | |
445 expected_urls.clear(); | |
446 expected_urls.push_back( | |
447 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
448 // The match will have an |inline_autocompletion| set, but the value will not | |
449 // be used because |allowed_to_be_default_match| will be false. | |
450 RunTest(text, true, expected_urls, expected_url, ASCIIToUTF16("ry")); | |
451 | |
452 // A pair of analogous tests where the shortcut ends at the end of | |
453 // |fill_into_edit|. This exercises the inline autocompletion and default | |
454 // match code. | |
455 text = ASCIIToUTF16("query"); | |
456 expected_urls.clear(); | |
457 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
458 RunTest(text, false, expected_urls, expected_url, base::string16()); | |
459 // With prevent inline autocomplete, the suggestion should be the same | |
460 // (because there is no completion). | |
461 RunTest(text, true, expected_urls, expected_url, base::string16()); | |
462 | |
463 // Now the shortcut ends at the end of |fill_into_edit| but has a | |
464 // non-droppable prefix. ("www.", for instance, is not droppable for | |
465 // queries.) | |
466 text = ASCIIToUTF16("word"); | |
467 expected_url = "https://www.google.com/search?q=www.word"; | |
468 expected_urls.clear(); | |
469 expected_urls.push_back( | |
470 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
471 RunTest(text, false, expected_urls, expected_url, base::string16()); | |
472 } | |
473 | |
474 // These tests are like those in SimpleSingleMatch but more complex, | |
475 // involving URLs that need to be fixed up to match properly. | |
476 TEST_F(ShortcutsProviderTest, TrickySingleMatch) { | |
477 // Test that about: URLs are fixed up/transformed to chrome:// URLs. | |
478 base::string16 text(ASCIIToUTF16("about:o")); | |
479 std::string expected_url("chrome://omnibox/"); | |
480 ExpectedURLs expected_urls; | |
481 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
482 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16("mnibox")); | |
483 | |
484 // Same test with prevent inline autocomplete. | |
485 expected_urls.clear(); | |
486 expected_urls.push_back( | |
487 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
488 // The match will have an |inline_autocompletion| set, but the value will not | |
489 // be used because |allowed_to_be_default_match| will be false. | |
490 RunTest(text, true, expected_urls, expected_url, ASCIIToUTF16("mnibox")); | |
491 | |
492 // Test that an input with a space can match URLs with a (escaped) space. | |
493 // This would fail if we didn't try to lookup the un-fixed-up string. | |
494 text = ASCIIToUTF16("www/real sp"); | |
495 expected_url = "http://www/real%20space/long-url-with-space.html"; | |
496 expected_urls.clear(); | |
497 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
498 RunTest(text, false, expected_urls, expected_url, | |
499 ASCIIToUTF16("ace/long-url-with-space.html")); | |
500 | |
501 // Same test with prevent inline autocomplete. | |
502 expected_urls.clear(); | |
503 expected_urls.push_back( | |
504 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
505 // The match will have an |inline_autocompletion| set, but the value will not | |
506 // be used because |allowed_to_be_default_match| will be false. | |
507 RunTest(text, true, expected_urls, expected_url, | |
508 ASCIIToUTF16("ace/long-url-with-space.html")); | |
509 | |
510 // Test when the user input has a trailing slash but fill_into_edit does | |
511 // not. This should still be allowed to be default. | |
512 text = ASCIIToUTF16("notrailing.com/"); | |
513 expected_url = "http://notrailing.com/"; | |
514 expected_urls.clear(); | |
515 expected_urls.push_back( | |
516 ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
517 RunTest(text, true, expected_urls, expected_url, base::string16()); | |
518 | |
519 // Test when the user input has a typo that can be fixed up for matching | |
520 // fill_into_edit. This should still be allowed to be default. | |
521 text = ASCIIToUTF16("http:///foo.com"); | |
522 expected_url = "http://foo.com/"; | |
523 expected_urls.clear(); | |
524 expected_urls.push_back( | |
525 ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
526 RunTest(text, true, expected_urls, expected_url, base::string16()); | |
527 | |
528 // A foursome of tests to verify that trailing spaces prevent the shortcut | |
529 // from being allowed to be the default match. For each of two tests, we | |
530 // first verify that the match is allowed to be default without the trailing | |
531 // space but is not allowed to be default with the trailing space. In both | |
532 // of these with-trailing-space cases, we actually get an | |
533 // inline_autocompletion, though it's never used because the match is | |
534 // prohibited from being default. | |
535 text = ASCIIToUTF16("trailing1"); | |
536 expected_url = "http://trailing1.com/"; | |
537 expected_urls.clear(); | |
538 expected_urls.push_back( | |
539 ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
540 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16(".com")); | |
541 text = ASCIIToUTF16("trailing1 "); | |
542 expected_urls.clear(); | |
543 expected_urls.push_back( | |
544 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
545 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16(".com")); | |
546 text = ASCIIToUTF16("about:trailing2"); | |
547 expected_url = "chrome://trailing2blah/"; | |
548 expected_urls.clear(); | |
549 expected_urls.push_back( | |
550 ExpectedURLAndAllowedToBeDefault(expected_url, true)); | |
551 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16("blah")); | |
552 text = ASCIIToUTF16("about:trailing2 "); | |
553 expected_urls.clear(); | |
554 expected_urls.push_back( | |
555 ExpectedURLAndAllowedToBeDefault(expected_url, false)); | |
556 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16("blah")); | |
557 } | |
558 | |
559 TEST_F(ShortcutsProviderTest, MultiMatch) { | |
560 base::string16 text(ASCIIToUTF16("NEWS")); | |
561 ExpectedURLs expected_urls; | |
562 // Scores high because of completion length. | |
563 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
564 "http://slashdot.org/", false)); | |
565 // Scores high because of visit count. | |
566 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
567 "http://sports.yahoo.com/", false)); | |
568 // Scores high because of visit count but less match span, | |
569 // which is more important. | |
570 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
571 "http://www.cnn.com/index.html", false)); | |
572 RunTest(text, false, expected_urls, "http://slashdot.org/", base::string16()); | |
573 } | |
574 | |
575 TEST_F(ShortcutsProviderTest, RemoveDuplicates) { | |
576 base::string16 text(ASCIIToUTF16("dupl")); | |
577 ExpectedURLs expected_urls; | |
578 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
579 "http://duplicate.com/", true)); | |
580 // Make sure the URL only appears once in the output list. | |
581 RunTest(text, false, expected_urls, "http://duplicate.com/", | |
582 ASCIIToUTF16("icate.com")); | |
583 } | |
584 | |
585 TEST_F(ShortcutsProviderTest, TypedCountMatches) { | |
586 base::string16 text(ASCIIToUTF16("just")); | |
587 ExpectedURLs expected_urls; | |
588 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
589 "http://www.testsite.com/b.html", false)); | |
590 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
591 "http://www.testsite.com/a.html", false)); | |
592 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
593 "http://www.testsite.com/c.html", false)); | |
594 RunTest(text, false, expected_urls, "http://www.testsite.com/b.html", | |
595 base::string16()); | |
596 } | |
597 | |
598 TEST_F(ShortcutsProviderTest, FragmentLengthMatches) { | |
599 base::string16 text(ASCIIToUTF16("just a")); | |
600 ExpectedURLs expected_urls; | |
601 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
602 "http://www.testsite.com/d.html", false)); | |
603 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
604 "http://www.testsite.com/e.html", false)); | |
605 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
606 "http://www.testsite.com/f.html", false)); | |
607 RunTest(text, false, expected_urls, "http://www.testsite.com/d.html", | |
608 base::string16()); | |
609 } | |
610 | |
611 TEST_F(ShortcutsProviderTest, DaysAgoMatches) { | |
612 base::string16 text(ASCIIToUTF16("ago")); | |
613 ExpectedURLs expected_urls; | |
614 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
615 "http://www.daysagotest.com/a.html", false)); | |
616 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
617 "http://www.daysagotest.com/b.html", false)); | |
618 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
619 "http://www.daysagotest.com/c.html", false)); | |
620 RunTest(text, false, expected_urls, "http://www.daysagotest.com/a.html", | |
621 base::string16()); | |
622 } | |
623 | |
624 TEST_F(ShortcutsProviderTest, ClassifyAllMatchesInString) { | |
625 ACMatchClassifications matches = | |
626 AutocompleteMatch::ClassificationsFromString("0,0"); | |
627 ClassifyTest classify_test(ASCIIToUTF16("A man, a plan, a canal Panama"), | |
628 matches); | |
629 | |
630 ACMatchClassifications spans_a = classify_test.RunTest(ASCIIToUTF16("man")); | |
631 // ACMatch spans should be: '--MMM------------------------' | |
632 EXPECT_EQ("0,0,2,2,5,0", AutocompleteMatch::ClassificationsToString(spans_a)); | |
633 | |
634 ACMatchClassifications spans_b = classify_test.RunTest(ASCIIToUTF16("man p")); | |
635 // ACMatch spans should be: '--MMM----M-------------M-----' | |
636 EXPECT_EQ("0,0,2,2,5,0,9,2,10,0,23,2,24,0", | |
637 AutocompleteMatch::ClassificationsToString(spans_b)); | |
638 | |
639 ACMatchClassifications spans_c = | |
640 classify_test.RunTest(ASCIIToUTF16("man plan panama")); | |
641 // ACMatch spans should be:'--MMM----MMMM----------MMMMMM' | |
642 EXPECT_EQ("0,0,2,2,5,0,9,2,13,0,23,2", | |
643 AutocompleteMatch::ClassificationsToString(spans_c)); | |
644 | |
645 ClassifyTest classify_test2(ASCIIToUTF16("Yahoo! Sports - Sports News, " | |
646 "Scores, Rumors, Fantasy Games, and more"), matches); | |
647 | |
648 ACMatchClassifications spans_d = classify_test2.RunTest(ASCIIToUTF16("ne")); | |
649 // ACMatch spans should match first two letters of the "news". | |
650 EXPECT_EQ("0,0,23,2,25,0", | |
651 AutocompleteMatch::ClassificationsToString(spans_d)); | |
652 | |
653 ACMatchClassifications spans_e = | |
654 classify_test2.RunTest(ASCIIToUTF16("news r")); | |
655 EXPECT_EQ("0,0,10,2,11,0,19,2,20,0,23,2,27,0,32,2,33,0,37,2,38,0,41,2,42,0," | |
656 "66,2,67,0", AutocompleteMatch::ClassificationsToString(spans_e)); | |
657 | |
658 matches = AutocompleteMatch::ClassificationsFromString("0,1"); | |
659 ClassifyTest classify_test3(ASCIIToUTF16("livescore.goal.com"), matches); | |
660 | |
661 ACMatchClassifications spans_f = classify_test3.RunTest(ASCIIToUTF16("go")); | |
662 // ACMatch spans should match first two letters of the "goal". | |
663 EXPECT_EQ("0,1,10,3,12,1", | |
664 AutocompleteMatch::ClassificationsToString(spans_f)); | |
665 | |
666 matches = AutocompleteMatch::ClassificationsFromString("0,0,13,1"); | |
667 ClassifyTest classify_test4(ASCIIToUTF16("Email login: mail.somecorp.com"), | |
668 matches); | |
669 | |
670 ACMatchClassifications spans_g = classify_test4.RunTest(ASCIIToUTF16("ail")); | |
671 EXPECT_EQ("0,0,2,2,5,0,13,1,14,3,17,1", | |
672 AutocompleteMatch::ClassificationsToString(spans_g)); | |
673 | |
674 ACMatchClassifications spans_h = | |
675 classify_test4.RunTest(ASCIIToUTF16("lo log")); | |
676 EXPECT_EQ("0,0,6,2,9,0,13,1", | |
677 AutocompleteMatch::ClassificationsToString(spans_h)); | |
678 | |
679 ACMatchClassifications spans_i = | |
680 classify_test4.RunTest(ASCIIToUTF16("ail em")); | |
681 // 'Email' and 'ail' should be matched. | |
682 EXPECT_EQ("0,2,5,0,13,1,14,3,17,1", | |
683 AutocompleteMatch::ClassificationsToString(spans_i)); | |
684 | |
685 // Some web sites do not have a description. If the string being searched is | |
686 // empty, the classifications must also be empty: http://crbug.com/148647 | |
687 // Extra parens in the next line hack around C++03's "most vexing parse". | |
688 class ClassifyTest classify_test5((base::string16()), | |
689 ACMatchClassifications()); | |
690 ACMatchClassifications spans_j = classify_test5.RunTest(ASCIIToUTF16("man")); | |
691 ASSERT_EQ(0U, spans_j.size()); | |
692 | |
693 // Matches which end at beginning of classification merge properly. | |
694 matches = AutocompleteMatch::ClassificationsFromString("0,4,9,0"); | |
695 ClassifyTest classify_test6(ASCIIToUTF16("html password example"), matches); | |
696 | |
697 // Extra space in the next string avoids having the string be a prefix of the | |
698 // text above, which would allow for two different valid classification sets, | |
699 // one of which uses two spans (the first of which would mark all of "html | |
700 // pass" as a match) and one which uses four (which marks the individual words | |
701 // as matches but not the space between them). This way only the latter is | |
702 // valid. | |
703 ACMatchClassifications spans_k = | |
704 classify_test6.RunTest(ASCIIToUTF16("html pass")); | |
705 EXPECT_EQ("0,6,4,4,5,6,9,0", | |
706 AutocompleteMatch::ClassificationsToString(spans_k)); | |
707 | |
708 // Multiple matches with both beginning and end at beginning of | |
709 // classifications merge properly. | |
710 matches = AutocompleteMatch::ClassificationsFromString("0,1,11,0"); | |
711 ClassifyTest classify_test7(ASCIIToUTF16("http://a.co is great"), matches); | |
712 | |
713 ACMatchClassifications spans_l = | |
714 classify_test7.RunTest(ASCIIToUTF16("ht co")); | |
715 EXPECT_EQ("0,3,2,1,9,3,11,0", | |
716 AutocompleteMatch::ClassificationsToString(spans_l)); | |
717 } | |
718 | |
719 TEST_F(ShortcutsProviderTest, CalculateScore) { | |
720 ShortcutsDatabase::Shortcut shortcut( | |
721 std::string(), ASCIIToUTF16("test"), | |
722 ShortcutsDatabase::Shortcut::MatchCore( | |
723 ASCIIToUTF16("www.test.com"), GURL("http://www.test.com"), | |
724 ASCIIToUTF16("www.test.com"), "0,1,4,3,8,1", | |
725 ASCIIToUTF16("A test"), "0,0,2,2", ui::PAGE_TRANSITION_TYPED, | |
726 AutocompleteMatchType::HISTORY_URL, base::string16()), | |
727 base::Time::Now(), 1); | |
728 | |
729 // Maximal score. | |
730 const int max_relevance = | |
731 ShortcutsProvider::kShortcutsProviderDefaultMaxRelevance; | |
732 const int kMaxScore = CalculateScore("test", shortcut, max_relevance); | |
733 | |
734 // Score decreases as percent of the match is decreased. | |
735 int score_three_quarters = CalculateScore("tes", shortcut, max_relevance); | |
736 EXPECT_LT(score_three_quarters, kMaxScore); | |
737 int score_one_half = CalculateScore("te", shortcut, max_relevance); | |
738 EXPECT_LT(score_one_half, score_three_quarters); | |
739 int score_one_quarter = CalculateScore("t", shortcut, max_relevance); | |
740 EXPECT_LT(score_one_quarter, score_one_half); | |
741 | |
742 // Should decay with time - one week. | |
743 shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(7); | |
744 int score_week_old = CalculateScore("test", shortcut, max_relevance); | |
745 EXPECT_LT(score_week_old, kMaxScore); | |
746 | |
747 // Should decay more in two weeks. | |
748 shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); | |
749 int score_two_weeks_old = CalculateScore("test", shortcut, max_relevance); | |
750 EXPECT_LT(score_two_weeks_old, score_week_old); | |
751 | |
752 // But not if it was activly clicked on. 2 hits slow decaying power. | |
753 shortcut.number_of_hits = 2; | |
754 shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); | |
755 int score_popular_two_weeks_old = | |
756 CalculateScore("test", shortcut, max_relevance); | |
757 EXPECT_LT(score_two_weeks_old, score_popular_two_weeks_old); | |
758 // But still decayed. | |
759 EXPECT_LT(score_popular_two_weeks_old, kMaxScore); | |
760 | |
761 // 3 hits slow decaying power even more. | |
762 shortcut.number_of_hits = 3; | |
763 shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14); | |
764 int score_more_popular_two_weeks_old = | |
765 CalculateScore("test", shortcut, max_relevance); | |
766 EXPECT_LT(score_two_weeks_old, score_more_popular_two_weeks_old); | |
767 EXPECT_LT(score_popular_two_weeks_old, score_more_popular_two_weeks_old); | |
768 // But still decayed. | |
769 EXPECT_LT(score_more_popular_two_weeks_old, kMaxScore); | |
770 } | |
771 | |
772 TEST_F(ShortcutsProviderTest, DeleteMatch) { | |
773 TestShortcutInfo shortcuts_to_test_delete[] = { | |
774 { "BD85DBA2-8C29-49F9-84AE-48E1E90881F1", "delete", "www.deletetest.com/1", | |
775 "http://www.deletetest.com/1", "http://www.deletetest.com/1", "0,2", | |
776 "Erase this shortcut!", "0,0", ui::PAGE_TRANSITION_TYPED, | |
777 AutocompleteMatchType::HISTORY_URL, "", 1, 1}, | |
778 { "BD85DBA2-8C29-49F9-84AE-48E1E90881F2", "erase", "www.deletetest.com/1", | |
779 "http://www.deletetest.com/1", "http://www.deletetest.com/1", "0,2", | |
780 "Erase this shortcut!", "0,0", ui::PAGE_TRANSITION_TYPED, | |
781 AutocompleteMatchType::HISTORY_TITLE, "", 1, 1}, | |
782 { "BD85DBA2-8C29-49F9-84AE-48E1E90881F3", "keep", "www.deletetest.com/1/2", | |
783 "http://www.deletetest.com/1/2", "http://www.deletetest.com/1/2", "0,2", | |
784 "Keep this shortcut!", "0,0", ui::PAGE_TRANSITION_TYPED, | |
785 AutocompleteMatchType::HISTORY_TITLE, "", 1, 1}, | |
786 { "BD85DBA2-8C29-49F9-84AE-48E1E90881F4", "delete", "www.deletetest.com/2", | |
787 "http://www.deletetest.com/2", "http://www.deletetest.com/2", "0,2", | |
788 "Erase this shortcut!", "0,0", ui::PAGE_TRANSITION_TYPED, | |
789 AutocompleteMatchType::HISTORY_URL, "", 1, 1}, | |
790 }; | |
791 | |
792 size_t original_shortcuts_count = backend_->shortcuts_map().size(); | |
793 | |
794 FillData(shortcuts_to_test_delete, arraysize(shortcuts_to_test_delete)); | |
795 | |
796 EXPECT_EQ(original_shortcuts_count + 4, backend_->shortcuts_map().size()); | |
797 EXPECT_FALSE(backend_->shortcuts_map().end() == | |
798 backend_->shortcuts_map().find(ASCIIToUTF16("delete"))); | |
799 EXPECT_FALSE(backend_->shortcuts_map().end() == | |
800 backend_->shortcuts_map().find(ASCIIToUTF16("erase"))); | |
801 | |
802 AutocompleteMatch match( | |
803 provider_.get(), 1200, true, AutocompleteMatchType::HISTORY_TITLE); | |
804 | |
805 match.destination_url = GURL(shortcuts_to_test_delete[0].destination_url); | |
806 match.contents = ASCIIToUTF16(shortcuts_to_test_delete[0].contents); | |
807 match.description = ASCIIToUTF16(shortcuts_to_test_delete[0].description); | |
808 | |
809 provider_->DeleteMatch(match); | |
810 | |
811 // shortcuts_to_test_delete[0] and shortcuts_to_test_delete[1] should be | |
812 // deleted, but not shortcuts_to_test_delete[2] or | |
813 // shortcuts_to_test_delete[3], which have different URLs. | |
814 EXPECT_EQ(original_shortcuts_count + 2, backend_->shortcuts_map().size()); | |
815 EXPECT_FALSE(backend_->shortcuts_map().end() == | |
816 backend_->shortcuts_map().find(ASCIIToUTF16("delete"))); | |
817 EXPECT_TRUE(backend_->shortcuts_map().end() == | |
818 backend_->shortcuts_map().find(ASCIIToUTF16("erase"))); | |
819 | |
820 match.destination_url = GURL(shortcuts_to_test_delete[3].destination_url); | |
821 match.contents = ASCIIToUTF16(shortcuts_to_test_delete[3].contents); | |
822 match.description = ASCIIToUTF16(shortcuts_to_test_delete[3].description); | |
823 | |
824 provider_->DeleteMatch(match); | |
825 EXPECT_EQ(original_shortcuts_count + 1, backend_->shortcuts_map().size()); | |
826 EXPECT_TRUE(backend_->shortcuts_map().end() == | |
827 backend_->shortcuts_map().find(ASCIIToUTF16("delete"))); | |
828 } | |
829 | |
830 TEST_F(ShortcutsProviderTest, DoesNotProvideOnFocus) { | |
831 AutocompleteInput input( | |
832 ASCIIToUTF16("about:o"), base::string16::npos, std::string(), GURL(), | |
833 metrics::OmniboxEventProto::INVALID_SPEC, false, false, true, true, true, | |
834 ChromeAutocompleteSchemeClassifier(&profile_)); | |
835 provider_->Start(input, false); | |
836 EXPECT_TRUE(provider_->matches().empty()); | |
837 } | |
838 | |
839 #if defined(ENABLE_EXTENSIONS) | |
840 TEST_F(ShortcutsProviderTest, Extension) { | |
841 // Try an input string that matches an extension URL. | |
842 base::string16 text(ASCIIToUTF16("echo")); | |
843 std::string expected_url( | |
844 "chrome-extension://cedabbhfglmiikkmdgcpjdkocfcmbkee/?q=echo"); | |
845 ExpectedURLs expected_urls; | |
846 expected_urls.push_back(ExpectedURLAndAllowedToBeDefault( | |
847 expected_url, true)); | |
848 RunTest(text, false, expected_urls, expected_url, ASCIIToUTF16(" echo")); | |
849 | |
850 // Claim the extension has been unloaded. | |
851 scoped_refptr<const extensions::Extension> extension = | |
852 extensions::ExtensionBuilder() | |
853 .SetManifest(std::move(extensions::DictionaryBuilder() | |
854 .Set("name", "Echo") | |
855 .Set("version", "1.0"))) | |
856 .SetID("cedabbhfglmiikkmdgcpjdkocfcmbkee") | |
857 .Build(); | |
858 extensions::UnloadedExtensionInfo details( | |
859 extension.get(), extensions::UnloadedExtensionInfo::REASON_UNINSTALL); | |
860 content::NotificationService::current()->Notify( | |
861 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | |
862 content::Source<Profile>(&profile_), | |
863 content::Details<extensions::UnloadedExtensionInfo>(&details)); | |
864 | |
865 // Now the URL should have disappeared. | |
866 RunTest(text, false, ExpectedURLs(), std::string(), base::string16()); | |
867 } | |
868 #endif | |
OLD | NEW |