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 <string>
6#include <vector>
7
8#include "base/memory/scoped_ptr.h"
9#include "base/values.h"
10#include "chrome/browser/sessions/session_types.h"
11#include "chrome/browser/sync/glue/session_model_associator.h"
12#include "chrome/common/url_constants.h"
13#include "content/common/page_transition_types.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16using browser_sync::SessionModelAssociator;
17using browser_sync::ForeignSessionTracker;
18namespace browser_sync {
19
20typedef testing::Test SessionModelAssociatorTest;
21
22TEST_F(SessionModelAssociatorTest, SessionWindowHasNoTabsToSync) {
23  SessionWindow win;
24  ASSERT_TRUE(SessionModelAssociator::SessionWindowHasNoTabsToSync(win));
25  scoped_ptr<SessionTab> tab(new SessionTab());
26  win.tabs.push_back(tab.release());
27  ASSERT_TRUE(SessionModelAssociator::SessionWindowHasNoTabsToSync(win));
28  TabNavigation nav(0, GURL("about:bubba"), GURL("about:referrer"),
29                    string16(ASCIIToUTF16("title")),
30                    std::string("state"), 0U);
31  win.tabs[0]->navigations.push_back(nav);
32  ASSERT_FALSE(SessionModelAssociator::SessionWindowHasNoTabsToSync(win));
33}
34
35TEST_F(SessionModelAssociatorTest, IsValidSessionTab) {
36  SessionTab tab;
37  ASSERT_FALSE(SessionModelAssociator::IsValidSessionTab(tab));
38  TabNavigation nav(0, GURL(chrome::kChromeUINewTabURL),
39                    GURL("about:referrer"),
40                    string16(ASCIIToUTF16("title")),
41                    std::string("state"), 0U);
42  tab.navigations.push_back(nav);
43  // NewTab does not count as valid if it's the only navigation.
44  ASSERT_FALSE(SessionModelAssociator::IsValidSessionTab(tab));
45  TabNavigation nav2(0, GURL("about:bubba"),
46                    GURL("about:referrer"),
47                    string16(ASCIIToUTF16("title")),
48                    std::string("state"), 0U);
49  tab.navigations.push_back(nav2);
50  // Once there's another navigation, the tab is valid.
51  ASSERT_TRUE(SessionModelAssociator::IsValidSessionTab(tab));
52}
53
54TEST_F(SessionModelAssociatorTest, PopulateSessionWindow) {
55  sync_pb::SessionWindow window_s;
56  window_s.add_tab(0);
57  window_s.set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_NORMAL);
58  window_s.set_selected_tab_index(1);
59
60  std::string tag = "tag";
61  ForeignSessionTracker tracker;
62  ForeignSession* session = tracker.GetForeignSession(tag);
63  SessionWindow* win = new SessionWindow();
64  session->windows.push_back(win);
65  SessionModelAssociator::PopulateSessionWindowFromSpecifics(
66      tag, window_s, 0, win, &tracker);
67  ASSERT_EQ(1U, win->tabs.size());
68  ASSERT_EQ(1, win->selected_tab_index);
69  ASSERT_EQ(1, win->type);
70  ASSERT_EQ(1U, tracker.num_foreign_sessions());
71  ASSERT_EQ(1U, tracker.num_foreign_tabs(std::string("tag")));
72
73  // We do this so that when the destructor for the tracker is called, it will
74  // be able to delete the session, window, and tab. We can't delete these
75  // ourselves, otherwise we would run into double free errors when the
76  // destructor was invoked (the true argument tells the tracker the tab
77  // is now associated with a window).
78  ASSERT_TRUE(tracker.GetSessionTab(tag, 0, true));
79}
80
81TEST_F(SessionModelAssociatorTest, PopulateSessionTab) {
82  sync_pb::SessionTab tab_s;
83  tab_s.set_tab_visual_index(13);
84  tab_s.set_current_navigation_index(3);
85  tab_s.set_pinned(true);
86  tab_s.set_extension_app_id("app_id");
87  sync_pb::TabNavigation* navigation = tab_s.add_navigation();
88  navigation->set_index(12);
89  navigation->set_virtual_url("http://foo/1");
90  navigation->set_referrer("referrer");
91  navigation->set_title("title");
92  navigation->set_page_transition(sync_pb::TabNavigation_PageTransition_TYPED);
93
94  SessionTab tab;
95  SessionModelAssociator::PopulateSessionTabFromSpecifics(tab_s, 0, &tab);
96  ASSERT_EQ(13, tab.tab_visual_index);
97  ASSERT_EQ(3, tab.current_navigation_index);
98  ASSERT_TRUE(tab.pinned);
99  ASSERT_EQ("app_id", tab.extension_app_id);
100  ASSERT_EQ(12, tab.navigations[0].index());
101  ASSERT_EQ(GURL("referrer"), tab.navigations[0].referrer());
102  ASSERT_EQ(string16(ASCIIToUTF16("title")), tab.navigations[0].title());
103  ASSERT_EQ(PageTransition::TYPED, tab.navigations[0].transition());
104  ASSERT_EQ(GURL("http://foo/1"), tab.navigations[0].virtual_url());
105}
106
107TEST_F(SessionModelAssociatorTest, ForeignSessionTracker) {
108  const std::string tag1 = "tag";
109  const std::string tag2 = "tag2";
110  const std::string tag3 = "tag3";
111  ForeignSessionTracker tracker;
112  ASSERT_TRUE(tracker.empty());
113  ASSERT_EQ(0U, tracker.num_foreign_sessions());
114  ASSERT_EQ(0U, tracker.num_foreign_tabs(tag1));
115  SessionTab* tab = tracker.GetSessionTab(tag1, 0, false);
116  ASSERT_EQ(1U, tracker.num_foreign_tabs(tag1));
117  ASSERT_EQ(0U, tracker.num_foreign_sessions());
118  SessionTab* tab2 = tracker.GetSessionTab(tag1, 0, false);
119  ASSERT_EQ(1U, tracker.num_foreign_tabs(tag1));
120  ASSERT_EQ(0U, tracker.num_foreign_sessions());
121  ASSERT_EQ(tab, tab2);
122  tab2 = tracker.GetSessionTab(tag2, 0, false);
123  ASSERT_EQ(1U, tracker.num_foreign_tabs(tag1));
124  ASSERT_EQ(1U, tracker.num_foreign_tabs(tag2));
125  ASSERT_EQ(0U, tracker.num_foreign_sessions());
126
127  ASSERT_FALSE(tracker.DeleteForeignSession(tag1));
128  ASSERT_FALSE(tracker.DeleteForeignSession(tag3));
129
130  ForeignSession* session = tracker.GetForeignSession(tag1);
131  ForeignSession* session2 = tracker.GetForeignSession(tag2);
132  ForeignSession* session3 = tracker.GetForeignSession(tag3);
133  ASSERT_EQ(3U, tracker.num_foreign_sessions());
134
135  ASSERT_TRUE(session);
136  ASSERT_TRUE(session2);
137  ASSERT_TRUE(session3);
138  ASSERT_NE(session, session2);
139  ASSERT_NE(session2, session3);
140  ASSERT_TRUE(tracker.DeleteForeignSession(tag3));
141  ASSERT_EQ(2U, tracker.num_foreign_sessions());
142
143  const SessionTab *tab_ptr;
144  ASSERT_TRUE(tracker.LookupSessionTab(tag1, 0, &tab_ptr));
145  ASSERT_EQ(tab_ptr, tab);
146
147  std::vector<SessionWindow*> windows;
148  ASSERT_TRUE(tracker.LookupSessionWindows(tag1, &windows));
149  ASSERT_EQ(0U, windows.size());
150
151  // The sessions don't have valid windows, lookup should not succeed.
152  std::vector<const ForeignSession*> sessions;
153  ASSERT_FALSE(tracker.LookupAllForeignSessions(&sessions));
154
155  tracker.clear();
156  ASSERT_EQ(0U, tracker.num_foreign_tabs(tag1));
157  ASSERT_EQ(0U, tracker.num_foreign_tabs(tag2));
158  ASSERT_EQ(0U, tracker.num_foreign_sessions());
159}
160
161}  // namespace browser_sync
162
163