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 "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
7 #include "base/rand_util.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/sync/glue/session_model_associator.h"
12 #include "chrome/browser/sync/open_tabs_ui_delegate.h"
13 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h"
14 #include "sync/protocol/session_specifics.pb.h"
15 #include "testing/gtest/include/gtest/gtest.h"
19 const char kBaseSessionTag
[] = "session_tag";
20 const char kBaseSessionName
[] = "session_name";
21 const char kBaseTabUrl
[] = "http://foo/?";
22 const char kTabTitleFormat
[] = "session=%d;window=%d;tab=%d";
24 struct TitleTimestampPair
{
29 bool SortTabTimesByRecency(const TitleTimestampPair
& t1
,
30 const TitleTimestampPair
& t2
) {
31 return t1
.timestamp
> t2
.timestamp
;
34 int CreateUniqueID() {
40 std::string
ToSessionTag(SessionID::id_type session_id
) {
41 return std::string(kBaseSessionTag
+ base::IntToString(session_id
));
44 std::string
ToSessionName(SessionID::id_type session_id
) {
45 return std::string(kBaseSessionName
+ base::IntToString(session_id
));
48 std::string
ToTabTitle(SessionID::id_type session_id
,
49 SessionID::id_type window_id
,
50 SessionID::id_type tab_id
) {
51 return base::StringPrintf(kTabTitleFormat
, session_id
, window_id
, tab_id
);
54 std::string
ToTabUrl(SessionID::id_type session_id
,
55 SessionID::id_type window_id
,
56 SessionID::id_type tab_id
) {
57 return std::string(kBaseTabUrl
+ ToTabTitle(session_id
, window_id
, tab_id
));
62 struct RecentTabsBuilderTestHelper::TabInfo
{
64 SessionID::id_type id
;
68 struct RecentTabsBuilderTestHelper::WindowInfo
{
69 WindowInfo() : id(0) {}
71 SessionID::id_type id
;
72 std::vector
<TabInfo
> tabs
;
74 struct RecentTabsBuilderTestHelper::SessionInfo
{
75 SessionInfo() : id(0) {}
77 SessionID::id_type id
;
78 std::vector
<WindowInfo
> windows
;
81 RecentTabsBuilderTestHelper::RecentTabsBuilderTestHelper()
82 : max_tab_node_id_(0) {
83 start_time_
= base::Time::Now();
86 RecentTabsBuilderTestHelper::~RecentTabsBuilderTestHelper() {
89 void RecentTabsBuilderTestHelper::AddSession() {
91 info
.id
= CreateUniqueID();
92 sessions_
.push_back(info
);
95 int RecentTabsBuilderTestHelper::GetSessionCount() {
96 return sessions_
.size();
99 SessionID::id_type
RecentTabsBuilderTestHelper::GetSessionID(
101 return sessions_
[session_index
].id
;
104 base::Time
RecentTabsBuilderTestHelper::GetSessionTimestamp(int session_index
) {
105 std::vector
<base::Time
> timestamps
;
106 for (int w
= 0; w
< GetWindowCount(session_index
); ++w
) {
107 for (int t
= 0; t
< GetTabCount(session_index
, w
); ++t
)
108 timestamps
.push_back(GetTabTimestamp(session_index
, w
, t
));
111 if (timestamps
.empty())
112 return base::Time::Now();
114 sort(timestamps
.begin(), timestamps
.end());
115 return timestamps
[0];
118 void RecentTabsBuilderTestHelper::AddWindow(int session_index
) {
119 WindowInfo window_info
;
120 window_info
.id
= CreateUniqueID();
121 sessions_
[session_index
].windows
.push_back(window_info
);
124 int RecentTabsBuilderTestHelper::GetWindowCount(int session_index
) {
125 return sessions_
[session_index
].windows
.size();
128 SessionID::id_type
RecentTabsBuilderTestHelper::GetWindowID(int session_index
,
130 return sessions_
[session_index
].windows
[window_index
].id
;
133 void RecentTabsBuilderTestHelper::AddTab(int session_index
, int window_index
) {
134 base::Time timestamp
=
135 start_time_
+ base::TimeDelta::FromMinutes(base::RandUint64());
136 AddTabWithInfo(session_index
, window_index
, timestamp
, base::string16());
139 void RecentTabsBuilderTestHelper::AddTabWithInfo(int session_index
,
141 base::Time timestamp
,
142 const base::string16
& title
) {
144 tab_info
.id
= CreateUniqueID();
145 tab_info
.timestamp
= timestamp
;
146 tab_info
.title
= title
;
147 sessions_
[session_index
].windows
[window_index
].tabs
.push_back(tab_info
);
150 int RecentTabsBuilderTestHelper::GetTabCount(int session_index
,
152 return sessions_
[session_index
].windows
[window_index
].tabs
.size();
155 SessionID::id_type
RecentTabsBuilderTestHelper::GetTabID(int session_index
,
158 return sessions_
[session_index
].windows
[window_index
].tabs
[tab_index
].id
;
161 base::Time
RecentTabsBuilderTestHelper::GetTabTimestamp(int session_index
,
164 return sessions_
[session_index
].windows
[window_index
]
165 .tabs
[tab_index
].timestamp
;
168 base::string16
RecentTabsBuilderTestHelper::GetTabTitle(int session_index
,
171 base::string16 title
=
172 sessions_
[session_index
].windows
[window_index
].tabs
[tab_index
].title
;
174 title
= base::UTF8ToUTF16(ToTabTitle(
175 GetSessionID(session_index
),
176 GetWindowID(session_index
, window_index
),
177 GetTabID(session_index
, window_index
, tab_index
)));
182 void RecentTabsBuilderTestHelper::ExportToSessionsSyncManager(
183 browser_sync::SessionsSyncManager
* manager
) {
184 syncer::SyncChangeList changes
;
185 for (int s
= 0; s
< GetSessionCount(); ++s
) {
186 sync_pb::EntitySpecifics session_entity
;
187 sync_pb::SessionSpecifics
* meta
= session_entity
.mutable_session();
188 BuildSessionSpecifics(s
, meta
);
189 for (int w
= 0; w
< GetWindowCount(s
); ++w
) {
190 BuildWindowSpecifics(s
, w
, meta
);
191 for (int t
= 0; t
< GetTabCount(s
, w
); ++t
) {
192 sync_pb::EntitySpecifics entity
;
193 sync_pb::SessionSpecifics
* tab_base
= entity
.mutable_session();
194 BuildTabSpecifics(s
, w
, t
, tab_base
);
195 changes
.push_back(syncer::SyncChange(
196 FROM_HERE
, syncer::SyncChange::ACTION_ADD
,
197 syncer::SyncData::CreateRemoteData(
198 tab_base
->tab_node_id(), entity
, GetTabTimestamp(s
, w
, t
))));
201 changes
.push_back(syncer::SyncChange(
202 FROM_HERE
, syncer::SyncChange::ACTION_ADD
,
203 syncer::SyncData::CreateRemoteData(1, session_entity
,
204 GetSessionTimestamp(s
))));
206 manager
->ProcessSyncChanges(FROM_HERE
, changes
);
207 VerifyExport(manager
);
210 void RecentTabsBuilderTestHelper::ExportToSessionModelAssociator(
211 browser_sync::SessionModelAssociator
* associator
) {
212 for (int s
= 0; s
< GetSessionCount(); ++s
) {
213 sync_pb::SessionSpecifics meta
;
214 BuildSessionSpecifics(s
, &meta
);
215 for (int w
= 0; w
< GetWindowCount(s
); ++w
) {
216 BuildWindowSpecifics(s
, w
, &meta
);
217 for (int t
= 0; t
< GetTabCount(s
, w
); ++t
) {
218 sync_pb::SessionSpecifics tab_base
;
219 BuildTabSpecifics(s
, w
, t
, &tab_base
);
220 associator
->AssociateForeignSpecifics(tab_base
,
221 GetTabTimestamp(s
, w
, t
));
224 associator
->AssociateForeignSpecifics(meta
, GetSessionTimestamp(s
));
226 VerifyExport(associator
);
229 void RecentTabsBuilderTestHelper::VerifyExport(
230 browser_sync::OpenTabsUIDelegate
* delegate
) {
231 // Make sure data is populated correctly in SessionModelAssociator.
232 std::vector
<const browser_sync::SyncedSession
*> sessions
;
233 ASSERT_TRUE(delegate
->GetAllForeignSessions(&sessions
));
234 ASSERT_EQ(GetSessionCount(), static_cast<int>(sessions
.size()));
235 for (int s
= 0; s
< GetSessionCount(); ++s
) {
236 std::vector
<const SessionWindow
*> windows
;
237 ASSERT_TRUE(delegate
->GetForeignSession(ToSessionTag(GetSessionID(s
)),
239 ASSERT_EQ(GetWindowCount(s
), static_cast<int>(windows
.size()));
240 for (int w
= 0; w
< GetWindowCount(s
); ++w
)
241 ASSERT_EQ(GetTabCount(s
, w
), static_cast<int>(windows
[w
]->tabs
.size()));
245 std::vector
<base::string16
>
246 RecentTabsBuilderTestHelper::GetTabTitlesSortedByRecency() {
247 std::vector
<TitleTimestampPair
> tabs
;
248 for (int s
= 0; s
< GetSessionCount(); ++s
) {
249 for (int w
= 0; w
< GetWindowCount(s
); ++w
) {
250 for (int t
= 0; t
< GetTabCount(s
, w
); ++t
) {
251 TitleTimestampPair pair
;
252 pair
.title
= GetTabTitle(s
, w
, t
);
253 pair
.timestamp
= GetTabTimestamp(s
, w
, t
);
254 tabs
.push_back(pair
);
258 sort(tabs
.begin(), tabs
.end(), SortTabTimesByRecency
);
260 std::vector
<base::string16
> titles
;
261 for (size_t i
= 0; i
< tabs
.size(); ++i
)
262 titles
.push_back(tabs
[i
].title
);
266 void RecentTabsBuilderTestHelper::BuildSessionSpecifics(
268 sync_pb::SessionSpecifics
* meta
) {
269 SessionID::id_type session_id
= GetSessionID(session_index
);
270 meta
->set_session_tag(ToSessionTag(session_id
));
271 sync_pb::SessionHeader
* header
= meta
->mutable_header();
272 header
->set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_CROS
);
273 header
->set_client_name(ToSessionName(session_id
));
276 void RecentTabsBuilderTestHelper::BuildWindowSpecifics(
279 sync_pb::SessionSpecifics
* meta
) {
280 sync_pb::SessionHeader
* header
= meta
->mutable_header();
281 sync_pb::SessionWindow
* window
= header
->add_window();
282 SessionID::id_type window_id
= GetWindowID(session_index
, window_index
);
283 window
->set_window_id(window_id
);
284 window
->set_selected_tab_index(0);
285 window
->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED
);
286 for (int i
= 0; i
< GetTabCount(session_index
, window_index
); ++i
)
287 window
->add_tab(GetTabID(session_index
, window_index
, i
));
290 void RecentTabsBuilderTestHelper::BuildTabSpecifics(
294 sync_pb::SessionSpecifics
* tab_base
) {
295 SessionID::id_type session_id
= GetSessionID(session_index
);
296 SessionID::id_type window_id
= GetWindowID(session_index
, window_index
);
297 SessionID::id_type tab_id
= GetTabID(session_index
, window_index
, tab_index
);
299 tab_base
->set_session_tag(ToSessionTag(session_id
));
300 tab_base
->set_tab_node_id(++max_tab_node_id_
);
301 sync_pb::SessionTab
* tab
= tab_base
->mutable_tab();
302 tab
->set_window_id(window_id
);
303 tab
->set_tab_id(tab_id
);
304 tab
->set_tab_visual_index(1);
305 tab
->set_current_navigation_index(0);
306 tab
->set_pinned(true);
307 tab
->set_extension_app_id("app_id");
308 sync_pb::TabNavigation
* navigation
= tab
->add_navigation();
309 navigation
->set_virtual_url(ToTabUrl(session_id
, window_id
, tab_id
));
310 navigation
->set_referrer("referrer");
311 navigation
->set_title(base::UTF16ToUTF8(GetTabTitle(
312 session_index
, window_index
, tab_index
)));
313 navigation
->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED
);