bookmark_menu_delegate_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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.
4
5#include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
6
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/bookmarks/bookmark_model.h"
9#include "chrome/browser/bookmarks/bookmark_model_factory.h"
10#include "chrome/browser/bookmarks/bookmark_stats.h"
11#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
12#include "chrome/browser/profiles/profile.h"
13#include "chrome/test/base/browser_with_test_window_test.h"
14#include "chrome/test/base/testing_profile.h"
15#include "ui/views/controls/menu/menu_runner.h"
16#include "ui/views/controls/menu/submenu_view.h"
17
18class BookmarkMenuDelegateTest : public BrowserWithTestWindowTest {
19 public:
20  BookmarkMenuDelegateTest() : model_(NULL) {}
21
22  virtual void SetUp() OVERRIDE {
23    BrowserWithTestWindowTest::SetUp();
24
25    profile()->CreateBookmarkModel(true);
26
27    model_ = BookmarkModelFactory::GetForProfile(profile());
28    test::WaitForBookmarkModelToLoad(model_);
29
30    AddTestData();
31  }
32
33  virtual void TearDown() OVERRIDE {
34    if (bookmark_menu_delegate_.get()) {
35      // Since we never show the menu we need to pass the MenuItemView to
36      // MenuRunner so that the MenuItemView is destroyed.
37      views::MenuRunner menu_runner(bookmark_menu_delegate_->menu());
38      bookmark_menu_delegate_.reset();
39    }
40    BrowserWithTestWindowTest::TearDown();
41  }
42
43 protected:
44  void NewDelegate(int min_menu_id, int max_menu_id) {
45    // Destroy current menu if available, see comments in TearDown().
46    if (bookmark_menu_delegate_.get())
47      views::MenuRunner menu_runner(bookmark_menu_delegate_->menu());
48
49    bookmark_menu_delegate_.reset(
50        new BookmarkMenuDelegate(browser(), NULL, NULL,
51                                 min_menu_id, max_menu_id));
52  }
53
54  void NewAndInitDelegateForPermanent(int min_menu_id,
55                                      int max_menu_id) {
56    const BookmarkNode* node = model_->bookmark_bar_node();
57    NewDelegate(min_menu_id, max_menu_id);
58    bookmark_menu_delegate_->Init(&test_delegate_, NULL, node, 0,
59                                  BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
60                                  BOOKMARK_LAUNCH_LOCATION_NONE);
61  }
62
63  BookmarkModel* model_;
64
65  scoped_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
66
67 private:
68  std::string base_path() const { return "file:///c:/tmp/"; }
69
70  // Creates the following structure:
71  // bookmark bar node
72  //   a
73  //   F1
74  //    f1a
75  //    F11
76  //     f11a
77  //   F2
78  // other node
79  //   oa
80  //   OF1
81  //     of1a
82  void AddTestData() {
83    const BookmarkNode* bb_node = model_->bookmark_bar_node();
84    std::string test_base = base_path();
85    model_->AddURL(bb_node, 0, ASCIIToUTF16("a"), GURL(test_base + "a"));
86    const BookmarkNode* f1 = model_->AddFolder(bb_node, 1, ASCIIToUTF16("F1"));
87    model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
88    const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11"));
89    model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
90    model_->AddFolder(bb_node, 2, ASCIIToUTF16("F2"));
91
92    // Children of the other node.
93    model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"),
94                   GURL(test_base + "oa"));
95    const BookmarkNode* of1 =
96        model_->AddFolder(model_->other_node(), 1, ASCIIToUTF16("OF1"));
97    model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a"));
98  }
99
100  views::MenuDelegate test_delegate_;
101
102  DISALLOW_COPY_AND_ASSIGN(BookmarkMenuDelegateTest);
103};
104
105// Verifies WillRemoveBookmarks() doesn't attempt to access MenuItemViews that
106// have since been deleted.
107TEST_F(BookmarkMenuDelegateTest, RemoveBookmarks) {
108  views::MenuDelegate test_delegate;
109  const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(1);
110  NewDelegate(0, kint32max);
111  bookmark_menu_delegate_->Init(&test_delegate, NULL, node, 0,
112                                BookmarkMenuDelegate::HIDE_PERMANENT_FOLDERS,
113                                BOOKMARK_LAUNCH_LOCATION_NONE);
114  std::vector<const BookmarkNode*> nodes_to_remove;
115  nodes_to_remove.push_back(node->GetChild(1));
116  bookmark_menu_delegate_->WillRemoveBookmarks(nodes_to_remove);
117  nodes_to_remove.clear();
118  bookmark_menu_delegate_->DidRemoveBookmarks();
119}
120
121// Verifies menu ID's of items in menu fall within the specified range.
122TEST_F(BookmarkMenuDelegateTest, MenuIdRange) {
123  // Start with maximum menu Id of 10 - the number of items that AddTestData()
124  // populated.  Everything should be created.
125  NewAndInitDelegateForPermanent(0, 10);
126  views::MenuItemView* root_item = bookmark_menu_delegate_->menu();
127  ASSERT_TRUE(root_item->HasSubmenu());
128  EXPECT_EQ(4, root_item->GetSubmenu()->GetMenuItemCount());
129  EXPECT_EQ(5, root_item->GetSubmenu()->child_count());  // Includes separator.
130  views::MenuItemView* F1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
131  ASSERT_TRUE(F1_item->HasSubmenu());
132  EXPECT_EQ(2, F1_item->GetSubmenu()->GetMenuItemCount());
133  views::MenuItemView* F11_item = F1_item->GetSubmenu()->GetMenuItemAt(1);
134  ASSERT_TRUE(F11_item->HasSubmenu());
135  EXPECT_EQ(1, F11_item->GetSubmenu()->GetMenuItemCount());
136  views::MenuItemView* other_item = root_item->GetSubmenu()->GetMenuItemAt(3);
137  ASSERT_TRUE(other_item->HasSubmenu());
138  EXPECT_EQ(2, other_item->GetSubmenu()->GetMenuItemCount());
139  views::MenuItemView* OF1_item = other_item->GetSubmenu()->GetMenuItemAt(1);
140  ASSERT_TRUE(OF1_item->HasSubmenu());
141  EXPECT_EQ(1, OF1_item->GetSubmenu()->GetMenuItemCount());
142
143  // Reduce maximum 9.  "of1a" item should not be created.
144  NewAndInitDelegateForPermanent(0, 9);
145  root_item = bookmark_menu_delegate_->menu();
146  EXPECT_EQ(4, root_item->GetSubmenu()->GetMenuItemCount());
147  EXPECT_EQ(5, root_item->GetSubmenu()->child_count());  // Includes separator.
148  other_item = root_item->GetSubmenu()->GetMenuItemAt(3);
149  OF1_item = other_item->GetSubmenu()->GetMenuItemAt(1);
150  EXPECT_EQ(0, OF1_item->GetSubmenu()->GetMenuItemCount());
151
152  // Reduce maximum 8.  "OF1" submenu should not be created.
153  NewAndInitDelegateForPermanent(0, 8);
154  root_item = bookmark_menu_delegate_->menu();
155  EXPECT_EQ(4, root_item->GetSubmenu()->GetMenuItemCount());
156  EXPECT_EQ(5, root_item->GetSubmenu()->child_count());  // Includes separator.
157  other_item = root_item->GetSubmenu()->GetMenuItemAt(3);
158  EXPECT_EQ(1, other_item->GetSubmenu()->GetMenuItemCount());
159
160  // Reduce maximum 7.  "Other" submenu should be empty.
161  NewAndInitDelegateForPermanent(0, 7);
162  root_item = bookmark_menu_delegate_->menu();
163  EXPECT_EQ(4, root_item->GetSubmenu()->GetMenuItemCount());
164  EXPECT_EQ(5, root_item->GetSubmenu()->child_count());  // Includes separator.
165  other_item = root_item->GetSubmenu()->GetMenuItemAt(3);
166  EXPECT_EQ(0, other_item->GetSubmenu()->GetMenuItemCount());
167
168  // Reduce maximum to 6.  "Other" submenu should not be created, and no
169  // separator.
170  NewAndInitDelegateForPermanent(0, 6);
171  root_item = bookmark_menu_delegate_->menu();
172  EXPECT_EQ(3, root_item->GetSubmenu()->GetMenuItemCount());
173  EXPECT_EQ(3, root_item->GetSubmenu()->child_count());  // No separator.
174
175  // Reduce maximum 5.  "F2" and "Other" submenus shouldn't be created.
176  NewAndInitDelegateForPermanent(0, 5);
177  root_item = bookmark_menu_delegate_->menu();
178  EXPECT_EQ(2, root_item->GetSubmenu()->GetMenuItemCount());
179  EXPECT_EQ(2, root_item->GetSubmenu()->child_count());  // No separator.
180  F1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
181  F11_item = F1_item->GetSubmenu()->GetMenuItemAt(1);
182  EXPECT_EQ(1, F11_item->GetSubmenu()->GetMenuItemCount());
183
184  // Reduce maximum to 4.  "f11a" item and "F2" and "Other" submenus should
185  // not be created.
186  NewAndInitDelegateForPermanent(0, 4);
187  root_item = bookmark_menu_delegate_->menu();
188  EXPECT_EQ(2, root_item->GetSubmenu()->GetMenuItemCount());
189  EXPECT_EQ(2, root_item->GetSubmenu()->child_count());  // No separator.
190  F1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
191  F11_item = F1_item->GetSubmenu()->GetMenuItemAt(1);
192  EXPECT_EQ(0, F11_item->GetSubmenu()->GetMenuItemCount());
193
194  // Reduce maximum to 3.  "F11", "F2" and "Other" submenus should not be
195  // created.
196  NewAndInitDelegateForPermanent(0, 3);
197  root_item = bookmark_menu_delegate_->menu();
198  EXPECT_EQ(2, root_item->GetSubmenu()->GetMenuItemCount());
199  EXPECT_EQ(2, root_item->GetSubmenu()->child_count());  // No separator.
200  F1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
201  EXPECT_EQ(views::MenuItemView::SUBMENU, F1_item->GetType());
202  EXPECT_EQ(1, F1_item->GetSubmenu()->GetMenuItemCount());
203
204  // Reduce maximum 2.  Only "a" item and empty "F1" submenu should be created.
205  NewAndInitDelegateForPermanent(0, 2);
206  root_item = bookmark_menu_delegate_->menu();
207  EXPECT_EQ(2, root_item->GetSubmenu()->GetMenuItemCount());
208  EXPECT_EQ(2, root_item->GetSubmenu()->child_count());  // No separator.
209  F1_item = root_item->GetSubmenu()->GetMenuItemAt(1);
210  EXPECT_EQ(views::MenuItemView::SUBMENU, F1_item->GetType());
211  EXPECT_EQ(0, F1_item->GetSubmenu()->GetMenuItemCount());
212
213  // Reduce maximum to 1.  Only "a" item should be created.
214  NewAndInitDelegateForPermanent(0, 1);
215  root_item = bookmark_menu_delegate_->menu();
216  EXPECT_EQ(1, root_item->GetSubmenu()->GetMenuItemCount());
217  EXPECT_EQ(1, root_item->GetSubmenu()->child_count());  // No separator.
218
219  // Verify correct handling of integer overflow with range, set kint32max as
220  // maximum and 1 less as minimum.  Only "a" item should be created.
221  NewAndInitDelegateForPermanent(kint32max - 1, kint32max);
222  root_item = bookmark_menu_delegate_->menu();
223  EXPECT_EQ(1, root_item->GetSubmenu()->GetMenuItemCount());
224  EXPECT_EQ(1, root_item->GetSubmenu()->child_count());  // No separator.
225}
226