sessions_sync_manager_unittest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/sessions_sync_manager.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_util.h"
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sessions/session_id.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sessions/session_types.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/device_info.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/session_sync_test_helper.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_tab_delegate.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync/glue/synced_window_delegate.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/notification_service_sessions_router.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/sessions_util.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/synced_window_delegates_getter.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/test/base/browser_with_test_window_test.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/sessions/serialized_navigation_entry_test_helper.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_details.h"
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_service.h"
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_source.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents.h"
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_id.h"
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_service_proxy_for_test.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_error_factory_mock.h"
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::WebContents;
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sessions::SerializedNavigationEntry;
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sessions::SerializedNavigationEntryTestHelper;
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using syncer::SyncChange;
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncData;
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace browser_sync {
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SyncedWindowDelegateOverride : public SyncedWindowDelegate {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit SyncedWindowDelegateOverride(SyncedWindowDelegate* wrapped)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : wrapped_(wrapped) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~SyncedWindowDelegateOverride() {}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool HasWindow() const OVERRIDE {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->HasWindow();
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SessionID::id_type GetSessionId() const OVERRIDE {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetSessionId();
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetTabCount() const OVERRIDE {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabCount();
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetActiveIndex() const OVERRIDE {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetActiveIndex();
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsApp() const OVERRIDE {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsApp();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTypeTabbed() const OVERRIDE {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTypeTabbed();
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTypePopup() const OVERRIDE {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTypePopup();
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTabPinned(const SyncedTabDelegate* tab) const OVERRIDE {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTabPinned(tab);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SyncedTabDelegate* GetTabAt(int index) const OVERRIDE {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tab_overrides_.find(index) != tab_overrides_.end())
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return tab_overrides_.find(index)->second;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabAt(index);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OverrideTabAt(int index,
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     SyncedTabDelegate* delegate,
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     SessionID::id_type tab_id) {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_overrides_[index] = delegate;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_id_overrides_[index] = tab_id;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SessionID::id_type GetTabIdAt(int index) const OVERRIDE {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tab_id_overrides_.find(index) != tab_id_overrides_.end())
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return tab_id_overrides_.find(index)->second;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabIdAt(index);
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsSessionRestoreInProgress() const OVERRIDE {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsSessionRestoreInProgress();
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, SyncedTabDelegate*> tab_overrides_;
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, SessionID::id_type> tab_id_overrides_;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedWindowDelegate* wrapped_;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSyncedWindowDelegatesGetter(
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::set<SyncedWindowDelegate*>& delegates)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : delegates_(delegates) {}
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual const std::set<SyncedWindowDelegate*> GetSyncedWindowDelegates()
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return delegates_;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::set<SyncedWindowDelegate*> delegates_;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : output_(output) {}
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual syncer::SyncError ProcessSyncChanges(
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const tracked_objects::Location& from_here,
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const syncer::SyncChangeList& change_list) OVERRIDE {
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (error_.IsSet()) {
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      syncer::SyncError error = error_;
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      error_ = syncer::SyncError();
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return error;
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (output_)
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      output_->insert(output_->end(), change_list.begin(), change_list.end());
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return syncer::SyncError();
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const OVERRIDE {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return sync_data_to_return_;
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void FailProcessSyncChangesWith(const syncer::SyncError& error) {
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    error_ = error;
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetSyncDataToReturn(const syncer::SyncDataList& data) {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_data_to_return_ = data;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncError error_;
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList* output_;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncDataList sync_data_to_return_;
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)syncer::SyncChange MakeRemoteChange(
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int64 id,
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics,
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    SyncChange::SyncChangeType type) {
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(specifics);
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return syncer::SyncChange(
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      FROM_HERE,
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      type,
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::SyncData::CreateRemoteData(
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          id,
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          entity,
177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          base::Time(),
178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::AttachmentIdList(),
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::AttachmentServiceProxyForTest::Create()));
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AddTabsToChangeList(
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const std::vector<sync_pb::SessionSpecifics>& batch,
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      SyncChange::SyncChangeType type,
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      syncer::SyncChangeList* change_list) {
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics>::const_iterator iter;
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (iter = batch.begin();
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       iter != batch.end(); ++iter) {
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    sync_pb::EntitySpecifics entity;
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    entity.mutable_session()->CopyFrom(*iter);
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    change_list->push_back(syncer::SyncChange(
192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        type,
194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            iter->tab_node_id(),
196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            entity,
197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AddTabsToSyncDataList(const std::vector<sync_pb::SessionSpecifics> tabs,
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                           syncer::SyncDataList* list) {
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = 0; i < tabs.size(); i++) {
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    sync_pb::EntitySpecifics entity;
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    entity.mutable_session()->CopyFrom(tabs[i]);
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    list->push_back(SyncData::CreateRemoteData(
209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        i + 2,
210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        entity,
211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
212a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DummyRouter : public LocalSessionEventRouter {
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~DummyRouter() {}
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void StartRoutingTo(LocalSessionEventHandler* handler) OVERRIDE {}
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void Stop() OVERRIDE {}
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<LocalSessionEventRouter> NewDummyRouter() {
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return scoped_ptr<LocalSessionEventRouter>(new DummyRouter());
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SessionsSyncManagerTest
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : public BrowserWithTestWindowTest,
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      public SessionsSyncManager::SyncInternalApiDelegate {
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionsSyncManagerTest() : test_processor_(NULL) {}
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BrowserWithTestWindowTest::SetUp();
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    browser_sync::NotificationServiceSessionsRouter* router(
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new browser_sync::NotificationServiceSessionsRouter(
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            profile(), syncer::SyncableService::StartSyncFlare()));
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    manager_.reset(new SessionsSyncManager(profile(), this,
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      scoped_ptr<LocalSessionEventRouter>(router)));
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_ = NULL;
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->Reset();
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    manager_.reset();
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BrowserWithTestWindowTest::TearDown();
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual scoped_ptr<DeviceInfo> GetLocalDeviceInfo() const OVERRIDE {
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return scoped_ptr<DeviceInfo>(
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new DeviceInfo(GetLocalSyncCacheGUID(),
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       "Wayne Gretzky's Hacking Box",
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       "Chromium 10k",
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       "Chrome 10k",
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       sync_pb::SyncEnums_DeviceType_TYPE_LINUX));
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual std::string GetLocalSyncCacheGUID() const OVERRIDE {
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return "cache_guid";
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager* manager() { return manager_.get(); }
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionSyncTestHelper* helper() { return &helper_; }
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  syncer::SyncChangeList* output) {
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_ = new TestSyncProcessorStub(output);
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    syncer::SyncMergeResult result = manager_->MergeDataAndStartSyncing(
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        syncer::SESSIONS, initial_data,
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        scoped_ptr<syncer::SyncChangeProcessor>(test_processor_),
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        scoped_ptr<syncer::SyncErrorFactory>(
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            new syncer::SyncErrorFactoryMock()));
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_FALSE(result.error().IsSet());
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void InitWithNoSyncData() {
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL);
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void TriggerProcessSyncChangesError() {
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_->FailProcessSyncChangesWith(syncer::SyncError(
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error",
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        syncer::SESSIONS));
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetSyncData(const syncer::SyncDataList& data) {
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     test_processor_->SetSyncDataToReturn(data);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList* FilterOutLocalHeaderChanges(
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SyncChangeList* list) {
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    syncer::SyncChangeList::iterator it = list->begin();
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool found = false;
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    while (it != list->end()) {
298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      if (syncer::SyncDataLocal(it->sync_data()).GetTag() ==
299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          manager_->current_machine_tag()) {
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() ||
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                    SyncChange::ACTION_UPDATE == it->change_type());
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        it = list->erase(it);
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        found = true;
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      } else {
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ++it;
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(found);
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return list;
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<SessionsSyncManager> manager_;
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionSyncTestHelper helper_;
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestSyncProcessorStub* test_processor_;
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that the SyncSessionManager can properly fill in a SessionHeader.
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) {
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionHeader header_s;
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  header_s.set_client_name("Client 1");
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN);
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedSession session;
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Time time = base::Time::Now();
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::PopulateSessionHeaderFromSpecifics(
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      header_s, time, &session);
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ("Client 1", session.session_name);
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(SyncedSession::TYPE_WIN, session.device_type);
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(time, session.modified_time);
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test translation between protobuf types and chrome session types.
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, PopulateSessionWindow) {
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionWindow window_s;
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.add_tab(0);
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.set_selected_tab_index(1);
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag";
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedSession* session = manager()->session_tracker_.GetSession(tag);
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->session_tracker_.PutWindowInSession(tag, 0);
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->BuildSyncedSessionFromSpecifics(
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, window_s, base::Time(), session->windows[0]);
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, session->windows[0]->tabs.size());
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1, session->windows[0]->selected_tab_index);
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1, session->windows[0]->type);
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, manager()->session_tracker_.num_synced_sessions());
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U,
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            manager()->session_tracker_.num_synced_tabs(std::string("tag")));
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SyncedTabDelegateFake : public SyncedTabDelegate {
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake() : current_entry_index_(0),
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            pending_entry_index_(-1),
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            is_managed_(false),
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            sync_id_(-1),
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            blocked_navigations_(NULL) {}
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~SyncedTabDelegateFake() {}
3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetCurrentEntryIndex() const OVERRIDE {
3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return current_entry_index_;
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_current_entry_index(int i) {
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    current_entry_index_ = i;
3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetEntryAtIndex(int i) const OVERRIDE {
3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const int size = entries_.size();
3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return (size < i + 1) ? NULL : entries_[i];
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AppendEntry(content::NavigationEntry* entry) {
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    entries_.push_back(entry);
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetEntryCount() const OVERRIDE {
3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return entries_.size();
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetPendingEntryIndex() const OVERRIDE {
3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return pending_entry_index_;
3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_pending_entry_index(int i) {
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending_entry_index_ = i;
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual SessionID::id_type GetWindowId() const OVERRIDE {
3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return SessionID::id_type();
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual SessionID::id_type GetSessionId() const OVERRIDE {
3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return SessionID::id_type();
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsBeingDestroyed() const OVERRIDE { return false; }
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual Profile* profile() const OVERRIDE { return NULL; }
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetExtensionAppId() const OVERRIDE {
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetPendingEntry() const OVERRIDE {
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetActiveEntry() const OVERRIDE {
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool ProfileIsManaged() const OVERRIDE {
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return is_managed_;
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_is_managed(bool is_managed) { is_managed_ = is_managed; }
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual const std::vector<const content::NavigationEntry*>*
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetBlockedNavigations() const OVERRIDE {
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return blocked_navigations_;
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_blocked_navigations(
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::vector<const content::NavigationEntry*>* navs) {
4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    blocked_navigations_ = navs;
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsPinned() const OVERRIDE {
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return false;
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool HasWebContents() const OVERRIDE {
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return false;
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::WebContents* GetWebContents() const OVERRIDE {
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Session sync related methods.
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetSyncId() const OVERRIDE {
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   return sync_id_;
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetSyncId(int sync_id) OVERRIDE {
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_id_ = sync_id;
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void reset() {
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    current_entry_index_ = 0;
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending_entry_index_ = -1;
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_id_ = -1;
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    entries_.clear();
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int current_entry_index_;
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int pending_entry_index_;
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   bool is_managed_;
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   int sync_id_;
4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   std::vector<const content::NavigationEntry*>* blocked_navigations_;
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   ScopedVector<content::NavigationEntry> entries_;
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test that we exclude tabs with only chrome:// and file:// schemed navigations
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from ShouldSyncTab(..).
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, ValidTabs) {
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A null entry shouldn't crash.
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(NULL);
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.reset();
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A chrome:// entry isn't valid.
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("chrome://preferences/"));
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A file:// entry isn't valid, even in addition to another entry.
4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("file://bla"));
4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry2);
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a valid scheme entry to tab, making the tab valid.
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
4834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.google.com"));
4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry3);
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Make sure GetCurrentVirtualURL() returns the virtual URL of the pending
4894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entry if the current entry is pending.
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, GetCurrentVirtualURLPending) {
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("http://www.google.com"));
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry->GetVirtualURL(), manager()->GetCurrentVirtualURL(tab));
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Make sure GetCurrentVirtualURL() returns the virtual URL of the current
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entry if the current entry is non-pending.
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, GetCurrentVirtualURLNonPending) {
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("http://www.google.com"));
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry->GetVirtualURL(), manager()->GetCurrentVirtualURL(tab));
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const base::Time kTime1 = base::Time::FromInternalValue(100);
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const base::Time kTime2 = base::Time::FromInternalValue(105);
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const base::Time kTime3 = base::Time::FromInternalValue(110);
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const base::Time kTime4 = base::Time::FromInternalValue(120);
5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const base::Time kTime5 = base::Time::FromInternalValue(130);
5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Populate the mock tab delegate with some data and navigation
5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entries and make sure that setting a SessionTab from it preserves
5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// those entries (and clobbers any existing data).
5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegate) {
5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a tab with three valid entries.
5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetVirtualURL(GURL("http://www.google.com"));
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetTimestamp(kTime1);
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetHttpStatusCode(200);
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("http://www.noodle.com"));
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetTimestamp(kTime2);
5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetHttpStatusCode(201);
5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.doodle.com"));
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetTimestamp(kTime3);
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetHttpStatusCode(202);
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry1);
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry2);
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry3);
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.set_current_entry_index(2);
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTab session_tab;
5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.window_id.set_id(1);
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_id.set_id(1);
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_visual_index = 1;
5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.current_navigation_index = 1;
5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.pinned = true;
5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.extension_app_id = "app id";
5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.user_agent_override = "override";
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.timestamp = kTime5;
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.navigations.push_back(
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      SerializedNavigationEntryTestHelper::CreateNavigation(
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "http://www.example.com", "Example"));
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.session_storage_persistent_id = "persistent id";
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime4, &session_tab);
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.window_id.id());
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_id.id());
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_visual_index);
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2, session_tab.current_navigation_index);
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(session_tab.pinned);
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.extension_app_id.empty());
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.user_agent_override.empty());
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime4, session_tab.timestamp);
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(3u, session_tab.navigations.size());
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry1->GetVirtualURL(),
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].virtual_url());
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry2->GetVirtualURL(),
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].virtual_url());
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry3->GetVirtualURL(),
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].virtual_url());
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime1, session_tab.navigations[0].timestamp());
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime2, session_tab.navigations[1].timestamp());
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime3, session_tab.navigations[2].timestamp());
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(200, session_tab.navigations[0].http_status_code());
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(201, session_tab.navigations[1].http_status_code());
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(202, session_tab.navigations[2].http_status_code());
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].blocked_state());
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].blocked_state());
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].blocked_state());
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.session_storage_persistent_id.empty());
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests that for managed users blocked navigations are recorded and marked as
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// such, while regular navigations are marked as allowed.
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, BlockedNavigations) {
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetVirtualURL(GURL("http://www.google.com"));
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetTimestamp(kTime1);
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry1);
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2 = content::NavigationEntry::Create();
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("http://blocked.com/foo"));
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetTimestamp(kTime2);
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3 = content::NavigationEntry::Create();
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://evil.com"));
5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetTimestamp(kTime3);
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<const content::NavigationEntry> blocked_navigations;
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_navigations.push_back(entry2);
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_navigations.push_back(entry3);
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.set_is_managed(true);
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.set_blocked_navigations(&blocked_navigations.get());
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTab session_tab;
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.window_id.set_id(1);
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_id.set_id(1);
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_visual_index = 1;
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.current_navigation_index = 1;
6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.pinned = true;
6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.extension_app_id = "app id";
6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.user_agent_override = "override";
6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.timestamp = kTime5;
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.navigations.push_back(
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      SerializedNavigationEntryTestHelper::CreateNavigation(
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "http://www.example.com", "Example"));
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.session_storage_persistent_id = "persistent id";
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime4, &session_tab);
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.window_id.id());
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_id.id());
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_visual_index);
6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.current_navigation_index);
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(session_tab.pinned);
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.extension_app_id.empty());
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.user_agent_override.empty());
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime4, session_tab.timestamp);
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(3u, session_tab.navigations.size());
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry1->GetVirtualURL(),
6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].virtual_url());
6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry2->GetVirtualURL(),
6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].virtual_url());
6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry3->GetVirtualURL(),
6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].virtual_url());
6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime1, session_tab.navigations[0].timestamp());
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime2, session_tab.navigations[1].timestamp());
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime3, session_tab.navigations[2].timestamp());
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_ALLOWED,
6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].blocked_state());
6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_BLOCKED,
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].blocked_state());
6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_BLOCKED,
6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].blocked_state());
6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.session_storage_persistent_id.empty());
6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that the local session header objects is created properly in
648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// presence of no other session activity, once and only once.
6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeLocalSessionNoTabs) {
6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(manager()->current_machine_tag().empty());
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2U, out.size());
6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].IsValid());
6560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data(out[0].sync_data());
658e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
659e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[1].IsValid());
6690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data_2(out[1].sync_data());
671e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
672e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s2.window_size());
6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Now take that header node and feed it in as input.
680a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
682a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      data.GetSpecifics(),
683a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
684a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
685a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
6864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
6874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  out.clear();
688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionsSyncManager manager2(profile(), this, NewDummyRouter());
6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SESSIONS, in,
6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new TestSyncProcessorStub(&out)),
6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
6954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(result.error().IsSet());
6964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1U, out.size());
6980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
7004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Ensure model association associates the pre-existing tabs.
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, SwappedOutOnRestore) {
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://bar1"));
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://baz1"));
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://baz2"));
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kRestoredTabId = 1337;
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNewTabId = 2468;
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncDataList in;
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList out;
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitWithSyncDataTakeOutput(in, &out);
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should be one header add, 3 tab add/update pairs, one header update.
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(8U, out.size());
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For input, we set up:
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "normal" fully loaded tab
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "frozen" tab with no WebContents and a tab_id change
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "frozen" tab with no WebContents and no tab_id change
724a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t0(SyncData::CreateRemoteData(
725a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
726a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      out[2].sync_data().GetSpecifics(),
727a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
728a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
729a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_pb::EntitySpecifics entity(out[4].sync_data().GetSpecifics());
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entity.mutable_session()->mutable_tab()->set_tab_id(kRestoredTabId);
732a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t1(SyncData::CreateRemoteData(
733a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      2,
734a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
735a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
736a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
737a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
738a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t2(SyncData::CreateRemoteData(
739a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      3,
740a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      out[6].sync_data().GetSpecifics(),
741a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
742a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
743a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t0);
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t1);
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t2);
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  out.clear();
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->StopSyncing(syncer::SESSIONS);
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::set<SyncedWindowDelegate*> windows(
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SyncedWindowDelegate::GetSyncedWindowDelegates());
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, windows.size());
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedTabDelegateFake t1_override, t2_override;
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  t1_override.SetSyncId(1);  // No WebContents by default.
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  t2_override.SetSyncId(2);  // No WebContents by default.
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedWindowDelegateOverride window_override(*windows.begin());
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_override.OverrideTabAt(1, &t1_override, kNewTabId);
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_override.OverrideTabAt(2, &t2_override,
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                t2.GetSpecifics().session().tab().tab_id());
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::set<SyncedWindowDelegate*> delegates;
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegates.insert(&window_override);
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestSyncedWindowDelegatesGetter> getter(
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new TestSyncedWindowDelegatesGetter(delegates));
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->synced_window_getter_.reset(getter.release());
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncMergeResult result = manager()->MergeDataAndStartSyncing(
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      syncer::SESSIONS, in,
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new TestSyncProcessorStub(&out)),
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // There should be two changes, one for the fully associated tab, and
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // one for the tab_id update to t1.  t2 shouldn't need to be updated.
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2U, FilterOutLocalHeaderChanges(&out)->size());
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kNewTabId,
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            out[1].sync_data().GetSpecifics().session().tab().tab_id());
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabLinks.
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3U, tab_map.size());
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int t2_tab_id = t2.GetSpecifics().session().tab().tab_id();
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, tab_map.find(t2_tab_id)->second->tab_node_id());
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, tab_map.find(kNewTabId)->second->tab_node_id());
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int t0_tab_id = out[0].sync_data().GetSpecifics().session().tab().tab_id();
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, tab_map.find(t0_tab_id)->second->tab_node_id());
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(tim): Once bug 337057 is fixed, we can issue an OnLocalTabModified
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from here (using an override similar to above) to return a new tab id
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and verify that we don't see any node creations in the SyncChangeProcessor
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (similar to how SessionsSyncManagerTest.OnLocalTabModified works.)
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests MergeDataAndStartSyncing with sync data but no local data.
7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeWithInitialForeignSession) {
7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
8014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a second window.
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n2[] = {7, 15, 18, 20};
8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(n2, n2 + arraysize(n2));
8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta);
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set up initial data.
8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList initial_data;
8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::EntitySpecifics entity;
8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
813a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  initial_data.push_back(SyncData::CreateRemoteData(
814a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
815a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
816a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
817a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
818a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
8190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &initial_data);
8200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < tab_list2.size(); ++i) {
8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sync_pb::EntitySpecifics entity;
8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->BuildTabSpecifics(tag, 0, tab_list2[i],
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                entity.mutable_session());
825a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_data.push_back(SyncData::CreateRemoteData(
826a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        i + 10,
827a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        entity,
828a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
829a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
830a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList output;
8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(initial_data, &output);
8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(FilterOutLocalHeaderChanges(&output)->empty());
8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
8390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list2);
8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
8444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// This is a combination of MergeWithInitialForeignSession and
8470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// MergeLocalSessionExistingTabs. We repeat some checks performed in each of
8480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// those tests to ensure the common mixed scenario works.
8490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeWithLocalAndForeignTabs) {
8500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Local.
8510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
8520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
8530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Foreign.
8550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag = "tag1";
8560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
8570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
8580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
8590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
8600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tag, tab_list1, &tabs1));
8610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncDataList foreign_data;
8620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
8630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
864a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
865a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
866a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
867a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
868a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
869a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
8700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
8710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList output;
8730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
8740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, output.size());
8750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the local header.
8770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[0].IsValid());
8780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, output[0].change_type());
8790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const SyncData data(output[0].sync_data());
880e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
881e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
8820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
8830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
8840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
8850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
8860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
8870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
8880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
8890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
8900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the tab node creations and updates with content.
8910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (int i = 1; i < 3; i++) {
8920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_TRUE(output[i].IsValid());
8930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const SyncData data(output[i].sync_data());
894e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
8950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                manager()->current_machine_tag(), true));
8960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
8970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
8980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
8990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, output[1].change_type());
9000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[2].change_type());
9010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[2].sync_data().GetSpecifics().session().has_tab());
9020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the header was updated to reflect window state.
9040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[3].IsValid());
9050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[3].change_type());
9060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const SyncData data_2(output[3].sync_data());
907e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
908e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
9090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
9100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
9110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
9120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
9130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(1, header_s2.window_size());
9140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify foreign data.
9160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
9170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
9180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
9190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  session_reference.push_back(tab_list1);
9200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
9210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // There should be one and only one foreign session. If VerifySyncedSession
9220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // was successful above this EXPECT call ensures the local session didn't
9230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // get mistakenly added to foreign tracking (Similar to ExistingTabs test).
9240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(1U, foreign_sessions.size());
9250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
9260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
927a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests the common scenario.  Merge with both local and foreign session data
928a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// followed by updates flowing from sync and local.
9290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, UpdatesAfterMixedMerge) {
9300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add local and foreign data.
9310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
9320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
9330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag1 = "tag1";
9350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncDataList foreign_data1;
9360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > meta1_reference;
9370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta1;
9380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
9400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
9410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference.push_back(tab_list1);
9420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
9430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1 = helper()->BuildForeignSession(tag1, tab_list1, &tabs1);
9440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
9450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta1);
9460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_data1.push_back(SyncData::CreateRemoteData(
947a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
948a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
949a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
950a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
951a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
9520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data1);
9530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList output1;
9550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data1, &output1);
9560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, output1.size());
9570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a second window to the foreign session.
9590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(tim): Bug 98892. Add local window too when observers are hooked up.
9600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type tab_nums2[] = {7, 15, 18, 20};
9610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(
9620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tab_nums2, tab_nums2 + arraysize(tab_nums2));
9630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference.push_back(tab_list2);
9640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta1);
9650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
9660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tabs2.resize(tab_list2.size());
9670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = 0; i < tab_list2.size(); ++i) {
9680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    helper()->BuildTabSpecifics(tag1, 0, tab_list2[i], &tabs2[i]);
9690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
9700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
9720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE));
9730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes);
9740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
9750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
9760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
9780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
9790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
9800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
9810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
9820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(1)->second->tabs.size());
9830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag1, meta1_reference, *(foreign_sessions[0]));
9840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a new foreign session.
9860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag2 = "tag2";
9870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n2[] = {107, 115};
9880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tag2_tab_list(n2, n2 + arraysize(n2));
9890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tag2_tabs;
9900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta2(helper()->BuildForeignSession(
9910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tag2, tag2_tab_list, &tag2_tabs));
9920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(100, meta2, SyncChange::ACTION_ADD));
9930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tag2_tabs, SyncChange::ACTION_ADD, &changes);
9940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
9960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
9970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
9990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > meta2_reference;
10000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta2_reference.push_back(tag2_tab_list);
10010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
10020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions[1]->windows.find(0)->second->tabs.size());
10030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag2, meta2_reference, *(foreign_sessions[1]));
10040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_sessions.clear();
10050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Remove a tab from a window.
10070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference[0].pop_back();
10080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tab_list1.pop_back();
10090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionWindow* win = meta1.mutable_header()->mutable_window(0);
10100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  win->clear_tab();
10110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::vector<int>::const_iterator iter = tab_list1.begin();
10120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       iter != tab_list1.end(); ++iter) {
10130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    win->add_tab(*iter);
10140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
10150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList removal;
10160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  removal.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE));
10170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_UPDATE, &removal);
10180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, removal);
10190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
10210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
10220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(3U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
10230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag1, meta1_reference, *(foreign_sessions[0]));
10240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
10250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1026a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that this SyncSessionManager knows how to delete foreign sessions
1027a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// if it wants to.
10284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, DeleteForeignSession) {
10294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
10304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
10314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
10324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
10344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
1035f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  manager()->DeleteForeignSessionInternal(tag, &changes);
10364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
10374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(changes.empty());
10384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   // Fill an instance of session specifics with a foreign session's data.
10404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs;
10414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
10424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_nums1(n1, n1 + arraysize(n1));
10434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
10444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_nums1, &tabs));
10454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update associator with the session's meta node, window, and tabs.
10474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->UpdateTrackerWithForeignSession(meta, base::Time());
10484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs.begin();
10494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != tabs.end(); ++iter) {
10504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    manager()->UpdateTrackerWithForeignSession(*iter, base::Time());
10514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
10534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
10544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Now delete the foreign session.
1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  manager()->DeleteForeignSessionInternal(tag, &changes);
10574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
10584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(5U, changes.size());
10604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::set<std::string> expected_tags(&tag, &tag + 1);
10614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < 5; i++)
10620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    expected_tags.insert(TabNodePool::TabIdToTag(tag, i));
10634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
10654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SCOPED_TRACE(changes[i].ToString());
10664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(changes[i].IsValid());
10670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_EQ(SyncChange::ACTION_DELETE, changes[i].change_type());
10684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(changes[i].sync_data().IsValid());
1069e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_EQ(1U,
1070e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              expected_tags.erase(
1071e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                  syncer::SyncDataLocal(changes[i].sync_data()).GetTag()));
10724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
10744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Write a foreign session to a node, with the tabs arriving first, and then
10764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// retrieve it.
10774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, WriteForeignSessionToNodeTabsFirst) {
10784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
10794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fill an instance of session specifics with a foreign session's data.
10814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
10824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type nums1[] = {5, 10, 13, 17};
10834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
10844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1 (nums1, nums1 + arraysize(nums1));
10854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
10864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
10874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList adds;
10890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add tabs for first window, then the meta node.
10900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &adds);
10910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  adds.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
10920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, adds);
10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
10954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
10964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
10974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
10984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
11004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
11014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Write a foreign session to a node with some tabs that never arrive.
11044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, WriteForeignSessionToNodeMissingTabs) {
11054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
11064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fill an instance of session specifics with a foreign session's data.
11084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
11094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type nums1[] = {5, 10, 13, 17};
11104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
11114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1 (nums1, nums1 + arraysize(nums1));
11124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
11134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
11144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a second window, but this time only create two tab nodes, despite the
11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // window expecting four tabs.
11164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type tab_nums2[] = {7, 15, 18, 20};
11174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(
11184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tab_nums2, tab_nums2 + arraysize(tab_nums2));
11194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta);
11204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
11214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tabs2.resize(2);
11224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < 2; ++i) {
11234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->BuildTabSpecifics(tag, 0, tab_list2[i], &tabs2[i]);
11244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
11270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
11280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
11290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes);
11300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
11310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
11324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
11344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
11354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
11364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
11374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions[0]->windows.size());
11384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
11394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(1)->second->tabs.size());
11404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Close the second window.
11424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  meta.mutable_header()->clear_window();
11434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(0, tab_list1, &meta);
11440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_UPDATE));
11454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update associator with the session's meta node containing one window.
11460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
11474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
11494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  foreign_sessions.clear();
11504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
11514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
11524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions[0]->windows.size());
11534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
11544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
11554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
11564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that the SessionsSyncManager can handle a remote client deleting
11595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// sync nodes that belong to this local session.
11605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ProcessRemoteDeleteOfLocalSession) {
11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList out;
11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
11635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());
11645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_pb::EntitySpecifics entity(out[0].sync_data().GetSpecifics());
1165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
1166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
1168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
11715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetSyncData(syncer::SyncDataList(&d, &d + 1));
11725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  out.clear();
11735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList changes;
11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  changes.push_back(
11765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MakeRemoteChange(1, entity.session(), SyncChange::ACTION_DELETE));
11775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
11785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager()->local_tab_pool_out_of_sync_);
11795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(out.empty());  // ChangeProcessor shouldn't see any activity.
11805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This should trigger repair of the TabNodePool.
11825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL foo1("http://foo/1");
11835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), foo1);
11845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager()->local_tab_pool_out_of_sync_);
11855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AddTab triggers two notifications, one for the tab insertion and one for
11875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // committing the NavigationEntry. The first notification results in a tab
11885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we don't associate although we do update the header node.  The second
11895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // notification triggers association of the tab, and the subsequent window
11905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // update.  So we should see 4 changes at the SyncChangeProcessor.
11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(4U, out.size());
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[1].change_type());
11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int tab_node_id = out[1].sync_data().GetSpecifics().session().tab_node_id();
11970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(TabNodePool::TabIdToTag(
11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                manager()->current_machine_tag(), tab_node_id),
1199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(out[1].sync_data()).GetTag());
12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_tab());
12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[3].change_type());
12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[3].sync_data().GetSpecifics().session().has_header());
12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify the actual content.
12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const sync_pb::SessionHeader& session_header =
12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      out[3].sync_data().GetSpecifics().session().header();
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, session_header.window_size());
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, session_header.window(0).tab_size());
12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const sync_pb::SessionTab& tab1 =
12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      out[2].sync_data().GetSpecifics().session().tab();
12125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, tab1.navigation_size());
12135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1.navigation(0).virtual_url());
12145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabNodePool integrity.
12165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, manager()->local_tab_pool_.Capacity());
12175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager()->local_tab_pool_.Empty());
12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabLinks.
12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, tab_map.size());
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int tab_id = out[2].sync_data().GetSpecifics().session().tab().tab_id();
12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(tab_node_id, tab_map.find(tab_id)->second->tab_node_id());
12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that receiving a session delete from sync removes the session
1227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// from tracking.
12280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ProcessForeignDelete) {
12290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithNoSyncData();
12300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n[] = {5};
12310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
12320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
12330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
12340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      "tag1", tab_list, &tabs1));
12350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
12360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
12370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
12380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
12390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
12400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
12410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
12420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
12430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
12440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
12450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
12460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_sessions.clear();
12470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE));
12480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
12490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
12500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
12510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
12520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
12534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(shashishekhar): "Move this to TabNodePool unittests."
12544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, SaveUnassociatedNodesForReassociation) {
12554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
12564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
12574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string local_tag = manager()->current_machine_tag();
12594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a free node and then dissassociate sessions so that it ends up
12604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unassociated.
12614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->local_tab_pool_.GetFreeTabNode(&changes);
12624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update the tab_id of the node, so that it is considered a valid
12644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unassociated node otherwise it will be mistaken for a corrupted node and
12654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will be deleted before being added to the tab node pool.
12664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics());
12674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entity.mutable_session()->mutable_tab()->set_tab_id(1);
1268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
1269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
1271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
12744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
12754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  changes.clear();
1276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionsSyncManager manager2(profile(), this, NewDummyRouter());
12774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
12784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SESSIONS, in,
12794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
12804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new TestSyncProcessorStub(&changes)),
12814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
12824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
12834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(result.error().IsSet());
12844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty());
12854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
12864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) {
12884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
12894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
12904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string local_tag = manager()->current_machine_tag();
12924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes);
12934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncData d(SyncData::CreateRemoteData(
1294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1295a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      changes[0].sync_data().GetSpecifics(),
1296a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1297a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
12994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
13004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  changes.clear();
13014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TearDown();
13024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetUp();
13034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(in, &changes);
13044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size());
13050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type());
13060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(TabNodePool::TabIdToTag(local_tag, tab_node_id),
1307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(changes[0].sync_data()).GetTag());
13084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
13094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that things work if a tab is initially ignored.
13114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) {
13124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
13134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Go to a URL that is ignored by session syncing.
13144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("chrome://preferences/"));
13154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());  // Header add and update.
13174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(
13184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      0,
13194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      out[1].sync_data().GetSpecifics().session().header().window_size());
13204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  out.clear();
13214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
13224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Go to a sync-interesting URL.
13234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
13244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(3U, out.size());  // Tab add, update, and header update.
13264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_TRUE(
1328e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      StartsWithASCII(syncer::SyncDataLocal(out[0].sync_data()).GetTag(),
1329e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      manager()->current_machine_tag(),
1330e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      true));
13314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(),
13324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            out[0].sync_data().GetSpecifics().session().session_tag());
13330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
13344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1335e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_TRUE(
1336e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      StartsWithASCII(syncer::SyncDataLocal(out[1].sync_data()).GetTag(),
1337e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      manager()->current_machine_tag(),
1338e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      true));
13394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(),
13404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            out[1].sync_data().GetSpecifics().session().session_tag());
13414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab());
13420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
13434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(out[2].IsValid());
1345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
1346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const SyncData data(out[2].sync_data());
1347e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1348e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
13494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
13504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
13514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
13524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
13534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s.window_size());
13544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s.window(0).tab_size());
13554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
13564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that the SyncSessionManager responds to local tab events properly.
1358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, OnLocalTabModified) {
1359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList out;
1360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Init with no local data, relies on MergeLocalSessionNoTabs.
1361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(manager()->current_machine_tag().empty());
1363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());
1364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Copy the original header.
1366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics header(out[0].sync_data().GetSpecifics());
1367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  out.clear();
1368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL foo1("http://foo/1");
1370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL foo2("http://foo/2");
1371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL bar1("http://bar/1");
1372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL bar2("http://bar/2");
1373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), foo1);
1374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(foo2);
1375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), bar1);
1376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(bar2);
1377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One add, one update for each AddTab.
1379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One update for each NavigateAndCommit.
1380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // = 6 total tab updates.
1381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One header update corresponding to each of those.
1382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // = 6 total header updates.
1383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 12 total updates.
1384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(12U, out.size());
1385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the tab node creations and updates to ensure the SyncProcessor
1387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // sees the right operations.
1388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (int i = 0; i < 12; i++) {
1389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SCOPED_TRACE(i);
1390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(out[i].IsValid());
1391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncData data(out[i].sync_data());
1392e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
1393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                manager()->current_machine_tag(), true));
1394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
1395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
1396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (i % 6 == 0) {
1397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // First thing on an AddTab is a no-op header update for parented tab.
1398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(header.SerializeAsString(),
1399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                data.GetSpecifics().SerializeAsString());
1400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      EXPECT_EQ(manager()->current_machine_tag(),
1401e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 1) {
1403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Next, the TabNodePool should create the tab node.
1404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
14050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
14075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1408e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 2) {
1410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Then we see the tab update to the URL.
1411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
14120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
14135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
14145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1415e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_tab());
1417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 3) {
1418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // The header needs to be updated to reflect the new window state.
1419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_TRUE(specifics.has_header());
1421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 4) {
1422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Now we move on to NavigateAndCommit.  Update the tab.
1423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
14240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
14255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
14265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1427e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_tab());
1429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 5) {
1430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // The header needs to be updated to reflect the new window state.
1431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_header());
1433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      header = data.GetSpecifics();
1434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the actual content to ensure sync sees the right data.
1438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // When it's all said and done, the header should reflect two tabs.
1439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionHeader& session_header = header.session().header();
1440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, session_header.window_size());
1441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2, session_header.window(0).tab_size());
1442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ASSERT_TRUEs above allow us to dive in freely here.
1444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify first tab.
1445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab1_1 =
1446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[2].sync_data().GetSpecifics().session().tab();
1447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, tab1_1.navigation_size());
1448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1_1.navigation(0).virtual_url());
1449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab1_2 =
1450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[4].sync_data().GetSpecifics().session().tab();
1451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2, tab1_2.navigation_size());
1452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1_2.navigation(0).virtual_url());
1453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo2.spec(), tab1_2.navigation(1).virtual_url());
1454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify second tab.
1456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab2_1 =
1457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[8].sync_data().GetSpecifics().session().tab();
1458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, tab2_1.navigation_size());
1459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar1.spec(), tab2_1.navigation(0).virtual_url());
1460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab2_2 =
1461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[10].sync_data().GetSpecifics().session().tab();
1462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2, tab2_2.navigation_size());
1463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar1.spec(), tab2_2.navigation(0).virtual_url());
1464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar2.spec(), tab2_2.navigation(1).virtual_url());
1465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
14674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Ensure model association associates the pre-existing tabs.
14684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) {
14694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
1470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));  // Adds back entry.
14714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://bar1"));
1472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));  // Adds back entry.
14734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
14754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
14764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(6U, out.size());
14774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that this machine's data is not included in the foreign windows.
14794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
14804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
14814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the header.
14834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].IsValid());
14840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
14854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data(out[0].sync_data());
1486e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1487e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
14884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
14894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
14904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
14914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
14924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
14934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
14944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
14954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the tab node creations and updates with content.
14974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 1; i < 5; i++) {
14984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(out[i].IsValid());
14994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const SyncData data(out[i].sync_data());
1500e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
15014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                manager()->current_machine_tag(), true));
15024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
15034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
15044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (i % 2 == 1) {
15050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
15064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
15070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
15084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      EXPECT_TRUE(specifics.has_tab());
15094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
15104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
15114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the header was updated to reflect new window state.
15134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[5].IsValid());
15140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
15154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data_2(out[5].sync_data());
1516e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1517e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
15184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
15194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
15204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
15214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
15224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s2.window_size());
15234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify TabLinks.
15254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
15264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2U, tab_map.size());
15274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Tabs are ordered by sessionid in tab_map, so should be able to traverse
15284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the tree based on order of tabs created
15294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::TabLinksMap::iterator iter = tab_map.begin();
15304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
15314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://foo1"), iter->second->tab()->
15324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          GetEntryAtIndex(0)->GetVirtualURL());
15334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://foo2"), iter->second->tab()->
15344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          GetEntryAtIndex(1)->GetVirtualURL());
15354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iter++;
15364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
15374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://bar1"), iter->second->tab()->
15384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetEntryAtIndex(0)->GetVirtualURL());
15394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://bar2"), iter->second->tab()->
15404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetEntryAtIndex(1)->GetVirtualURL());
15414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
15424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test garbage collection of stale foreign sessions.
1544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, DoGarbageCollection) {
1545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Fill two instances of session specifics with a foreign session's data.
1546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag1 = "tag1";
1547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
1548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
1549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
1550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, tab_list1, &tabs1));
1552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag2 = "tag2";
1553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n2[] = {8, 15, 18, 20};
1554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(n2, n2 + arraysize(n2));
1555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
1556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta2(helper()->BuildForeignSession(
1557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag2, tab_list2, &tabs2));
1558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the modification time for tag1 to be 21 days ago, tag2 to 5 days ago.
1559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag1_time = base::Time::Now() - base::TimeDelta::FromDays(21);
1560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag2_time = base::Time::Now() - base::TimeDelta::FromDays(5);
1561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncDataList foreign_data;
1563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics entity1, entity2;
1564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity1.mutable_session()->CopyFrom(meta);
1565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity2.mutable_session()->CopyFrom(meta2);
1566a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1567a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1568a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity1,
1569a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag1_time,
1570a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1571a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1572a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1573a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1574a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity2,
1575a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag2_time,
1576a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1577a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
1579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs2, &foreign_data);
1580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList output;
1582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
1583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, output.size());
1584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  output.clear();
1585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
1587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
1588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1589a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
1590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  foreign_sessions.clear();
1591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1592a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Now garbage collect and verify the non-stale session is still there.
1593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->DoGarbageCollection();
1594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(5U, output.size());
1595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_DELETE, output[0].change_type());
1596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const SyncData data(output[0].sync_data());
1597e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(tag1, syncer::SyncDataLocal(data).GetTag());
1598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (int i = 1; i < 5; i++) {
1599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SyncChange::ACTION_DELETE, output[i].change_type());
1600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncData data(output[i].sync_data());
16010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(TabNodePool::TabIdToTag(tag1, i),
1602e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              syncer::SyncDataLocal(data).GetTag());
1603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
1608a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  session_reference.push_back(tab_list2);
1609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  helper()->VerifySyncedSession(tag2, session_reference,
1610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                *(foreign_sessions[0]));
1611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that an update to a previously considered "stale" session,
1614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// prior to garbage collection, will save the session from deletion.
1615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, GarbageCollectionHonoursUpdate) {
1616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag1 = "tag1";
1617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
1618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
1619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
1620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, tab_list1, &tabs1));
1622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncDataList foreign_data;
1623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics entity1;
1624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag1_time = base::Time::Now() - base::TimeDelta::FromDays(21);
1625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity1.mutable_session()->CopyFrom(meta);
1626a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1627a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1628a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity1,
1629a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag1_time,
1630a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1631a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
1633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList output;
1634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
1635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, output.size());
1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Update to a non-stale time.
1638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics update_entity;
1639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update_entity.mutable_session()->CopyFrom(tabs1[0]);
1640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList changes;
1641a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  changes.push_back(
1642a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::SyncChange(FROM_HERE,
1643a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                         SyncChange::ACTION_UPDATE,
1644a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                         syncer::SyncData::CreateRemoteData(
1645a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             1,
1646a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             update_entity,
1647a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             base::Time::Now(),
1648a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             syncer::AttachmentIdList(),
1649a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             syncer::AttachmentServiceProxyForTest::Create())));
1650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
1651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
1653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
1654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  foreign_sessions.clear();
1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the now non-stale session does not get deleted.
1659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->DoGarbageCollection();
1660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
1663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  session_reference.push_back(tab_list1);
1664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  helper()->VerifySyncedSession(
1665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, session_reference, *(foreign_sessions[0]));
1666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that swapping WebContents for a tab is properly observed and handled
1669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// by the SessionsSyncManager.
16704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) {
16714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
16724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
16734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
16754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
16764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, out.size());  // Header, tab ADD, tab UPDATE, header UPDATE.
16774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // To simulate WebContents swap during prerendering, create new WebContents
16794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // and swap with old WebContents.
1680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<content::WebContents> old_web_contents;
1681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  old_web_contents.reset(browser()->tab_strip_model()->GetActiveWebContents());
16824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create new WebContents, with the required tab helpers.
16844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebContents* new_web_contents = WebContents::CreateWithSessionStorage(
16854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WebContents::CreateParams(profile()),
16864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      old_web_contents->GetController().GetSessionStorageNamespaceMap());
16874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTabHelper::CreateForWebContents(new_web_contents);
16884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents);
16894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_web_contents->GetController()
16904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      .CopyStateFrom(old_web_contents->GetController());
16914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Swap the WebContents.
1693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int index = browser()->tab_strip_model()->GetIndexOfWebContents(
1694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      old_web_contents.get());
16954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents);
16964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(9U, out.size());
16980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type());
16990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
17004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Navigate away.
17024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));
17034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Delete old WebContents. This should not crash.
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  old_web_contents.reset();
17064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Try more navigations and verify output size. This can also reveal
17084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // bugs (leaks) on memcheck bots if the SessionSyncManager
17094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // didn't properly clean up the tab pool or session tracker.
17104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar3"));
17114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://bar4"));
17134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar5"));
1714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(19U, out.size());
17154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
17164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace {
17180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SessionNotificationObserver : public content::NotificationObserver {
17190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionNotificationObserver() : notified_of_update_(false),
1721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  notified_of_refresh_(false) {
17220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
17230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   content::NotificationService::AllSources());
1724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
1725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   content::NotificationService::AllSources());
17260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
17270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void Observe(int type,
17280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       const content::NotificationSource& source,
17290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
17300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    switch (type) {
17310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
17320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        notified_of_update_ = true;
17330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        break;
1734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case chrome::NOTIFICATION_SYNC_REFRESH_LOCAL:
1735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        notified_of_refresh_ = true;
1736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
17370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      default:
17380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        NOTREACHED();
17390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        break;
17400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
17410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
17420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool notified_of_update() const { return notified_of_update_; }
1743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool notified_of_refresh() const { return notified_of_refresh_; }
1744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Reset() {
1745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    notified_of_update_ = false;
1746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    notified_of_refresh_ = false;
1747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
17480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
17490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  content::NotificationRegistrar registrar_;
17500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool notified_of_update_;
1751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool notified_of_refresh_;
17520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
17530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace
17540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1755effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Test that NOTIFICATION_FOREIGN_SESSION_UPDATED is sent when processing
1756effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// sync changes.
17570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) {
17580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionNotificationObserver observer;
1759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(observer.notified_of_update());
17600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithNoSyncData();
17610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
17620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n[] = {5};
17630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
17640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
17650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
17660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      "tag1", tab_list, &tabs1));
17670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
17680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
17690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
17700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
17710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
17720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
17730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
17740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  observer.Reset();
17750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
17760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
17770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
17780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
17790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
17800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  observer.Reset();
17810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE));
17820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
17830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
17840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
17850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1786effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Test that NOTIFICATION_FOREIGN_SESSION_UPDATED is sent when handling
1787effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// local hide/removal of foreign session.
1788effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(SessionsSyncManagerTest, NotifiedOfLocalRemovalOfForeignSession) {
1789effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  InitWithNoSyncData();
1790effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const std::string tag("tag1");
1791effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SessionID::id_type n[] = {5};
1792effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<sync_pb::SessionSpecifics> tabs1;
1793effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
1794effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1795effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      tag, tab_list, &tabs1));
1796effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1797effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  syncer::SyncChangeList changes;
1798effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
1799effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager()->ProcessSyncChanges(FROM_HERE, changes);
1800effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1801effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SessionNotificationObserver observer;
1802effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_FALSE(observer.notified_of_update());
1803effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager()->DeleteForeignSession(tag);
1804effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(observer.notified_of_update());
1805effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1806effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS)
1808a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that opening the other devices page triggers a session sync refresh.
1809a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This page only exists on mobile platforms today; desktop has a
1810a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// search-enhanced NTP without other devices.
1811a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, NotifiedOfRefresh) {
1812a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionNotificationObserver observer;
1813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(observer.notified_of_refresh());
1814a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithNoSyncData();
1815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
1816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(observer.notified_of_refresh());
1817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("chrome://newtab/#open_tabs"));
1818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_refresh());
1819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // defined(OS_ANDROID) || defined(OS_IOS)
1821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
18224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace browser_sync
1823