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 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. 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 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. 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. 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. 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