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