ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_download_manager_unittest.cc
blob1383e1f599106c3730b2fc423ffc34b808489ac8
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/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/histogram_tester.h"
14 #include "base/test/test_timeouts.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::MessageLoopProxy::current())),
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 // Request with id 0.
194 base::HistogramTester histogram;
195 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures.get()));
196 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
197 AutofillMetrics::QUERY_SENT, 1);
199 // Set upload to 100% so requests happen.
200 download_manager_.SetPositiveUploadRate(1.0);
201 download_manager_.SetNegativeUploadRate(1.0);
202 // Request with id 1.
203 EXPECT_TRUE(download_manager_.StartUploadRequest(
204 *(form_structures[0]), true, ServerFieldTypeSet()));
205 // Request with id 2.
206 EXPECT_TRUE(download_manager_.StartUploadRequest(
207 *(form_structures[1]), false, ServerFieldTypeSet()));
209 const char *responses[] = {
210 "<autofillqueryresponse>"
211 "<field autofilltype=\"0\" />"
212 "<field autofilltype=\"3\" />"
213 "<field autofilltype=\"5\" />"
214 "<field autofilltype=\"9\" />"
215 "<field autofilltype=\"0\" />"
216 "<field autofilltype=\"30\" />"
217 "<field autofilltype=\"31\" />"
218 "<field autofilltype=\"33\" />"
219 "</autofillqueryresponse>",
220 "<autofilluploadresponse positiveuploadrate=\"0.5\" "
221 "negativeuploadrate=\"0.3\"/>",
222 "<html></html>",
225 // Return them out of sequence.
226 net::TestURLFetcher* fetcher = factory.GetFetcherByID(1);
227 ASSERT_TRUE(fetcher);
228 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[1]));
230 // After that upload rates would be adjusted to 0.5/0.3
231 EXPECT_DOUBLE_EQ(0.5, download_manager_.GetPositiveUploadRate());
232 EXPECT_DOUBLE_EQ(0.3, download_manager_.GetNegativeUploadRate());
234 fetcher = factory.GetFetcherByID(2);
235 ASSERT_TRUE(fetcher);
236 FakeOnURLFetchComplete(fetcher, 404, std::string(responses[2]));
238 fetcher = factory.GetFetcherByID(0);
239 ASSERT_TRUE(fetcher);
240 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
241 EXPECT_EQ(static_cast<size_t>(3), responses_.size());
243 EXPECT_EQ(AutofillDownloadTest::UPLOAD_SUCCESSFULL,
244 responses_.front().type_of_response);
245 EXPECT_EQ(0, responses_.front().error);
246 EXPECT_EQ(std::string(), responses_.front().signature);
247 // Expected response on non-query request is an empty string.
248 EXPECT_EQ(std::string(), responses_.front().response);
249 responses_.pop_front();
251 EXPECT_EQ(AutofillDownloadTest::REQUEST_UPLOAD_FAILED,
252 responses_.front().type_of_response);
253 EXPECT_EQ(404, responses_.front().error);
254 EXPECT_EQ(form_structures[1]->FormSignature(),
255 responses_.front().signature);
256 // Expected response on non-query request is an empty string.
257 EXPECT_EQ(std::string(), responses_.front().response);
258 responses_.pop_front();
260 EXPECT_EQ(responses_.front().type_of_response,
261 AutofillDownloadTest::QUERY_SUCCESSFULL);
262 EXPECT_EQ(0, responses_.front().error);
263 EXPECT_EQ(std::string(), responses_.front().signature);
264 EXPECT_EQ(responses[0], responses_.front().response);
265 responses_.pop_front();
267 // Set upload to 0% so no new requests happen.
268 download_manager_.SetPositiveUploadRate(0.0);
269 download_manager_.SetNegativeUploadRate(0.0);
270 // No actual requests for the next two calls, as we set upload rate to 0%.
271 EXPECT_FALSE(download_manager_.StartUploadRequest(
272 *(form_structures[0]), true, ServerFieldTypeSet()));
273 EXPECT_FALSE(download_manager_.StartUploadRequest(
274 *(form_structures[1]), false, ServerFieldTypeSet()));
275 fetcher = factory.GetFetcherByID(3);
276 EXPECT_EQ(NULL, fetcher);
278 // Modify form structures to miss the cache.
279 field.label = ASCIIToUTF16("Address line 2");
280 field.name = ASCIIToUTF16("address2");
281 field.form_control_type = "text";
282 form.fields.push_back(field);
283 form_structure = new FormStructure(form);
284 form_structures.push_back(form_structure);
286 // Request with id 3.
287 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures.get()));
288 fetcher = factory.GetFetcherByID(3);
289 ASSERT_TRUE(fetcher);
290 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
291 AutofillMetrics::QUERY_SENT, 2);
292 fetcher->set_backoff_delay(TestTimeouts::action_max_timeout());
293 FakeOnURLFetchComplete(fetcher, 500, std::string(responses[0]));
295 EXPECT_EQ(AutofillDownloadTest::REQUEST_QUERY_FAILED,
296 responses_.front().type_of_response);
297 EXPECT_EQ(500, responses_.front().error);
298 // Expected response on non-query request is an empty string.
299 EXPECT_EQ(std::string(), responses_.front().response);
300 responses_.pop_front();
302 // Query requests should be ignored for the next 10 seconds.
303 EXPECT_FALSE(download_manager_.StartQueryRequest(form_structures.get()));
304 fetcher = factory.GetFetcherByID(4);
305 EXPECT_EQ(NULL, fetcher);
306 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
307 AutofillMetrics::QUERY_SENT, 2);
309 // Set upload required to true so requests happen.
310 form_structures[0]->upload_required_ = UPLOAD_REQUIRED;
311 // Request with id 4.
312 EXPECT_TRUE(download_manager_.StartUploadRequest(
313 *(form_structures[0]), true, ServerFieldTypeSet()));
314 fetcher = factory.GetFetcherByID(4);
315 ASSERT_TRUE(fetcher);
316 fetcher->set_backoff_delay(TestTimeouts::action_max_timeout());
317 FakeOnURLFetchComplete(fetcher, 503, std::string(responses[2]));
318 EXPECT_EQ(AutofillDownloadTest::REQUEST_UPLOAD_FAILED,
319 responses_.front().type_of_response);
320 EXPECT_EQ(503, responses_.front().error);
321 responses_.pop_front();
323 // Upload requests should be ignored for the next 10 seconds.
324 EXPECT_FALSE(download_manager_.StartUploadRequest(
325 *(form_structures[0]), true, ServerFieldTypeSet()));
326 fetcher = factory.GetFetcherByID(5);
327 EXPECT_EQ(NULL, fetcher);
330 TEST_F(AutofillDownloadTest, CacheQueryTest) {
331 // Create and register factory.
332 net::TestURLFetcherFactory factory;
334 FormData form;
336 FormFieldData field;
337 field.form_control_type = "text";
339 field.label = ASCIIToUTF16("username");
340 field.name = ASCIIToUTF16("username");
341 form.fields.push_back(field);
343 field.label = ASCIIToUTF16("First Name");
344 field.name = ASCIIToUTF16("firstname");
345 form.fields.push_back(field);
347 field.label = ASCIIToUTF16("Last Name");
348 field.name = ASCIIToUTF16("lastname");
349 form.fields.push_back(field);
351 FormStructure *form_structure = new FormStructure(form);
352 ScopedVector<FormStructure> form_structures0;
353 form_structures0.push_back(form_structure);
355 // Add a slightly different form, which should result in a different request.
356 field.label = ASCIIToUTF16("email");
357 field.name = ASCIIToUTF16("email");
358 form.fields.push_back(field);
359 form_structure = new FormStructure(form);
360 ScopedVector<FormStructure> form_structures1;
361 form_structures1.push_back(form_structure);
363 // Add another slightly different form, which should also result in a
364 // different request.
365 field.label = ASCIIToUTF16("email2");
366 field.name = ASCIIToUTF16("email2");
367 form.fields.push_back(field);
368 form_structure = new FormStructure(form);
369 ScopedVector<FormStructure> form_structures2;
370 form_structures2.push_back(form_structure);
372 // Limit cache to two forms.
373 LimitCache(2);
375 const char *responses[] = {
376 "<autofillqueryresponse>"
377 "<field autofilltype=\"0\" />"
378 "<field autofilltype=\"3\" />"
379 "<field autofilltype=\"5\" />"
380 "</autofillqueryresponse>",
381 "<autofillqueryresponse>"
382 "<field autofilltype=\"0\" />"
383 "<field autofilltype=\"3\" />"
384 "<field autofilltype=\"5\" />"
385 "<field autofilltype=\"9\" />"
386 "</autofillqueryresponse>",
387 "<autofillqueryresponse>"
388 "<field autofilltype=\"0\" />"
389 "<field autofilltype=\"3\" />"
390 "<field autofilltype=\"5\" />"
391 "<field autofilltype=\"9\" />"
392 "<field autofilltype=\"0\" />"
393 "</autofillqueryresponse>",
396 base::HistogramTester histogram;
397 // Request with id 0.
398 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
399 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
400 AutofillMetrics::QUERY_SENT, 1);
402 // No responses yet
403 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
405 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
406 ASSERT_TRUE(fetcher);
407 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
408 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
409 EXPECT_EQ(responses[0], responses_.front().response);
411 responses_.clear();
413 // No actual request - should be a cache hit.
414 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
415 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
416 AutofillMetrics::QUERY_SENT, 2);
417 // Data is available immediately from cache - no over-the-wire trip.
418 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
419 EXPECT_EQ(responses[0], responses_.front().response);
420 responses_.clear();
422 // Request with id 1.
423 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures1.get()));
424 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
425 AutofillMetrics::QUERY_SENT, 3);
426 // No responses yet
427 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
429 fetcher = factory.GetFetcherByID(1);
430 ASSERT_TRUE(fetcher);
431 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[1]));
432 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
433 EXPECT_EQ(responses[1], responses_.front().response);
435 responses_.clear();
437 // Request with id 2.
438 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures2.get()));
439 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
440 AutofillMetrics::QUERY_SENT, 4);
442 fetcher = factory.GetFetcherByID(2);
443 ASSERT_TRUE(fetcher);
444 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[2]));
445 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
446 EXPECT_EQ(responses[2], responses_.front().response);
448 responses_.clear();
450 // No actual requests - should be a cache hit.
451 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures1.get()));
452 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
453 AutofillMetrics::QUERY_SENT, 5);
455 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures2.get()));
456 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
457 AutofillMetrics::QUERY_SENT, 6);
459 ASSERT_EQ(static_cast<size_t>(2), responses_.size());
460 EXPECT_EQ(responses[1], responses_.front().response);
461 EXPECT_EQ(responses[2], responses_.back().response);
462 responses_.clear();
464 // The first structure should've expired.
465 // Request with id 3.
466 EXPECT_TRUE(download_manager_.StartQueryRequest(form_structures0.get()));
467 histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
468 AutofillMetrics::QUERY_SENT, 7);
469 // No responses yet
470 EXPECT_EQ(static_cast<size_t>(0), responses_.size());
472 fetcher = factory.GetFetcherByID(3);
473 ASSERT_TRUE(fetcher);
474 FakeOnURLFetchComplete(fetcher, 200, std::string(responses[0]));
475 ASSERT_EQ(static_cast<size_t>(1), responses_.size());
476 EXPECT_EQ(responses[0], responses_.front().response);
479 } // namespace autofill