1 // Copyright 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"
10 #include "base/command_line.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/sessions/persistent_tab_restore_service.h"
15 #include "chrome/browser/sessions/session_service.h"
16 #include "chrome/browser/sessions/session_service_factory.h"
17 #include "chrome/browser/sessions/tab_restore_service_factory.h"
18 #include "chrome/browser/sync/profile_sync_service_mock.h"
19 #include "chrome/browser/sync/sessions/sessions_sync_manager.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_tabstrip.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/test/base/browser_with_test_window_test.h"
26 #include "chrome/test/base/menu_model_test.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "components/sessions/serialized_navigation_entry_test_helper.h"
29 #include "components/sessions/session_types.h"
30 #include "components/sync_driver/glue/synced_session.h"
31 #include "components/sync_driver/local_device_info_provider_mock.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/test/test_utils.h"
34 #include "grit/generated_resources.h"
35 #include "sync/api/fake_sync_change_processor.h"
36 #include "sync/api/sync_error_factory_mock.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
42 // This copies parts of MenuModelTest::Delegate and combines them with the
43 // RecentTabsSubMenuModel since RecentTabsSubMenuModel is a
44 // SimpleMenuModel::Delegate and not just derived from SimpleMenuModel.
45 class TestRecentTabsSubMenuModel
: public RecentTabsSubMenuModel
{
47 TestRecentTabsSubMenuModel(ui::AcceleratorProvider
* provider
,
49 sync_driver::OpenTabsUIDelegate
* delegate
)
50 : RecentTabsSubMenuModel(provider
, browser
, delegate
),
54 // Testing overrides to ui::SimpleMenuModel::Delegate:
55 bool IsCommandIdEnabled(int command_id
) const override
{
56 bool val
= RecentTabsSubMenuModel::IsCommandIdEnabled(command_id
);
62 void ExecuteCommand(int command_id
, int event_flags
) override
{
66 int execute_count() const { return execute_count_
; }
67 int enable_count() const { return enable_count_
; }
71 int mutable enable_count_
; // Mutable because IsCommandIdEnabledAt is const.
73 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsSubMenuModel
);
76 class TestRecentTabsMenuModelDelegate
: public ui::MenuModelDelegate
{
78 explicit TestRecentTabsMenuModelDelegate(ui::MenuModel
* model
)
81 model_
->SetMenuModelDelegate(this);
84 ~TestRecentTabsMenuModelDelegate() override
{
85 model_
->SetMenuModelDelegate(NULL
);
88 // ui::MenuModelDelegate implementation:
90 void OnIconChanged(int index
) override
{}
92 void OnMenuStructureChanged() override
{ got_changes_
= true; }
94 bool got_changes() const { return got_changes_
; }
97 ui::MenuModel
* model_
;
100 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsMenuModelDelegate
);
103 class DummyRouter
: public browser_sync::LocalSessionEventRouter
{
105 ~DummyRouter() override
{}
107 browser_sync::LocalSessionEventHandler
* handler
) override
{}
108 void Stop() override
{}
113 class RecentTabsSubMenuModelTest
114 : public BrowserWithTestWindowTest
{
116 RecentTabsSubMenuModelTest()
117 : sync_service_(&testing_profile_
),
118 local_device_(new sync_driver::LocalDeviceInfoProviderMock(
119 "RecentTabsSubMenuModelTest",
123 sync_pb::SyncEnums_DeviceType_TYPE_LINUX
,
125 manager_
.reset(new browser_sync::SessionsSyncManager(
128 scoped_ptr
<browser_sync::LocalSessionEventRouter
>(
129 new DummyRouter())));
130 manager_
->MergeDataAndStartSyncing(
132 syncer::SyncDataList(),
133 scoped_ptr
<syncer::SyncChangeProcessor
>(
134 new syncer::FakeSyncChangeProcessor
),
135 scoped_ptr
<syncer::SyncErrorFactory
>(
136 new syncer::SyncErrorFactoryMock
));
139 void WaitForLoadFromLastSession() {
140 content::RunAllBlockingPoolTasksUntilIdle();
143 static scoped_ptr
<KeyedService
> GetTabRestoreService(
144 content::BrowserContext
* browser_context
) {
145 return make_scoped_ptr(new PersistentTabRestoreService(
146 Profile::FromBrowserContext(browser_context
), NULL
));
149 sync_driver::OpenTabsUIDelegate
* GetOpenTabsDelegate() {
150 return manager_
.get();
153 void RegisterRecentTabs(RecentTabsBuilderTestHelper
* helper
) {
154 helper
->ExportToSessionsSyncManager(manager_
.get());
158 TestingProfile testing_profile_
;
159 testing::NiceMock
<ProfileSyncServiceMock
> sync_service_
;
161 scoped_ptr
<browser_sync::SessionsSyncManager
> manager_
;
162 scoped_ptr
<sync_driver::LocalDeviceInfoProviderMock
> local_device_
;
165 // Test disabled "Recently closed" header with no foreign tabs.
166 TEST_F(RecentTabsSubMenuModelTest
, NoTabs
) {
167 TestRecentTabsSubMenuModel
model(NULL
, browser(), NULL
);
170 // Menu index Menu items
171 // ---------------------------------------------
174 // 2 Recently closed header (disabled)
176 // 4 No tabs from other Devices
178 int num_items
= model
.GetItemCount();
179 EXPECT_EQ(5, num_items
);
180 EXPECT_FALSE(model
.IsEnabledAt(2));
181 EXPECT_FALSE(model
.IsEnabledAt(4));
182 EXPECT_EQ(0, model
.enable_count());
184 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(0));
185 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(1));
186 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(2));
187 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(3));
188 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(4));
191 base::string16 title
;
192 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(0, &url
, &title
));
193 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(1, &url
, &title
));
194 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(2, &url
, &title
));
195 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(3, &url
, &title
));
196 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(4, &url
, &title
));
199 // Test enabled "Recently closed" header with no foreign tabs.
200 TEST_F(RecentTabsSubMenuModelTest
, RecentlyClosedTabsFromCurrentSession
) {
201 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
202 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService
);
204 // Add 2 tabs and close them.
205 AddTab(browser(), GURL("http://foo/1"));
206 AddTab(browser(), GURL("http://foo/2"));
207 browser()->tab_strip_model()->CloseAllTabs();
209 TestRecentTabsSubMenuModel
model(NULL
, browser(), NULL
);
211 // Menu index Menu items
212 // --------------------------------------
215 // 2 Recently closed header
216 // 3 <tab for http://foo/2>
217 // 4 <tab for http://foo/1>
219 // 6 No tabs from other Devices
220 int num_items
= model
.GetItemCount();
221 EXPECT_EQ(7, num_items
);
222 EXPECT_TRUE(model
.IsEnabledAt(0));
223 model
.ActivatedAt(0);
224 EXPECT_TRUE(model
.IsEnabledAt(1));
225 EXPECT_FALSE(model
.IsEnabledAt(2));
226 EXPECT_TRUE(model
.IsEnabledAt(3));
227 EXPECT_TRUE(model
.IsEnabledAt(4));
228 model
.ActivatedAt(3);
229 model
.ActivatedAt(4);
230 EXPECT_FALSE(model
.IsEnabledAt(6));
231 EXPECT_EQ(3, model
.enable_count());
232 EXPECT_EQ(3, model
.execute_count());
234 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(0));
235 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(1));
236 EXPECT_TRUE(model
.GetLabelFontListAt(2) != nullptr);
237 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(3));
238 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(4));
239 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(5));
240 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(6));
243 base::string16 title
;
244 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(0, &url
, &title
));
245 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(1, &url
, &title
));
246 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(2, &url
, &title
));
247 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(3, &url
, &title
));
248 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(4, &url
, &title
));
249 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(5, &url
, &title
));
250 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(6, &url
, &title
));
253 // TODO(sail): enable this test when dynamic model is enabled in
254 // RecentTabsSubMenuModel.
255 #if defined(OS_MACOSX)
256 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
257 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
259 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
260 RecentlyClosedTabsAndWindowsFromLastSession
262 TEST_F(RecentTabsSubMenuModelTest
,
263 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession
) {
264 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
265 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService
);
267 // Add 2 tabs and close them.
268 AddTab(browser(), GURL("http://wnd/tab0"));
269 AddTab(browser(), GURL("http://wnd/tab1"));
270 browser()->tab_strip_model()->CloseAllTabs();
272 // Create a SessionService for the profile (profile owns the service) and add
273 // a window with a tab to this session.
274 SessionService
* session_service
= new SessionService(profile());
275 SessionServiceFactory::SetForTestProfile(profile(),
276 make_scoped_ptr(session_service
));
279 session_service
->SetWindowType(window_id
,
280 Browser::TYPE_TABBED
,
281 SessionService::TYPE_NORMAL
);
282 session_service
->SetTabWindow(window_id
, tab_id
);
283 session_service
->SetTabIndexInWindow(window_id
, tab_id
, 0);
284 session_service
->SetSelectedTabInWindow(window_id
, 0);
285 session_service
->UpdateTabNavigation(
287 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
288 "http://wnd1/tab0", "title"));
289 // Set this, otherwise previous session won't be loaded.
290 profile()->set_last_session_exited_cleanly(false);
291 // Move this session to the last so that TabRestoreService will load it as the
293 SessionServiceFactory::GetForProfile(profile())->
294 MoveCurrentSessionToLastSession();
296 // Create a new TabRestoreService so that it'll load the recently closed tabs
297 // and windows afresh.
298 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
299 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService
);
300 // Let the shutdown of previous TabRestoreService run.
301 content::RunAllBlockingPoolTasksUntilIdle();
303 TestRecentTabsSubMenuModel
model(NULL
, browser(), NULL
);
304 TestRecentTabsMenuModelDelegate
delegate(&model
);
305 EXPECT_FALSE(delegate
.got_changes());
307 // Expected menu before tabs/windows from last session are loaded:
308 // Menu index Menu items
309 // ----------------------------------------------------------------
312 // 2 Recently closed header
314 // 4 No tabs from other Devices
316 int num_items
= model
.GetItemCount();
317 EXPECT_EQ(5, num_items
);
318 EXPECT_TRUE(model
.IsEnabledAt(0));
319 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR
, model
.GetTypeAt(1));
320 EXPECT_FALSE(model
.IsEnabledAt(2));
321 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR
, model
.GetTypeAt(3));
322 EXPECT_FALSE(model
.IsEnabledAt(4));
323 EXPECT_EQ(1, model
.enable_count());
325 // Wait for tabs from last session to be loaded.
326 WaitForLoadFromLastSession();
328 // Expected menu after tabs/windows from last session are loaded:
329 // Menu index Menu items
330 // --------------------------------------------------------------
333 // 2 Recently closed header
334 // 3 <window for the tab http://wnd1/tab0>
335 // 4 <tab for http://wnd0/tab1>
336 // 5 <tab for http://wnd0/tab0>
338 // 7 No tabs from other Devices
340 EXPECT_TRUE(delegate
.got_changes());
342 num_items
= model
.GetItemCount();
343 EXPECT_EQ(8, num_items
);
345 EXPECT_TRUE(model
.IsEnabledAt(0));
346 model
.ActivatedAt(0);
347 EXPECT_TRUE(model
.IsEnabledAt(1));
348 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR
, model
.GetTypeAt(1));
349 EXPECT_FALSE(model
.IsEnabledAt(2));
350 EXPECT_TRUE(model
.IsEnabledAt(3));
351 EXPECT_TRUE(model
.IsEnabledAt(4));
352 EXPECT_TRUE(model
.IsEnabledAt(5));
353 model
.ActivatedAt(3);
354 model
.ActivatedAt(4);
355 model
.ActivatedAt(5);
356 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR
, model
.GetTypeAt(6));
357 EXPECT_FALSE(model
.IsEnabledAt(7));
358 EXPECT_EQ(5, model
.enable_count());
359 EXPECT_EQ(4, model
.execute_count());
361 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(0));
362 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(1));
363 EXPECT_TRUE(model
.GetLabelFontListAt(2) != nullptr);
364 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(3));
365 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(4));
366 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(5));
367 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(6));
368 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(7));
371 base::string16 title
;
372 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(0, &url
, &title
));
373 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(1, &url
, &title
));
374 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(2, &url
, &title
));
375 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(3, &url
, &title
));
376 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(4, &url
, &title
));
377 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(5, &url
, &title
));
378 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(6, &url
, &title
));
379 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(7, &url
, &title
));
382 // Test disabled "Recently closed" header with multiple sessions, multiple
383 // windows, and multiple enabled tabs from other devices.
384 TEST_F(RecentTabsSubMenuModelTest
, OtherDevices
) {
385 // Tabs are populated in decreasing timestamp.
386 base::Time timestamp
= base::Time::Now();
387 const base::TimeDelta time_delta
= base::TimeDelta::FromMinutes(10);
389 RecentTabsBuilderTestHelper recent_tabs_builder
;
391 // Create 1st session : 1 window, 3 tabs
392 recent_tabs_builder
.AddSession();
393 recent_tabs_builder
.AddWindow(0);
394 for (int i
= 0; i
< 3; ++i
) {
395 timestamp
-= time_delta
;
396 recent_tabs_builder
.AddTabWithInfo(0, 0, timestamp
, base::string16());
399 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
400 recent_tabs_builder
.AddSession();
401 recent_tabs_builder
.AddWindow(1);
402 recent_tabs_builder
.AddWindow(1);
403 timestamp
-= time_delta
;
404 recent_tabs_builder
.AddTabWithInfo(1, 0, timestamp
, base::string16());
405 timestamp
-= time_delta
;
406 recent_tabs_builder
.AddTabWithInfo(1, 1, timestamp
, base::string16());
407 timestamp
-= time_delta
;
408 recent_tabs_builder
.AddTabWithInfo(1, 1, timestamp
, base::string16());
410 RegisterRecentTabs(&recent_tabs_builder
);
412 // Verify that data is populated correctly in RecentTabsSubMenuModel.
414 // - first inserted tab is most recent and hence is top
415 // Menu index Menu items
416 // -----------------------------------------------------
419 // 2 Recently closed header (disabled)
421 // 4 <section header for 1st session>
422 // 5-7 <3 tabs of the only window of session 0>
424 // 9 <section header for 2nd session>
425 // 10 <the only tab of window 0 of session 1>
426 // 11-12 <2 tabs of window 1 of session 2>
428 TestRecentTabsSubMenuModel
model(NULL
, browser(), GetOpenTabsDelegate());
429 int num_items
= model
.GetItemCount();
430 EXPECT_EQ(13, num_items
);
431 model
.ActivatedAt(0);
432 EXPECT_TRUE(model
.IsEnabledAt(0));
433 model
.ActivatedAt(1);
434 EXPECT_TRUE(model
.IsEnabledAt(1));
435 model
.ActivatedAt(2);
436 EXPECT_FALSE(model
.IsEnabledAt(2));
437 model
.ActivatedAt(3);
438 EXPECT_TRUE(model
.IsEnabledAt(3));
439 model
.ActivatedAt(5);
440 EXPECT_TRUE(model
.IsEnabledAt(5));
441 model
.ActivatedAt(6);
442 EXPECT_TRUE(model
.IsEnabledAt(6));
443 model
.ActivatedAt(7);
444 EXPECT_TRUE(model
.IsEnabledAt(7));
445 model
.ActivatedAt(10);
446 EXPECT_TRUE(model
.IsEnabledAt(10));
447 model
.ActivatedAt(11);
448 EXPECT_TRUE(model
.IsEnabledAt(11));
449 model
.ActivatedAt(12);
450 EXPECT_TRUE(model
.IsEnabledAt(12));
452 EXPECT_EQ(7, model
.enable_count());
453 EXPECT_EQ(10, model
.execute_count());
455 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(0));
456 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(1));
457 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(2));
458 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(3));
459 EXPECT_TRUE(model
.GetLabelFontListAt(4) != nullptr);
460 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(5));
461 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(6));
462 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(7));
463 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(8));
464 EXPECT_TRUE(model
.GetLabelFontListAt(9) != nullptr);
465 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(10));
466 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(11));
467 EXPECT_EQ(NULL
, model
.GetLabelFontListAt(12));
470 base::string16 title
;
471 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(0, &url
, &title
));
472 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(1, &url
, &title
));
473 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(2, &url
, &title
));
474 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(3, &url
, &title
));
475 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(4, &url
, &title
));
476 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(5, &url
, &title
));
477 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(6, &url
, &title
));
478 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(7, &url
, &title
));
479 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(8, &url
, &title
));
480 EXPECT_FALSE(model
.GetURLAndTitleForItemAtIndex(9, &url
, &title
));
481 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(10, &url
, &title
));
482 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(11, &url
, &title
));
483 EXPECT_TRUE(model
.GetURLAndTitleForItemAtIndex(12, &url
, &title
));
486 TEST_F(RecentTabsSubMenuModelTest
, MaxSessionsAndRecency
) {
487 // Create 4 sessions : each session has 1 window with 1 tab each.
488 RecentTabsBuilderTestHelper recent_tabs_builder
;
489 for (int s
= 0; s
< 4; ++s
) {
490 recent_tabs_builder
.AddSession();
491 recent_tabs_builder
.AddWindow(s
);
492 recent_tabs_builder
.AddTab(s
, 0);
494 RegisterRecentTabs(&recent_tabs_builder
);
496 // Verify that data is populated correctly in RecentTabsSubMenuModel.
498 // - max sessions is 3, so only 3 most-recent sessions will show.
499 // Menu index Menu items
500 // ----------------------------------------------------------
503 // 2 Recently closed header (disabled)
505 // 4 <section header for 1st session>
506 // 5 <the only tab of the only window of session 3>
508 // 7 <section header for 2nd session>
509 // 8 <the only tab of the only window of session 2>
511 // 10 <section header for 3rd session>
512 // 11 <the only tab of the only window of session 1>
514 TestRecentTabsSubMenuModel
model(NULL
, browser(), GetOpenTabsDelegate());
515 int num_items
= model
.GetItemCount();
516 EXPECT_EQ(12, num_items
);
518 std::vector
<base::string16
> tab_titles
=
519 recent_tabs_builder
.GetTabTitlesSortedByRecency();
520 EXPECT_EQ(tab_titles
[0], model
.GetLabelAt(5));
521 EXPECT_EQ(tab_titles
[1], model
.GetLabelAt(8));
522 EXPECT_EQ(tab_titles
[2], model
.GetLabelAt(11));
525 TEST_F(RecentTabsSubMenuModelTest
, MaxTabsPerSessionAndRecency
) {
526 // Create a session: 2 windows with 5 tabs each.
527 RecentTabsBuilderTestHelper recent_tabs_builder
;
528 recent_tabs_builder
.AddSession();
529 for (int w
= 0; w
< 2; ++w
) {
530 recent_tabs_builder
.AddWindow(0);
531 for (int t
= 0; t
< 5; ++t
)
532 recent_tabs_builder
.AddTab(0, w
);
534 RegisterRecentTabs(&recent_tabs_builder
);
536 // Verify that data is populated correctly in RecentTabsSubMenuModel.
538 // - max tabs per session is 4, so only 4 most-recent tabs will show,
539 // independent of which window they came from.
540 // Menu index Menu items
541 // ---------------------------------------------
544 // 2 Recently closed header (disabled)
546 // 4 <section header for session>
547 // 5-8 <4 most-recent tabs of session>
549 TestRecentTabsSubMenuModel
model(NULL
, browser(), GetOpenTabsDelegate());
550 int num_items
= model
.GetItemCount();
551 EXPECT_EQ(9, num_items
);
553 std::vector
<base::string16
> tab_titles
=
554 recent_tabs_builder
.GetTabTitlesSortedByRecency();
555 for (int i
= 0; i
< 4; ++i
)
556 EXPECT_EQ(tab_titles
[i
], model
.GetLabelAt(i
+ 5));
559 TEST_F(RecentTabsSubMenuModelTest
, MaxWidth
) {
560 // Create 1 session with 1 window and 1 tab.
561 RecentTabsBuilderTestHelper recent_tabs_builder
;
562 recent_tabs_builder
.AddSession();
563 recent_tabs_builder
.AddWindow(0);
564 recent_tabs_builder
.AddTab(0, 0);
565 RegisterRecentTabs(&recent_tabs_builder
);
567 // Menu index Menu items
568 // ----------------------------------------------------------
571 // 2 Recently closed header (disabled)
573 // 4 <section header for 1st session>
574 // 5 <the only tab of the only window of session 1>
576 TestRecentTabsSubMenuModel
model(NULL
, browser(), GetOpenTabsDelegate());
577 EXPECT_EQ(6, model
.GetItemCount());
578 EXPECT_EQ(-1, model
.GetMaxWidthForItemAtIndex(2));
579 EXPECT_NE(-1, model
.GetMaxWidthForItemAtIndex(3));
580 EXPECT_NE(-1, model
.GetMaxWidthForItemAtIndex(4));
581 EXPECT_NE(-1, model
.GetMaxWidthForItemAtIndex(5));
584 TEST_F(RecentTabsSubMenuModelTest
, MaxWidthNoDevices
) {
586 // Menu index Menu items
587 // --------------------------------------------
590 // 2 Recently closed heaer (disabled)
592 // 4 No tabs from other Devices
594 TestRecentTabsSubMenuModel
model(NULL
, browser(), NULL
);
595 EXPECT_EQ(5, model
.GetItemCount());
596 EXPECT_EQ(-1, model
.GetMaxWidthForItemAtIndex(2));
597 EXPECT_NE(-1, model
.GetMaxWidthForItemAtIndex(3));
598 EXPECT_EQ(-1, model
.GetMaxWidthForItemAtIndex(4));