1// Copyright (c) 2011 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 "base/memory/scoped_nsobject.h"
6#include "base/utf_string_conversions.h"
7#include "chrome/browser/bookmarks/bookmark_model.h"
8#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
9#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h"
10#import "chrome/browser/ui/cocoa/browser_test_helper.h"
11#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
12#import "chrome/browser/ui/cocoa/test_event_utils.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "testing/platform_test.h"
15
16// Fake BookmarkButton delegate to get a pong on mouse entered/exited
17@interface FakeButtonDelegate : NSObject<BookmarkButtonDelegate> {
18 @public
19  int entered_;
20  int exited_;
21  BOOL canDragToTrash_;
22  int didDragToTrashCount_;
23}
24@end
25
26@implementation FakeButtonDelegate
27
28- (void)fillPasteboard:(NSPasteboard*)pboard
29       forDragOfButton:(BookmarkButton*)button {
30}
31
32- (void)mouseEnteredButton:(id)buton event:(NSEvent*)event {
33  entered_++;
34}
35
36- (void)mouseExitedButton:(id)buton event:(NSEvent*)event {
37  exited_++;
38}
39
40- (BOOL)dragShouldLockBarVisibility {
41  return NO;
42}
43
44- (NSWindow*)browserWindow {
45  return nil;
46}
47
48- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
49  return canDragToTrash_;
50}
51
52- (void)didDragBookmarkToTrash:(BookmarkButton*)button {
53  didDragToTrashCount_++;
54}
55
56- (void)bookmarkDragDidEnd:(BookmarkButton*)button
57                 operation:(NSDragOperation)operation {
58}
59@end
60
61namespace {
62
63class BookmarkButtonTest : public CocoaTest {
64};
65
66// Make sure nothing leaks
67TEST_F(BookmarkButtonTest, Create) {
68  scoped_nsobject<BookmarkButton> button;
69  button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
70}
71
72// Test folder and empty node queries.
73TEST_F(BookmarkButtonTest, FolderAndEmptyOrNot) {
74  BrowserTestHelper helper_;
75  scoped_nsobject<BookmarkButton> button;
76  scoped_nsobject<BookmarkButtonCell> cell;
77
78  button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
79  cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
80  [button setCell:cell];
81
82  EXPECT_TRUE([button isEmpty]);
83  EXPECT_FALSE([button isFolder]);
84  EXPECT_FALSE([button bookmarkNode]);
85
86  NSEvent* downEvent =
87      test_event_utils::LeftMouseDownAtPoint(NSMakePoint(10,10));
88  // Since this returns (does not actually begin a modal drag), success!
89  [button beginDrag:downEvent];
90
91  BookmarkModel* model = helper_.profile()->GetBookmarkModel();
92  const BookmarkNode* node = model->GetBookmarkBarNode();
93  [cell setBookmarkNode:node];
94  EXPECT_FALSE([button isEmpty]);
95  EXPECT_TRUE([button isFolder]);
96  EXPECT_EQ([button bookmarkNode], node);
97
98  node = model->AddURL(node, 0, ASCIIToUTF16("hi mom"),
99                       GURL("http://www.google.com"));
100  [cell setBookmarkNode:node];
101  EXPECT_FALSE([button isEmpty]);
102  EXPECT_FALSE([button isFolder]);
103  EXPECT_EQ([button bookmarkNode], node);
104}
105
106TEST_F(BookmarkButtonTest, MouseEnterExitRedirect) {
107  NSEvent* moveEvent =
108      test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), NSMouseMoved, 0);
109  scoped_nsobject<BookmarkButton> button;
110  scoped_nsobject<BookmarkButtonCell> cell;
111  scoped_nsobject<FakeButtonDelegate>
112      delegate([[FakeButtonDelegate alloc] init]);
113  button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
114  cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
115  [button setCell:cell];
116  [button setDelegate:delegate];
117
118  EXPECT_EQ(0, delegate.get()->entered_);
119  EXPECT_EQ(0, delegate.get()->exited_);
120
121  [button mouseEntered:moveEvent];
122  EXPECT_EQ(1, delegate.get()->entered_);
123  EXPECT_EQ(0, delegate.get()->exited_);
124
125  [button mouseExited:moveEvent];
126  [button mouseExited:moveEvent];
127  EXPECT_EQ(1, delegate.get()->entered_);
128  EXPECT_EQ(2, delegate.get()->exited_);
129}
130
131TEST_F(BookmarkButtonTest, DragToTrash) {
132  BrowserTestHelper helper_;
133
134  scoped_nsobject<BookmarkButton> button;
135  scoped_nsobject<BookmarkButtonCell> cell;
136  scoped_nsobject<FakeButtonDelegate>
137      delegate([[FakeButtonDelegate alloc] init]);
138  button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
139  cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
140  [button setCell:cell];
141  [button setDelegate:delegate];
142
143  // Add a deletable bookmark to the button.
144  BookmarkModel* model = helper_.profile()->GetBookmarkModel();
145  const BookmarkNode* barNode = model->GetBookmarkBarNode();
146  const BookmarkNode* node = model->AddURL(barNode, 0, ASCIIToUTF16("hi mom"),
147                                           GURL("http://www.google.com"));
148  [cell setBookmarkNode:node];
149
150  // Verify that if canDragBookmarkButtonToTrash is NO then the button can't
151  // be dragged to the trash.
152  delegate.get()->canDragToTrash_ = NO;
153  NSDragOperation operation = [button draggingSourceOperationMaskForLocal:NO];
154  EXPECT_EQ(0u, operation & NSDragOperationDelete);
155  operation = [button draggingSourceOperationMaskForLocal:YES];
156  EXPECT_EQ(0u, operation & NSDragOperationDelete);
157
158  // Verify that if canDragBookmarkButtonToTrash is YES then the button can
159  // be dragged to the trash.
160  delegate.get()->canDragToTrash_ = YES;
161  operation = [button draggingSourceOperationMaskForLocal:NO];
162  EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
163  operation = [button draggingSourceOperationMaskForLocal:YES];
164  EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
165
166  // Verify that canDragBookmarkButtonToTrash is called when expected.
167  delegate.get()->canDragToTrash_ = YES;
168  EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
169  [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationCopy];
170  EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
171  [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationMove];
172  EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
173  [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationDelete];
174  EXPECT_EQ(1, delegate.get()->didDragToTrashCount_);
175}
176
177}
178