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.
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/path_service.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/search_engines/template_url.h"
15 #include "chrome/browser/webdata/keyword_table.h"
16 #include "components/webdata/common/web_database.h"
17 #include "sql/statement.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using base::ASCIIToUTF16
;
22 using base::TimeDelta
;
24 class KeywordTableTest
: public testing::Test
{
27 virtual ~KeywordTableTest() {}
30 virtual void SetUp() {
31 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
32 file_
= temp_dir_
.path().AppendASCII("TestWebDatabase");
34 table_
.reset(new KeywordTable
);
35 db_
.reset(new WebDatabase
);
36 db_
->AddTable(table_
.get());
37 ASSERT_EQ(sql::INIT_OK
, db_
->Init(file_
));
41 base::ScopedTempDir temp_dir_
;
42 scoped_ptr
<KeywordTable
> table_
;
43 scoped_ptr
<WebDatabase
> db_
;
46 DISALLOW_COPY_AND_ASSIGN(KeywordTableTest
);
50 TEST_F(KeywordTableTest
, Keywords
) {
51 TemplateURLData keyword
;
52 keyword
.short_name
= ASCIIToUTF16("short_name");
53 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
54 keyword
.SetURL("http://url/");
55 keyword
.instant_url
= "http://instant/";
56 keyword
.favicon_url
= GURL("http://favicon.url/");
57 keyword
.originating_url
= GURL("http://google.com/");
58 keyword
.show_in_default_list
= true;
59 keyword
.safe_for_autoreplace
= true;
60 keyword
.input_encodings
.push_back("UTF-8");
61 keyword
.input_encodings
.push_back("UTF-16");
63 keyword
.date_created
= Time::Now();
64 keyword
.last_modified
= keyword
.date_created
+ TimeDelta::FromSeconds(10);
65 keyword
.created_by_policy
= true;
66 keyword
.usage_count
= 32;
67 keyword
.prepopulate_id
= 10;
68 EXPECT_TRUE(table_
->AddKeyword(keyword
));
70 KeywordTable::Keywords keywords
;
71 EXPECT_TRUE(table_
->GetKeywords(&keywords
));
72 EXPECT_EQ(1U, keywords
.size());
73 const TemplateURLData
& restored_keyword
= keywords
.front();
75 EXPECT_EQ(keyword
.short_name
, restored_keyword
.short_name
);
76 EXPECT_EQ(keyword
.keyword(), restored_keyword
.keyword());
77 EXPECT_EQ(keyword
.url(), restored_keyword
.url());
78 EXPECT_EQ(keyword
.suggestions_url
, restored_keyword
.suggestions_url
);
79 EXPECT_EQ(keyword
.instant_url
, restored_keyword
.instant_url
);
80 EXPECT_EQ(keyword
.favicon_url
, restored_keyword
.favicon_url
);
81 EXPECT_EQ(keyword
.originating_url
, restored_keyword
.originating_url
);
82 EXPECT_EQ(keyword
.show_in_default_list
,
83 restored_keyword
.show_in_default_list
);
84 EXPECT_EQ(keyword
.safe_for_autoreplace
,
85 restored_keyword
.safe_for_autoreplace
);
86 EXPECT_EQ(keyword
.input_encodings
, restored_keyword
.input_encodings
);
87 EXPECT_EQ(keyword
.id
, restored_keyword
.id
);
88 // The database stores time only at the resolution of a second.
89 EXPECT_EQ(keyword
.date_created
.ToTimeT(),
90 restored_keyword
.date_created
.ToTimeT());
91 EXPECT_EQ(keyword
.last_modified
.ToTimeT(),
92 restored_keyword
.last_modified
.ToTimeT());
93 EXPECT_EQ(keyword
.created_by_policy
, restored_keyword
.created_by_policy
);
94 EXPECT_EQ(keyword
.usage_count
, restored_keyword
.usage_count
);
95 EXPECT_EQ(keyword
.prepopulate_id
, restored_keyword
.prepopulate_id
);
97 EXPECT_TRUE(table_
->RemoveKeyword(restored_keyword
.id
));
99 KeywordTable::Keywords empty_keywords
;
100 EXPECT_TRUE(table_
->GetKeywords(&empty_keywords
));
101 EXPECT_EQ(0U, empty_keywords
.size());
104 TEST_F(KeywordTableTest
, KeywordMisc
) {
105 EXPECT_EQ(kInvalidTemplateURLID
, table_
->GetDefaultSearchProviderID());
106 EXPECT_EQ(0, table_
->GetBuiltinKeywordVersion());
108 TemplateURLData keyword
;
109 keyword
.short_name
= ASCIIToUTF16("short_name");
110 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
111 keyword
.SetURL("http://url/");
112 keyword
.instant_url
= "http://instant/";
113 keyword
.favicon_url
= GURL("http://favicon.url/");
114 keyword
.originating_url
= GURL("http://google.com/");
115 keyword
.show_in_default_list
= true;
116 keyword
.safe_for_autoreplace
= true;
117 keyword
.input_encodings
.push_back("UTF-8");
118 keyword
.input_encodings
.push_back("UTF-16");
120 keyword
.date_created
= Time::Now();
121 keyword
.last_modified
= keyword
.date_created
+ TimeDelta::FromSeconds(10);
122 keyword
.created_by_policy
= true;
123 keyword
.usage_count
= 32;
124 keyword
.prepopulate_id
= 10;
125 EXPECT_TRUE(table_
->AddKeyword(keyword
));
127 EXPECT_TRUE(table_
->SetDefaultSearchProviderID(10));
128 EXPECT_TRUE(table_
->SetBuiltinKeywordVersion(11));
130 EXPECT_EQ(10, table_
->GetDefaultSearchProviderID());
131 EXPECT_EQ(11, table_
->GetBuiltinKeywordVersion());
134 TEST_F(KeywordTableTest
, GetTableContents
) {
135 TemplateURLData keyword
;
136 keyword
.short_name
= ASCIIToUTF16("short_name");
137 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
138 keyword
.SetURL("http://url/");
139 keyword
.suggestions_url
= "url2";
140 keyword
.image_url
= "http://image-search-url/";
141 keyword
.new_tab_url
= "http://new-tab-url/";
142 keyword
.favicon_url
= GURL("http://favicon.url/");
143 keyword
.show_in_default_list
= true;
144 keyword
.safe_for_autoreplace
= true;
146 keyword
.date_created
= base::Time::UnixEpoch();
147 keyword
.last_modified
= base::Time::UnixEpoch();
148 keyword
.sync_guid
= "1234-5678-90AB-CDEF";
149 keyword
.alternate_urls
.push_back("a_url1");
150 keyword
.alternate_urls
.push_back("a_url2");
151 keyword
.search_terms_replacement_key
= "espv";
152 EXPECT_TRUE(table_
->AddKeyword(keyword
));
154 keyword
.SetKeyword(ASCIIToUTF16("url"));
155 keyword
.instant_url
= "http://instant2/";
156 keyword
.image_url
.clear();
157 keyword
.new_tab_url
.clear();
158 keyword
.originating_url
= GURL("http://originating.url/");
159 keyword
.input_encodings
.push_back("Shift_JIS");
161 keyword
.prepopulate_id
= 5;
162 keyword
.sync_guid
= "FEDC-BA09-8765-4321";
163 keyword
.alternate_urls
.clear();
164 keyword
.search_terms_replacement_key
.clear();
165 EXPECT_TRUE(table_
->AddKeyword(keyword
));
167 const char kTestContents
[] = "1short_namekeywordhttp://favicon.url/"
168 "http://url/1001url20001234-5678-90AB-CDEF[\"a_url1\",\"a_url2\"]espv"
169 "http://image-search-url/http://new-tab-url/2short_nameurl"
170 "http://favicon.url/http://url/1http://originating.url/00Shift_JIS1url250"
171 "http://instant2/0FEDC-BA09-8765-4321[]";
173 std::string contents
;
174 EXPECT_TRUE(table_
->GetTableContents("keywords",
175 WebDatabase::kCurrentVersionNumber
, &contents
));
176 EXPECT_EQ(kTestContents
, contents
);
179 TEST_F(KeywordTableTest
, GetTableContentsOrdering
) {
180 TemplateURLData keyword
;
181 keyword
.short_name
= ASCIIToUTF16("short_name");
182 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
183 keyword
.SetURL("http://url/");
184 keyword
.suggestions_url
= "url2";
185 keyword
.favicon_url
= GURL("http://favicon.url/");
186 keyword
.show_in_default_list
= true;
187 keyword
.safe_for_autoreplace
= true;
189 keyword
.date_created
= base::Time::UnixEpoch();
190 keyword
.last_modified
= base::Time::UnixEpoch();
191 keyword
.sync_guid
= "1234-5678-90AB-CDEF";
192 keyword
.alternate_urls
.push_back("a_url1");
193 keyword
.alternate_urls
.push_back("a_url2");
194 keyword
.search_terms_replacement_key
= "espv";
195 keyword
.image_url
= "http://image-search-url/";
196 keyword
.search_url_post_params
= "ie=utf-8,oe=utf-8";
197 keyword
.image_url_post_params
= "name=1,value=2";
198 keyword
.new_tab_url
= "http://new-tab-url";
199 EXPECT_TRUE(table_
->AddKeyword(keyword
));
201 keyword
.SetKeyword(ASCIIToUTF16("url"));
202 keyword
.instant_url
= "http://instant2/";
203 keyword
.originating_url
= GURL("http://originating.url/");
204 keyword
.input_encodings
.push_back("Shift_JIS");
206 keyword
.prepopulate_id
= 5;
207 keyword
.sync_guid
= "FEDC-BA09-8765-4321";
208 keyword
.alternate_urls
.clear();
209 keyword
.search_terms_replacement_key
.clear();
210 keyword
.image_url
.clear();
211 keyword
.search_url_post_params
.clear();
212 keyword
.image_url_post_params
.clear();
213 keyword
.new_tab_url
.clear();
214 EXPECT_TRUE(table_
->AddKeyword(keyword
));
216 const char kTestContents
[] = "1short_nameurlhttp://favicon.url/"
217 "http://url/1http://originating.url/00Shift_JIS1url250http://instant2/"
218 "0FEDC-BA09-8765-4321[]2short_namekeywordhttp://favicon.url/http://url/"
219 "1001url20001234-5678-90AB-CDEF[\"a_url1\",\"a_url2\"]espv"
220 "http://image-search-url/ie=utf-8,oe=utf-8name=1,value=2"
221 "http://new-tab-url";
223 std::string contents
;
224 EXPECT_TRUE(table_
->GetTableContents("keywords",
225 WebDatabase::kCurrentVersionNumber
, &contents
));
226 EXPECT_EQ(kTestContents
, contents
);
229 TEST_F(KeywordTableTest
, UpdateKeyword
) {
230 TemplateURLData keyword
;
231 keyword
.short_name
= ASCIIToUTF16("short_name");
232 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
233 keyword
.SetURL("http://url/");
234 keyword
.suggestions_url
= "url2";
235 keyword
.favicon_url
= GURL("http://favicon.url/");
236 keyword
.show_in_default_list
= true;
237 keyword
.safe_for_autoreplace
= true;
239 EXPECT_TRUE(table_
->AddKeyword(keyword
));
241 keyword
.SetKeyword(ASCIIToUTF16("url"));
242 keyword
.instant_url
= "http://instant2/";
243 keyword
.originating_url
= GURL("http://originating.url/");
244 keyword
.input_encodings
.push_back("Shift_JIS");
245 keyword
.prepopulate_id
= 5;
246 EXPECT_TRUE(table_
->UpdateKeyword(keyword
));
248 KeywordTable::Keywords keywords
;
249 EXPECT_TRUE(table_
->GetKeywords(&keywords
));
250 EXPECT_EQ(1U, keywords
.size());
251 const TemplateURLData
& restored_keyword
= keywords
.front();
253 EXPECT_EQ(keyword
.short_name
, restored_keyword
.short_name
);
254 EXPECT_EQ(keyword
.keyword(), restored_keyword
.keyword());
255 EXPECT_EQ(keyword
.suggestions_url
, restored_keyword
.suggestions_url
);
256 EXPECT_EQ(keyword
.instant_url
, restored_keyword
.instant_url
);
257 EXPECT_EQ(keyword
.favicon_url
, restored_keyword
.favicon_url
);
258 EXPECT_EQ(keyword
.originating_url
, restored_keyword
.originating_url
);
259 EXPECT_EQ(keyword
.show_in_default_list
,
260 restored_keyword
.show_in_default_list
);
261 EXPECT_EQ(keyword
.safe_for_autoreplace
,
262 restored_keyword
.safe_for_autoreplace
);
263 EXPECT_EQ(keyword
.input_encodings
, restored_keyword
.input_encodings
);
264 EXPECT_EQ(keyword
.id
, restored_keyword
.id
);
265 EXPECT_EQ(keyword
.prepopulate_id
, restored_keyword
.prepopulate_id
);
268 TEST_F(KeywordTableTest
, KeywordWithNoFavicon
) {
269 TemplateURLData keyword
;
270 keyword
.short_name
= ASCIIToUTF16("short_name");
271 keyword
.SetKeyword(ASCIIToUTF16("keyword"));
272 keyword
.SetURL("http://url/");
273 keyword
.safe_for_autoreplace
= true;
275 EXPECT_TRUE(table_
->AddKeyword(keyword
));
277 KeywordTable::Keywords keywords
;
278 EXPECT_TRUE(table_
->GetKeywords(&keywords
));
279 EXPECT_EQ(1U, keywords
.size());
280 const TemplateURLData
& restored_keyword
= keywords
.front();
282 EXPECT_EQ(keyword
.short_name
, restored_keyword
.short_name
);
283 EXPECT_EQ(keyword
.keyword(), restored_keyword
.keyword());
284 EXPECT_EQ(keyword
.favicon_url
, restored_keyword
.favicon_url
);
285 EXPECT_EQ(keyword
.safe_for_autoreplace
,
286 restored_keyword
.safe_for_autoreplace
);
287 EXPECT_EQ(keyword
.id
, restored_keyword
.id
);
290 TEST_F(KeywordTableTest
, SanitizeURLs
) {
291 TemplateURLData keyword
;
292 keyword
.short_name
= ASCIIToUTF16("legit");
293 keyword
.SetKeyword(ASCIIToUTF16("legit"));
294 keyword
.SetURL("http://url/");
296 EXPECT_TRUE(table_
->AddKeyword(keyword
));
298 keyword
.short_name
= ASCIIToUTF16("bogus");
299 keyword
.SetKeyword(ASCIIToUTF16("bogus"));
301 EXPECT_TRUE(table_
->AddKeyword(keyword
));
303 KeywordTable::Keywords keywords
;
304 EXPECT_TRUE(table_
->GetKeywords(&keywords
));
305 EXPECT_EQ(2U, keywords
.size());
308 // Erase the URL field for the second keyword to simulate having bogus data
309 // previously saved into the database.
310 sql::Statement
s(table_
->db_
->GetUniqueStatement(
311 "UPDATE keywords SET url=? WHERE id=?"));
312 s
.BindString16(0, base::string16());
313 s
.BindInt64(1, 2000);
314 EXPECT_TRUE(s
.Run());
316 // GetKeywords() should erase the entry with the empty URL field.
317 EXPECT_TRUE(table_
->GetKeywords(&keywords
));
318 EXPECT_EQ(1U, keywords
.size());