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 <string> 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/utf_string_conversions.h" 9 #include "chrome/app/chrome_command_ids.h" 10 #include "chrome/browser/bookmarks/bookmark_context_menu_controller.h" 11 #include "chrome/browser/bookmarks/bookmark_model.h" 12 #include "chrome/browser/bookmarks/bookmark_utils.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/test/testing_profile.h" 15 #include "content/browser/browser_thread.h" 16 #include "content/browser/tab_contents/page_navigator.h" 17 #include "grit/generated_resources.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 #if defined(OS_WIN) 21 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 22 #endif 23 24 // PageNavigator implementation that records the URL. 25 class TestingPageNavigator : public PageNavigator { 26 public: 27 virtual void OpenURL(const GURL& url, 28 const GURL& referrer, 29 WindowOpenDisposition disposition, 30 PageTransition::Type transition) { 31 urls_.push_back(url); 32 } 33 34 std::vector<GURL> urls_; 35 }; 36 37 class BookmarkContextMenuControllerTest : public testing::Test { 38 public: 39 BookmarkContextMenuControllerTest() 40 : ui_thread_(BrowserThread::UI, &message_loop_), 41 file_thread_(BrowserThread::FILE, &message_loop_), 42 model_(NULL) { 43 } 44 45 virtual void SetUp() { 46 #if defined(OS_WIN) 47 BookmarkBarView::testing_ = true; 48 #endif 49 50 profile_.reset(new TestingProfile()); 51 profile_->CreateBookmarkModel(true); 52 profile_->BlockUntilBookmarkModelLoaded(); 53 54 model_ = profile_->GetBookmarkModel(); 55 56 AddTestData(); 57 } 58 59 virtual void TearDown() { 60 #if defined(OS_WIN) 61 BookmarkBarView::testing_ = false; 62 #endif 63 64 // Flush the message loop to make Purify happy. 65 message_loop_.RunAllPending(); 66 } 67 68 protected: 69 MessageLoopForUI message_loop_; 70 BrowserThread ui_thread_; 71 BrowserThread file_thread_; 72 scoped_ptr<TestingProfile> profile_; 73 BookmarkModel* model_; 74 TestingPageNavigator navigator_; 75 76 private: 77 // Creates the following structure: 78 // a 79 // F1 80 // f1a 81 // F11 82 // f11a 83 // F2 84 // F3 85 // F4 86 // f4a 87 void AddTestData() { 88 std::string test_base = "file:///c:/tmp/"; 89 90 model_->AddURL(model_->GetBookmarkBarNode(), 0, ASCIIToUTF16("a"), 91 GURL(test_base + "a")); 92 const BookmarkNode* f1 = 93 model_->AddFolder(model_->GetBookmarkBarNode(), 1, ASCIIToUTF16("F1")); 94 model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a")); 95 const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11")); 96 model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a")); 97 model_->AddFolder(model_->GetBookmarkBarNode(), 2, ASCIIToUTF16("F2")); 98 model_->AddFolder(model_->GetBookmarkBarNode(), 3, ASCIIToUTF16("F3")); 99 const BookmarkNode* f4 = 100 model_->AddFolder(model_->GetBookmarkBarNode(), 4, ASCIIToUTF16("F4")); 101 model_->AddURL(f4, 0, ASCIIToUTF16("f4a"), GURL(test_base + "f4a")); 102 } 103 }; 104 105 // Tests Deleting from the menu. 106 TEST_F(BookmarkContextMenuControllerTest, DeleteURL) { 107 std::vector<const BookmarkNode*> nodes; 108 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); 109 BookmarkContextMenuController controller( 110 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 111 GURL url = model_->GetBookmarkBarNode()->GetChild(0)->GetURL(); 112 ASSERT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 113 // Delete the URL. 114 controller.ExecuteCommand(IDC_BOOKMARK_BAR_REMOVE); 115 // Model shouldn't have URL anymore. 116 ASSERT_FALSE(model_->IsBookmarked(url)); 117 } 118 119 // Tests open all on a folder with a couple of bookmarks. 120 TEST_F(BookmarkContextMenuControllerTest, OpenAll) { 121 const BookmarkNode* folder = model_->GetBookmarkBarNode()->GetChild(1); 122 bookmark_utils::OpenAll( 123 NULL, profile_.get(), &navigator_, folder, NEW_FOREGROUND_TAB); 124 125 // Should have navigated to F1's child, but not F11's child. 126 ASSERT_EQ(static_cast<size_t>(1), navigator_.urls_.size()); 127 ASSERT_TRUE(folder->GetChild(0)->GetURL() == navigator_.urls_[0]); 128 } 129 130 // Tests the enabled state of the menus when supplied an empty vector. 131 TEST_F(BookmarkContextMenuControllerTest, EmptyNodes) { 132 BookmarkContextMenuController controller( 133 NULL, NULL, profile_.get(), NULL, model_->other_node(), 134 std::vector<const BookmarkNode*>()); 135 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 136 EXPECT_FALSE( 137 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 138 EXPECT_FALSE( 139 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 140 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 141 EXPECT_TRUE( 142 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 143 EXPECT_TRUE( 144 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 145 } 146 147 // Tests the enabled state of the menus when supplied a vector with a single 148 // url. 149 TEST_F(BookmarkContextMenuControllerTest, SingleURL) { 150 std::vector<const BookmarkNode*> nodes; 151 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); 152 BookmarkContextMenuController controller( 153 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 154 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 155 EXPECT_TRUE( 156 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 157 EXPECT_TRUE( 158 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 159 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 160 EXPECT_TRUE( 161 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 162 EXPECT_TRUE( 163 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 164 } 165 166 // Tests the enabled state of the menus when supplied a vector with multiple 167 // urls. 168 TEST_F(BookmarkContextMenuControllerTest, MultipleURLs) { 169 std::vector<const BookmarkNode*> nodes; 170 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); 171 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(1)->GetChild(0)); 172 BookmarkContextMenuController controller( 173 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 174 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 175 EXPECT_TRUE( 176 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 177 EXPECT_TRUE( 178 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 179 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 180 EXPECT_TRUE( 181 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 182 EXPECT_TRUE( 183 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 184 } 185 186 // Tests the enabled state of the menus when supplied an vector with a single 187 // folder. 188 TEST_F(BookmarkContextMenuControllerTest, SingleFolder) { 189 std::vector<const BookmarkNode*> nodes; 190 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); 191 BookmarkContextMenuController controller( 192 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 193 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 194 EXPECT_FALSE( 195 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 196 EXPECT_FALSE( 197 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 198 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 199 EXPECT_TRUE( 200 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 201 EXPECT_TRUE( 202 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 203 } 204 205 // Tests the enabled state of the menus when supplied a vector with multiple 206 // folders, all of which are empty. 207 TEST_F(BookmarkContextMenuControllerTest, MultipleEmptyFolders) { 208 std::vector<const BookmarkNode*> nodes; 209 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); 210 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); 211 BookmarkContextMenuController controller( 212 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 213 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 214 EXPECT_FALSE( 215 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 216 EXPECT_FALSE( 217 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 218 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 219 EXPECT_TRUE( 220 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 221 EXPECT_TRUE( 222 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 223 } 224 225 // Tests the enabled state of the menus when supplied a vector with multiple 226 // folders, some of which contain URLs. 227 TEST_F(BookmarkContextMenuControllerTest, MultipleFoldersWithURLs) { 228 std::vector<const BookmarkNode*> nodes; 229 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); 230 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(4)); 231 BookmarkContextMenuController controller( 232 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 233 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 234 EXPECT_TRUE( 235 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 236 EXPECT_TRUE( 237 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 238 EXPECT_TRUE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 239 EXPECT_TRUE( 240 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 241 EXPECT_TRUE( 242 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 243 } 244 245 // Tests the enabled state of open incognito. 246 TEST_F(BookmarkContextMenuControllerTest, DisableIncognito) { 247 std::vector<const BookmarkNode*> nodes; 248 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); 249 BookmarkContextMenuController controller( 250 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes); 251 profile_->set_incognito(true); 252 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_INCOGNITO)); 253 EXPECT_FALSE( 254 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 255 } 256 257 // Tests that you can't remove/edit when showing the other node. 258 TEST_F(BookmarkContextMenuControllerTest, DisabledItemsWithOtherNode) { 259 std::vector<const BookmarkNode*> nodes; 260 nodes.push_back(model_->other_node()); 261 BookmarkContextMenuController controller( 262 NULL, NULL, profile_.get(), NULL, nodes[0], nodes); 263 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_EDIT)); 264 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 265 } 266 267 // Tests the enabled state of the menus when supplied an empty vector and null 268 // parent. 269 TEST_F(BookmarkContextMenuControllerTest, EmptyNodesNullParent) { 270 BookmarkContextMenuController controller( 271 NULL, NULL, profile_.get(), NULL, NULL, 272 std::vector<const BookmarkNode*>()); 273 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL)); 274 EXPECT_FALSE( 275 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 276 EXPECT_FALSE( 277 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 278 EXPECT_FALSE(controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_REMOVE)); 279 EXPECT_FALSE( 280 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 281 EXPECT_FALSE( 282 controller.IsCommandIdEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER)); 283 } 284 285 TEST_F(BookmarkContextMenuControllerTest, CutCopyPasteNode) { 286 std::vector<const BookmarkNode*> nodes; 287 nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); 288 scoped_ptr<BookmarkContextMenuController> controller( 289 new BookmarkContextMenuController( 290 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes)); 291 EXPECT_TRUE(controller->IsCommandIdEnabled(IDC_COPY)); 292 EXPECT_TRUE(controller->IsCommandIdEnabled(IDC_CUT)); 293 294 // Copy the URL. 295 controller->ExecuteCommand(IDC_COPY); 296 297 controller.reset(new BookmarkContextMenuController( 298 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes)); 299 int old_count = model_->GetBookmarkBarNode()->child_count(); 300 controller->ExecuteCommand(IDC_PASTE); 301 302 ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(1)->is_url()); 303 ASSERT_EQ(old_count + 1, model_->GetBookmarkBarNode()->child_count()); 304 ASSERT_EQ(model_->GetBookmarkBarNode()->GetChild(0)->GetURL(), 305 model_->GetBookmarkBarNode()->GetChild(1)->GetURL()); 306 307 controller.reset(new BookmarkContextMenuController( 308 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes)); 309 // Cut the URL. 310 controller->ExecuteCommand(IDC_CUT); 311 ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(0)->is_url()); 312 ASSERT_TRUE(model_->GetBookmarkBarNode()->GetChild(1)->is_folder()); 313 ASSERT_EQ(old_count, model_->GetBookmarkBarNode()->child_count()); 314 } 315