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