Home | History | Annotate | Download | only in toolbar
      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 "chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h"
      6 
      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/open_tabs_ui_delegate.h"
     12 #include "chrome/browser/sync/sessions/sessions_sync_manager.h"
     13 #include "sync/api/attachments/attachment_id.h"
     14 #include "sync/api/attachments/attachment_service_proxy_for_test.h"
     15 #include "sync/protocol/session_specifics.pb.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 namespace {
     19 
     20 const char kBaseSessionTag[] = "session_tag";
     21 const char kBaseSessionName[] = "session_name";
     22 const char kBaseTabUrl[] = "http://foo/?";
     23 const char kTabTitleFormat[] = "session=%d;window=%d;tab=%d";
     24 
     25 struct TitleTimestampPair {
     26   base::string16 title;
     27   base::Time timestamp;
     28 };
     29 
     30 bool SortTabTimesByRecency(const TitleTimestampPair& t1,
     31                            const TitleTimestampPair& t2) {
     32   return t1.timestamp > t2.timestamp;
     33 }
     34 
     35 int CreateUniqueID() {
     36   static int s_id = 0;
     37   ++s_id;
     38   return s_id;
     39 }
     40 
     41 std::string ToSessionTag(SessionID::id_type session_id) {
     42   return std::string(kBaseSessionTag + base::IntToString(session_id));
     43 }
     44 
     45 std::string ToSessionName(SessionID::id_type session_id) {
     46   return std::string(kBaseSessionName + base::IntToString(session_id));
     47 }
     48 
     49 std::string ToTabTitle(SessionID::id_type session_id,
     50                        SessionID::id_type window_id,
     51                        SessionID::id_type tab_id) {
     52   return base::StringPrintf(kTabTitleFormat, session_id, window_id, tab_id);
     53 }
     54 
     55 std::string ToTabUrl(SessionID::id_type session_id,
     56                      SessionID::id_type window_id,
     57                      SessionID::id_type tab_id) {
     58   return std::string(kBaseTabUrl + ToTabTitle(session_id, window_id, tab_id));
     59 }
     60 
     61 }  // namespace
     62 
     63 struct RecentTabsBuilderTestHelper::TabInfo {
     64   TabInfo() : id(0) {}
     65   SessionID::id_type id;
     66   base::Time timestamp;
     67   base::string16 title;
     68 };
     69 struct RecentTabsBuilderTestHelper::WindowInfo {
     70   WindowInfo() : id(0) {}
     71   ~WindowInfo() {}
     72   SessionID::id_type id;
     73   std::vector<TabInfo> tabs;
     74 };
     75 struct RecentTabsBuilderTestHelper::SessionInfo {
     76   SessionInfo() : id(0) {}
     77   ~SessionInfo() {}
     78   SessionID::id_type id;
     79   std::vector<WindowInfo> windows;
     80 };
     81 
     82 RecentTabsBuilderTestHelper::RecentTabsBuilderTestHelper()
     83     : max_tab_node_id_(0) {
     84   start_time_ = base::Time::Now();
     85 }
     86 
     87 RecentTabsBuilderTestHelper::~RecentTabsBuilderTestHelper() {
     88 }
     89 
     90 void RecentTabsBuilderTestHelper::AddSession() {
     91   SessionInfo info;
     92   info.id = CreateUniqueID();
     93   sessions_.push_back(info);
     94 }
     95 
     96 int RecentTabsBuilderTestHelper::GetSessionCount() {
     97   return sessions_.size();
     98 }
     99 
    100 SessionID::id_type RecentTabsBuilderTestHelper::GetSessionID(
    101     int session_index) {
    102   return sessions_[session_index].id;
    103 }
    104 
    105 base::Time RecentTabsBuilderTestHelper::GetSessionTimestamp(int session_index) {
    106   std::vector<base::Time> timestamps;
    107   for (int w = 0; w < GetWindowCount(session_index); ++w) {
    108     for (int t = 0; t < GetTabCount(session_index, w); ++t)
    109       timestamps.push_back(GetTabTimestamp(session_index, w, t));
    110   }
    111 
    112   if (timestamps.empty())
    113     return base::Time::Now();
    114 
    115   sort(timestamps.begin(), timestamps.end());
    116   return timestamps[0];
    117 }
    118 
    119 void RecentTabsBuilderTestHelper::AddWindow(int session_index) {
    120   WindowInfo window_info;
    121   window_info.id = CreateUniqueID();
    122   sessions_[session_index].windows.push_back(window_info);
    123 }
    124 
    125 int RecentTabsBuilderTestHelper::GetWindowCount(int session_index) {
    126   return sessions_[session_index].windows.size();
    127 }
    128 
    129 SessionID::id_type RecentTabsBuilderTestHelper::GetWindowID(int session_index,
    130                                                             int window_index) {
    131   return sessions_[session_index].windows[window_index].id;
    132 }
    133 
    134 void RecentTabsBuilderTestHelper::AddTab(int session_index, int window_index) {
    135   base::Time timestamp =
    136       start_time_ + base::TimeDelta::FromMinutes(base::RandUint64());
    137   AddTabWithInfo(session_index, window_index, timestamp, base::string16());
    138 }
    139 
    140 void RecentTabsBuilderTestHelper::AddTabWithInfo(int session_index,
    141                                                  int window_index,
    142                                                  base::Time timestamp,
    143                                                  const base::string16& title) {
    144   TabInfo tab_info;
    145   tab_info.id = CreateUniqueID();
    146   tab_info.timestamp = timestamp;
    147   tab_info.title = title;
    148   sessions_[session_index].windows[window_index].tabs.push_back(tab_info);
    149 }
    150 
    151 int RecentTabsBuilderTestHelper::GetTabCount(int session_index,
    152                                              int window_index) {
    153   return sessions_[session_index].windows[window_index].tabs.size();
    154 }
    155 
    156 SessionID::id_type RecentTabsBuilderTestHelper::GetTabID(int session_index,
    157                                                          int window_index,
    158                                                          int tab_index) {
    159   return sessions_[session_index].windows[window_index].tabs[tab_index].id;
    160 }
    161 
    162 base::Time RecentTabsBuilderTestHelper::GetTabTimestamp(int session_index,
    163                                                         int window_index,
    164                                                         int tab_index) {
    165   return sessions_[session_index].windows[window_index]
    166       .tabs[tab_index].timestamp;
    167 }
    168 
    169 base::string16 RecentTabsBuilderTestHelper::GetTabTitle(int session_index,
    170                                                         int window_index,
    171                                                         int tab_index) {
    172   base::string16 title =
    173       sessions_[session_index].windows[window_index].tabs[tab_index].title;
    174   if (title.empty()) {
    175     title = base::UTF8ToUTF16(ToTabTitle(
    176         GetSessionID(session_index),
    177         GetWindowID(session_index, window_index),
    178         GetTabID(session_index, window_index, tab_index)));
    179   }
    180   return title;
    181 }
    182 
    183 void RecentTabsBuilderTestHelper::ExportToSessionsSyncManager(
    184     browser_sync::SessionsSyncManager* manager) {
    185   syncer::SyncChangeList changes;
    186   for (int s = 0; s < GetSessionCount(); ++s) {
    187     sync_pb::EntitySpecifics session_entity;
    188     sync_pb::SessionSpecifics* meta = session_entity.mutable_session();
    189     BuildSessionSpecifics(s, meta);
    190     for (int w = 0; w < GetWindowCount(s); ++w) {
    191       BuildWindowSpecifics(s, w, meta);
    192       for (int t = 0; t < GetTabCount(s, w); ++t) {
    193         sync_pb::EntitySpecifics entity;
    194         sync_pb::SessionSpecifics* tab_base = entity.mutable_session();
    195         BuildTabSpecifics(s, w, t, tab_base);
    196         changes.push_back(syncer::SyncChange(
    197             FROM_HERE,
    198             syncer::SyncChange::ACTION_ADD,
    199             syncer::SyncData::CreateRemoteData(
    200                 tab_base->tab_node_id(),
    201                 entity,
    202                 GetTabTimestamp(s, w, t),
    203                 syncer::AttachmentIdList(),
    204                 syncer::AttachmentServiceProxyForTest::Create())));
    205       }
    206     }
    207     changes.push_back(syncer::SyncChange(
    208         FROM_HERE,
    209         syncer::SyncChange::ACTION_ADD,
    210         syncer::SyncData::CreateRemoteData(
    211             1,
    212             session_entity,
    213             GetSessionTimestamp(s),
    214             syncer::AttachmentIdList(),
    215             syncer::AttachmentServiceProxyForTest::Create())));
    216   }
    217   manager->ProcessSyncChanges(FROM_HERE, changes);
    218   VerifyExport(manager);
    219 }
    220 
    221 void RecentTabsBuilderTestHelper::VerifyExport(
    222     browser_sync::OpenTabsUIDelegate* delegate) {
    223   // Make sure data is populated correctly in SessionModelAssociator.
    224   std::vector<const browser_sync::SyncedSession*> sessions;
    225   ASSERT_TRUE(delegate->GetAllForeignSessions(&sessions));
    226   ASSERT_EQ(GetSessionCount(), static_cast<int>(sessions.size()));
    227   for (int s = 0; s < GetSessionCount(); ++s) {
    228     std::vector<const SessionWindow*> windows;
    229     ASSERT_TRUE(delegate->GetForeignSession(ToSessionTag(GetSessionID(s)),
    230                                             &windows));
    231     ASSERT_EQ(GetWindowCount(s), static_cast<int>(windows.size()));
    232     for (int w = 0; w < GetWindowCount(s); ++w)
    233       ASSERT_EQ(GetTabCount(s, w), static_cast<int>(windows[w]->tabs.size()));
    234   }
    235 }
    236 
    237 std::vector<base::string16>
    238 RecentTabsBuilderTestHelper::GetTabTitlesSortedByRecency() {
    239   std::vector<TitleTimestampPair> tabs;
    240   for (int s = 0; s < GetSessionCount(); ++s) {
    241     for (int w = 0; w < GetWindowCount(s); ++w) {
    242       for (int t = 0; t < GetTabCount(s, w); ++t) {
    243         TitleTimestampPair pair;
    244         pair.title = GetTabTitle(s, w, t);
    245         pair.timestamp = GetTabTimestamp(s, w, t);
    246         tabs.push_back(pair);
    247       }
    248     }
    249   }
    250   sort(tabs.begin(), tabs.end(), SortTabTimesByRecency);
    251 
    252   std::vector<base::string16> titles;
    253   for (size_t i = 0; i < tabs.size(); ++i)
    254     titles.push_back(tabs[i].title);
    255   return titles;
    256 }
    257 
    258 void RecentTabsBuilderTestHelper::BuildSessionSpecifics(
    259     int session_index,
    260     sync_pb::SessionSpecifics* meta) {
    261   SessionID::id_type session_id = GetSessionID(session_index);
    262   meta->set_session_tag(ToSessionTag(session_id));
    263   sync_pb::SessionHeader* header = meta->mutable_header();
    264   header->set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_CROS);
    265   header->set_client_name(ToSessionName(session_id));
    266 }
    267 
    268 void RecentTabsBuilderTestHelper::BuildWindowSpecifics(
    269     int session_index,
    270     int window_index,
    271     sync_pb::SessionSpecifics* meta) {
    272   sync_pb::SessionHeader* header = meta->mutable_header();
    273   sync_pb::SessionWindow* window = header->add_window();
    274   SessionID::id_type window_id = GetWindowID(session_index, window_index);
    275   window->set_window_id(window_id);
    276   window->set_selected_tab_index(0);
    277   window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
    278   for (int i = 0; i < GetTabCount(session_index, window_index); ++i)
    279     window->add_tab(GetTabID(session_index, window_index, i));
    280 }
    281 
    282 void RecentTabsBuilderTestHelper::BuildTabSpecifics(
    283     int session_index,
    284     int window_index,
    285     int tab_index,
    286     sync_pb::SessionSpecifics* tab_base) {
    287   SessionID::id_type session_id = GetSessionID(session_index);
    288   SessionID::id_type window_id = GetWindowID(session_index, window_index);
    289   SessionID::id_type tab_id = GetTabID(session_index, window_index, tab_index);
    290 
    291   tab_base->set_session_tag(ToSessionTag(session_id));
    292   tab_base->set_tab_node_id(++max_tab_node_id_);
    293   sync_pb::SessionTab* tab = tab_base->mutable_tab();
    294   tab->set_window_id(window_id);
    295   tab->set_tab_id(tab_id);
    296   tab->set_tab_visual_index(1);
    297   tab->set_current_navigation_index(0);
    298   tab->set_pinned(true);
    299   tab->set_extension_app_id("app_id");
    300   sync_pb::TabNavigation* navigation = tab->add_navigation();
    301   navigation->set_virtual_url(ToTabUrl(session_id, window_id, tab_id));
    302   navigation->set_referrer("referrer");
    303   navigation->set_title(base::UTF16ToUTF8(GetTabTitle(
    304       session_index, window_index, tab_index)));
    305   navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED);
    306 }
    307