1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_
6#define CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_
7
8#include <string>
9
10#include "base/callback.h"
11#include "base/compiler_specific.h"
12#include "base/memory/weak_ptr.h"
13#include "chrome/browser/invalidation/invalidator_storage.h"
14#include "chrome/browser/signin/oauth2_token_service.h"
15#include "chrome/browser/signin/profile_oauth2_token_service.h"
16#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
17#include "chrome/browser/sync/glue/data_type_manager_impl.h"
18#include "chrome/browser/sync/profile_sync_components_factory_mock.h"
19#include "chrome/browser/sync/profile_sync_service.h"
20#include "chrome/browser/sync/sync_prefs.h"
21#include "chrome/test/base/profile_mock.h"
22#include "sync/internal_api/public/test/test_internal_components_factory.h"
23#include "sync/test/engine/test_id_factory.h"
24#include "testing/gmock/include/gmock/gmock.h"
25
26class Profile;
27class Task;
28class TestProfileSyncService;
29
30ACTION(ReturnNewDataTypeManager) {
31  return new browser_sync::DataTypeManagerImpl(arg0,
32                                               arg1,
33                                               arg2,
34                                               arg3,
35                                               arg4,
36                                               arg5);
37}
38
39namespace browser_sync {
40
41class SyncBackendHostForProfileSyncTest : public SyncBackendHost {
42 public:
43  // |synchronous_init| causes initialization to block until the syncapi has
44  //     completed setting itself up and called us back.
45  // TOOD(akalin): Remove |synchronous_init| (http://crbug.com/140354).
46  SyncBackendHostForProfileSyncTest(
47      Profile* profile,
48      const base::WeakPtr<SyncPrefs>& sync_prefs,
49      syncer::TestIdFactory& id_factory,
50      base::Closure& callback,
51      bool set_initial_sync_ended_on_init,
52      bool synchronous_init,
53      bool fail_initial_download,
54      syncer::StorageOption storage_option);
55  virtual ~SyncBackendHostForProfileSyncTest();
56
57  MOCK_METHOD1(RequestNudge, void(const tracked_objects::Location&));
58
59  virtual void UpdateCredentials(
60      const syncer::SyncCredentials& credentials) OVERRIDE;
61
62  virtual void RequestConfigureSyncer(
63      syncer::ConfigureReason reason,
64      syncer::ModelTypeSet to_download,
65      syncer::ModelTypeSet to_purge,
66      syncer::ModelTypeSet to_journal,
67      syncer::ModelTypeSet to_unapply,
68      syncer::ModelTypeSet to_ignore,
69      const syncer::ModelSafeRoutingInfo& routing_info,
70      const base::Callback<void(syncer::ModelTypeSet,
71                                syncer::ModelTypeSet)>& ready_task,
72      const base::Closure& retry_callback) OVERRIDE;
73
74  virtual void HandleSyncManagerInitializationOnFrontendLoop(
75      const syncer::WeakHandle<syncer::JsBackend>& js_backend,
76      const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
77          debug_info_listener,
78      syncer::ModelTypeSet restored_types) OVERRIDE;
79
80  static void SetHistoryServiceExpectations(ProfileMock* profile);
81
82 protected:
83  virtual void InitCore(scoped_ptr<DoInitializeOptions> options) OVERRIDE;
84
85 private:
86  void ContinueInitialization(
87      const syncer::WeakHandle<syncer::JsBackend>& js_backend,
88      const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
89          debug_info_listener,
90      syncer::ModelTypeSet restored_types);
91
92  base::WeakPtrFactory<SyncBackendHostForProfileSyncTest> weak_ptr_factory_;
93
94  syncer::TestIdFactory& id_factory_;
95
96  // Invoked at the start of HandleSyncManagerInitializationOnFrontendLoop.
97  // Allows extra initialization work to be performed before the backend comes
98  // up.
99  base::Closure& callback_;
100
101  // Saved closure in case we failed the initial download but then received
102  // new credentials. Holds the results of
103  // HandleSyncManagerInitializationOnFrontendLoop, and if
104  // |fail_initial_download_| was true, finishes the initialization process
105  // once we receive new credentials.
106  base::Closure initial_download_closure_;
107  bool fail_initial_download_;
108
109  bool set_initial_sync_ended_on_init_;
110  bool synchronous_init_;
111  syncer::StorageOption storage_option_;
112};
113
114}  // namespace browser_sync
115
116class TestProfileSyncService : public ProfileSyncService {
117 public:
118  // TODO(tim): Remove |synchronous_backend_initialization|, and add ability to
119  // inject TokenService alongside SigninManager.
120  TestProfileSyncService(
121      ProfileSyncComponentsFactory* factory,
122      Profile* profile,
123      SigninManagerBase* signin,
124      ProfileSyncService::StartBehavior behavior,
125      bool synchronous_backend_initialization);
126
127  virtual ~TestProfileSyncService();
128
129  virtual void RequestAccessToken() OVERRIDE;
130  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
131      const GoogleServiceAuthError& error) OVERRIDE;
132
133  virtual void OnBackendInitialized(
134      const syncer::WeakHandle<syncer::JsBackend>& backend,
135      const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
136          debug_info_listener,
137      bool success) OVERRIDE;
138
139  virtual void OnConfigureDone(
140      const browser_sync::DataTypeManager::ConfigureResult& result) OVERRIDE;
141
142  // We implement our own version to avoid some DCHECKs.
143  virtual syncer::UserShare* GetUserShare() const OVERRIDE;
144
145  static BrowserContextKeyedService* BuildAutoStartAsyncInit(
146      content::BrowserContext* profile);
147
148  ProfileSyncComponentsFactoryMock* components_factory_mock();
149
150  // If this is called, configuring data types will require a syncer
151  // nudge.
152  void dont_set_initial_sync_ended_on_init();
153  void set_synchronous_sync_configuration();
154
155  // Fails initial download until a new auth token is provided.
156  void fail_initial_download();
157
158  void set_storage_option(syncer::StorageOption option);
159
160  // |callback| can be used to populate nodes before the OnBackendInitialized
161  // callback fires.
162  void set_backend_init_callback(const base::Closure& callback) {
163    callback_ = callback;
164  }
165
166  syncer::TestIdFactory* id_factory();
167
168  // Override of ProfileSyncService::GetBackendForTest() with a more
169  // specific return type (since C++ supports covariant return types)
170  // that is made public.
171  virtual browser_sync::SyncBackendHostForProfileSyncTest*
172      GetBackendForTest() OVERRIDE;
173
174 protected:
175  virtual void CreateBackend() OVERRIDE;
176
177  // Return NULL handle to use in backend initialization to avoid receiving
178  // js messages on UI loop when it's being destroyed, which are not deleted
179  // and cause memory leak in test.
180  virtual syncer::WeakHandle<syncer::JsEventHandler> GetJsEventHandler()
181      OVERRIDE;
182
183 private:
184  syncer::TestIdFactory id_factory_;
185
186  bool synchronous_backend_initialization_;
187
188  // Set to true when a mock data type manager is being used and the configure
189  // step is performed synchronously.
190  bool synchronous_sync_configuration_;
191
192  base::Closure callback_;
193  bool set_initial_sync_ended_on_init_;
194
195  bool fail_initial_download_;
196  syncer::StorageOption storage_option_;
197};
198
199
200class FakeOAuth2TokenService : public ProfileOAuth2TokenService {
201 public:
202  virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
203      const OAuth2TokenService::ScopeSet& scopes,
204      OAuth2TokenService::Consumer* consumer) OVERRIDE;
205
206  static BrowserContextKeyedService* BuildTokenService(
207      content::BrowserContext* context);
208};
209
210#endif  // CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_
211