Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / bookmarks / bookmark_menu_delegate_unittest.cc
blobd7dd524b4ce1c59bee74f437a6c63c7ddada6d35
1 // Copyright 2013 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_menu_delegate.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
9 #include "chrome/browser/bookmarks/bookmark_stats.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/test/base/browser_with_test_window_test.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "components/bookmarks/browser/bookmark_model.h"
14 #include "components/bookmarks/test/bookmark_test_helpers.h"
15 #include "ui/views/controls/menu/menu_item_view.h"
16 #include "ui/views/controls/menu/menu_runner.h"
17 #include "ui/views/controls/menu/submenu_view.h"
19 using base::ASCIIToUTF16;
20 using bookmarks::BookmarkModel;
21 using bookmarks::BookmarkNode;
23 class BookmarkMenuDelegateTest : public BrowserWithTestWindowTest {
24 public:
25 BookmarkMenuDelegateTest() : model_(NULL) {}
27 void SetUp() override {
28 BrowserWithTestWindowTest::SetUp();
30 profile()->CreateBookmarkModel(true);
32 model_ = BookmarkModelFactory::GetForProfile(profile());
33 bookmarks::test::WaitForBookmarkModelToLoad(model_);
35 AddTestData();
38 void TearDown() override {
39 if (bookmark_menu_delegate_.get()) {
40 // Since we never show the menu we need to pass the MenuItemView to
41 // MenuRunner so that the MenuItemView is destroyed.
42 views::MenuRunner menu_runner(bookmark_menu_delegate_->menu(), 0);
43 bookmark_menu_delegate_.reset();
45 BrowserWithTestWindowTest::TearDown();
48 protected:
49 void NewDelegate() {
50 // Destroy current menu if available, see comments in TearDown().
51 if (bookmark_menu_delegate_.get())
52 views::MenuRunner menu_runner(bookmark_menu_delegate_->menu(), 0);
54 bookmark_menu_delegate_.reset(
55 new BookmarkMenuDelegate(browser(), nullptr, nullptr));
58 void NewAndInitDelegateForPermanent() {
59 const BookmarkNode* node = model_->bookmark_bar_node();
60 NewDelegate();
61 bookmark_menu_delegate_->Init(&test_delegate_, NULL, node, 0,
62 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
63 BOOKMARK_LAUNCH_LOCATION_NONE);
66 const BookmarkNode* GetNodeForMenuItem(views::MenuItemView* menu) {
67 const auto& node_map = bookmark_menu_delegate_->menu_id_to_node_map_;
68 auto iter = node_map.find(menu->GetCommand());
69 return (iter == node_map.end()) ? nullptr : iter->second;
72 int next_menu_id() { return bookmark_menu_delegate_->next_menu_id_; }
74 // Forces all the menus to load by way of invoking WillShowMenu() on all menu
75 // items of tyep SUBMENU.
76 void LoadAllMenus() { LoadAllMenus(bookmark_menu_delegate_->menu()); }
78 BookmarkModel* model_;
80 scoped_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
82 private:
83 void LoadAllMenus(views::MenuItemView* menu) {
84 EXPECT_EQ(views::MenuItemView::SUBMENU, menu->GetType());
86 for (int i = 0; i < menu->GetSubmenu()->GetMenuItemCount(); ++i) {
87 views::MenuItemView* child = menu->GetSubmenu()->GetMenuItemAt(i);
88 if (child->GetType() == views::MenuItemView::SUBMENU) {
89 bookmark_menu_delegate_->WillShowMenu(child);
90 LoadAllMenus(child);
95 std::string base_path() const { return "file:///c:/tmp/"; }
97 // Creates the following structure:
98 // bookmark bar node
99 // a
100 // F1
101 // f1a
102 // F11
103 // f11a
104 // F2
105 // other node
106 // oa
107 // OF1
108 // of1a
109 void AddTestData() {
110 const BookmarkNode* bb_node = model_->bookmark_bar_node();
111 std::string test_base = base_path();
112 model_->AddURL(bb_node, 0, ASCIIToUTF16("a"), GURL(test_base + "a"));
113 const BookmarkNode* f1 = model_->AddFolder(bb_node, 1, ASCIIToUTF16("F1"));
114 model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
115 const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11"));
116 model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
117 model_->AddFolder(bb_node, 2, ASCIIToUTF16("F2"));
119 // Children of the other node.
120 model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"),
121 GURL(test_base + "oa"));
122 const BookmarkNode* of1 =
123 model_->AddFolder(model_->other_node(), 1, ASCIIToUTF16("OF1"));
124 model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a"));
127 views::MenuDelegate test_delegate_;
129 DISALLOW_COPY_AND_ASSIGN(BookmarkMenuDelegateTest);
132 TEST_F(BookmarkMenuDelegateTest, VerifyLazyLoad) {
133 NewAndInitDelegateForPermanent();
134 views::MenuItemView* root_item = bookmark_menu_delegate_->menu();
135 ASSERT_TRUE(root_item->HasSubmenu());
136 EXPECT_EQ(4, root_item->GetSubmenu()->GetMenuItemCount());
137 EXPECT_EQ(5, root_item->GetSubmenu()->child_count()); // Includes separator.
138 views::MenuItemView* f1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
139 ASSERT_TRUE(f1_item->HasSubmenu());
140 // f1 hasn't been loaded yet.
141 EXPECT_EQ(0, f1_item->GetSubmenu()->GetMenuItemCount());
142 // Will show triggers a load.
143 int next_id_before_load = next_menu_id();
144 bookmark_menu_delegate_->WillShowMenu(f1_item);
145 // f1 should have loaded its children.
146 EXPECT_EQ(next_id_before_load + 2, next_menu_id());
147 ASSERT_EQ(2, f1_item->GetSubmenu()->GetMenuItemCount());
148 const BookmarkNode* f1_node = model_->bookmark_bar_node()->GetChild(1);
149 EXPECT_EQ(f1_node->GetChild(0),
150 GetNodeForMenuItem(f1_item->GetSubmenu()->GetMenuItemAt(0)));
151 EXPECT_EQ(f1_node->GetChild(1),
152 GetNodeForMenuItem(f1_item->GetSubmenu()->GetMenuItemAt(1)));
154 // F11 shouldn't have loaded yet.
155 views::MenuItemView* f11_item = f1_item->GetSubmenu()->GetMenuItemAt(1);
156 ASSERT_TRUE(f11_item->HasSubmenu());
157 EXPECT_EQ(0, f11_item->GetSubmenu()->GetMenuItemCount());
159 next_id_before_load = next_menu_id();
160 bookmark_menu_delegate_->WillShowMenu(f11_item);
161 // Invoke WillShowMenu() twice to make sure the second call doesn't cause
162 // problems.
163 bookmark_menu_delegate_->WillShowMenu(f11_item);
164 // F11 should have loaded its single child (f11a).
165 EXPECT_EQ(next_id_before_load + 1, next_menu_id());
167 ASSERT_EQ(1, f11_item->GetSubmenu()->GetMenuItemCount());
168 const BookmarkNode* f11_node = f1_node->GetChild(1);
169 EXPECT_EQ(f11_node->GetChild(0),
170 GetNodeForMenuItem(f11_item->GetSubmenu()->GetMenuItemAt(0)));
173 // Verifies WillRemoveBookmarks() doesn't attempt to access MenuItemViews that
174 // have since been deleted.
175 TEST_F(BookmarkMenuDelegateTest, RemoveBookmarks) {
176 views::MenuDelegate test_delegate;
177 const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(1);
178 NewDelegate();
179 bookmark_menu_delegate_->Init(&test_delegate, NULL, node, 0,
180 BookmarkMenuDelegate::HIDE_PERMANENT_FOLDERS,
181 BOOKMARK_LAUNCH_LOCATION_NONE);
182 LoadAllMenus();
183 std::vector<const BookmarkNode*> nodes_to_remove;
184 nodes_to_remove.push_back(node->GetChild(1));
185 bookmark_menu_delegate_->WillRemoveBookmarks(nodes_to_remove);
186 nodes_to_remove.clear();
187 bookmark_menu_delegate_->DidRemoveBookmarks();