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