This source file includes following definitions.
- GetDatabase
- AddObserver
- RemoveObserver
- RemoveExpiredFormElements
- NotifyOfMultipleAutofillChanges
- db_loaded_callback_
- LoadDatabase
- IsDatabaseLoaded
- RegisterDBLoadedCallback
- StartSyncableService
- CreateSyncableService
- Build
- Shutdown
- weak_ptr_factory_
- SetUp
- OnStartFinished
- OnLoadFinished
- TearDown
- BlockForDBThread
- TEST_F
- TEST_F
#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/shared_change_processor_mock.h"
#include "chrome/browser/sync/profile_sync_components_factory_mock.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/browser/webdata/autocomplete_syncable_service.h"
#include "chrome/browser/webdata/web_data_service_factory.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/sync_driver/data_type_controller_mock.h"
#include "components/webdata/common/web_data_service_test_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "sync/api/sync_error.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using autofill::AutofillWebDataService;
using autofill::AutofillWebDataBackend;
namespace browser_sync {
namespace {
using content::BrowserThread;
using testing::_;
using testing::NiceMock;
using testing::Return;
class NoOpAutofillBackend : public AutofillWebDataBackend {
public:
NoOpAutofillBackend() {}
virtual ~NoOpAutofillBackend() {}
virtual WebDatabase* GetDatabase() OVERRIDE { return NULL; }
virtual void AddObserver(
autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {}
virtual void RemoveObserver(
autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {}
virtual void RemoveExpiredFormElements() OVERRIDE {}
virtual void NotifyOfMultipleAutofillChanges() OVERRIDE {}
};
class FakeWebDataService : public AutofillWebDataService {
public:
FakeWebDataService()
: AutofillWebDataService(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)),
is_database_loaded_(false),
db_loaded_callback_(base::Callback<void(void)>()){}
void LoadDatabase() {
StartSyncableService();
is_database_loaded_ = true;
if (!db_loaded_callback_.is_null())
db_loaded_callback_.Run();
}
virtual bool IsDatabaseLoaded() OVERRIDE {
return is_database_loaded_;
}
virtual void RegisterDBLoadedCallback(
const base::Callback<void(void)>& callback) OVERRIDE {
db_loaded_callback_ = callback;
}
void StartSyncableService() {
base::RunLoop run_loop;
BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
base::Bind(&FakeWebDataService::CreateSyncableService,
base::Unretained(this)), run_loop.QuitClosure());
run_loop.Run();
}
private:
virtual ~FakeWebDataService() {
}
void CreateSyncableService() {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
this,
&autofill_backend_);
}
bool is_database_loaded_;
NoOpAutofillBackend autofill_backend_;
base::Callback<void(void)> db_loaded_callback_;
DISALLOW_COPY_AND_ASSIGN(FakeWebDataService);
};
class MockWebDataServiceWrapperSyncable : public MockWebDataServiceWrapper {
public:
static KeyedService* Build(content::BrowserContext* profile) {
return new MockWebDataServiceWrapperSyncable();
}
MockWebDataServiceWrapperSyncable()
: MockWebDataServiceWrapper(NULL, new FakeWebDataService(), NULL) {
}
virtual void Shutdown() OVERRIDE {
static_cast<FakeWebDataService*>(
fake_autofill_web_data_.get())->ShutdownOnUIThread();
base::RunLoop run_loop;
ASSERT_TRUE(BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
base::Bind(&base::DoNothing), run_loop.QuitClosure()));
run_loop.Run();
}
private:
DISALLOW_COPY_AND_ASSIGN(MockWebDataServiceWrapperSyncable);
};
class SyncAutofillDataTypeControllerTest : public testing::Test {
public:
SyncAutofillDataTypeControllerTest()
: thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD),
service_(&profile_),
last_start_result_(DataTypeController::OK),
weak_ptr_factory_(this) {}
virtual ~SyncAutofillDataTypeControllerTest() {}
virtual void SetUp() {
change_processor_ = new NiceMock<SharedChangeProcessorMock>();
EXPECT_CALL(profile_sync_factory_,
CreateSharedChangeProcessor()).
WillRepeatedly(Return(change_processor_.get()));
WebDataServiceFactory::GetInstance()->SetTestingFactory(
&profile_, MockWebDataServiceWrapperSyncable::Build);
autofill_dtc_ =
new AutofillDataTypeController(&profile_sync_factory_,
&profile_,
&service_);
}
void OnStartFinished(DataTypeController::StartResult result,
const syncer::SyncMergeResult& local_merge_result,
const syncer::SyncMergeResult& syncer_merge_result) {
last_start_result_ = result;
last_start_error_ = local_merge_result.error();
}
void OnLoadFinished(syncer::ModelType type, syncer::SyncError error) {
EXPECT_FALSE(error.IsSet());
EXPECT_EQ(type, syncer::AUTOFILL);
}
virtual void TearDown() {
autofill_dtc_ = NULL;
change_processor_ = NULL;
}
void BlockForDBThread() {
base::RunLoop run_loop;
ASSERT_TRUE(BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE,
base::Bind(&base::DoNothing), run_loop.QuitClosure()));
run_loop.Run();
}
protected:
content::TestBrowserThreadBundle thread_bundle_;
scoped_refptr<NiceMock<SharedChangeProcessorMock> > change_processor_;
ProfileSyncComponentsFactoryMock profile_sync_factory_;
TestingProfile profile_;
ProfileSyncServiceMock service_;
scoped_refptr<AutofillDataTypeController> autofill_dtc_;
DataTypeController::StartResult last_start_result_;
syncer::SyncError last_start_error_;
base::WeakPtrFactory<SyncAutofillDataTypeControllerTest> weak_ptr_factory_;
};
TEST_F(SyncAutofillDataTypeControllerTest, StartWDSReady) {
FakeWebDataService* web_db =
static_cast<FakeWebDataService*>(
WebDataServiceFactory::GetAutofillWebDataForProfile(
&profile_, Profile::EXPLICIT_ACCESS).get());
web_db->LoadDatabase();
autofill_dtc_->LoadModels(
base::Bind(&SyncAutofillDataTypeControllerTest::OnLoadFinished,
weak_ptr_factory_.GetWeakPtr()));
EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
.WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
autofill_dtc_->StartAssociating(
base::Bind(&SyncAutofillDataTypeControllerTest::OnStartFinished,
weak_ptr_factory_.GetWeakPtr()));
BlockForDBThread();
EXPECT_EQ(DataTypeController::ASSOCIATION_FAILED, last_start_result_);
EXPECT_TRUE(last_start_error_.IsSet());
EXPECT_EQ(DataTypeController::DISABLED, autofill_dtc_->state());
}
TEST_F(SyncAutofillDataTypeControllerTest, StartWDSNotReady) {
autofill_dtc_->LoadModels(
base::Bind(&SyncAutofillDataTypeControllerTest::OnLoadFinished,
weak_ptr_factory_.GetWeakPtr()));
EXPECT_EQ(DataTypeController::OK, last_start_result_);
EXPECT_FALSE(last_start_error_.IsSet());
EXPECT_EQ(DataTypeController::MODEL_STARTING, autofill_dtc_->state());
FakeWebDataService* web_db =
static_cast<FakeWebDataService*>(
WebDataServiceFactory::GetAutofillWebDataForProfile(
&profile_, Profile::EXPLICIT_ACCESS).get());
web_db->LoadDatabase();
EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
.WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
autofill_dtc_->StartAssociating(
base::Bind(&SyncAutofillDataTypeControllerTest::OnStartFinished,
weak_ptr_factory_.GetWeakPtr()));
BlockForDBThread();
EXPECT_EQ(DataTypeController::ASSOCIATION_FAILED, last_start_result_);
EXPECT_TRUE(last_start_error_.IsSet());
EXPECT_EQ(DataTypeController::DISABLED, autofill_dtc_->state());
}
}
}