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/utility/importer/safari_importer.h"
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/path_service.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/importer/imported_bookmark_entry.h"
19 #include "chrome/common/importer/importer_bridge.h"
20 #include "chrome/common/importer/safari_importer_utils.h"
21 #include "chrome/utility/importer/safari_importer.h"
22 #include "components/favicon_base/favicon_usage_data.h"
23 #include "sql/connection.h"
24 #include "testing/platform_test.h"
26 using base::ASCIIToUTF16;
28 // In order to test the Safari import functionality effectively, we store a
29 // simulated Library directory containing dummy data files in the same
30 // structure as ~/Library in the Chrome test data directory.
31 // This function returns the path to that directory.
32 base::FilePath GetTestSafariLibraryPath(const std::string& suffix) {
33 base::FilePath test_dir;
34 PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
36 // Our simulated ~/Library directory
38 test_dir.AppendASCII("import").AppendASCII("safari").AppendASCII(suffix);
41 class SafariImporterTest : public PlatformTest {
43 SafariImporter* GetSafariImporter() {
44 return GetSafariImporterWithPathSuffix("default");
47 SafariImporter* GetSafariImporterWithPathSuffix(const std::string& suffix) {
48 base::FilePath test_library_dir = GetTestSafariLibraryPath(suffix);
49 CHECK(base::PathExists(test_library_dir));
50 return new SafariImporter(test_library_dir);
54 TEST_F(SafariImporterTest, HistoryImport) {
55 scoped_refptr<SafariImporter> importer(GetSafariImporter());
57 std::vector<ImporterURLRow> history_items;
58 importer->ParseHistoryItems(&history_items);
60 // Should be 2 history items.
61 ASSERT_EQ(history_items.size(), 2U);
63 ImporterURLRow& it1 = history_items[0];
64 EXPECT_EQ(it1.url, GURL("http://www.firsthistoryitem.com/"));
65 EXPECT_EQ(it1.title, base::UTF8ToUTF16("First History Item Title"));
66 EXPECT_EQ(it1.visit_count, 1);
67 EXPECT_EQ(it1.hidden, 0);
68 EXPECT_EQ(it1.typed_count, 0);
69 EXPECT_EQ(it1.last_visit.ToDoubleT(),
70 importer->HistoryTimeToEpochTime(@"270598264.4"));
72 ImporterURLRow& it2 = history_items[1];
73 std::string second_item_title("http://www.secondhistoryitem.com/");
74 EXPECT_EQ(it2.url, GURL(second_item_title));
75 // The second item lacks a title so we expect the URL to be substituted.
76 EXPECT_EQ(base::UTF16ToUTF8(it2.title), second_item_title.c_str());
77 EXPECT_EQ(it2.visit_count, 55);
78 EXPECT_EQ(it2.hidden, 0);
79 EXPECT_EQ(it2.typed_count, 0);
80 EXPECT_EQ(it2.last_visit.ToDoubleT(),
81 importer->HistoryTimeToEpochTime(@"270598231.4"));
84 TEST_F(SafariImporterTest, BookmarkImport) {
89 // We store the path with levels of nesting delimited by forward slashes.
92 } kImportedBookmarksData[] = {
95 GURL("http://www.apple.com/"),
96 ASCIIToUTF16("Toolbar/"),
101 GURL("http://www.yahoo.com/"),
102 ASCIIToUTF16("Toolbar/"),
103 ASCIIToUTF16("Yahoo!")
107 GURL("http://www.cnn.com/"),
108 ASCIIToUTF16("Toolbar/News"),
113 GURL("http://www.nytimes.com/"),
114 ASCIIToUTF16("Toolbar/News"),
115 ASCIIToUTF16("The New York Times")
119 GURL("http://www.reddit.com/"),
121 ASCIIToUTF16("reddit.com: what's new online!")
127 ASCIIToUTF16("Empty Folder")
131 GURL("http://www.webkit.org/blog/"),
133 ASCIIToUTF16("Surfin' Safari - The WebKit Blog")
137 scoped_refptr<SafariImporter> importer(GetSafariImporter());
138 std::vector<ImportedBookmarkEntry> bookmarks;
139 importer->ParseBookmarks(ASCIIToUTF16("Toolbar"), &bookmarks);
140 size_t num_bookmarks = bookmarks.size();
141 ASSERT_EQ(arraysize(kImportedBookmarksData), num_bookmarks);
143 for (size_t i = 0; i < num_bookmarks; ++i) {
144 ImportedBookmarkEntry& entry = bookmarks[i];
145 EXPECT_EQ(kImportedBookmarksData[i].in_toolbar, entry.in_toolbar);
146 EXPECT_EQ(kImportedBookmarksData[i].url, entry.url);
148 std::vector<base::string16> path = base::SplitString(
149 kImportedBookmarksData[i].path, ASCIIToUTF16("/"),
150 base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
151 ASSERT_EQ(path.size(), entry.path.size());
152 for (size_t j = 0; j < path.size(); ++j) {
153 EXPECT_EQ(path[j], entry.path[j]);
156 EXPECT_EQ(kImportedBookmarksData[i].title, entry.title);
160 TEST_F(SafariImporterTest, BookmarkImportWithEmptyBookmarksMenu) {
165 // We store the path with levels of nesting delimited by forward slashes.
167 base::string16 title;
168 } kImportedBookmarksData[] = {
171 GURL("http://www.apple.com/"),
172 ASCIIToUTF16("Toolbar/"),
173 ASCIIToUTF16("Apple")
177 GURL("http://www.yahoo.com/"),
178 ASCIIToUTF16("Toolbar/"),
179 ASCIIToUTF16("Yahoo!")
183 GURL("http://www.cnn.com/"),
184 ASCIIToUTF16("Toolbar/News"),
189 GURL("http://www.nytimes.com/"),
190 ASCIIToUTF16("Toolbar/News"),
191 ASCIIToUTF16("The New York Times")
195 GURL("http://www.webkit.org/blog/"),
197 ASCIIToUTF16("Surfin' Safari - The WebKit Blog")
201 scoped_refptr<SafariImporter> importer(
202 GetSafariImporterWithPathSuffix("empty_bookmarks_menu"));
203 std::vector<ImportedBookmarkEntry> bookmarks;
204 importer->ParseBookmarks(ASCIIToUTF16("Toolbar"), &bookmarks);
205 size_t num_bookmarks = bookmarks.size();
206 ASSERT_EQ(arraysize(kImportedBookmarksData), num_bookmarks);
208 for (size_t i = 0; i < num_bookmarks; ++i) {
209 ImportedBookmarkEntry& entry = bookmarks[i];
210 EXPECT_EQ(kImportedBookmarksData[i].in_toolbar, entry.in_toolbar);
211 EXPECT_EQ(kImportedBookmarksData[i].url, entry.url);
213 std::vector<base::string16> path = base::SplitString(
214 kImportedBookmarksData[i].path, ASCIIToUTF16("/"),
215 base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
216 ASSERT_EQ(path.size(), entry.path.size());
217 for (size_t j = 0; j < path.size(); ++j) {
218 EXPECT_EQ(path[j], entry.path[j]);
221 EXPECT_EQ(kImportedBookmarksData[i].title, entry.title);
225 TEST_F(SafariImporterTest, FaviconImport) {
226 scoped_refptr<SafariImporter> importer(GetSafariImporter());
228 ASSERT_TRUE(importer->OpenDatabase(&db));
230 SafariImporter::FaviconMap favicon_map;
231 importer->ImportFaviconURLs(&db, &favicon_map);
233 favicon_base::FaviconUsageDataList favicons;
234 importer->LoadFaviconData(&db, favicon_map, &favicons);
236 size_t num_favicons = favicons.size();
237 ASSERT_EQ(num_favicons, 2U);
239 favicon_base::FaviconUsageData& fav0 = favicons[0];
240 EXPECT_EQ("http://s.ytimg.com/yt/favicon-vfl86270.ico",
241 fav0.favicon_url.spec());
242 EXPECT_GT(fav0.png_data.size(), 0U);
243 EXPECT_EQ(fav0.urls.size(), 1U);
244 EXPECT_TRUE(fav0.urls.find(GURL("http://www.youtube.com/"))
247 favicon_base::FaviconUsageData& fav1 = favicons[1];
248 EXPECT_EQ("http://www.opensearch.org/favicon.ico",
249 fav1.favicon_url.spec());
250 EXPECT_GT(fav1.png_data.size(), 0U);
251 EXPECT_EQ(fav1.urls.size(), 2U);
252 EXPECT_TRUE(fav1.urls.find(GURL("http://www.opensearch.org/Home"))
255 EXPECT_TRUE(fav1.urls.find(
256 GURL("http://www.opensearch.org/Special:Search?search=lalala&go=Search"))
260 TEST_F(SafariImporterTest, CanImport) {
261 uint16 items = importer::NONE;
262 EXPECT_TRUE(SafariImporterCanImport(
263 GetTestSafariLibraryPath("default"), &items));
264 EXPECT_EQ(items, importer::HISTORY | importer::FAVORITES);
265 EXPECT_EQ(items & importer::COOKIES, importer::NONE);
266 EXPECT_EQ(items & importer::PASSWORDS, importer::NONE);
267 EXPECT_EQ(items & importer::SEARCH_ENGINES, importer::NONE);
268 EXPECT_EQ(items & importer::HOME_PAGE, importer::NONE);
270 // Check that we don't import anything from a bogus library directory.
271 base::ScopedTempDir fake_library_dir;
272 ASSERT_TRUE(fake_library_dir.CreateUniqueTempDir());
273 EXPECT_FALSE(SafariImporterCanImport(fake_library_dir.path(), &items));