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 "base/mac/scoped_nsobject.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
8 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
9 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h"
10 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
11 #include "chrome/test/base/testing_profile.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/platform_test.h"
15 #import "ui/events/test/cocoa_test_event_utils.h"
17 using bookmarks::BookmarkModel;
18 using bookmarks::BookmarkNode;
20 // Fake BookmarkButton delegate to get a pong on mouse entered/exited
21 @interface FakeButtonDelegate : NSObject<BookmarkButtonDelegate> {
26 int didDragToTrashCount_;
30 @implementation FakeButtonDelegate
32 - (void)fillPasteboard:(NSPasteboard*)pboard
33 forDragOfButton:(BookmarkButton*)button {
36 - (void)mouseEnteredButton:(id)buton event:(NSEvent*)event {
40 - (void)mouseExitedButton:(id)buton event:(NSEvent*)event {
44 - (BOOL)dragShouldLockBarVisibility {
48 - (NSWindow*)browserWindow {
52 - (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
53 return canDragToTrash_;
56 - (void)didDragBookmarkToTrash:(BookmarkButton*)button {
57 didDragToTrashCount_++;
60 - (void)bookmarkDragDidEnd:(BookmarkButton*)button
61 operation:(NSDragOperation)operation {
67 class BookmarkButtonTest : public CocoaProfileTest {
70 // Make sure nothing leaks
71 TEST_F(BookmarkButtonTest, Create) {
72 base::scoped_nsobject<BookmarkButton> button;
73 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
76 // Test folder and empty node queries.
77 TEST_F(BookmarkButtonTest, FolderAndEmptyOrNot) {
78 base::scoped_nsobject<BookmarkButton> button;
79 base::scoped_nsobject<BookmarkButtonCell> cell;
81 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
82 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
83 [button setCell:cell];
85 EXPECT_TRUE([button isEmpty]);
86 EXPECT_FALSE([button isFolder]);
87 EXPECT_FALSE([button bookmarkNode]);
90 cocoa_test_event_utils::LeftMouseDownAtPoint(NSMakePoint(10,10));
91 // Since this returns (does not actually begin a modal drag), success!
92 [button beginDrag:downEvent];
94 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
95 const BookmarkNode* node = model->bookmark_bar_node();
96 [cell setBookmarkNode:node];
97 EXPECT_FALSE([button isEmpty]);
98 EXPECT_TRUE([button isFolder]);
99 EXPECT_EQ([button bookmarkNode], node);
101 node = model->AddURL(node, 0, base::ASCIIToUTF16("hi mom"),
102 GURL("http://www.google.com"));
103 [cell setBookmarkNode:node];
104 EXPECT_FALSE([button isEmpty]);
105 EXPECT_FALSE([button isFolder]);
106 EXPECT_EQ([button bookmarkNode], node);
109 TEST_F(BookmarkButtonTest, MouseEnterExitRedirect) {
111 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10),
114 base::scoped_nsobject<BookmarkButton> button;
115 base::scoped_nsobject<BookmarkButtonCell> cell;
116 base::scoped_nsobject<FakeButtonDelegate> delegate(
117 [[FakeButtonDelegate alloc] init]);
118 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
119 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
120 [button setCell:cell];
121 [button setDelegate:delegate];
123 EXPECT_EQ(0, delegate.get()->entered_);
124 EXPECT_EQ(0, delegate.get()->exited_);
126 [button mouseEntered:moveEvent];
127 EXPECT_EQ(1, delegate.get()->entered_);
128 EXPECT_EQ(0, delegate.get()->exited_);
130 [button mouseExited:moveEvent];
131 [button mouseExited:moveEvent];
132 EXPECT_EQ(1, delegate.get()->entered_);
133 EXPECT_EQ(2, delegate.get()->exited_);
136 TEST_F(BookmarkButtonTest, DragToTrash) {
137 base::scoped_nsobject<BookmarkButton> button;
138 base::scoped_nsobject<BookmarkButtonCell> cell;
139 base::scoped_nsobject<FakeButtonDelegate> delegate(
140 [[FakeButtonDelegate alloc] init]);
141 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
142 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
143 [button setCell:cell];
144 [button setDelegate:delegate];
146 // Add a deletable bookmark to the button.
147 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
148 const BookmarkNode* barNode = model->bookmark_bar_node();
149 const BookmarkNode* node = model->AddURL(barNode, 0,
150 base::ASCIIToUTF16("hi mom"),
151 GURL("http://www.google.com"));
152 [cell setBookmarkNode:node];
154 // Verify that if canDragBookmarkButtonToTrash is NO then the button can't
155 // be dragged to the trash.
156 delegate.get()->canDragToTrash_ = NO;
157 NSDragOperation operation = [button draggingSourceOperationMaskForLocal:NO];
158 EXPECT_EQ(0u, operation & NSDragOperationDelete);
159 operation = [button draggingSourceOperationMaskForLocal:YES];
160 EXPECT_EQ(0u, operation & NSDragOperationDelete);
162 // Verify that if canDragBookmarkButtonToTrash is YES then the button can
163 // be dragged to the trash.
164 delegate.get()->canDragToTrash_ = YES;
165 operation = [button draggingSourceOperationMaskForLocal:NO];
166 EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
167 operation = [button draggingSourceOperationMaskForLocal:YES];
168 EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
170 // Verify that canDragBookmarkButtonToTrash is called when expected.
171 delegate.get()->canDragToTrash_ = YES;
172 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
173 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationCopy];
174 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
175 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationMove];
176 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
177 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationDelete];
178 EXPECT_EQ(1, delegate.get()->didDragToTrashCount_);