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