Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / ui_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/ui_data_type_controller.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/tracked_objects.h"
11 #include "chrome/browser/sync/glue/fake_generic_change_processor.h"
12 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
13 #include "chrome/browser/sync/profile_sync_service_mock.h"
14 #include "chrome/test/base/profile_mock.h"
15 #include "components/sync_driver/data_type_controller_mock.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "sync/api/fake_syncable_service.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using content::BrowserThread;
21 using testing::_;
22 using testing::InvokeWithoutArgs;
23 using testing::Return;
24
25 namespace browser_sync {
26 namespace {
27
28 ACTION(MakeSharedChangeProcessor) {
29   return new SharedChangeProcessor();
30 }
31
32 ACTION_P(ReturnAndRelease, change_processor) {
33   return change_processor->release();
34 }
35
36 // TODO(zea): Expand this to make the dtc type paramterizable. This will let us
37 // test the basic functionality of all UIDataTypeControllers. We'll need to have
38 // intelligent default values for the methods queried in the dependent services
39 // (e.g. those queried in StartModels).
40 class SyncUIDataTypeControllerTest : public testing::Test {
41  public:
42   SyncUIDataTypeControllerTest()
43       : ui_thread_(BrowserThread::UI, &message_loop_),
44         profile_sync_service_(&profile_),
45         type_(syncer::PREFERENCES),
46         change_processor_(new FakeGenericChangeProcessor()) {}
47
48   virtual void SetUp() {
49     profile_sync_factory_.reset(new ProfileSyncComponentsFactoryMock());
50     preference_dtc_ =
51         new UIDataTypeController(base::MessageLoopProxy::current(),
52                                  base::Closure(),
53                                  type_,
54                                  profile_sync_factory_.get(),
55                                  &profile_,
56                                  &profile_sync_service_);
57     SetStartExpectations();
58   }
59
60   virtual void TearDown() {
61     // Must be done before we pump the loop.
62     syncable_service_.StopSyncing(type_);
63     preference_dtc_ = NULL;
64     PumpLoop();
65   }
66
67  protected:
68   void SetStartExpectations() {
69     // Ownership gets passed to caller of CreateGenericChangeProcessor.
70     change_processor_.reset(new FakeGenericChangeProcessor());
71     EXPECT_CALL(model_load_callback_, Run(_, _));
72     EXPECT_CALL(*profile_sync_factory_, GetSyncableServiceForType(type_)).
73         WillOnce(Return(syncable_service_.AsWeakPtr()));
74     EXPECT_CALL(*profile_sync_factory_, CreateSharedChangeProcessor()).
75         WillOnce(MakeSharedChangeProcessor());
76     EXPECT_CALL(*profile_sync_factory_,
77                 CreateGenericChangeProcessor(_, _, _, _)).
78         WillOnce(ReturnAndRelease(&change_processor_));
79   }
80
81   void SetActivateExpectations() {
82     EXPECT_CALL(profile_sync_service_, ActivateDataType(type_, _, _));
83   }
84
85   void SetStopExpectations() {
86     EXPECT_CALL(profile_sync_service_, DeactivateDataType(type_));
87   }
88
89   void Start() {
90     preference_dtc_->LoadModels(
91         base::Bind(&ModelLoadCallbackMock::Run,
92                    base::Unretained(&model_load_callback_)));
93     preference_dtc_->StartAssociating(
94         base::Bind(&StartCallbackMock::Run,
95                    base::Unretained(&start_callback_)));
96   }
97
98   void PumpLoop() {
99     message_loop_.RunUntilIdle();
100   }
101
102   base::MessageLoopForUI message_loop_;
103   content::TestBrowserThread ui_thread_;
104   ProfileMock profile_;
105   scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_;
106   ProfileSyncServiceMock profile_sync_service_;
107   const syncer::ModelType type_;
108   StartCallbackMock start_callback_;
109   ModelLoadCallbackMock model_load_callback_;
110   scoped_refptr<UIDataTypeController> preference_dtc_;
111   scoped_ptr<FakeGenericChangeProcessor> change_processor_;
112   syncer::FakeSyncableService syncable_service_;
113 };
114
115 // Start the DTC. Verify that the callback is called with OK, the
116 // service has been told to start syncing and that the DTC is now in RUNNING
117 // state.
118 TEST_F(SyncUIDataTypeControllerTest, Start) {
119   SetActivateExpectations();
120   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
121
122   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
123   EXPECT_FALSE(syncable_service_.syncing());
124   Start();
125   EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state());
126   EXPECT_TRUE(syncable_service_.syncing());
127 }
128
129 // Start and then stop the DTC. Verify that the service started and stopped
130 // syncing, and that the DTC went from RUNNING to NOT_RUNNING.
131 TEST_F(SyncUIDataTypeControllerTest, StartStop) {
132   SetActivateExpectations();
133   SetStopExpectations();
134   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
135
136   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
137   EXPECT_FALSE(syncable_service_.syncing());
138   Start();
139   EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state());
140   EXPECT_TRUE(syncable_service_.syncing());
141   preference_dtc_->Stop();
142   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
143   EXPECT_FALSE(syncable_service_.syncing());
144 }
145
146 // Start the DTC when no user nodes are created. Verify that the callback
147 // is called with OK_FIRST_RUN. Stop the DTC.
148 TEST_F(SyncUIDataTypeControllerTest, StartStopFirstRun) {
149   SetActivateExpectations();
150   SetStopExpectations();
151   EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
152   change_processor_->set_sync_model_has_user_created_nodes(false);
153
154   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
155   EXPECT_FALSE(syncable_service_.syncing());
156   Start();
157   EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state());
158   EXPECT_TRUE(syncable_service_.syncing());
159   preference_dtc_->Stop();
160   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
161   EXPECT_FALSE(syncable_service_.syncing());
162 }
163
164 // Start the DTC, but have the service fail association. Verify the callback
165 // is called with ASSOCIATION_FAILED, the DTC goes to state DISABLED, and the
166 // service is not syncing. Then stop the DTC.
167 TEST_F(SyncUIDataTypeControllerTest, StartAssociationFailed) {
168   SetStopExpectations();
169   EXPECT_CALL(start_callback_,
170               Run(DataTypeController::ASSOCIATION_FAILED, _, _));
171   syncable_service_.set_merge_data_and_start_syncing_error(
172       syncer::SyncError(FROM_HERE,
173                         syncer::SyncError::DATATYPE_ERROR,
174                         "Error",
175                         type_));
176
177   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
178   EXPECT_FALSE(syncable_service_.syncing());
179   Start();
180   EXPECT_EQ(DataTypeController::DISABLED, preference_dtc_->state());
181   EXPECT_FALSE(syncable_service_.syncing());
182   preference_dtc_->Stop();
183   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
184   EXPECT_FALSE(syncable_service_.syncing());
185 }
186
187 // Start the DTC but fail to check if there are user created nodes. Verify the
188 // DTC calls the callback with UNRECOVERABLE_ERROR and that it goes into
189 // NOT_RUNNING state. Verify the syncable service is not syncing.
190 TEST_F(SyncUIDataTypeControllerTest,
191        StartAssociationTriggersUnrecoverableError) {
192   EXPECT_CALL(start_callback_,
193               Run(DataTypeController::UNRECOVERABLE_ERROR, _, _));
194   change_processor_->set_sync_model_has_user_created_nodes_success(false);
195
196   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
197   EXPECT_FALSE(syncable_service_.syncing());
198   Start();
199   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
200   EXPECT_FALSE(syncable_service_.syncing());
201 }
202
203 // Start the DTC, but then trigger an unrecoverable error. Verify the syncer
204 // gets stopped and the DTC is in NOT_RUNNING state.
205 TEST_F(SyncUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
206   SetActivateExpectations();
207   EXPECT_CALL(profile_sync_service_, DisableBrokenDatatype(_,_,_)).
208       WillOnce(InvokeWithoutArgs(preference_dtc_.get(),
209                                  &UIDataTypeController::Stop));
210   SetStopExpectations();
211   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
212
213   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
214   EXPECT_FALSE(syncable_service_.syncing());
215   Start();
216   EXPECT_TRUE(syncable_service_.syncing());
217   preference_dtc_->OnSingleDatatypeUnrecoverableError(FROM_HERE, "Test");
218   PumpLoop();
219   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
220   EXPECT_FALSE(syncable_service_.syncing());
221 }
222
223 }  // namespace
224 }  // namespace browser_sync