Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / bookmarks / bookmark_editor_view_unittest.cc
blobb53eaacaf792c85b25b65c2e2e3ef62680a03442
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/browser/ui/views/bookmarks/bookmark_editor_view.h"
7 #include <string>
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/bookmarks/bookmark_model.h"
13 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
14 #include "chrome/browser/bookmarks/bookmark_test_helpers.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/views/controls/textfield/textfield.h"
20 #include "ui/views/controls/tree/tree_view.h"
22 using base::ASCIIToUTF16;
23 using base::Time;
24 using base::TimeDelta;
25 using content::BrowserThread;
27 // Base class for bookmark editor tests. Creates a BookmarkModel and populates
28 // it with test data.
29 class BookmarkEditorViewTest : public testing::Test {
30 public:
31 BookmarkEditorViewTest()
32 : ui_thread_(BrowserThread::UI, &message_loop_),
33 file_thread_(BrowserThread::FILE, &message_loop_),
34 model_(NULL) {
37 virtual void SetUp() {
38 profile_.reset(new TestingProfile());
39 profile_->CreateBookmarkModel(true);
41 model_ = BookmarkModelFactory::GetForProfile(profile_.get());
42 test::WaitForBookmarkModelToLoad(model_);
44 AddTestData();
47 virtual void TearDown() {
50 protected:
51 std::string base_path() const { return "file:///c:/tmp/"; }
53 const BookmarkNode* GetNode(const std::string& name) {
54 return model_->GetMostRecentlyAddedNodeForURL(GURL(base_path() + name));
57 BookmarkNode* GetMutableNode(const std::string& name) {
58 return const_cast<BookmarkNode*>(GetNode(name));
61 BookmarkEditorView::EditorTreeModel* editor_tree_model() {
62 return editor_->tree_model_.get();
65 void CreateEditor(Profile* profile,
66 const BookmarkNode* parent,
67 const BookmarkEditor::EditDetails& details,
68 BookmarkEditor::Configuration configuration) {
69 editor_.reset(new BookmarkEditorView(profile, parent, details,
70 configuration));
73 void SetTitleText(const base::string16& title) {
74 editor_->title_tf_->SetText(title);
77 void SetURLText(const base::string16& text) {
78 if (editor_->details_.type != BookmarkEditor::EditDetails::NEW_FOLDER)
79 editor_->url_tf_->SetText(text);
82 void ApplyEdits() {
83 editor_->ApplyEdits();
86 void ApplyEdits(BookmarkEditorView::EditorNode* node) {
87 editor_->ApplyEdits(node);
90 BookmarkEditorView::EditorNode* AddNewFolder(
91 BookmarkEditorView::EditorNode* parent) {
92 return editor_->AddNewFolder(parent);
95 void NewFolder() {
96 return editor_->NewFolder();
99 bool URLTFHasParent() {
100 if (editor_->details_.type == BookmarkEditor::EditDetails::NEW_FOLDER)
101 return false;
102 return editor_->url_tf_->parent();
105 void ExpandAndSelect() {
106 editor_->ExpandAndSelect();
109 views::TreeView* tree_view() { return editor_->tree_view_; }
111 base::MessageLoopForUI message_loop_;
112 content::TestBrowserThread ui_thread_;
113 content::TestBrowserThread file_thread_;
115 BookmarkModel* model_;
116 scoped_ptr<TestingProfile> profile_;
118 private:
119 // Creates the following structure:
120 // bookmark bar node
121 // a
122 // F1
123 // f1a
124 // F11
125 // f11a
126 // F2
127 // other node
128 // oa
129 // OF1
130 // of1a
131 void AddTestData() {
132 const BookmarkNode* bb_node = model_->bookmark_bar_node();
133 std::string test_base = base_path();
134 model_->AddURL(bb_node, 0, ASCIIToUTF16("a"), GURL(test_base + "a"));
135 const BookmarkNode* f1 = model_->AddFolder(bb_node, 1, ASCIIToUTF16("F1"));
136 model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
137 const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11"));
138 model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
139 model_->AddFolder(bb_node, 2, ASCIIToUTF16("F2"));
141 // Children of the other node.
142 model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"),
143 GURL(test_base + "oa"));
144 const BookmarkNode* of1 =
145 model_->AddFolder(model_->other_node(), 1, ASCIIToUTF16("OF1"));
146 model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a"));
149 scoped_ptr<BookmarkEditorView> editor_;
152 // Makes sure the tree model matches that of the bookmark bar model.
153 TEST_F(BookmarkEditorViewTest, ModelsMatch) {
154 CreateEditor(profile_.get(), NULL,
155 BookmarkEditor::EditDetails::AddNodeInFolder(
156 NULL, -1, GURL(), base::string16()),
157 BookmarkEditorView::SHOW_TREE);
158 BookmarkEditorView::EditorNode* editor_root = editor_tree_model()->GetRoot();
159 // The root should have two or three children: bookmark bar, other bookmarks
160 // and conditionally mobile bookmarks.
161 if (model_->mobile_node()->IsVisible()) {
162 ASSERT_EQ(3, editor_root->child_count());
163 } else {
164 ASSERT_EQ(2, editor_root->child_count());
167 BookmarkEditorView::EditorNode* bb_node = editor_root->GetChild(0);
168 // The root should have 2 nodes: folder F1 and F2.
169 ASSERT_EQ(2, bb_node->child_count());
170 ASSERT_EQ(ASCIIToUTF16("F1"), bb_node->GetChild(0)->GetTitle());
171 ASSERT_EQ(ASCIIToUTF16("F2"), bb_node->GetChild(1)->GetTitle());
173 // F1 should have one child, F11
174 ASSERT_EQ(1, bb_node->GetChild(0)->child_count());
175 ASSERT_EQ(ASCIIToUTF16("F11"), bb_node->GetChild(0)->GetChild(0)->GetTitle());
177 BookmarkEditorView::EditorNode* other_node = editor_root->GetChild(1);
178 // Other node should have one child (OF1).
179 ASSERT_EQ(1, other_node->child_count());
180 ASSERT_EQ(ASCIIToUTF16("OF1"), other_node->GetChild(0)->GetTitle());
183 // Changes the title and makes sure parent/visual order doesn't change.
184 TEST_F(BookmarkEditorViewTest, EditTitleKeepsPosition) {
185 CreateEditor(profile_.get(), NULL,
186 BookmarkEditor::EditDetails::EditNode(GetNode("a")),
187 BookmarkEditorView::SHOW_TREE);
188 SetTitleText(L"new_a");
190 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0));
192 const BookmarkNode* bb_node =
193 BookmarkModelFactory::GetForProfile(profile_.get())->bookmark_bar_node();
194 ASSERT_EQ(ASCIIToUTF16("new_a"), bb_node->GetChild(0)->GetTitle());
195 // The URL shouldn't have changed.
196 ASSERT_TRUE(GURL(base_path() + "a") == bb_node->GetChild(0)->url());
199 // Changes the url and makes sure parent/visual order doesn't change.
200 TEST_F(BookmarkEditorViewTest, EditURLKeepsPosition) {
201 Time node_time = Time::Now() + TimeDelta::FromDays(2);
202 GetMutableNode("a")->set_date_added(node_time);
203 CreateEditor(profile_.get(), NULL,
204 BookmarkEditor::EditDetails::EditNode(GetNode("a")),
205 BookmarkEditorView::SHOW_TREE);
207 SetURLText(base::UTF8ToWide(GURL(base_path() + "new_a").spec()));
209 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0));
211 const BookmarkNode* bb_node =
212 BookmarkModelFactory::GetForProfile(profile_.get())->bookmark_bar_node();
213 ASSERT_EQ(ASCIIToUTF16("a"), bb_node->GetChild(0)->GetTitle());
214 // The URL should have changed.
215 ASSERT_TRUE(GURL(base_path() + "new_a") == bb_node->GetChild(0)->url());
216 ASSERT_TRUE(node_time == bb_node->GetChild(0)->date_added());
219 // Moves 'a' to be a child of the other node.
220 TEST_F(BookmarkEditorViewTest, ChangeParent) {
221 CreateEditor(profile_.get(), NULL,
222 BookmarkEditor::EditDetails::EditNode(GetNode("a")),
223 BookmarkEditorView::SHOW_TREE);
225 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1));
227 const BookmarkNode* other_node =
228 BookmarkModelFactory::GetForProfile(profile_.get())->other_node();
229 ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle());
230 ASSERT_TRUE(GURL(base_path() + "a") == other_node->GetChild(2)->url());
233 // Moves 'a' to be a child of the other node and changes its url to new_a.
234 TEST_F(BookmarkEditorViewTest, ChangeParentAndURL) {
235 Time node_time = Time::Now() + TimeDelta::FromDays(2);
236 GetMutableNode("a")->set_date_added(node_time);
237 CreateEditor(profile_.get(), NULL,
238 BookmarkEditor::EditDetails::EditNode(GetNode("a")),
239 BookmarkEditorView::SHOW_TREE);
241 SetURLText(base::UTF8ToWide(GURL(base_path() + "new_a").spec()));
243 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1));
245 const BookmarkNode* other_node =
246 BookmarkModelFactory::GetForProfile(profile_.get())->other_node();
247 ASSERT_EQ(ASCIIToUTF16("a"), other_node->GetChild(2)->GetTitle());
248 ASSERT_TRUE(GURL(base_path() + "new_a") == other_node->GetChild(2)->url());
249 ASSERT_TRUE(node_time == other_node->GetChild(2)->date_added());
252 // Creates a new folder and moves a node to it.
253 TEST_F(BookmarkEditorViewTest, MoveToNewParent) {
254 CreateEditor(profile_.get(), NULL,
255 BookmarkEditor::EditDetails::EditNode(GetNode("a")),
256 BookmarkEditorView::SHOW_TREE);
258 // Create two nodes: "F21" as a child of "F2" and "F211" as a child of "F21".
259 BookmarkEditorView::EditorNode* f2 =
260 editor_tree_model()->GetRoot()->GetChild(0)->GetChild(1);
261 BookmarkEditorView::EditorNode* f21 = AddNewFolder(f2);
262 f21->SetTitle(ASCIIToUTF16("F21"));
263 BookmarkEditorView::EditorNode* f211 = AddNewFolder(f21);
264 f211->SetTitle(ASCIIToUTF16("F211"));
266 // Parent the node to "F21".
267 ApplyEdits(f2);
269 const BookmarkNode* bb_node =
270 BookmarkModelFactory::GetForProfile(profile_.get())->bookmark_bar_node();
271 const BookmarkNode* mf2 = bb_node->GetChild(1);
273 // F2 in the model should have two children now: F21 and the node edited.
274 ASSERT_EQ(2, mf2->child_count());
275 // F21 should be first.
276 ASSERT_EQ(ASCIIToUTF16("F21"), mf2->GetChild(0)->GetTitle());
277 // Then a.
278 ASSERT_EQ(ASCIIToUTF16("a"), mf2->GetChild(1)->GetTitle());
280 // F21 should have one child, F211.
281 const BookmarkNode* mf21 = mf2->GetChild(0);
282 ASSERT_EQ(1, mf21->child_count());
283 ASSERT_EQ(ASCIIToUTF16("F211"), mf21->GetChild(0)->GetTitle());
286 // Brings up the editor, creating a new URL on the bookmark bar.
287 TEST_F(BookmarkEditorViewTest, NewURL) {
288 const BookmarkNode* bb_node =
289 BookmarkModelFactory::GetForProfile(profile_.get())->bookmark_bar_node();
291 CreateEditor(profile_.get(), bb_node,
292 BookmarkEditor::EditDetails::AddNodeInFolder(
293 bb_node, 1, GURL(), base::string16()),
294 BookmarkEditorView::SHOW_TREE);
296 SetURLText(base::UTF8ToWide(GURL(base_path() + "a").spec()));
297 SetTitleText(L"new_a");
299 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0));
301 ASSERT_EQ(4, bb_node->child_count());
303 const BookmarkNode* new_node = bb_node->GetChild(1);
305 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle());
306 EXPECT_TRUE(GURL(base_path() + "a") == new_node->url());
309 // Brings up the editor with no tree and modifies the url.
310 TEST_F(BookmarkEditorViewTest, ChangeURLNoTree) {
311 CreateEditor(profile_.get(), NULL,
312 BookmarkEditor::EditDetails::EditNode(
313 model_->other_node()->GetChild(0)),
314 BookmarkEditorView::NO_TREE);
316 SetURLText(base::UTF8ToWide(GURL(base_path() + "a").spec()));
317 SetTitleText(L"new_a");
319 ApplyEdits(NULL);
321 const BookmarkNode* other_node =
322 BookmarkModelFactory::GetForProfile(profile_.get())->other_node();
323 ASSERT_EQ(2, other_node->child_count());
325 const BookmarkNode* new_node = other_node->GetChild(0);
327 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle());
328 EXPECT_TRUE(GURL(base_path() + "a") == new_node->url());
331 // Brings up the editor with no tree and modifies only the title.
332 TEST_F(BookmarkEditorViewTest, ChangeTitleNoTree) {
333 CreateEditor(profile_.get(), NULL,
334 BookmarkEditor::EditDetails::EditNode(
335 model_->other_node()->GetChild(0)),
336 BookmarkEditorView::NO_TREE);
338 SetTitleText(L"new_a");
340 ApplyEdits(NULL);
342 const BookmarkNode* other_node =
343 BookmarkModelFactory::GetForProfile(profile_.get())->other_node();
344 ASSERT_EQ(2, other_node->child_count());
346 const BookmarkNode* new_node = other_node->GetChild(0);
348 EXPECT_EQ(ASCIIToUTF16("new_a"), new_node->GetTitle());
351 // Creates a new folder.
352 TEST_F(BookmarkEditorViewTest, NewFolder) {
353 const BookmarkNode* bb_node = model_->bookmark_bar_node();
354 BookmarkEditor::EditDetails details =
355 BookmarkEditor::EditDetails::AddFolder(bb_node, 1);
356 details.urls.push_back(std::make_pair(GURL(base_path() + "x"),
357 ASCIIToUTF16("z")));
358 CreateEditor(profile_.get(), bb_node, details, BookmarkEditorView::SHOW_TREE);
360 // The url field shouldn't be visible.
361 EXPECT_FALSE(URLTFHasParent());
362 SetTitleText(L"new_F");
364 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0));
366 // Make sure the folder was created.
367 ASSERT_EQ(4, bb_node->child_count());
368 const BookmarkNode* new_node = bb_node->GetChild(1);
369 EXPECT_EQ(BookmarkNode::FOLDER, new_node->type());
370 EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle());
371 // The node should have one child.
372 ASSERT_EQ(1, new_node->child_count());
373 const BookmarkNode* new_child = new_node->GetChild(0);
374 // Make sure the child url/title match.
375 EXPECT_EQ(BookmarkNode::URL, new_child->type());
376 EXPECT_EQ(details.urls[0].second, new_child->GetTitle());
377 EXPECT_EQ(details.urls[0].first, new_child->url());
380 // Creates a new folder and selects a different folder for the folder to appear
381 // in then the editor is initially created showing.
382 TEST_F(BookmarkEditorViewTest, MoveFolder) {
383 BookmarkEditor::EditDetails details = BookmarkEditor::EditDetails::AddFolder(
384 model_->bookmark_bar_node(), -1);
385 details.urls.push_back(std::make_pair(GURL(base_path() + "x"),
386 ASCIIToUTF16("z")));
387 CreateEditor(profile_.get(), model_->bookmark_bar_node(),
388 details, BookmarkEditorView::SHOW_TREE);
390 SetTitleText(L"new_F");
392 // Create the folder in the 'other' folder.
393 ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1));
395 // Make sure the folder we edited is still there.
396 ASSERT_EQ(3, model_->other_node()->child_count());
397 const BookmarkNode* new_node = model_->other_node()->GetChild(2);
398 EXPECT_EQ(BookmarkNode::FOLDER, new_node->type());
399 EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle());
400 // The node should have one child.
401 ASSERT_EQ(1, new_node->child_count());
402 const BookmarkNode* new_child = new_node->GetChild(0);
403 // Make sure the child url/title match.
404 EXPECT_EQ(BookmarkNode::URL, new_child->type());
405 EXPECT_EQ(details.urls[0].second, new_child->GetTitle());
406 EXPECT_EQ(details.urls[0].first, new_child->url());
409 // Verifies the title of a new folder is updated correctly if ApplyEdits() is
410 // is invoked while focus is still on the text field.
411 TEST_F(BookmarkEditorViewTest, NewFolderTitleUpdatedOnCommit) {
412 const BookmarkNode* parent =
413 BookmarkModelFactory::GetForProfile(profile_.get())->
414 bookmark_bar_node() ->GetChild(2);
416 CreateEditor(profile_.get(), parent,
417 BookmarkEditor::EditDetails::AddNodeInFolder(
418 parent, 1, GURL(), base::string16()),
419 BookmarkEditorView::SHOW_TREE);
420 ExpandAndSelect();
422 SetURLText(base::UTF8ToWide(GURL(base_path() + "a").spec()));
423 SetTitleText(L"new_a");
425 NewFolder();
426 ASSERT_TRUE(tree_view()->editor() != NULL);
427 tree_view()->editor()->SetText(ASCIIToUTF16("modified"));
428 ApplyEdits();
430 // Verify the new folder was added and title set appropriately.
431 ASSERT_EQ(1, parent->child_count());
432 const BookmarkNode* new_folder = parent->GetChild(0);
433 ASSERT_TRUE(new_folder->is_folder());
434 EXPECT_EQ("modified", UTF16ToASCII(new_folder->GetTitle()));