OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/password_manager/core/browser/password_syncable_service.h" | 5 #include "components/password_manager/core/browser/password_syncable_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
| 9 #include <utility> |
9 #include <vector> | 10 #include <vector> |
10 | 11 |
11 #include "base/location.h" | 12 #include "base/location.h" |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
17 #include "components/password_manager/core/browser/mock_password_store.h" | 18 #include "components/password_manager/core/browser/mock_password_store.h" |
18 #include "sync/api/sync_change_processor.h" | 19 #include "sync/api/sync_change_processor.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } | 197 } |
197 | 198 |
198 ~PasswordSyncableServiceWrapper() { password_store_->ShutdownOnUIThread(); } | 199 ~PasswordSyncableServiceWrapper() { password_store_->ShutdownOnUIThread(); } |
199 | 200 |
200 MockPasswordStore* password_store() { return password_store_.get(); } | 201 MockPasswordStore* password_store() { return password_store_.get(); } |
201 | 202 |
202 MockPasswordSyncableService* service() { return service_.get(); } | 203 MockPasswordSyncableService* service() { return service_.get(); } |
203 | 204 |
204 // Returnes the scoped_ptr to |service_| thus NULLing out it. | 205 // Returnes the scoped_ptr to |service_| thus NULLing out it. |
205 scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() { | 206 scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() { |
206 return service_.Pass(); | 207 return std::move(service_); |
207 } | 208 } |
208 | 209 |
209 private: | 210 private: |
210 scoped_refptr<MockPasswordStore> password_store_; | 211 scoped_refptr<MockPasswordStore> password_store_; |
211 scoped_ptr<MockPasswordSyncableService> service_; | 212 scoped_ptr<MockPasswordSyncableService> service_; |
212 | 213 |
213 DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper); | 214 DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper); |
214 }; | 215 }; |
215 | 216 |
216 class PasswordSyncableServiceTest : public testing::Test { | 217 class PasswordSyncableServiceTest : public testing::Test { |
(...skipping 26 matching lines...) Expand all Loading... |
243 autofill::PasswordForm new_from_sync = | 244 autofill::PasswordForm new_from_sync = |
244 PasswordFromSpecifics(GetPasswordSpecifics(list.back())); | 245 PasswordFromSpecifics(GetPasswordSpecifics(list.back())); |
245 | 246 |
246 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 247 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
247 .WillOnce(AppendForm(form)); | 248 .WillOnce(AppendForm(form)); |
248 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 249 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
249 EXPECT_CALL(*password_store(), AddLoginImpl(PasswordIs(new_from_sync))); | 250 EXPECT_CALL(*password_store(), AddLoginImpl(PasswordIs(new_from_sync))); |
250 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( | 251 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( |
251 SyncChangeIs(SyncChange::ACTION_ADD, form)))); | 252 SyncChangeIs(SyncChange::ACTION_ADD, form)))); |
252 | 253 |
253 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 254 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, list, |
254 list, | 255 std::move(processor_), |
255 processor_.Pass(), | |
256 scoped_ptr<syncer::SyncErrorFactory>()); | 256 scoped_ptr<syncer::SyncErrorFactory>()); |
257 } | 257 } |
258 | 258 |
259 // Sync has data that is not present in the password db. | 259 // Sync has data that is not present in the password db. |
260 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInSync) { | 260 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInSync) { |
261 SyncDataList list; | 261 SyncDataList list; |
262 list.push_back(CreateSyncData(kSignonRealm)); | 262 list.push_back(CreateSyncData(kSignonRealm)); |
263 autofill::PasswordForm new_from_sync = | 263 autofill::PasswordForm new_from_sync = |
264 PasswordFromSpecifics(GetPasswordSpecifics(list.back())); | 264 PasswordFromSpecifics(GetPasswordSpecifics(list.back())); |
265 | 265 |
266 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 266 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
267 .WillOnce(Return(true)); | 267 .WillOnce(Return(true)); |
268 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 268 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
269 EXPECT_CALL(*password_store(), AddLoginImpl(PasswordIs(new_from_sync))); | 269 EXPECT_CALL(*password_store(), AddLoginImpl(PasswordIs(new_from_sync))); |
270 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); | 270 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); |
271 | 271 |
272 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 272 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, list, |
273 list, | 273 std::move(processor_), |
274 processor_.Pass(), | |
275 scoped_ptr<syncer::SyncErrorFactory>()); | 274 scoped_ptr<syncer::SyncErrorFactory>()); |
276 } | 275 } |
277 | 276 |
278 // Passwords db has data that is not present in sync. | 277 // Passwords db has data that is not present in sync. |
279 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInPasswordStore) { | 278 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInPasswordStore) { |
280 autofill::PasswordForm form; | 279 autofill::PasswordForm form; |
281 form.signon_realm = kSignonRealm; | 280 form.signon_realm = kSignonRealm; |
282 form.times_used = kTimesUsed; | 281 form.times_used = kTimesUsed; |
283 form.type = kArbitraryType; | 282 form.type = kArbitraryType; |
284 form.display_name = base::ASCIIToUTF16(kDisplayName); | 283 form.display_name = base::ASCIIToUTF16(kDisplayName); |
285 form.icon_url = GURL(kIconUrl); | 284 form.icon_url = GURL(kIconUrl); |
286 form.federation_url = GURL(kFederationUrl); | 285 form.federation_url = GURL(kFederationUrl); |
287 form.username_value = base::ASCIIToUTF16(kUsername); | 286 form.username_value = base::ASCIIToUTF16(kUsername); |
288 form.password_value = base::ASCIIToUTF16(kPassword); | 287 form.password_value = base::ASCIIToUTF16(kPassword); |
289 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 288 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
290 .WillOnce(AppendForm(form)); | 289 .WillOnce(AppendForm(form)); |
291 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 290 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
292 | 291 |
293 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( | 292 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( |
294 SyncChangeIs(SyncChange::ACTION_ADD, form)))); | 293 SyncChangeIs(SyncChange::ACTION_ADD, form)))); |
295 | 294 |
296 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 295 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, SyncDataList(), |
297 SyncDataList(), | 296 std::move(processor_), |
298 processor_.Pass(), | |
299 scoped_ptr<syncer::SyncErrorFactory>()); | 297 scoped_ptr<syncer::SyncErrorFactory>()); |
300 } | 298 } |
301 | 299 |
302 // Both passwords db and sync contain the same data. | 300 // Both passwords db and sync contain the same data. |
303 TEST_F(PasswordSyncableServiceTest, BothInSync) { | 301 TEST_F(PasswordSyncableServiceTest, BothInSync) { |
304 autofill::PasswordForm form; | 302 autofill::PasswordForm form; |
305 form.signon_realm = kSignonRealm; | 303 form.signon_realm = kSignonRealm; |
306 form.times_used = kTimesUsed; | 304 form.times_used = kTimesUsed; |
307 form.type = kArbitraryType; | 305 form.type = kArbitraryType; |
308 form.username_value = base::ASCIIToUTF16(kUsername); | 306 form.username_value = base::ASCIIToUTF16(kUsername); |
309 form.password_value = base::ASCIIToUTF16(kPassword); | 307 form.password_value = base::ASCIIToUTF16(kPassword); |
310 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 308 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
311 .WillOnce(AppendForm(form)); | 309 .WillOnce(AppendForm(form)); |
312 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 310 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
313 | 311 |
314 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); | 312 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); |
315 | 313 |
316 service()->MergeDataAndStartSyncing( | 314 service()->MergeDataAndStartSyncing( |
317 syncer::PASSWORDS, | 315 syncer::PASSWORDS, SyncDataList(1, SyncDataFromPassword(form)), |
318 SyncDataList(1, SyncDataFromPassword(form)), | 316 std::move(processor_), scoped_ptr<syncer::SyncErrorFactory>()); |
319 processor_.Pass(), | |
320 scoped_ptr<syncer::SyncErrorFactory>()); | |
321 } | 317 } |
322 | 318 |
323 // Both passwords db and sync have the same data but they need to be merged | 319 // Both passwords db and sync have the same data but they need to be merged |
324 // as some fields of the data differ. | 320 // as some fields of the data differ. |
325 TEST_F(PasswordSyncableServiceTest, Merge) { | 321 TEST_F(PasswordSyncableServiceTest, Merge) { |
326 autofill::PasswordForm form1; | 322 autofill::PasswordForm form1; |
327 form1.signon_realm = kSignonRealm; | 323 form1.signon_realm = kSignonRealm; |
328 form1.action = GURL("http://pie.com"); | 324 form1.action = GURL("http://pie.com"); |
329 form1.date_created = base::Time::Now(); | 325 form1.date_created = base::Time::Now(); |
330 form1.preferred = true; | 326 form1.preferred = true; |
331 form1.username_value = base::ASCIIToUTF16(kUsername); | 327 form1.username_value = base::ASCIIToUTF16(kUsername); |
332 form1.password_value = base::ASCIIToUTF16(kPassword); | 328 form1.password_value = base::ASCIIToUTF16(kPassword); |
333 | 329 |
334 autofill::PasswordForm form2(form1); | 330 autofill::PasswordForm form2(form1); |
335 form2.preferred = false; | 331 form2.preferred = false; |
336 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 332 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
337 .WillOnce(AppendForm(form1)); | 333 .WillOnce(AppendForm(form1)); |
338 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 334 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
339 EXPECT_CALL(*password_store(), UpdateLoginImpl(PasswordIs(form2))); | 335 EXPECT_CALL(*password_store(), UpdateLoginImpl(PasswordIs(form2))); |
340 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); | 336 EXPECT_CALL(*processor_, ProcessSyncChanges(_, IsEmpty())); |
341 | 337 |
342 service()->MergeDataAndStartSyncing( | 338 service()->MergeDataAndStartSyncing( |
343 syncer::PASSWORDS, | 339 syncer::PASSWORDS, SyncDataList(1, SyncDataFromPassword(form2)), |
344 SyncDataList(1, SyncDataFromPassword(form2)), | 340 std::move(processor_), scoped_ptr<syncer::SyncErrorFactory>()); |
345 processor_.Pass(), | |
346 scoped_ptr<syncer::SyncErrorFactory>()); | |
347 } | 341 } |
348 | 342 |
349 // Initiate sync due to local DB changes. | 343 // Initiate sync due to local DB changes. |
350 TEST_F(PasswordSyncableServiceTest, PasswordStoreChanges) { | 344 TEST_F(PasswordSyncableServiceTest, PasswordStoreChanges) { |
351 // Save the reference to the processor because |processor_| is NULL after | 345 // Save the reference to the processor because |processor_| is NULL after |
352 // MergeDataAndStartSyncing(). | 346 // MergeDataAndStartSyncing(). |
353 MockSyncChangeProcessor& weak_processor = *processor_; | 347 MockSyncChangeProcessor& weak_processor = *processor_; |
354 EXPECT_CALL(weak_processor, ProcessSyncChanges(_, IsEmpty())); | 348 EXPECT_CALL(weak_processor, ProcessSyncChanges(_, IsEmpty())); |
355 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 349 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
356 .WillOnce(Return(true)); | 350 .WillOnce(Return(true)); |
357 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)) | 351 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)) |
358 .WillOnce(Return(true)); | 352 .WillOnce(Return(true)); |
359 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 353 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, SyncDataList(), |
360 SyncDataList(), | 354 std::move(processor_), |
361 processor_.Pass(), | |
362 scoped_ptr<syncer::SyncErrorFactory>()); | 355 scoped_ptr<syncer::SyncErrorFactory>()); |
363 | 356 |
364 autofill::PasswordForm form1; | 357 autofill::PasswordForm form1; |
365 form1.signon_realm = kSignonRealm; | 358 form1.signon_realm = kSignonRealm; |
366 autofill::PasswordForm form2; | 359 autofill::PasswordForm form2; |
367 form2.signon_realm = kSignonRealm2; | 360 form2.signon_realm = kSignonRealm2; |
368 autofill::PasswordForm form3; | 361 autofill::PasswordForm form3; |
369 form3.signon_realm = kSignonRealm3; | 362 form3.signon_realm = kSignonRealm3; |
370 | 363 |
371 SyncChangeList sync_list; | 364 SyncChangeList sync_list; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 504 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
512 "Failed to get passwords from store.", | 505 "Failed to get passwords from store.", |
513 syncer::PASSWORDS); | 506 syncer::PASSWORDS); |
514 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 507 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
515 .WillOnce(Return(false)); | 508 .WillOnce(Return(false)); |
516 EXPECT_CALL(*error_factory, CreateAndUploadError(_, _)) | 509 EXPECT_CALL(*error_factory, CreateAndUploadError(_, _)) |
517 .WillOnce(Return(error)); | 510 .WillOnce(Return(error)); |
518 // ActOnPasswordStoreChanges() below shouldn't generate any changes for Sync. | 511 // ActOnPasswordStoreChanges() below shouldn't generate any changes for Sync. |
519 // |processor_| will be destroyed in MergeDataAndStartSyncing(). | 512 // |processor_| will be destroyed in MergeDataAndStartSyncing(). |
520 EXPECT_CALL(*processor_, ProcessSyncChanges(_, _)).Times(0); | 513 EXPECT_CALL(*processor_, ProcessSyncChanges(_, _)).Times(0); |
521 syncer::SyncMergeResult result = | 514 syncer::SyncMergeResult result = service()->MergeDataAndStartSyncing( |
522 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 515 syncer::PASSWORDS, syncer::SyncDataList(), std::move(processor_), |
523 syncer::SyncDataList(), | 516 std::move(error_factory)); |
524 processor_.Pass(), | |
525 error_factory.Pass()); | |
526 EXPECT_TRUE(result.error().IsSet()); | 517 EXPECT_TRUE(result.error().IsSet()); |
527 | 518 |
528 autofill::PasswordForm form; | 519 autofill::PasswordForm form; |
529 form.signon_realm = kSignonRealm; | 520 form.signon_realm = kSignonRealm; |
530 PasswordStoreChangeList list; | 521 PasswordStoreChangeList list; |
531 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 522 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
532 service()->ActOnPasswordStoreChanges(list); | 523 service()->ActOnPasswordStoreChanges(list); |
533 } | 524 } |
534 | 525 |
535 // Start syncing with an error in ProcessSyncChanges. Subsequent password store | 526 // Start syncing with an error in ProcessSyncChanges. Subsequent password store |
536 // updates shouldn't be propagated to Sync. | 527 // updates shouldn't be propagated to Sync. |
537 TEST_F(PasswordSyncableServiceTest, FailedProcessSyncChanges) { | 528 TEST_F(PasswordSyncableServiceTest, FailedProcessSyncChanges) { |
538 autofill::PasswordForm form; | 529 autofill::PasswordForm form; |
539 form.signon_realm = kSignonRealm; | 530 form.signon_realm = kSignonRealm; |
540 form.username_value = base::ASCIIToUTF16(kUsername); | 531 form.username_value = base::ASCIIToUTF16(kUsername); |
541 form.password_value = base::ASCIIToUTF16(kPassword); | 532 form.password_value = base::ASCIIToUTF16(kPassword); |
542 scoped_ptr<syncer::SyncErrorFactoryMock> error_factory( | 533 scoped_ptr<syncer::SyncErrorFactoryMock> error_factory( |
543 new syncer::SyncErrorFactoryMock); | 534 new syncer::SyncErrorFactoryMock); |
544 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 535 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
545 "There is a problem", syncer::PASSWORDS); | 536 "There is a problem", syncer::PASSWORDS); |
546 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) | 537 EXPECT_CALL(*password_store(), FillAutofillableLogins(_)) |
547 .WillOnce(AppendForm(form)); | 538 .WillOnce(AppendForm(form)); |
548 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 539 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
549 | 540 |
550 // ActOnPasswordStoreChanges() below shouldn't generate any changes for Sync. | 541 // ActOnPasswordStoreChanges() below shouldn't generate any changes for Sync. |
551 // |processor_| will be destroyed in MergeDataAndStartSyncing(). | 542 // |processor_| will be destroyed in MergeDataAndStartSyncing(). |
552 EXPECT_CALL(*processor_, ProcessSyncChanges(_, _)) | 543 EXPECT_CALL(*processor_, ProcessSyncChanges(_, _)) |
553 .Times(1) | 544 .Times(1) |
554 .WillOnce(Return(error)); | 545 .WillOnce(Return(error)); |
555 syncer::SyncMergeResult result = | 546 syncer::SyncMergeResult result = service()->MergeDataAndStartSyncing( |
556 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 547 syncer::PASSWORDS, syncer::SyncDataList(), std::move(processor_), |
557 syncer::SyncDataList(), | 548 std::move(error_factory)); |
558 processor_.Pass(), | |
559 error_factory.Pass()); | |
560 EXPECT_TRUE(result.error().IsSet()); | 549 EXPECT_TRUE(result.error().IsSet()); |
561 | 550 |
562 form.signon_realm = kSignonRealm2; | 551 form.signon_realm = kSignonRealm2; |
563 PasswordStoreChangeList list; | 552 PasswordStoreChangeList list; |
564 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 553 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
565 service()->ActOnPasswordStoreChanges(list); | 554 service()->ActOnPasswordStoreChanges(list); |
566 } | 555 } |
567 | 556 |
568 // Tests that empty forms known to the client and/or the server are deleted. | 557 // Tests that empty forms known to the client and/or the server are deleted. |
569 TEST_F(PasswordSyncableServiceTest, MergeEmptyPasswords) { | 558 TEST_F(PasswordSyncableServiceTest, MergeEmptyPasswords) { |
(...skipping 15 matching lines...) Expand all Loading... |
585 .WillOnce(DoAll(IgnoreResult(AppendForm(old_empty_form)), | 574 .WillOnce(DoAll(IgnoreResult(AppendForm(old_empty_form)), |
586 AppendForm(db_empty_form))); | 575 AppendForm(db_empty_form))); |
587 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); | 576 EXPECT_CALL(*password_store(), FillBlacklistLogins(_)).WillOnce(Return(true)); |
588 | 577 |
589 EXPECT_CALL(*password_store(), RemoveLoginImpl(PasswordIs(old_empty_form))); | 578 EXPECT_CALL(*password_store(), RemoveLoginImpl(PasswordIs(old_empty_form))); |
590 EXPECT_CALL(*password_store(), RemoveLoginImpl(PasswordIs(db_empty_form))); | 579 EXPECT_CALL(*password_store(), RemoveLoginImpl(PasswordIs(db_empty_form))); |
591 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( | 580 EXPECT_CALL(*processor_, ProcessSyncChanges(_, ElementsAre( |
592 SyncChangeIs(SyncChange::ACTION_DELETE, old_empty_form), | 581 SyncChangeIs(SyncChange::ACTION_DELETE, old_empty_form), |
593 SyncChangeIs(SyncChange::ACTION_DELETE, sync_empty_form)))); | 582 SyncChangeIs(SyncChange::ACTION_DELETE, sync_empty_form)))); |
594 | 583 |
595 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, | 584 service()->MergeDataAndStartSyncing(syncer::PASSWORDS, sync_data, |
596 sync_data, | 585 std::move(processor_), |
597 processor_.Pass(), | |
598 scoped_ptr<syncer::SyncErrorFactory>()); | 586 scoped_ptr<syncer::SyncErrorFactory>()); |
599 } | 587 } |
600 | 588 |
601 } // namespace | 589 } // namespace |
602 | 590 |
603 } // namespace password_manager | 591 } // namespace password_manager |
OLD | NEW |