Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / autofill_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/callback.h"
7 #include "base/compiler_specific.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/run_loop.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
13 #include "chrome/browser/sync/glue/shared_change_processor_mock.h"
14 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
15 #include "chrome/browser/sync/profile_sync_service_factory.h"
16 #include "chrome/browser/sync/profile_sync_service_mock.h"
17 #include "chrome/browser/webdata/autocomplete_syncable_service.h"
18 #include "chrome/browser/webdata/web_data_service_factory.h"
19 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
20 #include "components/sync_driver/data_type_controller_mock.h"
21 #include "components/webdata/common/web_data_service_test_util.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_source.h"
25 #include "content/public/browser/notification_types.h"
26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "sync/api/sync_error.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 using autofill::AutofillWebDataService;
32 using autofill::AutofillWebDataBackend;
33
34 namespace browser_sync {
35
36 namespace {
37
38 using content::BrowserThread;
39 using testing::_;
40 using testing::NiceMock;
41 using testing::Return;
42
43 class NoOpAutofillBackend : public AutofillWebDataBackend {
44  public:
45   NoOpAutofillBackend() {}
46   virtual ~NoOpAutofillBackend() {}
47   virtual WebDatabase* GetDatabase() OVERRIDE { return NULL; }
48   virtual void AddObserver(
49       autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {}
50   virtual void RemoveObserver(
51       autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {}
52   virtual void RemoveExpiredFormElements() OVERRIDE {}
53   virtual void NotifyOfMultipleAutofillChanges() OVERRIDE {}
54 };
55
56 // Fake WebDataService implementation that stubs out the database loading.
57 class FakeWebDataService : public AutofillWebDataService {
58  public:
59   FakeWebDataService()
60       : AutofillWebDataService(
61             BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
62             BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)),
63         is_database_loaded_(false),
64         db_loaded_callback_(base::Callback<void(void)>()){}
65
66   // Mark the database as loaded and send out the appropriate notification.
67   void LoadDatabase() {
68     StartSyncableService();
69     is_database_loaded_ = true;
70
71     if (!db_loaded_callback_.is_null())
72       db_loaded_callback_.Run();
73   }
74
75   virtual bool IsDatabaseLoaded() OVERRIDE {
76     return is_database_loaded_;
77   }
78
79   virtual void RegisterDBLoadedCallback(
80       const base::Callback<void(void)>& callback) OVERRIDE {
81     db_loaded_callback_ = callback;
82   }
83
84   void StartSyncableService() {
85     // The |autofill_profile_syncable_service_| must be constructed on the DB
86     // thread.
87     base::RunLoop run_loop;
88     BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
89         base::Bind(&FakeWebDataService::CreateSyncableService,
90                    base::Unretained(this)), run_loop.QuitClosure());
91     run_loop.Run();
92   }
93
94  private:
95   virtual ~FakeWebDataService() {
96   }
97
98   void CreateSyncableService() {
99     ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
100     // These services are deleted in DestroySyncableService().
101     AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
102         this,
103         &autofill_backend_);
104   }
105
106   bool is_database_loaded_;
107   NoOpAutofillBackend autofill_backend_;
108   base::Callback<void(void)> db_loaded_callback_;
109
110   DISALLOW_COPY_AND_ASSIGN(FakeWebDataService);
111 };
112
113 class MockWebDataServiceWrapperSyncable : public MockWebDataServiceWrapper {
114  public:
115   static BrowserContextKeyedService* Build(content::BrowserContext* profile) {
116     return new MockWebDataServiceWrapperSyncable();
117   }
118
119   MockWebDataServiceWrapperSyncable()
120       : MockWebDataServiceWrapper(NULL, new FakeWebDataService(), NULL) {
121   }
122
123   virtual void Shutdown() OVERRIDE {
124     static_cast<FakeWebDataService*>(
125         fake_autofill_web_data_.get())->ShutdownOnUIThread();
126     // Make sure WebDataService is shutdown properly on DB thread before we
127     // destroy it.
128     base::RunLoop run_loop;
129     ASSERT_TRUE(BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
130         base::Bind(&base::DoNothing), run_loop.QuitClosure()));
131     run_loop.Run();
132   }
133
134  private:
135   DISALLOW_COPY_AND_ASSIGN(MockWebDataServiceWrapperSyncable);
136 };
137
138 class SyncAutofillDataTypeControllerTest : public testing::Test {
139  public:
140   SyncAutofillDataTypeControllerTest()
141       : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD),
142         service_(&profile_),
143         last_start_result_(DataTypeController::OK),
144         weak_ptr_factory_(this) {}
145
146   virtual ~SyncAutofillDataTypeControllerTest() {}
147
148   virtual void SetUp() {
149     change_processor_ = new NiceMock<SharedChangeProcessorMock>();
150
151     EXPECT_CALL(profile_sync_factory_,
152                 CreateSharedChangeProcessor()).
153         WillRepeatedly(Return(change_processor_.get()));
154
155     WebDataServiceFactory::GetInstance()->SetTestingFactory(
156         &profile_, MockWebDataServiceWrapperSyncable::Build);
157
158     autofill_dtc_ =
159         new AutofillDataTypeController(&profile_sync_factory_,
160                                        &profile_,
161                                        &service_);
162   }
163
164   // Passed to AutofillDTC::Start().
165   void OnStartFinished(DataTypeController::StartResult result,
166                        const syncer::SyncMergeResult& local_merge_result,
167                        const syncer::SyncMergeResult& syncer_merge_result) {
168     last_start_result_ = result;
169     last_start_error_ = local_merge_result.error();
170   }
171
172   void OnLoadFinished(syncer::ModelType type, syncer::SyncError error) {
173     EXPECT_FALSE(error.IsSet());
174     EXPECT_EQ(type, syncer::AUTOFILL);
175   }
176
177   virtual void TearDown() {
178     autofill_dtc_ = NULL;
179     change_processor_ = NULL;
180   }
181
182   void BlockForDBThread() {
183     base::RunLoop run_loop;
184     ASSERT_TRUE(BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
185         base::Bind(&base::DoNothing), run_loop.QuitClosure()));
186     run_loop.Run();
187   }
188
189  protected:
190   content::TestBrowserThreadBundle thread_bundle_;
191
192   scoped_refptr<NiceMock<SharedChangeProcessorMock> > change_processor_;
193   ProfileSyncComponentsFactoryMock profile_sync_factory_;
194   TestingProfile profile_;
195   ProfileSyncServiceMock service_;
196   scoped_refptr<AutofillDataTypeController> autofill_dtc_;
197
198   // Stores arguments of most recent call of OnStartFinished().
199   DataTypeController::StartResult last_start_result_;
200   syncer::SyncError last_start_error_;
201   base::WeakPtrFactory<SyncAutofillDataTypeControllerTest> weak_ptr_factory_;
202 };
203
204 // Load the WDS's database, then start the Autofill DTC.  It should
205 // immediately try to start association and fail (due to missing DB
206 // thread).
207 TEST_F(SyncAutofillDataTypeControllerTest, StartWDSReady) {
208   FakeWebDataService* web_db =
209       static_cast<FakeWebDataService*>(
210           WebDataServiceFactory::GetAutofillWebDataForProfile(
211               &profile_, Profile::EXPLICIT_ACCESS).get());
212   web_db->LoadDatabase();
213   autofill_dtc_->LoadModels(
214     base::Bind(&SyncAutofillDataTypeControllerTest::OnLoadFinished,
215                weak_ptr_factory_.GetWeakPtr()));
216
217   EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
218       .WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
219   autofill_dtc_->StartAssociating(
220       base::Bind(&SyncAutofillDataTypeControllerTest::OnStartFinished,
221                  weak_ptr_factory_.GetWeakPtr()));
222   BlockForDBThread();
223
224   EXPECT_EQ(DataTypeController::ASSOCIATION_FAILED, last_start_result_);
225   EXPECT_TRUE(last_start_error_.IsSet());
226   EXPECT_EQ(DataTypeController::DISABLED, autofill_dtc_->state());
227 }
228
229 // Start the autofill DTC without the WDS's database loaded, then
230 // start the DB.  The Autofill DTC should be in the MODEL_STARTING
231 // state until the database in loaded, when it should try to start
232 // association and fail (due to missing DB thread).
233 TEST_F(SyncAutofillDataTypeControllerTest, StartWDSNotReady) {
234   autofill_dtc_->LoadModels(
235     base::Bind(&SyncAutofillDataTypeControllerTest::OnLoadFinished,
236                weak_ptr_factory_.GetWeakPtr()));
237
238   EXPECT_EQ(DataTypeController::OK, last_start_result_);
239   EXPECT_FALSE(last_start_error_.IsSet());
240   EXPECT_EQ(DataTypeController::MODEL_STARTING, autofill_dtc_->state());
241
242   FakeWebDataService* web_db =
243       static_cast<FakeWebDataService*>(
244           WebDataServiceFactory::GetAutofillWebDataForProfile(
245               &profile_, Profile::EXPLICIT_ACCESS).get());
246   web_db->LoadDatabase();
247
248   EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
249       .WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
250   autofill_dtc_->StartAssociating(
251       base::Bind(&SyncAutofillDataTypeControllerTest::OnStartFinished,
252                  weak_ptr_factory_.GetWeakPtr()));
253   BlockForDBThread();
254
255   EXPECT_EQ(DataTypeController::ASSOCIATION_FAILED, last_start_result_);
256   EXPECT_TRUE(last_start_error_.IsSet());
257
258   EXPECT_EQ(DataTypeController::DISABLED, autofill_dtc_->state());
259 }
260
261 }  // namespace
262
263 }  // namespace browser_sync