Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / bookmark_data_type_controller_unittest.cc
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 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
14 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
15 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/history/history_service.h"
18 #include "chrome/browser/history/history_service_factory.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
21 #include "chrome/browser/sync/profile_sync_service_mock.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/profile_mock.h"
24 #include "components/bookmarks/browser/bookmark_model.h"
25 #include "components/bookmarks/test/bookmark_test_helpers.h"
26 #include "components/keyed_service/content/refcounted_browser_context_keyed_service.h"
27 #include "components/sync_driver/change_processor_mock.h"
28 #include "components/sync_driver/data_type_controller_mock.h"
29 #include "components/sync_driver/model_associator_mock.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #include "sync/api/sync_error.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36
37 using browser_sync::BookmarkDataTypeController;
38 using sync_driver::ChangeProcessorMock;
39 using sync_driver::DataTypeController;
40 using sync_driver::ModelAssociatorMock;
41 using sync_driver::ModelLoadCallbackMock;
42 using sync_driver::StartCallbackMock;
43 using testing::_;
44 using testing::DoAll;
45 using testing::InvokeWithoutArgs;
46 using testing::Return;
47 using testing::SetArgumentPointee;
48
49 namespace {
50
51 class HistoryMock : public HistoryService {
52  public:
53   explicit HistoryMock(history::HistoryClient* client, Profile* profile)
54       : HistoryService(client, profile) {}
55   MOCK_METHOD0(BackendLoaded, bool(void));
56
57  protected:
58   virtual ~HistoryMock() {}
59 };
60
61 KeyedService* BuildChromeBookmarkClient(content::BrowserContext* context) {
62   return new ChromeBookmarkClient(static_cast<Profile*>(context));
63 }
64
65 KeyedService* BuildBookmarkModelWithoutLoading(
66     content::BrowserContext* context) {
67   Profile* profile = static_cast<Profile*>(context);
68   ChromeBookmarkClient* bookmark_client =
69       ChromeBookmarkClientFactory::GetForProfile(profile);
70   BookmarkModel* bookmark_model = new BookmarkModel(bookmark_client, false);
71   bookmark_client->Init(bookmark_model);
72   return bookmark_model;
73 }
74
75 KeyedService* BuildBookmarkModel(content::BrowserContext* context) {
76   BookmarkModel* bookmark_model = static_cast<BookmarkModel*>(
77       BuildBookmarkModelWithoutLoading(context));
78   Profile* profile = static_cast<Profile*>(context);
79   bookmark_model->Load(profile->GetPrefs(),
80                        profile->GetPrefs()->GetString(prefs::kAcceptLanguages),
81                        profile->GetPath(),
82                        profile->GetIOTaskRunner(),
83                        content::BrowserThread::GetMessageLoopProxyForThread(
84                            content::BrowserThread::UI));
85   return bookmark_model;
86 }
87
88 KeyedService* BuildHistoryService(content::BrowserContext* profile) {
89   return new HistoryMock(NULL, static_cast<Profile*>(profile));
90 }
91
92 }  // namespace
93
94 class SyncBookmarkDataTypeControllerTest : public testing::Test {
95  public:
96   SyncBookmarkDataTypeControllerTest()
97       : thread_bundle_(content::TestBrowserThreadBundle::DEFAULT),
98         service_(&profile_) {}
99
100   virtual void SetUp() {
101     model_associator_ = new ModelAssociatorMock();
102     change_processor_ = new ChangeProcessorMock();
103     history_service_ = static_cast<HistoryMock*>(
104         HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
105             &profile_, BuildHistoryService));
106     profile_sync_factory_.reset(
107         new ProfileSyncComponentsFactoryMock(model_associator_,
108                                              change_processor_));
109     bookmark_dtc_ = new BookmarkDataTypeController(profile_sync_factory_.get(),
110                                                    &profile_,
111                                                    &service_);
112   }
113
114  protected:
115   enum BookmarkLoadPolicy {
116     DONT_LOAD_MODEL,
117     LOAD_MODEL,
118   };
119
120   void CreateBookmarkModel(BookmarkLoadPolicy bookmark_load_policy) {
121     ChromeBookmarkClientFactory::GetInstance()->SetTestingFactory(
122         &profile_, BuildChromeBookmarkClient);
123     if (bookmark_load_policy == LOAD_MODEL) {
124       bookmark_model_ = static_cast<BookmarkModel*>(
125           BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
126               &profile_, BuildBookmarkModel));
127       test::WaitForBookmarkModelToLoad(bookmark_model_);
128     } else {
129       bookmark_model_ = static_cast<BookmarkModel*>(
130           BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
131               &profile_, BuildBookmarkModelWithoutLoading));
132     }
133   }
134
135   void SetStartExpectations() {
136     EXPECT_CALL(*history_service_,
137                 BackendLoaded()).WillRepeatedly(Return(true));
138     EXPECT_CALL(model_load_callback_, Run(_, _));
139   }
140
141   void SetAssociateExpectations() {
142     EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
143         WillRepeatedly(Return(true));
144     EXPECT_CALL(*profile_sync_factory_, CreateBookmarkSyncComponents(_, _));
145     EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
146         WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
147     EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
148         WillRepeatedly(Return(syncer::SyncError()));
149   }
150
151   void SetStopExpectations() {
152     EXPECT_CALL(service_, DeactivateDataType(_));
153     EXPECT_CALL(*model_associator_, DisassociateModels()).
154                 WillOnce(Return(syncer::SyncError()));
155   }
156
157   void Start() {
158     bookmark_dtc_->LoadModels(
159         base::Bind(&ModelLoadCallbackMock::Run,
160                    base::Unretained(&model_load_callback_)));
161     bookmark_dtc_->StartAssociating(
162         base::Bind(&StartCallbackMock::Run,
163                    base::Unretained(&start_callback_)));
164   }
165
166   content::TestBrowserThreadBundle thread_bundle_;
167   scoped_refptr<BookmarkDataTypeController> bookmark_dtc_;
168   scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_;
169   ProfileMock profile_;
170   BookmarkModel* bookmark_model_;
171   HistoryMock* history_service_;
172   ProfileSyncServiceMock service_;
173   ModelAssociatorMock* model_associator_;
174   ChangeProcessorMock* change_processor_;
175   StartCallbackMock start_callback_;
176   ModelLoadCallbackMock model_load_callback_;
177 };
178
179 TEST_F(SyncBookmarkDataTypeControllerTest, StartDependentsReady) {
180   CreateBookmarkModel(LOAD_MODEL);
181   SetStartExpectations();
182   SetAssociateExpectations();
183
184   EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
185
186   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
187   Start();
188   EXPECT_EQ(DataTypeController::RUNNING, bookmark_dtc_->state());
189 }
190
191 TEST_F(SyncBookmarkDataTypeControllerTest, StartBookmarkModelNotReady) {
192   CreateBookmarkModel(DONT_LOAD_MODEL);
193   SetStartExpectations();
194   SetAssociateExpectations();
195
196   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
197   bookmark_dtc_->LoadModels(
198       base::Bind(&ModelLoadCallbackMock::Run,
199                  base::Unretained(&model_load_callback_)));
200   EXPECT_EQ(DataTypeController::MODEL_STARTING, bookmark_dtc_->state());
201
202   bookmark_model_->Load(profile_.GetPrefs(),
203                         profile_.GetPrefs()->GetString(prefs::kAcceptLanguages),
204                         profile_.GetPath(),
205                         profile_.GetIOTaskRunner(),
206                         content::BrowserThread::GetMessageLoopProxyForThread(
207                             content::BrowserThread::UI));
208   test::WaitForBookmarkModelToLoad(bookmark_model_);
209   EXPECT_EQ(DataTypeController::MODEL_LOADED, bookmark_dtc_->state());
210
211   bookmark_dtc_->StartAssociating(
212       base::Bind(&StartCallbackMock::Run,
213                  base::Unretained(&start_callback_)));
214
215   EXPECT_EQ(DataTypeController::RUNNING, bookmark_dtc_->state());
216 }
217
218 TEST_F(SyncBookmarkDataTypeControllerTest, StartHistoryServiceNotReady) {
219   CreateBookmarkModel(LOAD_MODEL);
220   SetStartExpectations();
221   EXPECT_CALL(*history_service_,
222               BackendLoaded()).WillRepeatedly(Return(false));
223
224   bookmark_dtc_->LoadModels(
225       base::Bind(&ModelLoadCallbackMock::Run,
226                  base::Unretained(&model_load_callback_)));
227
228   EXPECT_EQ(DataTypeController::MODEL_STARTING, bookmark_dtc_->state());
229   testing::Mock::VerifyAndClearExpectations(history_service_);
230   EXPECT_CALL(*history_service_, BackendLoaded()).WillRepeatedly(Return(true));
231
232   // Send the notification that the history service has finished loading the db.
233   content::NotificationService::current()->Notify(
234       chrome::NOTIFICATION_HISTORY_LOADED,
235       content::Source<Profile>(&profile_),
236       content::NotificationService::NoDetails());
237   EXPECT_EQ(DataTypeController::MODEL_LOADED, bookmark_dtc_->state());
238 }
239
240 TEST_F(SyncBookmarkDataTypeControllerTest, StartFirstRun) {
241   CreateBookmarkModel(LOAD_MODEL);
242   SetStartExpectations();
243   SetAssociateExpectations();
244   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
245       WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
246   EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
247   Start();
248 }
249
250 TEST_F(SyncBookmarkDataTypeControllerTest, StartBusy) {
251   CreateBookmarkModel(LOAD_MODEL);
252   EXPECT_CALL(*history_service_, BackendLoaded()).WillRepeatedly(Return(false));
253
254   EXPECT_CALL(model_load_callback_, Run(_, _));
255   bookmark_dtc_->LoadModels(
256       base::Bind(&ModelLoadCallbackMock::Run,
257                  base::Unretained(&model_load_callback_)));
258   bookmark_dtc_->LoadModels(
259       base::Bind(&ModelLoadCallbackMock::Run,
260                  base::Unretained(&model_load_callback_)));
261 }
262
263 TEST_F(SyncBookmarkDataTypeControllerTest, StartOk) {
264   CreateBookmarkModel(LOAD_MODEL);
265   SetStartExpectations();
266   SetAssociateExpectations();
267   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
268       WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
269
270   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
271   Start();
272 }
273
274 TEST_F(SyncBookmarkDataTypeControllerTest, StartAssociationFailed) {
275   CreateBookmarkModel(LOAD_MODEL);
276   SetStartExpectations();
277   // Set up association to fail.
278   EXPECT_CALL(*profile_sync_factory_, CreateBookmarkSyncComponents(_, _));
279   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
280       WillRepeatedly(Return(true));
281   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
282       WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
283   EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
284       WillRepeatedly(Return(syncer::SyncError(FROM_HERE,
285                                               syncer::SyncError::DATATYPE_ERROR,
286                                               "error",
287                                               syncer::BOOKMARKS)));
288
289   EXPECT_CALL(start_callback_,
290               Run(DataTypeController::ASSOCIATION_FAILED, _, _));
291   Start();
292   EXPECT_EQ(DataTypeController::DISABLED, bookmark_dtc_->state());
293 }
294
295 TEST_F(SyncBookmarkDataTypeControllerTest,
296        StartAssociationTriggersUnrecoverableError) {
297   CreateBookmarkModel(LOAD_MODEL);
298   SetStartExpectations();
299   // Set up association to fail with an unrecoverable error.
300   EXPECT_CALL(*profile_sync_factory_, CreateBookmarkSyncComponents(_, _));
301   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
302       WillRepeatedly(Return(true));
303   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
304       WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false)));
305   EXPECT_CALL(start_callback_,
306               Run(DataTypeController::UNRECOVERABLE_ERROR, _, _));
307   Start();
308   EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
309 }
310
311 TEST_F(SyncBookmarkDataTypeControllerTest, StartAborted) {
312   CreateBookmarkModel(LOAD_MODEL);
313   EXPECT_CALL(*history_service_, BackendLoaded()).WillRepeatedly(Return(false));
314
315   EXPECT_CALL(model_load_callback_, Run(_, _));
316   bookmark_dtc_->LoadModels(
317       base::Bind(&ModelLoadCallbackMock::Run,
318                  base::Unretained(&model_load_callback_)));
319
320   bookmark_dtc_->Stop();
321   EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
322 }
323
324 TEST_F(SyncBookmarkDataTypeControllerTest, Stop) {
325   CreateBookmarkModel(LOAD_MODEL);
326   SetStartExpectations();
327   SetAssociateExpectations();
328   SetStopExpectations();
329
330   EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
331
332   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
333   Start();
334   EXPECT_EQ(DataTypeController::RUNNING, bookmark_dtc_->state());
335   bookmark_dtc_->Stop();
336   EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
337 }