1 // Copyright 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 <set> 6 #include <string> 7 #include <utility> 8 #include <vector> 9 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 #include "base/bind.h" 13 #include "base/bind_helpers.h" 14 #include "base/callback.h" 15 #include "base/compiler_specific.h" 16 #include "base/location.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "base/message_loop/message_loop.h" 20 #include "base/strings/string16.h" 21 #include "base/strings/utf_string_conversions.h" 22 #include "base/synchronization/waitable_event.h" 23 #include "base/time/time.h" 24 #include "chrome/browser/autofill/personal_data_manager_factory.h" 25 #include "chrome/browser/prefs/pref_service_syncable.h" 26 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h" 27 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" 28 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 29 #include "chrome/browser/signin/signin_manager_factory.h" 30 #include "chrome/browser/sync/abstract_profile_sync_service_test.h" 31 #include "chrome/browser/sync/glue/autofill_data_type_controller.h" 32 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h" 33 #include "chrome/browser/sync/profile_sync_components_factory.h" 34 #include "chrome/browser/sync/profile_sync_service.h" 35 #include "chrome/browser/sync/profile_sync_service_factory.h" 36 #include "chrome/browser/sync/profile_sync_test_util.h" 37 #include "chrome/browser/sync/test_profile_sync_service.h" 38 #include "chrome/browser/webdata/autocomplete_syncable_service.h" 39 #include "chrome/browser/webdata/web_data_service_factory.h" 40 #include "chrome/test/base/testing_browser_process.h" 41 #include "chrome/test/base/testing_profile.h" 42 #include "chrome/test/base/testing_profile_manager.h" 43 #include "components/autofill/core/browser/autofill_test_utils.h" 44 #include "components/autofill/core/browser/personal_data_manager.h" 45 #include "components/autofill/core/browser/webdata/autofill_change.h" 46 #include "components/autofill/core/browser/webdata/autofill_entry.h" 47 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" 48 #include "components/autofill/core/browser/webdata/autofill_table.h" 49 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 50 #include "components/signin/core/browser/signin_manager.h" 51 #include "components/sync_driver/data_type_controller.h" 52 #include "components/webdata/common/web_data_service_test_util.h" 53 #include "components/webdata/common/web_database.h" 54 #include "content/public/test/test_browser_thread.h" 55 #include "google_apis/gaia/gaia_constants.h" 56 #include "sync/internal_api/public/base/model_type.h" 57 #include "sync/internal_api/public/data_type_debug_info_listener.h" 58 #include "sync/internal_api/public/read_node.h" 59 #include "sync/internal_api/public/read_transaction.h" 60 #include "sync/internal_api/public/write_node.h" 61 #include "sync/internal_api/public/write_transaction.h" 62 #include "sync/protocol/autofill_specifics.pb.h" 63 #include "sync/syncable/mutable_entry.h" 64 #include "sync/syncable/syncable_write_transaction.h" 65 #include "sync/test/engine/test_id_factory.h" 66 #include "testing/gmock/include/gmock/gmock.h" 67 68 using autofill::AutofillChange; 69 using autofill::AutofillChangeList; 70 using autofill::AutofillEntry; 71 using autofill::ServerFieldType; 72 using autofill::AutofillKey; 73 using autofill::AutofillProfile; 74 using autofill::AutofillProfileChange; 75 using autofill::AutofillProfileSyncableService; 76 using autofill::AutofillTable; 77 using autofill::AutofillWebDataService; 78 using autofill::PersonalDataManager; 79 using base::Time; 80 using base::TimeDelta; 81 using base::WaitableEvent; 82 using browser_sync::AutofillDataTypeController; 83 using browser_sync::AutofillProfileDataTypeController; 84 using browser_sync::DataTypeController; 85 using content::BrowserThread; 86 using syncer::AUTOFILL; 87 using syncer::AUTOFILL_PROFILE; 88 using syncer::BaseNode; 89 using syncer::syncable::BASE_VERSION; 90 using syncer::syncable::CREATE; 91 using syncer::syncable::GET_TYPE_ROOT; 92 using syncer::syncable::MutableEntry; 93 using syncer::syncable::SERVER_SPECIFICS; 94 using syncer::syncable::SPECIFICS; 95 using syncer::syncable::UNITTEST; 96 using syncer::syncable::WriterTag; 97 using syncer::syncable::WriteTransaction; 98 using testing::_; 99 using testing::DoAll; 100 using testing::ElementsAre; 101 using testing::SetArgumentPointee; 102 using testing::Return; 103 104 class HistoryService; 105 106 namespace syncable { 107 class Id; 108 } 109 110 namespace { 111 112 const char kTestProfileName[] = "test-profile"; 113 114 void RunAndSignal(const base::Closure& cb, WaitableEvent* event) { 115 cb.Run(); 116 event->Signal(); 117 } 118 119 } // namespace 120 121 class AutofillTableMock : public AutofillTable { 122 public: 123 AutofillTableMock() : AutofillTable("en-US") {} 124 MOCK_METHOD2(RemoveFormElement, 125 bool(const base::string16& name, 126 const base::string16& value)); // NOLINT 127 MOCK_METHOD1(GetAllAutofillEntries, 128 bool(std::vector<AutofillEntry>* entries)); // NOLINT 129 MOCK_METHOD4(GetAutofillTimestamps, 130 bool(const base::string16& name, // NOLINT 131 const base::string16& value, 132 base::Time* date_created, 133 base::Time* date_last_used)); 134 MOCK_METHOD1(UpdateAutofillEntries, 135 bool(const std::vector<AutofillEntry>&)); // NOLINT 136 MOCK_METHOD1(GetAutofillProfiles, 137 bool(std::vector<AutofillProfile*>*)); // NOLINT 138 MOCK_METHOD1(UpdateAutofillProfile, 139 bool(const AutofillProfile&)); // NOLINT 140 MOCK_METHOD1(AddAutofillProfile, 141 bool(const AutofillProfile&)); // NOLINT 142 MOCK_METHOD1(RemoveAutofillProfile, 143 bool(const std::string&)); // NOLINT 144 }; 145 146 MATCHER_P(MatchProfiles, profile, "") { 147 return (profile.Compare(arg) == 0); 148 } 149 150 class WebDatabaseFake : public WebDatabase { 151 public: 152 explicit WebDatabaseFake(AutofillTable* autofill_table) { 153 AddTable(autofill_table); 154 } 155 }; 156 157 class MockAutofillBackend : public autofill::AutofillWebDataBackend { 158 public: 159 MockAutofillBackend( 160 WebDatabase* web_database, 161 const base::Closure& on_changed) 162 : web_database_(web_database), 163 on_changed_(on_changed) { 164 } 165 166 virtual ~MockAutofillBackend() {} 167 virtual WebDatabase* GetDatabase() OVERRIDE { return web_database_; } 168 virtual void AddObserver( 169 autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {} 170 virtual void RemoveObserver( 171 autofill::AutofillWebDataServiceObserverOnDBThread* observer) OVERRIDE {} 172 virtual void RemoveExpiredFormElements() OVERRIDE {} 173 virtual void NotifyOfMultipleAutofillChanges() OVERRIDE { 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 175 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_changed_); 176 } 177 178 private: 179 WebDatabase* web_database_; 180 base::Closure on_changed_; 181 }; 182 183 class ProfileSyncServiceAutofillTest; 184 185 template<class AutofillProfile> 186 syncer::ModelType GetModelType() { 187 return syncer::UNSPECIFIED; 188 } 189 190 template<> 191 syncer::ModelType GetModelType<AutofillEntry>() { 192 return syncer::AUTOFILL; 193 } 194 195 template<> 196 syncer::ModelType GetModelType<AutofillProfile>() { 197 return syncer::AUTOFILL_PROFILE; 198 } 199 200 class TokenWebDataServiceFake : public TokenWebData { 201 public: 202 TokenWebDataServiceFake() 203 : TokenWebData( 204 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 205 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)) { 206 } 207 208 virtual bool IsDatabaseLoaded() OVERRIDE { 209 return true; 210 } 211 212 virtual WebDataService::Handle GetAllTokens( 213 WebDataServiceConsumer* consumer) OVERRIDE { 214 // TODO(tim): It would be nice if WebDataService was injected on 215 // construction of ProfileOAuth2TokenService rather than fetched by 216 // Initialize so that this isn't necessary (we could pass a NULL service). 217 // We currently do return it via EXPECT_CALLs, but without depending on 218 // order-of-initialization (which seems way more fragile) we can't tell 219 // which component is asking at what time, and some components in these 220 // Autofill tests require a WebDataService. 221 return 0; 222 } 223 224 private: 225 virtual ~TokenWebDataServiceFake() {} 226 227 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake); 228 }; 229 230 class WebDataServiceFake : public AutofillWebDataService { 231 public: 232 WebDataServiceFake() 233 : AutofillWebDataService( 234 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)), 236 web_database_(NULL), 237 autocomplete_syncable_service_(NULL), 238 autofill_profile_syncable_service_(NULL), 239 syncable_service_created_or_destroyed_(false, false) { 240 } 241 242 void SetDatabase(WebDatabase* web_database) { 243 web_database_ = web_database; 244 } 245 246 void StartSyncableService() { 247 // The |autofill_profile_syncable_service_| must be constructed on the DB 248 // thread. 249 const base::Closure& on_changed_callback = base::Bind( 250 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread, 251 AsWeakPtr()); 252 253 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 254 base::Bind(&WebDataServiceFake::CreateSyncableService, 255 base::Unretained(this), 256 on_changed_callback)); 257 syncable_service_created_or_destroyed_.Wait(); 258 } 259 260 void ShutdownSyncableService() { 261 // The |autofill_profile_syncable_service_| must be destructed on the DB 262 // thread. 263 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 264 base::Bind(&WebDataServiceFake::DestroySyncableService, 265 base::Unretained(this))); 266 syncable_service_created_or_destroyed_.Wait(); 267 } 268 269 virtual bool IsDatabaseLoaded() OVERRIDE { 270 return true; 271 } 272 273 virtual WebDatabase* GetDatabase() OVERRIDE { 274 return web_database_; 275 } 276 277 void OnAutofillEntriesChanged(const AutofillChangeList& changes) { 278 WaitableEvent event(true, false); 279 280 base::Closure notify_cb = 281 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged, 282 base::Unretained(autocomplete_syncable_service_), 283 changes); 284 BrowserThread::PostTask( 285 BrowserThread::DB, 286 FROM_HERE, 287 base::Bind(&RunAndSignal, notify_cb, &event)); 288 event.Wait(); 289 } 290 291 void OnAutofillProfileChanged(const AutofillProfileChange& changes) { 292 WaitableEvent event(true, false); 293 294 base::Closure notify_cb = 295 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged, 296 base::Unretained(autofill_profile_syncable_service_), 297 changes); 298 BrowserThread::PostTask( 299 BrowserThread::DB, 300 FROM_HERE, 301 base::Bind(&RunAndSignal, notify_cb, &event)); 302 event.Wait(); 303 } 304 305 private: 306 virtual ~WebDataServiceFake() {} 307 308 void CreateSyncableService(const base::Closure& on_changed_callback) { 309 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 310 // These services are deleted in DestroySyncableService(). 311 backend_.reset(new MockAutofillBackend( 312 GetDatabase(), on_changed_callback)); 313 AutocompleteSyncableService::CreateForWebDataServiceAndBackend( 314 this, backend_.get()); 315 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend( 316 this, backend_.get(), "en-US"); 317 318 autocomplete_syncable_service_ = 319 AutocompleteSyncableService::FromWebDataService(this); 320 autofill_profile_syncable_service_ = 321 AutofillProfileSyncableService::FromWebDataService(this); 322 323 syncable_service_created_or_destroyed_.Signal(); 324 } 325 326 void DestroySyncableService() { 327 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 328 autocomplete_syncable_service_ = NULL; 329 autofill_profile_syncable_service_ = NULL; 330 backend_.reset(); 331 syncable_service_created_or_destroyed_.Signal(); 332 } 333 334 WebDatabase* web_database_; 335 AutocompleteSyncableService* autocomplete_syncable_service_; 336 AutofillProfileSyncableService* autofill_profile_syncable_service_; 337 scoped_ptr<autofill::AutofillWebDataBackend> backend_; 338 339 WaitableEvent syncable_service_created_or_destroyed_; 340 341 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake); 342 }; 343 344 KeyedService* BuildMockWebDataServiceWrapper(content::BrowserContext* profile) { 345 return new MockWebDataServiceWrapper( 346 NULL, 347 new WebDataServiceFake(), 348 new TokenWebDataServiceFake()); 349 } 350 351 ACTION_P(MakeAutocompleteSyncComponents, wds) { 352 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 353 if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) 354 return base::WeakPtr<syncer::SyncableService>(); 355 return AutocompleteSyncableService::FromWebDataService(wds)->AsWeakPtr(); 356 } 357 358 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) { 359 return new browser_sync::DataTypeManagerImpl( 360 base::Closure(), 361 debug_listener, 362 arg1, 363 arg2, 364 arg3, 365 arg4, 366 arg5); 367 } 368 369 ACTION_P(MakeAutofillProfileSyncComponents, wds) { 370 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 371 if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) 372 return base::WeakPtr<syncer::SyncableService>(); 373 return AutofillProfileSyncableService::FromWebDataService(wds)->AsWeakPtr(); 374 } 375 376 class AbstractAutofillFactory { 377 public: 378 virtual DataTypeController* CreateDataTypeController( 379 ProfileSyncComponentsFactory* factory, 380 TestingProfile* profile, 381 ProfileSyncService* service) = 0; 382 virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory, 383 ProfileSyncService* service, 384 AutofillWebDataService* wds, 385 DataTypeController* dtc) = 0; 386 virtual ~AbstractAutofillFactory() {} 387 }; 388 389 class AutofillEntryFactory : public AbstractAutofillFactory { 390 public: 391 virtual browser_sync::DataTypeController* CreateDataTypeController( 392 ProfileSyncComponentsFactory* factory, 393 TestingProfile* profile, 394 ProfileSyncService* service) OVERRIDE { 395 return new AutofillDataTypeController( 396 factory, profile, DataTypeController::DisableTypeCallback()); 397 } 398 399 virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory, 400 ProfileSyncService* service, 401 AutofillWebDataService* wds, 402 DataTypeController* dtc) OVERRIDE { 403 EXPECT_CALL(*factory, GetSyncableServiceForType(syncer::AUTOFILL)). 404 WillOnce(MakeAutocompleteSyncComponents(wds)); 405 } 406 }; 407 408 class AutofillProfileFactory : public AbstractAutofillFactory { 409 public: 410 virtual browser_sync::DataTypeController* CreateDataTypeController( 411 ProfileSyncComponentsFactory* factory, 412 TestingProfile* profile, 413 ProfileSyncService* service) OVERRIDE { 414 return new AutofillProfileDataTypeController( 415 factory, profile, DataTypeController::DisableTypeCallback()); 416 } 417 418 virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory, 419 ProfileSyncService* service, 420 AutofillWebDataService* wds, 421 DataTypeController* dtc) OVERRIDE { 422 EXPECT_CALL(*factory, 423 GetSyncableServiceForType(syncer::AUTOFILL_PROFILE)). 424 WillOnce(MakeAutofillProfileSyncComponents(wds)); 425 } 426 }; 427 428 class MockPersonalDataManager : public PersonalDataManager { 429 public: 430 MockPersonalDataManager() : PersonalDataManager("en-US") {} 431 MOCK_CONST_METHOD0(IsDataLoaded, bool()); 432 MOCK_METHOD0(LoadProfiles, void()); 433 MOCK_METHOD0(LoadCreditCards, void()); 434 MOCK_METHOD0(Refresh, void()); 435 436 static KeyedService* Build(content::BrowserContext* profile) { 437 return new MockPersonalDataManager(); 438 } 439 }; 440 441 template <class T> class AddAutofillHelper; 442 443 class ProfileSyncServiceAutofillTest 444 : public AbstractProfileSyncServiceTest, 445 public syncer::DataTypeDebugInfoListener { 446 public: 447 // DataTypeDebugInfoListener implementation. 448 virtual void OnDataTypeConfigureComplete( 449 const std::vector<syncer::DataTypeConfigurationStats>& 450 configuration_stats) OVERRIDE { 451 ASSERT_EQ(1u, configuration_stats.size()); 452 association_stats_ = configuration_stats[0].association_stats; 453 } 454 455 protected: 456 ProfileSyncServiceAutofillTest() 457 : profile_manager_(TestingBrowserProcess::GetGlobal()), 458 debug_ptr_factory_(this) { 459 } 460 virtual ~ProfileSyncServiceAutofillTest() { 461 } 462 463 AutofillProfileFactory profile_factory_; 464 AutofillEntryFactory entry_factory_; 465 466 AbstractAutofillFactory* GetFactory(syncer::ModelType type) { 467 if (type == syncer::AUTOFILL) { 468 return &entry_factory_; 469 } else if (type == syncer::AUTOFILL_PROFILE) { 470 return &profile_factory_; 471 } else { 472 NOTREACHED(); 473 return NULL; 474 } 475 } 476 477 virtual void SetUp() OVERRIDE { 478 AbstractProfileSyncServiceTest::SetUp(); 479 ASSERT_TRUE(profile_manager_.SetUp()); 480 TestingProfile::TestingFactories testing_factories; 481 testing_factories.push_back(std::make_pair( 482 ProfileOAuth2TokenServiceFactory::GetInstance(), 483 BuildAutoIssuingFakeProfileOAuth2TokenService)); 484 profile_ = profile_manager_.CreateTestingProfile( 485 kTestProfileName, 486 scoped_ptr<PrefServiceSyncable>(), 487 base::UTF8ToUTF16(kTestProfileName), 488 0, 489 std::string(), 490 testing_factories); 491 web_database_.reset(new WebDatabaseFake(&autofill_table_)); 492 MockWebDataServiceWrapper* wrapper = 493 static_cast<MockWebDataServiceWrapper*>( 494 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse( 495 profile_, BuildMockWebDataServiceWrapper)); 496 web_data_service_ = 497 static_cast<WebDataServiceFake*>(wrapper->GetAutofillWebData().get()); 498 web_data_service_->SetDatabase(web_database_.get()); 499 500 personal_data_manager_ = static_cast<MockPersonalDataManager*>( 501 autofill::PersonalDataManagerFactory::GetInstance() 502 ->SetTestingFactoryAndUse(profile_, 503 MockPersonalDataManager::Build)); 504 505 EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1); 506 EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1); 507 508 personal_data_manager_->Init( 509 WebDataServiceFactory::GetAutofillWebDataForProfile( 510 profile_, Profile::EXPLICIT_ACCESS), 511 profile_->GetPrefs(), 512 profile_->IsOffTheRecord()); 513 514 web_data_service_->StartSyncableService(); 515 } 516 517 virtual void TearDown() OVERRIDE { 518 // Note: The tear down order is important. 519 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL); 520 web_data_service_->ShutdownOnUIThread(); 521 web_data_service_->ShutdownSyncableService(); 522 web_data_service_ = NULL; 523 // To prevent a leak, fully release TestURLRequestContext to ensure its 524 // destruction on the IO message loop. 525 profile_ = NULL; 526 profile_manager_.DeleteTestingProfile(kTestProfileName); 527 AbstractProfileSyncServiceTest::TearDown(); 528 } 529 530 int GetSyncCount(syncer::ModelType type) { 531 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 532 syncer::ReadNode node(&trans); 533 if (node.InitTypeRoot(type) != syncer::BaseNode::INIT_OK) 534 return 0; 535 return node.GetTotalNodeCount() - 1; 536 } 537 538 void StartSyncService(const base::Closure& callback, 539 bool will_fail_association, 540 syncer::ModelType type) { 541 AbstractAutofillFactory* factory = GetFactory(type); 542 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile_); 543 signin->SetAuthenticatedUsername("test_user (at) gmail.com"); 544 sync_service_ = TestProfileSyncService::BuildAutoStartAsyncInit(profile_, 545 callback); 546 547 ProfileSyncComponentsFactoryMock* components = 548 sync_service_->components_factory_mock(); 549 DataTypeController* data_type_controller = 550 factory->CreateDataTypeController(components, profile_, sync_service_); 551 factory->SetExpectation(components, 552 sync_service_, 553 web_data_service_.get(), 554 data_type_controller); 555 556 EXPECT_CALL(*components, CreateDataTypeManager(_, _, _, _, _, _)). 557 WillOnce(ReturnNewDataTypeManagerWithDebugListener( 558 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr()))); 559 560 EXPECT_CALL(*personal_data_manager_, IsDataLoaded()). 561 WillRepeatedly(Return(true)); 562 563 // We need tokens to get the tests going 564 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) 565 ->UpdateCredentials("test_user (at) gmail.com", "oauth2_login_token"); 566 567 sync_service_->RegisterDataTypeController(data_type_controller); 568 sync_service_->Initialize(); 569 base::MessageLoop::current()->Run(); 570 571 // It's possible this test triggered an unrecoverable error, in which case 572 // we can't get the sync count. 573 if (sync_service_->ShouldPushChanges()) { 574 EXPECT_EQ(GetSyncCount(type), 575 association_stats_.num_sync_items_after_association); 576 } 577 EXPECT_EQ(association_stats_.num_sync_items_after_association, 578 association_stats_.num_sync_items_before_association + 579 association_stats_.num_sync_items_added - 580 association_stats_.num_sync_items_deleted); 581 } 582 583 bool AddAutofillSyncNode(const AutofillEntry& entry) { 584 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 585 syncer::ReadNode autofill_root(&trans); 586 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) { 587 return false; 588 } 589 590 syncer::WriteNode node(&trans); 591 std::string tag = AutocompleteSyncableService::KeyToTag( 592 base::UTF16ToUTF8(entry.key().name()), 593 base::UTF16ToUTF8(entry.key().value())); 594 syncer::WriteNode::InitUniqueByCreationResult result = 595 node.InitUniqueByCreation(syncer::AUTOFILL, autofill_root, tag); 596 if (result != syncer::WriteNode::INIT_SUCCESS) 597 return false; 598 599 sync_pb::EntitySpecifics specifics; 600 AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics); 601 sync_pb::AutofillSpecifics* autofill_specifics = 602 specifics.mutable_autofill(); 603 node.SetAutofillSpecifics(*autofill_specifics); 604 return true; 605 } 606 607 bool AddAutofillSyncNode(const AutofillProfile& profile) { 608 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 609 syncer::ReadNode autofill_root(&trans); 610 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) { 611 return false; 612 } 613 syncer::WriteNode node(&trans); 614 std::string tag = profile.guid(); 615 syncer::WriteNode::InitUniqueByCreationResult result = 616 node.InitUniqueByCreation(syncer::AUTOFILL_PROFILE, 617 autofill_root, tag); 618 if (result != syncer::WriteNode::INIT_SUCCESS) 619 return false; 620 621 sync_pb::EntitySpecifics specifics; 622 AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics); 623 sync_pb::AutofillProfileSpecifics* profile_specifics = 624 specifics.mutable_autofill_profile(); 625 node.SetAutofillProfileSpecifics(*profile_specifics); 626 return true; 627 } 628 629 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries, 630 std::vector<AutofillProfile>* profiles) { 631 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 632 syncer::ReadNode autofill_root(&trans); 633 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) { 634 return false; 635 } 636 637 int64 child_id = autofill_root.GetFirstChildId(); 638 while (child_id != syncer::kInvalidId) { 639 syncer::ReadNode child_node(&trans); 640 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) 641 return false; 642 643 const sync_pb::AutofillSpecifics& autofill( 644 child_node.GetAutofillSpecifics()); 645 if (autofill.has_value()) { 646 AutofillKey key(base::UTF8ToUTF16(autofill.name()), 647 base::UTF8ToUTF16(autofill.value())); 648 std::vector<base::Time> timestamps; 649 int timestamps_count = autofill.usage_timestamp_size(); 650 for (int i = 0; i < timestamps_count; ++i) { 651 timestamps.push_back(Time::FromInternalValue( 652 autofill.usage_timestamp(i))); 653 } 654 entries->push_back( 655 AutofillEntry(key, timestamps.front(), timestamps.back())); 656 } else if (autofill.has_profile()) { 657 AutofillProfile p; 658 p.set_guid(autofill.profile().guid()); 659 AutofillProfileSyncableService::OverwriteProfileWithServerData( 660 autofill.profile(), &p, "en-US"); 661 profiles->push_back(p); 662 } 663 child_id = child_node.GetSuccessorId(); 664 } 665 return true; 666 } 667 668 bool GetAutofillProfilesFromSyncDBUnderProfileNode( 669 std::vector<AutofillProfile>* profiles) { 670 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 671 syncer::ReadNode autofill_root(&trans); 672 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) { 673 return false; 674 } 675 676 int64 child_id = autofill_root.GetFirstChildId(); 677 while (child_id != syncer::kInvalidId) { 678 syncer::ReadNode child_node(&trans); 679 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) 680 return false; 681 682 const sync_pb::AutofillProfileSpecifics& autofill( 683 child_node.GetAutofillProfileSpecifics()); 684 AutofillProfile p; 685 p.set_guid(autofill.guid()); 686 AutofillProfileSyncableService::OverwriteProfileWithServerData( 687 autofill, &p, "en-US"); 688 profiles->push_back(p); 689 child_id = child_node.GetSuccessorId(); 690 } 691 return true; 692 } 693 694 void SetIdleChangeProcessorExpectations() { 695 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0); 696 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0); 697 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).Times(0); 698 } 699 700 static AutofillEntry MakeAutofillEntry(const char* name, 701 const char* value, 702 int time_shift0, 703 int time_shift1) { 704 // Time deep in the past would cause Autocomplete sync to discard the 705 // entries. 706 static Time base_time = Time::Now().LocalMidnight(); 707 708 base::Time date_created = base_time + TimeDelta::FromSeconds(time_shift0); 709 base::Time date_last_used = date_created; 710 if (time_shift1 >= 0) 711 date_last_used = base_time + TimeDelta::FromSeconds(time_shift1); 712 return AutofillEntry( 713 AutofillKey(base::ASCIIToUTF16(name), base::ASCIIToUTF16(value)), 714 date_created, date_last_used); 715 } 716 717 static AutofillEntry MakeAutofillEntry(const char* name, 718 const char* value, 719 int time_shift) { 720 return MakeAutofillEntry(name, value, time_shift, -1); 721 } 722 723 friend class AddAutofillHelper<AutofillEntry>; 724 friend class AddAutofillHelper<AutofillProfile>; 725 friend class FakeServerUpdater; 726 727 TestingProfileManager profile_manager_; 728 TestingProfile* profile_; 729 AutofillTableMock autofill_table_; 730 scoped_ptr<WebDatabaseFake> web_database_; 731 scoped_refptr<WebDataServiceFake> web_data_service_; 732 MockPersonalDataManager* personal_data_manager_; 733 syncer::DataTypeAssociationStats association_stats_; 734 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_; 735 }; 736 737 template <class T> 738 class AddAutofillHelper { 739 public: 740 AddAutofillHelper(ProfileSyncServiceAutofillTest* test, 741 const std::vector<T>& entries) 742 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback, 743 base::Unretained(this), test, entries)), 744 success_(false) { 745 } 746 747 const base::Closure& callback() const { return callback_; } 748 bool success() { return success_; } 749 750 private: 751 void AddAutofillCallback(ProfileSyncServiceAutofillTest* test, 752 const std::vector<T>& entries) { 753 if (!test->CreateRoot(GetModelType<T>())) 754 return; 755 756 for (size_t i = 0; i < entries.size(); ++i) { 757 if (!test->AddAutofillSyncNode(entries[i])) 758 return; 759 } 760 success_ = true; 761 } 762 763 base::Closure callback_; 764 bool success_; 765 }; 766 767 // Overload write transaction to use custom NotifyTransactionComplete 768 class WriteTransactionTest: public WriteTransaction { 769 public: 770 WriteTransactionTest(const tracked_objects::Location& from_here, 771 WriterTag writer, 772 syncer::syncable::Directory* directory, 773 scoped_ptr<WaitableEvent>* wait_for_syncapi) 774 : WriteTransaction(from_here, writer, directory), 775 wait_for_syncapi_(wait_for_syncapi) { } 776 777 virtual void NotifyTransactionComplete( 778 syncer::ModelTypeSet types) OVERRIDE { 779 // This is where we differ. Force a thread change here, giving another 780 // thread a chance to create a WriteTransaction 781 (*wait_for_syncapi_)->Wait(); 782 783 WriteTransaction::NotifyTransactionComplete(types); 784 } 785 786 private: 787 scoped_ptr<WaitableEvent>* wait_for_syncapi_; 788 }; 789 790 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can 791 // post tasks with it. 792 class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> { 793 public: 794 FakeServerUpdater(TestProfileSyncService* service, 795 scoped_ptr<WaitableEvent>* wait_for_start, 796 scoped_ptr<WaitableEvent>* wait_for_syncapi) 797 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)), 798 service_(service), 799 wait_for_start_(wait_for_start), 800 wait_for_syncapi_(wait_for_syncapi), 801 is_finished_(false, false) { } 802 803 void Update() { 804 // This gets called in a modelsafeworker thread. 805 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 806 807 syncer::UserShare* user_share = service_->GetUserShare(); 808 syncer::syncable::Directory* directory = user_share->directory.get(); 809 810 // Create autofill protobuf. 811 std::string tag = AutocompleteSyncableService::KeyToTag( 812 base::UTF16ToUTF8(entry_.key().name()), 813 base::UTF16ToUTF8(entry_.key().value())); 814 sync_pb::AutofillSpecifics new_autofill; 815 new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name())); 816 new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value())); 817 new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue()); 818 if (entry_.date_created() != entry_.date_last_used()) { 819 new_autofill.add_usage_timestamp( 820 entry_.date_last_used().ToInternalValue()); 821 } 822 823 sync_pb::EntitySpecifics entity_specifics; 824 entity_specifics.mutable_autofill()->CopyFrom(new_autofill); 825 826 { 827 // Tell main thread we've started 828 (*wait_for_start_)->Signal(); 829 830 // Create write transaction. 831 WriteTransactionTest trans(FROM_HERE, UNITTEST, directory, 832 wait_for_syncapi_); 833 834 // Create actual entry based on autofill protobuf information. 835 // Simulates effects of UpdateLocalDataFromServerData 836 MutableEntry parent(&trans, GET_TYPE_ROOT, syncer::AUTOFILL); 837 MutableEntry item(&trans, CREATE, syncer::AUTOFILL, parent.GetId(), tag); 838 ASSERT_TRUE(item.good()); 839 item.PutSpecifics(entity_specifics); 840 item.PutServerSpecifics(entity_specifics); 841 item.PutBaseVersion(1); 842 syncer::syncable::Id server_item_id = 843 service_->id_factory()->NewServerId(); 844 item.PutId(server_item_id); 845 syncer::syncable::Id new_predecessor; 846 ASSERT_TRUE(item.PutPredecessor(new_predecessor)); 847 } 848 DVLOG(1) << "FakeServerUpdater finishing."; 849 is_finished_.Signal(); 850 } 851 852 void CreateNewEntry(const AutofillEntry& entry) { 853 entry_ = entry; 854 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 855 if (!BrowserThread::PostTask( 856 BrowserThread::DB, FROM_HERE, 857 base::Bind(&FakeServerUpdater::Update, this))) { 858 NOTREACHED() << "Failed to post task to the db thread."; 859 return; 860 } 861 } 862 863 void CreateNewEntryAndWait(const AutofillEntry& entry) { 864 entry_ = entry; 865 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 866 is_finished_.Reset(); 867 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 868 base::Bind(&FakeServerUpdater::Update, this))) { 869 NOTREACHED() << "Failed to post task to the db thread."; 870 return; 871 } 872 is_finished_.Wait(); 873 } 874 875 private: 876 friend class base::RefCountedThreadSafe<FakeServerUpdater>; 877 ~FakeServerUpdater() { } 878 879 AutofillEntry entry_; 880 TestProfileSyncService* service_; 881 scoped_ptr<WaitableEvent>* wait_for_start_; 882 scoped_ptr<WaitableEvent>* wait_for_syncapi_; 883 WaitableEvent is_finished_; 884 syncer::syncable::Id parent_id_; 885 }; 886 887 namespace { 888 889 // Checks if the field of type |field_type| in |profile1| includes all values 890 // of the field in |profile2|. 891 bool IncludesField(const AutofillProfile& profile1, 892 const AutofillProfile& profile2, 893 ServerFieldType field_type) { 894 std::vector<base::string16> values1; 895 profile1.GetRawMultiInfo(field_type, &values1); 896 std::vector<base::string16> values2; 897 profile2.GetRawMultiInfo(field_type, &values2); 898 899 std::set<base::string16> values_set; 900 for (size_t i = 0; i < values1.size(); ++i) 901 values_set.insert(values1[i]); 902 for (size_t i = 0; i < values2.size(); ++i) 903 if (values_set.find(values2[i]) == values_set.end()) 904 return false; 905 return true; 906 } 907 908 } // namespace 909 910 // TODO(skrul): Test abort startup. 911 // TODO(skrul): Test processing of cloud changes. 912 // TODO(tim): Add autofill data type controller test, and a case to cover 913 // waiting for the PersonalDataManager. 914 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) { 915 // Don't create the root autofill node so startup fails. 916 StartSyncService(base::Closure(), true, syncer::AUTOFILL); 917 EXPECT_TRUE(sync_service_->HasUnrecoverableError()); 918 } 919 920 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) { 921 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 922 SetIdleChangeProcessorExpectations(); 923 CreateRootHelper create_root(this, syncer::AUTOFILL); 924 EXPECT_CALL(*personal_data_manager_, Refresh()); 925 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 926 EXPECT_TRUE(create_root.success()); 927 std::vector<AutofillEntry> sync_entries; 928 std::vector<AutofillProfile> sync_profiles; 929 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 930 EXPECT_EQ(0U, sync_entries.size()); 931 EXPECT_EQ(0U, sync_profiles.size()); 932 } 933 934 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) { 935 std::vector<AutofillEntry> entries; 936 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); 937 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 938 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); 939 SetIdleChangeProcessorExpectations(); 940 CreateRootHelper create_root(this, syncer::AUTOFILL); 941 EXPECT_CALL(*personal_data_manager_, Refresh()); 942 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 943 ASSERT_TRUE(create_root.success()); 944 std::vector<AutofillEntry> sync_entries; 945 std::vector<AutofillProfile> sync_profiles; 946 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 947 ASSERT_EQ(1U, entries.size()); 948 EXPECT_TRUE(entries[0] == sync_entries[0]); 949 EXPECT_EQ(0U, sync_profiles.size()); 950 } 951 952 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { 953 std::vector<AutofillProfile*> profiles; 954 std::vector<AutofillProfile> expected_profiles; 955 // Owned by GetAutofillProfiles caller. 956 AutofillProfile* profile0 = new AutofillProfile; 957 autofill::test::SetProfileInfoWithGuid(profile0, 958 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing", 959 "Mitchell", "Morrison", 960 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 961 "91601", "US", "12345678910"); 962 profiles.push_back(profile0); 963 expected_profiles.push_back(*profile0); 964 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 965 WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true))); 966 EXPECT_CALL(*personal_data_manager_, Refresh()); 967 SetIdleChangeProcessorExpectations(); 968 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE); 969 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE); 970 ASSERT_TRUE(create_root.success()); 971 std::vector<AutofillProfile> sync_profiles; 972 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles)); 973 EXPECT_EQ(1U, sync_profiles.size()); 974 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0])); 975 } 976 977 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) { 978 // There is buggy autofill code that allows duplicate name/value 979 // pairs to exist in the database with separate pair_ids. 980 std::vector<AutofillEntry> entries; 981 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); 982 entries.push_back(MakeAutofillEntry("dup", "", 2)); 983 entries.push_back(MakeAutofillEntry("dup", "", 3)); 984 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 985 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); 986 SetIdleChangeProcessorExpectations(); 987 CreateRootHelper create_root(this, syncer::AUTOFILL); 988 EXPECT_CALL(*personal_data_manager_, Refresh()); 989 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 990 ASSERT_TRUE(create_root.success()); 991 std::vector<AutofillEntry> sync_entries; 992 std::vector<AutofillProfile> sync_profiles; 993 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 994 EXPECT_EQ(2U, sync_entries.size()); 995 } 996 997 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) { 998 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1)); 999 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2)); 1000 1001 std::vector<AutofillEntry> native_entries; 1002 native_entries.push_back(native_entry); 1003 1004 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 1005 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); 1006 1007 std::vector<AutofillEntry> sync_entries; 1008 sync_entries.push_back(sync_entry); 1009 1010 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); 1011 1012 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))). 1013 WillOnce(Return(true)); 1014 1015 EXPECT_CALL(*personal_data_manager_, Refresh()); 1016 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL); 1017 ASSERT_TRUE(add_autofill.success()); 1018 1019 std::set<AutofillEntry> expected_entries; 1020 expected_entries.insert(native_entry); 1021 expected_entries.insert(sync_entry); 1022 1023 std::vector<AutofillEntry> new_sync_entries; 1024 std::vector<AutofillProfile> new_sync_profiles; 1025 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 1026 &new_sync_profiles)); 1027 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), 1028 new_sync_entries.end()); 1029 1030 EXPECT_TRUE(expected_entries == new_sync_entries_set); 1031 } 1032 1033 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) { 1034 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1)); 1035 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2)); 1036 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2)); 1037 1038 std::vector<AutofillEntry> native_entries; 1039 native_entries.push_back(native_entry); 1040 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 1041 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); 1042 1043 std::vector<AutofillEntry> sync_entries; 1044 sync_entries.push_back(sync_entry); 1045 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); 1046 1047 EXPECT_CALL(autofill_table_, 1048 UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true)); 1049 EXPECT_CALL(*personal_data_manager_, Refresh()); 1050 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL); 1051 ASSERT_TRUE(add_autofill.success()); 1052 1053 std::vector<AutofillEntry> new_sync_entries; 1054 std::vector<AutofillProfile> new_sync_profiles; 1055 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 1056 &new_sync_profiles)); 1057 ASSERT_EQ(1U, new_sync_entries.size()); 1058 EXPECT_TRUE(merged_entry == new_sync_entries[0]); 1059 } 1060 1061 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { 1062 AutofillProfile sync_profile; 1063 autofill::test::SetProfileInfoWithGuid(&sync_profile, 1064 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", 1065 "Mitchell", "Morrison", 1066 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 1067 "91601", "US", "12345678910"); 1068 1069 AutofillProfile* native_profile = new AutofillProfile; 1070 autofill::test::SetProfileInfoWithGuid(native_profile, 1071 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz", 1072 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 1073 "32801", "US", "19482937549"); 1074 1075 std::vector<AutofillProfile*> native_profiles; 1076 native_profiles.push_back(native_profile); 1077 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 1078 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 1079 1080 std::vector<AutofillProfile> sync_profiles; 1081 sync_profiles.push_back(sync_profile); 1082 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); 1083 1084 EXPECT_CALL(autofill_table_, 1085 UpdateAutofillProfile(MatchProfiles(sync_profile))). 1086 WillOnce(Return(true)); 1087 EXPECT_CALL(*personal_data_manager_, Refresh()); 1088 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE); 1089 ASSERT_TRUE(add_autofill.success()); 1090 1091 std::vector<AutofillProfile> new_sync_profiles; 1092 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1093 &new_sync_profiles)); 1094 ASSERT_EQ(1U, new_sync_profiles.size()); 1095 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); 1096 } 1097 1098 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfileCombine) { 1099 AutofillProfile sync_profile; 1100 autofill::test::SetProfileInfoWithGuid(&sync_profile, 1101 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", 1102 "Mitchell", "Morrison", 1103 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 1104 "91601", "US", "12345678910"); 1105 1106 AutofillProfile* native_profile = new AutofillProfile; 1107 // Same address, but different names, phones and e-mails. 1108 autofill::test::SetProfileInfoWithGuid(native_profile, 1109 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz", 1110 "joewayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 1111 "91601", "US", "19482937549"); 1112 1113 AutofillProfile expected_profile(sync_profile); 1114 expected_profile.OverwriteWithOrAddTo(*native_profile, "en-US"); 1115 1116 std::vector<AutofillProfile*> native_profiles; 1117 native_profiles.push_back(native_profile); 1118 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 1119 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 1120 EXPECT_CALL(autofill_table_, 1121 AddAutofillProfile(MatchProfiles(expected_profile))). 1122 WillOnce(Return(true)); 1123 EXPECT_CALL(autofill_table_, 1124 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")). 1125 WillOnce(Return(true)); 1126 std::vector<AutofillProfile> sync_profiles; 1127 sync_profiles.push_back(sync_profile); 1128 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); 1129 1130 EXPECT_CALL(*personal_data_manager_, Refresh()); 1131 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE); 1132 ASSERT_TRUE(add_autofill.success()); 1133 1134 std::vector<AutofillProfile> new_sync_profiles; 1135 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1136 &new_sync_profiles)); 1137 ASSERT_EQ(1U, new_sync_profiles.size()); 1138 // Check that key fields are the same. 1139 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US")); 1140 // Check that multivalued fields of the synced back data include original 1141 // data. 1142 EXPECT_TRUE( 1143 IncludesField(new_sync_profiles[0], sync_profile, autofill::NAME_FULL)); 1144 EXPECT_TRUE(IncludesField( 1145 new_sync_profiles[0], sync_profile, autofill::EMAIL_ADDRESS)); 1146 EXPECT_TRUE(IncludesField( 1147 new_sync_profiles[0], sync_profile, autofill::PHONE_HOME_WHOLE_NUMBER)); 1148 } 1149 1150 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) { 1151 AutofillProfile sync_profile; 1152 1153 autofill::test::SetProfileInfoWithGuid(&sync_profile, 1154 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", 1155 "Mitchell", "Morrison", 1156 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 1157 "91601", "US", "12345678910"); 1158 1159 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B"; 1160 AutofillProfile* native_profile = new AutofillProfile; 1161 autofill::test::SetProfileInfoWithGuid(native_profile, 1162 native_guid.c_str(), "Billing", 1163 "Mitchell", "Morrison", 1164 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 1165 "91601", "US", "12345678910"); 1166 1167 std::vector<AutofillProfile*> native_profiles; 1168 native_profiles.push_back(native_profile); 1169 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 1170 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 1171 1172 std::vector<AutofillProfile> sync_profiles; 1173 sync_profiles.push_back(sync_profile); 1174 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); 1175 1176 EXPECT_CALL(autofill_table_, AddAutofillProfile(_)). 1177 WillOnce(Return(true)); 1178 EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)). 1179 WillOnce(Return(true)); 1180 EXPECT_CALL(*personal_data_manager_, Refresh()); 1181 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE); 1182 ASSERT_TRUE(add_autofill.success()); 1183 1184 std::vector<AutofillProfile> new_sync_profiles; 1185 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1186 &new_sync_profiles)); 1187 ASSERT_EQ(1U, new_sync_profiles.size()); 1188 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); 1189 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid()); 1190 } 1191 1192 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { 1193 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 1194 EXPECT_CALL(*personal_data_manager_, Refresh()); 1195 SetIdleChangeProcessorExpectations(); 1196 CreateRootHelper create_root(this, syncer::AUTOFILL); 1197 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 1198 ASSERT_TRUE(create_root.success()); 1199 1200 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1)); 1201 1202 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)). 1203 WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()), 1204 SetArgumentPointee<3>(added_entry.date_last_used()), 1205 Return(true))); 1206 1207 AutofillChangeList changes; 1208 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); 1209 1210 web_data_service_->OnAutofillEntriesChanged(changes); 1211 1212 std::vector<AutofillEntry> new_sync_entries; 1213 std::vector<AutofillProfile> new_sync_profiles; 1214 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 1215 &new_sync_profiles)); 1216 ASSERT_EQ(1U, new_sync_entries.size()); 1217 EXPECT_TRUE(added_entry == new_sync_entries[0]); 1218 } 1219 1220 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { 1221 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 1222 EXPECT_CALL(*personal_data_manager_, Refresh()); 1223 SetIdleChangeProcessorExpectations(); 1224 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE); 1225 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE); 1226 ASSERT_TRUE(create_root.success()); 1227 1228 AutofillProfile added_profile; 1229 autofill::test::SetProfileInfoWithGuid(&added_profile, 1230 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz", 1231 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 1232 "32801", "US", "19482937549"); 1233 1234 AutofillProfileChange change( 1235 AutofillProfileChange::ADD, added_profile.guid(), &added_profile); 1236 web_data_service_->OnAutofillProfileChanged(change); 1237 1238 std::vector<AutofillProfile> new_sync_profiles; 1239 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1240 &new_sync_profiles)); 1241 ASSERT_EQ(1U, new_sync_profiles.size()); 1242 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0])); 1243 } 1244 1245 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { 1246 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); 1247 std::vector<AutofillEntry> original_entries; 1248 original_entries.push_back(original_entry); 1249 1250 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 1251 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); 1252 EXPECT_CALL(*personal_data_manager_, Refresh()); 1253 CreateRootHelper create_root(this, syncer::AUTOFILL); 1254 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 1255 ASSERT_TRUE(create_root.success()); 1256 1257 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2)); 1258 1259 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)). 1260 WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()), 1261 SetArgumentPointee<3>(updated_entry.date_last_used()), 1262 Return(true))); 1263 1264 AutofillChangeList changes; 1265 changes.push_back(AutofillChange(AutofillChange::UPDATE, 1266 updated_entry.key())); 1267 web_data_service_->OnAutofillEntriesChanged(changes); 1268 1269 std::vector<AutofillEntry> new_sync_entries; 1270 std::vector<AutofillProfile> new_sync_profiles; 1271 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 1272 &new_sync_profiles)); 1273 ASSERT_EQ(1U, new_sync_entries.size()); 1274 EXPECT_TRUE(updated_entry == new_sync_entries[0]); 1275 } 1276 1277 1278 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { 1279 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); 1280 std::vector<AutofillEntry> original_entries; 1281 original_entries.push_back(original_entry); 1282 1283 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 1284 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); 1285 EXPECT_CALL(*personal_data_manager_, Refresh()); 1286 CreateRootHelper create_root(this, syncer::AUTOFILL); 1287 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 1288 ASSERT_TRUE(create_root.success()); 1289 1290 AutofillChangeList changes; 1291 changes.push_back(AutofillChange(AutofillChange::REMOVE, 1292 original_entry.key())); 1293 web_data_service_->OnAutofillEntriesChanged(changes); 1294 1295 std::vector<AutofillEntry> new_sync_entries; 1296 std::vector<AutofillProfile> new_sync_profiles; 1297 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 1298 &new_sync_profiles)); 1299 ASSERT_EQ(0U, new_sync_entries.size()); 1300 } 1301 1302 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { 1303 AutofillProfile sync_profile; 1304 autofill::test::SetProfileInfoWithGuid(&sync_profile, 1305 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", 1306 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 1307 "32801", "US", "19482937549"); 1308 AutofillProfile* native_profile = new AutofillProfile; 1309 autofill::test::SetProfileInfoWithGuid(native_profile, 1310 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", 1311 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 1312 "32801", "US", "19482937549"); 1313 1314 std::vector<AutofillProfile*> native_profiles; 1315 native_profiles.push_back(native_profile); 1316 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 1317 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 1318 1319 std::vector<AutofillProfile> sync_profiles; 1320 sync_profiles.push_back(sync_profile); 1321 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); 1322 EXPECT_CALL(*personal_data_manager_, Refresh()); 1323 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE); 1324 ASSERT_TRUE(add_autofill.success()); 1325 1326 AutofillProfileChange change( 1327 AutofillProfileChange::REMOVE, sync_profile.guid(), NULL); 1328 web_data_service_->OnAutofillProfileChanged(change); 1329 1330 std::vector<AutofillProfile> new_sync_profiles; 1331 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1332 &new_sync_profiles)); 1333 ASSERT_EQ(0U, new_sync_profiles.size()); 1334 } 1335 1336 // http://crbug.com/57884 1337 TEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) { 1338 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via 1339 // LoadAutofillData(). 1340 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 1341 Times(3).WillRepeatedly(Return(true)); 1342 // On the other hand Autofill and Autocomplete are separated now, so 1343 // GetAutofillProfiles() should not be called. 1344 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).Times(0); 1345 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)). 1346 WillRepeatedly(Return(true)); 1347 EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3); 1348 CreateRootHelper create_root(this, syncer::AUTOFILL); 1349 StartSyncService(create_root.callback(), false, syncer::AUTOFILL); 1350 ASSERT_TRUE(create_root.success()); 1351 1352 // (true, false) means we have to reset after |Signal|, init to unsignaled. 1353 scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false)); 1354 scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false)); 1355 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater( 1356 sync_service_, &wait_for_start, &wait_for_syncapi)); 1357 1358 // This server side update will stall waiting for CommitWaiter. 1359 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1)); 1360 wait_for_start->Wait(); 1361 1362 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2)); 1363 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry)); 1364 DVLOG(1) << "Syncapi update finished."; 1365 1366 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay! 1367 // Signal FakeServerUpdater that it can complete. 1368 wait_for_syncapi->Signal(); 1369 1370 // Make another entry to ensure nothing broke afterwards and wait for finish 1371 // to clean up. 1372 updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3)); 1373 1374 std::vector<AutofillEntry> sync_entries; 1375 std::vector<AutofillProfile> sync_profiles; 1376 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 1377 EXPECT_EQ(3U, sync_entries.size()); 1378 EXPECT_EQ(0U, sync_profiles.size()); 1379 for (size_t i = 0; i < sync_entries.size(); i++) { 1380 DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name() 1381 << ", " << sync_entries[i].key().value(); 1382 } 1383 } 1384