1 // Copyright 2014 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 "base/basictypes.h" 6 #include "base/files/scoped_temp_dir.h" 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string16.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "components/bookmarks/browser/bookmark_model.h" 11 #include "components/bookmarks/browser/bookmark_node_data.h" 12 #include "components/bookmarks/test/bookmark_test_helpers.h" 13 #include "components/bookmarks/test/test_bookmark_client.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "ui/base/dragdrop/os_exchange_data.h" 16 #include "ui/events/platform/platform_event_source.h" 17 #include "url/gurl.h" 18 19 using base::ASCIIToUTF16; 20 21 namespace bookmarks { 22 23 class BookmarkNodeDataTest : public testing::Test { 24 public: 25 BookmarkNodeDataTest() {} 26 27 virtual void SetUp() OVERRIDE { 28 event_source_ = ui::PlatformEventSource::CreateDefault(); 29 model_ = client_.CreateModel(); 30 test::WaitForBookmarkModelToLoad(model_.get()); 31 bool success = profile_dir_.CreateUniqueTempDir(); 32 ASSERT_TRUE(success); 33 } 34 35 virtual void TearDown() OVERRIDE { 36 model_.reset(); 37 event_source_.reset(); 38 bool success = profile_dir_.Delete(); 39 ASSERT_TRUE(success); 40 } 41 42 const base::FilePath& GetProfilePath() const { return profile_dir_.path(); } 43 44 BookmarkModel* model() { return model_.get(); } 45 46 private: 47 base::ScopedTempDir profile_dir_; 48 TestBookmarkClient client_; 49 scoped_ptr<BookmarkModel> model_; 50 scoped_ptr<ui::PlatformEventSource> event_source_; 51 52 DISALLOW_COPY_AND_ASSIGN(BookmarkNodeDataTest); 53 }; 54 55 namespace { 56 57 ui::OSExchangeData::Provider* CloneProvider(const ui::OSExchangeData& data) { 58 return data.provider().Clone(); 59 } 60 61 } // namespace 62 63 // Makes sure BookmarkNodeData is initially invalid. 64 TEST_F(BookmarkNodeDataTest, InitialState) { 65 BookmarkNodeData data; 66 EXPECT_FALSE(data.is_valid()); 67 } 68 69 // Makes sure reading bogus data leaves the BookmarkNodeData invalid. 70 TEST_F(BookmarkNodeDataTest, BogusRead) { 71 ui::OSExchangeData data; 72 BookmarkNodeData drag_data; 73 EXPECT_FALSE(drag_data.Read(ui::OSExchangeData(CloneProvider(data)))); 74 EXPECT_FALSE(drag_data.is_valid()); 75 } 76 77 // Writes a URL to the clipboard and make sure BookmarkNodeData can correctly 78 // read it. 79 TEST_F(BookmarkNodeDataTest, JustURL) { 80 const GURL url("http://google.com"); 81 const base::string16 title(ASCIIToUTF16("google.com")); 82 83 ui::OSExchangeData data; 84 data.SetURL(url, title); 85 86 BookmarkNodeData drag_data; 87 EXPECT_TRUE(drag_data.Read(ui::OSExchangeData(CloneProvider(data)))); 88 EXPECT_TRUE(drag_data.is_valid()); 89 ASSERT_EQ(1u, drag_data.elements.size()); 90 EXPECT_TRUE(drag_data.elements[0].is_url); 91 EXPECT_EQ(url, drag_data.elements[0].url); 92 EXPECT_EQ(title, drag_data.elements[0].title); 93 EXPECT_TRUE(drag_data.elements[0].date_added.is_null()); 94 EXPECT_TRUE(drag_data.elements[0].date_folder_modified.is_null()); 95 EXPECT_EQ(0u, drag_data.elements[0].children.size()); 96 } 97 98 TEST_F(BookmarkNodeDataTest, URL) { 99 // Write a single node representing a URL to the clipboard. 100 const BookmarkNode* root = model()->bookmark_bar_node(); 101 GURL url(GURL("http://foo.com")); 102 const base::string16 title(ASCIIToUTF16("foo.com")); 103 const BookmarkNode* node = model()->AddURL(root, 0, title, url); 104 BookmarkNodeData drag_data(node); 105 EXPECT_TRUE(drag_data.is_valid()); 106 ASSERT_EQ(1u, drag_data.elements.size()); 107 EXPECT_TRUE(drag_data.elements[0].is_url); 108 EXPECT_EQ(url, drag_data.elements[0].url); 109 EXPECT_EQ(title, drag_data.elements[0].title); 110 EXPECT_EQ(node->date_added(), drag_data.elements[0].date_added); 111 EXPECT_EQ(node->date_folder_modified(), 112 drag_data.elements[0].date_folder_modified); 113 ui::OSExchangeData data; 114 drag_data.Write(GetProfilePath(), &data); 115 116 // Now read the data back in. 117 ui::OSExchangeData data2(CloneProvider(data)); 118 BookmarkNodeData read_data; 119 EXPECT_TRUE(read_data.Read(data2)); 120 EXPECT_TRUE(read_data.is_valid()); 121 ASSERT_EQ(1u, read_data.elements.size()); 122 EXPECT_TRUE(read_data.elements[0].is_url); 123 EXPECT_EQ(url, read_data.elements[0].url); 124 EXPECT_EQ(title, read_data.elements[0].title); 125 EXPECT_TRUE(read_data.elements[0].date_added.is_null()); 126 EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null()); 127 EXPECT_TRUE(read_data.GetFirstNode(model(), GetProfilePath()) == node); 128 129 // Make sure asking for the node with a different profile returns NULL. 130 base::ScopedTempDir other_profile_dir; 131 EXPECT_TRUE(other_profile_dir.CreateUniqueTempDir()); 132 EXPECT_TRUE(read_data.GetFirstNode(model(), other_profile_dir.path()) == 133 NULL); 134 135 // Writing should also put the URL and title on the clipboard. 136 GURL read_url; 137 base::string16 read_title; 138 EXPECT_TRUE(data2.GetURLAndTitle( 139 ui::OSExchangeData::CONVERT_FILENAMES, &read_url, &read_title)); 140 EXPECT_EQ(url, read_url); 141 EXPECT_EQ(title, read_title); 142 } 143 144 // Tests writing a folder to the clipboard. 145 TEST_F(BookmarkNodeDataTest, Folder) { 146 const BookmarkNode* root = model()->bookmark_bar_node(); 147 const BookmarkNode* g1 = model()->AddFolder(root, 0, ASCIIToUTF16("g1")); 148 model()->AddFolder(g1, 0, ASCIIToUTF16("g11")); 149 const BookmarkNode* g12 = model()->AddFolder(g1, 0, ASCIIToUTF16("g12")); 150 151 BookmarkNodeData drag_data(g12); 152 EXPECT_TRUE(drag_data.is_valid()); 153 ASSERT_EQ(1u, drag_data.elements.size()); 154 EXPECT_EQ(g12->GetTitle(), drag_data.elements[0].title); 155 EXPECT_FALSE(drag_data.elements[0].is_url); 156 EXPECT_EQ(g12->date_added(), drag_data.elements[0].date_added); 157 EXPECT_EQ(g12->date_folder_modified(), 158 drag_data.elements[0].date_folder_modified); 159 160 ui::OSExchangeData data; 161 drag_data.Write(GetProfilePath(), &data); 162 163 // Now read the data back in. 164 ui::OSExchangeData data2(CloneProvider(data)); 165 BookmarkNodeData read_data; 166 EXPECT_TRUE(read_data.Read(data2)); 167 EXPECT_TRUE(read_data.is_valid()); 168 ASSERT_EQ(1u, read_data.elements.size()); 169 EXPECT_EQ(g12->GetTitle(), read_data.elements[0].title); 170 EXPECT_FALSE(read_data.elements[0].is_url); 171 EXPECT_TRUE(read_data.elements[0].date_added.is_null()); 172 EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null()); 173 174 // We should get back the same node when asking for the same profile. 175 const BookmarkNode* r_g12 = read_data.GetFirstNode(model(), GetProfilePath()); 176 EXPECT_TRUE(g12 == r_g12); 177 178 // A different profile should return NULL for the node. 179 base::ScopedTempDir other_profile_dir; 180 EXPECT_TRUE(other_profile_dir.CreateUniqueTempDir()); 181 EXPECT_TRUE(read_data.GetFirstNode(model(), other_profile_dir.path()) == 182 NULL); 183 } 184 185 // Tests reading/writing a folder with children. 186 TEST_F(BookmarkNodeDataTest, FolderWithChild) { 187 const BookmarkNode* root = model()->bookmark_bar_node(); 188 const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1")); 189 190 GURL url(GURL("http://foo.com")); 191 const base::string16 title(ASCIIToUTF16("blah2")); 192 193 model()->AddURL(folder, 0, title, url); 194 195 BookmarkNodeData drag_data(folder); 196 197 ui::OSExchangeData data; 198 drag_data.Write(GetProfilePath(), &data); 199 200 // Now read the data back in. 201 ui::OSExchangeData data2(CloneProvider(data)); 202 BookmarkNodeData read_data; 203 EXPECT_TRUE(read_data.Read(data2)); 204 ASSERT_EQ(1u, read_data.elements.size()); 205 ASSERT_EQ(1u, read_data.elements[0].children.size()); 206 const BookmarkNodeData::Element& read_child = 207 read_data.elements[0].children[0]; 208 209 EXPECT_TRUE(read_child.is_url); 210 EXPECT_EQ(title, read_child.title); 211 EXPECT_EQ(url, read_child.url); 212 EXPECT_TRUE(read_data.elements[0].date_added.is_null()); 213 EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null()); 214 EXPECT_TRUE(read_child.is_url); 215 216 // And make sure we get the node back. 217 const BookmarkNode* r_folder = 218 read_data.GetFirstNode(model(), GetProfilePath()); 219 EXPECT_TRUE(folder == r_folder); 220 } 221 222 // Tests reading/writing of multiple nodes. 223 TEST_F(BookmarkNodeDataTest, MultipleNodes) { 224 const BookmarkNode* root = model()->bookmark_bar_node(); 225 const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1")); 226 227 GURL url(GURL("http://foo.com")); 228 const base::string16 title(ASCIIToUTF16("blah2")); 229 230 const BookmarkNode* url_node = model()->AddURL(folder, 0, title, url); 231 232 // Write the nodes to the clipboard. 233 std::vector<const BookmarkNode*> nodes; 234 nodes.push_back(folder); 235 nodes.push_back(url_node); 236 BookmarkNodeData drag_data(nodes); 237 ui::OSExchangeData data; 238 drag_data.Write(GetProfilePath(), &data); 239 240 // Read the data back in. 241 ui::OSExchangeData data2(CloneProvider(data)); 242 BookmarkNodeData read_data; 243 EXPECT_TRUE(read_data.Read(data2)); 244 EXPECT_TRUE(read_data.is_valid()); 245 ASSERT_EQ(2u, read_data.elements.size()); 246 ASSERT_EQ(1u, read_data.elements[0].children.size()); 247 EXPECT_TRUE(read_data.elements[0].date_added.is_null()); 248 EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null()); 249 250 const BookmarkNodeData::Element& read_folder = read_data.elements[0]; 251 EXPECT_FALSE(read_folder.is_url); 252 EXPECT_EQ(ASCIIToUTF16("g1"), read_folder.title); 253 EXPECT_EQ(1u, read_folder.children.size()); 254 255 const BookmarkNodeData::Element& read_url = read_data.elements[1]; 256 EXPECT_TRUE(read_url.is_url); 257 EXPECT_EQ(title, read_url.title); 258 EXPECT_EQ(0u, read_url.children.size()); 259 260 // And make sure we get the node back. 261 std::vector<const BookmarkNode*> read_nodes = 262 read_data.GetNodes(model(), GetProfilePath()); 263 ASSERT_EQ(2u, read_nodes.size()); 264 EXPECT_TRUE(read_nodes[0] == folder); 265 EXPECT_TRUE(read_nodes[1] == url_node); 266 267 // Asking for the first node should return NULL with more than one element 268 // present. 269 EXPECT_TRUE(read_data.GetFirstNode(model(), GetProfilePath()) == NULL); 270 } 271 272 // Tests reading/writing of meta info. 273 TEST_F(BookmarkNodeDataTest, MetaInfo) { 274 // Create a node containing meta info. 275 const BookmarkNode* node = model()->AddURL(model()->other_node(), 276 0, 277 ASCIIToUTF16("foo bar"), 278 GURL("http://www.google.com")); 279 model()->SetNodeMetaInfo(node, "somekey", "somevalue"); 280 model()->SetNodeMetaInfo(node, "someotherkey", "someothervalue"); 281 282 BookmarkNodeData node_data(node); 283 ui::OSExchangeData data; 284 node_data.Write(GetProfilePath(), &data); 285 286 // Read the data back in. 287 ui::OSExchangeData data2(CloneProvider(data)); 288 BookmarkNodeData read_data; 289 EXPECT_TRUE(read_data.Read(data2)); 290 EXPECT_TRUE(read_data.is_valid()); 291 ASSERT_EQ(1u, read_data.elements.size()); 292 293 // Verify that the read data contains the same meta info. 294 BookmarkNode::MetaInfoMap meta_info_map = read_data.elements[0].meta_info_map; 295 EXPECT_EQ(2u, meta_info_map.size()); 296 EXPECT_EQ("somevalue", meta_info_map["somekey"]); 297 EXPECT_EQ("someothervalue", meta_info_map["someotherkey"]); 298 } 299 300 } // namespace bookmarks 301