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.
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"
19 using base::ASCIIToUTF16
;
23 class BookmarkNodeDataTest
: public testing::Test
{
25 BookmarkNodeDataTest() {}
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();
35 virtual void TearDown() OVERRIDE
{
37 event_source_
.reset();
38 bool success
= profile_dir_
.Delete();
42 const base::FilePath
& GetProfilePath() const { return profile_dir_
.path(); }
44 BookmarkModel
* model() { return model_
.get(); }
47 base::ScopedTempDir profile_dir_
;
48 test::TestBookmarkClient client_
;
49 scoped_ptr
<BookmarkModel
> model_
;
50 scoped_ptr
<ui::PlatformEventSource
> event_source_
;
52 DISALLOW_COPY_AND_ASSIGN(BookmarkNodeDataTest
);
57 ui::OSExchangeData::Provider
* CloneProvider(const ui::OSExchangeData
& data
) {
58 return data
.provider().Clone();
63 // Makes sure BookmarkNodeData is initially invalid.
64 TEST_F(BookmarkNodeDataTest
, InitialState
) {
65 BookmarkNodeData data
;
66 EXPECT_FALSE(data
.is_valid());
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());
77 // Writes a URL to the clipboard and make sure BookmarkNodeData can correctly
79 TEST_F(BookmarkNodeDataTest
, JustURL
) {
80 const GURL
url("http://google.com");
81 const base::string16
title(ASCIIToUTF16("google.com"));
83 ui::OSExchangeData data
;
84 data
.SetURL(url
, title
);
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());
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
);
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
);
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()) ==
135 // Writing should also put the URL and title on the clipboard.
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
);
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"));
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
);
160 ui::OSExchangeData data
;
161 drag_data
.Write(GetProfilePath(), &data
);
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());
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
);
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()) ==
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"));
190 GURL
url(GURL("http://foo.com"));
191 const base::string16
title(ASCIIToUTF16("blah2"));
193 model()->AddURL(folder
, 0, title
, url
);
195 BookmarkNodeData
drag_data(folder
);
197 ui::OSExchangeData data
;
198 drag_data
.Write(GetProfilePath(), &data
);
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];
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
);
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
);
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"));
227 GURL
url(GURL("http://foo.com"));
228 const base::string16
title(ASCIIToUTF16("blah2"));
230 const BookmarkNode
* url_node
= model()->AddURL(folder
, 0, title
, url
);
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
);
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());
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());
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());
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
);
267 // Asking for the first node should return NULL with more than one element
269 EXPECT_TRUE(read_data
.GetFirstNode(model(), GetProfilePath()) == NULL
);
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(),
277 ASCIIToUTF16("foo bar"),
278 GURL("http://www.google.com"));
279 model()->SetNodeMetaInfo(node
, "somekey", "somevalue");
280 model()->SetNodeMetaInfo(node
, "someotherkey", "someothervalue");
282 BookmarkNodeData
node_data(node
);
283 ui::OSExchangeData data
;
284 node_data
.Write(GetProfilePath(), &data
);
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());
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"]);
300 } // namespace bookmarks