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

Unified Diff: components/sync_sessions/sessions_sync_manager_unittest.cc

Issue 2791183003: [Sync] Restore previous session if no tabbed windows present (Closed)
Patch Set: Self review Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: components/sync_sessions/sessions_sync_manager_unittest.cc
diff --git a/components/sync_sessions/sessions_sync_manager_unittest.cc b/components/sync_sessions/sessions_sync_manager_unittest.cc
index 7479a1833c5add313f4e0c0555dd263f569eba93..bc22ca1151ece4a41a006121d3f81fb5618ddbd7 100644
--- a/components/sync_sessions/sessions_sync_manager_unittest.cc
+++ b/components/sync_sessions/sessions_sync_manager_unittest.cc
@@ -243,7 +243,7 @@ class TestSyncedTabDelegate : public SyncedTabDelegate {
private:
int current_entry_index_ = -1;
bool is_supervised_ = false;
- int sync_id_ = -1;
+ int sync_id_ = kInvalidTabID;
SessionID tab_id_;
SessionID window_id_;
std::vector<std::unique_ptr<const sessions::SerializedNavigationEntry>>
@@ -328,7 +328,7 @@ class PlaceholderTabDelegate : public SyncedTabDelegate {
private:
SessionID::id_type session_id_;
- int sync_id_;
+ int sync_id_ = kInvalidTabID;
};
class TestSyncedWindowDelegate : public SyncedWindowDelegate {
@@ -358,6 +358,10 @@ class TestSyncedWindowDelegate : public SyncedWindowDelegate {
return false;
}
+ void OverrideWindowTypeToCustomTab() {
+ window_type_ = sync_pb::SessionWindow_BrowserType_TYPE_CUSTOM_TAB;
+ }
+
SyncedTabDelegate* GetTabAt(int index) const override {
if (tab_delegates_.find(index) != tab_delegates_.end())
return tab_delegates_.find(index)->second;
@@ -387,6 +391,8 @@ class TestSyncedWindowDelegate : public SyncedWindowDelegate {
SessionID window_id_;
sync_pb::SessionWindow_BrowserType window_type_ =
sync_pb::SessionWindow_BrowserType_TYPE_TABBED;
+ std::map<int, SyncedTabDelegate*> tab_overrides_;
+ std::map<int, SessionID::id_type> tab_id_overrides_;
};
class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
@@ -410,6 +416,8 @@ class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
delegates_[delegate->GetSessionId()] = delegate;
}
+ void ClearSyncedWindowDelegates() { delegates_.clear(); }
+
private:
SyncedWindowDelegateMap delegates_;
};
@@ -469,7 +477,7 @@ class DummyRouter : public LocalSessionEventRouter {
void StartRoutingTo(LocalSessionEventHandler* handler) override {
handler_ = handler;
}
- void Stop() override {}
+ void Stop() override { handler_ = nullptr; }
void NotifyNav(SyncedTabDelegate* tab) {
if (handler_)
@@ -716,12 +724,45 @@ class SessionsSyncManagerTest : public testing::Test {
NavigateTab(delegate, url, base::Time());
}
+ void ResetWindows() {
+ window_getter_.ClearSyncedWindowDelegates();
+ windows_.clear();
+ }
+
TestSyncedWindowDelegate* AddWindow() {
windows_.push_back(base::MakeUnique<TestSyncedWindowDelegate>());
window_getter_.AddSyncedWindowDelegate(windows_.back().get());
return windows_.back().get();
}
+ syncer::SyncDataList GetDataFromChanges(
+ const syncer::SyncChangeList& changes) {
+ syncer::SyncDataList data_list;
+ for (auto& change : changes) {
+ syncer::SyncDataLocal change_data(change.sync_data());
+ bool found = false;
+ for (auto&& data : data_list) {
+ syncer::SyncDataLocal local_data(data);
+ if (local_data.GetTag() == change_data.GetTag()) {
+ data = change.sync_data();
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ data_list.push_back(change_data);
+ }
+ return data_list;
+ }
+
+ syncer::SyncDataList ConvertToRemote(const syncer::SyncDataList& in) {
+ syncer::SyncDataList out;
+ for (auto& data : in) {
+ out.push_back(CreateRemoteData(data.GetSpecifics()));
+ }
+ return out;
+ }
+
private:
std::unique_ptr<syncer::FakeSyncClient> sync_client_;
std::unique_ptr<SyncSessionsClientShim> sessions_client_shim_;
@@ -737,41 +778,6 @@ class SessionsSyncManagerTest : public testing::Test {
std::unique_ptr<LocalDeviceInfoProviderMock> local_device_;
};
-// Test that the SyncSessionManager can properly fill in a SessionHeader.
-TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) {
- sync_pb::SessionHeader header_s;
- header_s.set_client_name("Client 1");
- header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN);
-
- SyncedSession session;
- base::Time time = base::Time::Now();
- SessionsSyncManager::PopulateSessionHeaderFromSpecifics(header_s, time,
- &session);
- ASSERT_EQ("Client 1", session.session_name);
- ASSERT_EQ(SyncedSession::TYPE_WIN, session.device_type);
- ASSERT_EQ(time, session.modified_time);
-}
-
-// Test translation between protobuf types and chrome session types.
-TEST_F(SessionsSyncManagerTest, PopulateSessionWindow) {
- sync_pb::SessionWindow window_s;
- window_s.add_tab(0);
- window_s.set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
- window_s.set_selected_tab_index(1);
-
- SyncedSession* session = manager()->session_tracker_.GetSession(kTag1);
- manager()->session_tracker_.PutWindowInSession(kTag1, 0);
- manager()->BuildSyncedSessionFromSpecifics(kTag1, window_s, base::Time(),
- session->windows[0].get());
- ASSERT_EQ(1U, session->windows[0]->wrapped_window.tabs.size());
- ASSERT_EQ(1, session->windows[0]->wrapped_window.selected_tab_index);
- ASSERT_EQ(sessions::SessionWindow::TYPE_TABBED,
- session->windows[0]->wrapped_window.type);
- ASSERT_EQ(1U, manager()->session_tracker_.num_synced_sessions());
- ASSERT_EQ(1U, manager()->session_tracker_.num_synced_tabs(kTag1));
-}
-
-// Populate the fake tab delegate with some data and navigation
// entries and make sure that setting a SessionTab from it preserves
// those entries (and clobbers any existing data).
TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegate) {
@@ -952,6 +958,117 @@ TEST_F(SessionsSyncManagerTest, MergeLocalSessionNoTabs) {
EXPECT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
}
+// Ensure that tabbed windows from a previous session are preserved if no
+// windows are present on startup.
+TEST_F(SessionsSyncManagerTest, PreserveTabbedDataNoWindows) {
+ syncer::SyncDataList in;
+ syncer::SyncChangeList out;
+
+ // Set up one tab and start sync with it.
+ TestSyncedTabDelegate* tab = AddTab(AddWindow()->GetSessionId(), kFoo1);
+ NavigateTab(tab, kFoo2);
+ InitWithSyncDataTakeOutput(in, &out);
+
+ // There should be two entities, a header and a tab.
+ in = GetDataFromChanges(out);
+ out.clear();
+ ASSERT_EQ(2U, in.size());
+
+ // Resync, using the previous sync data, but with no windows open now.
+ manager()->StopSyncing(syncer::SESSIONS);
+ ResetWindows();
+ InitWithSyncDataTakeOutput(ConvertToRemote(in), &out);
+
+ // There should be two changes: the rewritten tab (to update the tab id), and
+ // the rewritten header.
+ ASSERT_TRUE(ChangeTypeMatches(
+ out, {SyncChange::ACTION_UPDATE, SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(out[0], 2, kFoo2);
+ VerifyLocalHeaderChange(out[1], 1, 1);
+
+ // Verify the tab id of the restored tab is updated and consistent.
+ int restored_tab_id =
+ out[0].sync_data().GetSpecifics().session().tab().tab_id();
+ // SessionId should be rewritten on restore.
+ ASSERT_NE(tab->GetSessionId(), restored_tab_id);
+ ASSERT_EQ(
+ restored_tab_id,
+ out[1].sync_data().GetSpecifics().session().header().window(0).tab(0));
+}
+
+// Ensure that tabbed windows from a previous session are preserved if only
+// transient windows are present at startup.
+TEST_F(SessionsSyncManagerTest, PreserveTabbedDataCustomTab) {
+ syncer::SyncDataList in;
+ syncer::SyncChangeList out;
+
+ // Set up one tab and start sync with it.
+ TestSyncedWindowDelegate* window = AddWindow();
+ TestSyncedTabDelegate* tab = AddTab(window->GetSessionId(), kFoo1);
+ NavigateTab(tab, kFoo2);
+ InitWithSyncDataTakeOutput(in, &out);
+
+ // There should be two entities, a header and a tab.
+ in = GetDataFromChanges(out);
+ out.clear();
+ ASSERT_EQ(2U, in.size());
+
+ // Resync, using the previous sync data, but with only a custom tab open.
+ manager()->StopSyncing(syncer::SESSIONS);
+ window->OverrideWindowTypeToCustomTab();
+ SessionID new_window_id;
+ window->OverrideWindowId(new_window_id.id());
+ std::unique_ptr<TestSyncedTabDelegate> custom_tab =
+ base::MakeUnique<TestSyncedTabDelegate>();
+ NavigateTab(custom_tab.get(), kBar1);
+ window->OverrideTabAt(0, custom_tab.get());
+ InitWithSyncDataTakeOutput(ConvertToRemote(in), &out);
+
+ // The previous session should be preserved, and the transient window should
+ // be synced as a new transient window. This means that the original tab
+ // node will be updated with its new tab id, a new tab node will be created,
+ // and the header will be updated to reflect the two windows and two tabs.
+ ASSERT_TRUE(
+ ChangeTypeMatches(out, {SyncChange::ACTION_UPDATE, SyncChange::ACTION_ADD,
+ SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(out[0], 2, kFoo2);
+ VerifyLocalTabChange(out[1], 1, kBar1);
+ VerifyLocalHeaderChange(out[2], 2, 2);
+
+ // The two windows should have different window types.
+ ASSERT_EQ(sync_pb::SessionWindow::TYPE_CUSTOM_TAB, out[2]
+ .sync_data()
+ .GetSpecifics()
+ .session()
+ .header()
+ .window(0)
+ .browser_type());
+ ASSERT_EQ(sync_pb::SessionWindow::TYPE_TABBED, out[2]
+ .sync_data()
+ .GetSpecifics()
+ .session()
+ .header()
+ .window(1)
+ .browser_type());
+
+ // Verify the tab id of the restored tab is updated and consistent.
+ int restored_tab_id =
+ out[0].sync_data().GetSpecifics().session().tab().tab_id();
+ // SessionId should be rewritten on restore.
+ ASSERT_NE(tab->GetSessionId(), restored_tab_id);
+ ASSERT_EQ(
+ restored_tab_id,
+ out[2].sync_data().GetSpecifics().session().header().window(1).tab(0));
+
+ // Verify the tab id of the custom tab is consistent.
+ int custom_tab_id =
+ out[1].sync_data().GetSpecifics().session().tab().tab_id();
+ ASSERT_EQ(custom_tab->GetSessionId(), custom_tab_id);
+ ASSERT_EQ(
+ custom_tab_id,
+ out[2].sync_data().GetSpecifics().session().header().window(0).tab(0));
+}
+
// Tests MergeDataAndStartSyncing with sync data but no local data.
TEST_F(SessionsSyncManagerTest, MergeWithInitialForeignSession) {
std::vector<SessionID::id_type> tab_list1(std::begin(kTabIds1),
@@ -1582,9 +1699,9 @@ TEST_F(SessionsSyncManagerTest, AssociationReusesNodes) {
sync_pb::SessionSpecifics new_tab(
changes[1].sync_data().GetSpecifics().session());
new_tab.set_tab_node_id(tab_node_id + 1);
- in.push_back(CreateRemoteData(new_tab)); // New tab node.
in.push_back(CreateRemoteData(
changes[1].sync_data().GetSpecifics())); // Old tab node.
+ in.push_back(CreateRemoteData(new_tab)); // New tab node.
changes.clear();
// Reassociate (with the same single tab/window open).
@@ -2396,12 +2513,12 @@ TEST_F(SessionsSyncManagerTest, PlaceholderConflictAcrossWindows) {
// The tab entity will be overwritten twice. Once with the information for
// tab 1 and then again with the information for tab 2. This will be followed
- // by a header change reflecting both tabs.
+ // by a header change reflecting only the final tab.
ASSERT_TRUE(
ChangeTypeMatches(out,
{SyncChange::ACTION_UPDATE, SyncChange::ACTION_UPDATE,
SyncChange::ACTION_UPDATE}));
- VerifyLocalHeaderChange(out[2], 2, 2);
+ VerifyLocalHeaderChange(out[2], 2, 1);
VerifyLocalTabChange(out[0], 1, kFoo1);
EXPECT_EQ(sync_id, out[0].sync_data().GetSpecifics().session().tab_node_id());
EXPECT_EQ(tab1->GetSessionId(),

Powered by Google App Engine
This is Rietveld 408576698