NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / recent_tabs_sub_menu_model_unittest.cc
blob94cee719ddfa21475f2c37541fec6562d41825da
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 "content/public/browser/browser_thread.h"
29 #include "grit/generated_resources.h"
30 #include "sync/api/fake_sync_change_processor.h"
31 #include "sync/api/sync_error_factory_mock.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 namespace {
37 // This copies parts of MenuModelTest::Delegate and combines them with the
38 // RecentTabsSubMenuModel since RecentTabsSubMenuModel is a
39 // SimpleMenuModel::Delegate and not just derived from SimpleMenuModel.
40 class TestRecentTabsSubMenuModel : public RecentTabsSubMenuModel {
41 public:
42 TestRecentTabsSubMenuModel(ui::AcceleratorProvider* provider,
43 Browser* browser,
44 browser_sync::OpenTabsUIDelegate* delegate)
45 : RecentTabsSubMenuModel(provider, browser, delegate),
46 execute_count_(0),
47 enable_count_(0) {
50 // Testing overrides to ui::SimpleMenuModel::Delegate:
51 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
52 bool val = RecentTabsSubMenuModel::IsCommandIdEnabled(command_id);
53 if (val)
54 ++enable_count_;
55 return val;
58 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
59 ++execute_count_;
62 int execute_count() const { return execute_count_; }
63 int enable_count() const { return enable_count_; }
65 private:
66 int execute_count_;
67 int mutable enable_count_; // Mutable because IsCommandIdEnabledAt is const.
69 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsSubMenuModel);
72 class TestRecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
73 public:
74 explicit TestRecentTabsMenuModelDelegate(ui::MenuModel* model)
75 : model_(model),
76 got_changes_(false) {
77 model_->SetMenuModelDelegate(this);
80 virtual ~TestRecentTabsMenuModelDelegate() {
81 model_->SetMenuModelDelegate(NULL);
84 // ui::MenuModelDelegate implementation:
86 virtual void OnIconChanged(int index) OVERRIDE {
89 virtual void OnMenuStructureChanged() OVERRIDE {
90 got_changes_ = true;
93 bool got_changes() const { return got_changes_; }
95 private:
96 ui::MenuModel* model_;
97 bool got_changes_;
99 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsMenuModelDelegate);
102 class DummyRouter : public browser_sync::LocalSessionEventRouter {
103 public:
104 virtual ~DummyRouter() {}
105 virtual void StartRoutingTo(
106 browser_sync::LocalSessionEventHandler* handler) OVERRIDE {}
107 virtual void Stop() OVERRIDE {}
110 } // namespace
112 class RecentTabsSubMenuModelTest
113 : public BrowserWithTestWindowTest,
114 public browser_sync::SessionsSyncManager::SyncInternalApiDelegate {
115 public:
116 RecentTabsSubMenuModelTest()
117 : sync_service_(&testing_profile_) {
118 if (!CommandLine::ForCurrentProcess()->HasSwitch(
119 switches::kDisableSyncSessionsV2)) {
120 manager_.reset(new browser_sync::SessionsSyncManager(
121 &testing_profile_,
122 this,
123 scoped_ptr<browser_sync::LocalSessionEventRouter>(
124 new DummyRouter())));
125 manager_->MergeDataAndStartSyncing(
126 syncer::SESSIONS,
127 syncer::SyncDataList(),
128 scoped_ptr<syncer::SyncChangeProcessor>(
129 new syncer::FakeSyncChangeProcessor),
130 scoped_ptr<syncer::SyncErrorFactory>(
131 new syncer::SyncErrorFactoryMock));
132 } else {
133 associator_.reset(new browser_sync::SessionModelAssociator(
134 &sync_service_, true));
135 associator_->SetCurrentMachineTagForTesting(
136 GetLocalSyncCacheGUID());
140 void WaitForLoadFromLastSession() {
141 content::BrowserThread::GetBlockingPool()->FlushForTesting();
142 base::RunLoop().RunUntilIdle();
143 content::BrowserThread::GetBlockingPool()->FlushForTesting();
146 static BrowserContextKeyedService* GetTabRestoreService(
147 content::BrowserContext* browser_context) {
148 // Ownership is tranfered to the profile.
149 return new PersistentTabRestoreService(
150 Profile::FromBrowserContext(browser_context), NULL);;
154 browser_sync::OpenTabsUIDelegate* GetOpenTabsDelegate() {
155 if (!CommandLine::ForCurrentProcess()->HasSwitch(
156 switches::kDisableSyncSessionsV2)) {
157 return manager_.get();
158 } else {
159 return associator_.get();
163 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
164 if (!CommandLine::ForCurrentProcess()->HasSwitch(
165 switches::kDisableSyncSessionsV2)) {
166 helper->ExportToSessionsSyncManager(manager_.get());
167 } else {
168 helper->ExportToSessionModelAssociator(associator_.get());
172 virtual scoped_ptr<browser_sync::DeviceInfo> GetLocalDeviceInfo()
173 const OVERRIDE {
174 return scoped_ptr<browser_sync::DeviceInfo>(
175 new browser_sync::DeviceInfo(GetLocalSyncCacheGUID(),
176 "Test Machine",
177 "Chromium 10k",
178 "Chrome 10k",
179 sync_pb::SyncEnums_DeviceType_TYPE_LINUX));
182 virtual std::string GetLocalSyncCacheGUID() const OVERRIDE {
183 return "RecentTabsSubMenuModelTest";
186 private:
187 TestingProfile testing_profile_;
188 testing::NiceMock<ProfileSyncServiceMock> sync_service_;
190 // TODO(tim): Remove associator_ when sessions V2 is the default, bug 98892.
191 scoped_ptr<browser_sync::SessionModelAssociator> associator_;
192 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
195 // Test disabled "Recently closed" header with no foreign tabs.
196 TEST_F(RecentTabsSubMenuModelTest, NoTabs) {
197 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
199 // Expected menu:
200 // Menu index Menu items
201 // ---------------------------------------------
202 // 0 Recently closed header (disabled)
203 // 1 <separator>
204 // 2 No tabs from other Devices
206 int num_items = model.GetItemCount();
207 EXPECT_EQ(3, num_items);
208 EXPECT_FALSE(model.IsEnabledAt(0));
209 EXPECT_FALSE(model.IsEnabledAt(2));
210 EXPECT_EQ(0, model.enable_count());
212 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
213 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
214 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
216 std::string url;
217 base::string16 title;
218 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
219 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
220 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
223 // Test enabled "Recently closed" header with no foreign tabs.
224 TEST_F(RecentTabsSubMenuModelTest, RecentlyClosedTabsFromCurrentSession) {
225 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
226 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
228 // Add 2 tabs and close them.
229 AddTab(browser(), GURL("http://foo/1"));
230 AddTab(browser(), GURL("http://foo/2"));
231 browser()->tab_strip_model()->CloseAllTabs();
233 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
234 // Expected menu:
235 // Menu index Menu items
236 // --------------------------------------
237 // 0 Recently closed header
238 // 1 <tab for http://foo/2>
239 // 2 <tab for http://foo/1>
240 // 3 <separator>
241 // 4 No tabs from other Devices
242 int num_items = model.GetItemCount();
243 EXPECT_EQ(5, num_items);
244 EXPECT_FALSE(model.IsEnabledAt(0));
245 EXPECT_TRUE(model.IsEnabledAt(1));
246 EXPECT_TRUE(model.IsEnabledAt(2));
247 model.ActivatedAt(1);
248 model.ActivatedAt(2);
249 EXPECT_FALSE(model.IsEnabledAt(4));
250 EXPECT_EQ(2, model.enable_count());
251 EXPECT_EQ(2, model.execute_count());
253 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
254 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
255 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
256 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
257 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
259 std::string url;
260 base::string16 title;
261 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
262 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
263 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
264 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
265 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
268 // TODO(sail): enable this test when dynamic model is enabled in
269 // RecentTabsSubMenuModel.
270 #if defined(OS_MACOSX)
271 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
272 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
273 #else
274 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
275 RecentlyClosedTabsAndWindowsFromLastSession
276 #endif
277 TEST_F(RecentTabsSubMenuModelTest,
278 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession) {
279 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
280 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
282 // Add 2 tabs and close them.
283 AddTab(browser(), GURL("http://wnd/tab0"));
284 AddTab(browser(), GURL("http://wnd/tab1"));
285 browser()->tab_strip_model()->CloseAllTabs();
287 // Create a SessionService for the profile (profile owns the service) and add
288 // a window with a tab to this session.
289 SessionService* session_service = new SessionService(profile());
290 SessionServiceFactory::SetForTestProfile(profile(), session_service);
291 SessionID tab_id;
292 SessionID window_id;
293 session_service->SetWindowType(
294 window_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
295 session_service->SetTabWindow(window_id, tab_id);
296 session_service->SetTabIndexInWindow(window_id, tab_id, 0);
297 session_service->SetSelectedTabInWindow(window_id, 0);
298 session_service->UpdateTabNavigation(
299 window_id, tab_id,
300 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
301 "http://wnd1/tab0", "title"));
302 // Set this, otherwise previous session won't be loaded.
303 profile()->set_last_session_exited_cleanly(false);
304 // Move this session to the last so that TabRestoreService will load it as the
305 // last session.
306 SessionServiceFactory::GetForProfile(profile())->
307 MoveCurrentSessionToLastSession();
309 // Create a new TabRestoreService so that it'll load the recently closed tabs
310 // and windows afresh.
311 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
312 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
313 // Let the shutdown of previous TabRestoreService run.
314 content::BrowserThread::GetBlockingPool()->FlushForTesting();
316 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
317 TestRecentTabsMenuModelDelegate delegate(&model);
318 EXPECT_FALSE(delegate.got_changes());
320 // Expected menu before tabs/windows from last session are loaded:
321 // Menu index Menu items
322 // ----------------------------------------------------------------
323 // 0 Recently closed header
324 // 1 <separator>
325 // 2 No tabs from other Devices
327 int num_items = model.GetItemCount();
328 EXPECT_EQ(3, num_items);
329 EXPECT_FALSE(model.IsEnabledAt(0));
330 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
331 EXPECT_FALSE(model.IsEnabledAt(2));
332 EXPECT_EQ(0, model.enable_count());
334 // Wait for tabs from last session to be loaded.
335 WaitForLoadFromLastSession();
337 // Expected menu after tabs/windows from last session are loaded:
338 // Menu index Menu items
339 // --------------------------------------------------------------
340 // 0 Recently closed header
341 // 1 <window for the tab http://wnd1/tab0>
342 // 2 <tab for http://wnd0/tab1>
343 // 3 <tab for http://wnd0/tab0>
344 // 4 <separator>
345 // 5 No tabs from other Devices
347 EXPECT_TRUE(delegate.got_changes());
349 num_items = model.GetItemCount();
350 EXPECT_EQ(6, num_items);
351 EXPECT_FALSE(model.IsEnabledAt(0));
352 EXPECT_TRUE(model.IsEnabledAt(1));
353 EXPECT_TRUE(model.IsEnabledAt(2));
354 EXPECT_TRUE(model.IsEnabledAt(3));
355 model.ActivatedAt(1);
356 model.ActivatedAt(2);
357 model.ActivatedAt(3);
358 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(4));
359 EXPECT_FALSE(model.IsEnabledAt(5));
360 EXPECT_EQ(3, model.enable_count());
361 EXPECT_EQ(3, model.execute_count());
363 EXPECT_TRUE(model.GetLabelFontListAt(0) != NULL);
364 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
365 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
366 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
367 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
368 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
370 std::string url;
371 base::string16 title;
372 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
373 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
374 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
375 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
376 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
377 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
380 // Test disabled "Recently closed" header with multiple sessions, multiple
381 // windows, and multiple enabled tabs from other devices.
382 TEST_F(RecentTabsSubMenuModelTest, OtherDevices) {
383 // Tabs are populated in decreasing timestamp.
384 base::Time timestamp = base::Time::Now();
385 const base::TimeDelta time_delta = base::TimeDelta::FromMinutes(10);
387 RecentTabsBuilderTestHelper recent_tabs_builder;
389 // Create 1st session : 1 window, 3 tabs
390 recent_tabs_builder.AddSession();
391 recent_tabs_builder.AddWindow(0);
392 for (int i = 0; i < 3; ++i) {
393 timestamp -= time_delta;
394 recent_tabs_builder.AddTabWithInfo(0, 0, timestamp, base::string16());
397 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
398 recent_tabs_builder.AddSession();
399 recent_tabs_builder.AddWindow(1);
400 recent_tabs_builder.AddWindow(1);
401 timestamp -= time_delta;
402 recent_tabs_builder.AddTabWithInfo(1, 0, timestamp, base::string16());
403 timestamp -= time_delta;
404 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
405 timestamp -= time_delta;
406 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
408 RegisterRecentTabs(&recent_tabs_builder);
410 // Verify that data is populated correctly in RecentTabsSubMenuModel.
411 // Expected menu:
412 // - first inserted tab is most recent and hence is top
413 // Menu index Menu items
414 // -----------------------------------------------------
415 // 0 Recently closed header (disabled)
416 // 1 <separator>
417 // 2 <section header for 1st session>
418 // 3-5 <3 tabs of the only window of session 0>
419 // 6 <separator>
420 // 7 <section header for 2nd session>
421 // 8 <the only tab of window 0 of session 1>
422 // 9-10 <2 tabs of window 1 of session 2>
423 // 11 <separator>
424 // 12 More...
426 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
427 int num_items = model.GetItemCount();
428 EXPECT_EQ(13, num_items);
429 model.ActivatedAt(0);
430 EXPECT_FALSE(model.IsEnabledAt(0));
431 model.ActivatedAt(3);
432 EXPECT_TRUE(model.IsEnabledAt(3));
433 model.ActivatedAt(4);
434 EXPECT_TRUE(model.IsEnabledAt(4));
435 model.ActivatedAt(5);
436 EXPECT_TRUE(model.IsEnabledAt(5));
437 model.ActivatedAt(8);
438 EXPECT_TRUE(model.IsEnabledAt(8));
439 model.ActivatedAt(9);
440 EXPECT_TRUE(model.IsEnabledAt(9));
441 model.ActivatedAt(10);
442 EXPECT_TRUE(model.IsEnabledAt(10));
443 EXPECT_TRUE(model.IsEnabledAt(12));
444 EXPECT_EQ(7, model.enable_count());
445 EXPECT_EQ(7, model.execute_count());
447 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
448 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
449 EXPECT_TRUE(model.GetLabelFontListAt(2) != NULL);
450 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
451 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
452 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
453 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
454 EXPECT_TRUE(model.GetLabelFontListAt(7) != NULL);
455 EXPECT_EQ(NULL, model.GetLabelFontListAt(8));
456 EXPECT_EQ(NULL, model.GetLabelFontListAt(9));
457 EXPECT_EQ(NULL, model.GetLabelFontListAt(10));
458 EXPECT_EQ(NULL, model.GetLabelFontListAt(11));
459 EXPECT_EQ(NULL, model.GetLabelFontListAt(12));
461 std::string url;
462 base::string16 title;
463 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
464 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
465 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
466 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
467 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
468 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
469 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
470 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
471 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(8, &url, &title));
472 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(9, &url, &title));
473 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(10, &url, &title));
474 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(11, &url, &title));
475 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(12, &url, &title));
478 TEST_F(RecentTabsSubMenuModelTest, MaxSessionsAndRecency) {
479 // Create 4 sessions : each session has 1 window with 1 tab each.
480 RecentTabsBuilderTestHelper recent_tabs_builder;
481 for (int s = 0; s < 4; ++s) {
482 recent_tabs_builder.AddSession();
483 recent_tabs_builder.AddWindow(s);
484 recent_tabs_builder.AddTab(s, 0);
486 RegisterRecentTabs(&recent_tabs_builder);
488 // Verify that data is populated correctly in RecentTabsSubMenuModel.
489 // Expected menu:
490 // - max sessions is 3, so only 3 most-recent sessions will show.
491 // Menu index Menu items
492 // ----------------------------------------------------------
493 // 0 Recently closed header (disabled)
494 // 1 <separator>
495 // 2 <section header for 1st session>
496 // 3 <the only tab of the only window of session 3>
497 // 4 <separator>
498 // 5 <section header for 2nd session>
499 // 6 <the only tab of the only window of session 2>
500 // 7 <separator>
501 // 8 <section header for 3rd session>
502 // 9 <the only tab of the only window of session 1>
503 // 10 <separator>
504 // 11 More...
506 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
507 int num_items = model.GetItemCount();
508 EXPECT_EQ(12, num_items);
510 std::vector<base::string16> tab_titles =
511 recent_tabs_builder.GetTabTitlesSortedByRecency();
512 EXPECT_EQ(tab_titles[0], model.GetLabelAt(3));
513 EXPECT_EQ(tab_titles[1], model.GetLabelAt(6));
514 EXPECT_EQ(tab_titles[2], model.GetLabelAt(9));
517 TEST_F(RecentTabsSubMenuModelTest, MaxTabsPerSessionAndRecency) {
518 // Create a session: 2 windows with 5 tabs each.
519 RecentTabsBuilderTestHelper recent_tabs_builder;
520 recent_tabs_builder.AddSession();
521 for (int w = 0; w < 2; ++w) {
522 recent_tabs_builder.AddWindow(0);
523 for (int t = 0; t < 5; ++t)
524 recent_tabs_builder.AddTab(0, w);
526 RegisterRecentTabs(&recent_tabs_builder);
528 // Verify that data is populated correctly in RecentTabsSubMenuModel.
529 // Expected menu:
530 // - max tabs per session is 4, so only 4 most-recent tabs will show,
531 // independent of which window they came from.
532 // Menu index Menu items
533 // ---------------------------------------------
534 // 0 Recently closed header (disabled)
535 // 1 <separator>
536 // 2 <section header for session>
537 // 3-6 <4 most-recent tabs of session>
538 // 7 <separator>
539 // 8 More...
541 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
542 int num_items = model.GetItemCount();
543 EXPECT_EQ(9, num_items);
545 std::vector<base::string16> tab_titles =
546 recent_tabs_builder.GetTabTitlesSortedByRecency();
547 for (int i = 0; i < 4; ++i)
548 EXPECT_EQ(tab_titles[i], model.GetLabelAt(i + 3));
551 TEST_F(RecentTabsSubMenuModelTest, MaxWidth) {
552 // Create 1 session with 1 window and 1 tab.
553 RecentTabsBuilderTestHelper recent_tabs_builder;
554 recent_tabs_builder.AddSession();
555 recent_tabs_builder.AddWindow(0);
556 recent_tabs_builder.AddTab(0, 0);
557 RegisterRecentTabs(&recent_tabs_builder);
559 // Menu index Menu items
560 // ----------------------------------------------------------
561 // 0 Recently closed header (disabled)
562 // 1 <separator>
563 // 2 <section header for 1st session>
564 // 3 <the only tab of the only window of session 1>
565 // 4 <separator>
566 // 5 More...
568 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
569 EXPECT_EQ(6, model.GetItemCount());
570 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
571 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
572 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(2));
573 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
576 TEST_F(RecentTabsSubMenuModelTest, MaxWidthNoDevices) {
577 // Expected menu:
578 // Menu index Menu items
579 // --------------------------------------------
580 // 0 Recently closed heaer (disabled)
581 // 1 <separator>
582 // 2 No tabs from other Devices
584 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
585 EXPECT_EQ(3, model.GetItemCount());
586 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(0));
587 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(1));
588 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));