1 // Copyright (c) 2011 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/file_util.h" 6 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_vector.h" 8 #include "base/memory/scoped_temp_dir.h" 9 #include "base/path_service.h" 10 #include "base/stl_util-inl.h" 11 #include "base/string_number_conversions.h" 12 #include "base/time.h" 13 #include "base/utf_string_conversions.h" 14 #include "chrome/browser/defaults.h" 15 #include "chrome/browser/sessions/session_backend.h" 16 #include "chrome/browser/sessions/session_service.h" 17 #include "chrome/browser/sessions/session_service_test_helper.h" 18 #include "chrome/browser/sessions/session_types.h" 19 #include "chrome/common/chrome_paths.h" 20 #include "chrome/test/browser_with_test_window_test.h" 21 #include "chrome/test/file_test_utils.h" 22 #include "chrome/test/testing_profile.h" 23 #include "content/browser/tab_contents/navigation_entry.h" 24 #include "content/common/notification_observer.h" 25 #include "content/common/notification_registrar.h" 26 #include "content/common/notification_service.h" 27 #include "content/common/notification_type.h" 28 #include "testing/gtest/include/gtest/gtest.h" 29 30 class SessionServiceTest : public BrowserWithTestWindowTest, 31 public NotificationObserver { 32 public: 33 SessionServiceTest() : window_bounds(0, 1, 2, 3), sync_save_count_(0){} 34 35 protected: 36 virtual void SetUp() { 37 BrowserWithTestWindowTest::SetUp(); 38 std::string b = base::Int64ToString(base::Time::Now().ToInternalValue()); 39 40 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 41 path_ = temp_dir_.path().Append(FILE_PATH_LITERAL("SessionTestDirs")); 42 file_util::CreateDirectory(path_); 43 path_deleter_.reset(new FileAutoDeleter(path_)); 44 path_ = path_.AppendASCII(b); 45 46 SessionService* session_service = new SessionService(path_); 47 helper_.set_service(session_service); 48 49 service()->SetWindowType(window_id, Browser::TYPE_NORMAL); 50 service()->SetWindowBounds(window_id, window_bounds, false); 51 } 52 53 // Upon notification, increment the sync_save_count variable 54 void Observe(NotificationType type, 55 const NotificationSource& source, 56 const NotificationDetails& details) { 57 ASSERT_EQ(type.value, NotificationType::SESSION_SERVICE_SAVED); 58 sync_save_count_++; 59 } 60 61 virtual void TearDown() { 62 helper_.set_service(NULL); 63 path_deleter_.reset(); 64 } 65 66 void UpdateNavigation(const SessionID& window_id, 67 const SessionID& tab_id, 68 const TabNavigation& navigation, 69 int index, 70 bool select) { 71 NavigationEntry entry; 72 entry.set_url(navigation.virtual_url()); 73 entry.set_referrer(navigation.referrer()); 74 entry.set_title(navigation.title()); 75 entry.set_content_state(navigation.state()); 76 entry.set_transition_type(navigation.transition()); 77 entry.set_has_post_data( 78 navigation.type_mask() & TabNavigation::HAS_POST_DATA); 79 service()->UpdateTabNavigation(window_id, tab_id, index, entry); 80 if (select) 81 service()->SetSelectedNavigationIndex(window_id, tab_id, index); 82 } 83 84 void ReadWindows(std::vector<SessionWindow*>* windows) { 85 // Forces closing the file. 86 helper_.set_service(NULL); 87 88 SessionService* session_service = new SessionService(path_); 89 helper_.set_service(session_service); 90 helper_.ReadWindows(windows); 91 } 92 93 // Configures the session service with one window with one tab and a single 94 // navigation. If |pinned_state| is true or |write_always| is true, the 95 // pinned state of the tab is updated. The session service is then recreated 96 // and the pinned state of the read back tab is returned. 97 bool CreateAndWriteSessionWithOneTab(bool pinned_state, bool write_always) { 98 SessionID tab_id; 99 TabNavigation nav1(0, GURL("http://google.com"), 100 GURL("http://www.referrer.com"), 101 ASCIIToUTF16("abc"), "def", 102 PageTransition::QUALIFIER_MASK); 103 104 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 105 UpdateNavigation(window_id, tab_id, nav1, 0, true); 106 107 if (pinned_state || write_always) 108 helper_.service()->SetPinnedState(window_id, tab_id, pinned_state); 109 110 ScopedVector<SessionWindow> windows; 111 ReadWindows(&(windows.get())); 112 113 EXPECT_EQ(1U, windows->size()); 114 if (HasFatalFailure()) 115 return false; 116 EXPECT_EQ(1U, windows[0]->tabs.size()); 117 if (HasFatalFailure()) 118 return false; 119 120 SessionTab* tab = windows[0]->tabs[0]; 121 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 122 123 return tab->pinned; 124 } 125 126 SessionService* service() { return helper_.service(); } 127 128 SessionBackend* backend() { return helper_.backend(); } 129 130 const gfx::Rect window_bounds; 131 132 SessionID window_id; 133 134 int sync_save_count_; 135 136 // Path used in testing. 137 ScopedTempDir temp_dir_; 138 FilePath path_; 139 scoped_ptr<FileAutoDeleter> path_deleter_; 140 141 SessionServiceTestHelper helper_; 142 }; 143 144 TEST_F(SessionServiceTest, Basic) { 145 SessionID tab_id; 146 ASSERT_NE(window_id.id(), tab_id.id()); 147 148 TabNavigation nav1(0, GURL("http://google.com"), 149 GURL("http://www.referrer.com"), 150 ASCIIToUTF16("abc"), "def", 151 PageTransition::QUALIFIER_MASK); 152 153 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 154 UpdateNavigation(window_id, tab_id, nav1, 0, true); 155 156 ScopedVector<SessionWindow> windows; 157 ReadWindows(&(windows.get())); 158 159 ASSERT_EQ(1U, windows->size()); 160 ASSERT_TRUE(window_bounds == windows[0]->bounds); 161 ASSERT_EQ(0, windows[0]->selected_tab_index); 162 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 163 ASSERT_EQ(1U, windows[0]->tabs.size()); 164 ASSERT_EQ(Browser::TYPE_NORMAL, windows[0]->type); 165 166 SessionTab* tab = windows[0]->tabs[0]; 167 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 168 169 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 170 } 171 172 // Make sure we persist post entries. 173 TEST_F(SessionServiceTest, PersistPostData) { 174 SessionID tab_id; 175 ASSERT_NE(window_id.id(), tab_id.id()); 176 177 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 178 ASCIIToUTF16("abc"), std::string(), 179 PageTransition::QUALIFIER_MASK); 180 nav1.set_type_mask(TabNavigation::HAS_POST_DATA); 181 182 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 183 UpdateNavigation(window_id, tab_id, nav1, 0, true); 184 185 ScopedVector<SessionWindow> windows; 186 ReadWindows(&(windows.get())); 187 188 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1); 189 } 190 191 TEST_F(SessionServiceTest, ClosingTabStaysClosed) { 192 SessionID tab_id; 193 SessionID tab2_id; 194 ASSERT_NE(tab_id.id(), tab2_id.id()); 195 196 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 197 ASCIIToUTF16("abc"), "def", 198 PageTransition::QUALIFIER_MASK); 199 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 200 ASCIIToUTF16("abcd"), "defg", 201 PageTransition::AUTO_BOOKMARK); 202 203 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 204 UpdateNavigation(window_id, tab_id, nav1, 0, true); 205 206 helper_.PrepareTabInWindow(window_id, tab2_id, 1, false); 207 UpdateNavigation(window_id, tab2_id, nav2, 0, true); 208 service()->TabClosed(window_id, tab2_id, false); 209 210 ScopedVector<SessionWindow> windows; 211 ReadWindows(&(windows.get())); 212 213 ASSERT_EQ(1U, windows->size()); 214 ASSERT_EQ(0, windows[0]->selected_tab_index); 215 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 216 ASSERT_EQ(1U, windows[0]->tabs.size()); 217 218 SessionTab* tab = windows[0]->tabs[0]; 219 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 220 221 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 222 } 223 224 TEST_F(SessionServiceTest, Pruning) { 225 SessionID tab_id; 226 227 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 228 ASCIIToUTF16("abc"), "def", 229 PageTransition::QUALIFIER_MASK); 230 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 231 ASCIIToUTF16("abcd"), "defg", 232 PageTransition::AUTO_BOOKMARK); 233 234 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 235 for (int i = 0; i < 6; ++i) { 236 TabNavigation& nav = (i % 2) == 0 ? nav1 : nav2; 237 UpdateNavigation(window_id, tab_id, nav, i, true); 238 } 239 service()->TabNavigationPathPrunedFromBack(window_id, tab_id, 3); 240 241 ScopedVector<SessionWindow> windows; 242 ReadWindows(&(windows.get())); 243 244 ASSERT_EQ(1U, windows->size()); 245 ASSERT_EQ(0, windows[0]->selected_tab_index); 246 ASSERT_EQ(1U, windows[0]->tabs.size()); 247 248 SessionTab* tab = windows[0]->tabs[0]; 249 // We left the selected index at 5, then pruned. When rereading the 250 // index should get reset to last valid navigation, which is 2. 251 helper_.AssertTabEquals(window_id, tab_id, 0, 2, 3, *tab); 252 253 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 254 helper_.AssertNavigationEquals(nav2, tab->navigations[1]); 255 helper_.AssertNavigationEquals(nav1, tab->navigations[2]); 256 } 257 258 TEST_F(SessionServiceTest, TwoWindows) { 259 SessionID window2_id; 260 SessionID tab1_id; 261 SessionID tab2_id; 262 263 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 264 ASCIIToUTF16("abc"), "def", 265 PageTransition::QUALIFIER_MASK); 266 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 267 ASCIIToUTF16("abcd"), "defg", 268 PageTransition::AUTO_BOOKMARK); 269 270 helper_.PrepareTabInWindow(window_id, tab1_id, 0, true); 271 UpdateNavigation(window_id, tab1_id, nav1, 0, true); 272 273 const gfx::Rect window2_bounds(3, 4, 5, 6); 274 service()->SetWindowType(window2_id, Browser::TYPE_NORMAL); 275 service()->SetWindowBounds(window2_id, window2_bounds, true); 276 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true); 277 UpdateNavigation(window2_id, tab2_id, nav2, 0, true); 278 279 ScopedVector<SessionWindow> windows; 280 ReadWindows(&(windows.get())); 281 282 ASSERT_EQ(2U, windows->size()); 283 ASSERT_EQ(0, windows[0]->selected_tab_index); 284 ASSERT_EQ(0, windows[1]->selected_tab_index); 285 ASSERT_EQ(1U, windows[0]->tabs.size()); 286 ASSERT_EQ(1U, windows[1]->tabs.size()); 287 288 SessionTab* rt1; 289 SessionTab* rt2; 290 if (windows[0]->window_id.id() == window_id.id()) { 291 ASSERT_EQ(window2_id.id(), windows[1]->window_id.id()); 292 ASSERT_FALSE(windows[0]->is_maximized); 293 ASSERT_TRUE(windows[1]->is_maximized); 294 rt1 = windows[0]->tabs[0]; 295 rt2 = windows[1]->tabs[0]; 296 } else { 297 ASSERT_EQ(window2_id.id(), windows[0]->window_id.id()); 298 ASSERT_EQ(window_id.id(), windows[1]->window_id.id()); 299 ASSERT_TRUE(windows[0]->is_maximized); 300 ASSERT_FALSE(windows[1]->is_maximized); 301 rt1 = windows[1]->tabs[0]; 302 rt2 = windows[0]->tabs[0]; 303 } 304 SessionTab* tab = rt1; 305 helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab); 306 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 307 308 tab = rt2; 309 helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab); 310 helper_.AssertNavigationEquals(nav2, tab->navigations[0]); 311 } 312 313 TEST_F(SessionServiceTest, WindowWithNoTabsGetsPruned) { 314 SessionID window2_id; 315 SessionID tab1_id; 316 SessionID tab2_id; 317 318 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 319 ASCIIToUTF16("abc"), "def", 320 PageTransition::QUALIFIER_MASK); 321 322 helper_.PrepareTabInWindow(window_id, tab1_id, 0, true); 323 UpdateNavigation(window_id, tab1_id, nav1, 0, true); 324 325 const gfx::Rect window2_bounds(3, 4, 5, 6); 326 service()->SetWindowType(window2_id, Browser::TYPE_NORMAL); 327 service()->SetWindowBounds(window2_id, window2_bounds, false); 328 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true); 329 330 ScopedVector<SessionWindow> windows; 331 ReadWindows(&(windows.get())); 332 333 ASSERT_EQ(1U, windows->size()); 334 ASSERT_EQ(0, windows[0]->selected_tab_index); 335 ASSERT_EQ(1U, windows[0]->tabs.size()); 336 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 337 338 SessionTab* tab = windows[0]->tabs[0]; 339 helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab); 340 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 341 } 342 343 TEST_F(SessionServiceTest, ClosingWindowDoesntCloseTabs) { 344 SessionID tab_id; 345 SessionID tab2_id; 346 ASSERT_NE(tab_id.id(), tab2_id.id()); 347 348 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 349 ASCIIToUTF16("abc"), "def", 350 PageTransition::QUALIFIER_MASK); 351 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 352 ASCIIToUTF16("abcd"), "defg", 353 PageTransition::AUTO_BOOKMARK); 354 355 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 356 UpdateNavigation(window_id, tab_id, nav1, 0, true); 357 358 helper_.PrepareTabInWindow(window_id, tab2_id, 1, false); 359 UpdateNavigation(window_id, tab2_id, nav2, 0, true); 360 361 service()->WindowClosing(window_id); 362 363 ScopedVector<SessionWindow> windows; 364 ReadWindows(&(windows.get())); 365 366 ASSERT_EQ(1U, windows->size()); 367 ASSERT_EQ(0, windows[0]->selected_tab_index); 368 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 369 ASSERT_EQ(2U, windows[0]->tabs.size()); 370 371 SessionTab* tab = windows[0]->tabs[0]; 372 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 373 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 374 375 tab = windows[0]->tabs[1]; 376 helper_.AssertTabEquals(window_id, tab2_id, 1, 0, 1, *tab); 377 helper_.AssertNavigationEquals(nav2, tab->navigations[0]); 378 } 379 380 TEST_F(SessionServiceTest, WindowCloseCommittedAfterNavigate) { 381 SessionID window2_id; 382 SessionID tab_id; 383 SessionID tab2_id; 384 ASSERT_NE(window2_id.id(), window_id.id()); 385 386 service()->SetWindowType(window2_id, Browser::TYPE_NORMAL); 387 service()->SetWindowBounds(window2_id, window_bounds, false); 388 389 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 390 ASCIIToUTF16("abc"), "def", 391 PageTransition::QUALIFIER_MASK); 392 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 393 ASCIIToUTF16("abcd"), "defg", 394 PageTransition::AUTO_BOOKMARK); 395 396 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 397 UpdateNavigation(window_id, tab_id, nav1, 0, true); 398 399 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); 400 UpdateNavigation(window2_id, tab2_id, nav2, 0, true); 401 402 service()->WindowClosing(window2_id); 403 service()->TabClosed(window2_id, tab2_id, false); 404 service()->WindowClosed(window2_id); 405 406 ScopedVector<SessionWindow> windows; 407 ReadWindows(&(windows.get())); 408 409 ASSERT_EQ(1U, windows->size()); 410 ASSERT_EQ(0, windows[0]->selected_tab_index); 411 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 412 ASSERT_EQ(1U, windows[0]->tabs.size()); 413 414 SessionTab* tab = windows[0]->tabs[0]; 415 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 416 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 417 } 418 419 // Makes sure we don't track popups. 420 TEST_F(SessionServiceTest, IgnorePopups) { 421 if (browser_defaults::kRestorePopups) 422 return; // This test is only applicable if popups aren't restored. 423 424 SessionID window2_id; 425 SessionID tab_id; 426 SessionID tab2_id; 427 ASSERT_NE(window2_id.id(), window_id.id()); 428 429 service()->SetWindowType(window2_id, Browser::TYPE_POPUP); 430 service()->SetWindowBounds(window2_id, window_bounds, false); 431 432 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 433 ASCIIToUTF16("abc"), "def", 434 PageTransition::QUALIFIER_MASK); 435 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 436 ASCIIToUTF16("abcd"), "defg", 437 PageTransition::AUTO_BOOKMARK); 438 439 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 440 UpdateNavigation(window_id, tab_id, nav1, 0, true); 441 442 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); 443 UpdateNavigation(window2_id, tab2_id, nav2, 0, true); 444 445 ScopedVector<SessionWindow> windows; 446 ReadWindows(&(windows.get())); 447 448 ASSERT_EQ(1U, windows->size()); 449 ASSERT_EQ(0, windows[0]->selected_tab_index); 450 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 451 ASSERT_EQ(1U, windows[0]->tabs.size()); 452 453 SessionTab* tab = windows[0]->tabs[0]; 454 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 455 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 456 } 457 458 // Makes sure we track popups. 459 TEST_F(SessionServiceTest, RestorePopup) { 460 if (!browser_defaults::kRestorePopups) 461 return; // This test is only applicable if popups are restored. 462 463 SessionID window2_id; 464 SessionID tab_id; 465 SessionID tab2_id; 466 ASSERT_NE(window2_id.id(), window_id.id()); 467 468 service()->SetWindowType(window2_id, Browser::TYPE_POPUP); 469 service()->SetWindowBounds(window2_id, window_bounds, false); 470 471 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 472 ASCIIToUTF16("abc"), "def", 473 PageTransition::QUALIFIER_MASK); 474 TabNavigation nav2(0, GURL("http://google2.com"), GURL(), 475 ASCIIToUTF16("abcd"), "defg", 476 PageTransition::AUTO_BOOKMARK); 477 478 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 479 UpdateNavigation(window_id, tab_id, nav1, 0, true); 480 481 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); 482 UpdateNavigation(window2_id, tab2_id, nav2, 0, true); 483 484 ScopedVector<SessionWindow> windows; 485 ReadWindows(&(windows.get())); 486 487 ASSERT_EQ(2U, windows->size()); 488 int normal_index = windows[0]->type == Browser::TYPE_NORMAL ? 489 0 : 1; 490 int popup_index = normal_index == 0 ? 1 : 0; 491 ASSERT_EQ(0, windows[normal_index]->selected_tab_index); 492 ASSERT_EQ(window_id.id(), windows[normal_index]->window_id.id()); 493 ASSERT_EQ(1U, windows[normal_index]->tabs.size()); 494 495 SessionTab* tab = windows[normal_index]->tabs[0]; 496 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); 497 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); 498 499 ASSERT_EQ(0, windows[popup_index]->selected_tab_index); 500 ASSERT_EQ(window2_id.id(), windows[popup_index]->window_id.id()); 501 ASSERT_EQ(1U, windows[popup_index]->tabs.size()); 502 503 tab = windows[popup_index]->tabs[0]; 504 helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab); 505 helper_.AssertNavigationEquals(nav2, tab->navigations[0]); 506 } 507 508 // Tests pruning from the front. 509 TEST_F(SessionServiceTest, PruneFromFront) { 510 const std::string base_url("http://google.com/"); 511 SessionID tab_id; 512 513 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 514 515 // Add 5 navigations, with the 4th selected. 516 for (int i = 0; i < 5; ++i) { 517 TabNavigation nav(0, GURL(base_url + base::IntToString(i)), GURL(), 518 ASCIIToUTF16("a"), "b", PageTransition::QUALIFIER_MASK); 519 UpdateNavigation(window_id, tab_id, nav, i, (i == 3)); 520 } 521 522 // Prune the first two navigations from the front. 523 helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 2); 524 525 // Read back in. 526 ScopedVector<SessionWindow> windows; 527 ReadWindows(&(windows.get())); 528 529 ASSERT_EQ(1U, windows->size()); 530 ASSERT_EQ(0, windows[0]->selected_tab_index); 531 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); 532 ASSERT_EQ(1U, windows[0]->tabs.size()); 533 534 // There shouldn't be an app id. 535 EXPECT_TRUE(windows[0]->tabs[0]->extension_app_id.empty()); 536 537 // We should be left with three navigations, the 2nd selected. 538 SessionTab* tab = windows[0]->tabs[0]; 539 ASSERT_EQ(1, tab->current_navigation_index); 540 EXPECT_EQ(3U, tab->navigations.size()); 541 EXPECT_TRUE(GURL(base_url + base::IntToString(2)) == 542 tab->navigations[0].virtual_url()); 543 EXPECT_TRUE(GURL(base_url + base::IntToString(3)) == 544 tab->navigations[1].virtual_url()); 545 EXPECT_TRUE(GURL(base_url + base::IntToString(4)) == 546 tab->navigations[2].virtual_url()); 547 } 548 549 // Prunes from front so that we have no entries. 550 TEST_F(SessionServiceTest, PruneToEmpty) { 551 const std::string base_url("http://google.com/"); 552 SessionID tab_id; 553 554 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 555 556 // Add 5 navigations, with the 4th selected. 557 for (int i = 0; i < 5; ++i) { 558 TabNavigation nav(0, GURL(base_url + base::IntToString(i)), GURL(), 559 ASCIIToUTF16("a"), "b", PageTransition::QUALIFIER_MASK); 560 UpdateNavigation(window_id, tab_id, nav, i, (i == 3)); 561 } 562 563 // Prune the first two navigations from the front. 564 helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 5); 565 566 // Read back in. 567 ScopedVector<SessionWindow> windows; 568 ReadWindows(&(windows.get())); 569 570 ASSERT_EQ(0U, windows->size()); 571 } 572 573 // Don't set the pinned state and make sure the pinned value is false. 574 TEST_F(SessionServiceTest, PinnedDefaultsToFalse) { 575 EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, false)); 576 } 577 578 // Explicitly set the pinned state to false and make sure we get back false. 579 TEST_F(SessionServiceTest, PinnedFalseWhenSetToFalse) { 580 EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, true)); 581 } 582 583 // Make sure application extension ids are persisted. 584 TEST_F(SessionServiceTest, PersistApplicationExtensionID) { 585 SessionID tab_id; 586 ASSERT_NE(window_id.id(), tab_id.id()); 587 std::string app_id("foo"); 588 589 TabNavigation nav1(0, GURL("http://google.com"), GURL(), 590 ASCIIToUTF16("abc"), std::string(), 591 PageTransition::QUALIFIER_MASK); 592 593 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 594 UpdateNavigation(window_id, tab_id, nav1, 0, true); 595 helper_.SetTabExtensionAppID(window_id, tab_id, app_id); 596 597 ScopedVector<SessionWindow> windows; 598 ReadWindows(&(windows.get())); 599 600 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1); 601 EXPECT_TRUE(app_id == windows[0]->tabs[0]->extension_app_id); 602 } 603 604 // Explicitly set the pinned state to true and make sure we get back true. 605 TEST_F(SessionServiceTest, PinnedTrue) { 606 EXPECT_TRUE(CreateAndWriteSessionWithOneTab(true, true)); 607 } 608 609 class GetCurrentSessionCallbackHandler { 610 public: 611 void OnGotSession(int handle, std::vector<SessionWindow*>* windows) { 612 EXPECT_EQ(1U, windows->size()); 613 EXPECT_EQ(2U, (*windows)[0]->tabs.size()); 614 EXPECT_EQ(2U, (*windows)[0]->tabs[0]->navigations.size()); 615 EXPECT_EQ(GURL("http://bar/1"), 616 (*windows)[0]->tabs[0]->navigations[0].virtual_url()); 617 EXPECT_EQ(GURL("http://bar/2"), 618 (*windows)[0]->tabs[0]->navigations[1].virtual_url()); 619 EXPECT_EQ(2U, (*windows)[0]->tabs[1]->navigations.size()); 620 EXPECT_EQ(GURL("http://foo/1"), 621 (*windows)[0]->tabs[1]->navigations[0].virtual_url()); 622 EXPECT_EQ(GURL("http://foo/2"), 623 (*windows)[0]->tabs[1]->navigations[1].virtual_url()); 624 } 625 }; 626 627 TEST_F(SessionServiceTest, GetCurrentSession) { 628 AddTab(browser(), GURL("http://foo/1")); 629 NavigateAndCommitActiveTab(GURL("http://foo/2")); 630 AddTab(browser(), GURL("http://bar/1")); 631 NavigateAndCommitActiveTab(GURL("http://bar/2")); 632 633 CancelableRequestConsumer consumer; 634 GetCurrentSessionCallbackHandler handler; 635 service()->GetCurrentSession(&consumer, 636 NewCallback(&handler, &GetCurrentSessionCallbackHandler::OnGotSession)); 637 } 638 639 // Test that the notification for SESSION_SERVICE_SAVED is working properly. 640 TEST_F(SessionServiceTest, SavedSessionNotification) { 641 NotificationRegistrar registrar_; 642 registrar_.Add(this, NotificationType::SESSION_SERVICE_SAVED, 643 NotificationService::AllSources()); 644 service()->Save(); 645 EXPECT_EQ(sync_save_count_, 1); 646 } 647 648 // Makes sure a tab closed by a user gesture is not restored. 649 TEST_F(SessionServiceTest, CloseTabUserGesture) { 650 SessionID tab_id; 651 ASSERT_NE(window_id.id(), tab_id.id()); 652 653 TabNavigation nav1(0, GURL("http://google.com"), 654 GURL("http://www.referrer.com"), 655 ASCIIToUTF16("abc"), "def", 656 PageTransition::QUALIFIER_MASK); 657 658 helper_.PrepareTabInWindow(window_id, tab_id, 0, true); 659 UpdateNavigation(window_id, tab_id, nav1, 0, true); 660 service()->TabClosed(window_id, tab_id, true); 661 662 ScopedVector<SessionWindow> windows; 663 ReadWindows(&(windows.get())); 664 665 ASSERT_TRUE(windows->empty()); 666 } 667