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
13 namespace {
14
TEST(AutofillQueryXmlParserTest,BasicQuery)15 TEST(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.
TEST(AutofillQueryXmlParserTest,TestUploadRequired)45 TEST(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
TEST(AutofillQueryXmlParserTest,ParseExperimentId)97 TEST(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.
TEST(AutofillQueryXmlParserTest,ParseErrors)157 TEST(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.
TEST(AutofillUploadXmlParser,TestSuccessfulResponse)212 TEST(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.
TEST(AutofillUploadXmlParser,TestFailedResponse)226 TEST(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