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 "third_party/libaddressinput/chromium/chrome_address_validator.h" | 5 #include "third_party/libaddressinput/chromium/chrome_address_validator.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/macros.h" | 12 #include "base/run_loop.h" |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
15 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da
ta.h" | 14 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da
ta.h" |
16 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fi
eld.h" | |
17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_pr
oblem.h" | 15 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_pr
oblem.h" |
18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui
.h" | 16 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui
.h" |
19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_va
lidator.h" | |
20 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h
" | |
21 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader
.h" | 17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader
.h" |
22 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_stora
ge.h" | 18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_stora
ge.h" |
23 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" | 19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" |
24 #include "third_party/libaddressinput/src/cpp/test/fake_downloader.h" | 20 #include "third_party/libaddressinput/src/cpp/test/fake_downloader.h" |
25 | 21 |
26 namespace { | 22 namespace autofill { |
27 | 23 |
28 using ::autofill::AddressValidator; | |
29 using ::autofill::LoadRulesListener; | |
30 using ::i18n::addressinput::AddressData; | 24 using ::i18n::addressinput::AddressData; |
31 using ::i18n::addressinput::AddressField; | 25 using ::i18n::addressinput::AddressField; |
32 using ::i18n::addressinput::AddressProblem; | 26 using ::i18n::addressinput::AddressProblem; |
33 using ::i18n::addressinput::BuildCallback; | 27 using ::i18n::addressinput::BuildCallback; |
34 using ::i18n::addressinput::Downloader; | 28 using ::i18n::addressinput::Downloader; |
35 using ::i18n::addressinput::FakeDownloader; | 29 using ::i18n::addressinput::FakeDownloader; |
36 using ::i18n::addressinput::FieldProblemMap; | 30 using ::i18n::addressinput::FieldProblemMap; |
37 using ::i18n::addressinput::GetRegionCodes; | 31 using ::i18n::addressinput::GetRegionCodes; |
38 using ::i18n::addressinput::NullStorage; | 32 using ::i18n::addressinput::NullStorage; |
39 using ::i18n::addressinput::Storage; | 33 using ::i18n::addressinput::Storage; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 address_data.region_code = country_code; | 71 address_data.region_code = country_code; |
78 FieldProblemMap dummy; | 72 FieldProblemMap dummy; |
79 AddressValidator::Status status = | 73 AddressValidator::Status status = |
80 validator_->ValidateAddress(address_data, NULL, &dummy); | 74 validator_->ValidateAddress(address_data, NULL, &dummy); |
81 ASSERT_EQ(success, status == AddressValidator::SUCCESS); | 75 ASSERT_EQ(success, status == AddressValidator::SUCCESS); |
82 } | 76 } |
83 | 77 |
84 DISALLOW_COPY_AND_ASSIGN(AddressValidatorTest); | 78 DISALLOW_COPY_AND_ASSIGN(AddressValidatorTest); |
85 }; | 79 }; |
86 | 80 |
87 // Use this text fixture if you're going to use a region with a large set of | 81 // Use this test fixture if you're going to use a region with a large set of |
88 // validation rules. All rules should be loaded in SetUpTestCase(). | 82 // validation rules. All rules should be loaded in SetUpTestCase(). |
89 class LargeAddressValidatorTest : public testing::Test { | 83 class LargeAddressValidatorTest : public testing::Test { |
90 protected: | 84 protected: |
91 LargeAddressValidatorTest() {} | 85 LargeAddressValidatorTest() {} |
92 virtual ~LargeAddressValidatorTest() {} | 86 virtual ~LargeAddressValidatorTest() {} |
93 | 87 |
94 static void SetUpTestCase() { | 88 static void SetUpTestCase() { |
95 validator_ = | 89 validator_ = |
96 new AddressValidator(FakeDownloader::kFakeAggregateDataUrl, | 90 new AddressValidator(FakeDownloader::kFakeAggregateDataUrl, |
97 scoped_ptr<Downloader>(new FakeDownloader), | 91 scoped_ptr<Downloader>(new FakeDownloader), |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 | 724 |
731 FieldProblemMap filter; | 725 FieldProblemMap filter; |
732 filter.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE)); | 726 filter.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE)); |
733 | 727 |
734 FieldProblemMap problems; | 728 FieldProblemMap problems; |
735 EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE, | 729 EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE, |
736 validator_->ValidateAddress(address, &filter, &problems)); | 730 validator_->ValidateAddress(address, &filter, &problems)); |
737 EXPECT_TRUE(problems.empty()); | 731 EXPECT_TRUE(problems.empty()); |
738 } | 732 } |
739 | 733 |
740 } // namespace | 734 // Use this test fixture for configuring the number of failed attempts to load |
| 735 // rules. |
| 736 class FailingAddressValidatorTest : public testing::Test, LoadRulesListener { |
| 737 protected: |
| 738 // A validator that retries loading rules without delay. |
| 739 class TestAddressValidator : public AddressValidator { |
| 740 public: |
| 741 // Takes ownership of |downloader| and |storage|. |
| 742 TestAddressValidator( |
| 743 const std::string& validation_data_url, |
| 744 scoped_ptr< ::i18n::addressinput::Downloader> downloader, |
| 745 scoped_ptr< ::i18n::addressinput::Storage> storage, |
| 746 LoadRulesListener* load_rules_listener) |
| 747 : AddressValidator(validation_data_url, |
| 748 downloader.Pass(), |
| 749 storage.Pass(), |
| 750 load_rules_listener) {} |
| 751 |
| 752 virtual ~TestAddressValidator() {} |
| 753 |
| 754 protected: |
| 755 virtual base::TimeDelta GetBaseRetryPeriod() const OVERRIDE { |
| 756 return base::TimeDelta::FromSeconds(0); |
| 757 } |
| 758 |
| 759 private: |
| 760 DISALLOW_COPY_AND_ASSIGN(TestAddressValidator); |
| 761 }; |
| 762 |
| 763 // A downloader that always fails |failures_number| times before downloading |
| 764 // data. |
| 765 class FailingDownloader : public Downloader { |
| 766 public: |
| 767 explicit FailingDownloader() : failures_number_(0), attempts_number_(0) {} |
| 768 virtual ~FailingDownloader() {} |
| 769 |
| 770 // Sets the number of times to fail before downloading data. |
| 771 void set_failures_number(int failures_number) { |
| 772 failures_number_ = failures_number; |
| 773 } |
| 774 |
| 775 // Downloader implementation. |
| 776 // Always fails for the first |failures_number| times. |
| 777 virtual void Download(const std::string& url, |
| 778 const Callback& callback) const OVERRIDE { |
| 779 ++attempts_number_; |
| 780 // |callback| takes ownership of the |new std::string|. |
| 781 if (failures_number_-- > 0) |
| 782 callback(false, url, new std::string); |
| 783 else |
| 784 actual_downloader_.Download(url, callback); |
| 785 } |
| 786 |
| 787 // Returns the number of download attempts. |
| 788 int attempts_number() const { return attempts_number_; } |
| 789 |
| 790 private: |
| 791 // The number of times to fail before downloading data. |
| 792 mutable int failures_number_; |
| 793 |
| 794 // The number of times Download was called. |
| 795 mutable int attempts_number_; |
| 796 |
| 797 // The downloader to use for successful downloads. |
| 798 FakeDownloader actual_downloader_; |
| 799 |
| 800 DISALLOW_COPY_AND_ASSIGN(FailingDownloader); |
| 801 }; |
| 802 |
| 803 FailingAddressValidatorTest() |
| 804 : downloader_(new FailingDownloader), |
| 805 validator_( |
| 806 new TestAddressValidator(FakeDownloader::kFakeAggregateDataUrl, |
| 807 scoped_ptr<Downloader>(downloader_), |
| 808 scoped_ptr<Storage>(new NullStorage), |
| 809 this)), |
| 810 load_rules_success_(false) {} |
| 811 |
| 812 virtual ~FailingAddressValidatorTest() {} |
| 813 |
| 814 FailingDownloader* downloader_; // Owned by |validator_|. |
| 815 scoped_ptr<AddressValidator> validator_; |
| 816 bool load_rules_success_; |
| 817 |
| 818 private: |
| 819 // LoadRulesListener implementation. |
| 820 virtual void OnAddressValidationRulesLoaded(const std::string&, |
| 821 bool success) OVERRIDE { |
| 822 load_rules_success_ = success; |
| 823 } |
| 824 |
| 825 base::MessageLoop ui_; |
| 826 |
| 827 DISALLOW_COPY_AND_ASSIGN(FailingAddressValidatorTest); |
| 828 }; |
| 829 |
| 830 // The validator will attempt to load rules at most 8 times. |
| 831 TEST_F(FailingAddressValidatorTest, RetryLoadingRulesHasLimit) { |
| 832 downloader_->set_failures_number(99); |
| 833 validator_->LoadRules("CH"); |
| 834 base::RunLoop().RunUntilIdle(); |
| 835 |
| 836 EXPECT_FALSE(load_rules_success_); |
| 837 EXPECT_EQ(8, downloader_->attempts_number()); |
| 838 } |
| 839 |
| 840 // The validator will load rules successfully if the downloader returns data |
| 841 // before the maximum number of retries. |
| 842 TEST_F(FailingAddressValidatorTest, RuleRetryingWillSucceed) { |
| 843 downloader_->set_failures_number(4); |
| 844 validator_->LoadRules("CH"); |
| 845 base::RunLoop().RunUntilIdle(); |
| 846 |
| 847 EXPECT_TRUE(load_rules_success_); |
| 848 EXPECT_EQ(5, downloader_->attempts_number()); |
| 849 } |
| 850 |
| 851 // The delayed task to retry loading rules should stop (instead of crashing) if |
| 852 // the validator is destroyed before it fires. |
| 853 TEST_F(FailingAddressValidatorTest, DestroyedValidatorStopsRetries) { |
| 854 downloader_->set_failures_number(4); |
| 855 validator_->LoadRules("CH"); |
| 856 |
| 857 // Destroy the validator. |
| 858 validator_.reset(); |
| 859 |
| 860 // Fire the delayed task to retry loading rules. |
| 861 EXPECT_NO_FATAL_FAILURE(base::RunLoop().RunUntilIdle()); |
| 862 } |
| 863 |
| 864 // Each call to LoadRules should reset the number of retry attempts. If the |
| 865 // first call to LoadRules exceeded the maximum number of retries, the second |
| 866 // call to LoadRules should start counting the retries from zero. |
| 867 TEST_F(FailingAddressValidatorTest, LoadingRulesSecondTimeSucceeds) { |
| 868 downloader_->set_failures_number(11); |
| 869 validator_->LoadRules("CH"); |
| 870 base::RunLoop().RunUntilIdle(); |
| 871 |
| 872 EXPECT_FALSE(load_rules_success_); |
| 873 EXPECT_EQ(8, downloader_->attempts_number()); |
| 874 |
| 875 validator_->LoadRules("CH"); |
| 876 base::RunLoop().RunUntilIdle(); |
| 877 |
| 878 EXPECT_TRUE(load_rules_success_); |
| 879 EXPECT_EQ(12, downloader_->attempts_number()); |
| 880 } |
| 881 |
| 882 // Calling LoadRules("CH") and LoadRules("GB") simultaneously should attempt to |
| 883 // load both rules up to the maximum number of attempts for each region. |
| 884 TEST_F(FailingAddressValidatorTest, RegionsShouldRetryIndividually) { |
| 885 downloader_->set_failures_number(99); |
| 886 validator_->LoadRules("CH"); |
| 887 validator_->LoadRules("GB"); |
| 888 base::RunLoop().RunUntilIdle(); |
| 889 |
| 890 EXPECT_FALSE(load_rules_success_); |
| 891 EXPECT_EQ(16, downloader_->attempts_number()); |
| 892 } |
| 893 |
| 894 } // namespace autofill |
OLD | NEW |