autofill_xml_parser_unittest.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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 <string>
6#include <vector>
7
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/string_number_conversions.h"
10#include "components/autofill/core/browser/autofill_xml_parser.h"
11#include "components/autofill/core/browser/field_types.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "third_party/libjingle/source/talk/xmllite/xmlparser.h"
14
15namespace autofill {
16namespace {
17
18class AutofillQueryXmlParserTest : public testing::Test {
19 public:
20  AutofillQueryXmlParserTest(): upload_required_(USE_UPLOAD_RATES) {};
21  virtual ~AutofillQueryXmlParserTest() {};
22
23 protected:
24  void ParseQueryXML(const std::string& xml, bool should_succeed) {
25    // Create a parser.
26    AutofillQueryXmlParser parse_handler(&field_infos_,
27                                         &upload_required_,
28                                         &experiment_id_);
29    buzz::XmlParser parser(&parse_handler);
30    parser.Parse(xml.c_str(), xml.length(), true);
31    EXPECT_EQ(should_succeed, parse_handler.succeeded());
32  }
33
34  std::vector<AutofillServerFieldInfo> field_infos_;
35  UploadRequired upload_required_;
36  std::string experiment_id_;
37};
38
39class AutofillUploadXmlParserTest : public testing::Test {
40 public:
41  AutofillUploadXmlParserTest(): positive_(0), negative_(0) {};
42  virtual ~AutofillUploadXmlParserTest() {};
43
44 protected:
45  void ParseUploadXML(const std::string& xml, bool should_succeed) {
46    // Create a parser.
47    AutofillUploadXmlParser parse_handler(&positive_, &negative_);
48    buzz::XmlParser parser(&parse_handler);
49    parser.Parse(xml.c_str(), xml.length(), true);
50
51    EXPECT_EQ(should_succeed, parse_handler.succeeded());
52  }
53
54  double positive_;
55  double negative_;
56};
57
58TEST_F(AutofillQueryXmlParserTest, BasicQuery) {
59  // An XML string representing a basic query response.
60  std::string xml = "<autofillqueryresponse>"
61                    "<field autofilltype=\"0\" />"
62                    "<field autofilltype=\"1\" />"
63                    "<field autofilltype=\"3\" />"
64                    "<field autofilltype=\"2\" />"
65                    "<field autofilltype=\"61\" defaultvalue=\"default\"/>"
66                    "</autofillqueryresponse>";
67  ParseQueryXML(xml, true);
68
69  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
70  ASSERT_EQ(5U, field_infos_.size());
71  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
72  EXPECT_EQ(UNKNOWN_TYPE, field_infos_[1].field_type);
73  EXPECT_EQ(NAME_FIRST, field_infos_[2].field_type);
74  EXPECT_EQ(EMPTY_TYPE, field_infos_[3].field_type);
75  EXPECT_TRUE(field_infos_[3].default_value.empty());
76  EXPECT_EQ(FIELD_WITH_DEFAULT_VALUE, field_infos_[4].field_type);
77  EXPECT_EQ("default", field_infos_[4].default_value);
78  EXPECT_TRUE(experiment_id_.empty());
79}
80
81// Test parsing the upload required attribute.
82TEST_F(AutofillQueryXmlParserTest, TestUploadRequired) {
83  std::string xml = "<autofillqueryresponse uploadrequired=\"true\">"
84                    "<field autofilltype=\"0\" />"
85                    "</autofillqueryresponse>";
86
87  ParseQueryXML(xml, true);
88
89  EXPECT_EQ(upload_required_, upload_required_);
90  ASSERT_EQ(1U, field_infos_.size());
91  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
92  EXPECT_TRUE(experiment_id_.empty());
93
94  field_infos_.clear();
95  xml = "<autofillqueryresponse uploadrequired=\"false\">"
96        "<field autofilltype=\"0\" />"
97        "</autofillqueryresponse>";
98
99  ParseQueryXML(xml, true);
100
101  EXPECT_EQ(UPLOAD_NOT_REQUIRED, upload_required_);
102  ASSERT_EQ(1U, field_infos_.size());
103  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
104  EXPECT_TRUE(experiment_id_.empty());
105
106  field_infos_.clear();
107  xml = "<autofillqueryresponse uploadrequired=\"bad_value\">"
108        "<field autofilltype=\"0\" />"
109        "</autofillqueryresponse>";
110
111  ParseQueryXML(xml, true);
112
113  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
114  ASSERT_EQ(1U, field_infos_.size());
115  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
116  EXPECT_TRUE(experiment_id_.empty());
117}
118
119// Test parsing the experiment id attribute
120TEST_F(AutofillQueryXmlParserTest, ParseExperimentId) {
121  // When the attribute is missing, we should get back the default value -- the
122  // empty string.
123  std::string xml = "<autofillqueryresponse>"
124                    "<field autofilltype=\"0\" />"
125                    "</autofillqueryresponse>";
126
127  ParseQueryXML(xml, true);
128
129  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
130  ASSERT_EQ(1U, field_infos_.size());
131  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
132  EXPECT_TRUE(experiment_id_.empty());
133
134  field_infos_.clear();
135
136  // When the attribute is present, make sure we parse it.
137  xml = "<autofillqueryresponse experimentid=\"FancyNewAlgorithm\">"
138        "<field autofilltype=\"0\" />"
139        "</autofillqueryresponse>";
140
141  ParseQueryXML(xml, true);
142
143  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
144  ASSERT_EQ(1U, field_infos_.size());
145  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
146  EXPECT_EQ(std::string("FancyNewAlgorithm"), experiment_id_);
147
148  field_infos_.clear();
149
150  // Make sure that we can handle parsing both the upload required and the
151  // experiment id attribute together.
152  xml = "<autofillqueryresponse uploadrequired=\"false\""
153        "                       experimentid=\"ServerSmartyPants\">"
154        "<field autofilltype=\"0\" />"
155        "</autofillqueryresponse>";
156
157  ParseQueryXML(xml, true);
158
159  EXPECT_EQ(UPLOAD_NOT_REQUIRED, upload_required_);
160  ASSERT_EQ(1U, field_infos_.size());
161  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
162  EXPECT_EQ("ServerSmartyPants", experiment_id_);
163}
164
165// Test badly formed XML queries.
166TEST_F(AutofillQueryXmlParserTest, ParseErrors) {
167  // Test no Autofill type.
168  std::string xml = "<autofillqueryresponse>"
169                    "<field/>"
170                    "</autofillqueryresponse>";
171
172  ParseQueryXML(xml, false);
173
174  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
175  EXPECT_EQ(0U, field_infos_.size());
176  EXPECT_TRUE(experiment_id_.empty());
177
178  // Test an incorrect Autofill type.
179  xml = "<autofillqueryresponse>"
180        "<field autofilltype=\"-1\"/>"
181        "</autofillqueryresponse>";
182
183  ParseQueryXML(xml, true);
184
185  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
186  ASSERT_EQ(1U, field_infos_.size());
187  // AutofillType was out of range and should be set to NO_SERVER_DATA.
188  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
189  EXPECT_TRUE(experiment_id_.empty());
190
191  // Test upper bound for the field type, MAX_VALID_FIELD_TYPE.
192  field_infos_.clear();
193  xml = "<autofillqueryresponse><field autofilltype=\"" +
194      base::IntToString(MAX_VALID_FIELD_TYPE) + "\"/></autofillqueryresponse>";
195
196  ParseQueryXML(xml, true);
197
198  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
199  ASSERT_EQ(1U, field_infos_.size());
200  // AutofillType was out of range and should be set to NO_SERVER_DATA.
201  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
202  EXPECT_TRUE(experiment_id_.empty());
203
204  // Test an incorrect Autofill type.
205  field_infos_.clear();
206  xml = "<autofillqueryresponse>"
207        "<field autofilltype=\"No Type\"/>"
208        "</autofillqueryresponse>";
209
210  // Parse fails but an entry is still added to field_infos_.
211  ParseQueryXML(xml, false);
212
213  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
214  ASSERT_EQ(1U, field_infos_.size());
215  EXPECT_EQ(NO_SERVER_DATA, field_infos_[0].field_type);
216  EXPECT_TRUE(experiment_id_.empty());
217}
218
219// Test successfull upload response.
220TEST_F(AutofillUploadXmlParserTest, TestSuccessfulResponse) {
221  ParseUploadXML("<autofilluploadresponse positiveuploadrate=\"0.5\" "
222                 "negativeuploadrate=\"0.3\"/>",
223                 true);
224
225  EXPECT_DOUBLE_EQ(0.5, positive_);
226  EXPECT_DOUBLE_EQ(0.3, negative_);
227}
228
229// Test failed upload response.
230TEST_F(AutofillUploadXmlParserTest, TestFailedResponse) {
231  ParseUploadXML("<autofilluploadresponse positiveuploadrate=\"\" "
232                 "negativeuploadrate=\"0.3\"/>",
233                 false);
234
235  EXPECT_DOUBLE_EQ(0, positive_);
236  EXPECT_DOUBLE_EQ(0.3, negative_);  // Partially parsed.
237  negative_ = 0;
238
239  ParseUploadXML("<autofilluploadresponse positiveuploadrate=\"0.5\" "
240                 "negativeuploadrate=\"0.3\"",
241                 false);
242
243  EXPECT_DOUBLE_EQ(0, positive_);
244  EXPECT_DOUBLE_EQ(0, negative_);
245
246  ParseUploadXML("bad data", false);
247
248  EXPECT_DOUBLE_EQ(0, positive_);
249  EXPECT_DOUBLE_EQ(0, negative_);
250
251  ParseUploadXML(std::string(), false);
252
253  EXPECT_DOUBLE_EQ(0, positive_);
254  EXPECT_DOUBLE_EQ(0, negative_);
255}
256
257}  // namespace
258}  // namespace autofill
259