NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / sessions / session_service_unittest.cc
blob3e3b0096a494cfa963efb373c45de6f9c4c99789
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "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/chrome_notification_types.h"
17 #include "chrome/browser/defaults.h"
18 #include "chrome/browser/sessions/session_backend.h"
19 #include "chrome/browser/sessions/session_service.h"
20 #include "chrome/browser/sessions/session_service_test_helper.h"
21 #include "chrome/browser/sessions/session_types.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/common/url_constants.h"
24 #include "chrome/test/base/browser_with_test_window_test.h"
25 #include "chrome/test/base/testing_profile.h"
26 #include "components/sessions/serialized_navigation_entry_test_helper.h"
27 #include "content/public/browser/navigation_entry.h"
28 #include "content/public/browser/notification_observer.h"
29 #include "content/public/browser/notification_registrar.h"
30 #include "content/public/browser/notification_service.h"
31 #include "content/public/common/page_state.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 using content::NavigationEntry;
35 using sessions::SerializedNavigationEntry;
36 using sessions::SerializedNavigationEntryTestHelper;
38 class SessionServiceTest : public BrowserWithTestWindowTest,
39 public content::NotificationObserver {
40 public:
41 SessionServiceTest() : window_bounds(0, 1, 2, 3), sync_save_count_(0) {}
43 protected:
44 virtual void SetUp() {
45 BrowserWithTestWindowTest::SetUp();
46 std::string b = base::Int64ToString(base::Time::Now().ToInternalValue());
48 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
49 path_ = temp_dir_.path().Append(FILE_PATH_LITERAL("SessionTestDirs"));
50 ASSERT_TRUE(base::CreateDirectory(path_));
51 path_ = path_.AppendASCII(b);
53 SessionService* session_service = new SessionService(path_);
54 helper_.SetService(session_service);
56 service()->SetWindowType(
57 window_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
58 service()->SetWindowBounds(window_id,
59 window_bounds,
60 ui::SHOW_STATE_NORMAL);
63 // Upon notification, increment the sync_save_count variable
64 virtual void Observe(int type,
65 const content::NotificationSource& source,
66 const content::NotificationDetails& details) OVERRIDE {
67 ASSERT_EQ(type, chrome::NOTIFICATION_SESSION_SERVICE_SAVED);
68 sync_save_count_++;
71 virtual void TearDown() {
72 helper_.SetService(NULL);
73 BrowserWithTestWindowTest::TearDown();
76 void UpdateNavigation(
77 const SessionID& window_id,
78 const SessionID& tab_id,
79 const SerializedNavigationEntry& navigation,
80 bool select) {
81 service()->UpdateTabNavigation(window_id, tab_id, navigation);
82 if (select) {
83 service()->SetSelectedNavigationIndex(
84 window_id, tab_id, navigation.index());
88 void ReadWindows(std::vector<SessionWindow*>* windows,
89 SessionID::id_type* active_window_id) {
90 // Forces closing the file.
91 helper_.SetService(NULL);
93 SessionService* session_service = new SessionService(path_);
94 helper_.SetService(session_service);
96 SessionID::id_type* non_null_active_window_id = active_window_id;
97 SessionID::id_type dummy_active_window_id = 0;
98 if (!non_null_active_window_id)
99 non_null_active_window_id = &dummy_active_window_id;
100 helper_.ReadWindows(windows, non_null_active_window_id);
103 // Configures the session service with one window with one tab and a single
104 // navigation. If |pinned_state| is true or |write_always| is true, the
105 // pinned state of the tab is updated. The session service is then recreated
106 // and the pinned state of the read back tab is returned.
107 bool CreateAndWriteSessionWithOneTab(bool pinned_state, bool write_always) {
108 SessionID tab_id;
109 SerializedNavigationEntry nav1 =
110 SerializedNavigationEntryTestHelper::CreateNavigation(
111 "http://google.com", "abc");
113 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
114 UpdateNavigation(window_id, tab_id, nav1, true);
116 if (pinned_state || write_always)
117 helper_.service()->SetPinnedState(window_id, tab_id, pinned_state);
119 ScopedVector<SessionWindow> windows;
120 ReadWindows(&(windows.get()), NULL);
122 EXPECT_EQ(1U, windows.size());
123 if (HasFatalFailure())
124 return false;
125 EXPECT_EQ(1U, windows[0]->tabs.size());
126 if (HasFatalFailure())
127 return false;
129 SessionTab* tab = windows[0]->tabs[0];
130 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
132 return tab->pinned;
135 void CreateAndWriteSessionWithTwoWindows(
136 const SessionID& window2_id,
137 const SessionID& tab1_id,
138 const SessionID& tab2_id,
139 SerializedNavigationEntry* nav1,
140 SerializedNavigationEntry* nav2) {
141 *nav1 = SerializedNavigationEntryTestHelper::CreateNavigation(
142 "http://google.com", "abc");
143 *nav2 = SerializedNavigationEntryTestHelper::CreateNavigation(
144 "http://google2.com", "abcd");
146 helper_.PrepareTabInWindow(window_id, tab1_id, 0, true);
147 UpdateNavigation(window_id, tab1_id, *nav1, true);
149 const gfx::Rect window2_bounds(3, 4, 5, 6);
150 service()->SetWindowType(
151 window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
152 service()->SetWindowBounds(window2_id,
153 window2_bounds,
154 ui::SHOW_STATE_MAXIMIZED);
155 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true);
156 UpdateNavigation(window2_id, tab2_id, *nav2, true);
159 SessionService* service() { return helper_.service(); }
161 SessionBackend* backend() { return helper_.backend(); }
163 const gfx::Rect window_bounds;
165 SessionID window_id;
167 int sync_save_count_;
169 // Path used in testing.
170 base::ScopedTempDir temp_dir_;
171 base::FilePath path_;
173 SessionServiceTestHelper helper_;
176 TEST_F(SessionServiceTest, Basic) {
177 SessionID tab_id;
178 ASSERT_NE(window_id.id(), tab_id.id());
180 SerializedNavigationEntry nav1 =
181 SerializedNavigationEntryTestHelper::CreateNavigation(
182 "http://google.com", "abc");
183 SerializedNavigationEntryTestHelper::SetOriginalRequestURL(
184 GURL("http://original.request.com"), &nav1);
186 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
187 UpdateNavigation(window_id, tab_id, nav1, true);
189 ScopedVector<SessionWindow> windows;
190 ReadWindows(&(windows.get()), NULL);
192 ASSERT_EQ(1U, windows.size());
193 ASSERT_TRUE(window_bounds == windows[0]->bounds);
194 ASSERT_EQ(0, windows[0]->selected_tab_index);
195 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
196 ASSERT_EQ(1U, windows[0]->tabs.size());
197 ASSERT_EQ(Browser::TYPE_TABBED, windows[0]->type);
199 SessionTab* tab = windows[0]->tabs[0];
200 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
202 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
205 // Make sure we persist post entries.
206 TEST_F(SessionServiceTest, PersistPostData) {
207 SessionID tab_id;
208 ASSERT_NE(window_id.id(), tab_id.id());
210 SerializedNavigationEntry nav1 =
211 SerializedNavigationEntryTestHelper::CreateNavigation(
212 "http://google.com", "abc");
213 SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
215 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
216 UpdateNavigation(window_id, tab_id, nav1, true);
218 ScopedVector<SessionWindow> windows;
219 ReadWindows(&(windows.get()), NULL);
221 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
224 TEST_F(SessionServiceTest, ClosingTabStaysClosed) {
225 SessionID tab_id;
226 SessionID tab2_id;
227 ASSERT_NE(tab_id.id(), tab2_id.id());
229 SerializedNavigationEntry nav1 =
230 SerializedNavigationEntryTestHelper::CreateNavigation(
231 "http://google.com", "abc");
232 SerializedNavigationEntry nav2 =
233 SerializedNavigationEntryTestHelper::CreateNavigation(
234 "http://google2.com", "abcd");
236 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
237 UpdateNavigation(window_id, tab_id, nav1, true);
239 helper_.PrepareTabInWindow(window_id, tab2_id, 1, false);
240 UpdateNavigation(window_id, tab2_id, nav2, true);
241 service()->TabClosed(window_id, tab2_id, false);
243 ScopedVector<SessionWindow> windows;
244 ReadWindows(&(windows.get()), NULL);
246 ASSERT_EQ(1U, windows.size());
247 ASSERT_EQ(0, windows[0]->selected_tab_index);
248 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
249 ASSERT_EQ(1U, windows[0]->tabs.size());
251 SessionTab* tab = windows[0]->tabs[0];
252 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
254 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
257 TEST_F(SessionServiceTest, Pruning) {
258 SessionID tab_id;
260 SerializedNavigationEntry nav1 =
261 SerializedNavigationEntryTestHelper::CreateNavigation(
262 "http://google.com", "abc");
263 SerializedNavigationEntry nav2 =
264 SerializedNavigationEntryTestHelper::CreateNavigation(
265 "http://google2.com", "abcd");
267 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
268 for (int i = 0; i < 6; ++i) {
269 SerializedNavigationEntry* nav = (i % 2) == 0 ? &nav1 : &nav2;
270 nav->set_index(i);
271 UpdateNavigation(window_id, tab_id, *nav, true);
273 service()->TabNavigationPathPrunedFromBack(window_id, tab_id, 3);
275 ScopedVector<SessionWindow> windows;
276 ReadWindows(&(windows.get()), NULL);
278 ASSERT_EQ(1U, windows.size());
279 ASSERT_EQ(0, windows[0]->selected_tab_index);
280 ASSERT_EQ(1U, windows[0]->tabs.size());
282 SessionTab* tab = windows[0]->tabs[0];
283 // We left the selected index at 5, then pruned. When rereading the
284 // index should get reset to last valid navigation, which is 2.
285 helper_.AssertTabEquals(window_id, tab_id, 0, 2, 3, *tab);
287 ASSERT_EQ(3u, tab->navigations.size());
288 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
289 helper_.AssertNavigationEquals(nav2, tab->navigations[1]);
290 helper_.AssertNavigationEquals(nav1, tab->navigations[2]);
293 TEST_F(SessionServiceTest, TwoWindows) {
294 SessionID window2_id;
295 SessionID tab1_id;
296 SessionID tab2_id;
297 SerializedNavigationEntry nav1;
298 SerializedNavigationEntry nav2;
300 CreateAndWriteSessionWithTwoWindows(
301 window2_id, tab1_id, tab2_id, &nav1, &nav2);
303 ScopedVector<SessionWindow> windows;
304 ReadWindows(&(windows.get()), NULL);
306 ASSERT_EQ(2U, windows.size());
307 ASSERT_EQ(0, windows[0]->selected_tab_index);
308 ASSERT_EQ(0, windows[1]->selected_tab_index);
309 ASSERT_EQ(1U, windows[0]->tabs.size());
310 ASSERT_EQ(1U, windows[1]->tabs.size());
312 SessionTab* rt1;
313 SessionTab* rt2;
314 if (windows[0]->window_id.id() == window_id.id()) {
315 ASSERT_EQ(window2_id.id(), windows[1]->window_id.id());
316 ASSERT_EQ(ui::SHOW_STATE_NORMAL, windows[0]->show_state);
317 ASSERT_EQ(ui::SHOW_STATE_MAXIMIZED, windows[1]->show_state);
318 rt1 = windows[0]->tabs[0];
319 rt2 = windows[1]->tabs[0];
320 } else {
321 ASSERT_EQ(window2_id.id(), windows[0]->window_id.id());
322 ASSERT_EQ(window_id.id(), windows[1]->window_id.id());
323 ASSERT_EQ(ui::SHOW_STATE_MAXIMIZED, windows[0]->show_state);
324 ASSERT_EQ(ui::SHOW_STATE_NORMAL, windows[1]->show_state);
325 rt1 = windows[1]->tabs[0];
326 rt2 = windows[0]->tabs[0];
328 SessionTab* tab = rt1;
329 helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab);
330 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
332 tab = rt2;
333 helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
334 helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
337 TEST_F(SessionServiceTest, WindowWithNoTabsGetsPruned) {
338 SessionID window2_id;
339 SessionID tab1_id;
340 SessionID tab2_id;
342 SerializedNavigationEntry nav1 =
343 SerializedNavigationEntryTestHelper::CreateNavigation(
344 "http://google.com", "abc");
346 helper_.PrepareTabInWindow(window_id, tab1_id, 0, true);
347 UpdateNavigation(window_id, tab1_id, nav1, true);
349 const gfx::Rect window2_bounds(3, 4, 5, 6);
350 service()->SetWindowType(
351 window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
352 service()->SetWindowBounds(window2_id,
353 window2_bounds,
354 ui::SHOW_STATE_NORMAL);
355 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true);
357 ScopedVector<SessionWindow> windows;
358 ReadWindows(&(windows.get()), NULL);
360 ASSERT_EQ(1U, windows.size());
361 ASSERT_EQ(0, windows[0]->selected_tab_index);
362 ASSERT_EQ(1U, windows[0]->tabs.size());
363 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
365 SessionTab* tab = windows[0]->tabs[0];
366 helper_.AssertTabEquals(window_id, tab1_id, 0, 0, 1, *tab);
367 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
370 TEST_F(SessionServiceTest, ClosingWindowDoesntCloseTabs) {
371 SessionID tab_id;
372 SessionID tab2_id;
373 ASSERT_NE(tab_id.id(), tab2_id.id());
375 SerializedNavigationEntry nav1 =
376 SerializedNavigationEntryTestHelper::CreateNavigation(
377 "http://google.com", "abc");
378 SerializedNavigationEntry nav2 =
379 SerializedNavigationEntryTestHelper::CreateNavigation(
380 "http://google2.com", "abcd");
382 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
383 UpdateNavigation(window_id, tab_id, nav1, true);
385 helper_.PrepareTabInWindow(window_id, tab2_id, 1, false);
386 UpdateNavigation(window_id, tab2_id, nav2, true);
388 service()->WindowClosing(window_id);
390 ScopedVector<SessionWindow> windows;
391 ReadWindows(&(windows.get()), NULL);
393 ASSERT_EQ(1U, windows.size());
394 ASSERT_EQ(0, windows[0]->selected_tab_index);
395 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
396 ASSERT_EQ(2U, windows[0]->tabs.size());
398 SessionTab* tab = windows[0]->tabs[0];
399 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
400 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
402 tab = windows[0]->tabs[1];
403 helper_.AssertTabEquals(window_id, tab2_id, 1, 0, 1, *tab);
404 helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
407 TEST_F(SessionServiceTest, WindowCloseCommittedAfterNavigate) {
408 SessionID window2_id;
409 SessionID tab_id;
410 SessionID tab2_id;
411 ASSERT_NE(window2_id.id(), window_id.id());
413 service()->SetWindowType(
414 window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL);
415 service()->SetWindowBounds(window2_id,
416 window_bounds,
417 ui::SHOW_STATE_NORMAL);
419 SerializedNavigationEntry nav1 =
420 SerializedNavigationEntryTestHelper::CreateNavigation(
421 "http://google.com", "abc");
422 SerializedNavigationEntry nav2 =
423 SerializedNavigationEntryTestHelper::CreateNavigation(
424 "http://google2.com", "abcd");
426 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
427 UpdateNavigation(window_id, tab_id, nav1, true);
429 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
430 UpdateNavigation(window2_id, tab2_id, nav2, true);
432 service()->WindowClosing(window2_id);
433 service()->TabClosed(window2_id, tab2_id, false);
434 service()->WindowClosed(window2_id);
436 ScopedVector<SessionWindow> windows;
437 ReadWindows(&(windows.get()), NULL);
439 ASSERT_EQ(1U, windows.size());
440 ASSERT_EQ(0, windows[0]->selected_tab_index);
441 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
442 ASSERT_EQ(1U, windows[0]->tabs.size());
444 SessionTab* tab = windows[0]->tabs[0];
445 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
446 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
449 // Makes sure we don't track popups.
450 TEST_F(SessionServiceTest, IgnorePopups) {
451 if (browser_defaults::kRestorePopups)
452 return; // This test is only applicable if popups aren't restored.
454 SessionID window2_id;
455 SessionID tab_id;
456 SessionID tab2_id;
457 ASSERT_NE(window2_id.id(), window_id.id());
459 service()->SetWindowType(
460 window2_id, Browser::TYPE_POPUP, SessionService::TYPE_NORMAL);
461 service()->SetWindowBounds(window2_id,
462 window_bounds,
463 ui::SHOW_STATE_NORMAL);
465 SerializedNavigationEntry nav1 =
466 SerializedNavigationEntryTestHelper::CreateNavigation(
467 "http://google.com", "abc");
468 SerializedNavigationEntry nav2 =
469 SerializedNavigationEntryTestHelper::CreateNavigation(
470 "http://google2.com", "abcd");
472 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
473 UpdateNavigation(window_id, tab_id, nav1, true);
475 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
476 UpdateNavigation(window2_id, tab2_id, nav2, true);
478 ScopedVector<SessionWindow> windows;
479 ReadWindows(&(windows.get()), NULL);
481 ASSERT_EQ(1U, windows.size());
482 ASSERT_EQ(0, windows[0]->selected_tab_index);
483 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
484 ASSERT_EQ(1U, windows[0]->tabs.size());
486 SessionTab* tab = windows[0]->tabs[0];
487 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
488 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
491 // Makes sure we track popups.
492 TEST_F(SessionServiceTest, RestorePopup) {
493 if (!browser_defaults::kRestorePopups)
494 return; // This test is only applicable if popups are restored.
496 SessionID window2_id;
497 SessionID tab_id;
498 SessionID tab2_id;
499 ASSERT_NE(window2_id.id(), window_id.id());
501 service()->SetWindowType(
502 window2_id, Browser::TYPE_POPUP, SessionService::TYPE_NORMAL);
503 service()->SetWindowBounds(window2_id,
504 window_bounds,
505 ui::SHOW_STATE_NORMAL);
507 SerializedNavigationEntry nav1 =
508 SerializedNavigationEntryTestHelper::CreateNavigation(
509 "http://google.com", "abc");
510 SerializedNavigationEntry nav2 =
511 SerializedNavigationEntryTestHelper::CreateNavigation(
512 "http://google2.com", "abcd");
514 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
515 UpdateNavigation(window_id, tab_id, nav1, true);
517 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
518 UpdateNavigation(window2_id, tab2_id, nav2, true);
520 ScopedVector<SessionWindow> windows;
521 ReadWindows(&(windows.get()), NULL);
523 ASSERT_EQ(2U, windows.size());
524 int tabbed_index = windows[0]->type == Browser::TYPE_TABBED ?
525 0 : 1;
526 int popup_index = tabbed_index == 0 ? 1 : 0;
527 ASSERT_EQ(0, windows[tabbed_index]->selected_tab_index);
528 ASSERT_EQ(window_id.id(), windows[tabbed_index]->window_id.id());
529 ASSERT_EQ(1U, windows[tabbed_index]->tabs.size());
531 SessionTab* tab = windows[tabbed_index]->tabs[0];
532 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
533 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
535 ASSERT_EQ(0, windows[popup_index]->selected_tab_index);
536 ASSERT_EQ(window2_id.id(), windows[popup_index]->window_id.id());
537 ASSERT_EQ(1U, windows[popup_index]->tabs.size());
539 tab = windows[popup_index]->tabs[0];
540 helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
541 helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
544 #if defined (OS_CHROMEOS)
545 // Makes sure we track apps. Only applicable on chromeos.
546 TEST_F(SessionServiceTest, RestoreApp) {
547 SessionID window2_id;
548 SessionID tab_id;
549 SessionID tab2_id;
550 ASSERT_NE(window2_id.id(), window_id.id());
552 service()->SetWindowType(
553 window2_id, Browser::TYPE_POPUP, SessionService::TYPE_APP);
554 service()->SetWindowBounds(window2_id,
555 window_bounds,
556 ui::SHOW_STATE_NORMAL);
557 service()->SetWindowAppName(window2_id, "TestApp");
559 SerializedNavigationEntry nav1 =
560 SerializedNavigationEntryTestHelper::CreateNavigation(
561 "http://google.com", "abc");
562 SerializedNavigationEntry nav2 =
563 SerializedNavigationEntryTestHelper::CreateNavigation(
564 "http://google2.com", "abcd");
566 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
567 UpdateNavigation(window_id, tab_id, nav1, true);
569 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
570 UpdateNavigation(window2_id, tab2_id, nav2, true);
572 ScopedVector<SessionWindow> windows;
573 ReadWindows(&(windows.get()), NULL);
575 ASSERT_EQ(2U, windows.size());
576 int tabbed_index = windows[0]->type == Browser::TYPE_TABBED ?
577 0 : 1;
578 int app_index = tabbed_index == 0 ? 1 : 0;
579 ASSERT_EQ(0, windows[tabbed_index]->selected_tab_index);
580 ASSERT_EQ(window_id.id(), windows[tabbed_index]->window_id.id());
581 ASSERT_EQ(1U, windows[tabbed_index]->tabs.size());
583 SessionTab* tab = windows[tabbed_index]->tabs[0];
584 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
585 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
587 ASSERT_EQ(0, windows[app_index]->selected_tab_index);
588 ASSERT_EQ(window2_id.id(), windows[app_index]->window_id.id());
589 ASSERT_EQ(1U, windows[app_index]->tabs.size());
590 ASSERT_TRUE(windows[app_index]->type == Browser::TYPE_POPUP);
591 ASSERT_EQ("TestApp", windows[app_index]->app_name);
593 tab = windows[app_index]->tabs[0];
594 helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
595 helper_.AssertNavigationEquals(nav2, tab->navigations[0]);
597 #endif // defined (OS_CHROMEOS)
599 // Tests pruning from the front.
600 TEST_F(SessionServiceTest, PruneFromFront) {
601 const std::string base_url("http://google.com/");
602 SessionID tab_id;
604 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
606 // Add 5 navigations, with the 4th selected.
607 for (int i = 0; i < 5; ++i) {
608 SerializedNavigationEntry nav =
609 SerializedNavigationEntryTestHelper::CreateNavigation(
610 base_url + base::IntToString(i), "a");
611 nav.set_index(i);
612 UpdateNavigation(window_id, tab_id, nav, (i == 3));
615 // Prune the first two navigations from the front.
616 helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 2);
618 // Read back in.
619 ScopedVector<SessionWindow> windows;
620 ReadWindows(&(windows.get()), NULL);
622 ASSERT_EQ(1U, windows.size());
623 ASSERT_EQ(0, windows[0]->selected_tab_index);
624 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
625 ASSERT_EQ(1U, windows[0]->tabs.size());
627 // There shouldn't be an app id.
628 EXPECT_TRUE(windows[0]->tabs[0]->extension_app_id.empty());
630 // We should be left with three navigations, the 2nd selected.
631 SessionTab* tab = windows[0]->tabs[0];
632 ASSERT_EQ(1, tab->current_navigation_index);
633 EXPECT_EQ(3U, tab->navigations.size());
634 EXPECT_TRUE(GURL(base_url + base::IntToString(2)) ==
635 tab->navigations[0].virtual_url());
636 EXPECT_TRUE(GURL(base_url + base::IntToString(3)) ==
637 tab->navigations[1].virtual_url());
638 EXPECT_TRUE(GURL(base_url + base::IntToString(4)) ==
639 tab->navigations[2].virtual_url());
642 // Prunes from front so that we have no entries.
643 TEST_F(SessionServiceTest, PruneToEmpty) {
644 const std::string base_url("http://google.com/");
645 SessionID tab_id;
647 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
649 // Add 5 navigations, with the 4th selected.
650 for (int i = 0; i < 5; ++i) {
651 SerializedNavigationEntry nav =
652 SerializedNavigationEntryTestHelper::CreateNavigation(
653 base_url + base::IntToString(i), "a");
654 nav.set_index(i);
655 UpdateNavigation(window_id, tab_id, nav, (i == 3));
658 // Prune the first two navigations from the front.
659 helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 5);
661 // Read back in.
662 ScopedVector<SessionWindow> windows;
663 ReadWindows(&(windows.get()), NULL);
665 ASSERT_EQ(0U, windows.size());
668 // Don't set the pinned state and make sure the pinned value is false.
669 TEST_F(SessionServiceTest, PinnedDefaultsToFalse) {
670 EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, false));
673 // Explicitly set the pinned state to false and make sure we get back false.
674 TEST_F(SessionServiceTest, PinnedFalseWhenSetToFalse) {
675 EXPECT_FALSE(CreateAndWriteSessionWithOneTab(false, true));
678 // Explicitly set the pinned state to true and make sure we get back true.
679 TEST_F(SessionServiceTest, PinnedTrue) {
680 EXPECT_TRUE(CreateAndWriteSessionWithOneTab(true, true));
683 // Make sure application extension ids are persisted.
684 TEST_F(SessionServiceTest, PersistApplicationExtensionID) {
685 SessionID tab_id;
686 ASSERT_NE(window_id.id(), tab_id.id());
687 std::string app_id("foo");
689 SerializedNavigationEntry nav1 =
690 SerializedNavigationEntryTestHelper::CreateNavigation(
691 "http://google.com", "abc");
693 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
694 UpdateNavigation(window_id, tab_id, nav1, true);
695 helper_.SetTabExtensionAppID(window_id, tab_id, app_id);
697 ScopedVector<SessionWindow> windows;
698 ReadWindows(&(windows.get()), NULL);
700 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
701 EXPECT_TRUE(app_id == windows[0]->tabs[0]->extension_app_id);
704 // Check that user agent overrides are persisted.
705 TEST_F(SessionServiceTest, PersistUserAgentOverrides) {
706 SessionID tab_id;
707 ASSERT_NE(window_id.id(), tab_id.id());
708 std::string user_agent_override = "Mozilla/5.0 (X11; Linux x86_64) "
709 "AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 "
710 "Safari/535.19";
712 SerializedNavigationEntry nav1 =
713 SerializedNavigationEntryTestHelper::CreateNavigation(
714 "http://google.com", "abc");
715 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav1);
717 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
718 UpdateNavigation(window_id, tab_id, nav1, true);
719 helper_.SetTabUserAgentOverride(window_id, tab_id, user_agent_override);
721 ScopedVector<SessionWindow> windows;
722 ReadWindows(&(windows.get()), NULL);
723 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
725 SessionTab* tab = windows[0]->tabs[0];
726 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
727 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
728 EXPECT_TRUE(user_agent_override == tab->user_agent_override);
731 // Test that the notification for SESSION_SERVICE_SAVED is working properly.
732 TEST_F(SessionServiceTest, SavedSessionNotification) {
733 content::NotificationRegistrar registrar_;
734 registrar_.Add(this, chrome::NOTIFICATION_SESSION_SERVICE_SAVED,
735 content::NotificationService::AllSources());
736 service()->Save();
737 EXPECT_EQ(sync_save_count_, 1);
740 // Makes sure a tab closed by a user gesture is not restored.
741 TEST_F(SessionServiceTest, CloseTabUserGesture) {
742 SessionID tab_id;
743 ASSERT_NE(window_id.id(), tab_id.id());
745 SerializedNavigationEntry nav1 =
746 SerializedNavigationEntryTestHelper::CreateNavigation(
747 "http://google.com", "abc");
749 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
750 UpdateNavigation(window_id, tab_id, nav1, true);
751 service()->TabClosed(window_id, tab_id, true);
753 ScopedVector<SessionWindow> windows;
754 ReadWindows(&(windows.get()), NULL);
756 ASSERT_TRUE(windows.empty());
759 // Verifies SetWindowBounds maps SHOW_STATE_DEFAULT to SHOW_STATE_NORMAL.
760 TEST_F(SessionServiceTest, DontPersistDefault) {
761 SessionID tab_id;
762 ASSERT_NE(window_id.id(), tab_id.id());
763 SerializedNavigationEntry nav1 =
764 SerializedNavigationEntryTestHelper::CreateNavigation(
765 "http://google.com", "abc");
766 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
767 UpdateNavigation(window_id, tab_id, nav1, true);
768 service()->SetWindowBounds(window_id,
769 window_bounds,
770 ui::SHOW_STATE_DEFAULT);
772 ScopedVector<SessionWindow> windows;
773 ReadWindows(&(windows.get()), NULL);
774 ASSERT_EQ(1U, windows.size());
775 EXPECT_EQ(ui::SHOW_STATE_NORMAL, windows[0]->show_state);
778 TEST_F(SessionServiceTest, KeepPostDataWithoutPasswords) {
779 SessionID tab_id;
780 ASSERT_NE(window_id.id(), tab_id.id());
782 // Create a page state representing a HTTP body without posted passwords.
783 content::PageState page_state =
784 content::PageState::CreateForTesting(GURL(), false, "data", NULL);
786 // Create a TabNavigation containing page_state and representing a POST
787 // request.
788 SerializedNavigationEntry nav1 =
789 SerializedNavigationEntryTestHelper::CreateNavigation(
790 "http://google.com", "title");
791 SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
792 SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
794 // Create a TabNavigation containing page_state and representing a normal
795 // request.
796 SerializedNavigationEntry nav2 =
797 SerializedNavigationEntryTestHelper::CreateNavigation(
798 "http://google.com/nopost", "title");
799 SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav2);
800 nav2.set_index(1);
802 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
803 UpdateNavigation(window_id, tab_id, nav1, true);
804 UpdateNavigation(window_id, tab_id, nav2, true);
806 ScopedVector<SessionWindow> windows;
807 ReadWindows(&(windows.get()), NULL);
809 helper_.AssertSingleWindowWithSingleTab(windows.get(), 2);
811 // Expected: the page state of both navigations was saved and restored.
812 ASSERT_EQ(2u, windows[0]->tabs[0]->navigations.size());
813 helper_.AssertNavigationEquals(nav1, windows[0]->tabs[0]->navigations[0]);
814 helper_.AssertNavigationEquals(nav2, windows[0]->tabs[0]->navigations[1]);
817 TEST_F(SessionServiceTest, RemovePostDataWithPasswords) {
818 SessionID tab_id;
819 ASSERT_NE(window_id.id(), tab_id.id());
821 // Create a page state representing a HTTP body with posted passwords.
822 content::PageState page_state =
823 content::PageState::CreateForTesting(GURL(), true, "data", NULL);
825 // Create a TabNavigation containing page_state and representing a POST
826 // request with passwords.
827 SerializedNavigationEntry nav1 =
828 SerializedNavigationEntryTestHelper::CreateNavigation(
829 "http://google.com", "title");
830 SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
831 SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
832 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
833 UpdateNavigation(window_id, tab_id, nav1, true);
835 ScopedVector<SessionWindow> windows;
836 ReadWindows(&(windows.get()), NULL);
838 helper_.AssertSingleWindowWithSingleTab(windows.get(), 1);
840 // Expected: the HTTP body was removed from the page state of the POST
841 // navigation with passwords.
842 EXPECT_NE(page_state, windows[0]->tabs[0]->navigations[0].page_state());
845 // This test is only applicable to chromeos.
846 #if defined(OS_CHROMEOS)
847 // Verifies migration of tab/window closed works.
848 TEST_F(SessionServiceTest, CanOpenV1TabClosed) {
849 base::FilePath v1_file_path;
850 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &v1_file_path));
851 // v1_session_file contains a tab closed command with the original id. The
852 // file was generated from ClosingTabStaysClosed. If we successfully processed
853 // the file we'll have one tab.
854 v1_file_path =
855 v1_file_path.AppendASCII("sessions").AppendASCII("v1_session_file");
856 base::FilePath dest_file_path(path_);
857 dest_file_path = dest_file_path.AppendASCII("Current Session");
859 // Forces closing the file.
860 helper_.SetService(NULL);
862 ASSERT_TRUE(base::CopyFile(v1_file_path, dest_file_path));
864 SessionService* session_service = new SessionService(path_);
865 helper_.SetService(session_service);
866 ScopedVector<SessionWindow> windows;
867 SessionID::id_type active_window_id = 0;
868 helper_.ReadWindows(&(windows.get()), &active_window_id);
869 ASSERT_EQ(1u, windows.size());
870 EXPECT_EQ(1u, windows[0]->tabs.size());
872 #endif // defined(OS_CHROMEOS)
874 TEST_F(SessionServiceTest, ReplacePendingNavigation) {
875 const std::string base_url("http://google.com/");
876 SessionID tab_id;
878 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
880 // Add 5 navigations, some with the same index
881 for (int i = 0; i < 5; ++i) {
882 SerializedNavigationEntry nav =
883 SerializedNavigationEntryTestHelper::CreateNavigation(
884 base_url + base::IntToString(i), "a");
885 nav.set_index(i / 2);
886 UpdateNavigation(window_id, tab_id, nav, true);
889 // Read back in.
890 ScopedVector<SessionWindow> windows;
891 ReadWindows(&(windows.get()), NULL);
893 // The ones with index 0, and 2 should have been replaced by 1 and 3.
894 ASSERT_EQ(1U, windows.size());
895 ASSERT_EQ(1U, windows[0]->tabs.size());
896 EXPECT_EQ(3U, windows[0]->tabs[0]->navigations.size());
897 EXPECT_EQ(GURL(base_url + base::IntToString(1)),
898 windows[0]->tabs[0]->navigations[0].virtual_url());
899 EXPECT_EQ(GURL(base_url + base::IntToString(3)),
900 windows[0]->tabs[0]->navigations[1].virtual_url());
901 EXPECT_EQ(GURL(base_url + base::IntToString(4)),
902 windows[0]->tabs[0]->navigations[2].virtual_url());
905 TEST_F(SessionServiceTest, ReplacePendingNavigationAndPrune) {
906 const std::string base_url("http://google.com/");
907 SessionID tab_id;
909 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
911 for (int i = 0; i < 5; ++i) {
912 SerializedNavigationEntry nav =
913 SerializedNavigationEntryTestHelper::CreateNavigation(
914 base_url + base::IntToString(i), "a");
915 nav.set_index(i);
916 UpdateNavigation(window_id, tab_id, nav, true);
919 // Prune all those navigations.
920 helper_.service()->TabNavigationPathPrunedFromFront(window_id, tab_id, 5);
922 // Add another navigation to replace the last one.
923 SerializedNavigationEntry nav =
924 SerializedNavigationEntryTestHelper::CreateNavigation(
925 base_url + base::IntToString(5), "a");
926 nav.set_index(4);
927 UpdateNavigation(window_id, tab_id, nav, true);
929 // Read back in.
930 ScopedVector<SessionWindow> windows;
931 ReadWindows(&(windows.get()), NULL);
933 // We should still have that last navigation at the end,
934 // even though it replaced one that was set before the prune.
935 ASSERT_EQ(1U, windows.size());
936 ASSERT_EQ(1U, windows[0]->tabs.size());
937 ASSERT_EQ(1U, windows[0]->tabs[0]->navigations.size());
938 EXPECT_EQ(GURL(base_url + base::IntToString(5)),
939 windows[0]->tabs[0]->navigations[0].virtual_url());
942 TEST_F(SessionServiceTest, RestoreActivation1) {
943 SessionID window2_id;
944 SessionID tab1_id;
945 SessionID tab2_id;
946 SerializedNavigationEntry nav1;
947 SerializedNavigationEntry nav2;
949 CreateAndWriteSessionWithTwoWindows(
950 window2_id, tab1_id, tab2_id, &nav1, &nav2);
952 service()->ScheduleCommand(
953 service()->CreateSetActiveWindowCommand(window2_id));
954 service()->ScheduleCommand(
955 service()->CreateSetActiveWindowCommand(window_id));
957 ScopedVector<SessionWindow> windows;
958 SessionID::id_type active_window_id = 0;
959 ReadWindows(&(windows.get()), &active_window_id);
960 EXPECT_EQ(window_id.id(), active_window_id);
963 // It's easier to have two separate tests with setup/teardown than to manualy
964 // reset the state for the different flavors of the test.
965 TEST_F(SessionServiceTest, RestoreActivation2) {
966 SessionID window2_id;
967 SessionID tab1_id;
968 SessionID tab2_id;
969 SerializedNavigationEntry nav1;
970 SerializedNavigationEntry nav2;
972 CreateAndWriteSessionWithTwoWindows(
973 window2_id, tab1_id, tab2_id, &nav1, &nav2);
975 service()->ScheduleCommand(
976 service()->CreateSetActiveWindowCommand(window2_id));
977 service()->ScheduleCommand(
978 service()->CreateSetActiveWindowCommand(window_id));
979 service()->ScheduleCommand(
980 service()->CreateSetActiveWindowCommand(window2_id));
982 ScopedVector<SessionWindow> windows;
983 SessionID::id_type active_window_id = 0;
984 ReadWindows(&(windows.get()), &active_window_id);
985 EXPECT_EQ(window2_id.id(), active_window_id);
988 // Makes sure we don't track blacklisted URLs.
989 TEST_F(SessionServiceTest, IgnoreBlacklistedUrls) {
990 SessionID tab_id;
992 SerializedNavigationEntry nav1 =
993 SerializedNavigationEntryTestHelper::CreateNavigation(
994 "http://google.com", "abc");
995 SerializedNavigationEntry nav2 =
996 SerializedNavigationEntryTestHelper::CreateNavigation(
997 chrome::kChromeUIQuitURL, "quit");
998 SerializedNavigationEntry nav3 =
999 SerializedNavigationEntryTestHelper::CreateNavigation(
1000 chrome::kChromeUIRestartURL, "restart");
1002 helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
1003 UpdateNavigation(window_id, tab_id, nav1, true);
1004 UpdateNavigation(window_id, tab_id, nav2, true);
1005 UpdateNavigation(window_id, tab_id, nav3, true);
1007 ScopedVector<SessionWindow> windows;
1008 ReadWindows(&(windows.get()), NULL);
1010 ASSERT_EQ(1U, windows.size());
1011 ASSERT_EQ(0, windows[0]->selected_tab_index);
1012 ASSERT_EQ(window_id.id(), windows[0]->window_id.id());
1013 ASSERT_EQ(1U, windows[0]->tabs.size());
1015 SessionTab* tab = windows[0]->tabs[0];
1016 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
1017 helper_.AssertNavigationEquals(nav1, tab->navigations[0]);