OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/ui/gtk/bookmarks/bookmark_editor_gtk.h" | |
6 | |
7 #include <gtk/gtk.h> | |
8 | |
9 #include <string> | |
10 | |
11 #include "base/compiler_specific.h" | |
12 #include "base/message_loop/message_loop.h" | |
13 #include "base/strings/string_util.h" | |
14 #include "base/strings/utf_string_conversions.h" | |
15 #include "chrome/browser/bookmarks/bookmark_model.h" | |
16 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | |
17 #include "chrome/browser/bookmarks/bookmark_test_helpers.h" | |
18 #include "chrome/browser/ui/gtk/bookmarks/bookmark_tree_model.h" | |
19 #include "chrome/test/base/testing_profile.h" | |
20 #include "content/public/test/test_browser_thread.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 using base::ASCIIToUTF16; | |
24 using base::UTF16ToUTF8; | |
25 using base::Time; | |
26 using base::TimeDelta; | |
27 using content::BrowserThread; | |
28 | |
29 // Base class for bookmark editor tests. This class is a copy from | |
30 // bookmark_editor_view_unittest.cc, and all the tests in this file are | |
31 // GTK-ifications of the corresponding views tests. Testing here is really | |
32 // important because on Linux, we make round trip copies from chrome's | |
33 // BookmarkModel class to GTK's native GtkTreeStore. | |
34 class BookmarkEditorGtkTest : public testing::Test { | |
35 public: | |
36 BookmarkEditorGtkTest() | |
37 : model_(NULL), | |
38 ui_thread_(BrowserThread::UI, &message_loop_), | |
39 file_thread_(BrowserThread::FILE, &message_loop_) { | |
40 } | |
41 | |
42 virtual void SetUp() OVERRIDE { | |
43 profile_.reset(new TestingProfile()); | |
44 profile_->CreateBookmarkModel(true); | |
45 | |
46 model_ = BookmarkModelFactory::GetForProfile(profile_.get()); | |
47 test::WaitForBookmarkModelToLoad(model_); | |
48 | |
49 AddTestData(); | |
50 } | |
51 | |
52 virtual void TearDown() OVERRIDE { | |
53 } | |
54 | |
55 protected: | |
56 std::string base_path() const { return "file:///c:/tmp/"; } | |
57 | |
58 const BookmarkNode* GetNode(const std::string& name) { | |
59 return model_->GetMostRecentlyAddedNodeForURL(GURL(base_path() + name)); | |
60 } | |
61 | |
62 BookmarkModel* model_; | |
63 scoped_ptr<TestingProfile> profile_; | |
64 | |
65 private: | |
66 // Creates the following structure: | |
67 // bookmark bar node | |
68 // a | |
69 // F1 | |
70 // f1a | |
71 // F11 | |
72 // f11a | |
73 // F2 | |
74 // other node | |
75 // oa | |
76 // OF1 | |
77 // of1a | |
78 // mobile node | |
79 // sa | |
80 void AddTestData() { | |
81 std::string test_base = base_path(); | |
82 | |
83 model_->AddURL(model_->bookmark_bar_node(), 0, ASCIIToUTF16("a"), | |
84 GURL(test_base + "a")); | |
85 const BookmarkNode* f1 = | |
86 model_->AddFolder(model_->bookmark_bar_node(), 1, ASCIIToUTF16("F1")); | |
87 model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a")); | |
88 const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11")); | |
89 model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a")); | |
90 model_->AddFolder(model_->bookmark_bar_node(), 2, ASCIIToUTF16("F2")); | |
91 | |
92 // Children of the other node. | |
93 model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"), | |
94 GURL(test_base + "oa")); | |
95 const BookmarkNode* of1 = | |
96 model_->AddFolder(model_->other_node(), 1, ASCIIToUTF16("OF1")); | |
97 model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a")); | |
98 | |
99 // Children of the mobile node. | |
100 model_->AddURL(model_->mobile_node(), 0, ASCIIToUTF16("sa"), | |
101 GURL(test_base + "sa")); | |
102 } | |
103 | |
104 base::MessageLoopForUI message_loop_; | |
105 content::TestBrowserThread ui_thread_; | |
106 content::TestBrowserThread file_thread_; | |
107 }; | |
108 | |
109 // Makes sure the tree model matches that of the bookmark bar model. | |
110 TEST_F(BookmarkEditorGtkTest, ModelsMatch) { | |
111 BookmarkEditorGtk editor( | |
112 NULL, | |
113 profile_.get(), | |
114 NULL, | |
115 BookmarkEditor::EditDetails::AddNodeInFolder( | |
116 NULL, -1, GURL(), base::string16()), | |
117 BookmarkEditor::SHOW_TREE); | |
118 | |
119 // The root should have two or three children, one for the bookmark bar node, | |
120 // another for the 'other bookmarks' folder, and depending on the visib | |
121 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
122 GtkTreeIter toplevel; | |
123 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, &toplevel)); | |
124 GtkTreeIter bookmark_bar_node = toplevel; | |
125 ASSERT_TRUE(gtk_tree_model_iter_next(store, &toplevel)); | |
126 GtkTreeIter other_node = toplevel; | |
127 if (model_->mobile_node()->IsVisible()) { | |
128 // If we have a mobile node, then the iterator should find one element after | |
129 // "other bookmarks" | |
130 ASSERT_TRUE(gtk_tree_model_iter_next(store, &toplevel)); | |
131 ASSERT_FALSE(gtk_tree_model_iter_next(store, &toplevel)); | |
132 } else { | |
133 ASSERT_FALSE(gtk_tree_model_iter_next(store, &toplevel)); | |
134 } | |
135 | |
136 // The bookmark bar should have 2 nodes: folder F1 and F2. | |
137 GtkTreeIter f1_iter; | |
138 GtkTreeIter child; | |
139 ASSERT_EQ(2, gtk_tree_model_iter_n_children(store, &bookmark_bar_node)); | |
140 ASSERT_TRUE(gtk_tree_model_iter_children(store, &child, &bookmark_bar_node)); | |
141 f1_iter = child; | |
142 ASSERT_EQ("F1", UTF16ToUTF8(GetTitleFromTreeIter(store, &child))); | |
143 ASSERT_TRUE(gtk_tree_model_iter_next(store, &child)); | |
144 ASSERT_EQ("F2", UTF16ToUTF8(GetTitleFromTreeIter(store, &child))); | |
145 ASSERT_FALSE(gtk_tree_model_iter_next(store, &child)); | |
146 | |
147 // F1 should have one child, F11 | |
148 ASSERT_EQ(1, gtk_tree_model_iter_n_children(store, &f1_iter)); | |
149 ASSERT_TRUE(gtk_tree_model_iter_children(store, &child, &f1_iter)); | |
150 ASSERT_EQ("F11", UTF16ToUTF8(GetTitleFromTreeIter(store, &child))); | |
151 ASSERT_FALSE(gtk_tree_model_iter_next(store, &child)); | |
152 | |
153 // Other node should have one child (OF1). | |
154 ASSERT_EQ(1, gtk_tree_model_iter_n_children(store, &other_node)); | |
155 ASSERT_TRUE(gtk_tree_model_iter_children(store, &child, &other_node)); | |
156 ASSERT_EQ("OF1", UTF16ToUTF8(GetTitleFromTreeIter(store, &child))); | |
157 ASSERT_FALSE(gtk_tree_model_iter_next(store, &child)); | |
158 } | |
159 | |
160 // Changes the title and makes sure parent/visual order doesn't change. | |
161 TEST_F(BookmarkEditorGtkTest, EditTitleKeepsPosition) { | |
162 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
163 BookmarkEditor::EditDetails::EditNode(GetNode("a")), | |
164 BookmarkEditor::SHOW_TREE); | |
165 gtk_entry_set_text(GTK_ENTRY(editor.name_entry_), "new_a"); | |
166 | |
167 GtkTreeIter bookmark_bar_node; | |
168 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
169 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, &bookmark_bar_node)); | |
170 editor.ApplyEdits(&bookmark_bar_node); | |
171 | |
172 const BookmarkNode* bb_node = model_->bookmark_bar_node(); | |
173 ASSERT_EQ(ASCIIToUTF16("new_a"), bb_node->GetChild(0)->GetTitle()); | |
174 // The URL shouldn't have changed. | |
175 ASSERT_TRUE(GURL(base_path() + "a") == bb_node->GetChild(0)->url()); | |
176 } | |
177 | |
178 // Changes the url and makes sure parent/visual order doesn't change. | |
179 TEST_F(BookmarkEditorGtkTest, EditURLKeepsPosition) { | |
180 Time node_time = GetNode("a")->date_added(); | |
181 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
182 BookmarkEditor::EditDetails::EditNode(GetNode("a")), | |
183 BookmarkEditor::SHOW_TREE); | |
184 gtk_entry_set_text(GTK_ENTRY(editor.url_entry_), | |
185 GURL(base_path() + "new_a").spec().c_str()); | |
186 | |
187 GtkTreeIter bookmark_bar_node; | |
188 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
189 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, &bookmark_bar_node)); | |
190 editor.ApplyEdits(&bookmark_bar_node); | |
191 | |
192 const BookmarkNode* bb_node = model_->bookmark_bar_node(); | |
193 ASSERT_EQ(ASCIIToUTF16("a"), bb_node->GetChild(0)->GetTitle()); | |
194 // The URL should have changed. | |
195 ASSERT_TRUE(GURL(base_path() + "new_a") == bb_node->GetChild(0)->url()); | |
196 ASSERT_TRUE(node_time == bb_node->GetChild(0)->date_added()); | |
197 } | |
198 | |
199 // Moves 'a' to be a child of the other node. | |
200 TEST_F(BookmarkEditorGtkTest, ChangeParent) { | |
201 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
202 BookmarkEditor::EditDetails::EditNode(GetNode("a")), | |
203 BookmarkEditor::SHOW_TREE); | |
204 | |
205 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
206 GtkTreeIter gtk_other_node; | |
207 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, >k_other_node)); | |
208 ASSERT_TRUE(gtk_tree_model_iter_next(store, >k_other_node)); | |
209 editor.ApplyEdits(>k_other_node); | |
210 | |
211 const BookmarkNode* other_node = model_->other_node(); | |
212 ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle()); | |
213 ASSERT_TRUE(GURL(base_path() + "a") == other_node->GetChild(2)->url()); | |
214 } | |
215 | |
216 // Moves 'a' to be a child of the other node. | |
217 // Moves 'a' to be a child of the other node and changes its url to new_a. | |
218 TEST_F(BookmarkEditorGtkTest, ChangeParentAndURL) { | |
219 Time node_time = GetNode("a")->date_added(); | |
220 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
221 BookmarkEditor::EditDetails::EditNode(GetNode("a")), | |
222 BookmarkEditor::SHOW_TREE); | |
223 | |
224 gtk_entry_set_text(GTK_ENTRY(editor.url_entry_), | |
225 GURL(base_path() + "new_a").spec().c_str()); | |
226 | |
227 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
228 GtkTreeIter gtk_other_node; | |
229 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, >k_other_node)); | |
230 ASSERT_TRUE(gtk_tree_model_iter_next(store, >k_other_node)); | |
231 editor.ApplyEdits(>k_other_node); | |
232 | |
233 const BookmarkNode* other_node = model_->other_node(); | |
234 ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle()); | |
235 ASSERT_TRUE(GURL(base_path() + "new_a") == other_node->GetChild(2)->url()); | |
236 ASSERT_TRUE(node_time == other_node->GetChild(2)->date_added()); | |
237 } | |
238 | |
239 // Creates a new folder and moves a node to it. | |
240 TEST_F(BookmarkEditorGtkTest, MoveToNewParent) { | |
241 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
242 BookmarkEditor::EditDetails::EditNode(GetNode("a")), | |
243 BookmarkEditor::SHOW_TREE); | |
244 | |
245 GtkTreeIter bookmark_bar_node; | |
246 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
247 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, &bookmark_bar_node)); | |
248 | |
249 // The bookmark bar should have 2 nodes: folder F1 and F2. | |
250 GtkTreeIter f2_iter; | |
251 ASSERT_EQ(2, gtk_tree_model_iter_n_children(store, &bookmark_bar_node)); | |
252 ASSERT_TRUE(gtk_tree_model_iter_children(store, &f2_iter, | |
253 &bookmark_bar_node)); | |
254 ASSERT_TRUE(gtk_tree_model_iter_next(store, &f2_iter)); | |
255 | |
256 // Create two nodes: "F21" as a child of "F2" and "F211" as a child of "F21". | |
257 GtkTreeIter f21_iter; | |
258 editor.AddNewFolder(&f2_iter, &f21_iter); | |
259 gtk_tree_store_set(editor.tree_store_, &f21_iter, FOLDER_NAME, "F21", -1); | |
260 GtkTreeIter f211_iter; | |
261 editor.AddNewFolder(&f21_iter, &f211_iter); | |
262 gtk_tree_store_set(editor.tree_store_, &f211_iter, FOLDER_NAME, "F211", -1); | |
263 | |
264 ASSERT_EQ(1, gtk_tree_model_iter_n_children(store, &f2_iter)); | |
265 | |
266 editor.ApplyEdits(&f2_iter); | |
267 | |
268 const BookmarkNode* bb_node = model_->bookmark_bar_node(); | |
269 const BookmarkNode* mf2 = bb_node->GetChild(1); | |
270 | |
271 // F2 in the model should have two children now: F21 and the node edited. | |
272 ASSERT_EQ(2, mf2->child_count()); | |
273 // F21 should be first. | |
274 ASSERT_EQ(ASCIIToUTF16("F21"), mf2->GetChild(0)->GetTitle()); | |
275 // Then a. | |
276 ASSERT_EQ(ASCIIToUTF16("a"), mf2->GetChild(1)->GetTitle()); | |
277 | |
278 // F21 should have one child, F211. | |
279 const BookmarkNode* mf21 = mf2->GetChild(0); | |
280 ASSERT_EQ(1, mf21->child_count()); | |
281 ASSERT_EQ(ASCIIToUTF16("F211"), mf21->GetChild(0)->GetTitle()); | |
282 } | |
283 | |
284 // Brings up the editor, creating a new URL on the bookmark bar. | |
285 TEST_F(BookmarkEditorGtkTest, NewURL) { | |
286 BookmarkEditorGtk editor( | |
287 NULL, | |
288 profile_.get(), | |
289 NULL, | |
290 BookmarkEditor::EditDetails::AddNodeInFolder( | |
291 NULL, -1, GURL(), base::string16()), | |
292 BookmarkEditor::SHOW_TREE); | |
293 | |
294 gtk_entry_set_text(GTK_ENTRY(editor.url_entry_), | |
295 GURL(base_path() + "a").spec().c_str()); | |
296 gtk_entry_set_text(GTK_ENTRY(editor.name_entry_), "new_a"); | |
297 | |
298 GtkTreeIter bookmark_bar_node; | |
299 GtkTreeModel* store = GTK_TREE_MODEL(editor.tree_store_); | |
300 ASSERT_TRUE(gtk_tree_model_get_iter_first(store, &bookmark_bar_node)); | |
301 editor.ApplyEdits(&bookmark_bar_node); | |
302 | |
303 const BookmarkNode* bb_node = model_->bookmark_bar_node(); | |
304 ASSERT_EQ(4, bb_node->child_count()); | |
305 | |
306 const BookmarkNode* new_node = bb_node->GetChild(3); | |
307 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); | |
308 EXPECT_TRUE(GURL(base_path() + "a") == new_node->url()); | |
309 } | |
310 | |
311 // Brings up the editor with no tree and modifies the url. | |
312 TEST_F(BookmarkEditorGtkTest, ChangeURLNoTree) { | |
313 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
314 BookmarkEditor::EditDetails::EditNode( | |
315 model_->other_node()->GetChild(0)), | |
316 BookmarkEditor::NO_TREE); | |
317 | |
318 gtk_entry_set_text(GTK_ENTRY(editor.url_entry_), | |
319 GURL(base_path() + "a").spec().c_str()); | |
320 gtk_entry_set_text(GTK_ENTRY(editor.name_entry_), "new_a"); | |
321 | |
322 editor.ApplyEdits(NULL); | |
323 | |
324 const BookmarkNode* other_node = model_->other_node(); | |
325 ASSERT_EQ(2, other_node->child_count()); | |
326 | |
327 const BookmarkNode* new_node = other_node->GetChild(0); | |
328 | |
329 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); | |
330 EXPECT_TRUE(GURL(base_path() + "a") == new_node->url()); | |
331 } | |
332 | |
333 // Brings up the editor with no tree and modifies only the title. | |
334 TEST_F(BookmarkEditorGtkTest, ChangeTitleNoTree) { | |
335 BookmarkEditorGtk editor(NULL, profile_.get(), NULL, | |
336 BookmarkEditor::EditDetails::EditNode( | |
337 model_->other_node()->GetChild(0)), | |
338 BookmarkEditor::NO_TREE); | |
339 gtk_entry_set_text(GTK_ENTRY(editor.name_entry_), "new_a"); | |
340 | |
341 editor.ApplyEdits(); | |
342 | |
343 const BookmarkNode* other_node = model_->other_node(); | |
344 ASSERT_EQ(2, other_node->child_count()); | |
345 | |
346 const BookmarkNode* new_node = other_node->GetChild(0); | |
347 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle()); | |
348 } | |
OLD | NEW |