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