Home | History | Annotate | Download | only in sessions
      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.
      4 
      5 #include "base/bind.h"
      6 #include "base/bind_helpers.h"
      7 #include "base/file_util.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/memory/scoped_vector.h"
     11 #include "base/path_service.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "base/time/time.h"
     16 #include "chrome/browser/browser_process.h"
     17 #include "chrome/browser/chrome_notification_types.h"
     18 #include "chrome/browser/defaults.h"
     19 #include "chrome/browser/profiles/profile_manager.h"
     20 #include "chrome/browser/sessions/session_backend.h"
     21 #include "chrome/browser/sessions/session_service.h"
     22 #include "chrome/browser/sessions/session_service_test_helper.h"
     23 #include "chrome/browser/sessions/session_types.h"
     24 #include "chrome/common/chrome_paths.h"
     25 #include "chrome/common/url_constants.h"
     26 #include "chrome/test/base/browser_with_test_window_test.h"
     27 #include "chrome/test/base/testing_browser_process.h"
     28 #include "chrome/test/base/testing_profile.h"
     29 #include "chrome/test/base/testing_profile_manager.h"
     30 #include "components/sessions/serialized_navigation_entry_test_helper.h"
     31 #include "content/public/browser/navigation_entry.h"
     32 #include "content/public/browser/notification_observer.h"
     33 #include "content/public/browser/notification_registrar.h"
     34 #include "content/public/browser/notification_service.h"
     35 #include "content/public/common/page_state.h"
     36 #include "testing/gtest/include/gtest/gtest.h"
     37 
     38 using content::NavigationEntry;
     39 using sessions::SerializedNavigationEntry;
     40 using sessions::SerializedNavigationEntryTestHelper;
     41 
     42 class SessionServiceTest : public BrowserWithTestWindowTest,
     43                            public content::NotificationObserver {
     44  public:
     45   SessionServiceTest() : window_bounds(0, 1, 2, 3), sync_save_count_(0) {}
     46 
     47  protected:
     48   virtual void SetUp() {
     49     BrowserWithTestWindowTest::SetUp();
     50 
     51     profile_manager_.reset(
     52         new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
     53     ASSERT_TRUE(profile_manager_->SetUp());
     54 
     55     std::string b = base::Int64ToString(base::Time::Now().ToInternalValue());
     56     TestingProfile* profile = profile_manager_->CreateTestingProfile(b);
     57     SessionService* session_service = new SessionService(profile);
     58     path_ = profile->GetPath();
     59 
     60     helper_.SetService(session_service);
     61 
     62     service()->SetWindowType(
     63         window_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
     64     service()->SetWindowBounds(window_id,
     65                                window_bounds,
     66                                ui::SHOW_STATE_NORMAL);
     67   }
     68 
     69   // Upon notification, increment the sync_save_count variable
     70   virtual void Observe(int type,
     71                        const content::NotificationSource& source,
     72                        const content::NotificationDetails& details) OVERRIDE {
     73     ASSERT_EQ(type, chrome::NOTIFICATION_SESSION_SERVICE_SAVED);
     74     sync_save_count_++;
     75   }
     76 
     77   virtual void TearDown() {
     78     helper_.SetService(NULL);
     79     BrowserWithTestWindowTest::TearDown();
     80   }
     81 
     82   void UpdateNavigation(
     83       const SessionID& window_id,
     84       const SessionID& tab_id,
     85       const SerializedNavigationEntry& navigation,
     86       bool select) {
     87     service()->UpdateTabNavigation(window_id, tab_id, navigation);
     88     if (select) {
     89       service()->SetSelectedNavigationIndex(
     90           window_id, tab_id, navigation.index());
     91     }
     92   }
     93 
     94   void ReadWindows(std::vector<SessionWindow*>* windows,
     95                    SessionID::id_type* active_window_id) {
     96     // Forces closing the file.
     97     helper_.SetService(NULL);
     98 
     99     SessionService* session_service = new SessionService(path_);
    100     helper_.SetService(session_service);
    101 
    102     SessionID::id_type* non_null_active_window_id = active_window_id;
    103     SessionID::id_type dummy_active_window_id = 0;
    104     if (!non_null_active_window_id)
    105       non_null_active_window_id = &dummy_active_window_id;
    106     helper_.ReadWindows(windows, non_null_active_window_id);
    107   }
    108 
    109   // Configures the session service with one window with one tab and a single
    110   // navigation. If |pinned_state| is true or |write_always| is true, the
    111   // pinned state of the tab is updated. The session service is then recreated
    112   // and the pinned state of the read back tab is returned.
    113   bool CreateAndWriteSessionWithOneTab(bool pinned_state, bool write_always) {
    114     SessionID tab_id;
    115     SerializedNavigationEntry nav1 =
    116         SerializedNavigationEntryTestHelper::CreateNavigation(
    117             "http://google.com", "abc");
    118 
    119     helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    120     UpdateNavigation(window_id, tab_id, nav1, true);
    121 
    122     if (pinned_state || write_always)
    123       helper_.service()->SetPinnedState(window_id, tab_id, pinned_state);
    124 
    125     ScopedVector<SessionWindow> windows;
    126     ReadWindows(&(windows.get()), NULL);
    127 
    128     EXPECT_EQ(1U, windows.size());
    129     if (HasFatalFailure())
    130       return false;
    131     EXPECT_EQ(1U, windows[0]->tabs.size());
    132     if (HasFatalFailure())
    133       return false;
    134 
    135     SessionTab* tab = windows[0]->tabs[0];
    136     helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    137 
    138     return tab->pinned;
    139   }
    140 
    141   void CreateAndWriteSessionWithTwoWindows(
    142       const SessionID& window2_id,
    143       const SessionID& tab1_id,
    144       const SessionID& tab2_id,
    145       SerializedNavigationEntry* nav1,
    146       SerializedNavigationEntry* nav2) {
    147     *nav1 = SerializedNavigationEntryTestHelper::CreateNavigation(
    148         "http://google.com", "abc");
    149     *nav2 = SerializedNavigationEntryTestHelper::CreateNavigation(
    150         "http://google2.com", "abcd");
    151 
    152     helper_.PrepareTabInWindow(window_id, tab1_id, 0, true);
    153     UpdateNavigation(window_id, tab1_id, *nav1, true);
    154 
    155     const gfx::Rect window2_bounds(3, 4, 5, 6);
    156     service()->SetWindowType(
    157         window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
    158     service()->SetWindowBounds(window2_id,
    159                                window2_bounds,
    160                                ui::SHOW_STATE_MAXIMIZED);
    161     helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true);
    162     UpdateNavigation(window2_id, tab2_id, *nav2, true);
    163   }
    164 
    165   SessionService* service() { return helper_.service(); }
    166 
    167   SessionBackend* backend() { return helper_.backend(); }
    168 
    169   const gfx::Rect window_bounds;
    170 
    171   SessionID window_id;
    172 
    173   int sync_save_count_;
    174 
    175   // Path used in testing.
    176   base::ScopedTempDir temp_dir_;
    177   base::FilePath path_;
    178 
    179   SessionServiceTestHelper helper_;
    180   scoped_ptr<TestingProfileManager> profile_manager_;
    181 };
    182 
    183 TEST_F(SessionServiceTest, Basic) {
    184   SessionID tab_id;
    185   ASSERT_NE(window_id.id(), tab_id.id());
    186 
    187   SerializedNavigationEntry nav1 =
    188       SerializedNavigationEntryTestHelper::CreateNavigation(
    189           "http://google.com", "abc");
    190   SerializedNavigationEntryTestHelper::SetOriginalRequestURL(
    191       GURL("http://original.request.com"), &nav1);
    192 
    193   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    194   UpdateNavigation(window_id, tab_id, nav1, true);
    195 
    196   ScopedVector<SessionWindow> windows;
    197   ReadWindows(&(windows.get()), NULL);
    198 
    199   ASSERT_EQ(1U, windows.size());
    200   ASSERT_TRUE(window_bounds == windows[0]->bounds);
    201   ASSERT_EQ(0, windows[0]->selected_tab_index);
    202   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    203   ASSERT_EQ(1U, windows[0]->tabs.size());
    204   ASSERT_EQ(Browser::TYPE_TABBED, windows[0]->type);
    205 
    206   SessionTab* tab = windows[0]->tabs[0];
    207   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    208 
    209   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    210 }
    211 
    212 // Make sure we persist post entries.
    213 TEST_F(SessionServiceTest, PersistPostData) {
    214   SessionID tab_id;
    215   ASSERT_NE(window_id.id(), tab_id.id());
    216 
    217   SerializedNavigationEntry nav1 =
    218       SerializedNavigationEntryTestHelper::CreateNavigation(
    219           "http://google.com", "abc");
    220   SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
    221 
    222   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    223   UpdateNavigation(window_id, tab_id, nav1, true);
    224 
    225   ScopedVector<SessionWindow> windows;
    226   ReadWindows(&(windows.get()), NULL);
    227 
    228   helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
    229 }
    230 
    231 TEST_F(SessionServiceTest, ClosingTabStaysClosed) {
    232   SessionID tab_id;
    233   SessionID tab2_id;
    234   ASSERT_NE(tab_id.id(), tab2_id.id());
    235 
    236   SerializedNavigationEntry nav1 =
    237       SerializedNavigationEntryTestHelper::CreateNavigation(
    238           "http://google.com", "abc");
    239   SerializedNavigationEntry nav2 =
    240       SerializedNavigationEntryTestHelper::CreateNavigation(
    241           "http://google2.com", "abcd");
    242 
    243   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    244   UpdateNavigation(window_id, tab_id, nav1, true);
    245 
    246   helper_.PrepareTabInWindow(window_id, tab2_id, 1, false);
    247   UpdateNavigation(window_id, tab2_id, nav2, true);
    248   service()->TabClosed(window_id, tab2_id, false);
    249 
    250   ScopedVector<SessionWindow> windows;
    251   ReadWindows(&(windows.get()), NULL);
    252 
    253   ASSERT_EQ(1U, windows.size());
    254   ASSERT_EQ(0, windows[0]->selected_tab_index);
    255   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    256   ASSERT_EQ(1U, windows[0]->tabs.size());
    257 
    258   SessionTab* tab = windows[0]->tabs[0];
    259   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    260 
    261   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    262 }
    263 
    264 TEST_F(SessionServiceTest, Pruning) {
    265   SessionID tab_id;
    266 
    267   SerializedNavigationEntry nav1 =
    268       SerializedNavigationEntryTestHelper::CreateNavigation(
    269           "http://google.com", "abc");
    270   SerializedNavigationEntry nav2 =
    271       SerializedNavigationEntryTestHelper::CreateNavigation(
    272           "http://google2.com", "abcd");
    273 
    274   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    275   for (int i = 0; i < 6; ++i) {
    276     SerializedNavigationEntry* nav = (i % 2) == 0 ? &nav1 : &nav2;
    277     nav->set_index(i);
    278     UpdateNavigation(window_id, tab_id, *nav, true);
    279   }
    280   service()->TabNavigationPathPrunedFromBack(window_id, tab_id, 3);
    281 
    282   ScopedVector<SessionWindow> windows;
    283   ReadWindows(&(windows.get()), NULL);
    284 
    285   ASSERT_EQ(1U, windows.size());
    286   ASSERT_EQ(0, windows[0]->selected_tab_index);
    287   ASSERT_EQ(1U, windows[0]->tabs.size());
    288 
    289   SessionTab* tab = windows[0]->tabs[0];
    290   // We left the selected index at 5, then pruned. When rereading the
    291   // index should get reset to last valid navigation, which is 2.
    292   helper_.AssertTabEquals(window_id, tab_id, 0, 2, 3, *tab);
    293 
    294   ASSERT_EQ(3u, tab->navigations.size());
    295   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    296   helper_.AssertNavigationEquals(nav2, tab->navigations[1]);
    297   helper_.AssertNavigationEquals(nav1, tab->navigations[2]);
    298 }
    299 
    300 TEST_F(SessionServiceTest, TwoWindows) {
    301   SessionID window2_id;
    302   SessionID tab1_id;
    303   SessionID tab2_id;
    304   SerializedNavigationEntry nav1;
    305   SerializedNavigationEntry nav2;
    306 
    307   CreateAndWriteSessionWithTwoWindows(
    308       window2_id, tab1_id, tab2_id, &nav1, &nav2);
    309 
    310   ScopedVector<SessionWindow> windows;
    311   ReadWindows(&(windows.get()), NULL);
    312 
    313   ASSERT_EQ(2U, windows.size());
    314   ASSERT_EQ(0, windows[0]->selected_tab_index);
    315   ASSERT_EQ(0, windows[1]->selected_tab_index);
    316   ASSERT_EQ(1U, windows[0]->tabs.size());
    317   ASSERT_EQ(1U, windows[1]->tabs.size());
    318 
    319   SessionTab* rt1;
    320   SessionTab* rt2;
    321   if (windows[0]->window_id.id() == window_id.id()) {
    322     ASSERT_EQ(window2_id.id(), windows[1]->window_id.id());
    323     ASSERT_EQ(ui::SHOW_STATE_NORMAL, windows[0]->show_state);
    324     ASSERT_EQ(ui::SHOW_STATE_MAXIMIZED, windows[1]->show_state);
    325     rt1 = windows[0]->tabs[0];
    326     rt2 = windows[1]->tabs[0];
    327   } else {
    328     ASSERT_EQ(window2_id.id(), windows[0]->window_id.id());
    329     ASSERT_EQ(window_id.id(), windows[1]->window_id.id());
    330     ASSERT_EQ(ui::SHOW_STATE_MAXIMIZED, windows[0]->show_state);
    331     ASSERT_EQ(ui::SHOW_STATE_NORMAL, windows[1]->show_state);
    332     rt1 = windows[1]->tabs[0];
    333     rt2 = windows[0]->tabs[0];
    334   }
    335   SessionTab* tab = rt1;
    336   helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab);
    337   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    338 
    339   tab = rt2;
    340   helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
    341   helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
    342 }
    343 
    344 TEST_F(SessionServiceTest, WindowWithNoTabsGetsPruned) {
    345   SessionID window2_id;
    346   SessionID tab1_id;
    347   SessionID tab2_id;
    348 
    349   SerializedNavigationEntry nav1 =
    350       SerializedNavigationEntryTestHelper::CreateNavigation(
    351           "http://google.com", "abc");
    352 
    353   helper_.PrepareTabInWindow(window_id, tab1_id, 0, true);
    354   UpdateNavigation(window_id, tab1_id, nav1, true);
    355 
    356   const gfx::Rect window2_bounds(3, 4, 5, 6);
    357   service()->SetWindowType(
    358       window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
    359   service()->SetWindowBounds(window2_id,
    360                              window2_bounds,
    361                              ui::SHOW_STATE_NORMAL);
    362   helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true);
    363 
    364   ScopedVector<SessionWindow> windows;
    365   ReadWindows(&(windows.get()), NULL);
    366 
    367   ASSERT_EQ(1U, windows.size());
    368   ASSERT_EQ(0, windows[0]->selected_tab_index);
    369   ASSERT_EQ(1U, windows[0]->tabs.size());
    370   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    371 
    372   SessionTab* tab = windows[0]->tabs[0];
    373   helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab);
    374   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    375 }
    376 
    377 TEST_F(SessionServiceTest, ClosingWindowDoesntCloseTabs) {
    378   SessionID tab_id;
    379   SessionID tab2_id;
    380   ASSERT_NE(tab_id.id(), tab2_id.id());
    381 
    382   SerializedNavigationEntry nav1 =
    383       SerializedNavigationEntryTestHelper::CreateNavigation(
    384           "http://google.com", "abc");
    385   SerializedNavigationEntry nav2 =
    386       SerializedNavigationEntryTestHelper::CreateNavigation(
    387           "http://google2.com", "abcd");
    388 
    389   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    390   UpdateNavigation(window_id, tab_id, nav1, true);
    391 
    392   helper_.PrepareTabInWindow(window_id, tab2_id, 1, false);
    393   UpdateNavigation(window_id, tab2_id, nav2, true);
    394 
    395   service()->WindowClosing(window_id);
    396 
    397   ScopedVector<SessionWindow> windows;
    398   ReadWindows(&(windows.get()), NULL);
    399 
    400   ASSERT_EQ(1U, windows.size());
    401   ASSERT_EQ(0, windows[0]->selected_tab_index);
    402   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    403   ASSERT_EQ(2U, windows[0]->tabs.size());
    404 
    405   SessionTab* tab = windows[0]->tabs[0];
    406   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    407   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    408 
    409   tab = windows[0]->tabs[1];
    410   helper_.AssertTabEquals(window_id, tab2_id, 1, 0, 1, *tab);
    411   helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
    412 }
    413 
    414 TEST_F(SessionServiceTest, LockingWindowRemembersAll) {
    415   SessionID window2_id;
    416   SessionID tab1_id;
    417   SessionID tab2_id;
    418   SerializedNavigationEntry nav1;
    419   SerializedNavigationEntry nav2;
    420 
    421   CreateAndWriteSessionWithTwoWindows(
    422       window2_id, tab1_id, tab2_id, &nav1, &nav2);
    423 
    424   ASSERT_TRUE(service()->profile() != NULL);
    425   ASSERT_TRUE(g_browser_process->profile_manager() != NULL);
    426   ProfileInfoCache& profile_info =
    427       g_browser_process->profile_manager()->GetProfileInfoCache();
    428   size_t profile_index = profile_info.GetIndexOfProfileWithPath(
    429       service()->profile()->GetPath());
    430   ASSERT_NE(std::string::npos, profile_index);
    431   profile_info.SetProfileSigninRequiredAtIndex(profile_index, true);
    432 
    433   service()->WindowClosing(window_id);
    434   service()->WindowClosed(window_id);
    435   service()->WindowClosing(window2_id);
    436   service()->WindowClosed(window2_id);
    437 
    438   ScopedVector<SessionWindow> windows;
    439   ReadWindows(&(windows.get()), NULL);
    440 
    441   ASSERT_EQ(2U, windows.size());
    442   ASSERT_EQ(1U, windows[0]->tabs.size());
    443   ASSERT_EQ(1U, windows[1]->tabs.size());
    444 }
    445 
    446 TEST_F(SessionServiceTest, WindowCloseCommittedAfterNavigate) {
    447   SessionID window2_id;
    448   SessionID tab_id;
    449   SessionID tab2_id;
    450   ASSERT_NE(window2_id.id(), window_id.id());
    451 
    452   service()->SetWindowType(
    453       window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
    454   service()->SetWindowBounds(window2_id,
    455                              window_bounds,
    456                              ui::SHOW_STATE_NORMAL);
    457 
    458   SerializedNavigationEntry nav1 =
    459       SerializedNavigationEntryTestHelper::CreateNavigation(
    460           "http://google.com", "abc");
    461   SerializedNavigationEntry nav2 =
    462       SerializedNavigationEntryTestHelper::CreateNavigation(
    463           "http://google2.com", "abcd");
    464 
    465   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    466   UpdateNavigation(window_id, tab_id, nav1, true);
    467 
    468   helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
    469   UpdateNavigation(window2_id, tab2_id, nav2, true);
    470 
    471   service()->WindowClosing(window2_id);
    472   service()->TabClosed(window2_id, tab2_id, false);
    473   service()->WindowClosed(window2_id);
    474 
    475   ScopedVector<SessionWindow> windows;
    476   ReadWindows(&(windows.get()), NULL);
    477 
    478   ASSERT_EQ(1U, windows.size());
    479   ASSERT_EQ(0, windows[0]->selected_tab_index);
    480   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    481   ASSERT_EQ(1U, windows[0]->tabs.size());
    482 
    483   SessionTab* tab = windows[0]->tabs[0];
    484   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    485   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    486 }
    487 
    488 // Makes sure we don't track popups.
    489 TEST_F(SessionServiceTest, IgnorePopups) {
    490   SessionID window2_id;
    491   SessionID tab_id;
    492   SessionID tab2_id;
    493   ASSERT_NE(window2_id.id(), window_id.id());
    494 
    495   service()->SetWindowType(
    496       window2_id, Browser::TYPE_POPUP, SessionService::TYPE_NORMAL);
    497   service()->SetWindowBounds(window2_id,
    498                              window_bounds,
    499                              ui::SHOW_STATE_NORMAL);
    500 
    501   SerializedNavigationEntry nav1 =
    502       SerializedNavigationEntryTestHelper::CreateNavigation(
    503           "http://google.com", "abc");
    504   SerializedNavigationEntry nav2 =
    505       SerializedNavigationEntryTestHelper::CreateNavigation(
    506           "http://google2.com", "abcd");
    507 
    508   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    509   UpdateNavigation(window_id, tab_id, nav1, true);
    510 
    511   helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
    512   UpdateNavigation(window2_id, tab2_id, nav2, true);
    513 
    514   ScopedVector<SessionWindow> windows;
    515   ReadWindows(&(windows.get()), NULL);
    516 
    517   ASSERT_EQ(1U, windows.size());
    518   ASSERT_EQ(0, windows[0]->selected_tab_index);
    519   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    520   ASSERT_EQ(1U, windows[0]->tabs.size());
    521 
    522   SessionTab* tab = windows[0]->tabs[0];
    523   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    524   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    525 }
    526 
    527 #if defined (OS_CHROMEOS)
    528 // Makes sure we track apps. Only applicable on chromeos.
    529 TEST_F(SessionServiceTest, RestoreApp) {
    530   SessionID window2_id;
    531   SessionID tab_id;
    532   SessionID tab2_id;
    533   ASSERT_NE(window2_id.id(), window_id.id());
    534 
    535   service()->SetWindowType(
    536       window2_id, Browser::TYPE_POPUP, SessionService::TYPE_APP);
    537   service()->SetWindowBounds(window2_id,
    538                              window_bounds,
    539                              ui::SHOW_STATE_NORMAL);
    540   service()->SetWindowAppName(window2_id, "TestApp");
    541 
    542   SerializedNavigationEntry nav1 =
    543       SerializedNavigationEntryTestHelper::CreateNavigation(
    544           "http://google.com", "abc");
    545   SerializedNavigationEntry nav2 =
    546       SerializedNavigationEntryTestHelper::CreateNavigation(
    547           "http://google2.com", "abcd");
    548 
    549   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    550   UpdateNavigation(window_id, tab_id, nav1, true);
    551 
    552   helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
    553   UpdateNavigation(window2_id, tab2_id, nav2, true);
    554 
    555   ScopedVector<SessionWindow> windows;
    556   ReadWindows(&(windows.get()), NULL);
    557 
    558   ASSERT_EQ(2U, windows.size());
    559   int tabbed_index = windows[0]->type == Browser::TYPE_TABBED ?
    560       0 : 1;
    561   int app_index = tabbed_index == 0 ? 1 : 0;
    562   ASSERT_EQ(0, windows[tabbed_index]->selected_tab_index);
    563   ASSERT_EQ(window_id.id(), windows[tabbed_index]->window_id.id());
    564   ASSERT_EQ(1U, windows[tabbed_index]->tabs.size());
    565 
    566   SessionTab* tab = windows[tabbed_index]->tabs[0];
    567   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    568   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    569 
    570   ASSERT_EQ(0, windows[app_index]->selected_tab_index);
    571   ASSERT_EQ(window2_id.id(), windows[app_index]->window_id.id());
    572   ASSERT_EQ(1U, windows[app_index]->tabs.size());
    573   ASSERT_TRUE(windows[app_index]->type == Browser::TYPE_POPUP);
    574   ASSERT_EQ("TestApp", windows[app_index]->app_name);
    575 
    576   tab = windows[app_index]->tabs[0];
    577   helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
    578   helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
    579 }
    580 #endif  // defined (OS_CHROMEOS)
    581 
    582 // Tests pruning from the front.
    583 TEST_F(SessionServiceTest, PruneFromFront) {
    584   const std::string base_url("http://google.com/");
    585   SessionID tab_id;
    586 
    587   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    588 
    589   // Add 5 navigations, with the 4th selected.
    590   for (int i = 0; i < 5; ++i) {
    591     SerializedNavigationEntry nav =
    592         SerializedNavigationEntryTestHelper::CreateNavigation(
    593             base_url + base::IntToString(i), "a");
    594     nav.set_index(i);
    595     UpdateNavigation(window_id, tab_id, nav, (i == 3));
    596   }
    597 
    598   // Prune the first two navigations from the front.
    599   helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 2);
    600 
    601   // Read back in.
    602   ScopedVector<SessionWindow> windows;
    603   ReadWindows(&(windows.get()), NULL);
    604 
    605   ASSERT_EQ(1U, windows.size());
    606   ASSERT_EQ(0, windows[0]->selected_tab_index);
    607   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    608   ASSERT_EQ(1U, windows[0]->tabs.size());
    609 
    610   // There shouldn't be an app id.
    611   EXPECT_TRUE(windows[0]->tabs[0]->extension_app_id.empty());
    612 
    613   // We should be left with three navigations, the 2nd selected.
    614   SessionTab* tab = windows[0]->tabs[0];
    615   ASSERT_EQ(1, tab->current_navigation_index);
    616   EXPECT_EQ(3U, tab->navigations.size());
    617   EXPECT_TRUE(GURL(base_url + base::IntToString(2)) ==
    618               tab->navigations[0].virtual_url());
    619   EXPECT_TRUE(GURL(base_url + base::IntToString(3)) ==
    620               tab->navigations[1].virtual_url());
    621   EXPECT_TRUE(GURL(base_url + base::IntToString(4)) ==
    622               tab->navigations[2].virtual_url());
    623 }
    624 
    625 // Prunes from front so that we have no entries.
    626 TEST_F(SessionServiceTest, PruneToEmpty) {
    627   const std::string base_url("http://google.com/");
    628   SessionID tab_id;
    629 
    630   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    631 
    632   // Add 5 navigations, with the 4th selected.
    633   for (int i = 0; i < 5; ++i) {
    634     SerializedNavigationEntry nav =
    635         SerializedNavigationEntryTestHelper::CreateNavigation(
    636             base_url + base::IntToString(i), "a");
    637     nav.set_index(i);
    638     UpdateNavigation(window_id, tab_id, nav, (i == 3));
    639   }
    640 
    641   // Prune the first two navigations from the front.
    642   helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 5);
    643 
    644   // Read back in.
    645   ScopedVector<SessionWindow> windows;
    646   ReadWindows(&(windows.get()), NULL);
    647 
    648   ASSERT_EQ(0U, windows.size());
    649 }
    650 
    651 // Don't set the pinned state and make sure the pinned value is false.
    652 TEST_F(SessionServiceTest, PinnedDefaultsToFalse) {
    653   EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, false));
    654 }
    655 
    656 // Explicitly set the pinned state to false and make sure we get back false.
    657 TEST_F(SessionServiceTest, PinnedFalseWhenSetToFalse) {
    658   EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, true));
    659 }
    660 
    661 // Explicitly set the pinned state to true and make sure we get back true.
    662 TEST_F(SessionServiceTest, PinnedTrue) {
    663   EXPECT_TRUE(CreateAndWriteSessionWithOneTab(true, true));
    664 }
    665 
    666 // Make sure application extension ids are persisted.
    667 TEST_F(SessionServiceTest, PersistApplicationExtensionID) {
    668   SessionID tab_id;
    669   ASSERT_NE(window_id.id(), tab_id.id());
    670   std::string app_id("foo");
    671 
    672   SerializedNavigationEntry nav1 =
    673       SerializedNavigationEntryTestHelper::CreateNavigation(
    674           "http://google.com", "abc");
    675 
    676   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    677   UpdateNavigation(window_id, tab_id, nav1, true);
    678   helper_.SetTabExtensionAppID(window_id, tab_id, app_id);
    679 
    680   ScopedVector<SessionWindow> windows;
    681   ReadWindows(&(windows.get()), NULL);
    682 
    683   helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
    684   EXPECT_TRUE(app_id == windows[0]->tabs[0]->extension_app_id);
    685 }
    686 
    687 // Check that user agent overrides are persisted.
    688 TEST_F(SessionServiceTest, PersistUserAgentOverrides) {
    689   SessionID tab_id;
    690   ASSERT_NE(window_id.id(), tab_id.id());
    691   std::string user_agent_override = "Mozilla/5.0 (X11; Linux x86_64) "
    692       "AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 "
    693       "Safari/535.19";
    694 
    695   SerializedNavigationEntry nav1 =
    696       SerializedNavigationEntryTestHelper::CreateNavigation(
    697           "http://google.com", "abc");
    698   SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav1);
    699 
    700   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    701   UpdateNavigation(window_id, tab_id, nav1, true);
    702   helper_.SetTabUserAgentOverride(window_id, tab_id, user_agent_override);
    703 
    704   ScopedVector<SessionWindow> windows;
    705   ReadWindows(&(windows.get()), NULL);
    706   helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
    707 
    708   SessionTab* tab = windows[0]->tabs[0];
    709   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
    710   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
    711   EXPECT_TRUE(user_agent_override == tab->user_agent_override);
    712 }
    713 
    714 // Test that the notification for SESSION_SERVICE_SAVED is working properly.
    715 TEST_F(SessionServiceTest, SavedSessionNotification) {
    716   content::NotificationRegistrar registrar_;
    717   registrar_.Add(this, chrome::NOTIFICATION_SESSION_SERVICE_SAVED,
    718                  content::NotificationService::AllSources());
    719   service()->Save();
    720   EXPECT_EQ(sync_save_count_, 1);
    721 }
    722 
    723 // Makes sure a tab closed by a user gesture is not restored.
    724 TEST_F(SessionServiceTest, CloseTabUserGesture) {
    725   SessionID tab_id;
    726   ASSERT_NE(window_id.id(), tab_id.id());
    727 
    728   SerializedNavigationEntry nav1 =
    729       SerializedNavigationEntryTestHelper::CreateNavigation(
    730           "http://google.com", "abc");
    731 
    732   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    733   UpdateNavigation(window_id, tab_id, nav1, true);
    734   service()->TabClosed(window_id, tab_id, true);
    735 
    736   ScopedVector<SessionWindow> windows;
    737   ReadWindows(&(windows.get()), NULL);
    738 
    739   ASSERT_TRUE(windows.empty());
    740 }
    741 
    742 // Verifies SetWindowBounds maps SHOW_STATE_DEFAULT to SHOW_STATE_NORMAL.
    743 TEST_F(SessionServiceTest, DontPersistDefault) {
    744   SessionID tab_id;
    745   ASSERT_NE(window_id.id(), tab_id.id());
    746   SerializedNavigationEntry nav1 =
    747       SerializedNavigationEntryTestHelper::CreateNavigation(
    748           "http://google.com", "abc");
    749   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    750   UpdateNavigation(window_id, tab_id, nav1, true);
    751   service()->SetWindowBounds(window_id,
    752                              window_bounds,
    753                              ui::SHOW_STATE_DEFAULT);
    754 
    755   ScopedVector<SessionWindow> windows;
    756   ReadWindows(&(windows.get()), NULL);
    757   ASSERT_EQ(1U, windows.size());
    758   EXPECT_EQ(ui::SHOW_STATE_NORMAL, windows[0]->show_state);
    759 }
    760 
    761 TEST_F(SessionServiceTest, KeepPostDataWithoutPasswords) {
    762   SessionID tab_id;
    763   ASSERT_NE(window_id.id(), tab_id.id());
    764 
    765   // Create a page state representing a HTTP body without posted passwords.
    766   content::PageState page_state =
    767       content::PageState::CreateForTesting(GURL(), false, "data", NULL);
    768 
    769   // Create a TabNavigation containing page_state and representing a POST
    770   // request.
    771   SerializedNavigationEntry nav1 =
    772       SerializedNavigationEntryTestHelper::CreateNavigation(
    773           "http://google.com", "title");
    774   SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
    775   SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
    776 
    777   // Create a TabNavigation containing page_state and representing a normal
    778   // request.
    779   SerializedNavigationEntry nav2 =
    780       SerializedNavigationEntryTestHelper::CreateNavigation(
    781           "http://google.com/nopost", "title");
    782   SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav2);
    783   nav2.set_index(1);
    784 
    785   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    786   UpdateNavigation(window_id, tab_id, nav1, true);
    787   UpdateNavigation(window_id, tab_id, nav2, true);
    788 
    789   ScopedVector<SessionWindow> windows;
    790   ReadWindows(&(windows.get()), NULL);
    791 
    792   helper_.AssertSingleWindowWithSingleTab(windows.get(), 2);
    793 
    794   // Expected: the page state of both navigations was saved and restored.
    795   ASSERT_EQ(2u, windows[0]->tabs[0]->navigations.size());
    796   helper_.AssertNavigationEquals(nav1, windows[0]->tabs[0]->navigations[0]);
    797   helper_.AssertNavigationEquals(nav2, windows[0]->tabs[0]->navigations[1]);
    798 }
    799 
    800 TEST_F(SessionServiceTest, RemovePostDataWithPasswords) {
    801   SessionID tab_id;
    802   ASSERT_NE(window_id.id(), tab_id.id());
    803 
    804   // Create a page state representing a HTTP body with posted passwords.
    805   content::PageState page_state =
    806       content::PageState::CreateForTesting(GURL(), true, "data", NULL);
    807 
    808   // Create a TabNavigation containing page_state and representing a POST
    809   // request with passwords.
    810   SerializedNavigationEntry nav1 =
    811       SerializedNavigationEntryTestHelper::CreateNavigation(
    812           "http://google.com", "title");
    813   SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
    814   SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
    815   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    816   UpdateNavigation(window_id, tab_id, nav1, true);
    817 
    818   ScopedVector<SessionWindow> windows;
    819   ReadWindows(&(windows.get()), NULL);
    820 
    821   helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
    822 
    823   // Expected: the HTTP body was removed from the page state of the POST
    824   // navigation with passwords.
    825   EXPECT_NE(page_state, windows[0]->tabs[0]->navigations[0].page_state());
    826 }
    827 
    828 // This test is only applicable to chromeos.
    829 #if defined(OS_CHROMEOS)
    830 // Verifies migration of tab/window closed works.
    831 TEST_F(SessionServiceTest, CanOpenV1TabClosed) {
    832   base::FilePath v1_file_path;
    833   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &v1_file_path));
    834   // v1_session_file contains a tab closed command with the original id. The
    835   // file was generated from ClosingTabStaysClosed. If we successfully processed
    836   // the file we'll have one tab.
    837   v1_file_path =
    838       v1_file_path.AppendASCII("sessions").AppendASCII("v1_session_file");
    839   base::FilePath dest_file_path(path_);
    840   dest_file_path = dest_file_path.AppendASCII("Current Session");
    841 
    842   // Forces closing the file.
    843   helper_.SetService(NULL);
    844 
    845   ASSERT_TRUE(base::CopyFile(v1_file_path, dest_file_path));
    846 
    847   SessionService* session_service = new SessionService(path_);
    848   helper_.SetService(session_service);
    849   ScopedVector<SessionWindow> windows;
    850   SessionID::id_type active_window_id = 0;
    851   helper_.ReadWindows(&(windows.get()), &active_window_id);
    852   ASSERT_EQ(1u, windows.size());
    853   EXPECT_EQ(1u, windows[0]->tabs.size());
    854 }
    855 #endif  // defined(OS_CHROMEOS)
    856 
    857 TEST_F(SessionServiceTest, ReplacePendingNavigation) {
    858   const std::string base_url("http://google.com/");
    859   SessionID tab_id;
    860 
    861   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    862 
    863   // Add 5 navigations, some with the same index
    864   for (int i = 0; i < 5; ++i) {
    865     SerializedNavigationEntry nav =
    866         SerializedNavigationEntryTestHelper::CreateNavigation(
    867             base_url + base::IntToString(i), "a");
    868     nav.set_index(i / 2);
    869     UpdateNavigation(window_id, tab_id, nav, true);
    870   }
    871 
    872   // Read back in.
    873   ScopedVector<SessionWindow> windows;
    874   ReadWindows(&(windows.get()), NULL);
    875 
    876   // The ones with index 0, and 2 should have been replaced by 1 and 3.
    877   ASSERT_EQ(1U, windows.size());
    878   ASSERT_EQ(1U, windows[0]->tabs.size());
    879   EXPECT_EQ(3U, windows[0]->tabs[0]->navigations.size());
    880   EXPECT_EQ(GURL(base_url + base::IntToString(1)),
    881             windows[0]->tabs[0]->navigations[0].virtual_url());
    882   EXPECT_EQ(GURL(base_url + base::IntToString(3)),
    883             windows[0]->tabs[0]->navigations[1].virtual_url());
    884   EXPECT_EQ(GURL(base_url + base::IntToString(4)),
    885             windows[0]->tabs[0]->navigations[2].virtual_url());
    886 }
    887 
    888 TEST_F(SessionServiceTest, ReplacePendingNavigationAndPrune) {
    889   const std::string base_url("http://google.com/");
    890   SessionID tab_id;
    891 
    892   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    893 
    894   for (int i = 0; i < 5; ++i) {
    895     SerializedNavigationEntry nav =
    896         SerializedNavigationEntryTestHelper::CreateNavigation(
    897             base_url + base::IntToString(i), "a");
    898     nav.set_index(i);
    899     UpdateNavigation(window_id, tab_id, nav, true);
    900   }
    901 
    902   // Prune all those navigations.
    903   helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 5);
    904 
    905   // Add another navigation to replace the last one.
    906   SerializedNavigationEntry nav =
    907       SerializedNavigationEntryTestHelper::CreateNavigation(
    908         base_url + base::IntToString(5), "a");
    909   nav.set_index(4);
    910   UpdateNavigation(window_id, tab_id, nav, true);
    911 
    912   // Read back in.
    913   ScopedVector<SessionWindow> windows;
    914   ReadWindows(&(windows.get()), NULL);
    915 
    916   // We should still have that last navigation at the end,
    917   // even though it replaced one that was set before the prune.
    918   ASSERT_EQ(1U, windows.size());
    919   ASSERT_EQ(1U, windows[0]->tabs.size());
    920   ASSERT_EQ(1U, windows[0]->tabs[0]->navigations.size());
    921   EXPECT_EQ(GURL(base_url + base::IntToString(5)),
    922             windows[0]->tabs[0]->navigations[0].virtual_url());
    923 }
    924 
    925 TEST_F(SessionServiceTest, RestoreActivation1) {
    926   SessionID window2_id;
    927   SessionID tab1_id;
    928   SessionID tab2_id;
    929   SerializedNavigationEntry nav1;
    930   SerializedNavigationEntry nav2;
    931 
    932   CreateAndWriteSessionWithTwoWindows(
    933       window2_id, tab1_id, tab2_id, &nav1, &nav2);
    934 
    935   service()->ScheduleCommand(
    936       service()->CreateSetActiveWindowCommand(window2_id));
    937   service()->ScheduleCommand(
    938       service()->CreateSetActiveWindowCommand(window_id));
    939 
    940   ScopedVector<SessionWindow> windows;
    941   SessionID::id_type active_window_id = 0;
    942   ReadWindows(&(windows.get()), &active_window_id);
    943   EXPECT_EQ(window_id.id(), active_window_id);
    944 }
    945 
    946 // It's easier to have two separate tests with setup/teardown than to manualy
    947 // reset the state for the different flavors of the test.
    948 TEST_F(SessionServiceTest, RestoreActivation2) {
    949   SessionID window2_id;
    950   SessionID tab1_id;
    951   SessionID tab2_id;
    952   SerializedNavigationEntry nav1;
    953   SerializedNavigationEntry nav2;
    954 
    955   CreateAndWriteSessionWithTwoWindows(
    956       window2_id, tab1_id, tab2_id, &nav1, &nav2);
    957 
    958   service()->ScheduleCommand(
    959       service()->CreateSetActiveWindowCommand(window2_id));
    960   service()->ScheduleCommand(
    961       service()->CreateSetActiveWindowCommand(window_id));
    962   service()->ScheduleCommand(
    963       service()->CreateSetActiveWindowCommand(window2_id));
    964 
    965   ScopedVector<SessionWindow> windows;
    966   SessionID::id_type active_window_id = 0;
    967   ReadWindows(&(windows.get()), &active_window_id);
    968   EXPECT_EQ(window2_id.id(), active_window_id);
    969 }
    970 
    971 // Makes sure we don't track blacklisted URLs.
    972 TEST_F(SessionServiceTest, IgnoreBlacklistedUrls) {
    973   SessionID tab_id;
    974 
    975   SerializedNavigationEntry nav1 =
    976       SerializedNavigationEntryTestHelper::CreateNavigation(
    977           "http://google.com", "abc");
    978   SerializedNavigationEntry nav2 =
    979       SerializedNavigationEntryTestHelper::CreateNavigation(
    980           chrome::kChromeUIQuitURL, "quit");
    981   SerializedNavigationEntry nav3 =
    982       SerializedNavigationEntryTestHelper::CreateNavigation(
    983           chrome::kChromeUIRestartURL, "restart");
    984 
    985   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
    986   UpdateNavigation(window_id, tab_id, nav1, true);
    987   UpdateNavigation(window_id, tab_id, nav2, true);
    988   UpdateNavigation(window_id, tab_id, nav3, true);
    989 
    990   ScopedVector<SessionWindow> windows;
    991   ReadWindows(&(windows.get()), NULL);
    992 
    993   ASSERT_EQ(1U, windows.size());
    994   ASSERT_EQ(0, windows[0]->selected_tab_index);
    995   ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
    996   ASSERT_EQ(1U, windows[0]->tabs.size());
    997 
    998   SessionTab* tab = windows[0]->tabs[0];
    999   helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
   1000   helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
   1001 }
   1002