Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / recent_tabs_sub_menu_model_unittest.cc
blob0ed6ffc56fd67b8ee4112409451f88143b9c5337
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.
5 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/sessions/session_service.h"
11 #include "chrome/browser/sessions/session_service_factory.h"
12 #include "chrome/browser/sessions/session_types.h"
13 #include "chrome/browser/sessions/persistent_tab_restore_service.h"
14 #include "chrome/browser/sessions/tab_restore_service_factory.h"
15 #include "chrome/browser/sync/glue/session_model_associator.h"
16 #include "chrome/browser/sync/glue/synced_session.h"
17 #include "chrome/browser/sync/profile_sync_service_mock.h"
18 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_tabstrip.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/test/base/browser_with_test_window_test.h"
25 #include "chrome/test/base/menu_model_test.h"
26 #include "chrome/test/base/testing_profile.h"
27 #include "components/sessions/serialized_navigation_entry_test_helper.h"
28 #include "grit/generated_resources.h"
29 #include "sync/api/fake_sync_change_processor.h"
30 #include "sync/api/sync_error_factory_mock.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 namespace {
36 // This copies parts of MenuModelTest::Delegate and combines them with the
37 // RecentTabsSubMenuModel since RecentTabsSubMenuModel is a
38 // SimpleMenuModel::Delegate and not just derived from SimpleMenuModel.
39 class TestRecentTabsSubMenuModel : public RecentTabsSubMenuModel {
40 public:
41 TestRecentTabsSubMenuModel(ui::AcceleratorProvider* provider,
42 Browser* browser,
43 browser_sync::OpenTabsUIDelegate* delegate)
44 : RecentTabsSubMenuModel(provider, browser, delegate),
45 execute_count_(0),
46 enable_count_(0) {
49 // Testing overrides to ui::SimpleMenuModel::Delegate:
50 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
51 bool val = RecentTabsSubMenuModel::IsCommandIdEnabled(command_id);
52 if (val)
53 ++enable_count_;
54 return val;
57 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
58 ++execute_count_;
61 int execute_count() const { return execute_count_; }
62 int enable_count() const { return enable_count_; }
64 private:
65 int execute_count_;
66 int mutable enable_count_; // Mutable because IsCommandIdEnabledAt is const.
68 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsSubMenuModel);
71 class TestRecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
72 public:
73 explicit TestRecentTabsMenuModelDelegate(ui::MenuModel* model)
74 : model_(model),
75 got_changes_(false) {
76 model_->SetMenuModelDelegate(this);
79 virtual ~TestRecentTabsMenuModelDelegate() {
80 model_->SetMenuModelDelegate(NULL);
83 // ui::MenuModelDelegate implementation:
85 virtual void OnIconChanged(int index) OVERRIDE {
88 virtual void OnMenuStructureChanged() OVERRIDE {
89 got_changes_ = true;
92 bool got_changes() const { return got_changes_; }
94 private:
95 ui::MenuModel* model_;
96 bool got_changes_;
98 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsMenuModelDelegate);
101 class DummyRouter : public browser_sync::LocalSessionEventRouter {
102 public:
103 virtual ~DummyRouter() {}
104 virtual void StartRoutingTo(
105 browser_sync::LocalSessionEventHandler* handler) OVERRIDE {}
106 virtual void Stop() OVERRIDE {}
109 } // namespace
111 class RecentTabsSubMenuModelTest
112 : public BrowserWithTestWindowTest,
113 public browser_sync::SessionsSyncManager::SyncInternalApiDelegate {
114 public:
115 RecentTabsSubMenuModelTest()
116 : sync_service_(&testing_profile_) {
117 if (CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kEnableSyncSessionsV2)) {
119 manager_.reset(new browser_sync::SessionsSyncManager(
120 &testing_profile_,
121 this,
122 scoped_ptr<browser_sync::LocalSessionEventRouter>(
123 new DummyRouter())));
124 manager_->MergeDataAndStartSyncing(
125 syncer::SESSIONS,
126 syncer::SyncDataList(),
127 scoped_ptr<syncer::SyncChangeProcessor>(
128 new syncer::FakeSyncChangeProcessor),
129 scoped_ptr<syncer::SyncErrorFactory>(
130 new syncer::SyncErrorFactoryMock));
131 } else {
132 associator_.reset(new browser_sync::SessionModelAssociator(
133 &sync_service_, true));
134 associator_->SetCurrentMachineTagForTesting(
135 GetLocalSyncCacheGUID());
139 void WaitForLoadFromLastSession() {
140 content::BrowserThread::GetBlockingPool()->FlushForTesting();
141 base::RunLoop().RunUntilIdle();
142 content::BrowserThread::GetBlockingPool()->FlushForTesting();
145 static BrowserContextKeyedService* GetTabRestoreService(
146 content::BrowserContext* browser_context) {
147 // Ownership is tranfered to the profile.
148 return new PersistentTabRestoreService(
149 Profile::FromBrowserContext(browser_context), NULL);;
153 browser_sync::OpenTabsUIDelegate* GetOpenTabsDelegate() {
154 if (CommandLine::ForCurrentProcess()->HasSwitch(
155 switches::kEnableSyncSessionsV2)) {
156 return manager_.get();
157 } else {
158 return associator_.get();
162 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
163 if (CommandLine::ForCurrentProcess()->HasSwitch(
164 switches::kEnableSyncSessionsV2)) {
165 helper->ExportToSessionsSyncManager(manager_.get());
166 } else {
167 helper->ExportToSessionModelAssociator(associator_.get());
171 virtual scoped_ptr<browser_sync::DeviceInfo> GetLocalDeviceInfo()
172 const OVERRIDE {
173 return scoped_ptr<browser_sync::DeviceInfo>(
174 new browser_sync::DeviceInfo(GetLocalSyncCacheGUID(),
175 "Test Machine",
176 "Chromium 10k",
177 "Chrome 10k",
178 sync_pb::SyncEnums_DeviceType_TYPE_LINUX));
181 virtual std::string GetLocalSyncCacheGUID() const OVERRIDE {
182 return "RecentTabsSubMenuModelTest";
185 private:
186 TestingProfile testing_profile_;
187 testing::NiceMock<ProfileSyncServiceMock> sync_service_;
189 // TODO(tim): Remove associator_ when sessions V2 is the default, bug 98892.
190 scoped_ptr<browser_sync::SessionModelAssociator> associator_;
191 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
194 // Test disabled "Recently closed" header with no foreign tabs.
195 TEST_F(RecentTabsSubMenuModelTest, NoTabs) {
196 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
198 // Expected menu:
199 // Menu index Menu items
200 // ---------------------------------------------
201 // 0 Recently closed header (disabled)
202 // 1 <separator>
203 // 2 No tabs from other Devices
205 int num_items = model.GetItemCount();
206 EXPECT_EQ(3, num_items);
207 EXPECT_FALSE(model.IsEnabledAt(0));
208 EXPECT_FALSE(model.IsEnabledAt(2));
209 EXPECT_EQ(0, model.enable_count());
211 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
212 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
213 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
215 std::string url;
216 base::string16 title;
217 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
218 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
219 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
222 // Test enabled "Recently closed" header with no foreign tabs.
223 TEST_F(RecentTabsSubMenuModelTest, RecentlyClosedTabsFromCurrentSession) {
224 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
225 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
227 // Add 2 tabs and close them.
228 AddTab(browser(), GURL("http://foo/1"));
229 AddTab(browser(), GURL("http://foo/2"));
230 browser()->tab_strip_model()->CloseAllTabs();
232 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
233 // Expected menu:
234 // Menu index Menu items
235 // --------------------------------------
236 // 0 Recently closed header
237 // 1 <tab for http://foo/2>
238 // 2 <tab for http://foo/1>
239 // 3 <separator>
240 // 4 No tabs from other Devices
241 int num_items = model.GetItemCount();
242 EXPECT_EQ(5, num_items);
243 EXPECT_FALSE(model.IsEnabledAt(0));
244 EXPECT_TRUE(model.IsEnabledAt(1));
245 EXPECT_TRUE(model.IsEnabledAt(2));
246 model.ActivatedAt(1);
247 model.ActivatedAt(2);
248 EXPECT_FALSE(model.IsEnabledAt(4));
249 EXPECT_EQ(2, model.enable_count());
250 EXPECT_EQ(2, model.execute_count());
252 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
253 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
254 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
255 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
256 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
258 std::string url;
259 base::string16 title;
260 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
261 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
262 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
263 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
264 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
267 // TODO(sail): enable this test when dynamic model is enabled in
268 // RecentTabsSubMenuModel.
269 #if defined(OS_MACOSX)
270 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
271 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
272 #else
273 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
274 RecentlyClosedTabsAndWindowsFromLastSession
275 #endif
276 TEST_F(RecentTabsSubMenuModelTest,
277 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession) {
278 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
279 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
281 // Add 2 tabs and close them.
282 AddTab(browser(), GURL("http://wnd/tab0"));
283 AddTab(browser(), GURL("http://wnd/tab1"));
284 browser()->tab_strip_model()->CloseAllTabs();
286 // Create a SessionService for the profile (profile owns the service) and add
287 // a window with a tab to this session.
288 SessionService* session_service = new SessionService(profile());
289 SessionServiceFactory::SetForTestProfile(profile(), session_service);
290 SessionID tab_id;
291 SessionID window_id;
292 session_service->SetWindowType(
293 window_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
294 session_service->SetTabWindow(window_id, tab_id);
295 session_service->SetTabIndexInWindow(window_id, tab_id, 0);
296 session_service->SetSelectedTabInWindow(window_id, 0);
297 session_service->UpdateTabNavigation(
298 window_id, tab_id,
299 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
300 "http://wnd1/tab0", "title"));
301 // Set this, otherwise previous session won't be loaded.
302 profile()->set_last_session_exited_cleanly(false);
303 // Move this session to the last so that TabRestoreService will load it as the
304 // last session.
305 SessionServiceFactory::GetForProfile(profile())->
306 MoveCurrentSessionToLastSession();
308 // Create a new TabRestoreService so that it'll load the recently closed tabs
309 // and windows afresh.
310 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
311 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
312 // Let the shutdown of previous TabRestoreService run.
313 content::BrowserThread::GetBlockingPool()->FlushForTesting();
315 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
316 TestRecentTabsMenuModelDelegate delegate(&model);
317 EXPECT_FALSE(delegate.got_changes());
319 // Expected menu before tabs/windows from last session are loaded:
320 // Menu index Menu items
321 // ----------------------------------------------------------------
322 // 0 Recently closed header
323 // 1 <separator>
324 // 2 No tabs from other Devices
326 int num_items = model.GetItemCount();
327 EXPECT_EQ(3, num_items);
328 EXPECT_FALSE(model.IsEnabledAt(0));
329 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
330 EXPECT_FALSE(model.IsEnabledAt(2));
331 EXPECT_EQ(0, model.enable_count());
333 // Wait for tabs from last session to be loaded.
334 WaitForLoadFromLastSession();
336 // Expected menu after tabs/windows from last session are loaded:
337 // Menu index Menu items
338 // --------------------------------------------------------------
339 // 0 Recently closed header
340 // 1 <window for the tab http://wnd1/tab0>
341 // 2 <tab for http://wnd0/tab1>
342 // 3 <tab for http://wnd0/tab0>
343 // 4 <separator>
344 // 5 No tabs from other Devices
346 EXPECT_TRUE(delegate.got_changes());
348 num_items = model.GetItemCount();
349 EXPECT_EQ(6, num_items);
350 EXPECT_FALSE(model.IsEnabledAt(0));
351 EXPECT_TRUE(model.IsEnabledAt(1));
352 EXPECT_TRUE(model.IsEnabledAt(2));
353 EXPECT_TRUE(model.IsEnabledAt(3));
354 model.ActivatedAt(1);
355 model.ActivatedAt(2);
356 model.ActivatedAt(3);
357 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(4));
358 EXPECT_FALSE(model.IsEnabledAt(5));
359 EXPECT_EQ(3, model.enable_count());
360 EXPECT_EQ(3, model.execute_count());
362 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
363 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
364 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
365 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
366 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
367 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
369 std::string url;
370 base::string16 title;
371 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
372 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
373 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
374 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
375 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
376 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
379 // Test disabled "Recently closed" header with multiple sessions, multiple
380 // windows, and multiple enabled tabs from other devices.
381 TEST_F(RecentTabsSubMenuModelTest, OtherDevices) {
382 // Tabs are populated in decreasing timestamp.
383 base::Time timestamp = base::Time::Now();
384 const base::TimeDelta time_delta = base::TimeDelta::FromMinutes(10);
386 RecentTabsBuilderTestHelper recent_tabs_builder;
388 // Create 1st session : 1 window, 3 tabs
389 recent_tabs_builder.AddSession();
390 recent_tabs_builder.AddWindow(0);
391 for (int i = 0; i < 3; ++i) {
392 timestamp -= time_delta;
393 recent_tabs_builder.AddTabWithInfo(0, 0, timestamp, base::string16());
396 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
397 recent_tabs_builder.AddSession();
398 recent_tabs_builder.AddWindow(1);
399 recent_tabs_builder.AddWindow(1);
400 timestamp -= time_delta;
401 recent_tabs_builder.AddTabWithInfo(1, 0, timestamp, base::string16());
402 timestamp -= time_delta;
403 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
404 timestamp -= time_delta;
405 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
407 RegisterRecentTabs(&recent_tabs_builder);
409 // Verify that data is populated correctly in RecentTabsSubMenuModel.
410 // Expected menu:
411 // - first inserted tab is most recent and hence is top
412 // Menu index Menu items
413 // -----------------------------------------------------
414 // 0 Recently closed header (disabled)
415 // 1 <separator>
416 // 2 <section header for 1st session>
417 // 3-5 <3 tabs of the only window of session 0>
418 // 6 <separator>
419 // 7 <section header for 2nd session>
420 // 8 <the only tab of window 0 of session 1>
421 // 9-10 <2 tabs of window 1 of session 2>
422 // 11 <separator>
423 // 12 More...
425 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
426 int num_items = model.GetItemCount();
427 EXPECT_EQ(13, num_items);
428 model.ActivatedAt(0);
429 EXPECT_FALSE(model.IsEnabledAt(0));
430 model.ActivatedAt(3);
431 EXPECT_TRUE(model.IsEnabledAt(3));
432 model.ActivatedAt(4);
433 EXPECT_TRUE(model.IsEnabledAt(4));
434 model.ActivatedAt(5);
435 EXPECT_TRUE(model.IsEnabledAt(5));
436 model.ActivatedAt(8);
437 EXPECT_TRUE(model.IsEnabledAt(8));
438 model.ActivatedAt(9);
439 EXPECT_TRUE(model.IsEnabledAt(9));
440 model.ActivatedAt(10);
441 EXPECT_TRUE(model.IsEnabledAt(10));
442 EXPECT_TRUE(model.IsEnabledAt(12));
443 EXPECT_EQ(7, model.enable_count());
444 EXPECT_EQ(7, model.execute_count());
446 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
447 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
448 EXPECT_TRUE(model.GetLabelFontListAt(2) != NULL);
449 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
450 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
451 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
452 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
453 EXPECT_TRUE(model.GetLabelFontListAt(7) != NULL);
454 EXPECT_EQ(NULL, model.GetLabelFontListAt(8));
455 EXPECT_EQ(NULL, model.GetLabelFontListAt(9));
456 EXPECT_EQ(NULL, model.GetLabelFontListAt(10));
457 EXPECT_EQ(NULL, model.GetLabelFontListAt(11));
458 EXPECT_EQ(NULL, model.GetLabelFontListAt(12));
460 std::string url;
461 base::string16 title;
462 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
463 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
464 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
465 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
466 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
467 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
468 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
469 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
470 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(8, &url, &title));
471 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(9, &url, &title));
472 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(10, &url, &title));
473 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(11, &url, &title));
474 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(12, &url, &title));
477 TEST_F(RecentTabsSubMenuModelTest, MaxSessionsAndRecency) {
478 // Create 4 sessions : each session has 1 window with 1 tab each.
479 RecentTabsBuilderTestHelper recent_tabs_builder;
480 for (int s = 0; s < 4; ++s) {
481 recent_tabs_builder.AddSession();
482 recent_tabs_builder.AddWindow(s);
483 recent_tabs_builder.AddTab(s, 0);
485 RegisterRecentTabs(&recent_tabs_builder);
487 // Verify that data is populated correctly in RecentTabsSubMenuModel.
488 // Expected menu:
489 // - max sessions is 3, so only 3 most-recent sessions will show.
490 // Menu index Menu items
491 // ----------------------------------------------------------
492 // 0 Recently closed header (disabled)
493 // 1 <separator>
494 // 2 <section header for 1st session>
495 // 3 <the only tab of the only window of session 3>
496 // 4 <separator>
497 // 5 <section header for 2nd session>
498 // 6 <the only tab of the only window of session 2>
499 // 7 <separator>
500 // 8 <section header for 3rd session>
501 // 9 <the only tab of the only window of session 1>
502 // 10 <separator>
503 // 11 More...
505 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
506 int num_items = model.GetItemCount();
507 EXPECT_EQ(12, num_items);
509 std::vector<base::string16> tab_titles =
510 recent_tabs_builder.GetTabTitlesSortedByRecency();
511 EXPECT_EQ(tab_titles[0], model.GetLabelAt(3));
512 EXPECT_EQ(tab_titles[1], model.GetLabelAt(6));
513 EXPECT_EQ(tab_titles[2], model.GetLabelAt(9));
516 TEST_F(RecentTabsSubMenuModelTest, MaxTabsPerSessionAndRecency) {
517 // Create a session: 2 windows with 5 tabs each.
518 RecentTabsBuilderTestHelper recent_tabs_builder;
519 recent_tabs_builder.AddSession();
520 for (int w = 0; w < 2; ++w) {
521 recent_tabs_builder.AddWindow(0);
522 for (int t = 0; t < 5; ++t)
523 recent_tabs_builder.AddTab(0, w);
525 RegisterRecentTabs(&recent_tabs_builder);
527 // Verify that data is populated correctly in RecentTabsSubMenuModel.
528 // Expected menu:
529 // - max tabs per session is 4, so only 4 most-recent tabs will show,
530 // independent of which window they came from.
531 // Menu index Menu items
532 // ---------------------------------------------
533 // 0 Recently closed header (disabled)
534 // 1 <separator>
535 // 2 <section header for session>
536 // 3-6 <4 most-recent tabs of session>
537 // 7 <separator>
538 // 8 More...
540 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
541 int num_items = model.GetItemCount();
542 EXPECT_EQ(9, num_items);
544 std::vector<base::string16> tab_titles =
545 recent_tabs_builder.GetTabTitlesSortedByRecency();
546 for (int i = 0; i < 4; ++i)
547 EXPECT_EQ(tab_titles[i], model.GetLabelAt(i + 3));
550 TEST_F(RecentTabsSubMenuModelTest, MaxWidth) {
551 // Create 1 session with 1 window and 1 tab.
552 RecentTabsBuilderTestHelper recent_tabs_builder;
553 recent_tabs_builder.AddSession();
554 recent_tabs_builder.AddWindow(0);
555 recent_tabs_builder.AddTab(0, 0);
556 RegisterRecentTabs(&recent_tabs_builder);
558 // Menu index Menu items
559 // ----------------------------------------------------------
560 // 0 Recently closed header (disabled)
561 // 1 <separator>
562 // 2 <section header for 1st session>
563 // 3 <the only tab of the only window of session 1>
564 // 4 <separator>
565 // 5 More...
567 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
568 EXPECT_EQ(6, model.GetItemCount());
569 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
570 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
571 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(2));
572 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
575 TEST_F(RecentTabsSubMenuModelTest, MaxWidthNoDevices) {
576 // Expected menu:
577 // Menu index Menu items
578 // --------------------------------------------
579 // 0 Recently closed heaer (disabled)
580 // 1 <separator>
581 // 2 No tabs from other Devices
583 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
584 EXPECT_EQ(3, model.GetItemCount());
585 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
586 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
587 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));