Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1360)

Side by Side Diff: components/autofill/core/browser/autofill_download_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698