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