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.
5 #include "chrome/browser/autocomplete/shortcuts_backend.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/autocomplete/shortcuts_backend_factory.h"
13 #include "chrome/browser/history/shortcuts_database.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/test/test_browser_thread.h"
16 #include "sql/statement.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 // ShortcutsBackendTest -------------------------------------------------------
23 class ShortcutsBackendTest
: public testing::Test
,
24 public ShortcutsBackend::ShortcutsBackendObserver
{
26 ShortcutsBackendTest();
28 history::ShortcutsDatabase::Shortcut::MatchCore
MatchCoreForTesting(
29 const std::string
& url
,
30 const std::string
& contents_class
= std::string(),
31 const std::string
& description_class
= std::string(),
32 AutocompleteMatch::Type type
= AutocompleteMatchType::URL_WHAT_YOU_TYPED
);
35 virtual void TearDown();
37 virtual void OnShortcutsLoaded() OVERRIDE
;
38 virtual void OnShortcutsChanged() OVERRIDE
;
40 const ShortcutsBackend::ShortcutMap
& shortcuts_map() const {
41 return backend_
->shortcuts_map();
43 bool changed_notified() const { return changed_notified_
; }
44 void set_changed_notified(bool changed_notified
) {
45 changed_notified_
= changed_notified
;
49 bool AddShortcut(const history::ShortcutsDatabase::Shortcut
& shortcut
);
50 bool UpdateShortcut(const history::ShortcutsDatabase::Shortcut
& shortcut
);
51 bool DeleteShortcutsWithURL(const GURL
& url
);
52 bool DeleteShortcutsWithIDs(
53 const history::ShortcutsDatabase::ShortcutIDs
& deleted_ids
);
57 TestingProfile profile_
;
58 scoped_refptr
<ShortcutsBackend
> backend_
;
59 base::MessageLoopForUI ui_message_loop_
;
60 content::TestBrowserThread ui_thread_
;
61 content::TestBrowserThread db_thread_
;
64 bool changed_notified_
;
66 DISALLOW_COPY_AND_ASSIGN(ShortcutsBackendTest
);
69 ShortcutsBackendTest::ShortcutsBackendTest()
70 : ui_thread_(content::BrowserThread::UI
, &ui_message_loop_
),
71 db_thread_(content::BrowserThread::DB
),
72 load_notified_(false),
73 changed_notified_(false) {
76 history::ShortcutsDatabase::Shortcut::MatchCore
77 ShortcutsBackendTest::MatchCoreForTesting(
78 const std::string
& url
,
79 const std::string
& contents_class
,
80 const std::string
& description_class
,
81 AutocompleteMatch::Type type
) {
82 AutocompleteMatch
match(NULL
, 0, 0, type
);
83 match
.destination_url
= GURL(url
);
84 match
.contents
= base::ASCIIToUTF16("test");
85 match
.contents_class
=
86 AutocompleteMatch::ClassificationsFromString(contents_class
);
87 match
.description_class
=
88 AutocompleteMatch::ClassificationsFromString(description_class
);
89 return ShortcutsBackend::MatchToMatchCore(match
);
92 void ShortcutsBackendTest::SetUp() {
94 ShortcutsBackendFactory::GetInstance()->SetTestingFactoryAndUse(
95 &profile_
, &ShortcutsBackendFactory::BuildProfileForTesting
);
96 backend_
= ShortcutsBackendFactory::GetForProfile(&profile_
);
97 ASSERT_TRUE(backend_
.get());
98 backend_
->AddObserver(this);
101 void ShortcutsBackendTest::TearDown() {
102 backend_
->RemoveObserver(this);
106 void ShortcutsBackendTest::OnShortcutsLoaded() {
107 load_notified_
= true;
108 base::MessageLoop::current()->Quit();
111 void ShortcutsBackendTest::OnShortcutsChanged() {
112 changed_notified_
= true;
115 void ShortcutsBackendTest::InitBackend() {
116 ShortcutsBackend
* backend
=
117 ShortcutsBackendFactory::GetForProfile(&profile_
).get();
118 ASSERT_TRUE(backend
);
119 ASSERT_FALSE(load_notified_
);
120 ASSERT_FALSE(backend_
->initialized());
121 base::MessageLoop::current()->Run();
122 EXPECT_TRUE(load_notified_
);
123 EXPECT_TRUE(backend_
->initialized());
126 bool ShortcutsBackendTest::AddShortcut(
127 const history::ShortcutsDatabase::Shortcut
& shortcut
) {
128 return backend_
->AddShortcut(shortcut
);
131 bool ShortcutsBackendTest::UpdateShortcut(
132 const history::ShortcutsDatabase::Shortcut
& shortcut
) {
133 return backend_
->UpdateShortcut(shortcut
);
136 bool ShortcutsBackendTest::DeleteShortcutsWithURL(const GURL
& url
) {
137 return backend_
->DeleteShortcutsWithURL(url
);
140 bool ShortcutsBackendTest::DeleteShortcutsWithIDs(
141 const history::ShortcutsDatabase::ShortcutIDs
& deleted_ids
) {
142 return backend_
->DeleteShortcutsWithIDs(deleted_ids
);
146 // Actual tests ---------------------------------------------------------------
148 // Verifies that creating MatchCores strips classifications and sanitizes match
150 TEST_F(ShortcutsBackendTest
, SanitizeMatchCore
) {
152 std::string input_contents_class
;
153 std::string input_description_class
;
154 AutocompleteMatch::Type input_type
;
155 std::string output_contents_class
;
156 std::string output_description_class
;
157 AutocompleteMatch::Type output_type
;
159 { "0,1,4,0", "0,3,4,1", AutocompleteMatchType::URL_WHAT_YOU_TYPED
,
160 "0,1,4,0", "0,1", AutocompleteMatchType::HISTORY_URL
},
161 { "0,3,5,1", "0,2,5,0", AutocompleteMatchType::NAVSUGGEST
,
162 "0,1", "0,0", AutocompleteMatchType::HISTORY_URL
},
163 { "0,1", "0,0,11,2,15,0", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
,
164 "0,1", "0,0", AutocompleteMatchType::SEARCH_HISTORY
},
165 { "0,1", "0,0", AutocompleteMatchType::SEARCH_SUGGEST
,
166 "0,1", "0,0", AutocompleteMatchType::SEARCH_HISTORY
},
169 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(cases
); ++i
) {
170 history::ShortcutsDatabase::Shortcut::MatchCore
match_core(
171 MatchCoreForTesting(std::string(), cases
[i
].input_contents_class
,
172 cases
[i
].input_description_class
,
173 cases
[i
].input_type
));
174 EXPECT_EQ(cases
[i
].output_contents_class
, match_core
.contents_class
);
175 EXPECT_EQ(cases
[i
].output_description_class
, match_core
.description_class
);
176 EXPECT_EQ(cases
[i
].output_type
, match_core
.type
);
180 TEST_F(ShortcutsBackendTest
, AddAndUpdateShortcut
) {
182 EXPECT_FALSE(changed_notified());
184 history::ShortcutsDatabase::Shortcut
shortcut(
185 "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", base::ASCIIToUTF16("goog"),
186 MatchCoreForTesting("http://www.google.com"), base::Time::Now(), 100);
187 EXPECT_TRUE(AddShortcut(shortcut
));
188 EXPECT_TRUE(changed_notified());
189 ShortcutsBackend::ShortcutMap::const_iterator
shortcut_iter(
190 shortcuts_map().find(shortcut
.text
));
191 ASSERT_TRUE(shortcut_iter
!= shortcuts_map().end());
192 EXPECT_EQ(shortcut
.id
, shortcut_iter
->second
.id
);
193 EXPECT_EQ(shortcut
.match_core
.contents
,
194 shortcut_iter
->second
.match_core
.contents
);
196 set_changed_notified(false);
197 shortcut
.match_core
.contents
= base::ASCIIToUTF16("Google Web Search");
198 EXPECT_TRUE(UpdateShortcut(shortcut
));
199 EXPECT_TRUE(changed_notified());
200 shortcut_iter
= shortcuts_map().find(shortcut
.text
);
201 ASSERT_TRUE(shortcut_iter
!= shortcuts_map().end());
202 EXPECT_EQ(shortcut
.id
, shortcut_iter
->second
.id
);
203 EXPECT_EQ(shortcut
.match_core
.contents
,
204 shortcut_iter
->second
.match_core
.contents
);
207 TEST_F(ShortcutsBackendTest
, DeleteShortcuts
) {
209 history::ShortcutsDatabase::Shortcut
shortcut1(
210 "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", base::ASCIIToUTF16("goog"),
211 MatchCoreForTesting("http://www.google.com"), base::Time::Now(), 100);
212 EXPECT_TRUE(AddShortcut(shortcut1
));
214 history::ShortcutsDatabase::Shortcut
shortcut2(
215 "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", base::ASCIIToUTF16("gle"),
216 MatchCoreForTesting("http://www.google.com"), base::Time::Now(), 100);
217 EXPECT_TRUE(AddShortcut(shortcut2
));
219 history::ShortcutsDatabase::Shortcut
shortcut3(
220 "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", base::ASCIIToUTF16("sp"),
221 MatchCoreForTesting("http://www.sport.com"), base::Time::Now(), 10);
222 EXPECT_TRUE(AddShortcut(shortcut3
));
224 history::ShortcutsDatabase::Shortcut
shortcut4(
225 "BD85DBA2-8C29-49F9-84AE-48E1E90880E2", base::ASCIIToUTF16("mov"),
226 MatchCoreForTesting("http://www.film.com"), base::Time::Now(), 10);
227 EXPECT_TRUE(AddShortcut(shortcut4
));
229 ASSERT_EQ(4U, shortcuts_map().size());
230 EXPECT_EQ(shortcut1
.id
, shortcuts_map().find(shortcut1
.text
)->second
.id
);
231 EXPECT_EQ(shortcut2
.id
, shortcuts_map().find(shortcut2
.text
)->second
.id
);
232 EXPECT_EQ(shortcut3
.id
, shortcuts_map().find(shortcut3
.text
)->second
.id
);
233 EXPECT_EQ(shortcut4
.id
, shortcuts_map().find(shortcut4
.text
)->second
.id
);
235 EXPECT_TRUE(DeleteShortcutsWithURL(shortcut1
.match_core
.destination_url
));
237 ASSERT_EQ(2U, shortcuts_map().size());
238 EXPECT_EQ(0U, shortcuts_map().count(shortcut1
.text
));
239 EXPECT_EQ(0U, shortcuts_map().count(shortcut2
.text
));
240 const ShortcutsBackend::ShortcutMap::const_iterator
shortcut3_iter(
241 shortcuts_map().find(shortcut3
.text
));
242 ASSERT_TRUE(shortcut3_iter
!= shortcuts_map().end());
243 EXPECT_EQ(shortcut3
.id
, shortcut3_iter
->second
.id
);
244 const ShortcutsBackend::ShortcutMap::const_iterator
shortcut4_iter(
245 shortcuts_map().find(shortcut4
.text
));
246 ASSERT_TRUE(shortcut4_iter
!= shortcuts_map().end());
247 EXPECT_EQ(shortcut4
.id
, shortcut4_iter
->second
.id
);
249 history::ShortcutsDatabase::ShortcutIDs deleted_ids
;
250 deleted_ids
.push_back(shortcut3
.id
);
251 deleted_ids
.push_back(shortcut4
.id
);
252 EXPECT_TRUE(DeleteShortcutsWithIDs(deleted_ids
));
254 ASSERT_EQ(0U, shortcuts_map().size());