| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 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 <vector> | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/files/file_path.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "components/autofill/browser/autofill_common_test.h" | |
| 12 #include "components/autofill/browser/autofill_type.h" | |
| 13 #include "components/autofill/browser/data_driven_test.h" | |
| 14 #include "components/autofill/browser/form_structure.h" | |
| 15 #include "components/autofill/browser/personal_data_manager.h" | |
| 16 #include "components/autofill/core/common/form_data.h" | |
| 17 #include "googleurl/src/gurl.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" | |
| 20 | |
| 21 namespace autofill { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 const base::FilePath::CharType kTestName[] = FILE_PATH_LITERAL("merge"); | |
| 26 const base::FilePath::CharType kFileNamePattern[] = FILE_PATH_LITERAL("*.in"); | |
| 27 | |
| 28 const char kFieldSeparator[] = ": "; | |
| 29 const char kProfileSeparator[] = "---"; | |
| 30 const size_t kFieldOffset = arraysize(kFieldSeparator) - 1; | |
| 31 | |
| 32 const AutofillFieldType kProfileFieldTypes[] = { | |
| 33 NAME_FIRST, | |
| 34 NAME_MIDDLE, | |
| 35 NAME_LAST, | |
| 36 EMAIL_ADDRESS, | |
| 37 COMPANY_NAME, | |
| 38 ADDRESS_HOME_LINE1, | |
| 39 ADDRESS_HOME_LINE2, | |
| 40 ADDRESS_HOME_CITY, | |
| 41 ADDRESS_HOME_STATE, | |
| 42 ADDRESS_HOME_ZIP, | |
| 43 ADDRESS_HOME_COUNTRY, | |
| 44 PHONE_HOME_WHOLE_NUMBER | |
| 45 }; | |
| 46 | |
| 47 // Serializes the |profiles| into a string. | |
| 48 std::string SerializeProfiles(const std::vector<AutofillProfile*>& profiles) { | |
| 49 std::string result; | |
| 50 for (size_t i = 0; i < profiles.size(); ++i) { | |
| 51 result += kProfileSeparator; | |
| 52 result += "\n"; | |
| 53 for (size_t j = 0; j < arraysize(kProfileFieldTypes); ++j) { | |
| 54 AutofillFieldType type = kProfileFieldTypes[j]; | |
| 55 std::vector<base::string16> values; | |
| 56 profiles[i]->GetRawMultiInfo(type, &values); | |
| 57 for (size_t k = 0; k < values.size(); ++k) { | |
| 58 result += AutofillType::FieldTypeToString(type); | |
| 59 result += kFieldSeparator; | |
| 60 result += UTF16ToUTF8(values[k]); | |
| 61 result += "\n"; | |
| 62 } | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 return result; | |
| 67 } | |
| 68 | |
| 69 class PersonalDataManagerMock : public PersonalDataManager { | |
| 70 public: | |
| 71 PersonalDataManagerMock(); | |
| 72 virtual ~PersonalDataManagerMock(); | |
| 73 | |
| 74 // Reset the saved profiles. | |
| 75 void Reset(); | |
| 76 | |
| 77 // PersonalDataManager: | |
| 78 virtual void SaveImportedProfile(const AutofillProfile& profile) OVERRIDE; | |
| 79 virtual const std::vector<AutofillProfile*>& web_profiles() const OVERRIDE; | |
| 80 | |
| 81 private: | |
| 82 ScopedVector<AutofillProfile> profiles_; | |
| 83 | |
| 84 DISALLOW_COPY_AND_ASSIGN(PersonalDataManagerMock); | |
| 85 }; | |
| 86 | |
| 87 PersonalDataManagerMock::PersonalDataManagerMock() | |
| 88 : PersonalDataManager("en-US") { | |
| 89 } | |
| 90 | |
| 91 PersonalDataManagerMock::~PersonalDataManagerMock() { | |
| 92 } | |
| 93 | |
| 94 void PersonalDataManagerMock::Reset() { | |
| 95 profiles_.clear(); | |
| 96 } | |
| 97 | |
| 98 void PersonalDataManagerMock::SaveImportedProfile( | |
| 99 const AutofillProfile& profile) { | |
| 100 std::vector<AutofillProfile> profiles; | |
| 101 if (!MergeProfile(profile, profiles_.get(), "en-US", &profiles)) | |
| 102 profiles_.push_back(new AutofillProfile(profile)); | |
| 103 } | |
| 104 | |
| 105 const std::vector<AutofillProfile*>& PersonalDataManagerMock::web_profiles() | |
| 106 const { | |
| 107 return profiles_.get(); | |
| 108 } | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 // A data-driven test for verifying merging of Autofill profiles. Each input is | |
| 113 // a structured dump of a set of implicitly detected autofill profiles. The | |
| 114 // corresponding output file is a dump of the saved profiles that result from | |
| 115 // importing the input profiles. The output file format is identical to the | |
| 116 // input format. | |
| 117 class AutofillMergeTest : public testing::Test, | |
| 118 public DataDrivenTest { | |
| 119 protected: | |
| 120 AutofillMergeTest(); | |
| 121 virtual ~AutofillMergeTest(); | |
| 122 | |
| 123 // testing::Test: | |
| 124 virtual void SetUp(); | |
| 125 | |
| 126 // DataDrivenTest: | |
| 127 virtual void GenerateResults(const std::string& input, | |
| 128 std::string* output) OVERRIDE; | |
| 129 | |
| 130 // Deserializes a set of Autofill profiles from |profiles|, imports each | |
| 131 // sequentially, and fills |merged_profiles| with the serialized result. | |
| 132 void MergeProfiles(const std::string& profiles, std::string* merged_profiles); | |
| 133 | |
| 134 PersonalDataManagerMock personal_data_; | |
| 135 | |
| 136 private: | |
| 137 DISALLOW_COPY_AND_ASSIGN(AutofillMergeTest); | |
| 138 }; | |
| 139 | |
| 140 AutofillMergeTest::AutofillMergeTest() : DataDrivenTest() { | |
| 141 } | |
| 142 | |
| 143 AutofillMergeTest::~AutofillMergeTest() { | |
| 144 } | |
| 145 | |
| 146 void AutofillMergeTest::SetUp() { | |
| 147 test::DisableSystemServices(NULL); | |
| 148 } | |
| 149 | |
| 150 void AutofillMergeTest::GenerateResults(const std::string& input, | |
| 151 std::string* output) { | |
| 152 MergeProfiles(input, output); | |
| 153 } | |
| 154 | |
| 155 void AutofillMergeTest::MergeProfiles(const std::string& profiles, | |
| 156 std::string* merged_profiles) { | |
| 157 // Start with no saved profiles. | |
| 158 personal_data_.Reset(); | |
| 159 | |
| 160 // Create a test form. | |
| 161 FormData form; | |
| 162 form.name = ASCIIToUTF16("MyTestForm"); | |
| 163 form.method = ASCIIToUTF16("POST"); | |
| 164 form.origin = GURL("https://www.example.com/origin.html"); | |
| 165 form.action = GURL("https://www.example.com/action.html"); | |
| 166 form.user_submitted = true; | |
| 167 | |
| 168 // Parse the input line by line. | |
| 169 std::vector<std::string> lines; | |
| 170 Tokenize(profiles, "\n", &lines); | |
| 171 for (size_t i = 0; i < lines.size(); ++i) { | |
| 172 std::string line = lines[i]; | |
| 173 | |
| 174 if (line != kProfileSeparator) { | |
| 175 // Add a field to the current profile. | |
| 176 size_t separator_pos = line.find(kFieldSeparator); | |
| 177 ASSERT_NE(std::string::npos, separator_pos); | |
| 178 base::string16 field_type = UTF8ToUTF16(line.substr(0, separator_pos)); | |
| 179 base::string16 value = | |
| 180 UTF8ToUTF16(line.substr(separator_pos + kFieldOffset)); | |
| 181 | |
| 182 FormFieldData field; | |
| 183 field.label = field_type; | |
| 184 field.name = field_type; | |
| 185 field.value = value; | |
| 186 field.form_control_type = "text"; | |
| 187 form.fields.push_back(field); | |
| 188 } | |
| 189 | |
| 190 // The first line is always a profile separator, and the last profile is not | |
| 191 // followed by an explicit separator. | |
| 192 if ((i > 0 && line == kProfileSeparator) || i == lines.size() - 1) { | |
| 193 // Reached the end of a profile. Try to import it. | |
| 194 FormStructure form_structure(form, std::string()); | |
| 195 for (size_t i = 0; i < form_structure.field_count(); ++i) { | |
| 196 // Set the heuristic type for each field, which is currently serialized | |
| 197 // into the field's name. | |
| 198 AutofillField* field = | |
| 199 const_cast<AutofillField*>(form_structure.field(i)); | |
| 200 AutofillFieldType type = | |
| 201 AutofillType::StringToFieldType(UTF16ToUTF8(field->name)); | |
| 202 field->set_heuristic_type(type); | |
| 203 } | |
| 204 | |
| 205 // Import the profile. | |
| 206 const CreditCard* imported_credit_card; | |
| 207 personal_data_.ImportFormData(form_structure, &imported_credit_card); | |
| 208 EXPECT_EQ(static_cast<const CreditCard*>(NULL), imported_credit_card); | |
| 209 | |
| 210 // Clear the |form| to start a new profile. | |
| 211 form.fields.clear(); | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 *merged_profiles = SerializeProfiles(personal_data_.web_profiles()); | |
| 216 } | |
| 217 | |
| 218 TEST_F(AutofillMergeTest, DataDrivenMergeProfiles) { | |
| 219 RunDataDrivenTest(GetInputDirectory(kTestName), GetOutputDirectory(kTestName), | |
| 220 kFileNamePattern); | |
| 221 } | |
| 222 | |
| 223 } // namespace autofill | |
| OLD | NEW |