- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / search_engine_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 "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/tracked_objects.h"
11 #include "chrome/browser/search_engines/template_url_service_factory.h"
12 #include "chrome/browser/search_engines/template_url_service_test_util.h"
13 #include "chrome/browser/sync/glue/data_type_controller_mock.h"
14 #include "chrome/browser/sync/glue/fake_generic_change_processor.h"
15 #include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
16 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
17 #include "chrome/browser/sync/profile_sync_service_mock.h"
18 #include "chrome/test/base/profile_mock.h"
19 #include "sync/api/fake_syncable_service.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using testing::_;
23 using testing::DoAll;
24 using testing::InvokeWithoutArgs;
25 using testing::Return;
26 using testing::SetArgumentPointee;
27
28 namespace browser_sync {
29 namespace {
30
31 ACTION(MakeSharedChangeProcessor) {
32   return new SharedChangeProcessor();
33 }
34
35 ACTION_P(ReturnAndRelease, change_processor) {
36   return change_processor->release();
37 }
38
39 class SyncSearchEngineDataTypeControllerTest : public testing::Test {
40  public:
41   SyncSearchEngineDataTypeControllerTest()
42       : change_processor_(new FakeGenericChangeProcessor()) {}
43
44   virtual void SetUp() {
45     test_util_.SetUp();
46     profile_sync_factory_.reset(new ProfileSyncComponentsFactoryMock());
47     // Feed the DTC test_util_'s profile so it is reused later.
48     // This allows us to control the associated TemplateURLService.
49     search_engine_dtc_ =
50         new SearchEngineDataTypeController(profile_sync_factory_.get(),
51                                            test_util_.profile(),
52                                            &service_);
53   }
54
55   virtual void TearDown() {
56     // Must be done before we pump the loop.
57     syncable_service_.StopSyncing(syncer::SEARCH_ENGINES);
58     search_engine_dtc_ = NULL;
59     test_util_.TearDown();
60   }
61
62  protected:
63   // Pre-emptively get the TURL Service and make sure it is loaded.
64   void PreloadTemplateURLService() {
65     test_util_.VerifyLoad();
66   }
67
68   void SetStartExpectations() {
69     // Ownership gets passed to caller of CreateGenericChangeProcessor.
70     EXPECT_CALL(model_load_callback_, Run(_, _));
71     EXPECT_CALL(*profile_sync_factory_,
72                 GetSyncableServiceForType(syncer::SEARCH_ENGINES)).
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(service_, ActivateDataType(syncer::SEARCH_ENGINES, _, _));
83   }
84
85   void SetStopExpectations() {
86     EXPECT_CALL(service_, DeactivateDataType(syncer::SEARCH_ENGINES));
87   }
88
89   void Start() {
90     search_engine_dtc_->LoadModels(
91         base::Bind(&ModelLoadCallbackMock::Run,
92                    base::Unretained(&model_load_callback_)));
93     search_engine_dtc_->StartAssociating(
94         base::Bind(&StartCallbackMock::Run,
95                    base::Unretained(&start_callback_)));
96   }
97
98   // This also manages a BrowserThread and MessageLoop for us. Note that this
99   // must be declared here as the destruction order of the BrowserThread
100   // matters - we could leak if this is declared below.
101   TemplateURLServiceTestUtil test_util_;
102   scoped_refptr<SearchEngineDataTypeController> search_engine_dtc_;
103   scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_;
104   ProfileSyncServiceMock service_;
105   scoped_ptr<FakeGenericChangeProcessor> change_processor_;
106   syncer::FakeSyncableService syncable_service_;
107   StartCallbackMock start_callback_;
108   ModelLoadCallbackMock model_load_callback_;
109 };
110
111 TEST_F(SyncSearchEngineDataTypeControllerTest, StartURLServiceReady) {
112   SetStartExpectations();
113   // We want to start ready.
114   PreloadTemplateURLService();
115   SetActivateExpectations();
116   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
117
118   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
119   EXPECT_FALSE(syncable_service_.syncing());
120   Start();
121   EXPECT_EQ(DataTypeController::RUNNING, search_engine_dtc_->state());
122   EXPECT_TRUE(syncable_service_.syncing());
123 }
124
125 TEST_F(SyncSearchEngineDataTypeControllerTest, StartURLServiceNotReady) {
126   EXPECT_CALL(*profile_sync_factory_, CreateSharedChangeProcessor()).
127       WillOnce(MakeSharedChangeProcessor());
128
129   EXPECT_CALL(model_load_callback_, Run(_, _));
130   EXPECT_FALSE(syncable_service_.syncing());
131   search_engine_dtc_->LoadModels(
132       base::Bind(&ModelLoadCallbackMock::Run,
133                  base::Unretained(&model_load_callback_)));
134   EXPECT_EQ(DataTypeController::MODEL_STARTING, search_engine_dtc_->state());
135   EXPECT_FALSE(syncable_service_.syncing());
136
137   // Send the notification that the TemplateURLService has started.
138   PreloadTemplateURLService();
139   EXPECT_EQ(DataTypeController::MODEL_LOADED, search_engine_dtc_->state());
140
141   // Wait until WebDB is loaded before we shut it down.
142   base::RunLoop().RunUntilIdle();
143 }
144
145 TEST_F(SyncSearchEngineDataTypeControllerTest, StartFirstRun) {
146   SetStartExpectations();
147   PreloadTemplateURLService();
148   SetActivateExpectations();
149   change_processor_->set_sync_model_has_user_created_nodes(false);
150   EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
151
152   Start();
153   EXPECT_TRUE(syncable_service_.syncing());
154 }
155
156 TEST_F(SyncSearchEngineDataTypeControllerTest, StartAssociationFailed) {
157   SetStartExpectations();
158   PreloadTemplateURLService();
159   SetStopExpectations();
160   EXPECT_CALL(start_callback_,
161               Run(DataTypeController::ASSOCIATION_FAILED, _, _));
162   syncable_service_.set_merge_data_and_start_syncing_error(
163       syncer::SyncError(FROM_HERE,
164                         syncer::SyncError::DATATYPE_ERROR,
165                         "Error",
166                         syncer::SEARCH_ENGINES));
167
168   Start();
169   EXPECT_EQ(DataTypeController::DISABLED, search_engine_dtc_->state());
170   EXPECT_FALSE(syncable_service_.syncing());
171   search_engine_dtc_->Stop();
172   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
173   EXPECT_FALSE(syncable_service_.syncing());
174 }
175
176 TEST_F(SyncSearchEngineDataTypeControllerTest,
177        StartAssociationTriggersUnrecoverableError) {
178   SetStartExpectations();
179   PreloadTemplateURLService();
180   EXPECT_CALL(start_callback_,
181               Run(DataTypeController::UNRECOVERABLE_ERROR, _, _));
182   // Set up association to fail with an unrecoverable error.
183   change_processor_->set_sync_model_has_user_created_nodes_success(false);
184
185   Start();
186   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
187   EXPECT_FALSE(syncable_service_.syncing());
188 }
189
190 TEST_F(SyncSearchEngineDataTypeControllerTest, Stop) {
191   SetStartExpectations();
192   PreloadTemplateURLService();
193   SetActivateExpectations();
194   SetStopExpectations();
195   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
196
197   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
198   EXPECT_FALSE(syncable_service_.syncing());
199   Start();
200   EXPECT_EQ(DataTypeController::RUNNING, search_engine_dtc_->state());
201   EXPECT_TRUE(syncable_service_.syncing());
202   search_engine_dtc_->Stop();
203   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
204   EXPECT_FALSE(syncable_service_.syncing());
205 }
206
207 TEST_F(SyncSearchEngineDataTypeControllerTest,
208        OnSingleDatatypeUnrecoverableError) {
209   SetStartExpectations();
210   PreloadTemplateURLService();
211   SetActivateExpectations();
212   EXPECT_CALL(service_, DisableBrokenDatatype(_, _, _)).
213       WillOnce(InvokeWithoutArgs(search_engine_dtc_.get(),
214                                  &SearchEngineDataTypeController::Stop));
215   SetStopExpectations();
216
217   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
218   Start();
219   // This should cause search_engine_dtc_->Stop() to be called.
220   search_engine_dtc_->OnSingleDatatypeUnrecoverableError(FROM_HERE, "Test");
221   base::RunLoop().RunUntilIdle();
222   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
223   EXPECT_FALSE(syncable_service_.syncing());
224 }
225
226 }  // namespace
227 }  // namespace browser_sync