| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/mac/scoped_nsobject.h" | 
 | #include "base/strings/utf_string_conversions.h" | 
 | #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 
 | #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" | 
 | #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" | 
 | #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" | 
 | #include "chrome/test/base/testing_profile.h" | 
 | #include "components/bookmarks/browser/bookmark_model.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 | #include "testing/platform_test.h" | 
 | #import "ui/events/test/cocoa_test_event_utils.h" | 
 |  | 
 | // Fake BookmarkButton delegate to get a pong on mouse entered/exited | 
 | @interface FakeButtonDelegate : NSObject<BookmarkButtonDelegate> { | 
 |  @public | 
 |   int entered_; | 
 |   int exited_; | 
 |   BOOL canDragToTrash_; | 
 |   int didDragToTrashCount_; | 
 | } | 
 | @end | 
 |  | 
 | @implementation FakeButtonDelegate | 
 |  | 
 | - (void)fillPasteboard:(NSPasteboard*)pboard | 
 |        forDragOfButton:(BookmarkButton*)button { | 
 | } | 
 |  | 
 | - (void)mouseEnteredButton:(id)buton event:(NSEvent*)event { | 
 |   entered_++; | 
 | } | 
 |  | 
 | - (void)mouseExitedButton:(id)buton event:(NSEvent*)event { | 
 |   exited_++; | 
 | } | 
 |  | 
 | - (BOOL)dragShouldLockBarVisibility { | 
 |   return NO; | 
 | } | 
 |  | 
 | - (NSWindow*)browserWindow { | 
 |   return nil; | 
 | } | 
 |  | 
 | - (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button { | 
 |   return canDragToTrash_; | 
 | } | 
 |  | 
 | - (void)didDragBookmarkToTrash:(BookmarkButton*)button { | 
 |   didDragToTrashCount_++; | 
 | } | 
 |  | 
 | - (void)bookmarkDragDidEnd:(BookmarkButton*)button | 
 |                  operation:(NSDragOperation)operation { | 
 | } | 
 | @end | 
 |  | 
 | namespace { | 
 |  | 
 | class BookmarkButtonTest : public CocoaProfileTest { | 
 | }; | 
 |  | 
 | // Make sure nothing leaks | 
 | TEST_F(BookmarkButtonTest, Create) { | 
 |   base::scoped_nsobject<BookmarkButton> button; | 
 |   button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); | 
 | } | 
 |  | 
 | // Test folder and empty node queries. | 
 | TEST_F(BookmarkButtonTest, FolderAndEmptyOrNot) { | 
 |   base::scoped_nsobject<BookmarkButton> button; | 
 |   base::scoped_nsobject<BookmarkButtonCell> cell; | 
 |  | 
 |   button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); | 
 |   cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); | 
 |   [button setCell:cell]; | 
 |  | 
 |   EXPECT_TRUE([button isEmpty]); | 
 |   EXPECT_FALSE([button isFolder]); | 
 |   EXPECT_FALSE([button bookmarkNode]); | 
 |  | 
 |   NSEvent* downEvent = | 
 |       cocoa_test_event_utils::LeftMouseDownAtPoint(NSMakePoint(10,10)); | 
 |   // Since this returns (does not actually begin a modal drag), success! | 
 |   [button beginDrag:downEvent]; | 
 |  | 
 |   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile()); | 
 |   const BookmarkNode* node = model->bookmark_bar_node(); | 
 |   [cell setBookmarkNode:node]; | 
 |   EXPECT_FALSE([button isEmpty]); | 
 |   EXPECT_TRUE([button isFolder]); | 
 |   EXPECT_EQ([button bookmarkNode], node); | 
 |  | 
 |   node = model->AddURL(node, 0, base::ASCIIToUTF16("hi mom"), | 
 |                        GURL("http://www.google.com")); | 
 |   [cell setBookmarkNode:node]; | 
 |   EXPECT_FALSE([button isEmpty]); | 
 |   EXPECT_FALSE([button isFolder]); | 
 |   EXPECT_EQ([button bookmarkNode], node); | 
 | } | 
 |  | 
 | TEST_F(BookmarkButtonTest, MouseEnterExitRedirect) { | 
 |   NSEvent* moveEvent = | 
 |       cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), | 
 |                                                 NSMouseMoved, | 
 |                                                 0); | 
 |   base::scoped_nsobject<BookmarkButton> button; | 
 |   base::scoped_nsobject<BookmarkButtonCell> cell; | 
 |   base::scoped_nsobject<FakeButtonDelegate> delegate( | 
 |       [[FakeButtonDelegate alloc] init]); | 
 |   button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); | 
 |   cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); | 
 |   [button setCell:cell]; | 
 |   [button setDelegate:delegate]; | 
 |  | 
 |   EXPECT_EQ(0, delegate.get()->entered_); | 
 |   EXPECT_EQ(0, delegate.get()->exited_); | 
 |  | 
 |   [button mouseEntered:moveEvent]; | 
 |   EXPECT_EQ(1, delegate.get()->entered_); | 
 |   EXPECT_EQ(0, delegate.get()->exited_); | 
 |  | 
 |   [button mouseExited:moveEvent]; | 
 |   [button mouseExited:moveEvent]; | 
 |   EXPECT_EQ(1, delegate.get()->entered_); | 
 |   EXPECT_EQ(2, delegate.get()->exited_); | 
 | } | 
 |  | 
 | TEST_F(BookmarkButtonTest, DragToTrash) { | 
 |   base::scoped_nsobject<BookmarkButton> button; | 
 |   base::scoped_nsobject<BookmarkButtonCell> cell; | 
 |   base::scoped_nsobject<FakeButtonDelegate> delegate( | 
 |       [[FakeButtonDelegate alloc] init]); | 
 |   button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); | 
 |   cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]); | 
 |   [button setCell:cell]; | 
 |   [button setDelegate:delegate]; | 
 |  | 
 |   // Add a deletable bookmark to the button. | 
 |   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile()); | 
 |   const BookmarkNode* barNode = model->bookmark_bar_node(); | 
 |   const BookmarkNode* node = model->AddURL(barNode, 0, | 
 |                                            base::ASCIIToUTF16("hi mom"), | 
 |                                            GURL("http://www.google.com")); | 
 |   [cell setBookmarkNode:node]; | 
 |  | 
 |   // Verify that if canDragBookmarkButtonToTrash is NO then the button can't | 
 |   // be dragged to the trash. | 
 |   delegate.get()->canDragToTrash_ = NO; | 
 |   NSDragOperation operation = [button draggingSourceOperationMaskForLocal:NO]; | 
 |   EXPECT_EQ(0u, operation & NSDragOperationDelete); | 
 |   operation = [button draggingSourceOperationMaskForLocal:YES]; | 
 |   EXPECT_EQ(0u, operation & NSDragOperationDelete); | 
 |  | 
 |   // Verify that if canDragBookmarkButtonToTrash is YES then the button can | 
 |   // be dragged to the trash. | 
 |   delegate.get()->canDragToTrash_ = YES; | 
 |   operation = [button draggingSourceOperationMaskForLocal:NO]; | 
 |   EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete); | 
 |   operation = [button draggingSourceOperationMaskForLocal:YES]; | 
 |   EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete); | 
 |  | 
 |   // Verify that canDragBookmarkButtonToTrash is called when expected. | 
 |   delegate.get()->canDragToTrash_ = YES; | 
 |   EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); | 
 |   [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationCopy]; | 
 |   EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); | 
 |   [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationMove]; | 
 |   EXPECT_EQ(0, delegate.get()->didDragToTrashCount_); | 
 |   [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationDelete]; | 
 |   EXPECT_EQ(1, delegate.get()->didDragToTrashCount_); | 
 | } | 
 |  | 
 | } |