[sessions]: Componentize TabRestore code
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / recent_tabs_sub_menu_model_unittest.cc
blobaa364a01fa913a1d10fab8b0dd7f3b1c2128a6a5
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"
7 #include <string>
8 #include <vector>
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/chrome_tab_restore_service_client.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/sync/browser_synced_window_delegates_getter.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/browser_with_test_window_test.h"
27 #include "chrome/test/base/menu_model_test.h"
28 #include "chrome/test/base/testing_profile.h"
29 #include "components/sessions/core/persistent_tab_restore_service.h"
30 #include "components/sessions/serialized_navigation_entry_test_helper.h"
31 #include "components/sessions/session_types.h"
32 #include "components/sync_driver/glue/synced_session.h"
33 #include "components/sync_driver/local_device_info_provider_mock.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/test/test_utils.h"
36 #include "grit/generated_resources.h"
37 #include "sync/api/fake_sync_change_processor.h"
38 #include "sync/api/sync_error_factory_mock.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
42 namespace {
44 // This copies parts of MenuModelTest::Delegate and combines them with the
45 // RecentTabsSubMenuModel since RecentTabsSubMenuModel is a
46 // SimpleMenuModel::Delegate and not just derived from SimpleMenuModel.
47 class TestRecentTabsSubMenuModel : public RecentTabsSubMenuModel {
48 public:
49 TestRecentTabsSubMenuModel(ui::AcceleratorProvider* provider,
50 Browser* browser,
51 sync_driver::OpenTabsUIDelegate* delegate)
52 : RecentTabsSubMenuModel(provider, browser, delegate),
53 execute_count_(0),
54 enable_count_(0) {}
56 // Testing overrides to ui::SimpleMenuModel::Delegate:
57 bool IsCommandIdEnabled(int command_id) const override {
58 bool val = RecentTabsSubMenuModel::IsCommandIdEnabled(command_id);
59 if (val)
60 ++enable_count_;
61 return val;
64 void ExecuteCommand(int command_id, int event_flags) override {
65 ++execute_count_;
68 int execute_count() const { return execute_count_; }
69 int enable_count() const { return enable_count_; }
71 private:
72 int execute_count_;
73 int mutable enable_count_; // Mutable because IsCommandIdEnabledAt is const.
75 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsSubMenuModel);
78 class TestRecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
79 public:
80 explicit TestRecentTabsMenuModelDelegate(ui::MenuModel* model)
81 : model_(model),
82 got_changes_(false) {
83 model_->SetMenuModelDelegate(this);
86 ~TestRecentTabsMenuModelDelegate() override {
87 model_->SetMenuModelDelegate(NULL);
90 // ui::MenuModelDelegate implementation:
92 void OnIconChanged(int index) override {}
94 void OnMenuStructureChanged() override { got_changes_ = true; }
96 bool got_changes() const { return got_changes_; }
98 private:
99 ui::MenuModel* model_;
100 bool got_changes_;
102 DISALLOW_COPY_AND_ASSIGN(TestRecentTabsMenuModelDelegate);
105 class DummyRouter : public browser_sync::LocalSessionEventRouter {
106 public:
107 ~DummyRouter() override {}
108 void StartRoutingTo(
109 browser_sync::LocalSessionEventHandler* handler) override {}
110 void Stop() override {}
113 } // namespace
115 class RecentTabsSubMenuModelTest
116 : public BrowserWithTestWindowTest {
117 public:
118 RecentTabsSubMenuModelTest()
119 : sync_service_(&testing_profile_),
120 local_device_(new sync_driver::LocalDeviceInfoProviderMock(
121 "RecentTabsSubMenuModelTest",
122 "Test Machine",
123 "Chromium 10k",
124 "Chrome 10k",
125 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
126 "device_id")) {
127 manager_.reset(new browser_sync::SessionsSyncManager(
128 &testing_profile_, local_device_.get(),
129 scoped_ptr<browser_sync::LocalSessionEventRouter>(new DummyRouter()),
130 scoped_ptr<browser_sync::SyncedWindowDelegatesGetter>(
131 new browser_sync::BrowserSyncedWindowDelegatesGetter())));
132 manager_->MergeDataAndStartSyncing(
133 syncer::SESSIONS,
134 syncer::SyncDataList(),
135 scoped_ptr<syncer::SyncChangeProcessor>(
136 new syncer::FakeSyncChangeProcessor),
137 scoped_ptr<syncer::SyncErrorFactory>(
138 new syncer::SyncErrorFactoryMock));
141 void WaitForLoadFromLastSession() {
142 content::RunAllBlockingPoolTasksUntilIdle();
145 static scoped_ptr<KeyedService> GetTabRestoreService(
146 content::BrowserContext* browser_context) {
147 return make_scoped_ptr(new PersistentTabRestoreService(
148 make_scoped_ptr(new ChromeTabRestoreServiceClient(
149 Profile::FromBrowserContext(browser_context))),
150 nullptr));
153 sync_driver::OpenTabsUIDelegate* GetOpenTabsDelegate() {
154 return manager_.get();
157 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
158 helper->ExportToSessionsSyncManager(manager_.get());
161 private:
162 TestingProfile testing_profile_;
163 testing::NiceMock<ProfileSyncServiceMock> sync_service_;
165 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
166 scoped_ptr<sync_driver::LocalDeviceInfoProviderMock> local_device_;
169 // Test disabled "Recently closed" header with no foreign tabs.
170 TEST_F(RecentTabsSubMenuModelTest, NoTabs) {
171 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
173 // Expected menu:
174 // Menu index Menu items
175 // ---------------------------------------------
176 // 0 History
177 // 1 <separator>
178 // 2 Recently closed header (disabled)
179 // 3 <separator>
180 // 4 No tabs from other Devices
182 int num_items = model.GetItemCount();
183 EXPECT_EQ(5, num_items);
184 EXPECT_FALSE(model.IsEnabledAt(2));
185 EXPECT_FALSE(model.IsEnabledAt(4));
186 EXPECT_EQ(0, model.enable_count());
188 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
189 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
190 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
191 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
192 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
194 std::string url;
195 base::string16 title;
196 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
197 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
198 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
199 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
200 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
203 // Test enabled "Recently closed" header with no foreign tabs.
204 TEST_F(RecentTabsSubMenuModelTest, RecentlyClosedTabsFromCurrentSession) {
205 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
206 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
208 // Add 2 tabs and close them.
209 AddTab(browser(), GURL("http://foo/1"));
210 AddTab(browser(), GURL("http://foo/2"));
211 browser()->tab_strip_model()->CloseAllTabs();
213 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
214 // Expected menu:
215 // Menu index Menu items
216 // --------------------------------------
217 // 0 History
218 // 1 <separator>
219 // 2 Recently closed header
220 // 3 <tab for http://foo/2>
221 // 4 <tab for http://foo/1>
222 // 5 <separator>
223 // 6 No tabs from other Devices
224 int num_items = model.GetItemCount();
225 EXPECT_EQ(7, num_items);
226 EXPECT_TRUE(model.IsEnabledAt(0));
227 model.ActivatedAt(0);
228 EXPECT_TRUE(model.IsEnabledAt(1));
229 EXPECT_FALSE(model.IsEnabledAt(2));
230 EXPECT_TRUE(model.IsEnabledAt(3));
231 EXPECT_TRUE(model.IsEnabledAt(4));
232 model.ActivatedAt(3);
233 model.ActivatedAt(4);
234 EXPECT_FALSE(model.IsEnabledAt(6));
235 EXPECT_EQ(3, model.enable_count());
236 EXPECT_EQ(3, model.execute_count());
238 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
239 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
240 EXPECT_TRUE(model.GetLabelFontListAt(2) != nullptr);
241 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
242 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
243 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
244 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
246 std::string url;
247 base::string16 title;
248 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
249 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
250 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
251 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
252 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
253 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
254 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
257 // TODO(sail): enable this test when dynamic model is enabled in
258 // RecentTabsSubMenuModel.
259 #if defined(OS_MACOSX)
260 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
261 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
262 #else
263 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
264 RecentlyClosedTabsAndWindowsFromLastSession
265 #endif
266 TEST_F(RecentTabsSubMenuModelTest,
267 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession) {
268 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
269 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
271 // Add 2 tabs and close them.
272 AddTab(browser(), GURL("http://wnd/tab0"));
273 AddTab(browser(), GURL("http://wnd/tab1"));
274 browser()->tab_strip_model()->CloseAllTabs();
276 // Create a SessionService for the profile (profile owns the service) and add
277 // a window with a tab to this session.
278 SessionService* session_service = new SessionService(profile());
279 SessionServiceFactory::SetForTestProfile(profile(),
280 make_scoped_ptr(session_service));
281 SessionID tab_id;
282 SessionID window_id;
283 session_service->SetWindowType(window_id,
284 Browser::TYPE_TABBED,
285 SessionService::TYPE_NORMAL);
286 session_service->SetTabWindow(window_id, tab_id);
287 session_service->SetTabIndexInWindow(window_id, tab_id, 0);
288 session_service->SetSelectedTabInWindow(window_id, 0);
289 session_service->UpdateTabNavigation(
290 window_id, tab_id,
291 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
292 "http://wnd1/tab0", "title"));
293 // Set this, otherwise previous session won't be loaded.
294 profile()->set_last_session_exited_cleanly(false);
295 // Move this session to the last so that TabRestoreService will load it as the
296 // last session.
297 SessionServiceFactory::GetForProfile(profile())->
298 MoveCurrentSessionToLastSession();
300 // Create a new TabRestoreService so that it'll load the recently closed tabs
301 // and windows afresh.
302 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
303 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
304 // Let the shutdown of previous TabRestoreService run.
305 content::RunAllBlockingPoolTasksUntilIdle();
307 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
308 TestRecentTabsMenuModelDelegate delegate(&model);
309 EXPECT_FALSE(delegate.got_changes());
311 // Expected menu before tabs/windows from last session are loaded:
312 // Menu index Menu items
313 // ----------------------------------------------------------------
314 // 0 History
315 // 1 <separator>
316 // 2 Recently closed header
317 // 3 <separator>
318 // 4 No tabs from other Devices
320 int num_items = model.GetItemCount();
321 EXPECT_EQ(5, num_items);
322 EXPECT_TRUE(model.IsEnabledAt(0));
323 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
324 EXPECT_FALSE(model.IsEnabledAt(2));
325 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(3));
326 EXPECT_FALSE(model.IsEnabledAt(4));
327 EXPECT_EQ(1, model.enable_count());
329 // Wait for tabs from last session to be loaded.
330 WaitForLoadFromLastSession();
332 // Expected menu after tabs/windows from last session are loaded:
333 // Menu index Menu items
334 // --------------------------------------------------------------
335 // 0 History
336 // 1 <separator>
337 // 2 Recently closed header
338 // 3 <window for the tab http://wnd1/tab0>
339 // 4 <tab for http://wnd0/tab1>
340 // 5 <tab for http://wnd0/tab0>
341 // 6 <separator>
342 // 7 No tabs from other Devices
344 EXPECT_TRUE(delegate.got_changes());
346 num_items = model.GetItemCount();
347 EXPECT_EQ(8, num_items);
349 EXPECT_TRUE(model.IsEnabledAt(0));
350 model.ActivatedAt(0);
351 EXPECT_TRUE(model.IsEnabledAt(1));
352 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
353 EXPECT_FALSE(model.IsEnabledAt(2));
354 EXPECT_TRUE(model.IsEnabledAt(3));
355 EXPECT_TRUE(model.IsEnabledAt(4));
356 EXPECT_TRUE(model.IsEnabledAt(5));
357 model.ActivatedAt(3);
358 model.ActivatedAt(4);
359 model.ActivatedAt(5);
360 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(6));
361 EXPECT_FALSE(model.IsEnabledAt(7));
362 EXPECT_EQ(5, model.enable_count());
363 EXPECT_EQ(4, model.execute_count());
365 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
366 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
367 EXPECT_TRUE(model.GetLabelFontListAt(2) != nullptr);
368 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
369 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
370 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
371 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
372 EXPECT_EQ(NULL, model.GetLabelFontListAt(7));
374 std::string url;
375 base::string16 title;
376 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
377 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
378 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
379 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
380 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
381 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
382 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
383 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
386 // Test disabled "Recently closed" header with multiple sessions, multiple
387 // windows, and multiple enabled tabs from other devices.
388 TEST_F(RecentTabsSubMenuModelTest, OtherDevices) {
389 // Tabs are populated in decreasing timestamp.
390 base::Time timestamp = base::Time::Now();
391 const base::TimeDelta time_delta = base::TimeDelta::FromMinutes(10);
393 RecentTabsBuilderTestHelper recent_tabs_builder;
395 // Create 1st session : 1 window, 3 tabs
396 recent_tabs_builder.AddSession();
397 recent_tabs_builder.AddWindow(0);
398 for (int i = 0; i < 3; ++i) {
399 timestamp -= time_delta;
400 recent_tabs_builder.AddTabWithInfo(0, 0, timestamp, base::string16());
403 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
404 recent_tabs_builder.AddSession();
405 recent_tabs_builder.AddWindow(1);
406 recent_tabs_builder.AddWindow(1);
407 timestamp -= time_delta;
408 recent_tabs_builder.AddTabWithInfo(1, 0, timestamp, base::string16());
409 timestamp -= time_delta;
410 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
411 timestamp -= time_delta;
412 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
414 RegisterRecentTabs(&recent_tabs_builder);
416 // Verify that data is populated correctly in RecentTabsSubMenuModel.
417 // Expected menu:
418 // - first inserted tab is most recent and hence is top
419 // Menu index Menu items
420 // -----------------------------------------------------
421 // 0 History
422 // 1 <separator>
423 // 2 Recently closed header (disabled)
424 // 3 <separator>
425 // 4 <section header for 1st session>
426 // 5-7 <3 tabs of the only window of session 0>
427 // 8 <separator>
428 // 9 <section header for 2nd session>
429 // 10 <the only tab of window 0 of session 1>
430 // 11-12 <2 tabs of window 1 of session 2>
432 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
433 int num_items = model.GetItemCount();
434 EXPECT_EQ(13, num_items);
435 model.ActivatedAt(0);
436 EXPECT_TRUE(model.IsEnabledAt(0));
437 model.ActivatedAt(1);
438 EXPECT_TRUE(model.IsEnabledAt(1));
439 model.ActivatedAt(2);
440 EXPECT_FALSE(model.IsEnabledAt(2));
441 model.ActivatedAt(3);
442 EXPECT_TRUE(model.IsEnabledAt(3));
443 model.ActivatedAt(5);
444 EXPECT_TRUE(model.IsEnabledAt(5));
445 model.ActivatedAt(6);
446 EXPECT_TRUE(model.IsEnabledAt(6));
447 model.ActivatedAt(7);
448 EXPECT_TRUE(model.IsEnabledAt(7));
449 model.ActivatedAt(10);
450 EXPECT_TRUE(model.IsEnabledAt(10));
451 model.ActivatedAt(11);
452 EXPECT_TRUE(model.IsEnabledAt(11));
453 model.ActivatedAt(12);
454 EXPECT_TRUE(model.IsEnabledAt(12));
456 EXPECT_EQ(7, model.enable_count());
457 EXPECT_EQ(10, model.execute_count());
459 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
460 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
461 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
462 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
463 EXPECT_TRUE(model.GetLabelFontListAt(4) != nullptr);
464 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
465 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
466 EXPECT_EQ(NULL, model.GetLabelFontListAt(7));
467 EXPECT_EQ(NULL, model.GetLabelFontListAt(8));
468 EXPECT_TRUE(model.GetLabelFontListAt(9) != nullptr);
469 EXPECT_EQ(NULL, model.GetLabelFontListAt(10));
470 EXPECT_EQ(NULL, model.GetLabelFontListAt(11));
471 EXPECT_EQ(NULL, model.GetLabelFontListAt(12));
473 std::string url;
474 base::string16 title;
475 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
476 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
477 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
478 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
479 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
480 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
481 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
482 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
483 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(8, &url, &title));
484 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(9, &url, &title));
485 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(10, &url, &title));
486 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(11, &url, &title));
487 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(12, &url, &title));
490 TEST_F(RecentTabsSubMenuModelTest, MaxSessionsAndRecency) {
491 // Create 4 sessions : each session has 1 window with 1 tab each.
492 RecentTabsBuilderTestHelper recent_tabs_builder;
493 for (int s = 0; s < 4; ++s) {
494 recent_tabs_builder.AddSession();
495 recent_tabs_builder.AddWindow(s);
496 recent_tabs_builder.AddTab(s, 0);
498 RegisterRecentTabs(&recent_tabs_builder);
500 // Verify that data is populated correctly in RecentTabsSubMenuModel.
501 // Expected menu:
502 // - max sessions is 3, so only 3 most-recent sessions will show.
503 // Menu index Menu items
504 // ----------------------------------------------------------
505 // 0 History
506 // 1 <separator>
507 // 2 Recently closed header (disabled)
508 // 3 <separator>
509 // 4 <section header for 1st session>
510 // 5 <the only tab of the only window of session 3>
511 // 6 <separator>
512 // 7 <section header for 2nd session>
513 // 8 <the only tab of the only window of session 2>
514 // 9 <separator>
515 // 10 <section header for 3rd session>
516 // 11 <the only tab of the only window of session 1>
518 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
519 int num_items = model.GetItemCount();
520 EXPECT_EQ(12, num_items);
522 std::vector<base::string16> tab_titles =
523 recent_tabs_builder.GetTabTitlesSortedByRecency();
524 EXPECT_EQ(tab_titles[0], model.GetLabelAt(5));
525 EXPECT_EQ(tab_titles[1], model.GetLabelAt(8));
526 EXPECT_EQ(tab_titles[2], model.GetLabelAt(11));
529 TEST_F(RecentTabsSubMenuModelTest, MaxTabsPerSessionAndRecency) {
530 // Create a session: 2 windows with 5 tabs each.
531 RecentTabsBuilderTestHelper recent_tabs_builder;
532 recent_tabs_builder.AddSession();
533 for (int w = 0; w < 2; ++w) {
534 recent_tabs_builder.AddWindow(0);
535 for (int t = 0; t < 5; ++t)
536 recent_tabs_builder.AddTab(0, w);
538 RegisterRecentTabs(&recent_tabs_builder);
540 // Verify that data is populated correctly in RecentTabsSubMenuModel.
541 // Expected menu:
542 // - max tabs per session is 4, so only 4 most-recent tabs will show,
543 // independent of which window they came from.
544 // Menu index Menu items
545 // ---------------------------------------------
546 // 0 History
547 // 1 <separator>
548 // 2 Recently closed header (disabled)
549 // 3 <separator>
550 // 4 <section header for session>
551 // 5-8 <4 most-recent tabs of session>
553 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
554 int num_items = model.GetItemCount();
555 EXPECT_EQ(9, num_items);
557 std::vector<base::string16> tab_titles =
558 recent_tabs_builder.GetTabTitlesSortedByRecency();
559 for (int i = 0; i < 4; ++i)
560 EXPECT_EQ(tab_titles[i], model.GetLabelAt(i + 5));
563 TEST_F(RecentTabsSubMenuModelTest, MaxWidth) {
564 // Create 1 session with 1 window and 1 tab.
565 RecentTabsBuilderTestHelper recent_tabs_builder;
566 recent_tabs_builder.AddSession();
567 recent_tabs_builder.AddWindow(0);
568 recent_tabs_builder.AddTab(0, 0);
569 RegisterRecentTabs(&recent_tabs_builder);
571 // Menu index Menu items
572 // ----------------------------------------------------------
573 // 0 History
574 // 1 <separator>
575 // 2 Recently closed header (disabled)
576 // 3 <separator>
577 // 4 <section header for 1st session>
578 // 5 <the only tab of the only window of session 1>
580 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
581 EXPECT_EQ(6, model.GetItemCount());
582 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));
583 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
584 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(4));
585 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(5));
588 TEST_F(RecentTabsSubMenuModelTest, MaxWidthNoDevices) {
589 // Expected menu:
590 // Menu index Menu items
591 // --------------------------------------------
592 // 0 History
593 // 1 <separator>
594 // 2 Recently closed heaer (disabled)
595 // 3 <separator>
596 // 4 No tabs from other Devices
598 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
599 EXPECT_EQ(5, model.GetItemCount());
600 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));
601 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
602 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(4));