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 "base/mac/scoped_nsobject.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "chrome/browser/bookmarks/bookmark_model.h" 8 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 9 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" 10 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" 11 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/platform_test.h" 14 #import "ui/base/test/cocoa_test_event_utils.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 61 namespace { 62 63 class BookmarkButtonTest : public CocoaProfileTest { 64 }; 65 66 // Make sure nothing leaks 67 TEST_F(BookmarkButtonTest, Create) { 68 base::scoped_nsobject<BookmarkButton> button; 69 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 70 } 71 72 // Test folder and empty node queries. 73 TEST_F(BookmarkButtonTest, FolderAndEmptyOrNot) { 74 base::scoped_nsobject<BookmarkButton> button; 75 base::scoped_nsobject<BookmarkButtonCell> cell; 76 77 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 78 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); 79 [button setCell:cell]; 80 81 EXPECT_TRUE([button isEmpty]); 82 EXPECT_FALSE([button isFolder]); 83 EXPECT_FALSE([button bookmarkNode]); 84 85 NSEvent* downEvent = 86 cocoa_test_event_utils::LeftMouseDownAtPoint(NSMakePoint(10,10)); 87 // Since this returns (does not actually begin a modal drag), success! 88 [button beginDrag:downEvent]; 89 90 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile()); 91 const BookmarkNode* node = model->bookmark_bar_node(); 92 [cell setBookmarkNode:node]; 93 EXPECT_FALSE([button isEmpty]); 94 EXPECT_TRUE([button isFolder]); 95 EXPECT_EQ([button bookmarkNode], node); 96 97 node = model->AddURL(node, 0, ASCIIToUTF16("hi mom"), 98 GURL("http://www.google.com")); 99 [cell setBookmarkNode:node]; 100 EXPECT_FALSE([button isEmpty]); 101 EXPECT_FALSE([button isFolder]); 102 EXPECT_EQ([button bookmarkNode], node); 103 } 104 105 TEST_F(BookmarkButtonTest, MouseEnterExitRedirect) { 106 NSEvent* moveEvent = 107 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 108 NSMouseMoved, 109 0); 110 base::scoped_nsobject<BookmarkButton> button; 111 base::scoped_nsobject<BookmarkButtonCell> cell; 112 base::scoped_nsobject<FakeButtonDelegate> delegate( 113 [[FakeButtonDelegate alloc] init]); 114 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 115 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); 116 [button setCell:cell]; 117 [button setDelegate:delegate]; 118 119 EXPECT_EQ(0, delegate.get()->entered_); 120 EXPECT_EQ(0, delegate.get()->exited_); 121 122 [button mouseEntered:moveEvent]; 123 EXPECT_EQ(1, delegate.get()->entered_); 124 EXPECT_EQ(0, delegate.get()->exited_); 125 126 [button mouseExited:moveEvent]; 127 [button mouseExited:moveEvent]; 128 EXPECT_EQ(1, delegate.get()->entered_); 129 EXPECT_EQ(2, delegate.get()->exited_); 130 } 131 132 TEST_F(BookmarkButtonTest, DragToTrash) { 133 base::scoped_nsobject<BookmarkButton> button; 134 base::scoped_nsobject<BookmarkButtonCell> cell; 135 base::scoped_nsobject<FakeButtonDelegate> delegate( 136 [[FakeButtonDelegate alloc] init]); 137 button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 138 cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); 139 [button setCell:cell]; 140 [button setDelegate:delegate]; 141 142 // Add a deletable bookmark to the button. 143 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile()); 144 const BookmarkNode* barNode = model->bookmark_bar_node(); 145 const BookmarkNode* node = model->AddURL(barNode, 0, ASCIIToUTF16("hi mom"), 146 GURL("http://www.google.com")); 147 [cell setBookmarkNode:node]; 148 149 // Verify that if canDragBookmarkButtonToTrash is NO then the button can't 150 // be dragged to the trash. 151 delegate.get()->canDragToTrash_ = NO; 152 NSDragOperation operation = [button draggingSourceOperationMaskForLocal:NO]; 153 EXPECT_EQ(0u, operation & NSDragOperationDelete); 154 operation = [button draggingSourceOperationMaskForLocal:YES]; 155 EXPECT_EQ(0u, operation & NSDragOperationDelete); 156 157 // Verify that if canDragBookmarkButtonToTrash is YES then the button can 158 // be dragged to the trash. 159 delegate.get()->canDragToTrash_ = YES; 160 operation = [button draggingSourceOperationMaskForLocal:NO]; 161 EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete); 162 operation = [button draggingSourceOperationMaskForLocal:YES]; 163 EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete); 164 165 // Verify that canDragBookmarkButtonToTrash is called when expected. 166 delegate.get()->canDragToTrash_ = YES; 167 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); 168 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationCopy]; 169 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); 170 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationMove]; 171 EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); 172 [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationDelete]; 173 EXPECT_EQ(1, delegate.get()->didDragToTrashCount_); 174 } 175 176 } 177