| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Unit tests for the SyncApi. Note that a lot of the underlying | 5 // Unit tests for the SyncApi. Note that a lot of the underlying |
| 6 // functionality is provided by the Syncable layer, which has its own | 6 // functionality is provided by the Syncable layer, which has its own |
| 7 // unit tests. We'll test SyncApi specific things in this harness. | 7 // unit tests. We'll test SyncApi specific things in this harness. |
| 8 | 8 |
| 9 #include <cstddef> | 9 #include <cstddef> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 using browser_sync::MockJsReplyHandler; | 65 using browser_sync::MockJsReplyHandler; |
| 66 using browser_sync::ModelSafeRoutingInfo; | 66 using browser_sync::ModelSafeRoutingInfo; |
| 67 using browser_sync::ModelSafeWorker; | 67 using browser_sync::ModelSafeWorker; |
| 68 using browser_sync::ModelSafeWorkerRegistrar; | 68 using browser_sync::ModelSafeWorkerRegistrar; |
| 69 using browser_sync::sessions::SyncSessionSnapshot; | 69 using browser_sync::sessions::SyncSessionSnapshot; |
| 70 using browser_sync::WeakHandle; | 70 using browser_sync::WeakHandle; |
| 71 using syncable::GetAllRealModelTypes; | 71 using syncable::GetAllRealModelTypes; |
| 72 using syncable::kEncryptedString; | 72 using syncable::kEncryptedString; |
| 73 using syncable::ModelType; | 73 using syncable::ModelType; |
| 74 using syncable::ModelTypeSet; | 74 using syncable::ModelTypeSet; |
| 75 using test::ExpectDictDictionaryValue; | |
| 76 using test::ExpectDictStringValue; | 75 using test::ExpectDictStringValue; |
| 77 using testing::_; | 76 using testing::_; |
| 78 using testing::AnyNumber; | 77 using testing::AnyNumber; |
| 79 using testing::AtLeast; | 78 using testing::AtLeast; |
| 80 using testing::InSequence; | 79 using testing::InSequence; |
| 81 using testing::Invoke; | 80 using testing::Invoke; |
| 82 using testing::SaveArg; | 81 using testing::SaveArg; |
| 83 using testing::StrictMock; | 82 using testing::StrictMock; |
| 84 | 83 |
| 85 namespace sync_api { | 84 namespace sync_api { |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 scoped_ptr<DictionaryValue> details(node.GetDetailsAsValue()); | 549 scoped_ptr<DictionaryValue> details(node.GetDetailsAsValue()); |
| 551 if (details.get()) { | 550 if (details.get()) { |
| 552 CheckNodeValue(node, *details, true); | 551 CheckNodeValue(node, *details, true); |
| 553 } else { | 552 } else { |
| 554 ADD_FAILURE(); | 553 ADD_FAILURE(); |
| 555 } | 554 } |
| 556 } | 555 } |
| 557 | 556 |
| 558 namespace { | 557 namespace { |
| 559 | 558 |
| 560 void ExpectChangeRecordActionValue(ChangeRecord::Action expected_value, | |
| 561 const DictionaryValue& value, | |
| 562 const std::string& key) { | |
| 563 std::string str_value; | |
| 564 EXPECT_TRUE(value.GetString(key, &str_value)); | |
| 565 switch (expected_value) { | |
| 566 case ChangeRecord::ACTION_ADD: | |
| 567 EXPECT_EQ("Add", str_value); | |
| 568 break; | |
| 569 case ChangeRecord::ACTION_UPDATE: | |
| 570 EXPECT_EQ("Update", str_value); | |
| 571 break; | |
| 572 case ChangeRecord::ACTION_DELETE: | |
| 573 EXPECT_EQ("Delete", str_value); | |
| 574 break; | |
| 575 default: | |
| 576 NOTREACHED(); | |
| 577 break; | |
| 578 } | |
| 579 } | |
| 580 | |
| 581 void CheckNonDeleteChangeRecordValue(const ChangeRecord& record, | |
| 582 const DictionaryValue& value, | |
| 583 BaseTransaction* trans) { | |
| 584 EXPECT_NE(ChangeRecord::ACTION_DELETE, record.action); | |
| 585 ExpectChangeRecordActionValue(record.action, value, "action"); | |
| 586 { | |
| 587 ReadNode node(trans); | |
| 588 EXPECT_TRUE(node.InitByIdLookup(record.id)); | |
| 589 scoped_ptr<DictionaryValue> expected_details(node.GetDetailsAsValue()); | |
| 590 ExpectDictDictionaryValue(*expected_details, value, "node"); | |
| 591 } | |
| 592 } | |
| 593 | |
| 594 void CheckDeleteChangeRecordValue(const ChangeRecord& record, | |
| 595 const DictionaryValue& value) { | |
| 596 EXPECT_EQ(ChangeRecord::ACTION_DELETE, record.action); | |
| 597 ExpectChangeRecordActionValue(record.action, value, "action"); | |
| 598 DictionaryValue* node_value = NULL; | |
| 599 EXPECT_TRUE(value.GetDictionary("node", &node_value)); | |
| 600 if (node_value) { | |
| 601 ExpectInt64Value(record.id, *node_value, "id"); | |
| 602 scoped_ptr<DictionaryValue> expected_specifics_value( | |
| 603 browser_sync::EntitySpecificsToValue(record.specifics)); | |
| 604 ExpectDictDictionaryValue(*expected_specifics_value, | |
| 605 *node_value, "specifics"); | |
| 606 scoped_ptr<DictionaryValue> expected_extra_value; | |
| 607 if (record.extra.get()) { | |
| 608 expected_extra_value.reset(record.extra->ToValue()); | |
| 609 } | |
| 610 Value* extra_value = NULL; | |
| 611 EXPECT_EQ(record.extra.get() != NULL, | |
| 612 node_value->Get("extra", &extra_value)); | |
| 613 EXPECT_TRUE(Value::Equals(extra_value, expected_extra_value.get())); | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 class MockExtraChangeRecordData | |
| 618 : public ExtraPasswordChangeRecordData { | |
| 619 public: | |
| 620 MOCK_CONST_METHOD0(ToValue, DictionaryValue*()); | |
| 621 }; | |
| 622 | |
| 623 } // namespace | |
| 624 | |
| 625 TEST_F(SyncApiTest, ChangeRecordToValue) { | |
| 626 int64 child_id = MakeNode(test_user_share_.user_share(), | |
| 627 syncable::BOOKMARKS, "testtag"); | |
| 628 sync_pb::EntitySpecifics child_specifics; | |
| 629 { | |
| 630 ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
| 631 ReadNode node(&trans); | |
| 632 EXPECT_TRUE(node.InitByIdLookup(child_id)); | |
| 633 child_specifics = node.GetEntry()->Get(syncable::SPECIFICS); | |
| 634 } | |
| 635 | |
| 636 // Add | |
| 637 { | |
| 638 ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
| 639 ChangeRecord record; | |
| 640 record.action = ChangeRecord::ACTION_ADD; | |
| 641 record.id = 1; | |
| 642 record.specifics = child_specifics; | |
| 643 record.extra.reset(new StrictMock<MockExtraChangeRecordData>()); | |
| 644 scoped_ptr<DictionaryValue> value(record.ToValue(&trans)); | |
| 645 CheckNonDeleteChangeRecordValue(record, *value, &trans); | |
| 646 } | |
| 647 | |
| 648 // Update | |
| 649 { | |
| 650 ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
| 651 ChangeRecord record; | |
| 652 record.action = ChangeRecord::ACTION_UPDATE; | |
| 653 record.id = child_id; | |
| 654 record.specifics = child_specifics; | |
| 655 record.extra.reset(new StrictMock<MockExtraChangeRecordData>()); | |
| 656 scoped_ptr<DictionaryValue> value(record.ToValue(&trans)); | |
| 657 CheckNonDeleteChangeRecordValue(record, *value, &trans); | |
| 658 } | |
| 659 | |
| 660 // Delete (no extra) | |
| 661 { | |
| 662 ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
| 663 ChangeRecord record; | |
| 664 record.action = ChangeRecord::ACTION_DELETE; | |
| 665 record.id = child_id + 1; | |
| 666 record.specifics = child_specifics; | |
| 667 scoped_ptr<DictionaryValue> value(record.ToValue(&trans)); | |
| 668 CheckDeleteChangeRecordValue(record, *value); | |
| 669 } | |
| 670 | |
| 671 // Delete (with extra) | |
| 672 { | |
| 673 ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
| 674 ChangeRecord record; | |
| 675 record.action = ChangeRecord::ACTION_DELETE; | |
| 676 record.id = child_id + 1; | |
| 677 record.specifics = child_specifics; | |
| 678 | |
| 679 DictionaryValue extra_value; | |
| 680 extra_value.SetString("foo", "bar"); | |
| 681 scoped_ptr<StrictMock<MockExtraChangeRecordData> > extra( | |
| 682 new StrictMock<MockExtraChangeRecordData>()); | |
| 683 EXPECT_CALL(*extra, ToValue()).Times(2).WillRepeatedly( | |
| 684 Invoke(&extra_value, &DictionaryValue::DeepCopy)); | |
| 685 | |
| 686 record.extra.reset(extra.release()); | |
| 687 scoped_ptr<DictionaryValue> value(record.ToValue(&trans)); | |
| 688 CheckDeleteChangeRecordValue(record, *value); | |
| 689 } | |
| 690 } | |
| 691 | |
| 692 namespace { | |
| 693 | |
| 694 class TestHttpPostProviderInterface : public HttpPostProviderInterface { | 559 class TestHttpPostProviderInterface : public HttpPostProviderInterface { |
| 695 public: | 560 public: |
| 696 virtual ~TestHttpPostProviderInterface() {} | 561 virtual ~TestHttpPostProviderInterface() {} |
| 697 | 562 |
| 698 virtual void SetUserAgent(const char* user_agent) OVERRIDE {} | 563 virtual void SetUserAgent(const char* user_agent) OVERRIDE {} |
| 699 virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE {} | 564 virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE {} |
| 700 virtual void SetURL(const char* url, int port) OVERRIDE {} | 565 virtual void SetURL(const char* url, int port) OVERRIDE {} |
| 701 virtual void SetPostPayload(const char* content_type, | 566 virtual void SetPostPayload(const char* content_type, |
| 702 int content_length, | 567 int content_length, |
| 703 const char* content) OVERRIDE {} | 568 const char* content) OVERRIDE {} |
| (...skipping 20 matching lines...) Expand all Loading... |
| 724 virtual HttpPostProviderInterface* Create() OVERRIDE { | 589 virtual HttpPostProviderInterface* Create() OVERRIDE { |
| 725 return new TestHttpPostProviderInterface(); | 590 return new TestHttpPostProviderInterface(); |
| 726 } | 591 } |
| 727 virtual void Destroy(HttpPostProviderInterface* http) OVERRIDE { | 592 virtual void Destroy(HttpPostProviderInterface* http) OVERRIDE { |
| 728 delete http; | 593 delete http; |
| 729 } | 594 } |
| 730 }; | 595 }; |
| 731 | 596 |
| 732 class SyncManagerObserverMock : public SyncManager::Observer { | 597 class SyncManagerObserverMock : public SyncManager::Observer { |
| 733 public: | 598 public: |
| 734 MOCK_METHOD3(OnChangesApplied, | |
| 735 void(ModelType, | |
| 736 const BaseTransaction*, | |
| 737 const ImmutableChangeRecordList&)); // NOLINT | |
| 738 MOCK_METHOD1(OnChangesComplete, void(ModelType)); // NOLINT | |
| 739 MOCK_METHOD1(OnSyncCycleCompleted, | 599 MOCK_METHOD1(OnSyncCycleCompleted, |
| 740 void(const SyncSessionSnapshot*)); // NOLINT | 600 void(const SyncSessionSnapshot*)); // NOLINT |
| 741 MOCK_METHOD2(OnInitializationComplete, | 601 MOCK_METHOD2(OnInitializationComplete, |
| 742 void(const WeakHandle<JsBackend>&, bool)); // NOLINT | 602 void(const WeakHandle<JsBackend>&, bool)); // NOLINT |
| 743 MOCK_METHOD1(OnAuthError, void(const GoogleServiceAuthError&)); // NOLINT | 603 MOCK_METHOD1(OnAuthError, void(const GoogleServiceAuthError&)); // NOLINT |
| 744 MOCK_METHOD1(OnPassphraseRequired, | 604 MOCK_METHOD1(OnPassphraseRequired, |
| 745 void(sync_api::PassphraseRequiredReason)); // NOLINT | 605 void(sync_api::PassphraseRequiredReason)); // NOLINT |
| 746 MOCK_METHOD1(OnPassphraseAccepted, void(const std::string&)); // NOLINT | 606 MOCK_METHOD1(OnPassphraseAccepted, void(const std::string&)); // NOLINT |
| 747 MOCK_METHOD0(OnStopSyncingPermanently, void()); // NOLINT | 607 MOCK_METHOD0(OnStopSyncingPermanently, void()); // NOLINT |
| 748 MOCK_METHOD1(OnUpdatedToken, void(const std::string&)); // NOLINT | 608 MOCK_METHOD1(OnUpdatedToken, void(const std::string&)); // NOLINT |
| (...skipping 11 matching lines...) Expand all Loading... |
| 760 MOCK_METHOD1(SetUniqueId, void(const std::string&)); | 620 MOCK_METHOD1(SetUniqueId, void(const std::string&)); |
| 761 MOCK_METHOD1(SetState, void(const std::string&)); | 621 MOCK_METHOD1(SetState, void(const std::string&)); |
| 762 MOCK_METHOD2(UpdateCredentials, | 622 MOCK_METHOD2(UpdateCredentials, |
| 763 void(const std::string&, const std::string&)); | 623 void(const std::string&, const std::string&)); |
| 764 MOCK_METHOD1(UpdateEnabledTypes, | 624 MOCK_METHOD1(UpdateEnabledTypes, |
| 765 void(const syncable::ModelTypeSet&)); | 625 void(const syncable::ModelTypeSet&)); |
| 766 MOCK_METHOD1(SendNotification, void(const syncable::ModelTypeSet&)); | 626 MOCK_METHOD1(SendNotification, void(const syncable::ModelTypeSet&)); |
| 767 }; | 627 }; |
| 768 | 628 |
| 769 class SyncManagerTest : public testing::Test, | 629 class SyncManagerTest : public testing::Test, |
| 770 public ModelSafeWorkerRegistrar { | 630 public ModelSafeWorkerRegistrar, |
| 631 public SyncManager::ChangeDelegate { |
| 771 protected: | 632 protected: |
| 772 SyncManagerTest() | 633 SyncManagerTest() |
| 773 : ui_thread_(BrowserThread::UI, &ui_loop_), | 634 : ui_thread_(BrowserThread::UI, &ui_loop_), |
| 774 sync_notifier_mock_(NULL), | 635 sync_notifier_mock_(NULL), |
| 775 sync_manager_("Test sync manager"), | 636 sync_manager_("Test sync manager"), |
| 776 sync_notifier_observer_(NULL), | 637 sync_notifier_observer_(NULL), |
| 777 update_enabled_types_call_count_(0) {} | 638 update_enabled_types_call_count_(0) {} |
| 778 | 639 |
| 779 virtual ~SyncManagerTest() { | 640 virtual ~SyncManagerTest() { |
| 780 EXPECT_FALSE(sync_notifier_mock_); | 641 EXPECT_FALSE(sync_notifier_mock_); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 806 EXPECT_CALL(observer_, OnInitializationComplete(_, _)). | 667 EXPECT_CALL(observer_, OnInitializationComplete(_, _)). |
| 807 WillOnce(SaveArg<0>(&js_backend_)); | 668 WillOnce(SaveArg<0>(&js_backend_)); |
| 808 | 669 |
| 809 EXPECT_FALSE(sync_notifier_observer_); | 670 EXPECT_FALSE(sync_notifier_observer_); |
| 810 EXPECT_FALSE(js_backend_.IsInitialized()); | 671 EXPECT_FALSE(js_backend_.IsInitialized()); |
| 811 | 672 |
| 812 // Takes ownership of |sync_notifier_mock_|. | 673 // Takes ownership of |sync_notifier_mock_|. |
| 813 sync_manager_.Init(temp_dir_.path(), | 674 sync_manager_.Init(temp_dir_.path(), |
| 814 WeakHandle<JsEventHandler>(), | 675 WeakHandle<JsEventHandler>(), |
| 815 "bogus", 0, false, | 676 "bogus", 0, false, |
| 816 new TestHttpPostProviderFactory(), this, "bogus", | 677 new TestHttpPostProviderFactory(), this, this, "bogus", |
| 817 credentials, sync_notifier_mock_, "", | 678 credentials, sync_notifier_mock_, "", |
| 818 true /* setup_for_test_mode */); | 679 true /* setup_for_test_mode */); |
| 819 | 680 |
| 820 EXPECT_TRUE(sync_notifier_observer_); | 681 EXPECT_TRUE(sync_notifier_observer_); |
| 821 EXPECT_TRUE(js_backend_.IsInitialized()); | 682 EXPECT_TRUE(js_backend_.IsInitialized()); |
| 822 | 683 |
| 823 EXPECT_EQ(1, update_enabled_types_call_count_); | 684 EXPECT_EQ(1, update_enabled_types_call_count_); |
| 824 | 685 |
| 825 ModelSafeRoutingInfo routes; | 686 ModelSafeRoutingInfo routes; |
| 826 GetModelSafeRoutingInfo(&routes); | 687 GetModelSafeRoutingInfo(&routes); |
| 827 for (ModelSafeRoutingInfo::iterator i = routes.begin(); i != routes.end(); | 688 for (ModelSafeRoutingInfo::iterator i = routes.begin(); i != routes.end(); |
| 828 ++i) { | 689 ++i) { |
| 829 EXPECT_CALL(observer_, OnChangesApplied(i->first, _, _)) | |
| 830 .RetiresOnSaturation(); | |
| 831 EXPECT_CALL(observer_, OnChangesComplete(i->first)) | |
| 832 .RetiresOnSaturation(); | |
| 833 type_roots_[i->first] = MakeServerNodeForType( | 690 type_roots_[i->first] = MakeServerNodeForType( |
| 834 sync_manager_.GetUserShare(), i->first); | 691 sync_manager_.GetUserShare(), i->first); |
| 835 } | 692 } |
| 836 PumpLoop(); | 693 PumpLoop(); |
| 837 } | 694 } |
| 838 | 695 |
| 839 void TearDown() { | 696 void TearDown() { |
| 840 sync_manager_.RemoveObserver(&observer_); | 697 sync_manager_.RemoveObserver(&observer_); |
| 841 sync_manager_.Shutdown(); | 698 sync_manager_.Shutdown(); |
| 842 sync_notifier_mock_ = NULL; | 699 sync_notifier_mock_ = NULL; |
| 843 EXPECT_FALSE(sync_notifier_observer_); | 700 EXPECT_FALSE(sync_notifier_observer_); |
| 844 PumpLoop(); | 701 PumpLoop(); |
| 845 } | 702 } |
| 846 | 703 |
| 847 // ModelSafeWorkerRegistrar implementation. | 704 // ModelSafeWorkerRegistrar implementation. |
| 848 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) { | 705 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) OVERRIDE { |
| 849 NOTIMPLEMENTED(); | 706 NOTIMPLEMENTED(); |
| 850 out->clear(); | 707 out->clear(); |
| 851 } | 708 } |
| 852 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { | 709 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) OVERRIDE { |
| 853 (*out)[syncable::NIGORI] = browser_sync::GROUP_PASSIVE; | 710 (*out)[syncable::NIGORI] = browser_sync::GROUP_PASSIVE; |
| 854 (*out)[syncable::BOOKMARKS] = browser_sync::GROUP_PASSIVE; | 711 (*out)[syncable::BOOKMARKS] = browser_sync::GROUP_PASSIVE; |
| 855 (*out)[syncable::THEMES] = browser_sync::GROUP_PASSIVE; | 712 (*out)[syncable::THEMES] = browser_sync::GROUP_PASSIVE; |
| 856 (*out)[syncable::SESSIONS] = browser_sync::GROUP_PASSIVE; | 713 (*out)[syncable::SESSIONS] = browser_sync::GROUP_PASSIVE; |
| 857 (*out)[syncable::PASSWORDS] = browser_sync::GROUP_PASSIVE; | 714 (*out)[syncable::PASSWORDS] = browser_sync::GROUP_PASSIVE; |
| 858 } | 715 } |
| 859 | 716 |
| 717 virtual void OnChangesApplied( |
| 718 syncable::ModelType model_type, |
| 719 const BaseTransaction* trans, |
| 720 const ImmutableChangeRecordList& changes) OVERRIDE {} |
| 721 |
| 722 virtual void OnChangesComplete(syncable::ModelType model_type) OVERRIDE {} |
| 723 |
| 860 // Helper methods. | 724 // Helper methods. |
| 861 bool SetUpEncryption() { | 725 bool SetUpEncryption() { |
| 862 // Mock the Mac Keychain service. The real Keychain can block on user input. | 726 // Mock the Mac Keychain service. The real Keychain can block on user input. |
| 863 #if defined(OS_MACOSX) | 727 #if defined(OS_MACOSX) |
| 864 Encryptor::UseMockKeychain(true); | 728 Encryptor::UseMockKeychain(true); |
| 865 #endif | 729 #endif |
| 866 | 730 |
| 867 // We need to create the nigori node as if it were an applied server update. | 731 // We need to create the nigori node as if it were an applied server update. |
| 868 UserShare* share = sync_manager_.GetUserShare(); | 732 UserShare* share = sync_manager_.GetUserShare(); |
| 869 int64 nigori_id = GetIdForDataType(syncable::NIGORI); | 733 int64 nigori_id = GetIdForDataType(syncable::NIGORI); |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 ReadNode node(&trans); | 1411 ReadNode node(&trans); |
| 1548 EXPECT_TRUE(node.InitByIdLookup(node1)); | 1412 EXPECT_TRUE(node.InitByIdLookup(node1)); |
| 1549 EXPECT_EQ(syncable::BOOKMARKS, node.GetModelType()); | 1413 EXPECT_EQ(syncable::BOOKMARKS, node.GetModelType()); |
| 1550 EXPECT_EQ(title, node.GetTitle()); | 1414 EXPECT_EQ(title, node.GetTitle()); |
| 1551 EXPECT_EQ(title, node.GetBookmarkSpecifics().title()); | 1415 EXPECT_EQ(title, node.GetBookmarkSpecifics().title()); |
| 1552 EXPECT_EQ(url, node.GetBookmarkSpecifics().url()); | 1416 EXPECT_EQ(url, node.GetBookmarkSpecifics().url()); |
| 1553 } | 1417 } |
| 1554 } | 1418 } |
| 1555 | 1419 |
| 1556 } // namespace browser_sync | 1420 } // namespace browser_sync |
| OLD | NEW |