Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / frontend_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 "testing/gtest/include/gtest/gtest.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/message_loop/message_loop.h"
12 #include "base/tracked_objects.h"
13 #include "chrome/browser/sync/glue/frontend_data_type_controller.h"
14 #include "chrome/browser/sync/glue/frontend_data_type_controller_mock.h"
15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
16 #include "chrome/browser/sync/profile_sync_service_mock.h"
17 #include "chrome/test/base/profile_mock.h"
18 #include "components/sync_driver/change_processor_mock.h"
19 #include "components/sync_driver/data_type_controller_mock.h"
20 #include "components/sync_driver/model_associator_mock.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22
23 using browser_sync::FrontendDataTypeController;
24 using browser_sync::FrontendDataTypeControllerMock;
25 using sync_driver::ChangeProcessorMock;
26 using sync_driver::DataTypeController;
27 using sync_driver::ModelAssociatorMock;
28 using sync_driver::ModelLoadCallbackMock;
29 using sync_driver::StartCallbackMock;
30 using testing::_;
31 using testing::DoAll;
32 using testing::InvokeWithoutArgs;
33 using testing::Return;
34 using testing::SetArgumentPointee;
35 using testing::StrictMock;
36
37 class FrontendDataTypeControllerFake : public FrontendDataTypeController {
38  public:
39   FrontendDataTypeControllerFake(
40       ProfileSyncComponentsFactory* profile_sync_factory,
41       Profile* profile,
42       ProfileSyncService* sync_service,
43       FrontendDataTypeControllerMock* mock)
44       : FrontendDataTypeController(base::MessageLoopProxy::current(),
45                                    base::Closure(),
46                                    profile_sync_factory,
47                                    profile,
48                                    sync_service),
49         mock_(mock) {}
50   virtual syncer::ModelType type() const OVERRIDE { return syncer::BOOKMARKS; }
51
52  private:
53   virtual void CreateSyncComponents() OVERRIDE {
54     ProfileSyncComponentsFactory::SyncComponents sync_components =
55         profile_sync_factory_->
56             CreateBookmarkSyncComponents(sync_service_, this);
57     model_associator_.reset(sync_components.model_associator);
58     change_processor_.reset(sync_components.change_processor);
59   }
60
61   // We mock the following methods because their default implementations do
62   // nothing, but we still want to make sure they're called appropriately.
63   virtual bool StartModels() OVERRIDE {
64     return mock_->StartModels();
65   }
66   virtual void CleanUpState() OVERRIDE {
67     mock_->CleanUpState();
68   }
69   virtual void RecordUnrecoverableError(
70       const tracked_objects::Location& from_here,
71       const std::string& message) OVERRIDE {
72     mock_->RecordUnrecoverableError(from_here, message);
73   }
74   virtual void RecordAssociationTime(base::TimeDelta time) OVERRIDE {
75     mock_->RecordAssociationTime(time);
76   }
77   virtual void RecordStartFailure(
78       DataTypeController::ConfigureResult result) OVERRIDE {
79     mock_->RecordStartFailure(result);
80   }
81  private:
82   virtual ~FrontendDataTypeControllerFake() {}
83   FrontendDataTypeControllerMock* mock_;
84 };
85
86 class SyncFrontendDataTypeControllerTest : public testing::Test {
87  public:
88   SyncFrontendDataTypeControllerTest()
89       : thread_bundle_(content::TestBrowserThreadBundle::DEFAULT),
90         service_(&profile_) {}
91
92   virtual void SetUp() {
93     profile_sync_factory_.reset(new ProfileSyncComponentsFactoryMock());
94     dtc_mock_ = new StrictMock<FrontendDataTypeControllerMock>();
95     frontend_dtc_ =
96         new FrontendDataTypeControllerFake(profile_sync_factory_.get(),
97                                            &profile_,
98                                            &service_,
99                                            dtc_mock_.get());
100   }
101
102  protected:
103   void SetStartExpectations() {
104     EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true));
105     EXPECT_CALL(model_load_callback_, Run(_, _));
106     model_associator_ = new ModelAssociatorMock();
107     change_processor_ = new ChangeProcessorMock();
108     EXPECT_CALL(*profile_sync_factory_, CreateBookmarkSyncComponents(_, _)).
109         WillOnce(Return(ProfileSyncComponentsFactory::SyncComponents(
110             model_associator_, change_processor_)));
111   }
112
113   void SetAssociateExpectations() {
114     EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
115         WillOnce(Return(true));
116     EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
117         WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
118     EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
119         WillOnce(Return(syncer::SyncError()));
120     EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
121   }
122
123   void SetActivateExpectations(DataTypeController::ConfigureResult result) {
124     EXPECT_CALL(start_callback_, Run(result, _, _));
125   }
126
127   void SetStopExpectations() {
128     EXPECT_CALL(*dtc_mock_.get(), CleanUpState());
129     EXPECT_CALL(service_, DeactivateDataType(_));
130     EXPECT_CALL(*model_associator_, DisassociateModels()).
131                 WillOnce(Return(syncer::SyncError()));
132   }
133
134   void SetStartFailExpectations(DataTypeController::ConfigureResult result) {
135     if (DataTypeController::IsUnrecoverableResult(result))
136       EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, _));
137     EXPECT_CALL(*dtc_mock_.get(), CleanUpState());
138     EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result));
139     EXPECT_CALL(start_callback_, Run(result, _, _));
140   }
141
142   void Start() {
143     frontend_dtc_->LoadModels(
144         base::Bind(&ModelLoadCallbackMock::Run,
145                    base::Unretained(&model_load_callback_)));
146     frontend_dtc_->StartAssociating(
147         base::Bind(&StartCallbackMock::Run,
148                    base::Unretained(&start_callback_)));
149   }
150
151   void PumpLoop() { base::MessageLoop::current()->RunUntilIdle(); }
152
153   content::TestBrowserThreadBundle thread_bundle_;
154   scoped_refptr<FrontendDataTypeControllerFake> frontend_dtc_;
155   scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_;
156   scoped_refptr<FrontendDataTypeControllerMock> dtc_mock_;
157   ProfileMock profile_;
158   ProfileSyncServiceMock service_;
159   ModelAssociatorMock* model_associator_;
160   ChangeProcessorMock* change_processor_;
161   StartCallbackMock start_callback_;
162   ModelLoadCallbackMock model_load_callback_;
163 };
164
165 TEST_F(SyncFrontendDataTypeControllerTest, StartOk) {
166   SetStartExpectations();
167   SetAssociateExpectations();
168   SetActivateExpectations(DataTypeController::OK);
169   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
170   Start();
171   EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state());
172 }
173
174 TEST_F(SyncFrontendDataTypeControllerTest, StartFirstRun) {
175   SetStartExpectations();
176   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
177       WillOnce(Return(true));
178   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
179       WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true)));
180   EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
181       WillOnce(Return(syncer::SyncError()));
182   EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
183   SetActivateExpectations(DataTypeController::OK_FIRST_RUN);
184   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
185   Start();
186   EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state());
187 }
188
189 TEST_F(SyncFrontendDataTypeControllerTest, AbortDuringStartModels) {
190   EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false));
191   EXPECT_CALL(*dtc_mock_.get(), CleanUpState());
192   EXPECT_CALL(model_load_callback_, Run(_, _));
193   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
194   frontend_dtc_->LoadModels(
195       base::Bind(&ModelLoadCallbackMock::Run,
196                  base::Unretained(&model_load_callback_)));
197   EXPECT_EQ(DataTypeController::MODEL_STARTING, frontend_dtc_->state());
198   frontend_dtc_->Stop();
199   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
200 }
201
202 TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationFailed) {
203   SetStartExpectations();
204   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
205       WillOnce(Return(true));
206   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
207       WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
208   EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
209       WillOnce(Return(syncer::SyncError(FROM_HERE,
210                                         syncer::SyncError::DATATYPE_ERROR,
211                                         "error",
212                                         syncer::BOOKMARKS)));
213
214   EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
215   SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED);
216   // Set up association to fail with an association failed error.
217   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
218   Start();
219   EXPECT_EQ(DataTypeController::DISABLED, frontend_dtc_->state());
220 }
221
222 TEST_F(SyncFrontendDataTypeControllerTest,
223        StartAssociationTriggersUnrecoverableError) {
224   SetStartExpectations();
225   SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR);
226   // Set up association to fail with an unrecoverable error.
227   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
228       WillRepeatedly(Return(true));
229   EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
230       WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false)));
231   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
232   Start();
233   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
234 }
235
236 TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationCryptoNotReady) {
237   SetStartExpectations();
238   SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO);
239   // Set up association to fail with a NEEDS_CRYPTO error.
240   EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
241       WillRepeatedly(Return(false));
242   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
243   Start();
244   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
245 }
246
247 TEST_F(SyncFrontendDataTypeControllerTest, Stop) {
248   SetStartExpectations();
249   SetAssociateExpectations();
250   SetActivateExpectations(DataTypeController::OK);
251   SetStopExpectations();
252   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
253   Start();
254   EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state());
255   frontend_dtc_->Stop();
256   EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
257 }