OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 "testing/gtest/include/gtest/gtest.h" | |
6 | |
7 #include <windows.h> | |
8 #include <unknwn.h> | |
9 #include <intshcut.h> | |
10 #include <pstore.h> | |
11 #include <urlhist.h> | |
12 #include <shlguid.h> | |
13 #include <vector> | |
14 | |
15 #include "base/file_util.h" | |
16 #include "base/path_service.h" | |
17 #include "chrome/browser/ie_importer.h" | |
18 #include "chrome/browser/ie7_password.h" | |
19 #include "chrome/browser/importer.h" | |
20 #include "chrome/browser/profile.h" | |
21 #include "chrome/common/chrome_paths.h" | |
22 #include "chrome/common/env_util.h" | |
23 #include "chrome/common/win_util.h" | |
24 | |
25 class ImporterTest : public testing::Test { | |
26 public: | |
27 protected: | |
28 virtual void SetUp() { | |
29 // Creates a new profile in a new subdirectory in the temp directory. | |
30 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_path_)); | |
31 file_util::AppendToPath(&test_path_, L"ImporterTest"); | |
32 file_util::Delete(test_path_, true); | |
33 CreateDirectory(test_path_.c_str(), NULL); | |
34 profile_path_ = test_path_; | |
35 file_util::AppendToPath(&profile_path_, L"profile"); | |
36 CreateDirectory(profile_path_.c_str(), NULL); | |
37 app_path_ = test_path_; | |
38 file_util::AppendToPath(&app_path_, L"app"); | |
39 CreateDirectory(app_path_.c_str(), NULL); | |
40 } | |
41 | |
42 virtual void TearDown() { | |
43 // Deletes the profile and cleans up the profile directory. | |
44 ASSERT_TRUE(file_util::Delete(test_path_, true)); | |
45 ASSERT_FALSE(file_util::PathExists(test_path_)); | |
46 } | |
47 | |
48 MessageLoopForUI message_loop_; | |
49 std::wstring test_path_; | |
50 std::wstring profile_path_; | |
51 std::wstring app_path_; | |
52 }; | |
53 | |
54 const int kMaxPathSize = 5; | |
55 | |
56 typedef struct { | |
57 const bool in_toolbar; | |
58 const int path_size; | |
59 const wchar_t* path[kMaxPathSize]; | |
60 const wchar_t* title; | |
61 const char* url; | |
62 } BookmarkList; | |
63 | |
64 typedef struct { | |
65 const char* origin; | |
66 const char* action; | |
67 const char* realm; | |
68 const wchar_t* username_element; | |
69 const wchar_t* username; | |
70 const wchar_t* password_element; | |
71 const wchar_t* password; | |
72 bool blacklisted; | |
73 } PasswordList; | |
74 | |
75 static const BookmarkList kIEBookmarks[] = { | |
76 {true, 0, {}, | |
77 L"TheLink", | |
78 "http://www.links-thelink.com/"}, | |
79 {true, 1, {L"SubFolderOfLinks"}, | |
80 L"SubLink", | |
81 "http://www.links-sublink.com/"}, | |
82 {false, 0, {}, | |
83 L"Google Home Page", | |
84 "http://www.google.com/"}, | |
85 {false, 0, {}, | |
86 L"TheLink", | |
87 "http://www.links-thelink.com/"}, | |
88 {false, 1, {L"SubFolder"}, | |
89 L"Title", | |
90 "http://www.link.com/"}, | |
91 {false, 0, {}, | |
92 L"WithPortAndQuery", | |
93 "http://host:8080/cgi?q=query"}, | |
94 {false, 1, {L"a"}, | |
95 L"\x4E2D\x6587", | |
96 "http://chinese-title-favorite/"}, | |
97 }; | |
98 | |
99 static const wchar_t* kIEIdentifyUrl = | |
100 L"http://A79029D6-753E-4e27-B807-3D46AB1545DF.com:8080/path?key=value"; | |
101 static const wchar_t* kIEIdentifyTitle = | |
102 L"Unittest GUID"; | |
103 | |
104 bool IsWindowsVista() { | |
105 OSVERSIONINFO info = {0}; | |
106 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
107 GetVersionEx(&info); | |
108 return (info.dwMajorVersion >=6); | |
109 } | |
110 | |
111 // Returns true if the |entry| is in the |list|. | |
112 bool FindBookmarkEntry(const ProfileWriter::BookmarkEntry& entry, | |
113 const BookmarkList* list, int list_size) { | |
114 for (int i = 0; i < list_size; ++i) | |
115 if (list[i].in_toolbar == entry.in_toolbar && | |
116 list[i].path_size == entry.path.size() && | |
117 list[i].url == entry.url.spec() && | |
118 list[i].title == entry.title) { | |
119 bool equal = true; | |
120 for (int k = 0; k < list[i].path_size; ++k) | |
121 if (list[i].path[k] != entry.path[k]) { | |
122 equal = false; | |
123 break; | |
124 } | |
125 | |
126 if (equal) | |
127 return true; | |
128 } | |
129 return false; | |
130 } | |
131 | |
132 class TestObserver : public ProfileWriter, | |
133 public ImporterHost::Observer { | |
134 public: | |
135 TestObserver() : ProfileWriter(NULL) { | |
136 bookmark_count_ = 0; | |
137 history_count_ = 0; | |
138 password_count_ = 0; | |
139 } | |
140 | |
141 virtual void ImportItemStarted(ImportItem item) {} | |
142 virtual void ImportItemEnded(ImportItem item) {} | |
143 virtual void ImportStarted() {} | |
144 virtual void ImportEnded() { | |
145 MessageLoop::current()->Quit(); | |
146 EXPECT_EQ(arraysize(kIEBookmarks), bookmark_count_); | |
147 EXPECT_EQ(1, history_count_); | |
148 if (IsWindowsVista()) | |
149 EXPECT_EQ(0, password_count_); | |
150 else | |
151 EXPECT_EQ(1, password_count_); | |
152 } | |
153 | |
154 virtual bool BookmarkModelIsLoaded() const { | |
155 // Profile is ready for writing. | |
156 return true; | |
157 } | |
158 | |
159 virtual void AddBookmarkModelObserver(BookmarkModelObserver* observer) { | |
160 NOTREACHED(); | |
161 } | |
162 | |
163 virtual bool TemplateURLModelIsLoaded() const { | |
164 return true; | |
165 } | |
166 | |
167 virtual void AddTemplateURLModelObserver(NotificationObserver* observer) { | |
168 NOTREACHED(); | |
169 } | |
170 | |
171 virtual void AddPasswordForm(const PasswordForm& form) { | |
172 // Importer should obtain this password form only. | |
173 EXPECT_EQ(GURL("http://localhost:8080/security/index.htm"), form.origin); | |
174 EXPECT_EQ("http://localhost:8080/", form.signon_realm); | |
175 EXPECT_EQ(L"user", form.username_element); | |
176 EXPECT_EQ(L"1", form.username_value); | |
177 EXPECT_EQ(L"", form.password_element); | |
178 EXPECT_EQ(L"2", form.password_value); | |
179 EXPECT_EQ("", form.action.spec()); | |
180 ++password_count_; | |
181 } | |
182 | |
183 virtual void AddHistoryPage(const std::vector<history::URLRow>& page) { | |
184 // Importer should read the specified URL. | |
185 for (size_t i = 0; i < page.size(); ++i) | |
186 if (page[i].title() == kIEIdentifyTitle && | |
187 page[i].url() == GURL(kIEIdentifyUrl)) | |
188 ++history_count_; | |
189 } | |
190 | |
191 virtual void AddBookmarkEntry(const std::vector<BookmarkEntry>& bookmark) { | |
192 // Importer should import the IE Favorites folder the same as the list. | |
193 for (size_t i = 0; i < bookmark.size(); ++i) { | |
194 if (FindBookmarkEntry(bookmark[i], kIEBookmarks, | |
195 arraysize(kIEBookmarks))) | |
196 ++bookmark_count_; | |
197 } | |
198 } | |
199 | |
200 virtual void AddKeyword(std::vector<TemplateURL*> template_url, | |
201 int default_keyword_index) { | |
202 // TODO(jcampan): bug 1169230: we should test keyword importing for IE. | |
203 // In order to do that we'll probably need to mock the Windows registry. | |
204 NOTREACHED(); | |
205 STLDeleteContainerPointers(template_url.begin(), template_url.end()); | |
206 } | |
207 | |
208 private: | |
209 int bookmark_count_; | |
210 int history_count_; | |
211 int password_count_; | |
212 }; | |
213 | |
214 bool CreateUrlFile(std::wstring file, std::wstring url) { | |
215 CComPtr<IUniformResourceLocator> locator; | |
216 HRESULT result = locator.CoCreateInstance(CLSID_InternetShortcut, NULL, | |
217 CLSCTX_INPROC_SERVER); | |
218 if (FAILED(result)) | |
219 return false; | |
220 CComPtr<IPersistFile> persist_file; | |
221 result = locator->QueryInterface(IID_IPersistFile, | |
222 reinterpret_cast<void**>(&persist_file)); | |
223 if (FAILED(result)) | |
224 return false; | |
225 result = locator->SetURL(url.c_str(), 0); | |
226 if (FAILED(result)) | |
227 return false; | |
228 result = persist_file->Save(file.c_str(), TRUE); | |
229 if (FAILED(result)) | |
230 return false; | |
231 return true; | |
232 } | |
233 | |
234 void ClearPStoreType(IPStore* pstore, const GUID* type, const GUID* subtype) { | |
235 CComPtr<IEnumPStoreItems> item; | |
236 HRESULT result = pstore->EnumItems(0, type, subtype, 0, &item); | |
237 if (result == PST_E_OK) { | |
238 wchar_t* item_name; | |
239 while (SUCCEEDED(item->Next(1, &item_name, 0))) { | |
240 pstore->DeleteItem(0, type, subtype, item_name, NULL, 0); | |
241 CoTaskMemFree(item_name); | |
242 } | |
243 } | |
244 pstore->DeleteSubtype(0, type, subtype, 0); | |
245 pstore->DeleteType(0, type, 0); | |
246 } | |
247 | |
248 void WritePStore(IPStore* pstore, const GUID* type, const GUID* subtype) { | |
249 struct PStoreItem { | |
250 wchar_t* name; | |
251 int data_size; | |
252 char* data; | |
253 } items[] = { | |
254 {L"http://localhost:8080/security/index.htm#ref:StringData", 8, | |
255 "\x31\x00\x00\x00\x32\x00\x00\x00"}, | |
256 {L"http://localhost:8080/security/index.htm#ref:StringIndex", 20, | |
257 "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00" | |
258 "\x00\x00\x2f\x00\x74\x00\x01\x00\x00\x00"}, | |
259 {L"user:StringData", 4, | |
260 "\x31\x00\x00\x00"}, | |
261 {L"user:StringIndex", 20, | |
262 "\x57\x49\x43\x4b\x18\x00\x00\x00\x01\x00" | |
263 "\x00\x00\x2f\x00\x74\x00\x00\x00\x00\x00"}, | |
264 }; | |
265 | |
266 for (int i = 0; i < arraysize(items); ++i) { | |
267 HRESULT res = pstore->WriteItem(0, type, subtype, items[i].name, | |
268 items[i].data_size, reinterpret_cast<BYTE*>(items[i].data), | |
269 NULL, 0, 0); | |
270 ASSERT_TRUE(res == PST_E_OK); | |
271 } | |
272 } | |
273 | |
274 TEST_F(ImporterTest, IEImporter) { | |
275 // Skips in Win2000 for the running environment can not be set up. | |
276 if (env_util::GetOperatingSystemVersion() == "5.0") | |
277 return; | |
278 | |
279 // Sets up a favorites folder. | |
280 win_util::ScopedCOMInitializer com_init; | |
281 std::wstring path = test_path_; | |
282 file_util::AppendToPath(&path, L"Favorites"); | |
283 CreateDirectory(path.c_str(), NULL); | |
284 CreateDirectory((path + L"\\SubFolder").c_str(), NULL); | |
285 CreateDirectory((path + L"\\Links").c_str(), NULL); | |
286 CreateDirectory((path + L"\\Links\\SubFolderOfLinks").c_str(), NULL); | |
287 CreateDirectory((path + L"\\\x0061").c_str(), NULL); | |
288 ASSERT_TRUE(CreateUrlFile(path + L"\\Google Home Page.url", | |
289 L"http://www.google.com/")); | |
290 ASSERT_TRUE(CreateUrlFile(path + L"\\SubFolder\\Title.url", | |
291 L"http://www.link.com/")); | |
292 ASSERT_TRUE(CreateUrlFile(path + L"\\TheLink.url", | |
293 L"http://www.links-thelink.com/")); | |
294 ASSERT_TRUE(CreateUrlFile(path + L"\\WithPortAndQuery.url", | |
295 L"http://host:8080/cgi?q=query")); | |
296 ASSERT_TRUE(CreateUrlFile(path + L"\\\x0061\\\x4E2D\x6587.url", | |
297 L"http://chinese-title-favorite/")); | |
298 ASSERT_TRUE(CreateUrlFile(path + L"\\Links\\TheLink.url", | |
299 L"http://www.links-thelink.com/")); | |
300 ASSERT_TRUE(CreateUrlFile(path + L"\\Links\\SubFolderOfLinks\\SubLink.url", | |
301 L"http://www.links-sublink.com/")); | |
302 file_util::WriteFile(path + L"\\InvalidUrlFile.url", "x", 1); | |
303 file_util::WriteFile(path + L"\\PlainTextFile.txt", "x", 1); | |
304 | |
305 // Sets up dummy password data. | |
306 HRESULT res; | |
307 CComPtr<IPStore> pstore; | |
308 HMODULE pstorec_dll; | |
309 GUID type = IEImporter::kUnittestGUID; | |
310 GUID subtype = IEImporter::kUnittestGUID; | |
311 // PStore is read-only in Windows Vista. | |
312 if (!IsWindowsVista()) { | |
313 typedef HRESULT (WINAPI *PStoreCreateFunc)(IPStore**, DWORD, DWORD, DWORD); | |
314 pstorec_dll = LoadLibrary(L"pstorec.dll"); | |
315 PStoreCreateFunc PStoreCreateInstance = | |
316 (PStoreCreateFunc)GetProcAddress(pstorec_dll, "PStoreCreateInstance"); | |
317 res = PStoreCreateInstance(&pstore, 0, 0, 0); | |
318 ASSERT_TRUE(res == S_OK); | |
319 ClearPStoreType(pstore, &type, &subtype); | |
320 PST_TYPEINFO type_info; | |
321 type_info.szDisplayName = L"TestType"; | |
322 type_info.cbSize = 8; | |
323 pstore->CreateType(0, &type, &type_info, 0); | |
324 pstore->CreateSubtype(0, &type, &subtype, &type_info, NULL, 0); | |
325 WritePStore(pstore, &type, &subtype); | |
326 } | |
327 | |
328 // Sets up a special history link. | |
329 CComPtr<IUrlHistoryStg2> url_history_stg2; | |
330 res = url_history_stg2.CoCreateInstance(CLSID_CUrlHistory, NULL, | |
331 CLSCTX_INPROC_SERVER); | |
332 ASSERT_TRUE(res == S_OK); | |
333 res = url_history_stg2->AddUrl(kIEIdentifyUrl, kIEIdentifyTitle, 0); | |
334 ASSERT_TRUE(res == S_OK); | |
335 | |
336 // Starts to import the above settings. | |
337 MessageLoop* loop = MessageLoop::current(); | |
338 scoped_refptr<ImporterHost> host = new ImporterHost(loop); | |
339 | |
340 TestObserver* observer = new TestObserver(); | |
341 host->SetObserver(observer); | |
342 ProfileInfo profile_info; | |
343 profile_info.browser_type = MS_IE; | |
344 profile_info.source_path = test_path_; | |
345 | |
346 loop->PostTask(FROM_HERE, NewRunnableMethod(host.get(), | |
347 &ImporterHost::StartImportSettings, profile_info, | |
348 HISTORY | PASSWORDS | FAVORITES, observer, true)); | |
349 loop->Run(); | |
350 | |
351 // Cleans up. | |
352 url_history_stg2->DeleteUrl(kIEIdentifyUrl, 0); | |
353 url_history_stg2.Release(); | |
354 if (!IsWindowsVista()) { | |
355 ClearPStoreType(pstore, &type, &subtype); | |
356 // Releases it befor unload the dll. | |
357 pstore.Release(); | |
358 FreeLibrary(pstorec_dll); | |
359 } | |
360 } | |
361 | |
362 TEST_F(ImporterTest, IE7Importer) { | |
363 // This is the unencrypted values of my keys under Storage2. | |
364 // The passwords have been manually changed to abcdef... but the size remains | |
365 // the same. | |
366 unsigned char data1[] = "\x0c\x00\x00\x00\x38\x00\x00\x00\x2c\x00\x00\x00" | |
367 "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00\x00\x00" | |
368 "\x67\x00\x72\x00\x01\x00\x00\x00\x00\x00\x00\x00" | |
369 "\x00\x00\x00\x00\x4e\xfa\x67\x76\x22\x94\xc8\x01" | |
370 "\x08\x00\x00\x00\x12\x00\x00\x00\x4e\xfa\x67\x76" | |
371 "\x22\x94\xc8\x01\x0c\x00\x00\x00\x61\x00\x62\x00" | |
372 "\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00" | |
373 "\x00\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00" | |
374 "\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00" | |
375 "\x6c\x00\x00\x00"; | |
376 | |
377 unsigned char data2[] = "\x0c\x00\x00\x00\x38\x00\x00\x00\x24\x00\x00\x00" | |
378 "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00\x00\x00" | |
379 "\x67\x00\x72\x00\x01\x00\x00\x00\x00\x00\x00\x00" | |
380 "\x00\x00\x00\x00\xa8\xea\xf4\xe5\x9f\x9a\xc8\x01" | |
381 "\x09\x00\x00\x00\x14\x00\x00\x00\xa8\xea\xf4\xe5" | |
382 "\x9f\x9a\xc8\x01\x07\x00\x00\x00\x61\x00\x62\x00" | |
383 "\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00" | |
384 "\x69\x00\x00\x00\x61\x00\x62\x00\x63\x00\x64\x00" | |
385 "\x65\x00\x66\x00\x67\x00\x00\x00"; | |
386 | |
387 | |
388 | |
389 std::vector<unsigned char> decrypted_data1; | |
390 decrypted_data1.resize(arraysize(data1)); | |
391 memcpy(&decrypted_data1.front(), data1, sizeof(data1)); | |
392 | |
393 std::vector<unsigned char> decrypted_data2; | |
394 decrypted_data2.resize(arraysize(data2)); | |
395 memcpy(&decrypted_data2.front(), data2, sizeof(data2)); | |
396 | |
397 std::wstring password; | |
398 std::wstring username; | |
399 ASSERT_TRUE(ie7_password::GetUserPassFromData(decrypted_data1, &username, | |
400 &password)); | |
401 EXPECT_EQ(L"abcdefgh", username); | |
402 EXPECT_EQ(L"abcdefghijkl", password); | |
403 | |
404 ASSERT_TRUE(ie7_password::GetUserPassFromData(decrypted_data2, &username, | |
405 &password)); | |
406 EXPECT_EQ(L"abcdefghi", username); | |
407 EXPECT_EQ(L"abcdefg", password); | |
408 } | |
409 | |
410 static const BookmarkList kFirefox2Bookmarks[] = { | |
411 {true, 1, {L"Folder"}, | |
412 L"On Toolbar's Subfolder", | |
413 "http://on.toolbar/bookmark/folder"}, | |
414 {true, 0, {}, | |
415 L"On Bookmark Toolbar", | |
416 "http://on.toolbar/bookmark"}, | |
417 {false, 1, {L"Folder"}, | |
418 L"New Bookmark", | |
419 "http://domain/"}, | |
420 {false, 0, {}, | |
421 L"<Name>", | |
422 "http://domain.com/q?a=\"er\"&b=%3C%20%20%3E"}, | |
423 {false, 0, {}, | |
424 L"Google Home Page", | |
425 "http://www.google.com/"}, | |
426 {false, 0, {}, | |
427 L"\x4E2D\x6587", | |
428 "http://chinese.site.cn/path?query=1#ref"}, | |
429 {false, 0, {}, | |
430 L"mail", | |
431 "mailto:username@host"}, | |
432 }; | |
433 | |
434 static const PasswordList kFirefox2Passwords[] = { | |
435 {"https://www.google.com/", "", "https://www.google.com/", | |
436 L"", L"", L"", L"", true}, | |
437 {"http://localhost:8080/", "", "http://localhost:8080/corp.google.com", | |
438 L"", L"http", L"", L"Http1+1abcdefg", false}, | |
439 {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/", | |
440 L"loginuser", L"usr", L"loginpass", L"pwd", false}, | |
441 {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/", | |
442 L"loginuser", L"firefox", L"loginpass", L"firefox", false}, | |
443 {"http://localhost/", "", "http://localhost/", | |
444 L"loginuser", L"hello", L"", L"world", false}, | |
445 }; | |
446 | |
447 typedef struct { | |
448 const wchar_t* keyword; | |
449 const wchar_t* url; | |
450 } KeywordList; | |
451 | |
452 static const KeywordList kFirefox2Keywords[] = { | |
453 // Searh plugins | |
454 { L"amazon.com", | |
455 L"http://www.amazon.com/exec/obidos/external-search/?field-keywords=" | |
456 L"{searchTerms}&mode=blended" }, | |
457 { L"answers.com", | |
458 L"http://www.answers.com/main/ntquery?s={searchTerms}&gwp=13" }, | |
459 { L"search.creativecommons.org", | |
460 L"http://search.creativecommons.org/?q={searchTerms}" }, | |
461 { L"search.ebay.com", | |
462 L"http://search.ebay.com/search/search.dll?query={searchTerms}&" | |
463 L"MfcISAPICommand=GetResult&ht=1&ebaytag1=ebayreg&srchdesc=n&" | |
464 L"maxRecordsReturned=300&maxRecordsPerPage=50&SortProperty=MetaEndSort" }, | |
465 { L"google.com", | |
466 L"http://www.google.com/search?q={searchTerms}&ie=utf-8&oe=utf-8&aq=t" }, | |
467 { L"search.yahoo.com", | |
468 L"http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8" }, | |
469 { L"flickr.com", | |
470 L"http://www.flickr.com/photos/tags/?q={searchTerms}" }, | |
471 { L"imdb.com", | |
472 L"http://www.imdb.com/find?q={searchTerms}" }, | |
473 { L"webster.com", | |
474 L"http://www.webster.com/cgi-bin/dictionary?va={searchTerms}" }, | |
475 // Search keywords. | |
476 { L"google", L"http://www.google.com/" }, | |
477 { L"< > & \" ' \\ /", L"http://g.cn/"}, | |
478 }; | |
479 | |
480 static const int kDefaultFirefox2KeywordIndex = 8; | |
481 | |
482 class FirefoxObserver : public ProfileWriter, | |
483 public ImporterHost::Observer { | |
484 public: | |
485 FirefoxObserver() : ProfileWriter(NULL) { | |
486 bookmark_count_ = 0; | |
487 history_count_ = 0; | |
488 password_count_ = 0; | |
489 keyword_count_ = 0; | |
490 } | |
491 | |
492 virtual void ImportItemStarted(ImportItem item) {} | |
493 virtual void ImportItemEnded(ImportItem item) {} | |
494 virtual void ImportStarted() {} | |
495 virtual void ImportEnded() { | |
496 MessageLoop::current()->Quit(); | |
497 EXPECT_EQ(arraysize(kFirefox2Bookmarks), bookmark_count_); | |
498 EXPECT_EQ(1, history_count_); | |
499 EXPECT_EQ(arraysize(kFirefox2Passwords), password_count_); | |
500 EXPECT_EQ(arraysize(kFirefox2Keywords), keyword_count_); | |
501 EXPECT_EQ(kFirefox2Keywords[kDefaultFirefox2KeywordIndex].keyword, | |
502 default_keyword_); | |
503 EXPECT_EQ(kFirefox2Keywords[kDefaultFirefox2KeywordIndex].url, | |
504 default_keyword_url_); | |
505 } | |
506 | |
507 virtual bool BookmarkModelIsLoaded() const { | |
508 // Profile is ready for writing. | |
509 return true; | |
510 } | |
511 | |
512 virtual void AddBookmarkModelObserver(BookmarkModelObserver* observer) { | |
513 NOTREACHED(); | |
514 } | |
515 | |
516 virtual bool TemplateURLModelIsLoaded() const { | |
517 return true; | |
518 } | |
519 | |
520 virtual void AddTemplateURLModelObserver(NotificationObserver* observer) { | |
521 NOTREACHED(); | |
522 } | |
523 | |
524 virtual void AddPasswordForm(const PasswordForm& form) { | |
525 PasswordList p = kFirefox2Passwords[password_count_]; | |
526 EXPECT_EQ(p.origin, form.origin.spec()); | |
527 EXPECT_EQ(p.realm, form.signon_realm); | |
528 EXPECT_EQ(p.action, form.action.spec()); | |
529 EXPECT_EQ(p.username_element, form.username_element); | |
530 EXPECT_EQ(p.username, form.username_value); | |
531 EXPECT_EQ(p.password_element, form.password_element); | |
532 EXPECT_EQ(p.password, form.password_value); | |
533 EXPECT_EQ(p.blacklisted, form.blacklisted_by_user); | |
534 ++password_count_; | |
535 } | |
536 | |
537 virtual void AddHistoryPage(const std::vector<history::URLRow>& page) { | |
538 EXPECT_EQ(1, page.size()); | |
539 EXPECT_EQ("http://en-us.www.mozilla.com/", page[0].url().spec()); | |
540 EXPECT_EQ(L"Firefox Updated", page[0].title()); | |
541 ++history_count_; | |
542 } | |
543 | |
544 virtual void AddBookmarkEntry(const std::vector<BookmarkEntry>& bookmark) { | |
545 for (size_t i = 0; i < bookmark.size(); ++i) { | |
546 if (FindBookmarkEntry(bookmark[i], kFirefox2Bookmarks, | |
547 arraysize(kFirefox2Bookmarks))) | |
548 ++bookmark_count_; | |
549 } | |
550 } | |
551 | |
552 virtual void AddKeywords(const std::vector<TemplateURL*>& template_urls, | |
553 int default_keyword_index, | |
554 bool unique_on_host_and_path) { | |
555 for (size_t i = 0; i < template_urls.size(); ++i) { | |
556 // The order might not be deterministic, look in the expected list for | |
557 // that template URL. | |
558 bool found = false; | |
559 std::wstring keyword = template_urls[i]->keyword(); | |
560 for (int j = 0; j < arraysize(kFirefox2Keywords); ++j) { | |
561 const wchar_t* comp_keyword = kFirefox2Keywords[j].keyword; | |
562 bool equal = (keyword == comp_keyword); | |
563 if (template_urls[i]->keyword() == kFirefox2Keywords[j].keyword) { | |
564 EXPECT_EQ(kFirefox2Keywords[j].url, template_urls[i]->url()->url()); | |
565 found = true; | |
566 break; | |
567 } | |
568 } | |
569 EXPECT_TRUE(found); | |
570 ++keyword_count_; | |
571 } | |
572 | |
573 if (default_keyword_index != -1) { | |
574 EXPECT_LT(default_keyword_index, static_cast<int>(template_urls.size())); | |
575 TemplateURL* default_turl = template_urls[default_keyword_index]; | |
576 default_keyword_ = default_turl->keyword(); | |
577 default_keyword_url_ = default_turl->url()->url(); | |
578 } | |
579 | |
580 STLDeleteContainerPointers(template_urls.begin(), template_urls.end()); | |
581 } | |
582 | |
583 void AddFavicons(const std::vector<history::ImportedFavIconUsage>& favicons) { | |
584 } | |
585 | |
586 private: | |
587 int bookmark_count_; | |
588 int history_count_; | |
589 int password_count_; | |
590 int keyword_count_; | |
591 std::wstring default_keyword_; | |
592 std::wstring default_keyword_url_; | |
593 }; | |
594 | |
595 TEST_F(ImporterTest, Firefox2Importer) { | |
596 std::wstring data_path; | |
597 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
598 file_util::AppendToPath(&data_path, L"firefox2_profile\\*"); | |
599 file_util::CopyDirectory(data_path, profile_path_, true); | |
600 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
601 file_util::AppendToPath(&data_path, L"firefox2_nss"); | |
602 file_util::CopyDirectory(data_path, profile_path_, false); | |
603 | |
604 std::wstring search_engine_path = app_path_; | |
605 file_util::AppendToPath(&search_engine_path, L"searchplugins"); | |
606 CreateDirectory(search_engine_path.c_str(), NULL); | |
607 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
608 file_util::AppendToPath(&data_path, L"firefox2_searchplugins"); | |
609 file_util::CopyDirectory(data_path, search_engine_path, false); | |
610 | |
611 MessageLoop* loop = MessageLoop::current(); | |
612 scoped_refptr<ImporterHost> host = new ImporterHost(loop); | |
613 FirefoxObserver* observer = new FirefoxObserver(); | |
614 host->SetObserver(observer); | |
615 ProfileInfo profile_info; | |
616 profile_info.browser_type = FIREFOX2; | |
617 profile_info.app_path = app_path_; | |
618 profile_info.source_path = profile_path_; | |
619 | |
620 loop->PostTask(FROM_HERE, NewRunnableMethod(host.get(), | |
621 &ImporterHost::StartImportSettings, profile_info, | |
622 HISTORY | PASSWORDS | FAVORITES | SEARCH_ENGINES, observer, true)); | |
623 loop->Run(); | |
624 } | |
625 | |
626 static const BookmarkList kFirefox3Bookmarks[] = { | |
627 {true, 0, {}, | |
628 L"Toolbar", | |
629 "http://site/"}, | |
630 {false, 0, {}, | |
631 L"Title", | |
632 "http://www.google.com/"}, | |
633 }; | |
634 | |
635 static const PasswordList kFirefox3Passwords[] = { | |
636 {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/", | |
637 L"loginuser", L"abc", L"loginpass", L"123", false}, | |
638 {"http://localhost:8080/", "", "http://localhost:8080/localhost", | |
639 L"", L"http", L"", L"Http1+1abcdefg", false}, | |
640 }; | |
641 | |
642 static const KeywordList kFirefox3Keywords[] = { | |
643 { L"amazon.com", | |
644 L"http://www.amazon.com/exec/obidos/external-search/?field-keywords=" | |
645 L"{searchTerms}&mode=blended" }, | |
646 { L"answers.com", | |
647 L"http://www.answers.com/main/ntquery?s={searchTerms}&gwp=13" }, | |
648 { L"search.creativecommons.org", | |
649 L"http://search.creativecommons.org/?q={searchTerms}" }, | |
650 { L"search.ebay.com", | |
651 L"http://search.ebay.com/search/search.dll?query={searchTerms}&" | |
652 L"MfcISAPICommand=GetResult&ht=1&ebaytag1=ebayreg&srchdesc=n&" | |
653 L"maxRecordsReturned=300&maxRecordsPerPage=50&SortProperty=MetaEndSort" }, | |
654 { L"google.com", | |
655 L"http://www.google.com/search?q={searchTerms}&ie=utf-8&oe=utf-8&aq=t" }, | |
656 { L"en.wikipedia.org", | |
657 L"http://en.wikipedia.org/wiki/Special:Search?search={searchTerms}" }, | |
658 { L"search.yahoo.com", | |
659 L"http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8" }, | |
660 { L"flickr.com", | |
661 L"http://www.flickr.com/photos/tags/?q={searchTerms}" }, | |
662 { L"imdb.com", | |
663 L"http://www.imdb.com/find?q={searchTerms}" }, | |
664 { L"webster.com", | |
665 L"http://www.webster.com/cgi-bin/dictionary?va={searchTerms}" }, | |
666 // Search keywords. | |
667 { L"\x4E2D\x6587", L"http://www.google.com/" }, | |
668 }; | |
669 | |
670 static const int kDefaultFirefox3KeywordIndex = 8; | |
671 | |
672 class Firefox3Observer : public ProfileWriter, | |
673 public ImporterHost::Observer { | |
674 public: | |
675 Firefox3Observer() : ProfileWriter(NULL) { | |
676 bookmark_count_ = 0; | |
677 history_count_ = 0; | |
678 password_count_ = 0; | |
679 keyword_count_ = 0; | |
680 } | |
681 | |
682 virtual void ImportItemStarted(ImportItem item) {} | |
683 virtual void ImportItemEnded(ImportItem item) {} | |
684 virtual void ImportStarted() {} | |
685 virtual void ImportEnded() { | |
686 MessageLoop::current()->Quit(); | |
687 EXPECT_EQ(arraysize(kFirefox3Bookmarks), bookmark_count_); | |
688 EXPECT_EQ(1, history_count_); | |
689 EXPECT_EQ(arraysize(kFirefox3Passwords), password_count_); | |
690 EXPECT_EQ(arraysize(kFirefox3Keywords), keyword_count_); | |
691 EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].keyword, | |
692 default_keyword_); | |
693 EXPECT_EQ(kFirefox3Keywords[kDefaultFirefox3KeywordIndex].url, | |
694 default_keyword_url_); | |
695 } | |
696 | |
697 virtual bool BookmarkModelIsLoaded() const { | |
698 // Profile is ready for writing. | |
699 return true; | |
700 } | |
701 | |
702 virtual void AddBookmarkModelObserver(BookmarkModelObserver* observer) { | |
703 NOTREACHED(); | |
704 } | |
705 | |
706 virtual bool TemplateURLModelIsLoaded() const { | |
707 return true; | |
708 } | |
709 | |
710 virtual void AddTemplateURLModelObserver(NotificationObserver* observer) { | |
711 NOTREACHED(); | |
712 } | |
713 | |
714 virtual void AddPasswordForm(const PasswordForm& form) { | |
715 PasswordList p = kFirefox3Passwords[password_count_]; | |
716 EXPECT_EQ(p.origin, form.origin.spec()); | |
717 EXPECT_EQ(p.realm, form.signon_realm); | |
718 EXPECT_EQ(p.action, form.action.spec()); | |
719 EXPECT_EQ(p.username_element, form.username_element); | |
720 EXPECT_EQ(p.username, form.username_value); | |
721 EXPECT_EQ(p.password_element, form.password_element); | |
722 EXPECT_EQ(p.password, form.password_value); | |
723 EXPECT_EQ(p.blacklisted, form.blacklisted_by_user); | |
724 ++password_count_; | |
725 } | |
726 | |
727 virtual void AddHistoryPage(const std::vector<history::URLRow>& page) { | |
728 ASSERT_EQ(3, page.size()); | |
729 EXPECT_EQ("http://www.google.com/", page[0].url().spec()); | |
730 EXPECT_EQ(L"Google", page[0].title()); | |
731 EXPECT_EQ("http://www.google.com/", page[1].url().spec()); | |
732 EXPECT_EQ(L"Google", page[1].title()); | |
733 EXPECT_EQ("http://www.cs.unc.edu/~jbs/resources/perl/perl-cgi/programs/form1
-POST.html", | |
734 page[2].url().spec()); | |
735 EXPECT_EQ(L"example form (POST)", page[2].title()); | |
736 ++history_count_; | |
737 } | |
738 | |
739 virtual void AddBookmarkEntry(const std::vector<BookmarkEntry>& bookmark) { | |
740 for (size_t i = 0; i < bookmark.size(); ++i) { | |
741 if (FindBookmarkEntry(bookmark[i], kFirefox3Bookmarks, | |
742 arraysize(kFirefox3Bookmarks))) | |
743 ++bookmark_count_; | |
744 } | |
745 } | |
746 | |
747 void AddKeywords(const std::vector<TemplateURL*>& template_urls, | |
748 int default_keyword_index, | |
749 bool unique_on_host_and_path) { | |
750 for (size_t i = 0; i < template_urls.size(); ++i) { | |
751 // The order might not be deterministic, look in the expected list for | |
752 // that template URL. | |
753 bool found = false; | |
754 std::wstring keyword = template_urls[i]->keyword(); | |
755 for (int j = 0; j < arraysize(kFirefox3Keywords); ++j) { | |
756 const wchar_t* comp_keyword = kFirefox3Keywords[j].keyword; | |
757 bool equal = (keyword == comp_keyword); | |
758 if (template_urls[i]->keyword() == kFirefox3Keywords[j].keyword) { | |
759 EXPECT_EQ(kFirefox3Keywords[j].url, template_urls[i]->url()->url()); | |
760 found = true; | |
761 break; | |
762 } | |
763 } | |
764 EXPECT_TRUE(found); | |
765 ++keyword_count_; | |
766 } | |
767 | |
768 if (default_keyword_index != -1) { | |
769 EXPECT_LT(default_keyword_index, static_cast<int>(template_urls.size())); | |
770 TemplateURL* default_turl = template_urls[default_keyword_index]; | |
771 default_keyword_ = default_turl->keyword(); | |
772 default_keyword_url_ = default_turl->url()->url(); | |
773 } | |
774 | |
775 STLDeleteContainerPointers(template_urls.begin(), template_urls.end()); | |
776 } | |
777 | |
778 void AddFavicons(const std::vector<history::ImportedFavIconUsage>& favicons) { | |
779 } | |
780 | |
781 private: | |
782 int bookmark_count_; | |
783 int history_count_; | |
784 int password_count_; | |
785 int keyword_count_; | |
786 std::wstring default_keyword_; | |
787 std::wstring default_keyword_url_; | |
788 }; | |
789 | |
790 TEST_F(ImporterTest, Firefox3Importer) { | |
791 std::wstring data_path; | |
792 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
793 file_util::AppendToPath(&data_path, L"firefox3_profile\\*"); | |
794 file_util::CopyDirectory(data_path, profile_path_, true); | |
795 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
796 file_util::AppendToPath(&data_path, L"firefox3_nss"); | |
797 file_util::CopyDirectory(data_path, profile_path_, false); | |
798 | |
799 std::wstring search_engine_path = app_path_; | |
800 file_util::AppendToPath(&search_engine_path, L"searchplugins"); | |
801 CreateDirectory(search_engine_path.c_str(), NULL); | |
802 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); | |
803 file_util::AppendToPath(&data_path, L"firefox3_searchplugins"); | |
804 file_util::CopyDirectory(data_path, search_engine_path, false); | |
805 | |
806 MessageLoop* loop = MessageLoop::current(); | |
807 ProfileInfo profile_info; | |
808 profile_info.browser_type = FIREFOX3; | |
809 profile_info.app_path = app_path_; | |
810 profile_info.source_path = profile_path_; | |
811 scoped_refptr<ImporterHost> host = new ImporterHost(loop); | |
812 Firefox3Observer* observer = new Firefox3Observer(); | |
813 host->SetObserver(observer); | |
814 loop->PostTask(FROM_HERE, NewRunnableMethod(host.get(), | |
815 &ImporterHost::StartImportSettings, profile_info, | |
816 HISTORY | PASSWORDS | FAVORITES | SEARCH_ENGINES, observer, true)); | |
817 loop->Run(); | |
818 } | |
819 | |
OLD | NEW |