Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / bookmarks / bookmark_context_menu_unittest.cc
blob6b63f949bd522972f5f1c67a65d95b13bee0c2bf
1 // Copyright 2014 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.
5 #include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h"
7 #include <string>
8 #include <vector>
10 #include "base/compiler_specific.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "base/values.h"
16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
18 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "components/bookmarks/browser/bookmark_model.h"
24 #include "components/bookmarks/managed/managed_bookmark_service.h"
25 #include "components/bookmarks/test/bookmark_test_helpers.h"
26 #include "content/public/browser/page_navigator.h"
27 #include "content/public/test/test_browser_thread.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "ui/base/clipboard/clipboard.h"
30 #include "ui/events/platform/platform_event_source.h"
31 #include "ui/views/controls/menu/menu_item_view.h"
33 #if defined(OS_WIN)
34 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
35 #endif
37 using base::ASCIIToUTF16;
38 using bookmarks::BookmarkModel;
39 using bookmarks::BookmarkNode;
40 using content::BrowserThread;
41 using content::OpenURLParams;
42 using content::PageNavigator;
43 using content::WebContents;
45 namespace {
47 // PageNavigator implementation that records the URL.
48 class TestingPageNavigator : public PageNavigator {
49 public:
50 WebContents* OpenURL(const OpenURLParams& params) override {
51 urls_.push_back(params.url);
52 return NULL;
55 std::vector<GURL> urls_;
58 } // namespace
60 class BookmarkContextMenuTest : public testing::Test {
61 public:
62 BookmarkContextMenuTest()
63 : ui_thread_(BrowserThread::UI, &message_loop_),
64 file_thread_(BrowserThread::FILE, &message_loop_),
65 model_(NULL) {
68 void SetUp() override {
69 profile_.reset(new TestingProfile());
70 profile_->CreateBookmarkModel(true);
72 model_ = BookmarkModelFactory::GetForProfile(profile_.get());
73 bookmarks::test::WaitForBookmarkModelToLoad(model_);
75 AddTestData();
78 void TearDown() override {
79 ui::Clipboard::DestroyClipboardForCurrentThread();
81 BrowserThread::GetBlockingPool()->FlushForTesting();
82 // Flush the message loop to make application verifiers happy.
83 message_loop_.RunUntilIdle();
86 protected:
87 base::MessageLoopForUI message_loop_;
88 content::TestBrowserThread ui_thread_;
89 content::TestBrowserThread file_thread_;
90 scoped_ptr<TestingProfile> profile_;
91 BookmarkModel* model_;
92 TestingPageNavigator navigator_;
94 private:
95 // Creates the following structure:
96 // a
97 // F1
98 // f1a
99 // -f1b as "chrome://settings"
100 // F11
101 // f11a
102 // F2
103 // F3
104 // F4
105 // f4a
106 void AddTestData() {
107 const BookmarkNode* bb_node = model_->bookmark_bar_node();
108 std::string test_base = "file:///c:/tmp/";
109 model_->AddURL(bb_node, 0, ASCIIToUTF16("a"), GURL(test_base + "a"));
110 const BookmarkNode* f1 = model_->AddFolder(bb_node, 1, ASCIIToUTF16("F1"));
111 model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
112 model_->AddURL(f1, 1, ASCIIToUTF16("f1b"), GURL("chrome://settings"));
113 const BookmarkNode* f11 = model_->AddFolder(f1, 2, ASCIIToUTF16("F11"));
114 model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
115 model_->AddFolder(bb_node, 2, ASCIIToUTF16("F2"));
116 model_->AddFolder(bb_node, 3, ASCIIToUTF16("F3"));
117 const BookmarkNode* f4 = model_->AddFolder(bb_node, 4, ASCIIToUTF16("F4"));
118 model_->AddURL(f4, 0, ASCIIToUTF16("f4a"), GURL(test_base + "f4a"));
122 // Tests Deleting from the menu.
123 TEST_F(BookmarkContextMenuTest, DeleteURL) {
124 std::vector<const BookmarkNode*> nodes;
125 nodes.push_back(model_->bookmark_bar_node()->GetChild(0));
126 BookmarkContextMenu controller(
127 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
128 GURL url = model_->bookmark_bar_node()->GetChild(0)->url();
129 ASSERT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
130 // Delete the URL.
131 controller.ExecuteCommand(IDC_BOOKMARK_BAR_REMOVE, 0);
132 // Model shouldn't have URL anymore.
133 ASSERT_FALSE(model_->IsBookmarked(url));
136 // Tests open all on a folder with a couple of bookmarks.
137 TEST_F(BookmarkContextMenuTest, OpenAll) {
138 const BookmarkNode* folder = model_->bookmark_bar_node()->GetChild(1);
139 chrome::OpenAll(NULL, &navigator_, folder, NEW_FOREGROUND_TAB, NULL);
141 // Should have navigated to F1's child but not F11's child.
142 ASSERT_EQ(static_cast<size_t>(2), navigator_.urls_.size());
143 ASSERT_TRUE(folder->GetChild(0)->url() == navigator_.urls_[0]);
146 // Tests open all on a folder with a couple of bookmarks in incognito window.
147 TEST_F(BookmarkContextMenuTest, OpenAllIngonito) {
148 const BookmarkNode* folder = model_->bookmark_bar_node()->GetChild(1);
149 chrome::OpenAll(NULL, &navigator_, folder, OFF_THE_RECORD, NULL);
151 // Should have navigated to only f1a but not f2a.
152 ASSERT_EQ(static_cast<size_t>(1), navigator_.urls_.size());
153 ASSERT_TRUE(folder->GetChild(0)->url() == navigator_.urls_[0]);
156 // Tests the enabled state of the menus when supplied an empty vector.
157 TEST_F(BookmarkContextMenuTest, EmptyNodes) {
158 BookmarkContextMenu controller(
159 NULL, NULL, profile_.get(), NULL, model_->other_node(),
160 std::vector<const BookmarkNode*>(), false);
161 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
162 EXPECT_FALSE(
163 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
164 EXPECT_FALSE(
165 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
166 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
167 EXPECT_TRUE(
168 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
169 EXPECT_TRUE(
170 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
173 // Tests the enabled state of the menus when supplied a vector with a single
174 // url.
175 TEST_F(BookmarkContextMenuTest, SingleURL) {
176 std::vector<const BookmarkNode*> nodes;
177 nodes.push_back(model_->bookmark_bar_node()->GetChild(0));
178 BookmarkContextMenu controller(
179 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
180 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
181 EXPECT_TRUE(
182 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
183 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
184 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
185 EXPECT_TRUE(
186 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
187 EXPECT_TRUE(
188 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
191 // Tests the enabled state of the menus when supplied a vector with multiple
192 // urls.
193 TEST_F(BookmarkContextMenuTest, MultipleURLs) {
194 std::vector<const BookmarkNode*> nodes;
195 nodes.push_back(model_->bookmark_bar_node()->GetChild(0));
196 nodes.push_back(model_->bookmark_bar_node()->GetChild(1)->GetChild(0));
197 BookmarkContextMenu controller(
198 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
199 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
200 EXPECT_TRUE(
201 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
202 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
203 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
204 EXPECT_TRUE(
205 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
206 EXPECT_TRUE(
207 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
210 // Tests the enabled state of the menus when supplied an vector with a single
211 // folder.
212 TEST_F(BookmarkContextMenuTest, SingleFolder) {
213 std::vector<const BookmarkNode*> nodes;
214 nodes.push_back(model_->bookmark_bar_node()->GetChild(2));
215 BookmarkContextMenu controller(
216 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
217 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
218 EXPECT_FALSE(
219 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
220 EXPECT_FALSE(
221 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
222 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
223 EXPECT_TRUE(
224 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
225 EXPECT_TRUE(
226 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
229 // Tests the enabled state of the menus when supplied a vector with multiple
230 // folders, all of which are empty.
231 TEST_F(BookmarkContextMenuTest, MultipleEmptyFolders) {
232 std::vector<const BookmarkNode*> nodes;
233 nodes.push_back(model_->bookmark_bar_node()->GetChild(2));
234 nodes.push_back(model_->bookmark_bar_node()->GetChild(3));
235 BookmarkContextMenu controller(
236 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
237 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
238 EXPECT_FALSE(
239 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
240 EXPECT_FALSE(
241 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
242 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
243 EXPECT_TRUE(
244 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
245 EXPECT_TRUE(
246 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
249 // Tests the enabled state of the menus when supplied a vector with multiple
250 // folders, some of which contain URLs.
251 TEST_F(BookmarkContextMenuTest, MultipleFoldersWithURLs) {
252 std::vector<const BookmarkNode*> nodes;
253 nodes.push_back(model_->bookmark_bar_node()->GetChild(3));
254 nodes.push_back(model_->bookmark_bar_node()->GetChild(4));
255 BookmarkContextMenu controller(
256 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false);
257 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
258 EXPECT_TRUE(
259 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
260 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
261 EXPECT_TRUE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
262 EXPECT_TRUE(
263 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
264 EXPECT_TRUE(
265 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
268 // Tests the enabled state of open incognito.
269 TEST_F(BookmarkContextMenuTest, DisableIncognito) {
270 std::vector<const BookmarkNode*> nodes;
271 nodes.push_back(model_->bookmark_bar_node()->GetChild(0));
272 Profile* incognito = profile_->GetOffTheRecordProfile();
273 BookmarkContextMenu controller(
274 NULL, NULL, incognito, NULL, nodes[0]->parent(), nodes, false);
275 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_INCOGNITO));
276 EXPECT_FALSE(
277 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
280 // Tests that you can't remove/edit when showing the other node.
281 TEST_F(BookmarkContextMenuTest, DisabledItemsWithOtherNode) {
282 std::vector<const BookmarkNode*> nodes;
283 nodes.push_back(model_->other_node());
284 BookmarkContextMenu controller(
285 NULL, NULL, profile_.get(), NULL, nodes[0], nodes, false);
286 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_EDIT));
287 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
290 // Tests the enabled state of the menus when supplied an empty vector and null
291 // parent.
292 TEST_F(BookmarkContextMenuTest, EmptyNodesNullParent) {
293 BookmarkContextMenu controller(
294 NULL, NULL, profile_.get(), NULL, NULL,
295 std::vector<const BookmarkNode*>(), false);
296 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL));
297 EXPECT_FALSE(
298 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
299 EXPECT_FALSE(
300 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
301 EXPECT_FALSE(controller.IsCommandEnabled(IDC_BOOKMARK_BAR_REMOVE));
302 EXPECT_FALSE(
303 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
304 EXPECT_FALSE(
305 controller.IsCommandEnabled(IDC_BOOKMARK_BAR_NEW_FOLDER));
308 TEST_F(BookmarkContextMenuTest, CutCopyPasteNode) {
309 const BookmarkNode* bb_node = model_->bookmark_bar_node();
310 std::vector<const BookmarkNode*> nodes;
311 nodes.push_back(bb_node->GetChild(0));
312 scoped_ptr<BookmarkContextMenu> controller(new BookmarkContextMenu(
313 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false));
314 EXPECT_TRUE(controller->IsCommandEnabled(IDC_COPY));
315 EXPECT_TRUE(controller->IsCommandEnabled(IDC_CUT));
317 // Copy the URL.
318 controller->ExecuteCommand(IDC_COPY, 0);
320 controller.reset(new BookmarkContextMenu(
321 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false));
322 int old_count = bb_node->child_count();
323 controller->ExecuteCommand(IDC_PASTE, 0);
325 ASSERT_TRUE(bb_node->GetChild(1)->is_url());
326 ASSERT_EQ(old_count + 1, bb_node->child_count());
327 ASSERT_EQ(bb_node->GetChild(0)->url(), bb_node->GetChild(1)->url());
329 controller.reset(new BookmarkContextMenu(
330 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false));
331 // Cut the URL.
332 controller->ExecuteCommand(IDC_CUT, 0);
333 ASSERT_TRUE(bb_node->GetChild(0)->is_url());
334 ASSERT_TRUE(bb_node->GetChild(1)->is_folder());
335 ASSERT_EQ(old_count, bb_node->child_count());
338 // Tests that the "Show managed bookmarks" option in the context menu is only
339 // visible if the policy is set.
340 TEST_F(BookmarkContextMenuTest, ShowManagedBookmarks) {
341 // Create a BookmarkContextMenu for the bookmarks bar.
342 const BookmarkNode* bb_node = model_->bookmark_bar_node();
343 std::vector<const BookmarkNode*> nodes;
344 nodes.push_back(bb_node->GetChild(0));
345 scoped_ptr<BookmarkContextMenu> controller(new BookmarkContextMenu(
346 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false));
348 // Verify that there are no managed nodes yet.
349 bookmarks::ManagedBookmarkService* managed =
350 ManagedBookmarkServiceFactory::GetForProfile(profile_.get());
351 EXPECT_TRUE(managed->managed_node()->empty());
353 // The context menu should not show the option to "Show managed bookmarks".
354 EXPECT_FALSE(
355 controller->IsCommandVisible(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS));
356 views::MenuItemView* menu = controller->menu();
357 EXPECT_FALSE(menu->GetMenuItemByID(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS)
358 ->visible());
360 // Other options are not affected.
361 EXPECT_TRUE(controller->IsCommandVisible(IDC_BOOKMARK_BAR_NEW_FOLDER));
362 EXPECT_TRUE(menu->GetMenuItemByID(IDC_BOOKMARK_BAR_NEW_FOLDER)->visible());
364 // Now set the managed bookmarks policy.
365 base::DictionaryValue* dict = new base::DictionaryValue;
366 dict->SetString("name", "Google");
367 dict->SetString("url", "http://google.com");
368 base::ListValue list;
369 list.Append(dict);
370 EXPECT_TRUE(managed->managed_node()->empty());
371 profile_->GetPrefs()->Set(bookmarks::prefs::kManagedBookmarks, list);
372 EXPECT_FALSE(managed->managed_node()->empty());
374 // New context menus now show the "Show managed bookmarks" option.
375 controller.reset(new BookmarkContextMenu(
376 NULL, NULL, profile_.get(), NULL, nodes[0]->parent(), nodes, false));
377 EXPECT_TRUE(controller->IsCommandVisible(IDC_BOOKMARK_BAR_NEW_FOLDER));
378 EXPECT_TRUE(
379 controller->IsCommandVisible(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS));
380 menu = controller->menu();
381 EXPECT_TRUE(menu->GetMenuItemByID(IDC_BOOKMARK_BAR_NEW_FOLDER)->visible());
382 EXPECT_TRUE(menu->GetMenuItemByID(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS)
383 ->visible());