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