shortcuts_backend_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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/shortcuts_backend.h"
6
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"
17
18#include "testing/gtest/include/gtest/gtest.h"
19
20
21// ShortcutsBackendTest -------------------------------------------------------
22
23class ShortcutsBackendTest : public testing::Test,
24                             public ShortcutsBackend::ShortcutsBackendObserver {
25 public:
26  ShortcutsBackendTest();
27
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);
33
34  virtual void SetUp();
35  virtual void TearDown();
36
37  virtual void OnShortcutsLoaded() OVERRIDE;
38  virtual void OnShortcutsChanged() OVERRIDE;
39
40  const ShortcutsBackend::ShortcutMap& shortcuts_map() const {
41    return backend_->shortcuts_map();
42  }
43  bool changed_notified() const { return changed_notified_; }
44  void set_changed_notified(bool changed_notified) {
45      changed_notified_ = changed_notified;
46  }
47
48  void InitBackend();
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);
54
55
56 private:
57  TestingProfile profile_;
58  scoped_refptr<ShortcutsBackend> backend_;
59  base::MessageLoopForUI ui_message_loop_;
60  content::TestBrowserThread ui_thread_;
61  content::TestBrowserThread db_thread_;
62
63  bool load_notified_;
64  bool changed_notified_;
65
66  DISALLOW_COPY_AND_ASSIGN(ShortcutsBackendTest);
67};
68
69ShortcutsBackendTest::ShortcutsBackendTest()
70    : ui_thread_(content::BrowserThread::UI, &ui_message_loop_),
71      db_thread_(content::BrowserThread::DB),
72      load_notified_(false),
73      changed_notified_(false) {
74}
75
76history::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);
90}
91
92void ShortcutsBackendTest::SetUp() {
93  db_thread_.Start();
94  ShortcutsBackendFactory::GetInstance()->SetTestingFactoryAndUse(
95      &profile_, &ShortcutsBackendFactory::BuildProfileForTesting);
96  backend_ = ShortcutsBackendFactory::GetForProfile(&profile_);
97  ASSERT_TRUE(backend_.get());
98  backend_->AddObserver(this);
99}
100
101void ShortcutsBackendTest::TearDown() {
102  backend_->RemoveObserver(this);
103  db_thread_.Stop();
104}
105
106void ShortcutsBackendTest::OnShortcutsLoaded() {
107  load_notified_ = true;
108  base::MessageLoop::current()->Quit();
109}
110
111void ShortcutsBackendTest::OnShortcutsChanged() {
112  changed_notified_ = true;
113}
114
115void 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());
124}
125
126bool ShortcutsBackendTest::AddShortcut(
127    const history::ShortcutsDatabase::Shortcut& shortcut) {
128  return backend_->AddShortcut(shortcut);
129}
130
131bool ShortcutsBackendTest::UpdateShortcut(
132    const history::ShortcutsDatabase::Shortcut& shortcut) {
133  return backend_->UpdateShortcut(shortcut);
134}
135
136bool ShortcutsBackendTest::DeleteShortcutsWithURL(const GURL& url) {
137  return backend_->DeleteShortcutsWithURL(url);
138}
139
140bool ShortcutsBackendTest::DeleteShortcutsWithIDs(
141    const history::ShortcutsDatabase::ShortcutIDs& deleted_ids) {
142  return backend_->DeleteShortcutsWithIDs(deleted_ids);
143}
144
145
146// Actual tests ---------------------------------------------------------------
147
148// Verifies that creating MatchCores strips classifications and sanitizes match
149// types.
150TEST_F(ShortcutsBackendTest, SanitizeMatchCore) {
151  struct {
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;
158  } cases[] = {
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 },
167  };
168
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);
177  }
178}
179
180TEST_F(ShortcutsBackendTest, AddAndUpdateShortcut) {
181  InitBackend();
182  EXPECT_FALSE(changed_notified());
183
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);
195
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);
205}
206
207TEST_F(ShortcutsBackendTest, DeleteShortcuts) {
208  InitBackend();
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));
213
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));
218
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));
223
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));
228
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);
234
235  EXPECT_TRUE(DeleteShortcutsWithURL(shortcut1.match_core.destination_url));
236
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);
248
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));
253
254  ASSERT_EQ(0U, shortcuts_map().size());
255}
256