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_tab_helper.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sessions/session_types.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/sync/glue/local_device_info_provider_mock.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/session_sync_test_helper.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_tab_delegate.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync/glue/synced_window_delegate.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/notification_service_sessions_router.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/sessions_util.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/synced_window_delegates_getter.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/test/base/browser_with_test_window_test.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/sessions/serialized_navigation_entry_test_helper.h"
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/sessions/session_id.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/sync_driver/device_info.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_details.h"
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_service.h"
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_source.h"
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents.h"
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_id.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_error_factory_mock.h"
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::WebContents;
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sessions::SerializedNavigationEntry;
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sessions::SerializedNavigationEntryTestHelper;
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::DeviceInfo;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::LocalDeviceInfoProvider;
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using syncer::SyncChange;
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncData;
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace browser_sync {
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SyncedWindowDelegateOverride : public SyncedWindowDelegate {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit SyncedWindowDelegateOverride(SyncedWindowDelegate* wrapped)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : wrapped_(wrapped) {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~SyncedWindowDelegateOverride() {}
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool HasWindow() const OVERRIDE {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->HasWindow();
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SessionID::id_type GetSessionId() const OVERRIDE {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetSessionId();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetTabCount() const OVERRIDE {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabCount();
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetActiveIndex() const OVERRIDE {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetActiveIndex();
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsApp() const OVERRIDE {
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsApp();
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTypeTabbed() const OVERRIDE {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTypeTabbed();
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTypePopup() const OVERRIDE {
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTypePopup();
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsTabPinned(const SyncedTabDelegate* tab) const OVERRIDE {
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsTabPinned(tab);
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SyncedTabDelegate* GetTabAt(int index) const OVERRIDE {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tab_overrides_.find(index) != tab_overrides_.end())
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return tab_overrides_.find(index)->second;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabAt(index);
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OverrideTabAt(int index,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     SyncedTabDelegate* delegate,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     SessionID::id_type tab_id) {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_overrides_[index] = delegate;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_id_overrides_[index] = tab_id;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual SessionID::id_type GetTabIdAt(int index) const OVERRIDE {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tab_id_overrides_.find(index) != tab_id_overrides_.end())
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return tab_id_overrides_.find(index)->second;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->GetTabIdAt(index);
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool IsSessionRestoreInProgress() const OVERRIDE {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return wrapped_->IsSessionRestoreInProgress();
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, SyncedTabDelegate*> tab_overrides_;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, SessionID::id_type> tab_id_overrides_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedWindowDelegate* wrapped_;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSyncedWindowDelegatesGetter(
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::set<SyncedWindowDelegate*>& delegates)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : delegates_(delegates) {}
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual const std::set<SyncedWindowDelegate*> GetSyncedWindowDelegates()
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return delegates_;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::set<SyncedWindowDelegate*> delegates_;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : output_(output) {}
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual syncer::SyncError ProcessSyncChanges(
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const tracked_objects::Location& from_here,
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const syncer::SyncChangeList& change_list) OVERRIDE {
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (error_.IsSet()) {
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      syncer::SyncError error = error_;
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      error_ = syncer::SyncError();
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return error;
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (output_)
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      output_->insert(output_->end(), change_list.begin(), change_list.end());
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return syncer::SyncError();
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const OVERRIDE {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return sync_data_to_return_;
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void FailProcessSyncChangesWith(const syncer::SyncError& error) {
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    error_ = error;
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetSyncDataToReturn(const syncer::SyncDataList& data) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_data_to_return_ = data;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncError error_;
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList* output_;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncDataList sync_data_to_return_;
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)syncer::SyncChange MakeRemoteChange(
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int64 id,
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics,
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    SyncChange::SyncChangeType type) {
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(specifics);
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return syncer::SyncChange(
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      FROM_HERE,
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      type,
177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::SyncData::CreateRemoteData(
178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          id,
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          entity,
180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          base::Time(),
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::AttachmentIdList(),
182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::AttachmentServiceProxyForTest::Create()));
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AddTabsToChangeList(
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const std::vector<sync_pb::SessionSpecifics>& batch,
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      SyncChange::SyncChangeType type,
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      syncer::SyncChangeList* change_list) {
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics>::const_iterator iter;
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (iter = batch.begin();
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       iter != batch.end(); ++iter) {
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    sync_pb::EntitySpecifics entity;
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    entity.mutable_session()->CopyFrom(*iter);
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    change_list->push_back(syncer::SyncChange(
195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        type,
197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            iter->tab_node_id(),
199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            entity,
200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
201a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void AddTabsToSyncDataList(const std::vector<sync_pb::SessionSpecifics> tabs,
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                           syncer::SyncDataList* list) {
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = 0; i < tabs.size(); i++) {
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    sync_pb::EntitySpecifics entity;
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    entity.mutable_session()->CopyFrom(tabs[i]);
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    list->push_back(SyncData::CreateRemoteData(
212a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        i + 2,
213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        entity,
214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DummyRouter : public LocalSessionEventRouter {
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~DummyRouter() {}
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void StartRoutingTo(LocalSessionEventHandler* handler) OVERRIDE {}
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void Stop() OVERRIDE {}
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<LocalSessionEventRouter> NewDummyRouter() {
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return scoped_ptr<LocalSessionEventRouter>(new DummyRouter());
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SessionsSyncManagerTest
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public BrowserWithTestWindowTest {
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SessionsSyncManagerTest()
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : test_processor_(NULL) {
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    local_device_.reset(new LocalDeviceInfoProviderMock(
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "cache_guid",
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "Wayne Gretzky's Hacking Box",
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "Chromium 10k",
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "Chrome 10k",
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "device_id"));
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BrowserWithTestWindowTest::SetUp();
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    browser_sync::NotificationServiceSessionsRouter* router(
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new browser_sync::NotificationServiceSessionsRouter(
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            profile(), syncer::SyncableService::StartSyncFlare()));
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    manager_.reset(new SessionsSyncManager(profile(), local_device_.get(),
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      scoped_ptr<LocalSessionEventRouter>(router)));
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_ = NULL;
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->Reset();
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    manager_.reset();
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BrowserWithTestWindowTest::TearDown();
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const DeviceInfo* GetLocalDeviceInfo() {
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return local_device_->GetLocalDeviceInfo();
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager* manager() { return manager_.get(); }
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionSyncTestHelper* helper() { return &helper_; }
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LocalDeviceInfoProvider* local_device() { return local_device_.get(); }
2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  syncer::SyncChangeList* output) {
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_ = new TestSyncProcessorStub(output);
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    syncer::SyncMergeResult result = manager_->MergeDataAndStartSyncing(
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        syncer::SESSIONS, initial_data,
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        scoped_ptr<syncer::SyncChangeProcessor>(test_processor_),
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        scoped_ptr<syncer::SyncErrorFactory>(
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            new syncer::SyncErrorFactoryMock()));
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_FALSE(result.error().IsSet());
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void InitWithNoSyncData() {
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL);
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void TriggerProcessSyncChangesError() {
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    test_processor_->FailProcessSyncChangesWith(syncer::SyncError(
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error",
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        syncer::SESSIONS));
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetSyncData(const syncer::SyncDataList& data) {
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     test_processor_->SetSyncDataToReturn(data);
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList* FilterOutLocalHeaderChanges(
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SyncChangeList* list) {
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    syncer::SyncChangeList::iterator it = list->begin();
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool found = false;
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    while (it != list->end()) {
301e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      if (syncer::SyncDataLocal(it->sync_data()).GetTag() ==
302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          manager_->current_machine_tag()) {
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        EXPECT_TRUE(SyncChange::ACTION_ADD == it->change_type() ||
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                    SyncChange::ACTION_UPDATE == it->change_type());
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        it = list->erase(it);
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        found = true;
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      } else {
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ++it;
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(found);
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return list;
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<SessionsSyncManager> manager_;
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionSyncTestHelper helper_;
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestSyncProcessorStub* test_processor_;
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<LocalDeviceInfoProviderMock> local_device_;
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that the SyncSessionManager can properly fill in a SessionHeader.
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) {
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionHeader header_s;
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  header_s.set_client_name("Client 1");
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN);
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedSession session;
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Time time = base::Time::Now();
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::PopulateSessionHeaderFromSpecifics(
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      header_s, time, &session);
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ("Client 1", session.session_name);
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(SyncedSession::TYPE_WIN, session.device_type);
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(time, session.modified_time);
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test translation between protobuf types and chrome session types.
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, PopulateSessionWindow) {
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionWindow window_s;
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.add_tab(0);
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_s.set_selected_tab_index(1);
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag";
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedSession* session = manager()->session_tracker_.GetSession(tag);
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->session_tracker_.PutWindowInSession(tag, 0);
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->BuildSyncedSessionFromSpecifics(
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, window_s, base::Time(), session->windows[0]);
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, session->windows[0]->tabs.size());
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1, session->windows[0]->selected_tab_index);
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1, session->windows[0]->type);
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, manager()->session_tracker_.num_synced_sessions());
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U,
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            manager()->session_tracker_.num_synced_tabs(std::string("tag")));
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class SyncedTabDelegateFake : public SyncedTabDelegate {
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake() : current_entry_index_(0),
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            pending_entry_index_(-1),
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                            is_supervised_(false),
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            sync_id_(-1),
3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            blocked_navigations_(NULL) {}
3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~SyncedTabDelegateFake() {}
3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetCurrentEntryIndex() const OVERRIDE {
3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return current_entry_index_;
3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_current_entry_index(int i) {
3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    current_entry_index_ = i;
3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetEntryAtIndex(int i) const OVERRIDE {
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const int size = entries_.size();
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return (size < i + 1) ? NULL : entries_[i];
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AppendEntry(content::NavigationEntry* entry) {
3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    entries_.push_back(entry);
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetEntryCount() const OVERRIDE {
3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return entries_.size();
3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetPendingEntryIndex() const OVERRIDE {
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return pending_entry_index_;
3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_pending_entry_index(int i) {
3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending_entry_index_ = i;
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual SessionID::id_type GetWindowId() const OVERRIDE {
3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return SessionID::id_type();
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual SessionID::id_type GetSessionId() const OVERRIDE {
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return SessionID::id_type();
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsBeingDestroyed() const OVERRIDE { return false; }
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual Profile* profile() const OVERRIDE { return NULL; }
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetExtensionAppId() const OVERRIDE {
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetPendingEntry() const OVERRIDE {
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::NavigationEntry* GetActiveEntry() const OVERRIDE {
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool ProfileIsSupervised() const OVERRIDE {
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   return is_supervised_;
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void set_is_supervised(bool is_supervised) { is_supervised_ = is_supervised; }
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual const std::vector<const content::NavigationEntry*>*
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetBlockedNavigations() const OVERRIDE {
4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return blocked_navigations_;
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_blocked_navigations(
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::vector<const content::NavigationEntry*>* navs) {
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    blocked_navigations_ = navs;
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsPinned() const OVERRIDE {
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return false;
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool HasWebContents() const OVERRIDE {
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return false;
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual content::WebContents* GetWebContents() const OVERRIDE {
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return NULL;
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Session sync related methods.
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual int GetSyncId() const OVERRIDE {
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   return sync_id_;
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetSyncId(int sync_id) OVERRIDE {
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_id_ = sync_id;
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void reset() {
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    current_entry_index_ = 0;
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending_entry_index_ = -1;
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_id_ = -1;
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    entries_.clear();
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int current_entry_index_;
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int pending_entry_index_;
454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   bool is_supervised_;
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   int sync_id_;
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   std::vector<const content::NavigationEntry*>* blocked_navigations_;
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   ScopedVector<content::NavigationEntry> entries_;
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test that we exclude tabs with only chrome:// and file:// schemed navigations
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from ShouldSyncTab(..).
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, ValidTabs) {
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A null entry shouldn't crash.
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(NULL);
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.reset();
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A chrome:// entry isn't valid.
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("chrome://preferences/"));
4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A file:// entry isn't valid, even in addition to another entry.
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("file://bla"));
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry2);
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a valid scheme entry to tab, making the tab valid.
4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
4874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.google.com"));
4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry3);
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(sessions_util::ShouldSyncTab(tab));
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Make sure GetCurrentVirtualURL() returns the virtual URL of the pending
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entry if the current entry is pending.
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, GetCurrentVirtualURLPending) {
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("http://www.google.com"));
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry->GetVirtualURL(), manager()->GetCurrentVirtualURL(tab));
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Make sure GetCurrentVirtualURL() returns the virtual URL of the current
5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entry if the current entry is non-pending.
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, GetCurrentVirtualURLNonPending) {
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry(content::NavigationEntry::Create());
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry->SetVirtualURL(GURL("http://www.google.com"));
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry);
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry->GetVirtualURL(), manager()->GetCurrentVirtualURL(tab));
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime0 = base::Time::FromInternalValue(100);
5136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime1 = base::Time::FromInternalValue(110);
5146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime2 = base::Time::FromInternalValue(120);
5156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime3 = base::Time::FromInternalValue(130);
5166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime4 = base::Time::FromInternalValue(140);
5176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime5 = base::Time::FromInternalValue(150);
5186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime6 = base::Time::FromInternalValue(160);
5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime7 = base::Time::FromInternalValue(170);
5206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime8 = base::Time::FromInternalValue(180);
5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static const base::Time kTime9 = base::Time::FromInternalValue(190);
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Populate the mock tab delegate with some data and navigation
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// entries and make sure that setting a SessionTab from it preserves
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// those entries (and clobbers any existing data).
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegate) {
5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a tab with three valid entries.
5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetVirtualURL(GURL("http://www.google.com"));
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetTimestamp(kTime1);
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetHttpStatusCode(200);
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("http://www.noodle.com"));
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetTimestamp(kTime2);
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetHttpStatusCode(201);
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.doodle.com"));
5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetTimestamp(kTime3);
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetHttpStatusCode(202);
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry1);
5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry2);
5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry3);
5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.set_current_entry_index(2);
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTab session_tab;
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.window_id.set_id(1);
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_id.set_id(1);
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_visual_index = 1;
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.current_navigation_index = 1;
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.pinned = true;
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.extension_app_id = "app id";
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.user_agent_override = "override";
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.timestamp = kTime5;
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.navigations.push_back(
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      SerializedNavigationEntryTestHelper::CreateNavigation(
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "http://www.example.com", "Example"));
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.session_storage_persistent_id = "persistent id";
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime4, &session_tab);
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.window_id.id());
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_id.id());
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_visual_index);
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2, session_tab.current_navigation_index);
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(session_tab.pinned);
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.extension_app_id.empty());
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.user_agent_override.empty());
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime4, session_tab.timestamp);
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(3u, session_tab.navigations.size());
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry1->GetVirtualURL(),
5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].virtual_url());
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry2->GetVirtualURL(),
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].virtual_url());
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry3->GetVirtualURL(),
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].virtual_url());
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime1, session_tab.navigations[0].timestamp());
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime2, session_tab.navigations[1].timestamp());
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime3, session_tab.navigations[2].timestamp());
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(200, session_tab.navigations[0].http_status_code());
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(201, session_tab.navigations[1].http_status_code());
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(202, session_tab.navigations[2].http_status_code());
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].blocked_state());
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].blocked_state());
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_INVALID,
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].blocked_state());
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.session_storage_persistent_id.empty());
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Ensure the current_navigation_index gets set properly when the navigation
5936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// stack gets trucated to +/- 6 entries.
5946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegateNavigationIndex) {
5956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncedTabDelegateFake tab;
5966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry0(content::NavigationEntry::Create());
5976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetVirtualURL(GURL("http://www.google.com"));
5986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetTimestamp(kTime0);
5996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetHttpStatusCode(200);
6006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
6016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetVirtualURL(GURL("http://www.zoogle.com"));
6026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetTimestamp(kTime1);
6036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetHttpStatusCode(200);
6046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
6056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetVirtualURL(GURL("http://www.noogle.com"));
6066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetTimestamp(kTime2);
6076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetHttpStatusCode(200);
6086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
6096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.doogle.com"));
6106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetTimestamp(kTime3);
6116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetHttpStatusCode(200);
6126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry4(content::NavigationEntry::Create());
6136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry4->SetVirtualURL(GURL("http://www.yoogle.com"));
6146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry4->SetTimestamp(kTime4);
6156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry4->SetHttpStatusCode(200);
6166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry5(content::NavigationEntry::Create());
6176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry5->SetVirtualURL(GURL("http://www.foogle.com"));
6186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry5->SetTimestamp(kTime5);
6196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry5->SetHttpStatusCode(200);
6206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry6(content::NavigationEntry::Create());
6216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry6->SetVirtualURL(GURL("http://www.boogle.com"));
6226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry6->SetTimestamp(kTime6);
6236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry6->SetHttpStatusCode(200);
6246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry7(content::NavigationEntry::Create());
6256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry7->SetVirtualURL(GURL("http://www.moogle.com"));
6266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry7->SetTimestamp(kTime7);
6276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry7->SetHttpStatusCode(200);
6286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry8(content::NavigationEntry::Create());
6296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry8->SetVirtualURL(GURL("http://www.poogle.com"));
6306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry8->SetTimestamp(kTime8);
6316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry8->SetHttpStatusCode(200);
6326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry9(content::NavigationEntry::Create());
6336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry9->SetVirtualURL(GURL("http://www.roogle.com"));
6346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry9->SetTimestamp(kTime9);
6356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry9->SetHttpStatusCode(200);
6366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry0);
6386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry1);
6396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry2);
6406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry3);
6416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry4);
6426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry5);
6436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry6);
6446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry7);
6456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry8);
6466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry9);
6476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.set_current_entry_index(8);
6486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SessionTab session_tab;
6506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime9, &session_tab);
6516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(6, session_tab.current_navigation_index);
6536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_EQ(8u, session_tab.navigations.size());
6546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(entry2->GetVirtualURL(),
6556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            session_tab.navigations[0].virtual_url());
6566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(entry3->GetVirtualURL(),
6576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            session_tab.navigations[1].virtual_url());
6586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(entry4->GetVirtualURL(),
6596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            session_tab.navigations[2].virtual_url());
6606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
6616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Ensure the current_navigation_index gets set to the end of the navigation
6636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// stack if the current navigation is invalid.
6646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegateCurrentInvalid) {
6656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncedTabDelegateFake tab;
6666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry0(content::NavigationEntry::Create());
6676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetVirtualURL(GURL("http://www.google.com"));
6686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetTimestamp(kTime0);
6696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry0->SetHttpStatusCode(200);
6706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
6716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetVirtualURL(GURL(""));
6726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetTimestamp(kTime1);
6736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry1->SetHttpStatusCode(200);
6746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry2(content::NavigationEntry::Create());
6756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetVirtualURL(GURL("http://www.noogle.com"));
6766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetTimestamp(kTime2);
6776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry2->SetHttpStatusCode(200);
6786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  content::NavigationEntry* entry3(content::NavigationEntry::Create());
6796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetVirtualURL(GURL("http://www.doogle.com"));
6806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetTimestamp(kTime3);
6816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  entry3->SetHttpStatusCode(200);
6826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry0);
6846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry1);
6856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry2);
6866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.AppendEntry(entry3);
6876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  tab.set_current_entry_index(1);
6886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SessionTab session_tab;
6906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime9, &session_tab);
6916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(2, session_tab.current_navigation_index);
6936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_EQ(3u, session_tab.navigations.size());
6946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
6956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Tests that for supervised users blocked navigations are recorded and marked
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// as such, while regular navigations are marked as allowed.
6984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, BlockedNavigations) {
6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncedTabDelegateFake tab;
7004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry1(content::NavigationEntry::Create());
7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetVirtualURL(GURL("http://www.google.com"));
7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry1->SetTimestamp(kTime1);
7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.AppendEntry(entry1);
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry2 = content::NavigationEntry::Create();
7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetVirtualURL(GURL("http://blocked.com/foo"));
7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry2->SetTimestamp(kTime2);
7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::NavigationEntry* entry3 = content::NavigationEntry::Create();
7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetVirtualURL(GURL("http://evil.com"));
7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entry3->SetTimestamp(kTime3);
7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<const content::NavigationEntry> blocked_navigations;
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_navigations.push_back(entry2);
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_navigations.push_back(entry3);
7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  tab.set_is_supervised(true);
7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tab.set_blocked_navigations(&blocked_navigations.get());
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTab session_tab;
7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.window_id.set_id(1);
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_id.set_id(1);
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.tab_visual_index = 1;
7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.current_navigation_index = 1;
7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.pinned = true;
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.extension_app_id = "app id";
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.user_agent_override = "override";
7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.timestamp = kTime5;
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.navigations.push_back(
7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      SerializedNavigationEntryTestHelper::CreateNavigation(
7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "http://www.example.com", "Example"));
7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_tab.session_storage_persistent_id = "persistent id";
7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->SetSessionTabFromDelegate(tab, kTime4, &session_tab);
7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.window_id.id());
7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_id.id());
7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.tab_visual_index);
7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, session_tab.current_navigation_index);
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(session_tab.pinned);
7384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.extension_app_id.empty());
7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.user_agent_override.empty());
7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime4, session_tab.timestamp);
7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(3u, session_tab.navigations.size());
7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry1->GetVirtualURL(),
7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].virtual_url());
7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry2->GetVirtualURL(),
7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].virtual_url());
7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(entry3->GetVirtualURL(),
7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].virtual_url());
7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime1, session_tab.navigations[0].timestamp());
7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime2, session_tab.navigations[1].timestamp());
7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTime3, session_tab.navigations[2].timestamp());
7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_ALLOWED,
7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[0].blocked_state());
7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_BLOCKED,
7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[1].blocked_state());
7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(SerializedNavigationEntry::STATE_BLOCKED,
7564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            session_tab.navigations[2].blocked_state());
7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(session_tab.session_storage_persistent_id.empty());
7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that the local session header objects is created properly in
761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// presence of no other session activity, once and only once.
7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeLocalSessionNoTabs) {
7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(manager()->current_machine_tag().empty());
7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2U, out.size());
7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].IsValid());
7690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data(out[0].sync_data());
771e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
772e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[1].IsValid());
7820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data_2(out[1].sync_data());
784e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
785e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s2.window_size());
7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Now take that header node and feed it in as input.
793a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
794a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
795a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      data.GetSpecifics(),
796a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
797a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
798a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  out.clear();
8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SessionsSyncManager manager2(profile(), local_device(), NewDummyRouter());
8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SESSIONS, in,
8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new TestSyncProcessorStub(&out)),
8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(result.error().IsSet());
8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1U, out.size());
8110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Ensure model association associates the pre-existing tabs.
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, SwappedOutOnRestore) {
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://bar1"));
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), GURL("http://baz1"));
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://baz2"));
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kRestoredTabId = 1337;
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNewTabId = 2468;
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncDataList in;
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList out;
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitWithSyncDataTakeOutput(in, &out);
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should be one header add, 3 tab add/update pairs, one header update.
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(8U, out.size());
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For input, we set up:
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "normal" fully loaded tab
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "frozen" tab with no WebContents and a tab_id change
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // * one "frozen" tab with no WebContents and no tab_id change
837a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t0(SyncData::CreateRemoteData(
838a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
839a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      out[2].sync_data().GetSpecifics(),
840a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
841a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
842a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
8435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_pb::EntitySpecifics entity(out[4].sync_data().GetSpecifics());
8445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entity.mutable_session()->mutable_tab()->set_tab_id(kRestoredTabId);
845a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t1(SyncData::CreateRemoteData(
846a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      2,
847a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
848a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
849a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
850a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
851a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData t2(SyncData::CreateRemoteData(
852a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      3,
853a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      out[6].sync_data().GetSpecifics(),
854a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
855a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
856a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t0);
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t1);
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in.push_back(t2);
8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  out.clear();
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->StopSyncing(syncer::SESSIONS);
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::set<SyncedWindowDelegate*> windows(
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SyncedWindowDelegate::GetSyncedWindowDelegates());
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, windows.size());
8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedTabDelegateFake t1_override, t2_override;
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  t1_override.SetSyncId(1);  // No WebContents by default.
8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  t2_override.SetSyncId(2);  // No WebContents by default.
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncedWindowDelegateOverride window_override(*windows.begin());
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_override.OverrideTabAt(1, &t1_override, kNewTabId);
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_override.OverrideTabAt(2, &t2_override,
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                t2.GetSpecifics().session().tab().tab_id());
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::set<SyncedWindowDelegate*> delegates;
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegates.insert(&window_override);
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestSyncedWindowDelegatesGetter> getter(
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new TestSyncedWindowDelegatesGetter(delegates));
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->synced_window_getter_.reset(getter.release());
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncMergeResult result = manager()->MergeDataAndStartSyncing(
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      syncer::SESSIONS, in,
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new TestSyncProcessorStub(&out)),
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // There should be two changes, one for the fully associated tab, and
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // one for the tab_id update to t1.  t2 shouldn't need to be updated.
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2U, FilterOutLocalHeaderChanges(&out)->size());
8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kNewTabId,
8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            out[1].sync_data().GetSpecifics().session().tab().tab_id());
8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabLinks.
8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3U, tab_map.size());
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int t2_tab_id = t2.GetSpecifics().session().tab().tab_id();
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, tab_map.find(t2_tab_id)->second->tab_node_id());
8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, tab_map.find(kNewTabId)->second->tab_node_id());
9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int t0_tab_id = out[0].sync_data().GetSpecifics().session().tab().tab_id();
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, tab_map.find(t0_tab_id)->second->tab_node_id());
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(tim): Once bug 337057 is fixed, we can issue an OnLocalTabModified
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from here (using an override similar to above) to return a new tab id
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and verify that we don't see any node creations in the SyncChangeProcessor
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (similar to how SessionsSyncManagerTest.OnLocalTabModified works.)
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests MergeDataAndStartSyncing with sync data but no local data.
9094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeWithInitialForeignSession) {
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
9134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
9144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
9154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
9164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
9174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a second window.
9184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n2[] = {7, 15, 18, 20};
9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(n2, n2 + arraysize(n2));
9204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta);
9214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set up initial data.
9234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList initial_data;
9244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::EntitySpecifics entity;
9254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
926a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  initial_data.push_back(SyncData::CreateRemoteData(
927a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
928a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
929a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
930a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
931a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
9320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &initial_data);
9330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < tab_list2.size(); ++i) {
9354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sync_pb::EntitySpecifics entity;
9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->BuildTabSpecifics(tag, 0, tab_list2[i],
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                entity.mutable_session());
938a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_data.push_back(SyncData::CreateRemoteData(
939a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        i + 10,
940a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        entity,
941a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
942a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
943a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList output;
9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(initial_data, &output);
9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(FilterOutLocalHeaderChanges(&output)->empty());
9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
9514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
9520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
9534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
9544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
9554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list2);
9564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
9574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// This is a combination of MergeWithInitialForeignSession and
9600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// MergeLocalSessionExistingTabs. We repeat some checks performed in each of
9610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// those tests to ensure the common mixed scenario works.
9620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeWithLocalAndForeignTabs) {
9630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Local.
9640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
9650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
9660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Foreign.
9680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag = "tag1";
9690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
9700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
9710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
9720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
9730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tag, tab_list1, &tabs1));
9740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncDataList foreign_data;
9750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
9760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
977a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
978a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
979a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
980a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
981a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
982a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
9830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
9840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList output;
9860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
9870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, output.size());
9880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
9890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the local header.
9900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[0].IsValid());
9910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, output[0].change_type());
9920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const SyncData data(output[0].sync_data());
993e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
994e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
9950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
9960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
9970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
9980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
9990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
10000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
10010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
10020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the tab node creations and updates with content.
10040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (int i = 1; i < 3; i++) {
10050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_TRUE(output[i].IsValid());
10060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const SyncData data(output[i].sync_data());
1007e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
10080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                manager()->current_machine_tag(), true));
10090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
10100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
10110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
10120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, output[1].change_type());
10130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[2].change_type());
10140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[2].sync_data().GetSpecifics().session().has_tab());
10150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify the header was updated to reflect window state.
10170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(output[3].IsValid());
10180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[3].change_type());
10190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const SyncData data_2(output[3].sync_data());
1020e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1021e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
10220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
10230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
10240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
10250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
10260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(1, header_s2.window_size());
10270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Verify foreign data.
10290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
10300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
10310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
10320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  session_reference.push_back(tab_list1);
10330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
10340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // There should be one and only one foreign session. If VerifySyncedSession
10350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // was successful above this EXPECT call ensures the local session didn't
10360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // get mistakenly added to foreign tracking (Similar to ExistingTabs test).
10370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(1U, foreign_sessions.size());
10380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
10390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1040a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests the common scenario.  Merge with both local and foreign session data
1041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// followed by updates flowing from sync and local.
10420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, UpdatesAfterMixedMerge) {
10430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add local and foreign data.
10440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
10450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
10460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag1 = "tag1";
10480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncDataList foreign_data1;
10490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > meta1_reference;
10500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta1;
10510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
10530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
10540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference.push_back(tab_list1);
10550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
10560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1 = helper()->BuildForeignSession(tag1, tab_list1, &tabs1);
10570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
10580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta1);
10590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_data1.push_back(SyncData::CreateRemoteData(
1060a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1061a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
1062a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1063a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1064a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
10650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data1);
10660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList output1;
10680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data1, &output1);
10690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, output1.size());
10700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a second window to the foreign session.
10720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(tim): Bug 98892. Add local window too when observers are hooked up.
10730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type tab_nums2[] = {7, 15, 18, 20};
10740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(
10750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tab_nums2, tab_nums2 + arraysize(tab_nums2));
10760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference.push_back(tab_list2);
10770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta1);
10780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
10790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tabs2.resize(tab_list2.size());
10800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = 0; i < tab_list2.size(); ++i) {
10810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    helper()->BuildTabSpecifics(tag1, 0, tab_list2[i], &tabs2[i]);
10820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
10830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
10850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE));
10860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes);
10870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
10880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
10890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
10910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
10920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
10930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
10940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
10950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(1)->second->tabs.size());
10960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag1, meta1_reference, *(foreign_sessions[0]));
10970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
10980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a new foreign session.
10990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::string tag2 = "tag2";
11000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n2[] = {107, 115};
11010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tag2_tab_list(n2, n2 + arraysize(n2));
11020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tag2_tabs;
11030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta2(helper()->BuildForeignSession(
11040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      tag2, tag2_tab_list, &tag2_tabs));
11050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(100, meta2, SyncChange::ACTION_ADD));
11060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tag2_tabs, SyncChange::ACTION_ADD, &changes);
11070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
11080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
11090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
11100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
11110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
11120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > meta2_reference;
11130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta2_reference.push_back(tag2_tab_list);
11140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
11150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions[1]->windows.find(0)->second->tabs.size());
11160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag2, meta2_reference, *(foreign_sessions[1]));
11170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_sessions.clear();
11180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
11190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Remove a tab from a window.
11200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  meta1_reference[0].pop_back();
11210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tab_list1.pop_back();
11220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionWindow* win = meta1.mutable_header()->mutable_window(0);
11230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  win->clear_tab();
11240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (std::vector<int>::const_iterator iter = tab_list1.begin();
11250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)       iter != tab_list1.end(); ++iter) {
11260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    win->add_tab(*iter);
11270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
11280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList removal;
11290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  removal.push_back(MakeRemoteChange(1, meta1, SyncChange::ACTION_UPDATE));
11300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_UPDATE, &removal);
11310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, removal);
11320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
11330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
11340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
11350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(3U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
11360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  helper()->VerifySyncedSession(tag1, meta1_reference, *(foreign_sessions[0]));
11370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
11380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that this SyncSessionManager knows how to delete foreign sessions
1140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// if it wants to.
11414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, DeleteForeignSession) {
11424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
11434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
11444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
11454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
11474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
1148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  manager()->DeleteForeignSessionInternal(tag, &changes);
11494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
11504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(changes.empty());
11514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   // Fill an instance of session specifics with a foreign session's data.
11534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs;
11544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
11554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_nums1(n1, n1 + arraysize(n1));
11564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
11574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_nums1, &tabs));
11584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update associator with the session's meta node, window, and tabs.
11604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->UpdateTrackerWithForeignSession(meta, base::Time());
11614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs.begin();
11624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != tabs.end(); ++iter) {
11634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    manager()->UpdateTrackerWithForeignSession(*iter, base::Time());
11644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
11664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
11674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Now delete the foreign session.
1169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  manager()->DeleteForeignSessionInternal(tag, &changes);
11704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
11714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(5U, changes.size());
11734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::set<std::string> expected_tags(&tag, &tag + 1);
11744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < 5; i++)
11750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    expected_tags.insert(TabNodePool::TabIdToTag(tag, i));
11764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
11784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SCOPED_TRACE(changes[i].ToString());
11794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(changes[i].IsValid());
11800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    EXPECT_EQ(SyncChange::ACTION_DELETE, changes[i].change_type());
11814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(changes[i].sync_data().IsValid());
1182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_EQ(1U,
1183e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              expected_tags.erase(
1184e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                  syncer::SyncDataLocal(changes[i].sync_data()).GetTag()));
11854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Write a foreign session to a node, with the tabs arriving first, and then
11894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// retrieve it.
11904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, WriteForeignSessionToNodeTabsFirst) {
11914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
11924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fill an instance of session specifics with a foreign session's data.
11944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
11954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type nums1[] = {5, 10, 13, 17};
11964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
11974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1 (nums1, nums1 + arraysize(nums1));
11984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
11994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
12004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList adds;
12020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add tabs for first window, then the meta node.
12030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &adds);
12040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  adds.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
12050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, adds);
12064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
12084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
12094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
12104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
12114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
12124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
12134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
12144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
12154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Write a foreign session to a node with some tabs that never arrive.
12174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, WriteForeignSessionToNodeMissingTabs) {
12184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
12194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fill an instance of session specifics with a foreign session's data.
12214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tag = "tag1";
12224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type nums1[] = {5, 10, 13, 17};
12234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
12244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list1 (nums1, nums1 + arraysize(nums1));
12254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
12264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tag, tab_list1, &tabs1));
12274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a second window, but this time only create two tab nodes, despite the
12284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // window expecting four tabs.
12294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionID::id_type tab_nums2[] = {7, 15, 18, 20};
12304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(
12314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      tab_nums2, tab_nums2 + arraysize(tab_nums2));
12324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta);
12334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
12344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  tabs2.resize(2);
12354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < 2; ++i) {
12364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    helper()->BuildTabSpecifics(tag, 0, tab_list2[i], &tabs2[i]);
12374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
12384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
12400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
12410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
12420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs2, SyncChange::ACTION_ADD, &changes);
12430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
12440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
12454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
12474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
12484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
12494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
12504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions[0]->windows.size());
12514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(0)->second->tabs.size());
12524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, foreign_sessions[0]->windows.find(1)->second->tabs.size());
12534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Close the second window.
12554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  meta.mutable_header()->clear_window();
12564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->AddWindowSpecifics(0, tab_list1, &meta);
12570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_UPDATE));
12584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update associator with the session's meta node containing one window.
12590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
12604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
12624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  foreign_sessions.clear();
12634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
12644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
12654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions[0]->windows.size());
12664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
12674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_reference.push_back(tab_list1);
12684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper()->VerifySyncedSession(tag, session_reference, *(foreign_sessions[0]));
12694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
12704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that the SessionsSyncManager can handle a remote client deleting
12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// sync nodes that belong to this local session.
12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ProcessRemoteDeleteOfLocalSession) {
12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList out;
12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());
12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_pb::EntitySpecifics entity(out[0].sync_data().GetSpecifics());
1278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
1279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1280a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
1281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1282a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1283a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetSyncData(syncer::SyncDataList(&d, &d + 1));
12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  out.clear();
12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  syncer::SyncChangeList changes;
12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  changes.push_back(
12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MakeRemoteChange(1, entity.session(), SyncChange::ACTION_DELETE));
12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager()->local_tab_pool_out_of_sync_);
12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(out.empty());  // ChangeProcessor shouldn't see any activity.
12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This should trigger repair of the TabNodePool.
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL foo1("http://foo/1");
12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddTab(browser(), foo1);
12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(manager()->local_tab_pool_out_of_sync_);
12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AddTab triggers two notifications, one for the tab insertion and one for
13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // committing the NavigationEntry. The first notification results in a tab
13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we don't associate although we do update the header node.  The second
13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // notification triggers association of the tab, and the subsequent window
13035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // update.  So we should see 4 changes at the SyncChangeProcessor.
13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(4U, out.size());
13055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[1].change_type());
13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int tab_node_id = out[1].sync_data().GetSpecifics().session().tab_node_id();
13100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(TabNodePool::TabIdToTag(
13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                manager()->current_machine_tag(), tab_node_id),
1312e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(out[1].sync_data()).GetTag());
13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_tab());
13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[3].change_type());
13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(out[3].sync_data().GetSpecifics().session().has_header());
13175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify the actual content.
13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const sync_pb::SessionHeader& session_header =
13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      out[3].sync_data().GetSpecifics().session().header();
13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, session_header.window_size());
13225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, session_header.window(0).tab_size());
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const sync_pb::SessionTab& tab1 =
13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      out[2].sync_data().GetSpecifics().session().tab();
13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, tab1.navigation_size());
13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1.navigation(0).virtual_url());
13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabNodePool integrity.
13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, manager()->local_tab_pool_.Capacity());
13305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(manager()->local_tab_pool_.Empty());
13315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify TabLinks.
13335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
13345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, tab_map.size());
13355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int tab_id = out[2].sync_data().GetSpecifics().session().tab().tab_id();
13365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(tab_node_id, tab_map.find(tab_id)->second->tab_node_id());
13375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that receiving a session delete from sync removes the session
1340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// from tracking.
13410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ProcessForeignDelete) {
13420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithNoSyncData();
13430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n[] = {5};
13440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
13450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
13460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
13470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      "tag1", tab_list, &tabs1));
13480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
13490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
13500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
13510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
13520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
13530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
13540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
13550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
13560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
13570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
13580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
13590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  foreign_sessions.clear();
13600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE));
13610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
13620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
13630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
13640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
13650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
13664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(shashishekhar): "Move this to TabNodePool unittests."
13674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, SaveUnassociatedNodesForReassociation) {
13684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
13694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
13704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
13714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string local_tag = manager()->current_machine_tag();
13724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a free node and then dissassociate sessions so that it ends up
13734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unassociated.
13744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  manager()->local_tab_pool_.GetFreeTabNode(&changes);
13754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
13764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update the tab_id of the node, so that it is considered a valid
13774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unassociated node otherwise it will be mistaken for a corrupted node and
13784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will be deleted before being added to the tab node pool.
13794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics());
13804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  entity.mutable_session()->mutable_tab()->set_tab_id(1);
1381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SyncData d(SyncData::CreateRemoteData(
1382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity,
1384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
13874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
13884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  changes.clear();
13895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SessionsSyncManager manager2(profile(), local_device(), NewDummyRouter());
13904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
13914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      syncer::SESSIONS, in,
13924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncChangeProcessor>(
13934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new TestSyncProcessorStub(&changes)),
13944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<syncer::SyncErrorFactory>(
13954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          new syncer::SyncErrorFactoryMock()));
13964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(result.error().IsSet());
13974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty());
13984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
13994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) {
14014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList changes;
14024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithNoSyncData();
14034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string local_tag = manager()->current_machine_tag();
14054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes);
14064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncData d(SyncData::CreateRemoteData(
1407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      changes[0].sync_data().GetSpecifics(),
1409a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1411a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
14124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList in(&d, &d + 1);
14134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  changes.clear();
14144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TearDown();
14154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetUp();
14164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(in, &changes);
14174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size());
14180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type());
14190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(TabNodePool::TabIdToTag(local_tag, tab_node_id),
1420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(changes[0].sync_data()).GetTag());
14214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
14224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that things work if a tab is initially ignored.
14244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, AssociateWindowsDontReloadTabs) {
14254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
14264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Go to a URL that is ignored by session syncing.
14274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("chrome://preferences/"));
14284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());  // Header add and update.
14304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(
14314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      0,
14324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      out[1].sync_data().GetSpecifics().session().header().window_size());
14334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  out.clear();
14344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
14354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Go to a sync-interesting URL.
14364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
14374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(3U, out.size());  // Tab add, update, and header update.
14394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1440e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_TRUE(
1441e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      StartsWithASCII(syncer::SyncDataLocal(out[0].sync_data()).GetTag(),
1442e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      manager()->current_machine_tag(),
1443e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      true));
14444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(),
14454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            out[0].sync_data().GetSpecifics().session().session_tag());
14460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
14474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1448e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_TRUE(
1449e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      StartsWithASCII(syncer::SyncDataLocal(out[1].sync_data()).GetTag(),
1450e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      manager()->current_machine_tag(),
1451e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      true));
14524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(),
14534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            out[1].sync_data().GetSpecifics().session().session_tag());
14544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab());
14550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
14564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(out[2].IsValid());
1458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
1459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const SyncData data(out[2].sync_data());
1460e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1461e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
14624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
14634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
14644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
14654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
14664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s.window_size());
14674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s.window(0).tab_size());
14684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
14694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that the SyncSessionManager responds to local tab events properly.
1471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, OnLocalTabModified) {
1472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList out;
1473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Init with no local data, relies on MergeLocalSessionNoTabs.
1474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
1475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(manager()->current_machine_tag().empty());
1476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, out.size());
1477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Copy the original header.
1479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics header(out[0].sync_data().GetSpecifics());
1480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  out.clear();
1481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL foo1("http://foo/1");
1483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL foo2("http://foo/2");
1484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL bar1("http://bar/1");
1485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL bar2("http://bar/2");
1486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), foo1);
1487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(foo2);
1488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), bar1);
1489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(bar2);
1490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One add, one update for each AddTab.
1492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One update for each NavigateAndCommit.
1493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // = 6 total tab updates.
1494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // One header update corresponding to each of those.
1495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // = 6 total header updates.
1496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 12 total updates.
1497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(12U, out.size());
1498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the tab node creations and updates to ensure the SyncProcessor
1500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // sees the right operations.
1501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (int i = 0; i < 12; i++) {
1502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SCOPED_TRACE(i);
1503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(out[i].IsValid());
1504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncData data(out[i].sync_data());
1505e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
1506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                manager()->current_machine_tag(), true));
1507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
1508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
1509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (i % 6 == 0) {
1510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // First thing on an AddTab is a no-op header update for parented tab.
1511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(header.SerializeAsString(),
1512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                data.GetSpecifics().SerializeAsString());
1513e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      EXPECT_EQ(manager()->current_machine_tag(),
1514e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 1) {
1516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Next, the TabNodePool should create the tab node.
1517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
15180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
15195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
15205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1521e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 2) {
1523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Then we see the tab update to the URL.
1524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
15250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
15265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
15275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1528e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_tab());
1530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 3) {
1531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // The header needs to be updated to reflect the new window state.
1532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_TRUE(specifics.has_header());
1534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 4) {
1535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Now we move on to NavigateAndCommit.  Update the tab.
1536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
15370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(TabNodePool::TabIdToTag(
15385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    manager()->current_machine_tag(),
15395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    data.GetSpecifics().session().tab_node_id()),
1540e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                syncer::SyncDataLocal(data).GetTag());
1541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_tab());
1542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (i % 6 == 5) {
1543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // The header needs to be updated to reflect the new window state.
1544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
1545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ASSERT_TRUE(specifics.has_header());
1546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      header = data.GetSpecifics();
1547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the actual content to ensure sync sees the right data.
1551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // When it's all said and done, the header should reflect two tabs.
1552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionHeader& session_header = header.session().header();
1553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, session_header.window_size());
1554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2, session_header.window(0).tab_size());
1555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ASSERT_TRUEs above allow us to dive in freely here.
1557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify first tab.
1558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab1_1 =
1559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[2].sync_data().GetSpecifics().session().tab();
1560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, tab1_1.navigation_size());
1561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1_1.navigation(0).virtual_url());
1562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab1_2 =
1563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[4].sync_data().GetSpecifics().session().tab();
1564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2, tab1_2.navigation_size());
1565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo1.spec(), tab1_2.navigation(0).virtual_url());
1566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(foo2.spec(), tab1_2.navigation(1).virtual_url());
1567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1568a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify second tab.
1569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab2_1 =
1570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[8].sync_data().GetSpecifics().session().tab();
1571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, tab2_1.navigation_size());
1572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar1.spec(), tab2_1.navigation(0).virtual_url());
1573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const sync_pb::SessionTab& tab2_2 =
1574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      out[10].sync_data().GetSpecifics().session().tab();
1575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2, tab2_2.navigation_size());
1576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar1.spec(), tab2_2.navigation(0).virtual_url());
1577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(bar2.spec(), tab2_2.navigation(1).virtual_url());
1578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
15804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Ensure model association associates the pre-existing tabs.
15814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, MergeLocalSessionExistingTabs) {
15824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
1583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));  // Adds back entry.
15844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://bar1"));
1585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));  // Adds back entry.
15864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
15884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
15894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(6U, out.size());
15904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that this machine's data is not included in the foreign windows.
15924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
15934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(manager()->GetAllForeignSessions(&foreign_sessions));
15944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the header.
15964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[0].IsValid());
15970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
15984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data(out[0].sync_data());
1599e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1600e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data).GetTag());
16014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
16024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
16034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics.has_header());
16044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s = specifics.header();
16054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(header_s.has_device_type());
16064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GetLocalDeviceInfo()->client_name(), header_s.client_name());
16074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, header_s.window_size());
16084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the tab node creations and updates with content.
16104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 1; i < 5; i++) {
16114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_TRUE(out[i].IsValid());
16124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const SyncData data(out[i].sync_data());
1613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_TRUE(StartsWithASCII(syncer::SyncDataLocal(data).GetTag(),
16144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                manager()->current_machine_tag(), true));
16154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
16164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
16174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (i % 2 == 1) {
16180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
16194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
16200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
16214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      EXPECT_TRUE(specifics.has_tab());
16224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
16234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
16244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify the header was updated to reflect new window state.
16264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(out[5].IsValid());
16270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
16284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const SyncData data_2(out[5].sync_data());
1629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(manager()->current_machine_tag(),
1630e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            syncer::SyncDataLocal(data_2).GetTag());
16314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
16324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(manager()->current_machine_tag(), specifics2.session_tag());
16334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(specifics2.has_header());
16344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const sync_pb::SessionHeader& header_s2 = specifics2.header();
16354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, header_s2.window_size());
16364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify TabLinks.
16384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
16394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2U, tab_map.size());
16404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Tabs are ordered by sessionid in tab_map, so should be able to traverse
16414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the tree based on order of tabs created
16424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionsSyncManager::TabLinksMap::iterator iter = tab_map.begin();
16434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
16444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://foo1"), iter->second->tab()->
16454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          GetEntryAtIndex(0)->GetVirtualURL());
16464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://foo2"), iter->second->tab()->
16474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          GetEntryAtIndex(1)->GetVirtualURL());
16484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iter++;
16494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
16504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://bar1"), iter->second->tab()->
16514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetEntryAtIndex(0)->GetVirtualURL());
16524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(GURL("http://bar2"), iter->second->tab()->
16534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetEntryAtIndex(1)->GetVirtualURL());
16544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
16554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test garbage collection of stale foreign sessions.
1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, DoGarbageCollection) {
1658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Fill two instances of session specifics with a foreign session's data.
1659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag1 = "tag1";
1660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
1661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
1662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
1663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, tab_list1, &tabs1));
1665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag2 = "tag2";
1666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n2[] = {8, 15, 18, 20};
1667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(n2, n2 + arraysize(n2));
1668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs2;
1669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta2(helper()->BuildForeignSession(
1670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag2, tab_list2, &tabs2));
1671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the modification time for tag1 to be 21 days ago, tag2 to 5 days ago.
1672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag1_time = base::Time::Now() - base::TimeDelta::FromDays(21);
1673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag2_time = base::Time::Now() - base::TimeDelta::FromDays(5);
1674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncDataList foreign_data;
1676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics entity1, entity2;
1677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity1.mutable_session()->CopyFrom(meta);
1678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity2.mutable_session()->CopyFrom(meta2);
1679a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1680a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity1,
1682a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag1_time,
1683a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1684a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1685a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1686a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1687a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity2,
1688a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag2_time,
1689a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1690a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
1692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs2, &foreign_data);
1693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList output;
1695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
1696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, output.size());
1697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  output.clear();
1698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
1700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
1701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, foreign_sessions.size());
1703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  foreign_sessions.clear();
1704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Now garbage collect and verify the non-stale session is still there.
1706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->DoGarbageCollection();
1707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(5U, output.size());
1708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_DELETE, output[0].change_type());
1709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const SyncData data(output[0].sync_data());
1710e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(tag1, syncer::SyncDataLocal(data).GetTag());
1711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (int i = 1; i < 5; i++) {
1712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SyncChange::ACTION_DELETE, output[i].change_type());
1713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyncData data(output[i].sync_data());
17140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(TabNodePool::TabIdToTag(tag1, i),
1715e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              syncer::SyncDataLocal(data).GetTag());
1716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
1721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  session_reference.push_back(tab_list2);
1722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  helper()->VerifySyncedSession(tag2, session_reference,
1723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                *(foreign_sessions[0]));
1724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that an update to a previously considered "stale" session,
1727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// prior to garbage collection, will save the session from deletion.
1728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, GarbageCollectionHonoursUpdate) {
1729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string tag1 = "tag1";
1730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 13, 17};
1731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
1732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
1733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, tab_list1, &tabs1));
1735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncDataList foreign_data;
1736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics entity1;
1737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Time tag1_time = base::Time::Now() - base::TimeDelta::FromDays(21);
1738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entity1.mutable_session()->CopyFrom(meta);
1739a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  foreign_data.push_back(SyncData::CreateRemoteData(
1740a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1741a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity1,
1742a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      tag1_time,
1743a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1744a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
1745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &foreign_data);
1746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList output;
1747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithSyncDataTakeOutput(foreign_data, &output);
1748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, output.size());
1749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Update to a non-stale time.
1751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_pb::EntitySpecifics update_entity;
1752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update_entity.mutable_session()->CopyFrom(tabs1[0]);
1753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  syncer::SyncChangeList changes;
1754a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  changes.push_back(
1755a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::SyncChange(FROM_HERE,
1756a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                         SyncChange::ACTION_UPDATE,
1757a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                         syncer::SyncData::CreateRemoteData(
1758a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             1,
1759a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             update_entity,
1760a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             base::Time::Now(),
1761a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             syncer::AttachmentIdList(),
1762a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             syncer::AttachmentServiceProxyForTest::Create())));
1763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
1764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check that the foreign session was associated and retrieve the data.
1766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<const SyncedSession*> foreign_sessions;
1767a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1768a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  foreign_sessions.clear();
1770a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify the now non-stale session does not get deleted.
1772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  manager()->DoGarbageCollection();
1773a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
1774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1U, foreign_sessions.size());
1775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<std::vector<SessionID::id_type> > session_reference;
1776a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  session_reference.push_back(tab_list1);
1777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  helper()->VerifySyncedSession(
1778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      tag1, session_reference, *(foreign_sessions[0]));
1779a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1780a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1781a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that swapping WebContents for a tab is properly observed and handled
1782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// by the SessionsSyncManager.
17834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SessionsSyncManagerTest, CheckPrerenderedWebContentsSwap) {
17844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
17854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://foo2"));
17864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncChangeList out;
17884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
17894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_EQ(4U, out.size());  // Header, tab ADD, tab UPDATE, header UPDATE.
17904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // To simulate WebContents swap during prerendering, create new WebContents
17924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // and swap with old WebContents.
1793a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<content::WebContents> old_web_contents;
1794a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  old_web_contents.reset(browser()->tab_strip_model()->GetActiveWebContents());
17954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create new WebContents, with the required tab helpers.
17974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebContents* new_web_contents = WebContents::CreateWithSessionStorage(
17984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WebContents::CreateParams(profile()),
17994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      old_web_contents->GetController().GetSessionStorageNamespaceMap());
18004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SessionTabHelper::CreateForWebContents(new_web_contents);
18014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents);
18024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_web_contents->GetController()
18034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      .CopyStateFrom(old_web_contents->GetController());
18044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Swap the WebContents.
1806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int index = browser()->tab_strip_model()->GetIndexOfWebContents(
1807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      old_web_contents.get());
18084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents);
18094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1810a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(9U, out.size());
18110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type());
18120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
18134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Navigate away.
18154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar2"));
18164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Delete old WebContents. This should not crash.
1818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  old_web_contents.reset();
18194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Try more navigations and verify output size. This can also reveal
18214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // bugs (leaks) on memcheck bots if the SessionSyncManager
18224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // didn't properly clean up the tab pool or session tracker.
18234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar3"));
18244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddTab(browser(), GURL("http://bar4"));
18264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommitActiveTab(GURL("http://bar5"));
1827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(19U, out.size());
18284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
18294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace {
18310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SessionNotificationObserver : public content::NotificationObserver {
18320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionNotificationObserver() : notified_of_update_(false),
1834a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  notified_of_refresh_(false) {
18350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
18360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   content::NotificationService::AllSources());
1837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
1838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   content::NotificationService::AllSources());
18390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
18400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void Observe(int type,
18410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       const content::NotificationSource& source,
18420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
18430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    switch (type) {
18440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
18450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        notified_of_update_ = true;
18460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        break;
1847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case chrome::NOTIFICATION_SYNC_REFRESH_LOCAL:
1848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        notified_of_refresh_ = true;
1849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
18500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      default:
18510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        NOTREACHED();
18520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        break;
18530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
18540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
18550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool notified_of_update() const { return notified_of_update_; }
1856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool notified_of_refresh() const { return notified_of_refresh_; }
1857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Reset() {
1858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    notified_of_update_ = false;
1859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    notified_of_refresh_ = false;
1860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
18610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
18620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  content::NotificationRegistrar registrar_;
18630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool notified_of_update_;
1864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool notified_of_refresh_;
18650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
18660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace
18670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1868effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Test that NOTIFICATION_FOREIGN_SESSION_UPDATED is sent when processing
1869effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// sync changes.
18700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, NotifiedOfUpdates) {
18710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionNotificationObserver observer;
1872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(observer.notified_of_update());
18730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InitWithNoSyncData();
18740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
18750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SessionID::id_type n[] = {5};
18760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
18770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
18780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
18790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      "tag1", tab_list, &tabs1));
18800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
18810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  syncer::SyncChangeList changes;
18820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
18830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
18840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
18850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
18860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
18870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  observer.Reset();
18880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddTabsToChangeList(tabs1, SyncChange::ACTION_ADD, &changes);
18890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
18900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
18910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
18920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.clear();
18930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  observer.Reset();
18940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_DELETE));
18950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  manager()->ProcessSyncChanges(FROM_HERE, changes);
18960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_update());
18970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
18980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1899effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Test that NOTIFICATION_FOREIGN_SESSION_UPDATED is sent when handling
1900effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// local hide/removal of foreign session.
1901effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(SessionsSyncManagerTest, NotifiedOfLocalRemovalOfForeignSession) {
1902effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  InitWithNoSyncData();
1903effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const std::string tag("tag1");
1904effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SessionID::id_type n[] = {5};
1905effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<sync_pb::SessionSpecifics> tabs1;
1906effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<SessionID::id_type> tab_list(n, n + arraysize(n));
1907effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  sync_pb::SessionSpecifics meta(helper()->BuildForeignSession(
1908effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      tag, tab_list, &tabs1));
1909effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1910effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  syncer::SyncChangeList changes;
1911effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  changes.push_back(MakeRemoteChange(1, meta, SyncChange::ACTION_ADD));
1912effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager()->ProcessSyncChanges(FROM_HERE, changes);
1913effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1914effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SessionNotificationObserver observer;
1915effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_FALSE(observer.notified_of_update());
1916effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  manager()->DeleteForeignSession(tag);
1917effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(observer.notified_of_update());
1918effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1919effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1920a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS)
1921a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests that opening the other devices page triggers a session sync refresh.
1922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This page only exists on mobile platforms today; desktop has a
1923a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// search-enhanced NTP without other devices.
1924a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, NotifiedOfRefresh) {
1925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionNotificationObserver observer;
1926a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(observer.notified_of_refresh());
1927a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitWithNoSyncData();
1928a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddTab(browser(), GURL("http://foo1"));
1929a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(observer.notified_of_refresh());
1930a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NavigateAndCommitActiveTab(GURL("chrome://newtab/#open_tabs"));
1931a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(observer.notified_of_refresh());
1932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // defined(OS_ANDROID) || defined(OS_IOS)
1934a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
193503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests receipt of duplicate tab IDs in the same window.  This should never
193603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// happen, but we want to make sure the client won't do anything bad if it does
193703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// receive such garbage input data.
193803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ReceiveDuplicateTabInSameWindow) {
193903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string tag = "tag1";
194003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
194103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Reuse tab ID 10 in an attempt to trigger bad behavior.
194203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 10, 17};
194303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
194403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
194503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sync_pb::SessionSpecifics meta(
194603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      helper()->BuildForeignSession(tag, tab_list1, &tabs1));
194703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
194803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Set up initial data.
194903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  syncer::SyncDataList initial_data;
195003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
195103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
195203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  initial_data.push_back(SyncData::CreateRemoteData(
195303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      1,
195403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      entity,
195503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Time(),
195603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      syncer::AttachmentIdList(),
195703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      syncer::AttachmentServiceProxyForTest::Create()));
195803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &initial_data);
195903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
196003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  syncer::SyncChangeList output;
196103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  InitWithSyncDataTakeOutput(initial_data, &output);
196203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
196303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
196403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests receipt of duplicate tab IDs for the same session.  The duplicate tab
196503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ID is present in two different windows.  A client can't be expected to do
196603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// anything reasonable with this input, but we can expect that it doesn't
196703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// crash.
196803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(SessionsSyncManagerTest, ReceiveDuplicateTabInOtherWindow) {
196903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string tag = "tag1";
197003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
197103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SessionID::id_type n1[] = {5, 10, 17};
197203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list1(n1, n1 + arraysize(n1));
197303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<sync_pb::SessionSpecifics> tabs1;
197403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sync_pb::SessionSpecifics meta(
197503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      helper()->BuildForeignSession(tag, tab_list1, &tabs1));
197603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
197703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Add a second window.  Tab ID 10 is a duplicate.
197803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SessionID::id_type n2[] = {10, 18, 20};
197903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<SessionID::id_type> tab_list2(n2, n2 + arraysize(n2));
198003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  helper()->AddWindowSpecifics(1, tab_list2, &meta);
198103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
198203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Set up initial data.
198303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  syncer::SyncDataList initial_data;
198403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sync_pb::EntitySpecifics entity;
198503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  entity.mutable_session()->CopyFrom(meta);
198603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  initial_data.push_back(SyncData::CreateRemoteData(
198703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      1,
198803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      entity,
198903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Time(),
199003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      syncer::AttachmentIdList(),
199103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      syncer::AttachmentServiceProxyForTest::Create()));
199203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  AddTabsToSyncDataList(tabs1, &initial_data);
199303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
199403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < tab_list2.size(); ++i) {
199503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    sync_pb::EntitySpecifics entity;
199603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    helper()->BuildTabSpecifics(tag, 0, tab_list2[i], entity.mutable_session());
199703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    initial_data.push_back(SyncData::CreateRemoteData(
199803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        i + 10,
199903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        entity,
200003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Time(),
200103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        syncer::AttachmentIdList(),
200203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        syncer::AttachmentServiceProxyForTest::Create()));
200303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
200403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
200503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  syncer::SyncChangeList output;
200603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  InitWithSyncDataTakeOutput(initial_data, &output);
200703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
200803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace browser_sync
2010