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

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

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

Powered by Google App Engine
This is Rietveld 408576698