Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(776)

Side by Side Diff: chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller_unittest.mm

Issue 1419993010: chrome: Rename WrenchMenuController to AppMenuController. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rewrap comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "base/command_line.h"
6 #include "base/mac/scoped_nsobject.h"
7 #include "base/run_loop.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/app/chrome_command_ids.h"
11 #include "chrome/browser/sync/profile_sync_service_factory.h"
12 #include "chrome/browser/ui/browser_list.h"
13 #include "chrome/browser/ui/browser_list_observer.h"
14 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
15 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
16 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
17 #import "chrome/browser/ui/cocoa/view_resizer_pong.h"
18 #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h"
19 #include "chrome/browser/ui/sync/browser_synced_window_delegates_getter.h"
20 #include "chrome/browser/ui/toolbar/app_menu_model.h"
21 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
22 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "chrome/test/base/testing_profile.h"
26 #include "components/browser_sync/browser/profile_sync_service.h"
27 #include "components/sync_driver/local_device_info_provider_mock.h"
28 #include "components/sync_driver/sync_client.h"
29 #include "components/sync_driver/sync_prefs.h"
30 #include "components/sync_sessions/fake_sync_sessions_client.h"
31 #include "components/sync_sessions/sessions_sync_manager.h"
32 #include "grit/theme_resources.h"
33 #include "sync/api/fake_sync_change_processor.h"
34 #include "sync/api/sync_error_factory_mock.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "testing/gtest_mac.h"
38 #include "testing/platform_test.h"
39 #include "ui/base/l10n/l10n_util.h"
40 #include "ui/base/resource/resource_bundle.h"
41
42 namespace {
43
44 class MockAppMenuModel : public AppMenuModel {
45 public:
46 MockAppMenuModel() : AppMenuModel() {}
47 ~MockAppMenuModel() {}
48 MOCK_METHOD2(ExecuteCommand, void(int command_id, int event_flags));
49 };
50
51 class DummyRouter : public browser_sync::LocalSessionEventRouter {
52 public:
53 ~DummyRouter() override {}
54 void StartRoutingTo(
55 browser_sync::LocalSessionEventHandler* handler) override {}
56 void Stop() override {}
57 };
58
59 class WrenchMenuControllerTest
60 : public CocoaProfileTest {
61 public:
62 WrenchMenuControllerTest()
63 : local_device_(new sync_driver::LocalDeviceInfoProviderMock(
64 "WrenchMenuControllerTest",
65 "Test Machine",
66 "Chromium 10k",
67 "Chrome 10k",
68 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
69 "device_id")) {
70 }
71
72 void SetUp() override {
73 CocoaProfileTest::SetUp();
74 ASSERT_TRUE(browser());
75
76 controller_.reset([[WrenchMenuController alloc] initWithBrowser:browser()]);
77 fake_model_.reset(new MockAppMenuModel);
78
79 sync_prefs_.reset(new sync_driver::SyncPrefs(profile()->GetPrefs()));
80 manager_.reset(new browser_sync::SessionsSyncManager(
81 ProfileSyncServiceFactory::GetForProfile(profile())
82 ->GetSyncClient()
83 ->GetSyncSessionsClient(),
84 sync_prefs_.get(), local_device_.get(),
85 scoped_ptr<browser_sync::LocalSessionEventRouter>(new DummyRouter()),
86 base::Closure(), base::Closure()));
87 manager_->MergeDataAndStartSyncing(
88 syncer::SESSIONS,
89 syncer::SyncDataList(),
90 scoped_ptr<syncer::SyncChangeProcessor>(
91 new syncer::FakeSyncChangeProcessor),
92 scoped_ptr<syncer::SyncErrorFactory>(
93 new syncer::SyncErrorFactoryMock));
94 }
95
96 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
97 helper->ExportToSessionsSyncManager(manager_.get());
98 }
99
100 sync_driver::OpenTabsUIDelegate* GetOpenTabsDelegate() {
101 return manager_.get();
102 }
103
104 void TearDown() override {
105 fake_model_.reset();
106 controller_.reset();
107 manager_.reset();
108 CocoaProfileTest::TearDown();
109 }
110
111 WrenchMenuController* controller() {
112 return controller_.get();
113 }
114
115 base::scoped_nsobject<WrenchMenuController> controller_;
116
117 scoped_ptr<MockAppMenuModel> fake_model_;
118
119 private:
120 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
121 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
122 scoped_ptr<sync_driver::LocalDeviceInfoProviderMock> local_device_;
123 };
124
125 TEST_F(WrenchMenuControllerTest, Initialized) {
126 EXPECT_TRUE([controller() menu]);
127 EXPECT_GE([[controller() menu] numberOfItems], 5);
128 }
129
130 TEST_F(WrenchMenuControllerTest, DispatchSimple) {
131 base::scoped_nsobject<NSButton> button([[NSButton alloc] init]);
132 [button setTag:IDC_ZOOM_PLUS];
133
134 // Set fake model to test dispatching.
135 EXPECT_CALL(*fake_model_, ExecuteCommand(IDC_ZOOM_PLUS, 0));
136 [controller() setModel:fake_model_.get()];
137
138 [controller() dispatchWrenchMenuCommand:button.get()];
139 chrome::testing::NSRunLoopRunAllPending();
140 }
141
142 TEST_F(WrenchMenuControllerTest, RecentTabsFavIcon) {
143 RecentTabsBuilderTestHelper recent_tabs_builder;
144 recent_tabs_builder.AddSession();
145 recent_tabs_builder.AddWindow(0);
146 recent_tabs_builder.AddTab(0, 0);
147 RegisterRecentTabs(&recent_tabs_builder);
148
149 RecentTabsSubMenuModel recent_tabs_sub_menu_model(
150 NULL, browser(), GetOpenTabsDelegate());
151 fake_model_->AddSubMenuWithStringId(
152 IDC_RECENT_TABS_MENU, IDS_RECENT_TABS_MENU,
153 &recent_tabs_sub_menu_model);
154
155 [controller() setModel:fake_model_.get()];
156 NSMenu* menu = [controller() menu];
157 [controller() updateRecentTabsSubmenu];
158
159 NSString* title = l10n_util::GetNSStringWithFixup(IDS_RECENT_TABS_MENU);
160 NSMenu* recent_tabs_menu = [[menu itemWithTitle:title] submenu];
161 EXPECT_TRUE(recent_tabs_menu);
162 EXPECT_EQ(6, [recent_tabs_menu numberOfItems]);
163
164 // Send a icon changed event and verify that the icon is updated.
165 gfx::Image icon(ResourceBundle::GetSharedInstance().GetNativeImageNamed(
166 IDR_BOOKMARKS_FAVICON));
167 recent_tabs_sub_menu_model.SetIcon(3, icon);
168 EXPECT_NSNE(icon.ToNSImage(), [[recent_tabs_menu itemAtIndex:3] image]);
169 recent_tabs_sub_menu_model.GetMenuModelDelegate()->OnIconChanged(3);
170 EXPECT_TRUE([[recent_tabs_menu itemAtIndex:3] image]);
171 EXPECT_NSEQ(icon.ToNSImage(), [[recent_tabs_menu itemAtIndex:3] image]);
172
173 controller_.reset();
174 fake_model_.reset();
175 }
176
177 TEST_F(WrenchMenuControllerTest, RecentTabsElideTitle) {
178 // Add 1 session with 1 window and 2 tabs.
179 RecentTabsBuilderTestHelper recent_tabs_builder;
180 recent_tabs_builder.AddSession();
181 recent_tabs_builder.AddWindow(0);
182 base::string16 tab1_short_title = base::ASCIIToUTF16("Short");
183 recent_tabs_builder.AddTabWithInfo(0, 0, base::Time::Now(), tab1_short_title);
184 base::string16 tab2_long_title = base::ASCIIToUTF16(
185 "Very very very very very very very very very very very very long");
186 recent_tabs_builder.AddTabWithInfo(0, 0,
187 base::Time::Now() - base::TimeDelta::FromMinutes(10), tab2_long_title);
188 RegisterRecentTabs(&recent_tabs_builder);
189
190 RecentTabsSubMenuModel recent_tabs_sub_menu_model(
191 NULL, browser(), GetOpenTabsDelegate());
192 fake_model_->AddSubMenuWithStringId(
193 IDC_RECENT_TABS_MENU, IDS_RECENT_TABS_MENU,
194 &recent_tabs_sub_menu_model);
195
196 [controller() setModel:fake_model_.get()];
197 NSMenu* menu = [controller() menu];
198 [controller() updateRecentTabsSubmenu];
199
200 NSString* title = l10n_util::GetNSStringWithFixup(IDS_RECENT_TABS_MENU);
201 NSMenu* recent_tabs_menu = [[menu itemWithTitle:title] submenu];
202 EXPECT_TRUE(recent_tabs_menu);
203 EXPECT_EQ(7, [recent_tabs_menu numberOfItems]);
204
205 // Item 1: separator.
206 EXPECT_TRUE([[recent_tabs_menu itemAtIndex:1] isSeparatorItem]);
207
208 // Index 2: restore tabs menu item.
209 NSString* restore_tab_label = l10n_util::FixUpWindowsStyleLabel(
210 recent_tabs_sub_menu_model.GetLabelAt(2));
211 EXPECT_NSEQ(restore_tab_label, [[recent_tabs_menu itemAtIndex:2] title]);
212
213 // Item 3: separator.
214 EXPECT_TRUE([[recent_tabs_menu itemAtIndex:3] isSeparatorItem]);
215
216 // Item 4: window title.
217 EXPECT_NSEQ(
218 base::SysUTF16ToNSString(recent_tabs_sub_menu_model.GetLabelAt(4)),
219 [[recent_tabs_menu itemAtIndex:4] title]);
220
221 // Item 5: short tab title.
222 EXPECT_NSEQ(base::SysUTF16ToNSString(tab1_short_title),
223 [[recent_tabs_menu itemAtIndex:5] title]);
224
225 // Item 6: long tab title.
226 NSString* tab2_actual_title = [[recent_tabs_menu itemAtIndex:6] title];
227 NSUInteger title_length = [tab2_actual_title length];
228 EXPECT_GT(tab2_long_title.size(), title_length);
229 NSString* actual_substring =
230 [tab2_actual_title substringToIndex:title_length - 1];
231 NSString* expected_substring = [base::SysUTF16ToNSString(tab2_long_title)
232 substringToIndex:title_length - 1];
233 EXPECT_NSEQ(expected_substring, actual_substring);
234
235 controller_.reset();
236 fake_model_.reset();
237 }
238
239 // Verify that |RecentTabsMenuModelDelegate| is deleted before the model
240 // it's observing.
241 TEST_F(WrenchMenuControllerTest, RecentTabDeleteOrder) {
242 [controller_ menuNeedsUpdate:[controller_ menu]];
243 // If the delete order is wrong then the test will crash on exit.
244 }
245
246 class BrowserRemovedObserver : public chrome::BrowserListObserver {
247 public:
248 BrowserRemovedObserver() { BrowserList::AddObserver(this); }
249 ~BrowserRemovedObserver() override { BrowserList::RemoveObserver(this); }
250 void WaitUntilBrowserRemoved() { run_loop_.Run(); }
251 void OnBrowserRemoved(Browser* browser) override { run_loop_.Quit(); }
252
253 private:
254 base::RunLoop run_loop_;
255
256 DISALLOW_COPY_AND_ASSIGN(BrowserRemovedObserver);
257 };
258
259 // Test that WrenchMenuController can be destroyed after the Browser.
260 // This can happen because the WrenchMenuController's owner (ToolbarController)
261 // can outlive the Browser.
262 TEST_F(WrenchMenuControllerTest, DestroyedAfterBrowser) {
263 BrowserRemovedObserver observer;
264 // This is normally called by ToolbarController, but since |controller_| is
265 // not owned by one, call it here.
266 [controller_ browserWillBeDestroyed];
267 CloseBrowserWindow();
268 observer.WaitUntilBrowserRemoved();
269 // |controller_| is released in TearDown().
270 }
271
272 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.mm ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698