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 #import <Cocoa/Cocoa.h>
7 #include "base/strings/string16.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
12 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "components/bookmarks/browser/bookmark_model.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #import "testing/gtest_mac.h"
17 #include "testing/platform_test.h"
19 using base::ASCIIToUTF16;
21 class BookmarkEditorControllerTest : public CocoaProfileTest {
23 const BookmarkNode* default_node_;
24 const BookmarkNode* default_parent_;
25 const char* default_name_;
26 base::string16 default_title_;
27 BookmarkEditorController* controller_;
29 virtual void SetUp() OVERRIDE {
30 CocoaProfileTest::SetUp();
31 ASSERT_TRUE(profile());
33 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
34 default_parent_ = model->bookmark_bar_node();
35 default_name_ = "http://www.zim-bop-a-dee.com/";
36 default_title_ = ASCIIToUTF16("ooh title");
37 const BookmarkNode* default_node = model->AddURL(default_parent_, 0,
40 controller_ = [[BookmarkEditorController alloc]
41 initWithParentWindow:test_window()
43 parent:default_parent_
46 title:base::string16()
47 configuration:BookmarkEditor::NO_TREE];
48 [controller_ runAsModalSheet];
51 virtual void TearDown() OVERRIDE {
53 CocoaProfileTest::TearDown();
57 TEST_F(BookmarkEditorControllerTest, NoEdit) {
58 [controller_ cancel:nil];
59 ASSERT_EQ(default_parent_->child_count(), 1);
60 const BookmarkNode* child = default_parent_->GetChild(0);
61 EXPECT_EQ(child->GetTitle(), default_title_);
62 EXPECT_EQ(child->url(), GURL(default_name_));
65 TEST_F(BookmarkEditorControllerTest, EditTitle) {
66 [controller_ setDisplayName:@"whamma jamma bamma"];
68 ASSERT_EQ(default_parent_->child_count(), 1);
69 const BookmarkNode* child = default_parent_->GetChild(0);
70 EXPECT_EQ(child->GetTitle(), ASCIIToUTF16("whamma jamma bamma"));
71 EXPECT_EQ(child->url(), GURL(default_name_));
74 TEST_F(BookmarkEditorControllerTest, EditURL) {
75 EXPECT_TRUE([controller_ okButtonEnabled]);
76 [controller_ setDisplayURL:@"http://yellow-sneakers.com/"];
77 EXPECT_TRUE([controller_ okButtonEnabled]);
79 ASSERT_EQ(default_parent_->child_count(), 1);
80 const BookmarkNode* child = default_parent_->GetChild(0);
81 EXPECT_EQ(child->GetTitle(), default_title_);
82 EXPECT_EQ(child->url(), GURL("http://yellow-sneakers.com/"));
85 TEST_F(BookmarkEditorControllerTest, EditAndFixPrefix) {
86 [controller_ setDisplayURL:@"x"];
88 ASSERT_EQ(default_parent_->child_count(), 1);
89 const BookmarkNode* child = default_parent_->GetChild(0);
90 EXPECT_TRUE(child->url().is_valid());
93 TEST_F(BookmarkEditorControllerTest, NodeDeleted) {
94 // Delete the bookmark being edited and verify the sheet cancels itself:
95 ASSERT_TRUE([test_window() attachedSheet]);
96 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
97 model->Remove(default_parent_, 0);
98 ASSERT_FALSE([test_window() attachedSheet]);
101 TEST_F(BookmarkEditorControllerTest, EditAndConfirmOKButton) {
102 // Confirm OK button enabled/disabled as appropriate:
103 // First test the URL.
104 EXPECT_TRUE([controller_ okButtonEnabled]);
105 [controller_ setDisplayURL:@""];
106 EXPECT_FALSE([controller_ okButtonEnabled]);
107 [controller_ setDisplayURL:@"http://www.cnn.com"];
108 EXPECT_TRUE([controller_ okButtonEnabled]);
109 // Then test the name.
110 [controller_ setDisplayName:@""];
111 EXPECT_TRUE([controller_ okButtonEnabled]);
112 [controller_ setDisplayName:@" "];
113 EXPECT_TRUE([controller_ okButtonEnabled]);
114 // Then little mix of both.
115 [controller_ setDisplayName:@"name"];
116 EXPECT_TRUE([controller_ okButtonEnabled]);
117 [controller_ setDisplayURL:@""];
118 EXPECT_FALSE([controller_ okButtonEnabled]);
119 [controller_ cancel:nil];
122 TEST_F(BookmarkEditorControllerTest, GoodAndBadURLsChangeColor) {
123 // Confirm that the background color of the URL edit field changes
124 // based on whether it contains a valid or invalid URL.
125 [controller_ setDisplayURL:@"http://www.cnn.com"];
126 NSColor *urlColorA = [controller_ urlFieldColor];
127 EXPECT_TRUE(urlColorA);
128 [controller_ setDisplayURL:@""];
129 NSColor *urlColorB = [controller_ urlFieldColor];
130 EXPECT_TRUE(urlColorB);
131 EXPECT_NSNE(urlColorA, urlColorB);
132 [controller_ setDisplayURL:@"http://www.google.com"];
133 [controller_ cancel:nil];
134 urlColorB = [controller_ urlFieldColor];
135 EXPECT_TRUE(urlColorB);
136 EXPECT_NSEQ(urlColorA, urlColorB);
139 class BookmarkEditorControllerNoNodeTest : public CocoaProfileTest {
141 BookmarkEditorController* controller_;
143 virtual void SetUp() OVERRIDE {
144 CocoaProfileTest::SetUp();
145 ASSERT_TRUE(profile());
147 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
148 const BookmarkNode* parent = model->bookmark_bar_node();
149 controller_ = [[BookmarkEditorController alloc]
150 initWithParentWindow:test_window()
155 title:base::string16()
156 configuration:BookmarkEditor::NO_TREE];
158 [controller_ runAsModalSheet];
161 virtual void TearDown() OVERRIDE {
163 CocoaProfileTest::TearDown();
167 TEST_F(BookmarkEditorControllerNoNodeTest, NoNodeNoTree) {
168 EXPECT_NSEQ(@"", [controller_ displayName]);
169 EXPECT_EQ(nil, [controller_ displayURL]);
170 EXPECT_FALSE([controller_ okButtonEnabled]);
171 [controller_ cancel:nil];
174 class BookmarkEditorControllerYesNodeTest : public CocoaProfileTest {
176 base::string16 default_title_;
177 BookmarkEditorController* controller_;
179 virtual void SetUp() OVERRIDE {
180 CocoaProfileTest::SetUp();
181 ASSERT_TRUE(profile());
183 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
184 const BookmarkNode* parent = model->bookmark_bar_node();
185 default_title_ = ASCIIToUTF16("wooh title");
186 const BookmarkNode* node =
187 model->AddURL(parent, 0, default_title_,
188 GURL("http://www.zoom-baby-doo-da.com/"));
189 controller_ = [[BookmarkEditorController alloc]
190 initWithParentWindow:test_window()
195 title:base::string16()
196 configuration:BookmarkEditor::NO_TREE];
198 [controller_ runAsModalSheet];
201 virtual void TearDown() OVERRIDE {
203 CocoaProfileTest::TearDown();
207 TEST_F(BookmarkEditorControllerYesNodeTest, YesNodeShowTree) {
208 EXPECT_NSEQ(base::SysUTF16ToNSString(default_title_),
209 [controller_ displayName]);
210 EXPECT_NSEQ([NSString stringWithCString:"www.zoom-baby-doo-da.com"
211 encoding:NSUTF8StringEncoding],
212 [controller_ displayURL]);
213 [controller_ cancel:nil];
217 class BookmarkEditorControllerUtf8NodeTest : public CocoaProfileTest {
219 BookmarkEditorController* controller_;
221 virtual void SetUp() OVERRIDE {
222 CocoaProfileTest::SetUp();
223 ASSERT_TRUE(profile());
225 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
226 const BookmarkNode* parent = model->bookmark_bar_node();
227 base::string16 title = ASCIIToUTF16("wooh title");
228 const char* url_name = "http://www.foobar.com/心得寫作";
229 const BookmarkNode* node = model->AddURL(parent, 0, title, GURL(url_name));
230 controller_ = [[BookmarkEditorController alloc]
231 initWithParentWindow:test_window()
236 title:base::string16()
237 configuration:BookmarkEditor::NO_TREE];
239 [controller_ runAsModalSheet];
242 virtual void TearDown() OVERRIDE {
244 CocoaProfileTest::TearDown();
248 TEST_F(BookmarkEditorControllerUtf8NodeTest, DisplayUtf8Name) {
249 // The "http://" prefix is trimmed, but the UTF-8 formatted characters remain.
250 EXPECT_NSEQ([NSString stringWithCString:"www.foobar.com/心得寫作"
251 encoding:NSUTF8StringEncoding],
252 [controller_ displayURL]);
253 [controller_ cancel:nil];
256 class BookmarkEditorControllerTreeTest : public CocoaProfileTest {
259 BookmarkEditorController* controller_;
260 const BookmarkNode* folder_a_;
261 const BookmarkNode* folder_b_;
262 const BookmarkNode* folder_bb_;
263 const BookmarkNode* folder_c_;
264 const BookmarkNode* bookmark_bb_3_;
269 // Set up a small bookmark hierarchy, which will look as follows:
279 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
280 const BookmarkNode* root = model->bookmark_bar_node();
281 folder_a_ = model->AddFolder(root, 0, ASCIIToUTF16("a"));
282 model->AddURL(folder_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com"));
283 model->AddURL(folder_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com"));
284 model->AddURL(folder_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com"));
286 folder_b_ = model->AddFolder(root, 1, ASCIIToUTF16("b"));
287 model->AddURL(folder_b_, 0, ASCIIToUTF16("b-0"), GURL("http://b-0.com"));
288 folder_bb_ = model->AddFolder(folder_b_, 1, ASCIIToUTF16("bb"));
289 model->AddURL(folder_bb_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com"));
290 model->AddURL(folder_bb_, 1, ASCIIToUTF16("bb-1"), GURL("http://bb-1.com"));
291 model->AddURL(folder_bb_, 2, ASCIIToUTF16("bb-2"), GURL("http://bb-2.com"));
293 // To find it later, this bookmark name must always have a URL
294 // of http://bb-3.com or https://bb-3.com
295 bb3_url_1_ = GURL("http://bb-3.com");
296 bb3_url_2_ = GURL("https://bb-3.com");
297 bookmark_bb_3_ = model->AddURL(folder_bb_, 3, ASCIIToUTF16("bb-3"),
300 model->AddURL(folder_bb_, 4, ASCIIToUTF16("bb-4"), GURL("http://bb-4.com"));
301 model->AddURL(folder_b_, 2, ASCIIToUTF16("b-1"), GURL("http://b-2.com"));
302 model->AddURL(folder_b_, 3, ASCIIToUTF16("b-2"), GURL("http://b-3.com"));
304 folder_c_ = model->AddFolder(root, 2, ASCIIToUTF16("c"));
305 model->AddURL(folder_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com"));
306 model->AddURL(folder_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com"));
307 model->AddURL(folder_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com"));
308 model->AddURL(folder_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com"));
310 model->AddURL(root, 3, ASCIIToUTF16("d"), GURL("http://d-0.com"));
313 virtual BookmarkEditorController* CreateController() {
314 return [[BookmarkEditorController alloc]
315 initWithParentWindow:test_window()
320 title:base::string16()
321 configuration:BookmarkEditor::SHOW_TREE];
324 virtual void SetUp() OVERRIDE {
325 CocoaProfileTest::SetUp();
326 ASSERT_TRUE(profile());
329 controller_ = CreateController();
330 [controller_ runAsModalSheet];
333 virtual void TearDown() OVERRIDE {
335 CocoaProfileTest::TearDown();
338 // After changing a node, pointers to the node may be invalid. This
339 // is because the node itself may not be updated; it may removed and
340 // a new one is added in that location. (Implementation detail of
341 // BookmarkEditorController). This method updates the class's
342 // bookmark_bb_3_ so that it points to the new node for testing.
344 std::vector<const BookmarkNode*> nodes;
345 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
346 model->GetNodesByURL(bb3_url_1_, &nodes);
348 model->GetNodesByURL(bb3_url_2_, &nodes);
349 DCHECK(nodes.size());
350 bookmark_bb_3_ = nodes[0];
355 TEST_F(BookmarkEditorControllerTreeTest, VerifyBookmarkTestModel) {
356 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
358 const BookmarkNode* root = model->bookmark_bar_node();
359 EXPECT_EQ(4, root->child_count());
360 const BookmarkNode* child = root->GetChild(0);
361 EXPECT_EQ(3, child->child_count());
362 const BookmarkNode* subchild = child->GetChild(0);
363 EXPECT_EQ(0, subchild->child_count());
364 subchild = child->GetChild(1);
365 EXPECT_EQ(0, subchild->child_count());
366 subchild = child->GetChild(2);
367 EXPECT_EQ(0, subchild->child_count());
369 child = root->GetChild(1);
370 EXPECT_EQ(4, child->child_count());
371 subchild = child->GetChild(0);
372 EXPECT_EQ(0, subchild->child_count());
373 subchild = child->GetChild(1);
374 EXPECT_EQ(5, subchild->child_count());
375 const BookmarkNode* subsubchild = subchild->GetChild(0);
376 EXPECT_EQ(0, subsubchild->child_count());
377 subsubchild = subchild->GetChild(1);
378 EXPECT_EQ(0, subsubchild->child_count());
379 subsubchild = subchild->GetChild(2);
380 EXPECT_EQ(0, subsubchild->child_count());
381 subsubchild = subchild->GetChild(3);
382 EXPECT_EQ(0, subsubchild->child_count());
383 subsubchild = subchild->GetChild(4);
384 EXPECT_EQ(0, subsubchild->child_count());
385 subchild = child->GetChild(2);
386 EXPECT_EQ(0, subchild->child_count());
387 subchild = child->GetChild(3);
388 EXPECT_EQ(0, subchild->child_count());
390 child = root->GetChild(2);
391 EXPECT_EQ(4, child->child_count());
392 subchild = child->GetChild(0);
393 EXPECT_EQ(0, subchild->child_count());
394 subchild = child->GetChild(1);
395 EXPECT_EQ(0, subchild->child_count());
396 subchild = child->GetChild(2);
397 EXPECT_EQ(0, subchild->child_count());
398 subchild = child->GetChild(3);
399 EXPECT_EQ(0, subchild->child_count());
401 child = root->GetChild(3);
402 EXPECT_EQ(0, child->child_count());
403 [controller_ cancel:nil];
406 TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) {
407 const BookmarkNode* oldParent = bookmark_bb_3_->parent();
408 [controller_ setDisplayName:@"NEW NAME"];
409 [controller_ ok:nil];
411 const BookmarkNode* newParent = bookmark_bb_3_->parent();
412 ASSERT_EQ(newParent, oldParent);
413 int childIndex = newParent->GetIndexOf(bookmark_bb_3_);
414 ASSERT_EQ(3, childIndex);
417 TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkURLInPlace) {
418 const BookmarkNode* oldParent = bookmark_bb_3_->parent();
419 [controller_ setDisplayURL:@"https://bb-3.com"];
420 [controller_ ok:nil];
422 const BookmarkNode* newParent = bookmark_bb_3_->parent();
423 ASSERT_EQ(newParent, oldParent);
424 int childIndex = newParent->GetIndexOf(bookmark_bb_3_);
425 ASSERT_EQ(3, childIndex);
428 TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkFolder) {
429 [controller_ selectTestNodeInBrowser:folder_c_];
430 [controller_ ok:nil];
432 const BookmarkNode* parent = bookmark_bb_3_->parent();
433 ASSERT_EQ(parent, folder_c_);
434 int childIndex = parent->GetIndexOf(bookmark_bb_3_);
435 ASSERT_EQ(4, childIndex);
438 TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkFolder) {
439 [controller_ setDisplayName:@"NEW NAME"];
440 [controller_ selectTestNodeInBrowser:folder_c_];
441 [controller_ ok:nil];
443 const BookmarkNode* parent = bookmark_bb_3_->parent();
444 ASSERT_EQ(parent, folder_c_);
445 int childIndex = parent->GetIndexOf(bookmark_bb_3_);
446 ASSERT_EQ(4, childIndex);
447 EXPECT_EQ(bookmark_bb_3_->GetTitle(), ASCIIToUTF16("NEW NAME"));
450 TEST_F(BookmarkEditorControllerTreeTest, AddFolderWithFolderSelected) {
451 // Folders are NOT added unless the OK button is pressed.
452 [controller_ newFolder:nil];
453 [controller_ cancel:nil];
454 EXPECT_EQ(5, folder_bb_->child_count());
457 class BookmarkEditorControllerTreeNoNodeTest :
458 public BookmarkEditorControllerTreeTest {
460 virtual BookmarkEditorController* CreateController() OVERRIDE {
461 return [[BookmarkEditorController alloc]
462 initWithParentWindow:test_window()
467 title:base::string16()
468 configuration:BookmarkEditor::SHOW_TREE];
473 TEST_F(BookmarkEditorControllerTreeNoNodeTest, NewBookmarkNoNode) {
474 [controller_ setDisplayName:@"NEW BOOKMARK"];
475 [controller_ setDisplayURL:@"http://NEWURL.com"];
476 [controller_ ok:nil];
477 const BookmarkNode* new_node = folder_bb_->GetChild(5);
478 ASSERT_EQ(0, new_node->child_count());
479 EXPECT_EQ(new_node->GetTitle(), ASCIIToUTF16("NEW BOOKMARK"));
480 EXPECT_EQ(new_node->url(), GURL("http://NEWURL.com"));