1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "components/search_engines/keyword_table.h"
14 #include "components/search_engines/template_url_data.h"
15 #include "components/webdata/common/web_database.h"
16 #include "sql/statement.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using base::ASCIIToUTF16;
22 class KeywordTableTest : public testing::Test {
26 KeywordTableTest(const KeywordTableTest&) = delete;
27 KeywordTableTest& operator=(const KeywordTableTest&) = delete;
29 ~KeywordTableTest() override {}
32 void SetUp() override {
33 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
34 file_ = temp_dir_.GetPath().AppendASCII("TestWebDatabase");
36 table_ = std::make_unique<KeywordTable>();
37 db_ = std::make_unique<WebDatabase>();
38 db_->AddTable(table_.get());
39 ASSERT_EQ(sql::INIT_OK, db_->Init(file_));
42 void AddKeyword(const TemplateURLData& keyword) const {
43 EXPECT_TRUE(table_->AddKeyword(keyword));
46 TemplateURLData CreateAndAddKeyword() const {
47 TemplateURLData keyword;
48 keyword.SetShortName(u"short_name");
49 keyword.SetKeyword(u"keyword");
50 keyword.SetURL("http://url/");
51 keyword.suggestions_url = "url2";
52 keyword.image_url = "http://image-search-url/";
53 keyword.new_tab_url = "http://new-tab-url/";
54 keyword.search_url_post_params = "ie=utf-8,oe=utf-8";
55 keyword.image_url_post_params = "name=1,value=2";
56 keyword.favicon_url = GURL("http://favicon.url/");
57 keyword.originating_url = GURL("http://google.com/");
58 keyword.safe_for_autoreplace = true;
59 keyword.input_encodings.push_back("UTF-8");
60 keyword.input_encodings.push_back("UTF-16");
62 keyword.date_created = base::Time::UnixEpoch();
63 keyword.last_modified = base::Time::UnixEpoch();
64 keyword.last_visited = base::Time::UnixEpoch();
65 keyword.created_by_policy = true;
66 keyword.usage_count = 32;
67 keyword.prepopulate_id = 10;
68 keyword.sync_guid = "1234-5678-90AB-CDEF";
69 keyword.alternate_urls.push_back("a_url1");
70 keyword.alternate_urls.push_back("a_url2");
71 keyword.starter_pack_id = 1;
72 keyword.enforced_by_policy = true;
77 void RemoveKeyword(TemplateURLID id) const {
78 EXPECT_TRUE(table_->RemoveKeyword(id));
81 void UpdateKeyword(const TemplateURLData& keyword) const {
82 EXPECT_TRUE(table_->UpdateKeyword(keyword));
85 KeywordTable::Keywords GetKeywords() const {
86 KeywordTable::Keywords keywords;
87 EXPECT_TRUE(table_->GetKeywords(&keywords));
91 void KeywordMiscTest() const {
92 EXPECT_EQ(kInvalidTemplateURLID, table_->GetDefaultSearchProviderID());
93 EXPECT_EQ(0, table_->GetBuiltinKeywordVersion());
95 EXPECT_TRUE(table_->SetDefaultSearchProviderID(10));
96 EXPECT_TRUE(table_->SetBuiltinKeywordVersion(11));
98 EXPECT_EQ(10, table_->GetDefaultSearchProviderID());
99 EXPECT_EQ(11, table_->GetBuiltinKeywordVersion());
102 void GetStatement(const char* sql, sql::Statement* statement) const {
103 statement->Assign(table_->db_->GetUniqueStatement(sql));
107 base::FilePath file_;
108 base::ScopedTempDir temp_dir_;
109 std::unique_ptr<KeywordTable> table_;
110 std::unique_ptr<WebDatabase> db_;
114 TEST_F(KeywordTableTest, Keywords) {
115 TemplateURLData keyword(CreateAndAddKeyword());
117 KeywordTable::Keywords keywords(GetKeywords());
118 EXPECT_EQ(1U, keywords.size());
119 const TemplateURLData& restored_keyword = keywords.front();
121 EXPECT_EQ(keyword.short_name(), restored_keyword.short_name());
122 EXPECT_EQ(keyword.keyword(), restored_keyword.keyword());
123 EXPECT_EQ(keyword.url(), restored_keyword.url());
124 EXPECT_EQ(keyword.suggestions_url, restored_keyword.suggestions_url);
125 EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url);
126 EXPECT_EQ(keyword.originating_url, restored_keyword.originating_url);
127 EXPECT_EQ(keyword.safe_for_autoreplace,
128 restored_keyword.safe_for_autoreplace);
129 EXPECT_EQ(keyword.input_encodings, restored_keyword.input_encodings);
130 EXPECT_EQ(keyword.id, restored_keyword.id);
131 // The database stores time only at the resolution of a second.
132 EXPECT_EQ(keyword.date_created.ToTimeT(),
133 restored_keyword.date_created.ToTimeT());
134 EXPECT_EQ(keyword.last_modified.ToTimeT(),
135 restored_keyword.last_modified.ToTimeT());
136 EXPECT_EQ(keyword.last_visited.ToTimeT(),
137 restored_keyword.last_visited.ToTimeT());
138 EXPECT_EQ(keyword.created_by_policy, restored_keyword.created_by_policy);
139 EXPECT_EQ(keyword.created_from_play_api,
140 restored_keyword.created_from_play_api);
141 EXPECT_EQ(keyword.usage_count, restored_keyword.usage_count);
142 EXPECT_EQ(keyword.prepopulate_id, restored_keyword.prepopulate_id);
143 EXPECT_EQ(keyword.is_active, restored_keyword.is_active);
144 EXPECT_EQ(keyword.starter_pack_id, restored_keyword.starter_pack_id);
145 EXPECT_EQ(keyword.enforced_by_policy, restored_keyword.enforced_by_policy);
147 RemoveKeyword(restored_keyword.id);
149 EXPECT_EQ(0U, GetKeywords().size());
152 TEST_F(KeywordTableTest, KeywordMisc) {
156 TEST_F(KeywordTableTest, UpdateKeyword) {
157 TemplateURLData keyword(CreateAndAddKeyword());
159 keyword.SetKeyword(u"url");
160 keyword.originating_url = GURL("http://originating.url/");
161 keyword.input_encodings.push_back("Shift_JIS");
162 keyword.prepopulate_id = 5;
163 keyword.created_from_play_api = true;
164 keyword.starter_pack_id = 0;
165 keyword.enforced_by_policy = false;
166 UpdateKeyword(keyword);
168 KeywordTable::Keywords keywords(GetKeywords());
169 EXPECT_EQ(1U, keywords.size());
170 const TemplateURLData& restored_keyword = keywords.front();
172 EXPECT_EQ(keyword.short_name(), restored_keyword.short_name());
173 EXPECT_EQ(keyword.keyword(), restored_keyword.keyword());
174 EXPECT_EQ(keyword.suggestions_url, restored_keyword.suggestions_url);
175 EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url);
176 EXPECT_EQ(keyword.originating_url, restored_keyword.originating_url);
177 EXPECT_EQ(keyword.safe_for_autoreplace,
178 restored_keyword.safe_for_autoreplace);
179 EXPECT_EQ(keyword.input_encodings, restored_keyword.input_encodings);
180 EXPECT_EQ(keyword.id, restored_keyword.id);
181 EXPECT_EQ(keyword.prepopulate_id, restored_keyword.prepopulate_id);
182 EXPECT_EQ(keyword.created_from_play_api,
183 restored_keyword.created_from_play_api);
184 EXPECT_EQ(keyword.is_active, restored_keyword.is_active);
185 EXPECT_EQ(keyword.starter_pack_id, restored_keyword.starter_pack_id);
186 EXPECT_EQ(keyword.enforced_by_policy, restored_keyword.enforced_by_policy);
189 TEST_F(KeywordTableTest, KeywordWithNoFavicon) {
190 TemplateURLData keyword;
191 keyword.SetShortName(u"short_name");
192 keyword.SetKeyword(u"keyword");
193 keyword.SetURL("http://url/");
194 keyword.safe_for_autoreplace = true;
198 KeywordTable::Keywords keywords(GetKeywords());
199 EXPECT_EQ(1U, keywords.size());
200 const TemplateURLData& restored_keyword = keywords.front();
202 EXPECT_EQ(keyword.short_name(), restored_keyword.short_name());
203 EXPECT_EQ(keyword.keyword(), restored_keyword.keyword());
204 EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url);
205 EXPECT_EQ(keyword.safe_for_autoreplace,
206 restored_keyword.safe_for_autoreplace);
207 EXPECT_EQ(keyword.id, restored_keyword.id);
210 TEST_F(KeywordTableTest, SanitizeURLs) {
211 TemplateURLData keyword;
212 keyword.SetShortName(u"legit");
213 keyword.SetKeyword(u"legit");
214 keyword.SetURL("http://url/");
218 keyword.SetShortName(u"bogus");
219 keyword.SetKeyword(u"bogus");
223 EXPECT_EQ(2U, GetKeywords().size());
225 // Erase the URL field for the second keyword to simulate having bogus data
226 // previously saved into the database.
228 GetStatement("UPDATE keywords SET url=? WHERE id=?", &s);
229 s.BindString16(0, std::u16string());
230 s.BindInt64(1, 2000);
231 EXPECT_TRUE(s.Run());
233 // GetKeywords() should erase the entry with the empty URL field.
234 EXPECT_EQ(1U, GetKeywords().size());
237 TEST_F(KeywordTableTest, SanitizeShortName) {
238 TemplateURLData keyword;
240 keyword.SetShortName(u"legit name");
241 keyword.SetKeyword(u"legit");
242 keyword.SetURL("http://url/");
245 KeywordTable::Keywords keywords(GetKeywords());
246 EXPECT_EQ(1U, keywords.size());
247 const TemplateURLData& keyword_from_database = keywords.front();
248 EXPECT_EQ(keyword.id, keyword_from_database.id);
249 EXPECT_EQ(u"legit name", keyword_from_database.short_name());
250 RemoveKeyword(keyword.id);
254 keyword.SetShortName(u"\t\tbogus \tname \n");
255 keyword.SetKeyword(u"bogus");
258 KeywordTable::Keywords keywords(GetKeywords());
259 EXPECT_EQ(1U, keywords.size());
260 const TemplateURLData& keyword_from_database = keywords.front();
261 EXPECT_EQ(keyword.id, keyword_from_database.id);
262 EXPECT_EQ(u"bogus name", keyword_from_database.short_name());
263 RemoveKeyword(keyword.id);