Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: chrome/browser/sync/glue/session_model_associator_unittest.cc

Issue 10990012: [Sync] Refactor handling of session tabs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Few more fixes Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698