Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / recent_tabs_sub_menu_model_unittest.cc
blobc55dddecaf1389cc40700456b7a8804ddac217a8
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/persistent_tab_restore_service.h"
16 #include "chrome/browser/sessions/session_service.h"
17 #include "chrome/browser/sessions/session_service_factory.h"
18 #include "chrome/browser/sessions/tab_restore_service_factory.h"
19 #include "chrome/browser/sync/profile_sync_service_mock.h"
20 #include "chrome/browser/sync/sessions/sessions_sync_manager.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_tabstrip.h"
23 #include "chrome/browser/ui/sync/browser_synced_window_delegates_getter.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/test/base/browser_with_test_window_test.h"
28 #include "chrome/test/base/menu_model_test.h"
29 #include "chrome/test/base/testing_profile.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 Profile::FromBrowserContext(browser_context),
149 make_scoped_ptr(new ChromeTabRestoreServiceClient(
150 Profile::FromBrowserContext(browser_context))),
151 nullptr));
154 sync_driver::OpenTabsUIDelegate* GetOpenTabsDelegate() {
155 return manager_.get();
158 void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
159 helper->ExportToSessionsSyncManager(manager_.get());
162 private:
163 TestingProfile testing_profile_;
164 testing::NiceMock<ProfileSyncServiceMock> sync_service_;
166 scoped_ptr<browser_sync::SessionsSyncManager> manager_;
167 scoped_ptr<sync_driver::LocalDeviceInfoProviderMock> local_device_;
170 // Test disabled "Recently closed" header with no foreign tabs.
171 TEST_F(RecentTabsSubMenuModelTest, NoTabs) {
172 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
174 // Expected menu:
175 // Menu index Menu items
176 // ---------------------------------------------
177 // 0 History
178 // 1 <separator>
179 // 2 Recently closed header (disabled)
180 // 3 <separator>
181 // 4 No tabs from other Devices
183 int num_items = model.GetItemCount();
184 EXPECT_EQ(5, num_items);
185 EXPECT_FALSE(model.IsEnabledAt(2));
186 EXPECT_FALSE(model.IsEnabledAt(4));
187 EXPECT_EQ(0, model.enable_count());
189 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
190 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
191 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
192 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
193 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
195 std::string url;
196 base::string16 title;
197 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
198 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
199 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
200 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
201 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
204 // Test enabled "Recently closed" header with no foreign tabs.
205 TEST_F(RecentTabsSubMenuModelTest, RecentlyClosedTabsFromCurrentSession) {
206 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
207 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
209 // Add 2 tabs and close them.
210 AddTab(browser(), GURL("http://foo/1"));
211 AddTab(browser(), GURL("http://foo/2"));
212 browser()->tab_strip_model()->CloseAllTabs();
214 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
215 // Expected menu:
216 // Menu index Menu items
217 // --------------------------------------
218 // 0 History
219 // 1 <separator>
220 // 2 Recently closed header
221 // 3 <tab for http://foo/2>
222 // 4 <tab for http://foo/1>
223 // 5 <separator>
224 // 6 No tabs from other Devices
225 int num_items = model.GetItemCount();
226 EXPECT_EQ(7, num_items);
227 EXPECT_TRUE(model.IsEnabledAt(0));
228 model.ActivatedAt(0);
229 EXPECT_TRUE(model.IsEnabledAt(1));
230 EXPECT_FALSE(model.IsEnabledAt(2));
231 EXPECT_TRUE(model.IsEnabledAt(3));
232 EXPECT_TRUE(model.IsEnabledAt(4));
233 model.ActivatedAt(3);
234 model.ActivatedAt(4);
235 EXPECT_FALSE(model.IsEnabledAt(6));
236 EXPECT_EQ(3, model.enable_count());
237 EXPECT_EQ(3, model.execute_count());
239 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
240 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
241 EXPECT_TRUE(model.GetLabelFontListAt(2) != nullptr);
242 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
243 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
244 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
245 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
247 std::string url;
248 base::string16 title;
249 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
250 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
251 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
252 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
253 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
254 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
255 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
258 // TODO(sail): enable this test when dynamic model is enabled in
259 // RecentTabsSubMenuModel.
260 #if defined(OS_MACOSX)
261 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
262 DISABLED_RecentlyClosedTabsAndWindowsFromLastSession
263 #else
264 #define MAYBE_RecentlyClosedTabsAndWindowsFromLastSession \
265 RecentlyClosedTabsAndWindowsFromLastSession
266 #endif
267 TEST_F(RecentTabsSubMenuModelTest,
268 MAYBE_RecentlyClosedTabsAndWindowsFromLastSession) {
269 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
270 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
272 // Add 2 tabs and close them.
273 AddTab(browser(), GURL("http://wnd/tab0"));
274 AddTab(browser(), GURL("http://wnd/tab1"));
275 browser()->tab_strip_model()->CloseAllTabs();
277 // Create a SessionService for the profile (profile owns the service) and add
278 // a window with a tab to this session.
279 SessionService* session_service = new SessionService(profile());
280 SessionServiceFactory::SetForTestProfile(profile(),
281 make_scoped_ptr(session_service));
282 SessionID tab_id;
283 SessionID window_id;
284 session_service->SetWindowType(window_id,
285 Browser::TYPE_TABBED,
286 SessionService::TYPE_NORMAL);
287 session_service->SetTabWindow(window_id, tab_id);
288 session_service->SetTabIndexInWindow(window_id, tab_id, 0);
289 session_service->SetSelectedTabInWindow(window_id, 0);
290 session_service->UpdateTabNavigation(
291 window_id, tab_id,
292 sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
293 "http://wnd1/tab0", "title"));
294 // Set this, otherwise previous session won't be loaded.
295 profile()->set_last_session_exited_cleanly(false);
296 // Move this session to the last so that TabRestoreService will load it as the
297 // last session.
298 SessionServiceFactory::GetForProfile(profile())->
299 MoveCurrentSessionToLastSession();
301 // Create a new TabRestoreService so that it'll load the recently closed tabs
302 // and windows afresh.
303 TabRestoreServiceFactory::GetInstance()->SetTestingFactory(
304 profile(), RecentTabsSubMenuModelTest::GetTabRestoreService);
305 // Let the shutdown of previous TabRestoreService run.
306 content::RunAllBlockingPoolTasksUntilIdle();
308 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
309 TestRecentTabsMenuModelDelegate delegate(&model);
310 EXPECT_FALSE(delegate.got_changes());
312 // Expected menu before tabs/windows from last session are loaded:
313 // Menu index Menu items
314 // ----------------------------------------------------------------
315 // 0 History
316 // 1 <separator>
317 // 2 Recently closed header
318 // 3 <separator>
319 // 4 No tabs from other Devices
321 int num_items = model.GetItemCount();
322 EXPECT_EQ(5, num_items);
323 EXPECT_TRUE(model.IsEnabledAt(0));
324 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
325 EXPECT_FALSE(model.IsEnabledAt(2));
326 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(3));
327 EXPECT_FALSE(model.IsEnabledAt(4));
328 EXPECT_EQ(1, model.enable_count());
330 // Wait for tabs from last session to be loaded.
331 WaitForLoadFromLastSession();
333 // Expected menu after tabs/windows from last session are loaded:
334 // Menu index Menu items
335 // --------------------------------------------------------------
336 // 0 History
337 // 1 <separator>
338 // 2 Recently closed header
339 // 3 <window for the tab http://wnd1/tab0>
340 // 4 <tab for http://wnd0/tab1>
341 // 5 <tab for http://wnd0/tab0>
342 // 6 <separator>
343 // 7 No tabs from other Devices
345 EXPECT_TRUE(delegate.got_changes());
347 num_items = model.GetItemCount();
348 EXPECT_EQ(8, num_items);
350 EXPECT_TRUE(model.IsEnabledAt(0));
351 model.ActivatedAt(0);
352 EXPECT_TRUE(model.IsEnabledAt(1));
353 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(1));
354 EXPECT_FALSE(model.IsEnabledAt(2));
355 EXPECT_TRUE(model.IsEnabledAt(3));
356 EXPECT_TRUE(model.IsEnabledAt(4));
357 EXPECT_TRUE(model.IsEnabledAt(5));
358 model.ActivatedAt(3);
359 model.ActivatedAt(4);
360 model.ActivatedAt(5);
361 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model.GetTypeAt(6));
362 EXPECT_FALSE(model.IsEnabledAt(7));
363 EXPECT_EQ(5, model.enable_count());
364 EXPECT_EQ(4, model.execute_count());
366 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
367 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
368 EXPECT_TRUE(model.GetLabelFontListAt(2) != nullptr);
369 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
370 EXPECT_EQ(NULL, model.GetLabelFontListAt(4));
371 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
372 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
373 EXPECT_EQ(NULL, model.GetLabelFontListAt(7));
375 std::string url;
376 base::string16 title;
377 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
378 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
379 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
380 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
381 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
382 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
383 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
384 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
387 // Test disabled "Recently closed" header with multiple sessions, multiple
388 // windows, and multiple enabled tabs from other devices.
389 TEST_F(RecentTabsSubMenuModelTest, OtherDevices) {
390 // Tabs are populated in decreasing timestamp.
391 base::Time timestamp = base::Time::Now();
392 const base::TimeDelta time_delta = base::TimeDelta::FromMinutes(10);
394 RecentTabsBuilderTestHelper recent_tabs_builder;
396 // Create 1st session : 1 window, 3 tabs
397 recent_tabs_builder.AddSession();
398 recent_tabs_builder.AddWindow(0);
399 for (int i = 0; i < 3; ++i) {
400 timestamp -= time_delta;
401 recent_tabs_builder.AddTabWithInfo(0, 0, timestamp, base::string16());
404 // Create 2nd session : 2 windows, 1 tab in 1st window, 2 tabs in 2nd window
405 recent_tabs_builder.AddSession();
406 recent_tabs_builder.AddWindow(1);
407 recent_tabs_builder.AddWindow(1);
408 timestamp -= time_delta;
409 recent_tabs_builder.AddTabWithInfo(1, 0, timestamp, base::string16());
410 timestamp -= time_delta;
411 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
412 timestamp -= time_delta;
413 recent_tabs_builder.AddTabWithInfo(1, 1, timestamp, base::string16());
415 RegisterRecentTabs(&recent_tabs_builder);
417 // Verify that data is populated correctly in RecentTabsSubMenuModel.
418 // Expected menu:
419 // - first inserted tab is most recent and hence is top
420 // Menu index Menu items
421 // -----------------------------------------------------
422 // 0 History
423 // 1 <separator>
424 // 2 Recently closed header (disabled)
425 // 3 <separator>
426 // 4 <section header for 1st session>
427 // 5-7 <3 tabs of the only window of session 0>
428 // 8 <separator>
429 // 9 <section header for 2nd session>
430 // 10 <the only tab of window 0 of session 1>
431 // 11-12 <2 tabs of window 1 of session 2>
433 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
434 int num_items = model.GetItemCount();
435 EXPECT_EQ(13, num_items);
436 model.ActivatedAt(0);
437 EXPECT_TRUE(model.IsEnabledAt(0));
438 model.ActivatedAt(1);
439 EXPECT_TRUE(model.IsEnabledAt(1));
440 model.ActivatedAt(2);
441 EXPECT_FALSE(model.IsEnabledAt(2));
442 model.ActivatedAt(3);
443 EXPECT_TRUE(model.IsEnabledAt(3));
444 model.ActivatedAt(5);
445 EXPECT_TRUE(model.IsEnabledAt(5));
446 model.ActivatedAt(6);
447 EXPECT_TRUE(model.IsEnabledAt(6));
448 model.ActivatedAt(7);
449 EXPECT_TRUE(model.IsEnabledAt(7));
450 model.ActivatedAt(10);
451 EXPECT_TRUE(model.IsEnabledAt(10));
452 model.ActivatedAt(11);
453 EXPECT_TRUE(model.IsEnabledAt(11));
454 model.ActivatedAt(12);
455 EXPECT_TRUE(model.IsEnabledAt(12));
457 EXPECT_EQ(7, model.enable_count());
458 EXPECT_EQ(10, model.execute_count());
460 EXPECT_EQ(NULL, model.GetLabelFontListAt(0));
461 EXPECT_EQ(NULL, model.GetLabelFontListAt(1));
462 EXPECT_EQ(NULL, model.GetLabelFontListAt(2));
463 EXPECT_EQ(NULL, model.GetLabelFontListAt(3));
464 EXPECT_TRUE(model.GetLabelFontListAt(4) != nullptr);
465 EXPECT_EQ(NULL, model.GetLabelFontListAt(5));
466 EXPECT_EQ(NULL, model.GetLabelFontListAt(6));
467 EXPECT_EQ(NULL, model.GetLabelFontListAt(7));
468 EXPECT_EQ(NULL, model.GetLabelFontListAt(8));
469 EXPECT_TRUE(model.GetLabelFontListAt(9) != nullptr);
470 EXPECT_EQ(NULL, model.GetLabelFontListAt(10));
471 EXPECT_EQ(NULL, model.GetLabelFontListAt(11));
472 EXPECT_EQ(NULL, model.GetLabelFontListAt(12));
474 std::string url;
475 base::string16 title;
476 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(0, &url, &title));
477 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(1, &url, &title));
478 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(2, &url, &title));
479 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(3, &url, &title));
480 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(4, &url, &title));
481 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(5, &url, &title));
482 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(6, &url, &title));
483 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(7, &url, &title));
484 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(8, &url, &title));
485 EXPECT_FALSE(model.GetURLAndTitleForItemAtIndex(9, &url, &title));
486 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(10, &url, &title));
487 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(11, &url, &title));
488 EXPECT_TRUE(model.GetURLAndTitleForItemAtIndex(12, &url, &title));
491 TEST_F(RecentTabsSubMenuModelTest, MaxSessionsAndRecency) {
492 // Create 4 sessions : each session has 1 window with 1 tab each.
493 RecentTabsBuilderTestHelper recent_tabs_builder;
494 for (int s = 0; s < 4; ++s) {
495 recent_tabs_builder.AddSession();
496 recent_tabs_builder.AddWindow(s);
497 recent_tabs_builder.AddTab(s, 0);
499 RegisterRecentTabs(&recent_tabs_builder);
501 // Verify that data is populated correctly in RecentTabsSubMenuModel.
502 // Expected menu:
503 // - max sessions is 3, so only 3 most-recent sessions will show.
504 // Menu index Menu items
505 // ----------------------------------------------------------
506 // 0 History
507 // 1 <separator>
508 // 2 Recently closed header (disabled)
509 // 3 <separator>
510 // 4 <section header for 1st session>
511 // 5 <the only tab of the only window of session 3>
512 // 6 <separator>
513 // 7 <section header for 2nd session>
514 // 8 <the only tab of the only window of session 2>
515 // 9 <separator>
516 // 10 <section header for 3rd session>
517 // 11 <the only tab of the only window of session 1>
519 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
520 int num_items = model.GetItemCount();
521 EXPECT_EQ(12, num_items);
523 std::vector<base::string16> tab_titles =
524 recent_tabs_builder.GetTabTitlesSortedByRecency();
525 EXPECT_EQ(tab_titles[0], model.GetLabelAt(5));
526 EXPECT_EQ(tab_titles[1], model.GetLabelAt(8));
527 EXPECT_EQ(tab_titles[2], model.GetLabelAt(11));
530 TEST_F(RecentTabsSubMenuModelTest, MaxTabsPerSessionAndRecency) {
531 // Create a session: 2 windows with 5 tabs each.
532 RecentTabsBuilderTestHelper recent_tabs_builder;
533 recent_tabs_builder.AddSession();
534 for (int w = 0; w < 2; ++w) {
535 recent_tabs_builder.AddWindow(0);
536 for (int t = 0; t < 5; ++t)
537 recent_tabs_builder.AddTab(0, w);
539 RegisterRecentTabs(&recent_tabs_builder);
541 // Verify that data is populated correctly in RecentTabsSubMenuModel.
542 // Expected menu:
543 // - max tabs per session is 4, so only 4 most-recent tabs will show,
544 // independent of which window they came from.
545 // Menu index Menu items
546 // ---------------------------------------------
547 // 0 History
548 // 1 <separator>
549 // 2 Recently closed header (disabled)
550 // 3 <separator>
551 // 4 <section header for session>
552 // 5-8 <4 most-recent tabs of session>
554 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
555 int num_items = model.GetItemCount();
556 EXPECT_EQ(9, num_items);
558 std::vector<base::string16> tab_titles =
559 recent_tabs_builder.GetTabTitlesSortedByRecency();
560 for (int i = 0; i < 4; ++i)
561 EXPECT_EQ(tab_titles[i], model.GetLabelAt(i + 5));
564 TEST_F(RecentTabsSubMenuModelTest, MaxWidth) {
565 // Create 1 session with 1 window and 1 tab.
566 RecentTabsBuilderTestHelper recent_tabs_builder;
567 recent_tabs_builder.AddSession();
568 recent_tabs_builder.AddWindow(0);
569 recent_tabs_builder.AddTab(0, 0);
570 RegisterRecentTabs(&recent_tabs_builder);
572 // Menu index Menu items
573 // ----------------------------------------------------------
574 // 0 History
575 // 1 <separator>
576 // 2 Recently closed header (disabled)
577 // 3 <separator>
578 // 4 <section header for 1st session>
579 // 5 <the only tab of the only window of session 1>
581 TestRecentTabsSubMenuModel model(NULL, browser(), GetOpenTabsDelegate());
582 EXPECT_EQ(6, model.GetItemCount());
583 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));
584 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
585 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(4));
586 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(5));
589 TEST_F(RecentTabsSubMenuModelTest, MaxWidthNoDevices) {
590 // Expected menu:
591 // Menu index Menu items
592 // --------------------------------------------
593 // 0 History
594 // 1 <separator>
595 // 2 Recently closed heaer (disabled)
596 // 3 <separator>
597 // 4 No tabs from other Devices
599 TestRecentTabsSubMenuModel model(NULL, browser(), NULL);
600 EXPECT_EQ(5, model.GetItemCount());
601 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(2));
602 EXPECT_NE(-1, model.GetMaxWidthForItemAtIndex(3));
603 EXPECT_EQ(-1, model.GetMaxWidthForItemAtIndex(4));