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

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

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

Powered by Google App Engine
This is Rietveld 408576698