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.
5 #include "components/omnibox/autocomplete_provider.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/chrome_autocomplete_scheme_classifier.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/search_engines/template_url_service_factory.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/metrics/proto/omnibox_event.pb.h"
22 #include "components/omnibox/autocomplete_input.h"
23 #include "components/omnibox/autocomplete_match.h"
24 #include "components/omnibox/autocomplete_provider_listener.h"
25 #include "components/omnibox/keyword_provider.h"
26 #include "components/omnibox/search_provider.h"
27 #include "components/search_engines/search_engines_switches.h"
28 #include "components/search_engines/template_url.h"
29 #include "components/search_engines/template_url_service.h"
30 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/notification_registrar.h"
32 #include "content/public/browser/notification_source.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 static std::ostream& operator<<(std::ostream& os,
36 const AutocompleteResult::const_iterator& it) {
37 return os << static_cast<const AutocompleteMatch*>(&(*it));
41 const size_t kResultsPerProvider = 3;
42 const char kTestTemplateURLKeyword[] = "t";
45 // Autocomplete provider that provides known results. Note that this is
46 // refcounted so that it can also be a task on the message loop.
47 class TestProvider : public AutocompleteProvider {
49 TestProvider(int relevance, const base::string16& prefix,
51 const base::string16 match_keyword)
52 : AutocompleteProvider(AutocompleteProvider::TYPE_SEARCH),
55 relevance_(relevance),
57 match_keyword_(match_keyword) {
60 virtual void Start(const AutocompleteInput& input,
61 bool minimal_changes) OVERRIDE;
63 void set_listener(AutocompleteProviderListener* listener) {
68 virtual ~TestProvider() {}
72 void AddResults(int start_at, int num);
73 void AddResultsWithSearchTermsArgs(
76 AutocompleteMatch::Type type,
77 const TemplateURLRef::SearchTermsArgs& search_terms_args);
79 AutocompleteProviderListener* listener_;
82 const base::string16 prefix_;
83 const base::string16 match_keyword_;
86 void TestProvider::Start(const AutocompleteInput& input,
87 bool minimal_changes) {
93 // Generate 4 results synchronously, the rest later.
95 AddResultsWithSearchTermsArgs(
96 1, 1, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
97 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("echo")));
98 AddResultsWithSearchTermsArgs(
99 2, 1, AutocompleteMatchType::NAVSUGGEST,
100 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("nav")));
101 AddResultsWithSearchTermsArgs(
102 3, 1, AutocompleteMatchType::SEARCH_SUGGEST,
103 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("query")));
105 if (input.want_asynchronous_matches()) {
107 base::MessageLoop::current()->PostTask(
108 FROM_HERE, base::Bind(&TestProvider::Run, this));
112 void TestProvider::Run() {
113 DCHECK_GT(kResultsPerProvider, 0U);
114 AddResults(1, kResultsPerProvider);
117 listener_->OnProviderUpdate(true);
120 void TestProvider::AddResults(int start_at, int num) {
121 AddResultsWithSearchTermsArgs(start_at,
123 AutocompleteMatchType::URL_WHAT_YOU_TYPED,
124 TemplateURLRef::SearchTermsArgs(
128 void TestProvider::AddResultsWithSearchTermsArgs(
131 AutocompleteMatch::Type type,
132 const TemplateURLRef::SearchTermsArgs& search_terms_args) {
133 for (int i = start_at; i < num; i++) {
134 AutocompleteMatch match(this, relevance_ - i, false, type);
136 match.fill_into_edit = prefix_ + base::UTF8ToUTF16(base::IntToString(i));
137 match.destination_url = GURL(base::UTF16ToUTF8(match.fill_into_edit));
138 match.allowed_to_be_default_match = true;
140 match.contents = match.fill_into_edit;
141 match.contents_class.push_back(
142 ACMatchClassification(0, ACMatchClassification::NONE));
143 match.description = match.fill_into_edit;
144 match.description_class.push_back(
145 ACMatchClassification(0, ACMatchClassification::NONE));
146 match.search_terms_args.reset(
147 new TemplateURLRef::SearchTermsArgs(search_terms_args));
148 if (!match_keyword_.empty()) {
149 match.keyword = match_keyword_;
150 TemplateURLService* service =
151 TemplateURLServiceFactory::GetForProfile(profile_);
152 ASSERT_TRUE(match.GetTemplateURL(service, false) != NULL);
155 matches_.push_back(match);
159 class AutocompleteProviderTest : public testing::Test,
160 public content::NotificationObserver {
162 struct KeywordTestData {
163 const base::string16 fill_into_edit;
164 const base::string16 keyword;
165 const base::string16 expected_associated_keyword;
168 struct AssistedQueryStatsTestData {
169 const AutocompleteMatch::Type match_type;
170 const std::string expected_aqs;
174 // Registers a test TemplateURL under the given keyword.
175 void RegisterTemplateURL(const base::string16 keyword,
176 const std::string& template_url);
178 // Resets |controller_| with two TestProviders. |provider1_ptr| and
179 // |provider2_ptr| are updated to point to the new providers if non-NULL.
180 void ResetControllerWithTestProviders(bool same_destinations,
181 TestProvider** provider1_ptr,
182 TestProvider** provider2_ptr);
184 // Runs a query on the input "a", and makes sure both providers' input is
185 // properly collected.
188 // Constructs an AutocompleteResult from |match_data|, sets the |controller_|
189 // to pretend it was running against input |input|, calls the |controller_|'s
190 // UpdateAssociatedKeywords, and checks that the matches have associated
191 // keywords as expected.
192 void RunKeywordTest(const base::string16& input,
193 const KeywordTestData* match_data,
196 void RunAssistedQueryStatsTest(
197 const AssistedQueryStatsTestData* aqs_test_data,
200 void RunQuery(const base::string16 query);
202 void ResetControllerWithKeywordAndSearchProviders();
203 void ResetControllerWithKeywordProvider();
204 void RunExactKeymatchTest(bool allow_exact_keyword_match);
208 // Returns match.destination_url as it would be set by
209 // AutocompleteController::UpdateMatchDestinationURL().
210 GURL GetDestinationURL(AutocompleteMatch match,
211 base::TimeDelta query_formulation_time) const;
213 AutocompleteResult result_;
214 scoped_ptr<AutocompleteController> controller_;
217 // content::NotificationObserver:
218 virtual void Observe(int type,
219 const content::NotificationSource& source,
220 const content::NotificationDetails& details) OVERRIDE;
222 base::MessageLoopForUI message_loop_;
223 content::NotificationRegistrar registrar_;
224 TestingProfile profile_;
227 void AutocompleteProviderTest::RegisterTemplateURL(
228 const base::string16 keyword,
229 const std::string& template_url) {
230 if (TemplateURLServiceFactory::GetForProfile(&profile_) == NULL) {
231 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
232 &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
234 TemplateURLData data;
235 data.SetURL(template_url);
236 data.SetKeyword(keyword);
237 TemplateURL* default_t_url = new TemplateURL(data);
238 TemplateURLService* turl_model =
239 TemplateURLServiceFactory::GetForProfile(&profile_);
240 turl_model->Add(default_t_url);
241 turl_model->SetUserSelectedDefaultSearchProvider(default_t_url);
243 TemplateURLID default_provider_id = default_t_url->id();
244 ASSERT_NE(0, default_provider_id);
247 void AutocompleteProviderTest::ResetControllerWithTestProviders(
248 bool same_destinations,
249 TestProvider** provider1_ptr,
250 TestProvider** provider2_ptr) {
251 // TODO: Move it outside this method, after refactoring the existing
252 // unit tests. Specifically:
253 // (1) Make sure that AutocompleteMatch.keyword is set iff there is
254 // a corresponding call to RegisterTemplateURL; otherwise the
255 // controller flow will crash; this practically means that
256 // RunTests/ResetControllerXXX/RegisterTemplateURL should
257 // be coordinated with each other.
258 // (2) Inject test arguments rather than rely on the hardcoded values, e.g.
259 // don't rely on kResultsPerProvided and default relevance ordering
261 RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword),
262 "http://aqs/{searchTerms}/{google:assistedQueryStats}");
264 AutocompleteController::Providers providers;
266 // Construct two new providers, with either the same or different prefixes.
267 TestProvider* provider1 = new TestProvider(
269 base::ASCIIToUTF16("http://a"),
271 base::ASCIIToUTF16(kTestTemplateURLKeyword));
272 providers.push_back(provider1);
274 TestProvider* provider2 = new TestProvider(
275 kResultsPerProvider * 2,
276 same_destinations ? base::ASCIIToUTF16("http://a")
277 : base::ASCIIToUTF16("http://b"),
280 providers.push_back(provider2);
282 // Reset the controller to contain our new providers.
283 controller_.reset(new AutocompleteController(
284 &profile_, TemplateURLServiceFactory::GetForProfile(&profile_), NULL, 0));
285 // We're going to swap the providers vector, but the old vector should be
286 // empty so no elements need to be freed at this point.
287 EXPECT_TRUE(controller_->providers_.empty());
288 controller_->providers_.swap(providers);
289 provider1->set_listener(controller_.get());
290 provider2->set_listener(controller_.get());
292 // The providers don't complete synchronously, so listen for "result updated"
295 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
296 content::Source<AutocompleteController>(controller_.get()));
299 *provider1_ptr = provider1;
301 *provider2_ptr = provider2;
304 void AutocompleteProviderTest::
305 ResetControllerWithKeywordAndSearchProviders() {
306 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
307 &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
309 // Reset the default TemplateURL.
310 TemplateURLData data;
311 data.SetURL("http://defaultturl/{searchTerms}");
312 TemplateURL* default_t_url = new TemplateURL(data);
313 TemplateURLService* turl_model =
314 TemplateURLServiceFactory::GetForProfile(&profile_);
315 turl_model->Add(default_t_url);
316 turl_model->SetUserSelectedDefaultSearchProvider(default_t_url);
317 TemplateURLID default_provider_id = default_t_url->id();
318 ASSERT_NE(0, default_provider_id);
320 // Create another TemplateURL for KeywordProvider.
321 TemplateURLData data2;
322 data2.short_name = base::ASCIIToUTF16("k");
323 data2.SetKeyword(base::ASCIIToUTF16("k"));
324 data2.SetURL("http://keyword/{searchTerms}");
325 TemplateURL* keyword_t_url = new TemplateURL(data2);
326 turl_model->Add(keyword_t_url);
327 ASSERT_NE(0, keyword_t_url->id());
329 controller_.reset(new AutocompleteController(
330 &profile_, TemplateURLServiceFactory::GetForProfile(&profile_), NULL,
331 AutocompleteProvider::TYPE_KEYWORD | AutocompleteProvider::TYPE_SEARCH));
334 void AutocompleteProviderTest::ResetControllerWithKeywordProvider() {
335 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
336 &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
338 TemplateURLService* turl_model =
339 TemplateURLServiceFactory::GetForProfile(&profile_);
341 // Create a TemplateURL for KeywordProvider.
342 TemplateURLData data;
343 data.short_name = base::ASCIIToUTF16("foo.com");
344 data.SetKeyword(base::ASCIIToUTF16("foo.com"));
345 data.SetURL("http://foo.com/{searchTerms}");
346 TemplateURL* keyword_t_url = new TemplateURL(data);
347 turl_model->Add(keyword_t_url);
348 ASSERT_NE(0, keyword_t_url->id());
350 // Make a TemplateURL for KeywordProvider that a shorter version of the
352 data.short_name = base::ASCIIToUTF16("f");
353 data.SetKeyword(base::ASCIIToUTF16("f"));
354 data.SetURL("http://f.com/{searchTerms}");
355 keyword_t_url = new TemplateURL(data);
356 turl_model->Add(keyword_t_url);
357 ASSERT_NE(0, keyword_t_url->id());
359 // Create another TemplateURL for KeywordProvider.
360 data.short_name = base::ASCIIToUTF16("bar.com");
361 data.SetKeyword(base::ASCIIToUTF16("bar.com"));
362 data.SetURL("http://bar.com/{searchTerms}");
363 keyword_t_url = new TemplateURL(data);
364 turl_model->Add(keyword_t_url);
365 ASSERT_NE(0, keyword_t_url->id());
367 controller_.reset(new AutocompleteController(
368 &profile_, TemplateURLServiceFactory::GetForProfile(&profile_), NULL,
369 AutocompleteProvider::TYPE_KEYWORD));
372 void AutocompleteProviderTest::RunTest() {
373 RunQuery(base::ASCIIToUTF16("a"));
376 void AutocompleteProviderTest::RunKeywordTest(const base::string16& input,
377 const KeywordTestData* match_data,
380 for (size_t i = 0; i < size; ++i) {
381 AutocompleteMatch match;
382 match.relevance = 1000; // Arbitrary non-zero value.
383 match.allowed_to_be_default_match = true;
384 match.fill_into_edit = match_data[i].fill_into_edit;
385 match.transition = ui::PAGE_TRANSITION_KEYWORD;
386 match.keyword = match_data[i].keyword;
387 matches.push_back(match);
390 AutocompleteResult result;
391 result.AppendMatches(matches);
392 controller_->input_ = AutocompleteInput(
393 input, base::string16::npos, base::string16(), GURL(),
394 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS,
395 false, true, true, true, ChromeAutocompleteSchemeClassifier(&profile_));
396 controller_->UpdateAssociatedKeywords(&result);
398 for (size_t j = 0; j < result.size(); ++j) {
399 EXPECT_EQ(match_data[j].expected_associated_keyword,
400 result.match_at(j)->associated_keyword.get() ?
401 result.match_at(j)->associated_keyword->keyword :
406 void AutocompleteProviderTest::RunAssistedQueryStatsTest(
407 const AssistedQueryStatsTestData* aqs_test_data,
410 const size_t kMaxRelevance = 1000;
412 for (size_t i = 0; i < size; ++i) {
413 AutocompleteMatch match(NULL, kMaxRelevance - i, false,
414 aqs_test_data[i].match_type);
415 match.allowed_to_be_default_match = true;
416 match.keyword = base::ASCIIToUTF16(kTestTemplateURLKeyword);
417 match.search_terms_args.reset(
418 new TemplateURLRef::SearchTermsArgs(base::string16()));
419 matches.push_back(match);
422 result_.AppendMatches(matches);
425 controller_->UpdateAssistedQueryStats(&result_);
428 for (size_t i = 0; i < size; ++i) {
429 EXPECT_EQ(aqs_test_data[i].expected_aqs,
430 result_.match_at(i)->search_terms_args->assisted_query_stats);
434 void AutocompleteProviderTest::RunQuery(const base::string16 query) {
436 controller_->Start(AutocompleteInput(
437 query, base::string16::npos, base::string16(), GURL(),
438 metrics::OmniboxEventProto::INVALID_SPEC, true, false, true, true,
439 ChromeAutocompleteSchemeClassifier(&profile_)));
441 if (!controller_->done())
442 // The message loop will terminate when all autocomplete input has been
444 base::MessageLoop::current()->Run();
447 void AutocompleteProviderTest::RunExactKeymatchTest(
448 bool allow_exact_keyword_match) {
449 // Send the controller input which exactly matches the keyword provider we
450 // created in ResetControllerWithKeywordAndSearchProviders(). The default
451 // match should thus be a search-other-engine match iff
452 // |allow_exact_keyword_match| is true. Regardless, the match should
453 // be from SearchProvider. (It provides all verbatim search matches,
455 controller_->Start(AutocompleteInput(
456 base::ASCIIToUTF16("k test"), base::string16::npos, base::string16(),
457 GURL(), metrics::OmniboxEventProto::INVALID_SPEC, true, false,
458 allow_exact_keyword_match, false,
459 ChromeAutocompleteSchemeClassifier(&profile_)));
460 EXPECT_TRUE(controller_->done());
461 EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH,
462 controller_->result().default_match()->provider->type());
463 EXPECT_EQ(allow_exact_keyword_match ?
464 AutocompleteMatchType::SEARCH_OTHER_ENGINE :
465 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
466 controller_->result().default_match()->type);
469 void AutocompleteProviderTest::CopyResults() {
470 result_.CopyFrom(controller_->result());
473 GURL AutocompleteProviderTest::GetDestinationURL(
474 AutocompleteMatch match,
475 base::TimeDelta query_formulation_time) const {
476 controller_->UpdateMatchDestinationURLWithQueryFormulationTime(
477 query_formulation_time, &match);
478 return match.destination_url;
481 void AutocompleteProviderTest::Observe(
483 const content::NotificationSource& source,
484 const content::NotificationDetails& details) {
485 if (controller_->done()) {
487 base::MessageLoop::current()->Quit();
491 // Tests that the default selection is set properly when updating results.
492 TEST_F(AutocompleteProviderTest, Query) {
493 TestProvider* provider1 = NULL;
494 TestProvider* provider2 = NULL;
495 ResetControllerWithTestProviders(false, &provider1, &provider2);
498 // Make sure the default match gets set to the highest relevance match. The
499 // highest relevance matches should come from the second provider.
500 EXPECT_EQ(kResultsPerProvider * 2, result_.size());
501 ASSERT_NE(result_.end(), result_.default_match());
502 EXPECT_EQ(provider2, result_.default_match()->provider);
505 // Tests assisted query stats.
506 TEST_F(AutocompleteProviderTest, AssistedQueryStats) {
507 ResetControllerWithTestProviders(false, NULL, NULL);
510 ASSERT_EQ(kResultsPerProvider * 2, result_.size());
512 // Now, check the results from the second provider, as they should not have
513 // assisted query stats set.
514 for (size_t i = 0; i < kResultsPerProvider; ++i) {
516 result_.match_at(i)->search_terms_args->assisted_query_stats.empty());
518 // The first provider has a test keyword, so AQS should be non-empty.
519 for (size_t i = kResultsPerProvider; i < kResultsPerProvider * 2; ++i) {
521 result_.match_at(i)->search_terms_args->assisted_query_stats.empty());
525 TEST_F(AutocompleteProviderTest, RemoveDuplicates) {
526 TestProvider* provider1 = NULL;
527 TestProvider* provider2 = NULL;
528 ResetControllerWithTestProviders(true, &provider1, &provider2);
531 // Make sure all the first provider's results were eliminated by the second
533 EXPECT_EQ(kResultsPerProvider, result_.size());
534 for (AutocompleteResult::const_iterator i(result_.begin());
535 i != result_.end(); ++i)
536 EXPECT_EQ(provider2, i->provider);
539 TEST_F(AutocompleteProviderTest, AllowExactKeywordMatch) {
540 ResetControllerWithKeywordAndSearchProviders();
541 RunExactKeymatchTest(true);
542 RunExactKeymatchTest(false);
545 // Ensures matches from (only) the default search provider respect any extra
546 // query params set on the command line.
547 TEST_F(AutocompleteProviderTest, ExtraQueryParams) {
548 ResetControllerWithKeywordAndSearchProviders();
549 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
550 switches::kExtraSearchQueryParams, "a=b");
551 RunExactKeymatchTest(true);
553 ASSERT_EQ(2U, result_.size());
554 EXPECT_EQ("http://keyword/test",
555 result_.match_at(0)->destination_url.possibly_invalid_spec());
556 EXPECT_EQ("http://defaultturl/k%20test?a=b",
557 result_.match_at(1)->destination_url.possibly_invalid_spec());
560 // Test that redundant associated keywords are removed.
561 TEST_F(AutocompleteProviderTest, RedundantKeywordsIgnoredInResult) {
562 ResetControllerWithKeywordProvider();
565 KeywordTestData duplicate_url[] = {
566 { base::ASCIIToUTF16("fo"), base::string16(), base::string16() },
567 { base::ASCIIToUTF16("foo.com"), base::string16(),
568 base::ASCIIToUTF16("foo.com") },
569 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() }
572 SCOPED_TRACE("Duplicate url");
573 RunKeywordTest(base::ASCIIToUTF16("fo"), duplicate_url,
574 ARRAYSIZE_UNSAFE(duplicate_url));
578 KeywordTestData keyword_match[] = {
579 { base::ASCIIToUTF16("foo.com"), base::ASCIIToUTF16("foo.com"),
581 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() }
584 SCOPED_TRACE("Duplicate url with keyword match");
585 RunKeywordTest(base::ASCIIToUTF16("fo"), keyword_match,
586 ARRAYSIZE_UNSAFE(keyword_match));
590 KeywordTestData multiple_keyword[] = {
591 { base::ASCIIToUTF16("fo"), base::string16(), base::string16() },
592 { base::ASCIIToUTF16("foo.com"), base::string16(),
593 base::ASCIIToUTF16("foo.com") },
594 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() },
595 { base::ASCIIToUTF16("bar.com"), base::string16(),
596 base::ASCIIToUTF16("bar.com") },
599 SCOPED_TRACE("Duplicate url with multiple keywords");
600 RunKeywordTest(base::ASCIIToUTF16("fo"), multiple_keyword,
601 ARRAYSIZE_UNSAFE(multiple_keyword));
605 // Test that exact match keywords trump keywords associated with
607 TEST_F(AutocompleteProviderTest, ExactMatchKeywords) {
608 ResetControllerWithKeywordProvider();
611 KeywordTestData keyword_match[] = {
612 { base::ASCIIToUTF16("foo.com"), base::string16(),
613 base::ASCIIToUTF16("foo.com") }
616 SCOPED_TRACE("keyword match as usual");
617 RunKeywordTest(base::ASCIIToUTF16("fo"), keyword_match,
618 ARRAYSIZE_UNSAFE(keyword_match));
621 // The same result set with an input of "f" (versus "fo") should get
622 // a different associated keyword because "f" is an exact match for
623 // a keyword and that should trump the keyword normally associated with
626 KeywordTestData keyword_match[] = {
627 { base::ASCIIToUTF16("foo.com"), base::string16(),
628 base::ASCIIToUTF16("f") }
631 SCOPED_TRACE("keyword exact match");
632 RunKeywordTest(base::ASCIIToUTF16("f"), keyword_match,
633 ARRAYSIZE_UNSAFE(keyword_match));
637 TEST_F(AutocompleteProviderTest, UpdateAssistedQueryStats) {
638 ResetControllerWithTestProviders(false, NULL, NULL);
641 AssistedQueryStatsTestData test_data[] = {
642 // MSVC doesn't support zero-length arrays, so supply some dummy data.
643 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, "" }
645 SCOPED_TRACE("No matches");
646 // Note: We pass 0 here to ignore the dummy data above.
647 RunAssistedQueryStatsTest(test_data, 0);
651 AssistedQueryStatsTestData test_data[] = {
652 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, "chrome..69i57" }
654 SCOPED_TRACE("One match");
655 RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data));
659 AssistedQueryStatsTestData test_data[] = {
660 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
661 "chrome..69i57j69i58j5l2j0l3j69i59" },
662 { AutocompleteMatchType::URL_WHAT_YOU_TYPED,
663 "chrome..69i57j69i58j5l2j0l3j69i59" },
664 { AutocompleteMatchType::NAVSUGGEST,
665 "chrome.2.69i57j69i58j5l2j0l3j69i59" },
666 { AutocompleteMatchType::NAVSUGGEST,
667 "chrome.3.69i57j69i58j5l2j0l3j69i59" },
668 { AutocompleteMatchType::SEARCH_SUGGEST,
669 "chrome.4.69i57j69i58j5l2j0l3j69i59" },
670 { AutocompleteMatchType::SEARCH_SUGGEST,
671 "chrome.5.69i57j69i58j5l2j0l3j69i59" },
672 { AutocompleteMatchType::SEARCH_SUGGEST,
673 "chrome.6.69i57j69i58j5l2j0l3j69i59" },
674 { AutocompleteMatchType::SEARCH_HISTORY,
675 "chrome.7.69i57j69i58j5l2j0l3j69i59" },
677 SCOPED_TRACE("Multiple matches");
678 RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data));
682 TEST_F(AutocompleteProviderTest, GetDestinationURL) {
683 ResetControllerWithKeywordAndSearchProviders();
685 // For the destination URL to have aqs parameters for query formulation time
686 // and the field trial triggered bit, many conditions need to be satisfied.
687 AutocompleteMatch match(NULL, 1100, false,
688 AutocompleteMatchType::SEARCH_SUGGEST);
689 GURL url(GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456)));
690 EXPECT_TRUE(url.path().empty());
692 // The protocol needs to be https.
693 RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword),
694 "https://aqs/{searchTerms}/{google:assistedQueryStats}");
695 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
696 EXPECT_TRUE(url.path().empty());
698 // There needs to be a keyword provider.
699 match.keyword = base::ASCIIToUTF16(kTestTemplateURLKeyword);
700 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
701 EXPECT_TRUE(url.path().empty());
703 // search_terms_args needs to be set.
704 match.search_terms_args.reset(
705 new TemplateURLRef::SearchTermsArgs(base::string16()));
706 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
707 EXPECT_TRUE(url.path().empty());
709 // assisted_query_stats needs to have been previously set.
710 match.search_terms_args->assisted_query_stats =
711 "chrome.0.69i57j69i58j5l2j0l3j69i59";
712 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
713 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j0&", url.path());
715 // Test field trial triggered bit set.
716 controller_->search_provider_->field_trial_triggered_in_session_ = true;
718 controller_->search_provider_->field_trial_triggered_in_session());
719 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
720 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j0&", url.path());
722 // Test page classification set.
723 controller_->input_.current_page_classification_ =
724 metrics::OmniboxEventProto::OTHER;
725 controller_->search_provider_->field_trial_triggered_in_session_ = false;
727 controller_->search_provider_->field_trial_triggered_in_session());
728 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
729 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j4&", url.path());
731 // Test page classification and field trial triggered set.
732 controller_->search_provider_->field_trial_triggered_in_session_ = true;
734 controller_->search_provider_->field_trial_triggered_in_session());
735 url = GetDestinationURL(match, base::TimeDelta::FromMilliseconds(2456));
736 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j4&", url.path());