Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / autocomplete / autocomplete_provider_unittest.cc
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 "chrome/browser/autocomplete/autocomplete_provider.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/autocomplete/autocomplete_controller.h"
16 #include "chrome/browser/autocomplete/autocomplete_input.h"
17 #include "chrome/browser/autocomplete/autocomplete_match.h"
18 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
19 #include "chrome/browser/autocomplete/keyword_provider.h"
20 #include "chrome/browser/autocomplete/search_provider.h"
21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/search_engines/template_url.h"
23 #include "chrome/browser/search_engines/template_url_service.h"
24 #include "chrome/browser/search_engines/template_url_service_factory.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/testing_browser_process.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "content/public/browser/notification_observer.h"
29 #include "content/public/browser/notification_registrar.h"
30 #include "content/public/browser/notification_source.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32
33 static std::ostream& operator<<(std::ostream& os,
34                                 const AutocompleteResult::const_iterator& it) {
35   return os << static_cast<const AutocompleteMatch*>(&(*it));
36 }
37
38 namespace {
39 const size_t kResultsPerProvider = 3;
40 const char kTestTemplateURLKeyword[] = "t";
41 }
42
43 // Autocomplete provider that provides known results. Note that this is
44 // refcounted so that it can also be a task on the message loop.
45 class TestProvider : public AutocompleteProvider {
46  public:
47   TestProvider(int relevance, const base::string16& prefix,
48                Profile* profile,
49                const base::string16 match_keyword)
50       : AutocompleteProvider(NULL, profile, AutocompleteProvider::TYPE_SEARCH),
51         relevance_(relevance),
52         prefix_(prefix),
53         match_keyword_(match_keyword) {
54   }
55
56   virtual void Start(const AutocompleteInput& input,
57                      bool minimal_changes) OVERRIDE;
58
59   void set_listener(AutocompleteProviderListener* listener) {
60     listener_ = listener;
61   }
62
63  private:
64   virtual ~TestProvider() {}
65
66   void Run();
67
68   void AddResults(int start_at, int num);
69   void AddResultsWithSearchTermsArgs(
70       int start_at,
71       int num,
72       AutocompleteMatch::Type type,
73       const TemplateURLRef::SearchTermsArgs& search_terms_args);
74
75   int relevance_;
76   const base::string16 prefix_;
77   const base::string16 match_keyword_;
78 };
79
80 void TestProvider::Start(const AutocompleteInput& input,
81                          bool minimal_changes) {
82   if (minimal_changes)
83     return;
84
85   matches_.clear();
86
87   // Generate 4 results synchronously, the rest later.
88   AddResults(0, 1);
89   AddResultsWithSearchTermsArgs(
90       1, 1, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
91       TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("echo")));
92   AddResultsWithSearchTermsArgs(
93       2, 1, AutocompleteMatchType::NAVSUGGEST,
94       TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("nav")));
95   AddResultsWithSearchTermsArgs(
96       3, 1, AutocompleteMatchType::SEARCH_SUGGEST,
97       TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("query")));
98
99   if (input.want_asynchronous_matches()) {
100     done_ = false;
101     base::MessageLoop::current()->PostTask(
102         FROM_HERE, base::Bind(&TestProvider::Run, this));
103   }
104 }
105
106 void TestProvider::Run() {
107   DCHECK_GT(kResultsPerProvider, 0U);
108   AddResults(1, kResultsPerProvider);
109   done_ = true;
110   DCHECK(listener_);
111   listener_->OnProviderUpdate(true);
112 }
113
114 void TestProvider::AddResults(int start_at, int num) {
115   AddResultsWithSearchTermsArgs(start_at,
116                                 num,
117                                 AutocompleteMatchType::URL_WHAT_YOU_TYPED,
118                                 TemplateURLRef::SearchTermsArgs(
119                                     base::string16()));
120 }
121
122 void TestProvider::AddResultsWithSearchTermsArgs(
123     int start_at,
124     int num,
125     AutocompleteMatch::Type type,
126     const TemplateURLRef::SearchTermsArgs& search_terms_args) {
127   for (int i = start_at; i < num; i++) {
128     AutocompleteMatch match(this, relevance_ - i, false, type);
129
130     match.fill_into_edit = prefix_ + base::UTF8ToUTF16(base::IntToString(i));
131     match.destination_url = GURL(base::UTF16ToUTF8(match.fill_into_edit));
132     match.allowed_to_be_default_match = true;
133
134     match.contents = match.fill_into_edit;
135     match.contents_class.push_back(
136         ACMatchClassification(0, ACMatchClassification::NONE));
137     match.description = match.fill_into_edit;
138     match.description_class.push_back(
139         ACMatchClassification(0, ACMatchClassification::NONE));
140     match.search_terms_args.reset(
141         new TemplateURLRef::SearchTermsArgs(search_terms_args));
142     if (!match_keyword_.empty()) {
143       match.keyword = match_keyword_;
144       ASSERT_TRUE(match.GetTemplateURL(profile_, false) != NULL);
145     }
146
147     matches_.push_back(match);
148   }
149 }
150
151 class AutocompleteProviderTest : public testing::Test,
152                                  public content::NotificationObserver {
153  protected:
154   struct KeywordTestData {
155     const base::string16 fill_into_edit;
156     const base::string16 keyword;
157     const bool expected_keyword_result;
158   };
159
160   struct AssistedQueryStatsTestData {
161     const AutocompleteMatch::Type match_type;
162     const std::string expected_aqs;
163   };
164
165  protected:
166    // Registers a test TemplateURL under the given keyword.
167   void RegisterTemplateURL(const base::string16 keyword,
168                            const std::string& template_url);
169
170   // Resets |controller_| with two TestProviders.  |provider1_ptr| and
171   // |provider2_ptr| are updated to point to the new providers if non-NULL.
172   void ResetControllerWithTestProviders(bool same_destinations,
173                                         TestProvider** provider1_ptr,
174                                         TestProvider** provider2_ptr);
175
176   // Runs a query on the input "a", and makes sure both providers' input is
177   // properly collected.
178   void RunTest();
179
180   void RunRedundantKeywordTest(const KeywordTestData* match_data, size_t size);
181
182   void RunAssistedQueryStatsTest(
183       const AssistedQueryStatsTestData* aqs_test_data,
184       size_t size);
185
186   void RunQuery(const base::string16 query);
187
188   void ResetControllerWithKeywordAndSearchProviders();
189   void ResetControllerWithKeywordProvider();
190   void RunExactKeymatchTest(bool allow_exact_keyword_match);
191
192   void CopyResults();
193
194   // Returns match.destination_url as it would be set by
195   // AutocompleteController::UpdateMatchDestinationURL().
196   GURL GetDestinationURL(AutocompleteMatch match,
197                          base::TimeDelta query_formulation_time) const;
198
199   AutocompleteResult result_;
200   scoped_ptr<AutocompleteController> controller_;
201
202  private:
203   // content::NotificationObserver:
204   virtual void Observe(int type,
205                        const content::NotificationSource& source,
206                        const content::NotificationDetails& details) OVERRIDE;
207
208   base::MessageLoopForUI message_loop_;
209   content::NotificationRegistrar registrar_;
210   TestingProfile profile_;
211 };
212
213 void AutocompleteProviderTest::RegisterTemplateURL(
214     const base::string16 keyword,
215     const std::string& template_url) {
216   TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
217       &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
218   TemplateURLData data;
219   data.SetURL(template_url);
220   data.SetKeyword(keyword);
221   TemplateURL* default_t_url = new TemplateURL(&profile_, data);
222   TemplateURLService* turl_model =
223       TemplateURLServiceFactory::GetForProfile(&profile_);
224   turl_model->Add(default_t_url);
225   turl_model->SetUserSelectedDefaultSearchProvider(default_t_url);
226   turl_model->Load();
227   TemplateURLID default_provider_id = default_t_url->id();
228   ASSERT_NE(0, default_provider_id);
229 }
230
231 void AutocompleteProviderTest::ResetControllerWithTestProviders(
232     bool same_destinations,
233     TestProvider** provider1_ptr,
234     TestProvider** provider2_ptr) {
235   // TODO: Move it outside this method, after refactoring the existing
236   // unit tests.  Specifically:
237   //   (1) Make sure that AutocompleteMatch.keyword is set iff there is
238   //       a corresponding call to RegisterTemplateURL; otherwise the
239   //       controller flow will crash; this practically means that
240   //       RunTests/ResetControllerXXX/RegisterTemplateURL should
241   //       be coordinated with each other.
242   //   (2) Inject test arguments rather than rely on the hardcoded values, e.g.
243   //       don't rely on kResultsPerProvided and default relevance ordering
244   //       (B > A).
245   RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword),
246                       "http://aqs/{searchTerms}/{google:assistedQueryStats}");
247
248   ACProviders providers;
249
250   // Construct two new providers, with either the same or different prefixes.
251   TestProvider* provider1 = new TestProvider(
252       kResultsPerProvider,
253       base::ASCIIToUTF16("http://a"),
254       &profile_,
255       base::ASCIIToUTF16(kTestTemplateURLKeyword));
256   provider1->AddRef();
257   providers.push_back(provider1);
258
259   TestProvider* provider2 = new TestProvider(
260       kResultsPerProvider * 2,
261       same_destinations ? base::ASCIIToUTF16("http://a")
262                         : base::ASCIIToUTF16("http://b"),
263       &profile_,
264       base::string16());
265   provider2->AddRef();
266   providers.push_back(provider2);
267
268   // Reset the controller to contain our new providers.
269   controller_.reset(new AutocompleteController(&profile_, NULL, 0));
270   // We're going to swap the providers vector, but the old vector should be
271   // empty so no elements need to be freed at this point.
272   EXPECT_TRUE(controller_->providers_.empty());
273   controller_->providers_.swap(providers);
274   provider1->set_listener(controller_.get());
275   provider2->set_listener(controller_.get());
276
277   // The providers don't complete synchronously, so listen for "result updated"
278   // notifications.
279   registrar_.Add(this,
280                  chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
281                  content::Source<AutocompleteController>(controller_.get()));
282
283   if (provider1_ptr)
284     *provider1_ptr = provider1;
285   if (provider2_ptr)
286     *provider2_ptr = provider2;
287 }
288
289 void AutocompleteProviderTest::
290     ResetControllerWithKeywordAndSearchProviders() {
291   TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
292       &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
293
294   // Reset the default TemplateURL.
295   TemplateURLData data;
296   data.SetURL("http://defaultturl/{searchTerms}");
297   TemplateURL* default_t_url = new TemplateURL(&profile_, data);
298   TemplateURLService* turl_model =
299       TemplateURLServiceFactory::GetForProfile(&profile_);
300   turl_model->Add(default_t_url);
301   turl_model->SetUserSelectedDefaultSearchProvider(default_t_url);
302   TemplateURLID default_provider_id = default_t_url->id();
303   ASSERT_NE(0, default_provider_id);
304
305   // Create another TemplateURL for KeywordProvider.
306   TemplateURLData data2;
307   data2.short_name = base::ASCIIToUTF16("k");
308   data2.SetKeyword(base::ASCIIToUTF16("k"));
309   data2.SetURL("http://keyword/{searchTerms}");
310   TemplateURL* keyword_t_url = new TemplateURL(&profile_, data2);
311   turl_model->Add(keyword_t_url);
312   ASSERT_NE(0, keyword_t_url->id());
313
314   controller_.reset(new AutocompleteController(
315       &profile_, NULL,
316       AutocompleteProvider::TYPE_KEYWORD | AutocompleteProvider::TYPE_SEARCH));
317 }
318
319 void AutocompleteProviderTest::ResetControllerWithKeywordProvider() {
320   TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
321       &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
322
323   TemplateURLService* turl_model =
324       TemplateURLServiceFactory::GetForProfile(&profile_);
325
326   // Create a TemplateURL for KeywordProvider.
327   TemplateURLData data;
328   data.short_name = base::ASCIIToUTF16("foo.com");
329   data.SetKeyword(base::ASCIIToUTF16("foo.com"));
330   data.SetURL("http://foo.com/{searchTerms}");
331   TemplateURL* keyword_t_url = new TemplateURL(&profile_, data);
332   turl_model->Add(keyword_t_url);
333   ASSERT_NE(0, keyword_t_url->id());
334
335   // Create another TemplateURL for KeywordProvider.
336   data.short_name = base::ASCIIToUTF16("bar.com");
337   data.SetKeyword(base::ASCIIToUTF16("bar.com"));
338   data.SetURL("http://bar.com/{searchTerms}");
339   keyword_t_url = new TemplateURL(&profile_, data);
340   turl_model->Add(keyword_t_url);
341   ASSERT_NE(0, keyword_t_url->id());
342
343   controller_.reset(new AutocompleteController(
344       &profile_, NULL, AutocompleteProvider::TYPE_KEYWORD));
345 }
346
347 void AutocompleteProviderTest::RunTest() {
348   RunQuery(base::ASCIIToUTF16("a"));
349 }
350
351 void AutocompleteProviderTest::RunRedundantKeywordTest(
352     const KeywordTestData* match_data,
353     size_t size) {
354   ACMatches matches;
355   for (size_t i = 0; i < size; ++i) {
356     AutocompleteMatch match;
357     match.relevance = 1000;  // Arbitrary non-zero value.
358     match.allowed_to_be_default_match = true;
359     match.fill_into_edit = match_data[i].fill_into_edit;
360     match.transition = content::PAGE_TRANSITION_KEYWORD;
361     match.keyword = match_data[i].keyword;
362     matches.push_back(match);
363   }
364
365   AutocompleteResult result;
366   result.AppendMatches(matches);
367   controller_->UpdateAssociatedKeywords(&result);
368
369   for (size_t j = 0; j < result.size(); ++j) {
370     EXPECT_EQ(match_data[j].expected_keyword_result,
371         result.match_at(j)->associated_keyword.get() != NULL);
372   }
373 }
374
375 void AutocompleteProviderTest::RunAssistedQueryStatsTest(
376     const AssistedQueryStatsTestData* aqs_test_data,
377     size_t size) {
378   // Prepare input.
379   const size_t kMaxRelevance = 1000;
380   ACMatches matches;
381   for (size_t i = 0; i < size; ++i) {
382     AutocompleteMatch match(NULL, kMaxRelevance - i, false,
383                             aqs_test_data[i].match_type);
384     match.allowed_to_be_default_match = true;
385     match.keyword = base::ASCIIToUTF16(kTestTemplateURLKeyword);
386     match.search_terms_args.reset(
387         new TemplateURLRef::SearchTermsArgs(base::string16()));
388     matches.push_back(match);
389   }
390   result_.Reset();
391   result_.AppendMatches(matches);
392
393   // Update AQS.
394   controller_->UpdateAssistedQueryStats(&result_);
395
396   // Verify data.
397   for (size_t i = 0; i < size; ++i) {
398     EXPECT_EQ(aqs_test_data[i].expected_aqs,
399               result_.match_at(i)->search_terms_args->assisted_query_stats);
400   }
401 }
402
403 void AutocompleteProviderTest::RunQuery(const base::string16 query) {
404   result_.Reset();
405   controller_->Start(AutocompleteInput(
406       query, base::string16::npos, base::string16(), GURL(),
407       AutocompleteInput::INVALID_SPEC, true, false, true, true));
408
409   if (!controller_->done())
410     // The message loop will terminate when all autocomplete input has been
411     // collected.
412     base::MessageLoop::current()->Run();
413 }
414
415 void AutocompleteProviderTest::RunExactKeymatchTest(
416     bool allow_exact_keyword_match) {
417   // Send the controller input which exactly matches the keyword provider we
418   // created in ResetControllerWithKeywordAndSearchProviders().  The default
419   // match should thus be a search-other-engine match iff
420   // |allow_exact_keyword_match| is true.  Regardless, the match should
421   // be from SearchProvider.  (It provides all verbatim search matches,
422   // keyword or not.)
423   controller_->Start(AutocompleteInput(
424       base::ASCIIToUTF16("k test"), base::string16::npos, base::string16(),
425       GURL(), AutocompleteInput::INVALID_SPEC, true, false,
426       allow_exact_keyword_match, false));
427   EXPECT_TRUE(controller_->done());
428   EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH,
429       controller_->result().default_match()->provider->type());
430   EXPECT_EQ(allow_exact_keyword_match ?
431       AutocompleteMatchType::SEARCH_OTHER_ENGINE :
432       AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
433       controller_->result().default_match()->type);
434 }
435
436 void AutocompleteProviderTest::CopyResults() {
437   result_.CopyFrom(controller_->result());
438 }
439
440 GURL AutocompleteProviderTest::GetDestinationURL(
441     AutocompleteMatch match,
442     base::TimeDelta query_formulation_time) const {
443   controller_->UpdateMatchDestinationURL(query_formulation_time, &match);
444   return match.destination_url;
445 }
446
447 void AutocompleteProviderTest::Observe(
448     int type,
449     const content::NotificationSource& source,
450     const content::NotificationDetails& details) {
451   if (controller_->done()) {
452     CopyResults();
453     base::MessageLoop::current()->Quit();
454   }
455 }
456
457 // Tests that the default selection is set properly when updating results.
458 TEST_F(AutocompleteProviderTest, Query) {
459   TestProvider* provider1 = NULL;
460   TestProvider* provider2 = NULL;
461   ResetControllerWithTestProviders(false, &provider1, &provider2);
462   RunTest();
463
464   // Make sure the default match gets set to the highest relevance match.  The
465   // highest relevance matches should come from the second provider.
466   EXPECT_EQ(kResultsPerProvider * 2, result_.size());
467   ASSERT_NE(result_.end(), result_.default_match());
468   EXPECT_EQ(provider2, result_.default_match()->provider);
469 }
470
471 // Tests assisted query stats.
472 TEST_F(AutocompleteProviderTest, AssistedQueryStats) {
473   ResetControllerWithTestProviders(false, NULL, NULL);
474   RunTest();
475
476   ASSERT_EQ(kResultsPerProvider * 2, result_.size());
477
478   // Now, check the results from the second provider, as they should not have
479   // assisted query stats set.
480   for (size_t i = 0; i < kResultsPerProvider; ++i) {
481     EXPECT_TRUE(
482         result_.match_at(i)->search_terms_args->assisted_query_stats.empty());
483   }
484   // The first provider has a test keyword, so AQS should be non-empty.
485   for (size_t i = kResultsPerProvider; i < kResultsPerProvider * 2; ++i) {
486     EXPECT_FALSE(
487         result_.match_at(i)->search_terms_args->assisted_query_stats.empty());
488   }
489 }
490
491 TEST_F(AutocompleteProviderTest, RemoveDuplicates) {
492   TestProvider* provider1 = NULL;
493   TestProvider* provider2 = NULL;
494   ResetControllerWithTestProviders(true, &provider1, &provider2);
495   RunTest();
496
497   // Make sure all the first provider's results were eliminated by the second
498   // provider's.
499   EXPECT_EQ(kResultsPerProvider, result_.size());
500   for (AutocompleteResult::const_iterator i(result_.begin());
501        i != result_.end(); ++i)
502     EXPECT_EQ(provider2, i->provider);
503 }
504
505 TEST_F(AutocompleteProviderTest, AllowExactKeywordMatch) {
506   ResetControllerWithKeywordAndSearchProviders();
507   RunExactKeymatchTest(true);
508   RunExactKeymatchTest(false);
509 }
510
511 // Ensures matches from (only) the default search provider respect any extra
512 // query params set on the command line.
513 TEST_F(AutocompleteProviderTest, ExtraQueryParams) {
514   ResetControllerWithKeywordAndSearchProviders();
515   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
516       switches::kExtraSearchQueryParams, "a=b");
517   RunExactKeymatchTest(true);
518   CopyResults();
519   ASSERT_EQ(2U, result_.size());
520   EXPECT_EQ("http://keyword/test",
521             result_.match_at(0)->destination_url.possibly_invalid_spec());
522   EXPECT_EQ("http://defaultturl/k%20test?a=b",
523             result_.match_at(1)->destination_url.possibly_invalid_spec());
524 }
525
526 // Test that redundant associated keywords are removed.
527 TEST_F(AutocompleteProviderTest, RedundantKeywordsIgnoredInResult) {
528   ResetControllerWithKeywordProvider();
529
530   {
531     KeywordTestData duplicate_url[] = {
532       { base::ASCIIToUTF16("fo"), base::string16(), false },
533       { base::ASCIIToUTF16("foo.com"), base::string16(), true },
534       { base::ASCIIToUTF16("foo.com"), base::string16(), false }
535     };
536
537     SCOPED_TRACE("Duplicate url");
538     RunRedundantKeywordTest(duplicate_url, ARRAYSIZE_UNSAFE(duplicate_url));
539   }
540
541   {
542     KeywordTestData keyword_match[] = {
543       { base::ASCIIToUTF16("foo.com"), base::ASCIIToUTF16("foo.com"), false },
544       { base::ASCIIToUTF16("foo.com"), base::string16(), false }
545     };
546
547     SCOPED_TRACE("Duplicate url with keyword match");
548     RunRedundantKeywordTest(keyword_match, ARRAYSIZE_UNSAFE(keyword_match));
549   }
550
551   {
552     KeywordTestData multiple_keyword[] = {
553       { base::ASCIIToUTF16("fo"), base::string16(), false },
554       { base::ASCIIToUTF16("foo.com"), base::string16(), true },
555       { base::ASCIIToUTF16("foo.com"), base::string16(), false },
556       { base::ASCIIToUTF16("bar.com"), base::string16(), true },
557     };
558
559     SCOPED_TRACE("Duplicate url with multiple keywords");
560     RunRedundantKeywordTest(multiple_keyword,
561         ARRAYSIZE_UNSAFE(multiple_keyword));
562   }
563 }
564
565 TEST_F(AutocompleteProviderTest, UpdateAssistedQueryStats) {
566   ResetControllerWithTestProviders(false, NULL, NULL);
567
568   {
569     AssistedQueryStatsTestData test_data[] = {
570       //  MSVC doesn't support zero-length arrays, so supply some dummy data.
571       { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, "" }
572     };
573     SCOPED_TRACE("No matches");
574     // Note: We pass 0 here to ignore the dummy data above.
575     RunAssistedQueryStatsTest(test_data, 0);
576   }
577
578   {
579     AssistedQueryStatsTestData test_data[] = {
580       { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, "chrome..69i57" }
581     };
582     SCOPED_TRACE("One match");
583     RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data));
584   }
585
586   {
587     AssistedQueryStatsTestData test_data[] = {
588       { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
589         "chrome..69i57j69i58j5l2j0l3j69i59" },
590       { AutocompleteMatchType::URL_WHAT_YOU_TYPED,
591         "chrome..69i57j69i58j5l2j0l3j69i59" },
592       { AutocompleteMatchType::NAVSUGGEST,
593         "chrome.2.69i57j69i58j5l2j0l3j69i59" },
594       { AutocompleteMatchType::NAVSUGGEST,
595         "chrome.3.69i57j69i58j5l2j0l3j69i59" },
596       { AutocompleteMatchType::SEARCH_SUGGEST,
597         "chrome.4.69i57j69i58j5l2j0l3j69i59" },
598       { AutocompleteMatchType::SEARCH_SUGGEST,
599         "chrome.5.69i57j69i58j5l2j0l3j69i59" },
600       { AutocompleteMatchType::SEARCH_SUGGEST,
601         "chrome.6.69i57j69i58j5l2j0l3j69i59" },
602       { AutocompleteMatchType::SEARCH_HISTORY,
603         "chrome.7.69i57j69i58j5l2j0l3j69i59" },
604     };
605     SCOPED_TRACE("Multiple matches");
606     RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data));
607   }
608 }
609
610 TEST_F(AutocompleteProviderTest, GetDestinationURL) {
611   ResetControllerWithKeywordAndSearchProviders();
612
613   // For the destination URL to have aqs parameters for query formulation time
614   // and the field trial triggered bit, many conditions need to be satisfied.
615   AutocompleteMatch match(NULL, 1100, false,
616                           AutocompleteMatchType::SEARCH_SUGGEST);
617   GURL url(GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456)));
618   EXPECT_TRUE(url.path().empty());
619
620   // The protocol needs to be https.
621   RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword),
622                       "https://aqs/{searchTerms}/{google:assistedQueryStats}");
623   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
624   EXPECT_TRUE(url.path().empty());
625
626   // There needs to be a keyword provider.
627   match.keyword = base::ASCIIToUTF16(kTestTemplateURLKeyword);
628   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
629   EXPECT_TRUE(url.path().empty());
630
631   // search_terms_args needs to be set.
632   match.search_terms_args.reset(
633       new TemplateURLRef::SearchTermsArgs(base::string16()));
634   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
635   EXPECT_TRUE(url.path().empty());
636
637   // assisted_query_stats needs to have been previously set.
638   match.search_terms_args->assisted_query_stats =
639       "chrome.0.69i57j69i58j5l2j0l3j69i59";
640   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
641   EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j0&", url.path());
642
643   // Test field trial triggered bit set.
644   controller_->search_provider_->field_trial_triggered_in_session_ = true;
645   EXPECT_TRUE(
646       controller_->search_provider_->field_trial_triggered_in_session());
647   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
648   EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j0&", url.path());
649
650   // Test page classification set.
651   controller_->input_.current_page_classification_ = AutocompleteInput::OTHER;
652   controller_->search_provider_->field_trial_triggered_in_session_ = false;
653   EXPECT_FALSE(
654       controller_->search_provider_->field_trial_triggered_in_session());
655   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
656   EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j4&", url.path());
657
658   // Test page classification and field trial triggered set.
659   controller_->search_provider_->field_trial_triggered_in_session_ = true;
660   EXPECT_TRUE(
661       controller_->search_provider_->field_trial_triggered_in_session());
662   url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
663   EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j4&", url.path());
664 }