| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/string_number_conversions.h" | |
| 11 #include "chrome/browser/sessions/session_types.h" | 10 #include "chrome/browser/sessions/session_types.h" |
| 12 #include "chrome/browser/sessions/session_types_test_helper.h" | 11 #include "chrome/browser/sessions/session_types_test_helper.h" |
| 13 #include "chrome/browser/sync/glue/session_model_associator.h" | 12 #include "chrome/browser/sync/glue/session_model_associator.h" |
| 14 #include "chrome/browser/sync/glue/synced_tab_delegate.h" | 13 #include "chrome/browser/sync/glue/synced_tab_delegate.h" |
| 15 #include "chrome/browser/sync/profile_sync_service_mock.h" | 14 #include "chrome/browser/sync/profile_sync_service_mock.h" |
| 16 #include "chrome/common/chrome_notification_types.h" | 15 #include "chrome/common/chrome_notification_types.h" |
| 17 #include "chrome/common/url_constants.h" | 16 #include "chrome/common/url_constants.h" |
| 18 #include "chrome/test/base/profile_mock.h" | 17 #include "chrome/test/base/profile_mock.h" |
| 19 #include "content/public/browser/navigation_entry.h" | 18 #include "content/public/browser/navigation_entry.h" |
| 20 #include "content/public/browser/notification_details.h" | 19 #include "content/public/browser/notification_details.h" |
| 21 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
| 22 #include "content/public/common/page_transition_types.h" | 21 #include "content/public/common/page_transition_types.h" |
| 23 #include "content/public/test/test_browser_thread.h" | 22 #include "content/public/test/test_browser_thread.h" |
| 23 #include "googleurl/src/gurl.h" |
| 24 #include "sync/protocol/session_specifics.pb.h" | 24 #include "sync/protocol/session_specifics.pb.h" |
| 25 #include "sync/util/time.h" | 25 #include "sync/util/time.h" |
| 26 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 28 |
| 29 using content::BrowserThread; | 29 using content::BrowserThread; |
| 30 using testing::NiceMock; | 30 using testing::NiceMock; |
| 31 using testing::Return; | 31 using testing::Return; |
| 32 using testing::StrictMock; |
| 32 using testing::_; | 33 using testing::_; |
| 33 | 34 |
| 34 namespace browser_sync { | 35 namespace browser_sync { |
| 35 | 36 |
| 36 class SyncSessionModelAssociatorTest : public testing::Test { | 37 class SyncSessionModelAssociatorTest : public testing::Test { |
| 37 public: | 38 protected: |
| 38 SyncSessionModelAssociatorTest() | 39 SyncSessionModelAssociatorTest() |
| 39 : ui_thread_(BrowserThread::UI, &message_loop_), | 40 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 40 sync_service_(&profile_), | 41 sync_service_(&profile_), |
| 41 model_associator_(&sync_service_, true) {} | 42 model_associator_(&sync_service_, true) {} |
| 42 | 43 |
| 43 // Helper methods to avoid having to friend individual tests. | 44 // Helper methods to avoid having to friend individual tests. |
| 44 bool GetFavicon(std::string page_url, std::string* favicon) { | 45 bool GetFavicon(std::string page_url, std::string* favicon) { |
| 45 return model_associator_.GetSyncedFaviconForPageURL(page_url, favicon); | 46 return model_associator_.GetSyncedFaviconForPageURL(page_url, favicon); |
| 46 } | 47 } |
| 47 | 48 |
| 48 void LoadTabFavicon(const sync_pb::SessionTab& tab) { | 49 void LoadTabFavicon(const sync_pb::SessionTab& tab) { |
| 49 model_associator_.LoadForeignTabFavicon(tab); | 50 model_associator_.LoadForeignTabFavicon(tab); |
| 50 } | 51 } |
| 51 | 52 |
| 52 size_t NumFavicons() { | 53 size_t NumFavicons() { |
| 53 return model_associator_.NumFaviconsForTesting(); | 54 return model_associator_.NumFaviconsForTesting(); |
| 54 } | 55 } |
| 55 | 56 |
| 56 void DecrementFavicon(std::string url) { | 57 void DecrementFavicon(std::string url) { |
| 57 model_associator_.DecrementAndCleanFaviconForURL(url); | 58 model_associator_.DecrementAndCleanFaviconForURL(url); |
| 58 } | 59 } |
| 59 | 60 |
| 60 void AssociateTabContents(const SyncedWindowDelegate& window, | 61 static GURL GetCurrentVirtualURL(const SyncedTabDelegate& tab_delegate) { |
| 61 const SyncedTabDelegate& new_tab, | 62 return SessionModelAssociator::GetCurrentVirtualURL(tab_delegate); |
| 62 SessionTab* prev_tab, | |
| 63 sync_pb::SessionTab* sync_tab, | |
| 64 GURL* new_url) { | |
| 65 model_associator_.AssociateTabContents(window, | |
| 66 new_tab, | |
| 67 prev_tab, | |
| 68 sync_tab, | |
| 69 new_url); | |
| 70 } | 63 } |
| 71 | 64 |
| 72 protected: | 65 static void UpdateSessionTabFromDelegate( |
| 66 const SyncedTabDelegate& tab_delegate, |
| 67 base::Time mtime, |
| 68 base::Time default_navigation_timestamp, |
| 69 SessionTab* session_tab) { |
| 70 SessionModelAssociator::UpdateSessionTabFromDelegate( |
| 71 tab_delegate, |
| 72 mtime, |
| 73 default_navigation_timestamp, |
| 74 session_tab); |
| 75 } |
| 76 |
| 77 private: |
| 73 MessageLoopForUI message_loop_; | 78 MessageLoopForUI message_loop_; |
| 74 content::TestBrowserThread ui_thread_; | 79 content::TestBrowserThread ui_thread_; |
| 75 NiceMock<ProfileMock> profile_; | 80 NiceMock<ProfileMock> profile_; |
| 76 NiceMock<ProfileSyncServiceMock> sync_service_; | 81 NiceMock<ProfileSyncServiceMock> sync_service_; |
| 82 |
| 83 protected: |
| 77 SessionModelAssociator model_associator_; | 84 SessionModelAssociator model_associator_; |
| 78 }; | 85 }; |
| 79 | 86 |
| 87 namespace { |
| 88 |
| 80 TEST_F(SyncSessionModelAssociatorTest, SessionWindowHasNoTabsToSync) { | 89 TEST_F(SyncSessionModelAssociatorTest, SessionWindowHasNoTabsToSync) { |
| 81 SessionWindow win; | 90 SessionWindow win; |
| 82 ASSERT_TRUE(SessionWindowHasNoTabsToSync(win)); | 91 ASSERT_TRUE(SessionWindowHasNoTabsToSync(win)); |
| 83 scoped_ptr<SessionTab> tab(new SessionTab()); | 92 scoped_ptr<SessionTab> tab(new SessionTab()); |
| 84 win.tabs.push_back(tab.release()); | 93 win.tabs.push_back(tab.release()); |
| 85 ASSERT_TRUE(SessionWindowHasNoTabsToSync(win)); | 94 ASSERT_TRUE(SessionWindowHasNoTabsToSync(win)); |
| 86 TabNavigation nav = | 95 TabNavigation nav = |
| 87 SessionTypesTestHelper::CreateNavigation("about:bubba", "title"); | 96 SessionTypesTestHelper::CreateNavigation("about:bubba", "title"); |
| 88 win.tabs[0]->navigations.push_back(nav); | 97 win.tabs[0]->navigations.push_back(nav); |
| 89 ASSERT_FALSE(SessionWindowHasNoTabsToSync(win)); | 98 ASSERT_FALSE(SessionWindowHasNoTabsToSync(win)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 110 SessionTab tab; | 119 SessionTab tab; |
| 111 ASSERT_FALSE(ShouldSyncSessionTab(tab)); | 120 ASSERT_FALSE(ShouldSyncSessionTab(tab)); |
| 112 TabNavigation nav = | 121 TabNavigation nav = |
| 113 SessionTypesTestHelper::CreateNavigation( | 122 SessionTypesTestHelper::CreateNavigation( |
| 114 std::string(chrome::kChromeUINewTabURL) + "#bookmarks", "title"); | 123 std::string(chrome::kChromeUINewTabURL) + "#bookmarks", "title"); |
| 115 tab.navigations.push_back(nav); | 124 tab.navigations.push_back(nav); |
| 116 // NewTab does not count as valid if it's the only navigation. | 125 // NewTab does not count as valid if it's the only navigation. |
| 117 ASSERT_FALSE(ShouldSyncSessionTab(tab)); | 126 ASSERT_FALSE(ShouldSyncSessionTab(tab)); |
| 118 } | 127 } |
| 119 | 128 |
| 129 } // namespace |
| 130 |
| 120 TEST_F(SyncSessionModelAssociatorTest, PopulateSessionHeader) { | 131 TEST_F(SyncSessionModelAssociatorTest, PopulateSessionHeader) { |
| 121 sync_pb::SessionHeader header_s; | 132 sync_pb::SessionHeader header_s; |
| 122 header_s.set_client_name("Client 1"); | 133 header_s.set_client_name("Client 1"); |
| 123 header_s.set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_WIN); | 134 header_s.set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_WIN); |
| 124 | 135 |
| 125 SyncedSession session; | 136 SyncedSession session; |
| 126 base::Time time = base::Time::Now(); | 137 base::Time time = base::Time::Now(); |
| 127 SessionModelAssociator::PopulateSessionHeaderFromSpecifics( | 138 SessionModelAssociator::PopulateSessionHeaderFromSpecifics( |
| 128 header_s, time, &session); | 139 header_s, time, &session); |
| 129 ASSERT_EQ("Client 1", session.session_name); | 140 ASSERT_EQ("Client 1", session.session_name); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 143 tracker.PutWindowInSession(tag, 0); | 154 tracker.PutWindowInSession(tag, 0); |
| 144 SessionModelAssociator::PopulateSessionWindowFromSpecifics( | 155 SessionModelAssociator::PopulateSessionWindowFromSpecifics( |
| 145 tag, window_s, base::Time(), session->windows[0], &tracker); | 156 tag, window_s, base::Time(), session->windows[0], &tracker); |
| 146 ASSERT_EQ(1U, session->windows[0]->tabs.size()); | 157 ASSERT_EQ(1U, session->windows[0]->tabs.size()); |
| 147 ASSERT_EQ(1, session->windows[0]->selected_tab_index); | 158 ASSERT_EQ(1, session->windows[0]->selected_tab_index); |
| 148 ASSERT_EQ(1, session->windows[0]->type); | 159 ASSERT_EQ(1, session->windows[0]->type); |
| 149 ASSERT_EQ(1U, tracker.num_synced_sessions()); | 160 ASSERT_EQ(1U, tracker.num_synced_sessions()); |
| 150 ASSERT_EQ(1U, tracker.num_synced_tabs(std::string("tag"))); | 161 ASSERT_EQ(1U, tracker.num_synced_tabs(std::string("tag"))); |
| 151 } | 162 } |
| 152 | 163 |
| 153 TEST_F(SyncSessionModelAssociatorTest, PopulateSessionTab) { | |
| 154 sync_pb::SessionTab tab_s; | |
| 155 tab_s.set_tab_id(5); | |
| 156 tab_s.set_tab_visual_index(13); | |
| 157 tab_s.set_current_navigation_index(3); | |
| 158 tab_s.set_pinned(true); | |
| 159 tab_s.set_extension_app_id("app_id"); | |
| 160 for (int i = 0; i < 5; ++i) { | |
| 161 sync_pb::TabNavigation* navigation = tab_s.add_navigation(); | |
| 162 navigation->set_virtual_url("http://foo/" + base::IntToString(i)); | |
| 163 navigation->set_referrer("referrer"); | |
| 164 navigation->set_title("title"); | |
| 165 navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED); | |
| 166 } | |
| 167 | |
| 168 SessionTab tab; | |
| 169 tab.tab_id.set_id(5); // Expected to be set by the SyncedSessionTracker. | |
| 170 SessionModelAssociator::PopulateSessionTabFromSpecifics( | |
| 171 tab_s, base::Time(), &tab); | |
| 172 ASSERT_EQ(5, tab.tab_id.id()); | |
| 173 ASSERT_EQ(13, tab.tab_visual_index); | |
| 174 ASSERT_EQ(3, tab.current_navigation_index); | |
| 175 ASSERT_TRUE(tab.pinned); | |
| 176 ASSERT_EQ("app_id", tab.extension_app_id); | |
| 177 ASSERT_EQ(5u, tab.navigations.size()); | |
| 178 for (int i = 0; i < 5; ++i) { | |
| 179 ASSERT_EQ(i, tab.navigations[i].index()); | |
| 180 ASSERT_EQ(GURL("referrer"), | |
| 181 SessionTypesTestHelper::GetReferrer(tab.navigations[i]).url); | |
| 182 ASSERT_EQ(string16(ASCIIToUTF16("title")), tab.navigations[i].title()); | |
| 183 ASSERT_EQ(content::PAGE_TRANSITION_TYPED, | |
| 184 SessionTypesTestHelper::GetTransitionType(tab.navigations[i])); | |
| 185 ASSERT_EQ(GURL("http://foo/" + base::IntToString(i)), | |
| 186 tab.navigations[i].virtual_url()); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 TEST_F(SyncSessionModelAssociatorTest, TabNodePool) { | 164 TEST_F(SyncSessionModelAssociatorTest, TabNodePool) { |
| 191 SessionModelAssociator::TabNodePool pool(NULL); | 165 SessionModelAssociator::TabNodePool pool(NULL); |
| 192 pool.set_machine_tag("tag"); | 166 pool.set_machine_tag("tag"); |
| 193 ASSERT_TRUE(pool.empty()); | 167 ASSERT_TRUE(pool.empty()); |
| 194 ASSERT_TRUE(pool.full()); | 168 ASSERT_TRUE(pool.full()); |
| 195 ASSERT_EQ(0U, pool.capacity()); | 169 ASSERT_EQ(0U, pool.capacity()); |
| 196 pool.AddTabNode(5); | 170 pool.AddTabNode(5); |
| 197 pool.AddTabNode(10); | 171 pool.AddTabNode(10); |
| 198 ASSERT_FALSE(pool.empty()); | 172 ASSERT_FALSE(pool.empty()); |
| 199 ASSERT_TRUE(pool.full()); | 173 ASSERT_TRUE(pool.full()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 230 ASSERT_TRUE(pool.full()); | 204 ASSERT_TRUE(pool.full()); |
| 231 ASSERT_EQ(2U, pool.capacity()); | 205 ASSERT_EQ(2U, pool.capacity()); |
| 232 pool.clear(); | 206 pool.clear(); |
| 233 ASSERT_TRUE(pool.empty()); | 207 ASSERT_TRUE(pool.empty()); |
| 234 ASSERT_TRUE(pool.full()); | 208 ASSERT_TRUE(pool.full()); |
| 235 ASSERT_EQ(0U, pool.capacity()); | 209 ASSERT_EQ(0U, pool.capacity()); |
| 236 } | 210 } |
| 237 | 211 |
| 238 namespace { | 212 namespace { |
| 239 | 213 |
| 240 class SyncedWindowDelegateMock : public SyncedWindowDelegate { | |
| 241 public: | |
| 242 SyncedWindowDelegateMock() {} | |
| 243 virtual ~SyncedWindowDelegateMock() {} | |
| 244 MOCK_CONST_METHOD0(HasWindow, bool()); | |
| 245 MOCK_CONST_METHOD0(GetSessionId, SessionID::id_type()); | |
| 246 MOCK_CONST_METHOD0(GetTabCount, int()); | |
| 247 MOCK_CONST_METHOD0(GetActiveIndex, int()); | |
| 248 MOCK_CONST_METHOD0(IsApp, bool()); | |
| 249 MOCK_CONST_METHOD0(IsTypeTabbed, bool()); | |
| 250 MOCK_CONST_METHOD0(IsTypePopup, bool()); | |
| 251 MOCK_CONST_METHOD1(IsTabPinned, bool(const SyncedTabDelegate* tab)); | |
| 252 MOCK_CONST_METHOD1(GetTabAt, SyncedTabDelegate*(int index)); | |
| 253 MOCK_CONST_METHOD1(GetTabIdAt, SessionID::id_type(int index)); | |
| 254 MOCK_CONST_METHOD0(IsSessionRestoreInProgress, bool()); | |
| 255 }; | |
| 256 | |
| 257 class SyncedTabDelegateMock : public SyncedTabDelegate { | 214 class SyncedTabDelegateMock : public SyncedTabDelegate { |
| 258 public: | 215 public: |
| 259 SyncedTabDelegateMock() {} | 216 SyncedTabDelegateMock() {} |
| 260 virtual ~SyncedTabDelegateMock() {} | 217 virtual ~SyncedTabDelegateMock() {} |
| 261 | 218 |
| 262 MOCK_CONST_METHOD0(GetWindowId, SessionID::id_type()); | 219 MOCK_CONST_METHOD0(GetWindowId, SessionID::id_type()); |
| 263 MOCK_CONST_METHOD0(GetSessionId, SessionID::id_type()); | 220 MOCK_CONST_METHOD0(GetSessionId, SessionID::id_type()); |
| 264 MOCK_CONST_METHOD0(IsBeingDestroyed, bool()); | 221 MOCK_CONST_METHOD0(IsBeingDestroyed, bool()); |
| 265 MOCK_CONST_METHOD0(profile, Profile*()); | 222 MOCK_CONST_METHOD0(profile, Profile*()); |
| 266 MOCK_CONST_METHOD0(HasExtensionAppId, bool()); | 223 MOCK_CONST_METHOD0(GetExtensionAppId, std::string()); |
| 267 MOCK_CONST_METHOD0(GetExtensionAppId, const std::string&()); | |
| 268 MOCK_CONST_METHOD0(GetCurrentEntryIndex, int()); | 224 MOCK_CONST_METHOD0(GetCurrentEntryIndex, int()); |
| 269 MOCK_CONST_METHOD0(GetEntryCount, int()); | 225 MOCK_CONST_METHOD0(GetEntryCount, int()); |
| 270 MOCK_CONST_METHOD0(GetPendingEntryIndex, int()); | 226 MOCK_CONST_METHOD0(GetPendingEntryIndex, int()); |
| 271 MOCK_CONST_METHOD0(GetPendingEntry, content::NavigationEntry*()); | 227 MOCK_CONST_METHOD0(GetPendingEntry, content::NavigationEntry*()); |
| 272 MOCK_CONST_METHOD1(GetEntryAtIndex, content::NavigationEntry*(int i)); | 228 MOCK_CONST_METHOD1(GetEntryAtIndex, content::NavigationEntry*(int i)); |
| 273 MOCK_CONST_METHOD0(GetActiveEntry, content::NavigationEntry*()); | 229 MOCK_CONST_METHOD0(GetActiveEntry, content::NavigationEntry*()); |
| 230 MOCK_CONST_METHOD0(IsPinned, bool()); |
| 274 }; | 231 }; |
| 275 | 232 |
| 276 class SyncRefreshListener : public content::NotificationObserver { | 233 class SyncRefreshListener : public content::NotificationObserver { |
| 277 public: | 234 public: |
| 278 SyncRefreshListener() : notified_of_refresh_(false) { | 235 SyncRefreshListener() : notified_of_refresh_(false) { |
| 279 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | 236 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
| 280 content::NotificationService::AllSources()); | 237 content::NotificationService::AllSources()); |
| 281 } | 238 } |
| 282 | 239 |
| 283 void Observe(int type, | 240 void Observe(int type, |
| 284 const content::NotificationSource& source, | 241 const content::NotificationSource& source, |
| 285 const content::NotificationDetails& details) { | 242 const content::NotificationDetails& details) { |
| 286 if (type == chrome::NOTIFICATION_SYNC_REFRESH_LOCAL) { | 243 if (type == chrome::NOTIFICATION_SYNC_REFRESH_LOCAL) { |
| 287 notified_of_refresh_ = true; | 244 notified_of_refresh_ = true; |
| 288 } | 245 } |
| 289 } | 246 } |
| 290 | 247 |
| 291 bool notified_of_refresh() const { return notified_of_refresh_; } | 248 bool notified_of_refresh() const { return notified_of_refresh_; } |
| 292 | 249 |
| 293 private: | 250 private: |
| 294 bool notified_of_refresh_; | 251 bool notified_of_refresh_; |
| 295 content::NotificationRegistrar registrar_; | 252 content::NotificationRegistrar registrar_; |
| 296 }; | 253 }; |
| 297 | 254 |
| 298 } // namespace. | |
| 299 | |
| 300 // Test that AttemptSessionsDataRefresh() triggers the | 255 // Test that AttemptSessionsDataRefresh() triggers the |
| 301 // NOTIFICATION_SYNC_REFRESH_LOCAL notification. | 256 // NOTIFICATION_SYNC_REFRESH_LOCAL notification. |
| 302 TEST_F(SyncSessionModelAssociatorTest, TriggerSessionRefresh) { | 257 TEST_F(SyncSessionModelAssociatorTest, TriggerSessionRefresh) { |
| 303 SyncRefreshListener refresh_listener; | 258 SyncRefreshListener refresh_listener; |
| 304 | 259 |
| 305 EXPECT_FALSE(refresh_listener.notified_of_refresh()); | 260 EXPECT_FALSE(refresh_listener.notified_of_refresh()); |
| 306 model_associator_.AttemptSessionsDataRefresh(); | 261 model_associator_.AttemptSessionsDataRefresh(); |
| 307 EXPECT_TRUE(refresh_listener.notified_of_refresh()); | 262 EXPECT_TRUE(refresh_listener.notified_of_refresh()); |
| 308 } | 263 } |
| 309 | 264 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 synced_favicon.clear(); | 510 synced_favicon.clear(); |
| 556 EXPECT_FALSE(GetFavicon(page_url, &synced_favicon)); | 511 EXPECT_FALSE(GetFavicon(page_url, &synced_favicon)); |
| 557 EXPECT_TRUE(synced_favicon.empty()); | 512 EXPECT_TRUE(synced_favicon.empty()); |
| 558 EXPECT_EQ(0U, NumFavicons()); | 513 EXPECT_EQ(0U, NumFavicons()); |
| 559 synced_favicon.clear(); | 514 synced_favicon.clear(); |
| 560 EXPECT_FALSE(GetFavicon(page_url2, &synced_favicon)); | 515 EXPECT_FALSE(GetFavicon(page_url2, &synced_favicon)); |
| 561 EXPECT_TRUE(synced_favicon.empty()); | 516 EXPECT_TRUE(synced_favicon.empty()); |
| 562 EXPECT_EQ(0U, NumFavicons()); | 517 EXPECT_EQ(0U, NumFavicons()); |
| 563 } | 518 } |
| 564 | 519 |
| 565 // Ensure new tabs have the current timestamp set for the current navigation, | 520 // TODO(akalin): We should really use a fake for SyncedTabDelegate. |
| 566 // while other navigations have timestamp zero. | |
| 567 TEST_F(SyncSessionModelAssociatorTest, AssociateNewTab) { | |
| 568 NiceMock<SyncedWindowDelegateMock> window_mock; | |
| 569 EXPECT_CALL(window_mock, IsTabPinned(_)).WillRepeatedly(Return(false)); | |
| 570 | 521 |
| 522 // Make sure GetCurrentVirtualURL() returns the virtual URL of the pending |
| 523 // entry if the current entry is pending. |
| 524 TEST_F(SyncSessionModelAssociatorTest, GetCurrentVirtualURLPending) { |
| 525 StrictMock<SyncedTabDelegateMock> tab_mock; |
| 526 scoped_ptr<content::NavigationEntry> entry( |
| 527 content::NavigationEntry::Create()); |
| 528 entry->SetVirtualURL(GURL("http://www.google.com")); |
| 529 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillOnce(Return(0)); |
| 530 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillOnce(Return(0)); |
| 531 EXPECT_CALL(tab_mock, GetPendingEntry()).WillOnce(Return(entry.get())); |
| 532 EXPECT_EQ(entry->GetVirtualURL(), GetCurrentVirtualURL(tab_mock)); |
| 533 } |
| 534 |
| 535 // Make sure GetCurrentVirtualURL() returns the virtual URL of the current |
| 536 // entry if the current entry is non-pending. |
| 537 TEST_F(SyncSessionModelAssociatorTest, GetCurrentVirtualURLNonPending) { |
| 538 StrictMock<SyncedTabDelegateMock> tab_mock; |
| 539 scoped_ptr<content::NavigationEntry> entry( |
| 540 content::NavigationEntry::Create()); |
| 541 entry->SetVirtualURL(GURL("http://www.google.com")); |
| 542 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillOnce(Return(0)); |
| 543 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillOnce(Return(-1)); |
| 544 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillOnce(Return(entry.get())); |
| 545 EXPECT_EQ(entry->GetVirtualURL(), GetCurrentVirtualURL(tab_mock)); |
| 546 } |
| 547 |
| 548 const base::Time kTime1 = base::Time::FromInternalValue(100); |
| 549 const base::Time kTime2 = base::Time::FromInternalValue(105); |
| 550 const base::Time kTime3 = base::Time::FromInternalValue(110); |
| 551 const base::Time kTime4 = base::Time::FromInternalValue(120); |
| 552 const base::Time kTime5 = base::Time::FromInternalValue(150); |
| 553 const base::Time kTime6 = base::Time::FromInternalValue(200); |
| 554 const base::Time kTime7 = base::Time::FromInternalValue(500); |
| 555 const base::Time kTime8 = base::Time::FromInternalValue(1000); |
| 556 |
| 557 // Ensure new tabs have the current timestamp set for the current |
| 558 // navigation, while other navigations have null timestamps. |
| 559 TEST_F(SyncSessionModelAssociatorTest, UpdateNewTab) { |
| 571 // Create a tab with three valid entries. | 560 // Create a tab with three valid entries. |
| 572 NiceMock<SyncedTabDelegateMock> tab_mock; | 561 NiceMock<SyncedTabDelegateMock> tab_mock; |
| 573 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); | 562 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); |
| 574 scoped_ptr<content::NavigationEntry> entry1( | 563 scoped_ptr<content::NavigationEntry> entry1( |
| 575 content::NavigationEntry::Create()); | 564 content::NavigationEntry::Create()); |
| 576 entry1->SetVirtualURL(GURL("http://www.google.com")); | 565 entry1->SetVirtualURL(GURL("http://www.google.com")); |
| 577 scoped_ptr<content::NavigationEntry> entry2( | 566 scoped_ptr<content::NavigationEntry> entry2( |
| 578 content::NavigationEntry::Create()); | 567 content::NavigationEntry::Create()); |
| 579 entry2->SetVirtualURL(GURL("http://www.noodle.com")); | 568 entry2->SetVirtualURL(GURL("http://www.noodle.com")); |
| 580 scoped_ptr<content::NavigationEntry> entry3( | 569 scoped_ptr<content::NavigationEntry> entry3( |
| 581 content::NavigationEntry::Create()); | 570 content::NavigationEntry::Create()); |
| 582 entry3->SetVirtualURL(GURL("http://www.doodle.com")); | 571 entry3->SetVirtualURL(GURL("http://www.doodle.com")); |
| 583 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); | 572 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); |
| 584 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( | 573 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( |
| 585 Return(entry1.get())); | 574 Return(entry1.get())); |
| 586 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( | 575 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( |
| 587 Return(entry2.get())); | 576 Return(entry2.get())); |
| 588 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( | 577 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( |
| 589 Return(entry3.get())); | 578 Return(entry3.get())); |
| 590 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); | 579 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); |
| 591 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); | 580 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); |
| 592 | 581 |
| 593 // This tab is new, so prev_tab is the default SyncedSessionTab object. | 582 SessionTab session_tab; |
| 594 SessionTab prev_tab; | 583 UpdateSessionTabFromDelegate(tab_mock, kTime1, kTime2, &session_tab); |
| 595 prev_tab.tab_id.set_id(0); | |
| 596 | 584 |
| 597 sync_pb::SessionTab sync_tab; | 585 EXPECT_EQ(0, session_tab.window_id.id()); |
| 598 GURL new_url; | 586 EXPECT_EQ(0, session_tab.tab_id.id()); |
| 599 int64 now = syncer::TimeToProtoTime(base::Time::Now()); | 587 EXPECT_EQ(0, session_tab.tab_visual_index); |
| 600 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | 588 EXPECT_EQ(2, session_tab.current_navigation_index); |
| 601 | 589 EXPECT_FALSE(session_tab.pinned); |
| 602 EXPECT_EQ(new_url, entry3->GetVirtualURL()); | 590 EXPECT_TRUE(session_tab.extension_app_id.empty()); |
| 603 ASSERT_EQ(3, sync_tab.navigation_size()); | 591 EXPECT_TRUE(session_tab.user_agent_override.empty()); |
| 604 EXPECT_EQ(entry1->GetVirtualURL().spec(), | 592 EXPECT_EQ(kTime1, session_tab.timestamp); |
| 605 sync_tab.navigation(0).virtual_url()); | 593 ASSERT_EQ(3u, session_tab.navigations.size()); |
| 606 EXPECT_EQ(entry2->GetVirtualURL().spec(), | 594 EXPECT_EQ(entry1->GetVirtualURL(), |
| 607 sync_tab.navigation(1).virtual_url()); | 595 session_tab.navigations[0].virtual_url()); |
| 608 EXPECT_EQ(entry3->GetVirtualURL().spec(), | 596 EXPECT_EQ(entry2->GetVirtualURL(), |
| 609 sync_tab.navigation(2).virtual_url()); | 597 session_tab.navigations[1].virtual_url()); |
| 610 EXPECT_EQ(2, sync_tab.current_navigation_index()); | 598 EXPECT_EQ(entry3->GetVirtualURL(), |
| 611 EXPECT_LE(0, sync_tab.navigation(0).timestamp()); | 599 session_tab.navigations[2].virtual_url()); |
| 612 EXPECT_LE(0, sync_tab.navigation(1).timestamp()); | 600 EXPECT_EQ(2, session_tab.current_navigation_index); |
| 613 EXPECT_LE(now, sync_tab.navigation(2).timestamp()); | 601 EXPECT_TRUE(session_tab.navigations[0].timestamp().is_null()); |
| 602 EXPECT_TRUE(session_tab.navigations[1].timestamp().is_null()); |
| 603 EXPECT_EQ(kTime2, session_tab.navigations[2].timestamp()); |
| 604 EXPECT_TRUE(session_tab.session_storage_persistent_id.empty()); |
| 614 } | 605 } |
| 615 | 606 |
| 616 // Ensure we preserve old timestamps when the entries don't change. | 607 // Ensure we preserve old timestamps when the entries don't change. |
| 617 TEST_F(SyncSessionModelAssociatorTest, AssociateExistingTab) { | 608 TEST_F(SyncSessionModelAssociatorTest, UpdateExistingTab) { |
| 618 NiceMock<SyncedWindowDelegateMock> window_mock; | |
| 619 EXPECT_CALL(window_mock, IsTabPinned(_)).WillRepeatedly(Return(false)); | |
| 620 | |
| 621 // Create a tab with three valid entries. | 609 // Create a tab with three valid entries. |
| 622 NiceMock<SyncedTabDelegateMock> tab_mock; | 610 NiceMock<SyncedTabDelegateMock> tab_mock; |
| 623 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); | 611 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); |
| 624 scoped_ptr<content::NavigationEntry> entry1( | 612 scoped_ptr<content::NavigationEntry> entry1( |
| 625 content::NavigationEntry::Create()); | 613 content::NavigationEntry::Create()); |
| 626 entry1->SetVirtualURL(GURL("http://www.google.com")); | 614 entry1->SetVirtualURL(GURL("http://www.google.com")); |
| 627 scoped_ptr<content::NavigationEntry> entry2( | 615 scoped_ptr<content::NavigationEntry> entry2( |
| 628 content::NavigationEntry::Create()); | 616 content::NavigationEntry::Create()); |
| 629 entry2->SetVirtualURL(GURL("http://www.noodle.com")); | 617 entry2->SetVirtualURL(GURL("http://www.noodle.com")); |
| 630 scoped_ptr<content::NavigationEntry> entry3( | 618 scoped_ptr<content::NavigationEntry> entry3( |
| 631 content::NavigationEntry::Create()); | 619 content::NavigationEntry::Create()); |
| 632 entry3->SetVirtualURL(GURL("http://www.doodle.com")); | 620 entry3->SetVirtualURL(GURL("http://www.doodle.com")); |
| 633 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); | 621 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); |
| 634 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( | 622 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( |
| 635 Return(entry1.get())); | 623 Return(entry1.get())); |
| 636 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( | 624 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( |
| 637 Return(entry2.get())); | 625 Return(entry2.get())); |
| 638 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( | 626 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( |
| 639 Return(entry3.get())); | 627 Return(entry3.get())); |
| 640 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); | 628 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); |
| 641 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); | 629 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); |
| 630 EXPECT_CALL(tab_mock, IsPinned()).WillRepeatedly(Return(true)); |
| 642 | 631 |
| 643 // This tab is new, so prev_tab is the default SyncedSessionTab object. | 632 // The initial UpdateSessionTabFromDelegate call builds the session_tab. |
| 644 SessionTab prev_tab; | 633 SessionTab session_tab; |
| 645 prev_tab.tab_id.set_id(0); | 634 UpdateSessionTabFromDelegate(tab_mock, kTime1, kTime2, &session_tab); |
| 646 | 635 |
| 647 // The initial AssociateTabContents call builds the prev_tab. | 636 // Tweak the timestamps a bit. |
| 648 sync_pb::SessionTab sync_tab; | 637 ASSERT_EQ(3u, session_tab.navigations.size()); |
| 649 GURL new_url; | 638 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[0], kTime3); |
| 650 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | 639 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[1], kTime4); |
| 651 | 640 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[2], kTime5); |
| 652 ASSERT_EQ(3u, prev_tab.navigations.size()); | |
| 653 | 641 |
| 654 // Now re-associate with the same data. | 642 // Now re-associate with the same data. |
| 655 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | 643 UpdateSessionTabFromDelegate(tab_mock, kTime3, kTime4, &session_tab); |
| 656 | 644 |
| 657 EXPECT_EQ(new_url, entry3->GetVirtualURL()); | 645 EXPECT_TRUE(session_tab.pinned); |
| 658 ASSERT_EQ(3, sync_tab.navigation_size()); | 646 EXPECT_EQ(kTime3, session_tab.timestamp); |
| 659 EXPECT_EQ(entry1->GetVirtualURL().spec(), | 647 EXPECT_EQ(entry1->GetVirtualURL(), |
| 660 sync_tab.navigation(0).virtual_url()); | 648 session_tab.navigations[0].virtual_url()); |
| 661 EXPECT_EQ(entry2->GetVirtualURL().spec(), | 649 EXPECT_EQ(entry2->GetVirtualURL(), |
| 662 sync_tab.navigation(1).virtual_url()); | 650 session_tab.navigations[1].virtual_url()); |
| 663 EXPECT_EQ(entry3->GetVirtualURL().spec(), | 651 EXPECT_EQ(entry3->GetVirtualURL(), |
| 664 sync_tab.navigation(2).virtual_url()); | 652 session_tab.navigations[2].virtual_url()); |
| 665 EXPECT_EQ(2, sync_tab.current_navigation_index()); | 653 EXPECT_EQ(2, session_tab.current_navigation_index); |
| 666 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), | 654 EXPECT_EQ(kTime3, session_tab.navigations[0].timestamp()); |
| 667 sync_tab.navigation(0).timestamp()); | 655 EXPECT_EQ(kTime4, session_tab.navigations[1].timestamp()); |
| 668 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[1].timestamp()), | 656 EXPECT_EQ(kTime5, session_tab.navigations[2].timestamp()); |
| 669 sync_tab.navigation(1).timestamp()); | |
| 670 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[2].timestamp()), | |
| 671 sync_tab.navigation(2).timestamp()); | |
| 672 EXPECT_EQ(3U, prev_tab.navigations.size()); | |
| 673 } | 657 } |
| 674 | 658 |
| 675 // Ensure we add a fresh timestamp for new entries appended to the end. | 659 // Ensure we add a fresh timestamp for new entries appended to the end. |
| 676 TEST_F(SyncSessionModelAssociatorTest, AssociateAppendedTab) { | 660 TEST_F(SyncSessionModelAssociatorTest, UpdateAppendedTab) { |
| 677 NiceMock<SyncedWindowDelegateMock> window_mock; | |
| 678 EXPECT_CALL(window_mock, IsTabPinned(_)).WillRepeatedly(Return(false)); | |
| 679 | |
| 680 // Create a tab with three valid entries. | 661 // Create a tab with three valid entries. |
| 681 NiceMock<SyncedTabDelegateMock> tab_mock; | 662 NiceMock<SyncedTabDelegateMock> tab_mock; |
| 682 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); | 663 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); |
| 683 scoped_ptr<content::NavigationEntry> entry1( | 664 scoped_ptr<content::NavigationEntry> entry1( |
| 684 content::NavigationEntry::Create()); | 665 content::NavigationEntry::Create()); |
| 685 entry1->SetVirtualURL(GURL("http://www.google.com")); | 666 entry1->SetVirtualURL(GURL("http://www.google.com")); |
| 686 scoped_ptr<content::NavigationEntry> entry2( | 667 scoped_ptr<content::NavigationEntry> entry2( |
| 687 content::NavigationEntry::Create()); | 668 content::NavigationEntry::Create()); |
| 688 entry2->SetVirtualURL(GURL("http://www.noodle.com")); | 669 entry2->SetVirtualURL(GURL("http://www.noodle.com")); |
| 689 scoped_ptr<content::NavigationEntry> entry3( | 670 scoped_ptr<content::NavigationEntry> entry3( |
| 690 content::NavigationEntry::Create()); | 671 content::NavigationEntry::Create()); |
| 691 entry3->SetVirtualURL(GURL("http://www.doodle.com")); | 672 entry3->SetVirtualURL(GURL("http://www.doodle.com")); |
| 692 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); | 673 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(2)); |
| 693 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( | 674 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( |
| 694 Return(entry1.get())); | 675 Return(entry1.get())); |
| 695 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( | 676 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( |
| 696 Return(entry2.get())); | 677 Return(entry2.get())); |
| 697 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( | 678 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( |
| 698 Return(entry3.get())); | 679 Return(entry3.get())); |
| 699 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); | 680 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); |
| 700 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); | 681 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); |
| 701 | 682 |
| 702 // This tab is new, so prev_tab is the default SyncedSessionTab object. | 683 // The initial UpdateSessionTabFromDelegate call builds the session_tab. |
| 703 SessionTab prev_tab; | 684 SessionTab session_tab; |
| 704 prev_tab.tab_id.set_id(0); | 685 UpdateSessionTabFromDelegate(tab_mock, kTime1, kTime2, &session_tab); |
| 705 | |
| 706 // The initial AssociateTabContents call builds the prev_tab. | |
| 707 sync_pb::SessionTab sync_tab; | |
| 708 GURL new_url; | |
| 709 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | |
| 710 | |
| 711 ASSERT_EQ(3u, prev_tab.navigations.size()); | |
| 712 | 686 |
| 713 // Add a new entry and change the current navigation index. | 687 // Add a new entry and change the current navigation index. |
| 714 scoped_ptr<content::NavigationEntry> entry4( | 688 scoped_ptr<content::NavigationEntry> entry4( |
| 715 content::NavigationEntry::Create()); | 689 content::NavigationEntry::Create()); |
| 716 entry4->SetVirtualURL(GURL("http://www.poodle.com")); | 690 entry4->SetVirtualURL(GURL("http://www.poodle.com")); |
| 717 EXPECT_CALL(tab_mock, GetEntryAtIndex(3)).WillRepeatedly( | 691 EXPECT_CALL(tab_mock, GetEntryAtIndex(3)).WillRepeatedly( |
| 718 Return(entry4.get())); | 692 Return(entry4.get())); |
| 719 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(4)); | 693 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(4)); |
| 720 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(3)); | 694 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(3)); |
| 721 | 695 |
| 722 // The new entry should have a timestamp later than this. | 696 // Now re-associate with the new version. |
| 723 int64 now = syncer::TimeToProtoTime(base::Time::Now()); | 697 UpdateSessionTabFromDelegate(tab_mock, kTime3, kTime4, &session_tab); |
| 724 | 698 |
| 725 // Now re-associate with the new version. | 699 ASSERT_EQ(4u, session_tab.navigations.size()); |
| 726 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | 700 EXPECT_EQ(entry1->GetVirtualURL(), |
| 727 | 701 session_tab.navigations[0].virtual_url()); |
| 728 EXPECT_EQ(new_url, entry4->GetVirtualURL()); | 702 EXPECT_EQ(entry2->GetVirtualURL(), |
| 729 ASSERT_EQ(4, sync_tab.navigation_size()); | 703 session_tab.navigations[1].virtual_url()); |
| 730 EXPECT_EQ(entry1->GetVirtualURL().spec(), | 704 EXPECT_EQ(entry3->GetVirtualURL(), |
| 731 sync_tab.navigation(0).virtual_url()); | 705 session_tab.navigations[2].virtual_url()); |
| 732 EXPECT_EQ(entry2->GetVirtualURL().spec(), | 706 EXPECT_EQ(entry4->GetVirtualURL(), |
| 733 sync_tab.navigation(1).virtual_url()); | 707 session_tab.navigations[3].virtual_url()); |
| 734 EXPECT_EQ(entry3->GetVirtualURL().spec(), | 708 EXPECT_EQ(3, session_tab.current_navigation_index); |
| 735 sync_tab.navigation(2).virtual_url()); | 709 EXPECT_TRUE(session_tab.navigations[0].timestamp().is_null()); |
| 736 EXPECT_EQ(entry4->GetVirtualURL().spec(), | 710 EXPECT_TRUE(session_tab.navigations[1].timestamp().is_null()); |
| 737 sync_tab.navigation(3).virtual_url()); | 711 EXPECT_EQ(kTime2, session_tab.navigations[2].timestamp()); |
| 738 EXPECT_EQ(3, sync_tab.current_navigation_index()); | 712 EXPECT_EQ(kTime4, session_tab.navigations[3].timestamp()); |
| 739 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), | |
| 740 sync_tab.navigation(0).timestamp()); | |
| 741 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[1].timestamp()), | |
| 742 sync_tab.navigation(1).timestamp()); | |
| 743 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[2].timestamp()), | |
| 744 sync_tab.navigation(2).timestamp()); | |
| 745 EXPECT_LE(now, sync_tab.navigation(3).timestamp()); | |
| 746 EXPECT_EQ(4U, prev_tab.navigations.size()); | |
| 747 } | 713 } |
| 748 | 714 |
| 749 // We shouldn't get confused when old/new entries from the previous tab have | 715 // We shouldn't get confused when old/new entries from the previous tab have |
| 750 // been pruned in the new tab. Timestamps for old entries we move back to in the | 716 // been pruned in the new tab. Timestamps for old entries we move back to in the |
| 751 // navigation stack should be refreshed. | 717 // navigation stack should be refreshed. |
| 752 TEST_F(SyncSessionModelAssociatorTest, AssociatePrunedTab) { | 718 TEST_F(SyncSessionModelAssociatorTest, UpdatePrunedTab) { |
| 753 NiceMock<SyncedWindowDelegateMock> window_mock; | |
| 754 EXPECT_CALL(window_mock, IsTabPinned(_)).WillRepeatedly(Return(false)); | |
| 755 | |
| 756 // Create a tab with four valid entries. | 719 // Create a tab with four valid entries. |
| 757 NiceMock<SyncedTabDelegateMock> tab_mock; | 720 NiceMock<SyncedTabDelegateMock> tab_mock; |
| 758 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); | 721 EXPECT_CALL(tab_mock, GetSessionId()).WillRepeatedly(Return(0)); |
| 759 scoped_ptr<content::NavigationEntry> entry1( | 722 scoped_ptr<content::NavigationEntry> entry1( |
| 760 content::NavigationEntry::Create()); | 723 content::NavigationEntry::Create()); |
| 761 entry1->SetVirtualURL(GURL("http://www.google.com")); | 724 entry1->SetVirtualURL(GURL("http://www.google.com")); |
| 762 scoped_ptr<content::NavigationEntry> entry2( | 725 scoped_ptr<content::NavigationEntry> entry2( |
| 763 content::NavigationEntry::Create()); | 726 content::NavigationEntry::Create()); |
| 764 entry2->SetVirtualURL(GURL("http://www.noodle.com")); | 727 entry2->SetVirtualURL(GURL("http://www.noodle.com")); |
| 765 scoped_ptr<content::NavigationEntry> entry3( | 728 scoped_ptr<content::NavigationEntry> entry3( |
| 766 content::NavigationEntry::Create()); | 729 content::NavigationEntry::Create()); |
| 767 entry3->SetVirtualURL(GURL("http://www.doodle.com")); | 730 entry3->SetVirtualURL(GURL("http://www.doodle.com")); |
| 768 scoped_ptr<content::NavigationEntry> entry4( | 731 scoped_ptr<content::NavigationEntry> entry4( |
| 769 content::NavigationEntry::Create()); | 732 content::NavigationEntry::Create()); |
| 770 entry4->SetVirtualURL(GURL("http://www.poodle.com")); | 733 entry4->SetVirtualURL(GURL("http://www.poodle.com")); |
| 771 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(3)); | 734 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(3)); |
| 772 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( | 735 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( |
| 773 Return(entry1.get())); | 736 Return(entry1.get())); |
| 774 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( | 737 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( |
| 775 Return(entry2.get())); | 738 Return(entry2.get())); |
| 776 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( | 739 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( |
| 777 Return(entry3.get())); | 740 Return(entry3.get())); |
| 778 EXPECT_CALL(tab_mock, GetEntryAtIndex(3)).WillRepeatedly( | 741 EXPECT_CALL(tab_mock, GetEntryAtIndex(3)).WillRepeatedly( |
| 779 Return(entry4.get())); | 742 Return(entry4.get())); |
| 780 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(4)); | 743 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(4)); |
| 781 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); | 744 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); |
| 782 | 745 |
| 783 // This tab is new, so prev_tab is the default SyncedSessionTab object. | 746 // The initial UpdateSessionTabFromDelegate call builds the session_tab. |
| 784 SessionTab prev_tab; | 747 SessionTab session_tab; |
| 785 prev_tab.tab_id.set_id(0); | 748 UpdateSessionTabFromDelegate(tab_mock, kTime1, kTime2, &session_tab); |
| 786 | |
| 787 // The initial AssociateTabContents call builds the prev_tab. | |
| 788 sync_pb::SessionTab sync_tab; | |
| 789 GURL new_url; | |
| 790 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | |
| 791 | |
| 792 ASSERT_EQ(4u, prev_tab.navigations.size()); | |
| 793 | 749 |
| 794 // Reset new tab to have the oldest entry pruned, the current navigation | 750 // Reset new tab to have the oldest entry pruned, the current navigation |
| 795 // set to entry3, and a new entry added in place of entry4. | 751 // set to entry3, and a new entry added in place of entry4. |
| 796 testing::Mock::VerifyAndClearExpectations(&tab_mock); | 752 testing::Mock::VerifyAndClearExpectations(&tab_mock); |
| 797 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(1)); | 753 EXPECT_CALL(tab_mock, GetCurrentEntryIndex()).WillRepeatedly(Return(1)); |
| 798 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( | 754 EXPECT_CALL(tab_mock, GetEntryAtIndex(0)).WillRepeatedly( |
| 799 Return(entry2.get())); | 755 Return(entry2.get())); |
| 800 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( | 756 EXPECT_CALL(tab_mock, GetEntryAtIndex(1)).WillRepeatedly( |
| 801 Return(entry3.get())); | 757 Return(entry3.get())); |
| 802 scoped_ptr<content::NavigationEntry> entry5( | 758 scoped_ptr<content::NavigationEntry> entry5( |
| 803 content::NavigationEntry::Create()); | 759 content::NavigationEntry::Create()); |
| 804 entry5->SetVirtualURL(GURL("http://www.noogle.com")); | 760 entry5->SetVirtualURL(GURL("http://www.noogle.com")); |
| 805 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( | 761 EXPECT_CALL(tab_mock, GetEntryAtIndex(2)).WillRepeatedly( |
| 806 Return(entry5.get())); | 762 Return(entry5.get())); |
| 807 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); | 763 EXPECT_CALL(tab_mock, GetEntryCount()).WillRepeatedly(Return(3)); |
| 808 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); | 764 EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); |
| 809 | 765 |
| 810 // The new entry should have a timestamp later than this. | 766 // Tweak the timestamps a bit. |
| 811 int64 now = syncer::TimeToProtoTime(base::Time::Now()); | 767 ASSERT_EQ(4u, session_tab.navigations.size()); |
| 768 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[0], kTime3); |
| 769 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[1], kTime4); |
| 770 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[2], kTime5); |
| 771 SessionTypesTestHelper::SetTimestamp(&session_tab.navigations[3], kTime6); |
| 812 | 772 |
| 813 // Now re-associate with the new version. | 773 // Now re-associate with the new version. |
| 814 AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); | 774 UpdateSessionTabFromDelegate(tab_mock, kTime7, kTime8, &session_tab); |
| 815 | 775 |
| 816 // Only entry2's timestamp should be preserved. The new entry should have a | 776 // Only entry2's and entry3's timestamps should be preserved. The new |
| 817 // new timestamp. | 777 // entry should have a new timestamp. |
| 818 EXPECT_EQ(new_url, entry3->GetVirtualURL()); | 778 ASSERT_EQ(3u, session_tab.navigations.size()); |
| 819 ASSERT_EQ(3, sync_tab.navigation_size()); | 779 EXPECT_EQ(entry2->GetVirtualURL(), |
| 820 EXPECT_EQ(entry2->GetVirtualURL().spec(), | 780 session_tab.navigations[0].virtual_url()); |
| 821 sync_tab.navigation(0).virtual_url()); | 781 EXPECT_EQ(entry3->GetVirtualURL(), |
| 822 EXPECT_EQ(entry3->GetVirtualURL().spec(), | 782 session_tab.navigations[1].virtual_url()); |
| 823 sync_tab.navigation(1).virtual_url()); | 783 EXPECT_EQ(entry5->GetVirtualURL(), |
| 824 EXPECT_EQ(entry5->GetVirtualURL().spec(), | 784 session_tab.navigations[2].virtual_url()); |
| 825 sync_tab.navigation(2).virtual_url()); | 785 EXPECT_EQ(1, session_tab.current_navigation_index); |
| 826 EXPECT_EQ(1, sync_tab.current_navigation_index()); | 786 EXPECT_EQ(kTime4, session_tab.navigations[0].timestamp()); |
| 827 EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), | 787 EXPECT_EQ(kTime5, session_tab.navigations[1].timestamp()); |
| 828 sync_tab.navigation(0).timestamp()); | 788 EXPECT_EQ(kTime8, session_tab.navigations[2].timestamp()); |
| 829 EXPECT_LE(now, sync_tab.navigation(1).timestamp()); | |
| 830 EXPECT_LE(now, sync_tab.navigation(2).timestamp()); | |
| 831 EXPECT_EQ(3U, prev_tab.navigations.size()); | |
| 832 } | 789 } |
| 833 | 790 |
| 791 } // namespace |
| 792 |
| 834 } // namespace browser_sync | 793 } // namespace browser_sync |
| OLD | NEW |