Rename GetIconID to GetIconId
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_download_manager_unittest.cc
blob5bc8f585d17ed27081a40fc5ccccbea2f7f6cd47
1 // Copyright 2014 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.
5 #include "components/autofill/core/browser/autofill_download_manager.h"
7 #include <list>
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/histogram_tester.h"
13 #include "base/test/test_timeouts.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "components/autofill/core/browser/autofill_field.h"
16 #include "components/autofill/core/browser/autofill_metrics.h"
17 #include "components/autofill/core/browser/autofill_test_utils.h"
18 #include "components/autofill/core/browser/autofill_type.h"
19 #include "components/autofill/core/browser/form_structure.h"
20 #include "components/autofill/core/browser/test_autofill_driver.h"
21 #include "components/autofill/core/common/form_data.h"
22 #include "net/url_request/test_url_fetcher_factory.h"
23 #include "net/url_request/url_request_status.h"
24 #include "net/url_request/url_request_test_util.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 using base::ASCIIToUTF16;
30 namespace autofill {
32 namespace {
34 // Call |fetcher->OnURLFetchComplete()| as the URLFetcher would when
35 // a response is received. Params allow caller to set fake status.
36 void FakeOnURLFetchComplete(net::TestURLFetcher* fetcher,
37 int response_code,
38 const std::string& response_body) {
39 fetcher->set_url(GURL());
40 fetcher->set_status(net::URLRequestStatus());
41 fetcher->set_response_code(response_code);
42 fetcher->SetResponseString(response_body);
44 fetcher->delegate()->OnURLFetchComplete(fetcher);
47 } // namespace
49 // This tests AutofillDownloadManager. AutofillDownloadTest implements
50 // AutofillDownloadManager::Observer and creates an instance of
51 // AutofillDownloadManager. Then it records responses to different initiated
52 // requests, which are verified later. To mock network requests
53 // TestURLFetcherFactory is used, which creates URLFetchers that do not
54 // go over the wire, but allow calling back HTTP responses directly.
55 // The responses in test are out of order and verify: successful query request,
56 // successful upload request, failed upload request.
57 class AutofillDownloadTest : public AutofillDownloadManager::Observer,
58 public testing::Test {
59 public:
60 AutofillDownloadTest()
61 : prefs_(test::PrefServiceForTesting()),
62 request_context_(new net::TestURLRequestContextGetter(
63 base::ThreadTaskRunnerHandle::Get())),
64 download_manager_(&driver_, prefs_.get(), this) {
65 driver_.SetURLRequestContext(request_context_.get());
68 void LimitCache(size_t cache_size) {
69 download_manager_.set_max_form_cache_size(cache_size);
72 // AutofillDownloadManager::Observer implementation.
73 void OnLoadedServerPredictions(const std::string& response_xml) override {
74 ResponseData response;
75 response.response = response_xml;
76 response.type_of_response = QUERY_SUCCESSFULL;
77 responses_.push_back(response);
80 void OnUploadedPossibleFieldTypes() override {
81 ResponseData response;
82 response.type_of_response = UPLOAD_SUCCESSFULL;
83 responses_.push_back(response);
86 void OnServerRequestError(const std::string& form_signature,
87 AutofillDownloadManager::RequestType request_type,
88 int http_error) override {
89 ResponseData response;
90 response.signature = form_signature;
91 response.error = http_error;
92 response.type_of_response =
93 request_type == AutofillDownloadManager::REQUEST_QUERY ?
94 REQUEST_QUERY_FAILED : REQUEST_UPLOAD_FAILED;
95 responses_.push_back(response);
98 enum ResponseType {
99 QUERY_SUCCESSFULL,
100 UPLOAD_SUCCESSFULL,
101 REQUEST_QUERY_FAILED,
102 REQUEST_UPLOAD_FAILED,
105 struct ResponseData {
106 ResponseType type_of_response;
107 int error;
108 std::string signature;
109 std::string response;
111 ResponseData() : type_of_response(REQUEST_QUERY_FAILED), error(0) {}
114 base::MessageLoop message_loop_;
115 std::list<ResponseData> responses_;
116 scoped_ptr<PrefService> prefs_;
117 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
118 TestAutofillDriver driver_;
119 AutofillDownloadManager download_manager_;
122 TEST_F(AutofillDownloadTest, QueryAndUploadTest) {
123 // Create and register factory.
124 net::TestURLFetcherFactory factory;
126 FormData form;
128 FormFieldData field;
129 field.label = ASCIIToUTF16("username");
130 field.name = ASCIIToUTF16("username");
131 field.form_control_type = "text";
132 form.fields.push_back(field);
134 field.label = ASCIIToUTF16("First Name");
135 field.name = ASCIIToUTF16("firstname");
136 field.form_control_type = "text";
137 form.fields.push_back(field);
139 field.label = ASCIIToUTF16("Last Name");
140 field.name = ASCIIToUTF16("lastname");
141 field.form_control_type = "text";
142 form.fields.push_back(field);
144 field.label = ASCIIToUTF16("email");
145 field.name = ASCIIToUTF16("email");
146 field.form_control_type = "text";
147 form.fields.push_back(field);
149 field.label = ASCIIToUTF16("email2");
150 field.name = ASCIIToUTF16("email2");
151 field.form_control_type = "text";
152 form.fields.push_back(field);
154 field.label = ASCIIToUTF16("password");
155 field.name = ASCIIToUTF16("password");
156 field.form_control_type = "password";
157 form.fields.push_back(field);
159 field.label = base::string16();
160 field.name = ASCIIToUTF16("Submit");
161 field.form_control_type = "submit";
162 form.fields.push_back(field);
164 FormStructure *form_structure = new FormStructure(form);
165 ScopedVector<FormStructure> form_structures;
166 form_structures.push_back(form_structure);
168 form.fields.clear();
170 field.label = ASCIIToUTF16("address");
171 field.name = ASCIIToUTF16("address");
172 field.form_control_type = "text";
173 form.fields.push_back(field);
175 field.label = ASCIIToUTF16("address2");
176 field.name = ASCIIToUTF16("address2");
177 field.form_control_type = "text";
178 form.fields.push_back(field);
180 field.label = ASCIIToUTF16("city");
181 field.name = ASCIIToUTF16("city");
182 field.form_control_type = "text";
183 form.fields.push_back(field);
185 field.label = base::string16();
186 field.name = ASCIIToUTF16("Submit");
187 field.form_control_type = "submit";
188 form.fields.push_back(field);
190 form_structure = new FormStructure(form);
191 form_structures.push_back(form_structure);
193 form.fields.clear();
195 field.label = ASCIIToUTF16("username");
196 field.name = ASCIIToUTF16("username");
197 field.form_control_type = "text";
198 form.fields.push_back(field);
200 field.label = ASCIIToUTF16("password");
201 field.name = ASCIIToUTF16("password");
202 field.form_control_type = "password";
203 form.fields.push_back(field);
205 field.label = base::string16();
206 field.name = ASCIIToUTF16("Submit");
207 field.form_control_type = "submit";
208 form.fields.push_back(field);
210 form_structure = new FormStructure(form);
211 form_structures.push_back(form_structure);
213 // Request with id 0.
214 base::HistogramTester histogram;
215 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures.get()));
216 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
217 AutofillMetrics::QUERY_SENT, 1);
219 // Set upload to 100% so requests happen.
220 download_manager_.SetPositiveUploadRate(1.0);
221 download_manager_.SetNegativeUploadRate(1.0);
222 // Request with id 1.
223 EXPECT_TRUE(download_manager_.StartUploadRequest(
224 *(form_structures[0]), true, ServerFieldTypeSet(), std::string()));
225 // Request with id 2.
226 EXPECT_TRUE(download_manager_.StartUploadRequest(
227 *(form_structures[1]), false, ServerFieldTypeSet(), std::string()));
228 // Request with id 3. Upload request with a non-empty additional password form
229 // signature.
230 EXPECT_TRUE(download_manager_.StartUploadRequest(*(form_structures[2]), false,
231 ServerFieldTypeSet(), "42"));
233 const char *responses[] = {
234 "<autofillqueryresponse>"
235 "<field autofilltype=\"0\" />"
236 "<field autofilltype=\"3\" />"
237 "<field autofilltype=\"5\" />"
238 "<field autofilltype=\"9\" />"
239 "<field autofilltype=\"0\" />"
240 "<field autofilltype=\"30\" />"
241 "<field autofilltype=\"31\" />"
242 "<field autofilltype=\"33\" />"
243 "</autofillqueryresponse>",
244 "<autofilluploadresponse positiveuploadrate=\"0.5\" "
245 "negativeuploadrate=\"0.3\"/>",
246 "<html></html>",
249 // Return them out of sequence.
250 net::TestURLFetcher* fetcher = factory.GetFetcherByID(1);
251 ASSERT_TRUE(fetcher);
252 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[1]));
254 // After that upload rates would be adjusted to 0.5/0.3
255 EXPECT_DOUBLE_EQ(0.5, download_manager_.GetPositiveUploadRate());
256 EXPECT_DOUBLE_EQ(0.3, download_manager_.GetNegativeUploadRate());
258 fetcher = factory.GetFetcherByID(2);
259 ASSERT_TRUE(fetcher);
260 FakeOnURLFetchComplete(fetcher, 404, std::string(responses[2]));
262 fetcher = factory.GetFetcherByID(0);
263 ASSERT_TRUE(fetcher);
264 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
265 EXPECT_EQ(static_cast<size_t>(3), responses_.size());
267 EXPECT_EQ(AutofillDownloadTest::UPLOAD_SUCCESSFULL,
268 responses_.front().type_of_response);
269 EXPECT_EQ(0, responses_.front().error);
270 EXPECT_EQ(std::string(), responses_.front().signature);
271 // Expected response on non-query request is an empty string.
272 EXPECT_EQ(std::string(), responses_.front().response);
273 responses_.pop_front();
275 EXPECT_EQ(AutofillDownloadTest::REQUEST_UPLOAD_FAILED,
276 responses_.front().type_of_response);
277 EXPECT_EQ(404, responses_.front().error);
278 EXPECT_EQ(form_structures[1]->FormSignature(),
279 responses_.front().signature);
280 // Expected response on non-query request is an empty string.
281 EXPECT_EQ(std::string(), responses_.front().response);
282 responses_.pop_front();
284 EXPECT_EQ(responses_.front().type_of_response,
285 AutofillDownloadTest::QUERY_SUCCESSFULL);
286 EXPECT_EQ(0, responses_.front().error);
287 EXPECT_EQ(std::string(), responses_.front().signature);
288 EXPECT_EQ(responses[0], responses_.front().response);
289 responses_.pop_front();
291 // Set upload to 0% so no new requests happen.
292 download_manager_.SetPositiveUploadRate(0.0);
293 download_manager_.SetNegativeUploadRate(0.0);
294 // No actual requests for the next two calls, as we set upload rate to 0%.
295 EXPECT_FALSE(download_manager_.StartUploadRequest(
296 *(form_structures[0]), true, ServerFieldTypeSet(), std::string()));
297 EXPECT_FALSE(download_manager_.StartUploadRequest(
298 *(form_structures[1]), false, ServerFieldTypeSet(), std::string()));
299 fetcher = factory.GetFetcherByID(4);
300 EXPECT_EQ(NULL, fetcher);
302 // Modify form structures to miss the cache.
303 field.label = ASCIIToUTF16("Address line 2");
304 field.name = ASCIIToUTF16("address2");
305 field.form_control_type = "text";
306 form.fields.push_back(field);
307 form_structure = new FormStructure(form);
308 form_structures.push_back(form_structure);
310 // Request with id 4.
311 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures.get()));
312 fetcher = factory.GetFetcherByID(4);
313 ASSERT_TRUE(fetcher);
314 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
315 AutofillMetrics::QUERY_SENT, 2);
316 fetcher->set_backoff_delay(TestTimeouts::action_max_timeout());
317 FakeOnURLFetchComplete(fetcher, 500, std::string(responses[0]));
319 EXPECT_EQ(AutofillDownloadTest::REQUEST_QUERY_FAILED,
320 responses_.front().type_of_response);
321 EXPECT_EQ(500, responses_.front().error);
322 // Expected response on non-query request is an empty string.
323 EXPECT_EQ(std::string(), responses_.front().response);
324 responses_.pop_front();
326 // Query requests should be ignored for the next 10 seconds.
327 EXPECT_FALSE(download_manager_.StartQueryRequest(form_structures.get()));
328 fetcher = factory.GetFetcherByID(5);
329 EXPECT_EQ(NULL, fetcher);
330 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
331 AutofillMetrics::QUERY_SENT, 2);
333 // Set upload required to true so requests happen.
334 form_structures[0]->upload_required_ = UPLOAD_REQUIRED;
335 // Request with id 4.
336 EXPECT_TRUE(download_manager_.StartUploadRequest(
337 *(form_structures[0]), true, ServerFieldTypeSet(), std::string()));
338 fetcher = factory.GetFetcherByID(5);
339 ASSERT_TRUE(fetcher);
340 fetcher->set_backoff_delay(TestTimeouts::action_max_timeout());
341 FakeOnURLFetchComplete(fetcher, 503, std::string(responses[2]));
342 EXPECT_EQ(AutofillDownloadTest::REQUEST_UPLOAD_FAILED,
343 responses_.front().type_of_response);
344 EXPECT_EQ(503, responses_.front().error);
345 responses_.pop_front();
347 // Upload requests should be ignored for the next 10 seconds.
348 EXPECT_FALSE(download_manager_.StartUploadRequest(
349 *(form_structures[0]), true, ServerFieldTypeSet(), std::string()));
350 fetcher = factory.GetFetcherByID(6);
351 EXPECT_EQ(NULL, fetcher);
354 TEST_F(AutofillDownloadTest, CacheQueryTest) {
355 // Create and register factory.
356 net::TestURLFetcherFactory factory;
358 FormData form;
360 FormFieldData field;
361 field.form_control_type = "text";
363 field.label = ASCIIToUTF16("username");
364 field.name = ASCIIToUTF16("username");
365 form.fields.push_back(field);
367 field.label = ASCIIToUTF16("First Name");
368 field.name = ASCIIToUTF16("firstname");
369 form.fields.push_back(field);
371 field.label = ASCIIToUTF16("Last Name");
372 field.name = ASCIIToUTF16("lastname");
373 form.fields.push_back(field);
375 FormStructure *form_structure = new FormStructure(form);
376 ScopedVector<FormStructure> form_structures0;
377 form_structures0.push_back(form_structure);
379 // Add a slightly different form, which should result in a different request.
380 field.label = ASCIIToUTF16("email");
381 field.name = ASCIIToUTF16("email");
382 form.fields.push_back(field);
383 form_structure = new FormStructure(form);
384 ScopedVector<FormStructure> form_structures1;
385 form_structures1.push_back(form_structure);
387 // Add another slightly different form, which should also result in a
388 // different request.
389 field.label = ASCIIToUTF16("email2");
390 field.name = ASCIIToUTF16("email2");
391 form.fields.push_back(field);
392 form_structure = new FormStructure(form);
393 ScopedVector<FormStructure> form_structures2;
394 form_structures2.push_back(form_structure);
396 // Limit cache to two forms.
397 LimitCache(2);
399 const char *responses[] = {
400 "<autofillqueryresponse>"
401 "<field autofilltype=\"0\" />"
402 "<field autofilltype=\"3\" />"
403 "<field autofilltype=\"5\" />"
404 "</autofillqueryresponse>",
405 "<autofillqueryresponse>"
406 "<field autofilltype=\"0\" />"
407 "<field autofilltype=\"3\" />"
408 "<field autofilltype=\"5\" />"
409 "<field autofilltype=\"9\" />"
410 "</autofillqueryresponse>",
411 "<autofillqueryresponse>"
412 "<field autofilltype=\"0\" />"
413 "<field autofilltype=\"3\" />"
414 "<field autofilltype=\"5\" />"
415 "<field autofilltype=\"9\" />"
416 "<field autofilltype=\"0\" />"
417 "</autofillqueryresponse>",
420 base::HistogramTester histogram;
421 // Request with id 0.
422 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
423 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
424 AutofillMetrics::QUERY_SENT, 1);
426 // No responses yet
427 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
429 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
430 ASSERT_TRUE(fetcher);
431 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
432 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
433 EXPECT_EQ(responses[0], responses_.front().response);
435 responses_.clear();
437 // No actual request - should be a cache hit.
438 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
439 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
440 AutofillMetrics::QUERY_SENT, 2);
441 // Data is available immediately from cache - no over-the-wire trip.
442 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
443 EXPECT_EQ(responses[0], responses_.front().response);
444 responses_.clear();
446 // Request with id 1.
447 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures1.get()));
448 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
449 AutofillMetrics::QUERY_SENT, 3);
450 // No responses yet
451 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
453 fetcher = factory.GetFetcherByID(1);
454 ASSERT_TRUE(fetcher);
455 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[1]));
456 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
457 EXPECT_EQ(responses[1], responses_.front().response);
459 responses_.clear();
461 // Request with id 2.
462 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures2.get()));
463 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
464 AutofillMetrics::QUERY_SENT, 4);
466 fetcher = factory.GetFetcherByID(2);
467 ASSERT_TRUE(fetcher);
468 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[2]));
469 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
470 EXPECT_EQ(responses[2], responses_.front().response);
472 responses_.clear();
474 // No actual requests - should be a cache hit.
475 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures1.get()));
476 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
477 AutofillMetrics::QUERY_SENT, 5);
479 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures2.get()));
480 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
481 AutofillMetrics::QUERY_SENT, 6);
483 ASSERT_EQ(static_cast<size_t>(2), responses_.size());
484 EXPECT_EQ(responses[1], responses_.front().response);
485 EXPECT_EQ(responses[2], responses_.back().response);
486 responses_.clear();
488 // The first structure should've expired.
489 // Request with id 3.
490 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
491 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
492 AutofillMetrics::QUERY_SENT, 7);
493 // No responses yet
494 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
496 fetcher = factory.GetFetcherByID(3);
497 ASSERT_TRUE(fetcher);
498 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
499 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
500 EXPECT_EQ(responses[0], responses_.front().response);
503 } // namespace autofill