summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
blob: 3860ea89f6cb910cf867503e4c42ab53506117bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/toolbar/wrench_menu_model.h"

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/global_error/global_error.h"
#include "chrome/browser/ui/global_error/global_error_service.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/menu_model_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_io_thread_state.h"
#include "chrome/test/base/testing_pref_service_syncable.h"
#include "chrome/test/base/testing_profile.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Error class has a menu item.
class MenuError : public GlobalError {
 public:
  explicit MenuError(int command_id)
      : command_id_(command_id),
        execute_count_(0) {
  }

  int execute_count() { return execute_count_; }

  virtual bool HasMenuItem() OVERRIDE { return true; }
  virtual int MenuItemCommandID() OVERRIDE { return command_id_; }
  virtual string16 MenuItemLabel() OVERRIDE { return string16(); }
  virtual void ExecuteMenuItem(Browser* browser) OVERRIDE { execute_count_++; }

  virtual bool HasBubbleView() OVERRIDE { return false; }
  virtual bool HasShownBubbleView() OVERRIDE { return false; }
  virtual void ShowBubbleView(Browser* browser) OVERRIDE { ADD_FAILURE(); }
  virtual GlobalErrorBubbleViewBase* GetBubbleView() OVERRIDE { return NULL; }

 private:
  int command_id_;
  int execute_count_;

  DISALLOW_COPY_AND_ASSIGN(MenuError);
};

} // namespace

class WrenchMenuModelTest : public BrowserWithTestWindowTest,
                            public ui::AcceleratorProvider {
 public:
  // Don't handle accelerators.
  virtual bool GetAcceleratorForCommandId(
      int command_id,
      ui::Accelerator* accelerator) OVERRIDE { return false; }

 protected:
  virtual void SetUp() OVERRIDE {
    prefs_.reset(new TestingPrefServiceSimple());
    chrome::RegisterLocalState(prefs_->registry());

    TestingBrowserProcess::GetGlobal()->SetLocalState(prefs_.get());
    testing_io_thread_state_.reset(new chrome::TestingIOThreadState());
    BrowserWithTestWindowTest::SetUp();
  }

  virtual void TearDown() OVERRIDE {
    BrowserWithTestWindowTest::TearDown();
    testing_io_thread_state_.reset();
    TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
    DestroyBrowserAndProfile();
  }

 private:
  scoped_ptr<TestingPrefServiceSimple> prefs_;
  scoped_ptr<chrome::TestingIOThreadState> testing_io_thread_state_;
};

// Copies parts of MenuModelTest::Delegate and combines them with the
// WrenchMenuModel since WrenchMenuModel is now a SimpleMenuModel::Delegate and
// not derived from SimpleMenuModel.
class TestWrenchMenuModel : public WrenchMenuModel {
 public:
  TestWrenchMenuModel(ui::AcceleratorProvider* provider,
                      Browser* browser)
      : WrenchMenuModel(provider, browser, false),
        execute_count_(0),
        checked_count_(0),
        enable_count_(0) {
  }

  // Testing overrides to ui::SimpleMenuModel::Delegate:
  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
    bool val = WrenchMenuModel::IsCommandIdChecked(command_id);
    if (val)
      checked_count_++;
    return val;
  }

  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
    ++enable_count_;
    return true;
  }

  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
    ++execute_count_;
  }

  int execute_count_;
  mutable int checked_count_;
  mutable int enable_count_;
};

TEST_F(WrenchMenuModelTest, Basics) {
  TestWrenchMenuModel model(this, browser());
  int itemCount = model.GetItemCount();

  // Verify it has items. The number varies by platform, so we don't check
  // the exact number.
  EXPECT_GT(itemCount, 10);

  // Execute a couple of the items and make sure it gets back to our delegate.
  // We can't use CountEnabledExecutable() here because the encoding menu's
  // delegate is internal, it doesn't use the one we pass in.
  // Note: The new menu has a spacing separator at the first slot.
  model.ActivatedAt(1);
  EXPECT_TRUE(model.IsEnabledAt(1));
  // Make sure to use the index that is not separator in all configurations.
  model.ActivatedAt(2);
  EXPECT_TRUE(model.IsEnabledAt(2));
  EXPECT_EQ(model.execute_count_, 2);
  EXPECT_EQ(model.enable_count_, 2);

  model.execute_count_ = 0;
  model.enable_count_ = 0;

  // Choose something from the bookmark submenu and make sure it makes it back
  // to the delegate as well.
  int bookmarksModelIndex = -1;
  for (int i = 0; i < itemCount; ++i) {
    if (model.GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU) {
      bookmarksModelIndex = i;
      break;
    }
  }
  EXPECT_GT(bookmarksModelIndex, -1);
  ui::MenuModel* bookmarksModel = model.GetSubmenuModelAt(bookmarksModelIndex);
  EXPECT_TRUE(bookmarksModel);
  // The bookmarks model may be empty until we tell it we're going to show it.
  bookmarksModel->MenuWillShow();
  EXPECT_GT(bookmarksModel->GetItemCount(), 1);
  bookmarksModel->ActivatedAt(1);
  EXPECT_TRUE(bookmarksModel->IsEnabledAt(1));
  EXPECT_EQ(model.execute_count_, 1);
  EXPECT_EQ(model.enable_count_, 1);
}

// Tests global error menu items in the wrench menu.
TEST_F(WrenchMenuModelTest, GlobalError) {
  // Make sure services required for tests are initialized.
  GlobalErrorService* service =
      GlobalErrorServiceFactory::GetForProfile(browser()->profile());
  ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile());
  const int command1 = 1234567;
  // AddGlobalError takes ownership of error1.
  MenuError* error1 = new MenuError(command1);
  service->AddGlobalError(error1);
  const int command2 = 1234568;
  // AddGlobalError takes ownership of error2.
  MenuError* error2 = new MenuError(command2);
  service->AddGlobalError(error2);

  WrenchMenuModel model(this, browser(), false);
  int index1 = model.GetIndexOfCommandId(command1);
  EXPECT_GT(index1, -1);
  int index2 = model.GetIndexOfCommandId(command2);
  EXPECT_GT(index2, -1);

  EXPECT_TRUE(model.IsEnabledAt(index1));
  EXPECT_EQ(0, error1->execute_count());
  model.ActivatedAt(index1);
  EXPECT_EQ(1, error1->execute_count());

  EXPECT_TRUE(model.IsEnabledAt(index2));
  EXPECT_EQ(0, error2->execute_count());
  model.ActivatedAt(index2);
  EXPECT_EQ(1, error1->execute_count());
}

class EncodingMenuModelTest : public BrowserWithTestWindowTest,
                              public MenuModelTest {
};

TEST_F(EncodingMenuModelTest, IsCommandIdCheckedWithNoTabs) {
  EncodingMenuModel model(browser());
  ASSERT_EQ(NULL, browser()->tab_strip_model()->GetActiveWebContents());
  EXPECT_FALSE(model.IsCommandIdChecked(IDC_ENCODING_ISO88591));
}