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