password_syncable_service_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/password_manager/core/browser/password_syncable_service.h" 6 7#include <algorithm> 8#include <string> 9#include <vector> 10 11#include "base/basictypes.h" 12#include "base/location.h" 13#include "base/memory/ref_counted.h" 14#include "base/memory/scoped_ptr.h" 15#include "components/password_manager/core/browser/mock_password_store.h" 16#include "sync/api/sync_change_processor.h" 17#include "sync/api/sync_error.h" 18#include "sync/api/sync_error_factory.h" 19#include "testing/gmock/include/gmock/gmock.h" 20#include "testing/gtest/include/gtest/gtest.h" 21 22using syncer::SyncChange; 23using syncer::SyncData; 24using syncer::SyncDataList; 25using syncer::SyncError; 26using testing::Invoke; 27using testing::Return; 28using testing::SetArgPointee; 29using testing::_; 30 31namespace { 32 33typedef std::vector<SyncChange> SyncChangeList; 34 35const sync_pb::PasswordSpecificsData& GetPasswordSpecifics( 36 const syncer::SyncData& sync_data) { 37 const sync_pb::EntitySpecifics& specifics = sync_data.GetSpecifics(); 38 return specifics.password().client_only_encrypted_data(); 39} 40 41void PasswordsEqual(const sync_pb::PasswordSpecificsData& expected_password, 42 const sync_pb::PasswordSpecificsData& actual_password) { 43 EXPECT_EQ(expected_password.scheme(), actual_password.scheme()); 44 EXPECT_EQ(expected_password.signon_realm(), actual_password.signon_realm()); 45 EXPECT_EQ(expected_password.origin(), actual_password.origin()); 46 EXPECT_EQ(expected_password.action(), actual_password.action()); 47 EXPECT_EQ(expected_password.username_element(), 48 actual_password.username_element()); 49 EXPECT_EQ(expected_password.password_element(), 50 actual_password.password_element()); 51 EXPECT_EQ(expected_password.username_value(), 52 actual_password.username_value()); 53 EXPECT_EQ(expected_password.password_value(), 54 actual_password.password_value()); 55 EXPECT_EQ(expected_password.ssl_valid(), actual_password.ssl_valid()); 56 EXPECT_EQ(expected_password.preferred(), actual_password.preferred()); 57 EXPECT_EQ(expected_password.date_created(), actual_password.date_created()); 58 EXPECT_EQ(expected_password.blacklisted(), actual_password.blacklisted()); 59} 60 61// Creates a sync data consisting of password specifics. The sign on realm is 62// set to |signon_realm|. 63SyncData CreateSyncData(const std::string& signon_realm) { 64 sync_pb::EntitySpecifics password_data; 65 sync_pb::PasswordSpecificsData* password_specifics = 66 password_data.mutable_password()->mutable_client_only_encrypted_data(); 67 password_specifics->set_signon_realm(signon_realm); 68 69 std::string tag = MakePasswordSyncTag(*password_specifics); 70 return syncer::SyncData::CreateLocalData(tag, tag, password_data); 71} 72 73SyncChange CreateSyncChange(const autofill::PasswordForm& password, 74 SyncChange::SyncChangeType type) { 75 SyncData data = SyncDataFromPassword(password); 76 return SyncChange(FROM_HERE, type, data); 77} 78 79// A testable implementation of the |PasswordSyncableService| that mocks 80// out all interaction with the password database. 81class MockPasswordSyncableService : public PasswordSyncableService { 82 public: 83 explicit MockPasswordSyncableService(PasswordStore* password_store) 84 : PasswordSyncableService(password_store) {} 85 virtual ~MockPasswordSyncableService() {} 86 87 MOCK_METHOD1(NotifyPasswordStoreOfLoginChanges, 88 void (const PasswordStoreChangeList&)); 89}; 90 91// Class to verify the arguments passed to |PasswordStore|. 92class PasswordStoreDataVerifier { 93 public: 94 PasswordStoreDataVerifier() {} 95 ~PasswordStoreDataVerifier() { 96 EXPECT_TRUE(expected_db_add_changes_.empty()); 97 EXPECT_TRUE(expected_db_update_changes_.empty()); 98 EXPECT_TRUE(expected_db_delete_changes_.empty()); 99 } 100 101 class TestSyncChangeProcessor; 102 103 // Sets expected changes to the password database. 104 void SetExpectedDBChanges( 105 const SyncDataList& add_forms, 106 const std::vector<autofill::PasswordForm*>& update_forms, 107 const std::vector<autofill::PasswordForm*>& delete_forms, 108 MockPasswordStore* password_store); 109 // Sets expected changes to TestSyncChangeProcessor. 110 void SetExpectedSyncChanges(SyncChangeList list); 111 112 private: 113 // Checks that |change_list| matches |expected_sync_change_list_|. 114 SyncError TestSyncChanges(const SyncChangeList& change_list); 115 116 // Verifies that the |password| is present in the |expected_db_add_changes_| 117 // list. If found, |password| would be removed from 118 // |expected_db_add_changes_| list. 119 PasswordStoreChangeList VerifyAdd(const autofill::PasswordForm& password) { 120 return VerifyChange(PasswordStoreChange::ADD, password, 121 &expected_db_add_changes_); 122 } 123 124 // Verifies that the |password| is present in the 125 // |expected_db_update_changes_| list. If found, |password| would be removed 126 // from |expected_db_update_changes_| list. 127 PasswordStoreChangeList VerifyUpdate(const autofill::PasswordForm& password) { 128 return VerifyChange(PasswordStoreChange::UPDATE, password, 129 &expected_db_update_changes_); 130 } 131 132 // Verifies that the |password| is present in the 133 // |expected_db_delete_changes_| list. If found, |password| would be removed 134 // from |expected_db_delete_changes_| list. 135 PasswordStoreChangeList VerifyDelete(const autofill::PasswordForm& password) { 136 return VerifyChange(PasswordStoreChange::REMOVE, password, 137 &expected_db_delete_changes_); 138 } 139 140 static PasswordStoreChangeList VerifyChange( 141 PasswordStoreChange::Type type, 142 const autofill::PasswordForm& password, 143 std::vector<autofill::PasswordForm>* password_list); 144 145 std::vector<autofill::PasswordForm> expected_db_add_changes_; 146 std::vector<autofill::PasswordForm> expected_db_update_changes_; 147 std::vector<autofill::PasswordForm> expected_db_delete_changes_; 148 SyncChangeList expected_sync_change_list_; 149 150 DISALLOW_COPY_AND_ASSIGN(PasswordStoreDataVerifier); 151}; 152 153class PasswordStoreDataVerifier::TestSyncChangeProcessor 154 : public syncer::SyncChangeProcessor { 155 public: 156 explicit TestSyncChangeProcessor(PasswordStoreDataVerifier* verifier) 157 : verifier_(verifier) { 158 } 159 virtual ~TestSyncChangeProcessor() {} 160 161 virtual SyncError ProcessSyncChanges(const tracked_objects::Location&, 162 const SyncChangeList& list) OVERRIDE { 163 return verifier_->TestSyncChanges(list); 164 } 165 166 virtual SyncDataList GetAllSyncData(syncer::ModelType type) const OVERRIDE { 167 return SyncDataList(); 168 } 169 private: 170 PasswordStoreDataVerifier* verifier_; 171 172 DISALLOW_COPY_AND_ASSIGN(TestSyncChangeProcessor); 173}; 174 175void PasswordStoreDataVerifier::SetExpectedDBChanges( 176 const SyncDataList& add_forms, 177 const std::vector<autofill::PasswordForm*>& update_forms, 178 const std::vector<autofill::PasswordForm*>& delete_forms, 179 MockPasswordStore* password_store) { 180 DCHECK(expected_db_add_changes_.empty()); 181 DCHECK(expected_db_update_changes_.empty()); 182 DCHECK(password_store); 183 184 for (SyncDataList::const_iterator it = add_forms.begin(); 185 it != add_forms.end(); ++it) { 186 autofill::PasswordForm form; 187 PasswordFromSpecifics(GetPasswordSpecifics(*it), &form); 188 expected_db_add_changes_.push_back(form); 189 } 190 if (expected_db_add_changes_.empty()) { 191 EXPECT_CALL(*password_store, AddLoginImpl(_)).Times(0); 192 } else { 193 EXPECT_CALL(*password_store, AddLoginImpl(_)) 194 .Times(expected_db_add_changes_.size()) 195 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyAdd)); 196 } 197 198 for (std::vector<autofill::PasswordForm*>::const_iterator it = 199 update_forms.begin(); 200 it != update_forms.end(); ++it) { 201 expected_db_update_changes_.push_back(**it); 202 } 203 if (expected_db_update_changes_.empty()) { 204 EXPECT_CALL(*password_store, UpdateLoginImpl(_)).Times(0); 205 } else { 206 EXPECT_CALL(*password_store, UpdateLoginImpl(_)) 207 .Times(expected_db_update_changes_.size()) 208 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyUpdate)); 209 } 210 211 for (std::vector<autofill::PasswordForm*>::const_iterator it = 212 delete_forms.begin(); 213 it != delete_forms.end(); ++it) { 214 expected_db_delete_changes_.push_back(**it); 215 } 216 if (expected_db_delete_changes_.empty()) { 217 EXPECT_CALL(*password_store, RemoveLoginImpl(_)).Times(0); 218 } else { 219 EXPECT_CALL(*password_store, RemoveLoginImpl(_)) 220 .Times(expected_db_delete_changes_.size()) 221 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyDelete)); 222 } 223} 224 225void PasswordStoreDataVerifier::SetExpectedSyncChanges(SyncChangeList list) { 226 expected_sync_change_list_.swap(list); 227} 228 229SyncError PasswordStoreDataVerifier::TestSyncChanges( 230 const SyncChangeList& change_list) { 231 for (SyncChangeList::const_iterator it = change_list.begin(); 232 it != change_list.end(); ++it) { 233 const SyncChange& data = *it; 234 const sync_pb::PasswordSpecificsData& actual_password( 235 GetPasswordSpecifics(data.sync_data())); 236 std::string actual_tag = MakePasswordSyncTag(actual_password); 237 238 bool matched = false; 239 for (SyncChangeList::iterator expected_it = 240 expected_sync_change_list_.begin(); 241 expected_it != expected_sync_change_list_.end(); 242 ++expected_it) { 243 const sync_pb::PasswordSpecificsData& expected_password( 244 GetPasswordSpecifics(expected_it->sync_data())); 245 if (actual_tag == MakePasswordSyncTag(expected_password)) { 246 PasswordsEqual(expected_password, actual_password); 247 EXPECT_EQ(expected_it->change_type(), data.change_type()); 248 matched = true; 249 break; 250 } 251 } 252 EXPECT_TRUE(matched) << actual_tag; 253 } 254 EXPECT_EQ(expected_sync_change_list_.size(), change_list.size()); 255 return SyncError(); 256} 257 258// static 259PasswordStoreChangeList PasswordStoreDataVerifier::VerifyChange( 260 PasswordStoreChange::Type type, 261 const autofill::PasswordForm& password, 262 std::vector<autofill::PasswordForm>* password_list) { 263 std::vector<autofill::PasswordForm>::iterator it = 264 std::find(password_list->begin(), password_list->end(), password); 265 EXPECT_NE(password_list->end(), it); 266 password_list->erase(it); 267 return PasswordStoreChangeList(1, PasswordStoreChange(type, password)); 268} 269 270class PasswordSyncableServiceWrapper { 271 public: 272 PasswordSyncableServiceWrapper() { 273 password_store_ = new MockPasswordStore; 274 service_.reset(new MockPasswordSyncableService(password_store_)); 275 } 276 277 ~PasswordSyncableServiceWrapper() { 278 password_store_->Shutdown(); 279 } 280 281 MockPasswordStore* password_store() { 282 return password_store_; 283 } 284 285 MockPasswordSyncableService* service() { 286 return service_.get(); 287 } 288 289 // Returnes the scoped_ptr to |service_| thus NULLing out it. 290 scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() { 291 return service_.PassAs<syncer::SyncChangeProcessor>(); 292 } 293 294 PasswordStoreDataVerifier* verifier() { 295 return &verifier_; 296 } 297 298 scoped_ptr<syncer::SyncChangeProcessor> CreateSyncChangeProcessor() { 299 return make_scoped_ptr<syncer::SyncChangeProcessor>( 300 new PasswordStoreDataVerifier::TestSyncChangeProcessor(verifier())); 301 } 302 303 // Sets the data that will be returned to the caller accessing password store. 304 void SetPasswordStoreData( 305 const std::vector<autofill::PasswordForm*>& forms, 306 const std::vector<autofill::PasswordForm*>& blacklist_forms) { 307 EXPECT_CALL(*password_store_, FillAutofillableLogins(_)) 308 .WillOnce(Invoke(AppendVector(forms))) 309 .RetiresOnSaturation(); 310 EXPECT_CALL(*password_store_, FillBlacklistLogins(_)) 311 .WillOnce(Invoke(AppendVector(blacklist_forms))) 312 .RetiresOnSaturation(); 313 } 314 315 protected: 316 scoped_refptr<MockPasswordStore> password_store_; 317 scoped_ptr<MockPasswordSyncableService> service_; 318 PasswordStoreDataVerifier verifier_; 319 320 private: 321 struct AppendVector { 322 explicit AppendVector( 323 const std::vector<autofill::PasswordForm*>& append_forms) 324 : append_forms_(append_forms) { 325 } 326 327 ~AppendVector() {} 328 329 bool operator()(std::vector<autofill::PasswordForm*>* forms) const { 330 forms->insert(forms->end(), append_forms_.begin(), append_forms_.end()); 331 return true; 332 } 333 334 std::vector<autofill::PasswordForm*> append_forms_; 335 }; 336 337 DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper); 338}; 339 340class PasswordSyncableServiceTest : public testing::Test, 341 public PasswordSyncableServiceWrapper { 342 public: 343 PasswordSyncableServiceTest() {} 344 virtual ~PasswordSyncableServiceTest() {} 345}; 346 347 348// Both sync and password db have data that are not present in the other. 349TEST_F(PasswordSyncableServiceTest, AdditionsInBoth) { 350 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 351 form1->signon_realm = "abc"; 352 std::vector<autofill::PasswordForm*> forms; 353 forms.push_back(form1.release()); 354 SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>()); 355 356 SyncData sync_data = CreateSyncData("def"); 357 SyncDataList list; 358 list.push_back(sync_data); 359 360 verifier()->SetExpectedDBChanges(list, 361 std::vector<autofill::PasswordForm*>(), 362 std::vector<autofill::PasswordForm*>(), 363 password_store()); 364 verifier()->SetExpectedSyncChanges( 365 SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD))); 366 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_)); 367 368 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, 369 list, 370 CreateSyncChangeProcessor(), 371 scoped_ptr<syncer::SyncErrorFactory>()); 372} 373 374// Sync has data that is not present in the password db. 375TEST_F(PasswordSyncableServiceTest, AdditionOnlyInSync) { 376 SetPasswordStoreData(std::vector<autofill::PasswordForm*>(), 377 std::vector<autofill::PasswordForm*>()); 378 379 SyncData sync_data = CreateSyncData("def"); 380 SyncDataList list; 381 list.push_back(sync_data); 382 383 verifier()->SetExpectedDBChanges(list, 384 std::vector<autofill::PasswordForm*>(), 385 std::vector<autofill::PasswordForm*>(), 386 password_store()); 387 verifier()->SetExpectedSyncChanges(SyncChangeList()); 388 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_)); 389 390 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, 391 list, 392 CreateSyncChangeProcessor(), 393 scoped_ptr<syncer::SyncErrorFactory>()); 394} 395 396// Passwords db has data that is not present in sync. 397TEST_F(PasswordSyncableServiceTest, AdditionOnlyInPasswordStore) { 398 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 399 form1->signon_realm = "abc"; 400 std::vector<autofill::PasswordForm*> forms; 401 forms.push_back(form1.release()); 402 SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>()); 403 404 verifier()->SetExpectedDBChanges(SyncDataList(), 405 std::vector<autofill::PasswordForm*>(), 406 std::vector<autofill::PasswordForm*>(), 407 password_store()); 408 verifier()->SetExpectedSyncChanges( 409 SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD))); 410 EXPECT_CALL(*service_, 411 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList())); 412 413 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, 414 SyncDataList(), 415 CreateSyncChangeProcessor(), 416 scoped_ptr<syncer::SyncErrorFactory>()); 417} 418 419// Both passwords db and sync contain the same data. 420TEST_F(PasswordSyncableServiceTest, BothInSync) { 421 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 422 form1->signon_realm = "abc"; 423 std::vector<autofill::PasswordForm*> forms; 424 forms.push_back(form1.release()); 425 SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>()); 426 427 verifier()->SetExpectedDBChanges(SyncDataList(), 428 std::vector<autofill::PasswordForm*>(), 429 std::vector<autofill::PasswordForm*>(), 430 password_store()); 431 verifier()->SetExpectedSyncChanges(SyncChangeList()); 432 EXPECT_CALL(*service_, 433 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList())); 434 435 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, 436 SyncDataList(1, CreateSyncData("abc")), 437 CreateSyncChangeProcessor(), 438 scoped_ptr<syncer::SyncErrorFactory>()); 439} 440 441// Both passwords db and sync have the same data but they need to be merged 442// as some fields of the data differ. 443TEST_F(PasswordSyncableServiceTest, Merge) { 444 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 445 form1->signon_realm = "abc"; 446 form1->action = GURL("http://pie.com"); 447 form1->date_created = base::Time::Now(); 448 std::vector<autofill::PasswordForm*> forms; 449 forms.push_back(form1.release()); 450 SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>()); 451 452 verifier()->SetExpectedDBChanges(SyncDataList(), 453 std::vector<autofill::PasswordForm*>(), 454 std::vector<autofill::PasswordForm*>(), 455 password_store()); 456 verifier()->SetExpectedSyncChanges( 457 SyncChangeList(1, CreateSyncChange(*forms[0], 458 SyncChange::ACTION_UPDATE))); 459 460 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_)); 461 462 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, 463 SyncDataList(1, CreateSyncData("abc")), 464 CreateSyncChangeProcessor(), 465 scoped_ptr<syncer::SyncErrorFactory>()); 466} 467 468// Initiate sync due to local DB changes. 469TEST_F(PasswordSyncableServiceTest, PasswordStoreChanges) { 470 // Set the sync change processor first. 471 SetPasswordStoreData(std::vector<autofill::PasswordForm*>(), 472 std::vector<autofill::PasswordForm*>()); 473 verifier()->SetExpectedSyncChanges(SyncChangeList()); 474 EXPECT_CALL(*service_, 475 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList())); 476 service_->MergeDataAndStartSyncing(syncer::PASSWORDS, 477 SyncDataList(), 478 CreateSyncChangeProcessor(), 479 scoped_ptr<syncer::SyncErrorFactory>()); 480 481 autofill::PasswordForm form1; 482 form1.signon_realm = "abc"; 483 autofill::PasswordForm form2; 484 form2.signon_realm = "def"; 485 autofill::PasswordForm form3; 486 form3.signon_realm = "xyz"; 487 488 SyncChangeList sync_list; 489 sync_list.push_back(CreateSyncChange(form1, SyncChange::ACTION_ADD)); 490 sync_list.push_back(CreateSyncChange(form2, SyncChange::ACTION_UPDATE)); 491 sync_list.push_back(CreateSyncChange(form3, SyncChange::ACTION_DELETE)); 492 493 verifier()->SetExpectedDBChanges(SyncDataList(), 494 std::vector<autofill::PasswordForm*>(), 495 std::vector<autofill::PasswordForm*>(), 496 password_store()); 497 verifier()->SetExpectedSyncChanges(sync_list); 498 499 PasswordStoreChangeList list; 500 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form1)); 501 list.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form2)); 502 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form3)); 503 service()->ActOnPasswordStoreChanges(list); 504} 505 506// Process all types of changes from sync. 507TEST_F(PasswordSyncableServiceTest, ProcessSyncChanges) { 508 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 509 form1->signon_realm = "abc"; 510 form1->action = GURL("http://foo.com"); 511 scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm); 512 form2->signon_realm = "xyz"; 513 form2->action = GURL("http://bar.com"); 514 form2->date_created = base::Time::Now(); 515 form2->blacklisted_by_user = true; 516 std::vector<autofill::PasswordForm*> forms(1, form1.release()); 517 std::vector<autofill::PasswordForm*> blacklist_forms(1, form2.release()); 518 SetPasswordStoreData(forms, blacklist_forms); 519 520 SyncData add_data = CreateSyncData("def"); 521 autofill::PasswordForm updated_form = *forms[0]; 522 updated_form.date_created = base::Time::Now(); 523 std::vector<autofill::PasswordForm*> updated_passwords(1, &updated_form); 524 std::vector<autofill::PasswordForm*> deleted_passwords(1, blacklist_forms[0]); 525 verifier()->SetExpectedDBChanges(SyncDataList(1, add_data), 526 updated_passwords, 527 deleted_passwords, 528 password_store()); 529 530 SyncChangeList list; 531 list.push_back(SyncChange(FROM_HERE, 532 syncer::SyncChange::ACTION_ADD, 533 add_data)); 534 list.push_back(SyncChange(FROM_HERE, 535 syncer::SyncChange::ACTION_UPDATE, 536 SyncDataFromPassword(updated_form))); 537 list.push_back(CreateSyncChange(*blacklist_forms[0], 538 syncer::SyncChange::ACTION_DELETE)); 539 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_)); 540 service()->ProcessSyncChanges(FROM_HERE, list); 541} 542 543// Retrives sync data from the model. 544TEST_F(PasswordSyncableServiceTest, GetAllSyncData) { 545 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 546 form1->signon_realm = "abc"; 547 form1->action = GURL("http://foo.com"); 548 scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm); 549 form2->signon_realm = "xyz"; 550 form2->action = GURL("http://bar.com"); 551 form2->blacklisted_by_user = true; 552 std::vector<autofill::PasswordForm*> forms(1, form1.release()); 553 std::vector<autofill::PasswordForm*> blacklist_forms(1, form2.release()); 554 SetPasswordStoreData(forms, blacklist_forms); 555 556 SyncDataList expected_list; 557 expected_list.push_back(SyncDataFromPassword(*forms[0])); 558 expected_list.push_back(SyncDataFromPassword(*blacklist_forms[0])); 559 560 verifier()->SetExpectedDBChanges(SyncDataList(), 561 std::vector<autofill::PasswordForm*>(), 562 std::vector<autofill::PasswordForm*>(), 563 password_store()); 564 565 SyncDataList actual_list = service()->GetAllSyncData(syncer::PASSWORDS); 566 EXPECT_EQ(expected_list.size(), actual_list.size()); 567 for (SyncDataList::iterator i(actual_list.begin()), j(expected_list.begin()); 568 i != actual_list.end() && j != expected_list.end(); ++i, ++j) { 569 PasswordsEqual(GetPasswordSpecifics(*j), GetPasswordSpecifics(*i)); 570 } 571} 572 573// Creates 2 PasswordSyncableService instances, merges the content of the first 574// one to the second one and back. 575TEST_F(PasswordSyncableServiceTest, MergeDataAndPushBack) { 576 scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm); 577 form1->signon_realm = "abc"; 578 form1->action = GURL("http://foo.com"); 579 std::vector<autofill::PasswordForm*> forms(1, form1.release()); 580 SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>()); 581 582 PasswordSyncableServiceWrapper other_service_wrapper; 583 scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm); 584 form2->signon_realm = "xyz"; 585 form2->action = GURL("http://bar.com"); 586 syncer::SyncData form2_sync_data = SyncDataFromPassword(*form2); 587 other_service_wrapper.SetPasswordStoreData( 588 std::vector<autofill::PasswordForm*>(1, form2.release()), 589 std::vector<autofill::PasswordForm*>()); 590 591 verifier()->SetExpectedDBChanges(SyncDataList(1, form2_sync_data), 592 std::vector<autofill::PasswordForm*>(), 593 std::vector<autofill::PasswordForm*>(), 594 password_store()); 595 other_service_wrapper.verifier()->SetExpectedDBChanges( 596 SyncDataList(1, SyncDataFromPassword(*forms[0])), 597 std::vector<autofill::PasswordForm*>(), 598 std::vector<autofill::PasswordForm*>(), 599 other_service_wrapper.password_store()); 600 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_)); 601 EXPECT_CALL(*other_service_wrapper.service(), 602 NotifyPasswordStoreOfLoginChanges(_)); 603 604 syncer::SyncDataList other_service_data = 605 other_service_wrapper.service()->GetAllSyncData(syncer::PASSWORDS); 606 service()->MergeDataAndStartSyncing( 607 syncer::PASSWORDS, 608 other_service_data, 609 other_service_wrapper.ReleaseSyncableService(), 610 scoped_ptr<syncer::SyncErrorFactory>()); 611} 612 613} // namespace 614