1 // Copyright (c) 2011 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/importer/safari_importer.h" 6 7 #include "app/sql/connection.h" 8 #include "base/basictypes.h" 9 #include "base/file_path.h" 10 #include "base/file_util.h" 11 #include "base/path_service.h" 12 #include "base/sys_string_conversions.h" 13 #include "base/utf_string_conversions.h" 14 #include "chrome/browser/history/history_types.h" 15 #include "chrome/browser/importer/importer_bridge.h" 16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/test/file_test_utils.h" 18 #include "testing/platform_test.h" 19 20 // In order to test the Safari import functionality effectively, we store a 21 // simulated Library directory containing dummy data files in the same 22 // structure as ~/Library in the Chrome test data directory. 23 // This function returns the path to that directory. 24 FilePath GetTestSafariLibraryPath() { 25 FilePath test_dir; 26 PathService::Get(chrome::DIR_TEST_DATA, &test_dir); 27 28 // Our simulated ~/Library directory 29 test_dir = test_dir.AppendASCII("safari_import"); 30 return test_dir; 31 } 32 33 class SafariImporterTest : public PlatformTest { 34 public: 35 SafariImporter* GetSafariImporter() { 36 FilePath test_library_dir = GetTestSafariLibraryPath(); 37 CHECK(file_util::PathExists(test_library_dir)) << 38 "Missing test data directory"; 39 40 return new SafariImporter(test_library_dir); 41 } 42 }; 43 44 TEST_F(SafariImporterTest, HistoryImport) { 45 scoped_refptr<SafariImporter> importer(GetSafariImporter()); 46 47 std::vector<history::URLRow> history_items; 48 importer->ParseHistoryItems(&history_items); 49 50 // Should be 2 history items. 51 ASSERT_EQ(history_items.size(), 2U); 52 53 history::URLRow& it1 = history_items[0]; 54 EXPECT_EQ(it1.url(), GURL("http://www.firsthistoryitem.com/")); 55 EXPECT_EQ(it1.title(), UTF8ToUTF16("First History Item Title")); 56 EXPECT_EQ(it1.visit_count(), 1); 57 EXPECT_EQ(it1.hidden(), 0); 58 EXPECT_EQ(it1.typed_count(), 0); 59 EXPECT_EQ(it1.last_visit().ToDoubleT(), 60 importer->HistoryTimeToEpochTime(@"270598264.4")); 61 62 history::URLRow& it2 = history_items[1]; 63 std::string second_item_title("http://www.secondhistoryitem.com/"); 64 EXPECT_EQ(it2.url(), GURL(second_item_title)); 65 // The second item lacks a title so we expect the URL to be substituted. 66 EXPECT_EQ(UTF16ToUTF8(it2.title()), second_item_title.c_str()); 67 EXPECT_EQ(it2.visit_count(), 55); 68 EXPECT_EQ(it2.hidden(), 0); 69 EXPECT_EQ(it2.typed_count(), 0); 70 EXPECT_EQ(it2.last_visit().ToDoubleT(), 71 importer->HistoryTimeToEpochTime(@"270598231.4")); 72 } 73 74 TEST_F(SafariImporterTest, BookmarkImport) { 75 // Expected results 76 const struct { 77 bool in_toolbar; 78 GURL url; 79 // If the path array for an element is entry set this to true. 80 bool path_is_empty; 81 // We ony support one level of nesting in paths, this makes testing a little 82 // easier. 83 std::wstring path; 84 std::wstring title; 85 } kImportedBookmarksData[] = { 86 {true, GURL("http://www.apple.com/"), true, L"", L"Apple"}, 87 {true, GURL("http://www.yahoo.com/"), true, L"", L"Yahoo!"}, 88 {true, GURL("http://www.cnn.com/"), false, L"News", L"CNN"}, 89 {true, GURL("http://www.nytimes.com/"), false, L"News", 90 L"The New York Times"}, 91 {false, GURL("http://www.reddit.com/"), true, L"", 92 L"reddit.com: what's new online!"}, 93 }; 94 95 scoped_refptr<SafariImporter> importer(GetSafariImporter()); 96 std::vector<ProfileWriter::BookmarkEntry> bookmarks; 97 importer->ParseBookmarks(&bookmarks); 98 size_t num_bookmarks = bookmarks.size(); 99 EXPECT_EQ(num_bookmarks, ARRAYSIZE_UNSAFE(kImportedBookmarksData)); 100 101 for (size_t i = 0; i < num_bookmarks; ++i) { 102 ProfileWriter::BookmarkEntry& entry = bookmarks[i]; 103 EXPECT_EQ(entry.in_toolbar, kImportedBookmarksData[i].in_toolbar); 104 EXPECT_EQ(entry.url, kImportedBookmarksData[i].url); 105 if (kImportedBookmarksData[i].path_is_empty) { 106 EXPECT_EQ(entry.path.size(), 0U); 107 } else { 108 EXPECT_EQ(entry.path.size(), 1U); 109 EXPECT_EQ(UTF16ToWideHack(entry.path[0]), kImportedBookmarksData[i].path); 110 EXPECT_EQ(UTF16ToWideHack(entry.title), kImportedBookmarksData[i].title); 111 } 112 } 113 } 114 115 TEST_F(SafariImporterTest, FaviconImport) { 116 scoped_refptr<SafariImporter> importer(GetSafariImporter()); 117 sql::Connection db; 118 ASSERT_TRUE(importer->OpenDatabase(&db)); 119 120 SafariImporter::FaviconMap favicon_map; 121 importer->ImportFaviconURLs(&db, &favicon_map); 122 123 std::vector<history::ImportedFaviconUsage> favicons; 124 importer->LoadFaviconData(&db, favicon_map, &favicons); 125 126 size_t num_favicons = favicons.size(); 127 ASSERT_EQ(num_favicons, 2U); 128 129 history::ImportedFaviconUsage &fav0 = favicons[0]; 130 EXPECT_EQ("http://s.ytimg.com/yt/favicon-vfl86270.ico", 131 fav0.favicon_url.spec()); 132 EXPECT_GT(fav0.png_data.size(), 0U); 133 EXPECT_EQ(fav0.urls.size(), 1U); 134 EXPECT_TRUE(fav0.urls.find(GURL("http://www.youtube.com/")) 135 != fav0.urls.end()); 136 137 history::ImportedFaviconUsage &fav1 = favicons[1]; 138 EXPECT_EQ("http://www.opensearch.org/favicon.ico", 139 fav1.favicon_url.spec()); 140 EXPECT_GT(fav1.png_data.size(), 0U); 141 EXPECT_EQ(fav1.urls.size(), 2U); 142 EXPECT_TRUE(fav1.urls.find(GURL("http://www.opensearch.org/Home")) 143 != fav1.urls.end()); 144 145 EXPECT_TRUE(fav1.urls.find( 146 GURL("http://www.opensearch.org/Special:Search?search=lalala&go=Search")) 147 != fav1.urls.end()); 148 } 149 150 TEST_F(SafariImporterTest, CanImport) { 151 uint16 items = importer::NONE; 152 EXPECT_TRUE(SafariImporter::CanImport(GetTestSafariLibraryPath(), &items)); 153 EXPECT_EQ(items, importer::HISTORY | importer::FAVORITES); 154 EXPECT_EQ(items & importer::COOKIES, importer::NONE); 155 EXPECT_EQ(items & importer::PASSWORDS, importer::NONE); 156 EXPECT_EQ(items & importer::SEARCH_ENGINES, importer::NONE); 157 EXPECT_EQ(items & importer::HOME_PAGE, importer::NONE); 158 159 // Check that we don't import anything from a bogus library directory. 160 FilePath fake_library_dir; 161 file_util::CreateNewTempDirectory("FakeSafariLibrary", &fake_library_dir); 162 FileAutoDeleter deleter(fake_library_dir); 163 EXPECT_FALSE(SafariImporter::CanImport(fake_library_dir, &items)); 164 } 165