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 void Start(const AutocompleteInput
& input
, bool minimal_changes
) override
;
62 void set_listener(AutocompleteProviderListener
* listener
) {
67 ~TestProvider() override
{}
71 void AddResults(int start_at
, int num
);
72 void AddResultsWithSearchTermsArgs(
75 AutocompleteMatch::Type type
,
76 const TemplateURLRef::SearchTermsArgs
& search_terms_args
);
78 AutocompleteProviderListener
* listener_
;
81 const base::string16 prefix_
;
82 const base::string16 match_keyword_
;
85 void TestProvider::Start(const AutocompleteInput
& input
,
86 bool minimal_changes
) {
92 // Generate 4 results synchronously, the rest later.
94 AddResultsWithSearchTermsArgs(
95 1, 1, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
,
96 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("echo")));
97 AddResultsWithSearchTermsArgs(
98 2, 1, AutocompleteMatchType::NAVSUGGEST
,
99 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("nav")));
100 AddResultsWithSearchTermsArgs(
101 3, 1, AutocompleteMatchType::SEARCH_SUGGEST
,
102 TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("query")));
104 if (input
.want_asynchronous_matches()) {
106 base::MessageLoop::current()->PostTask(
107 FROM_HERE
, base::Bind(&TestProvider::Run
, this));
111 void TestProvider::Run() {
112 DCHECK_GT(kResultsPerProvider
, 0U);
113 AddResults(1, kResultsPerProvider
);
116 listener_
->OnProviderUpdate(true);
119 void TestProvider::AddResults(int start_at
, int num
) {
120 AddResultsWithSearchTermsArgs(start_at
,
122 AutocompleteMatchType::URL_WHAT_YOU_TYPED
,
123 TemplateURLRef::SearchTermsArgs(
127 void TestProvider::AddResultsWithSearchTermsArgs(
130 AutocompleteMatch::Type type
,
131 const TemplateURLRef::SearchTermsArgs
& search_terms_args
) {
132 for (int i
= start_at
; i
< num
; i
++) {
133 AutocompleteMatch
match(this, relevance_
- i
, false, type
);
135 match
.fill_into_edit
= prefix_
+ base::UTF8ToUTF16(base::IntToString(i
));
136 match
.destination_url
= GURL(base::UTF16ToUTF8(match
.fill_into_edit
));
137 match
.allowed_to_be_default_match
= true;
139 match
.contents
= match
.fill_into_edit
;
140 match
.contents_class
.push_back(
141 ACMatchClassification(0, ACMatchClassification::NONE
));
142 match
.description
= match
.fill_into_edit
;
143 match
.description_class
.push_back(
144 ACMatchClassification(0, ACMatchClassification::NONE
));
145 match
.search_terms_args
.reset(
146 new TemplateURLRef::SearchTermsArgs(search_terms_args
));
147 if (!match_keyword_
.empty()) {
148 match
.keyword
= match_keyword_
;
149 TemplateURLService
* service
=
150 TemplateURLServiceFactory::GetForProfile(profile_
);
151 ASSERT_TRUE(match
.GetTemplateURL(service
, false) != NULL
);
154 matches_
.push_back(match
);
158 class AutocompleteProviderTest
: public testing::Test
,
159 public content::NotificationObserver
{
161 struct KeywordTestData
{
162 const base::string16 fill_into_edit
;
163 const base::string16 keyword
;
164 const base::string16 expected_associated_keyword
;
167 struct AssistedQueryStatsTestData
{
168 const AutocompleteMatch::Type match_type
;
169 const std::string expected_aqs
;
173 // Registers a test TemplateURL under the given keyword.
174 void RegisterTemplateURL(const base::string16 keyword
,
175 const std::string
& template_url
);
177 // Resets |controller_| with two TestProviders. |provider1_ptr| and
178 // |provider2_ptr| are updated to point to the new providers if non-NULL.
179 void ResetControllerWithTestProviders(bool same_destinations
,
180 TestProvider
** provider1_ptr
,
181 TestProvider
** provider2_ptr
);
183 // Runs a query on the input "a", and makes sure both providers' input is
184 // properly collected.
187 // Constructs an AutocompleteResult from |match_data|, sets the |controller_|
188 // to pretend it was running against input |input|, calls the |controller_|'s
189 // UpdateAssociatedKeywords, and checks that the matches have associated
190 // keywords as expected.
191 void RunKeywordTest(const base::string16
& input
,
192 const KeywordTestData
* match_data
,
195 void RunAssistedQueryStatsTest(
196 const AssistedQueryStatsTestData
* aqs_test_data
,
199 void RunQuery(const base::string16 query
);
201 void ResetControllerWithKeywordAndSearchProviders();
202 void ResetControllerWithKeywordProvider();
203 void RunExactKeymatchTest(bool allow_exact_keyword_match
);
207 // Returns match.destination_url as it would be set by
208 // AutocompleteController::UpdateMatchDestinationURL().
209 GURL
GetDestinationURL(AutocompleteMatch match
,
210 base::TimeDelta query_formulation_time
) const;
212 AutocompleteResult result_
;
213 scoped_ptr
<AutocompleteController
> controller_
;
216 // content::NotificationObserver:
217 void Observe(int type
,
218 const content::NotificationSource
& source
,
219 const content::NotificationDetails
& details
) override
;
221 base::MessageLoopForUI message_loop_
;
222 content::NotificationRegistrar registrar_
;
223 TestingProfile profile_
;
226 void AutocompleteProviderTest::RegisterTemplateURL(
227 const base::string16 keyword
,
228 const std::string
& template_url
) {
229 if (TemplateURLServiceFactory::GetForProfile(&profile_
) == NULL
) {
230 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
231 &profile_
, &TemplateURLServiceFactory::BuildInstanceFor
);
233 TemplateURLData data
;
234 data
.SetURL(template_url
);
235 data
.SetKeyword(keyword
);
236 TemplateURL
* default_t_url
= new TemplateURL(data
);
237 TemplateURLService
* turl_model
=
238 TemplateURLServiceFactory::GetForProfile(&profile_
);
239 turl_model
->Add(default_t_url
);
240 turl_model
->SetUserSelectedDefaultSearchProvider(default_t_url
);
242 TemplateURLID default_provider_id
= default_t_url
->id();
243 ASSERT_NE(0, default_provider_id
);
246 void AutocompleteProviderTest::ResetControllerWithTestProviders(
247 bool same_destinations
,
248 TestProvider
** provider1_ptr
,
249 TestProvider
** provider2_ptr
) {
250 // TODO: Move it outside this method, after refactoring the existing
251 // unit tests. Specifically:
252 // (1) Make sure that AutocompleteMatch.keyword is set iff there is
253 // a corresponding call to RegisterTemplateURL; otherwise the
254 // controller flow will crash; this practically means that
255 // RunTests/ResetControllerXXX/RegisterTemplateURL should
256 // be coordinated with each other.
257 // (2) Inject test arguments rather than rely on the hardcoded values, e.g.
258 // don't rely on kResultsPerProvided and default relevance ordering
260 RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword
),
261 "http://aqs/{searchTerms}/{google:assistedQueryStats}");
263 AutocompleteController::Providers providers
;
265 // Construct two new providers, with either the same or different prefixes.
266 TestProvider
* provider1
= new TestProvider(
268 base::ASCIIToUTF16("http://a"),
270 base::ASCIIToUTF16(kTestTemplateURLKeyword
));
271 providers
.push_back(provider1
);
273 TestProvider
* provider2
= new TestProvider(
274 kResultsPerProvider
* 2,
275 same_destinations
? base::ASCIIToUTF16("http://a")
276 : base::ASCIIToUTF16("http://b"),
279 providers
.push_back(provider2
);
281 // Reset the controller to contain our new providers.
282 controller_
.reset(new AutocompleteController(
283 &profile_
, TemplateURLServiceFactory::GetForProfile(&profile_
), NULL
, 0));
284 // We're going to swap the providers vector, but the old vector should be
285 // empty so no elements need to be freed at this point.
286 EXPECT_TRUE(controller_
->providers_
.empty());
287 controller_
->providers_
.swap(providers
);
288 provider1
->set_listener(controller_
.get());
289 provider2
->set_listener(controller_
.get());
291 // The providers don't complete synchronously, so listen for "result updated"
294 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY
,
295 content::Source
<AutocompleteController
>(controller_
.get()));
298 *provider1_ptr
= provider1
;
300 *provider2_ptr
= provider2
;
303 void AutocompleteProviderTest::
304 ResetControllerWithKeywordAndSearchProviders() {
305 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
306 &profile_
, &TemplateURLServiceFactory::BuildInstanceFor
);
308 // Reset the default TemplateURL.
309 TemplateURLData data
;
310 data
.SetURL("http://defaultturl/{searchTerms}");
311 TemplateURL
* default_t_url
= new TemplateURL(data
);
312 TemplateURLService
* turl_model
=
313 TemplateURLServiceFactory::GetForProfile(&profile_
);
314 turl_model
->Add(default_t_url
);
315 turl_model
->SetUserSelectedDefaultSearchProvider(default_t_url
);
316 TemplateURLID default_provider_id
= default_t_url
->id();
317 ASSERT_NE(0, default_provider_id
);
319 // Create another TemplateURL for KeywordProvider.
320 TemplateURLData data2
;
321 data2
.short_name
= base::ASCIIToUTF16("k");
322 data2
.SetKeyword(base::ASCIIToUTF16("k"));
323 data2
.SetURL("http://keyword/{searchTerms}");
324 TemplateURL
* keyword_t_url
= new TemplateURL(data2
);
325 turl_model
->Add(keyword_t_url
);
326 ASSERT_NE(0, keyword_t_url
->id());
328 controller_
.reset(new AutocompleteController(
329 &profile_
, TemplateURLServiceFactory::GetForProfile(&profile_
), NULL
,
330 AutocompleteProvider::TYPE_KEYWORD
| AutocompleteProvider::TYPE_SEARCH
));
333 void AutocompleteProviderTest::ResetControllerWithKeywordProvider() {
334 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
335 &profile_
, &TemplateURLServiceFactory::BuildInstanceFor
);
337 TemplateURLService
* turl_model
=
338 TemplateURLServiceFactory::GetForProfile(&profile_
);
340 // Create a TemplateURL for KeywordProvider.
341 TemplateURLData data
;
342 data
.short_name
= base::ASCIIToUTF16("foo.com");
343 data
.SetKeyword(base::ASCIIToUTF16("foo.com"));
344 data
.SetURL("http://foo.com/{searchTerms}");
345 TemplateURL
* keyword_t_url
= new TemplateURL(data
);
346 turl_model
->Add(keyword_t_url
);
347 ASSERT_NE(0, keyword_t_url
->id());
349 // Make a TemplateURL for KeywordProvider that a shorter version of the
351 data
.short_name
= base::ASCIIToUTF16("f");
352 data
.SetKeyword(base::ASCIIToUTF16("f"));
353 data
.SetURL("http://f.com/{searchTerms}");
354 keyword_t_url
= new TemplateURL(data
);
355 turl_model
->Add(keyword_t_url
);
356 ASSERT_NE(0, keyword_t_url
->id());
358 // Create another TemplateURL for KeywordProvider.
359 data
.short_name
= base::ASCIIToUTF16("bar.com");
360 data
.SetKeyword(base::ASCIIToUTF16("bar.com"));
361 data
.SetURL("http://bar.com/{searchTerms}");
362 keyword_t_url
= new TemplateURL(data
);
363 turl_model
->Add(keyword_t_url
);
364 ASSERT_NE(0, keyword_t_url
->id());
366 controller_
.reset(new AutocompleteController(
367 &profile_
, TemplateURLServiceFactory::GetForProfile(&profile_
), NULL
,
368 AutocompleteProvider::TYPE_KEYWORD
));
371 void AutocompleteProviderTest::RunTest() {
372 RunQuery(base::ASCIIToUTF16("a"));
375 void AutocompleteProviderTest::RunKeywordTest(const base::string16
& input
,
376 const KeywordTestData
* match_data
,
379 for (size_t i
= 0; i
< size
; ++i
) {
380 AutocompleteMatch match
;
381 match
.relevance
= 1000; // Arbitrary non-zero value.
382 match
.allowed_to_be_default_match
= true;
383 match
.fill_into_edit
= match_data
[i
].fill_into_edit
;
384 match
.transition
= ui::PAGE_TRANSITION_KEYWORD
;
385 match
.keyword
= match_data
[i
].keyword
;
386 matches
.push_back(match
);
389 AutocompleteResult result
;
390 result
.AppendMatches(matches
);
391 controller_
->input_
= AutocompleteInput(
392 input
, base::string16::npos
, std::string(), GURL(),
393 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS
,
394 false, true, true, true, ChromeAutocompleteSchemeClassifier(&profile_
));
395 controller_
->UpdateAssociatedKeywords(&result
);
397 for (size_t j
= 0; j
< result
.size(); ++j
) {
398 EXPECT_EQ(match_data
[j
].expected_associated_keyword
,
399 result
.match_at(j
)->associated_keyword
.get() ?
400 result
.match_at(j
)->associated_keyword
->keyword
:
405 void AutocompleteProviderTest::RunAssistedQueryStatsTest(
406 const AssistedQueryStatsTestData
* aqs_test_data
,
409 const size_t kMaxRelevance
= 1000;
411 for (size_t i
= 0; i
< size
; ++i
) {
412 AutocompleteMatch
match(NULL
, kMaxRelevance
- i
, false,
413 aqs_test_data
[i
].match_type
);
414 match
.allowed_to_be_default_match
= true;
415 match
.keyword
= base::ASCIIToUTF16(kTestTemplateURLKeyword
);
416 match
.search_terms_args
.reset(
417 new TemplateURLRef::SearchTermsArgs(base::string16()));
418 matches
.push_back(match
);
421 result_
.AppendMatches(matches
);
424 controller_
->UpdateAssistedQueryStats(&result_
);
427 for (size_t i
= 0; i
< size
; ++i
) {
428 EXPECT_EQ(aqs_test_data
[i
].expected_aqs
,
429 result_
.match_at(i
)->search_terms_args
->assisted_query_stats
);
433 void AutocompleteProviderTest::RunQuery(const base::string16 query
) {
435 controller_
->Start(AutocompleteInput(
436 query
, base::string16::npos
, std::string(), GURL(),
437 metrics::OmniboxEventProto::INVALID_SPEC
, true, false, true, true,
438 ChromeAutocompleteSchemeClassifier(&profile_
)));
440 if (!controller_
->done())
441 // The message loop will terminate when all autocomplete input has been
443 base::MessageLoop::current()->Run();
446 void AutocompleteProviderTest::RunExactKeymatchTest(
447 bool allow_exact_keyword_match
) {
448 // Send the controller input which exactly matches the keyword provider we
449 // created in ResetControllerWithKeywordAndSearchProviders(). The default
450 // match should thus be a search-other-engine match iff
451 // |allow_exact_keyword_match| is true. Regardless, the match should
452 // be from SearchProvider. (It provides all verbatim search matches,
454 controller_
->Start(AutocompleteInput(
455 base::ASCIIToUTF16("k test"), base::string16::npos
, std::string(), GURL(),
456 metrics::OmniboxEventProto::INVALID_SPEC
, true, false,
457 allow_exact_keyword_match
, false,
458 ChromeAutocompleteSchemeClassifier(&profile_
)));
459 EXPECT_TRUE(controller_
->done());
460 EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH
,
461 controller_
->result().default_match()->provider
->type());
462 EXPECT_EQ(allow_exact_keyword_match
?
463 AutocompleteMatchType::SEARCH_OTHER_ENGINE
:
464 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
,
465 controller_
->result().default_match()->type
);
468 void AutocompleteProviderTest::CopyResults() {
469 result_
.CopyFrom(controller_
->result());
472 GURL
AutocompleteProviderTest::GetDestinationURL(
473 AutocompleteMatch match
,
474 base::TimeDelta query_formulation_time
) const {
475 controller_
->UpdateMatchDestinationURLWithQueryFormulationTime(
476 query_formulation_time
, &match
);
477 return match
.destination_url
;
480 void AutocompleteProviderTest::Observe(
482 const content::NotificationSource
& source
,
483 const content::NotificationDetails
& details
) {
484 if (controller_
->done()) {
486 base::MessageLoop::current()->Quit();
490 // Tests that the default selection is set properly when updating results.
491 TEST_F(AutocompleteProviderTest
, Query
) {
492 TestProvider
* provider1
= NULL
;
493 TestProvider
* provider2
= NULL
;
494 ResetControllerWithTestProviders(false, &provider1
, &provider2
);
497 // Make sure the default match gets set to the highest relevance match. The
498 // highest relevance matches should come from the second provider.
499 EXPECT_EQ(kResultsPerProvider
* 2, result_
.size());
500 ASSERT_NE(result_
.end(), result_
.default_match());
501 EXPECT_EQ(provider2
, result_
.default_match()->provider
);
504 // Tests assisted query stats.
505 TEST_F(AutocompleteProviderTest
, AssistedQueryStats
) {
506 ResetControllerWithTestProviders(false, NULL
, NULL
);
509 ASSERT_EQ(kResultsPerProvider
* 2, result_
.size());
511 // Now, check the results from the second provider, as they should not have
512 // assisted query stats set.
513 for (size_t i
= 0; i
< kResultsPerProvider
; ++i
) {
515 result_
.match_at(i
)->search_terms_args
->assisted_query_stats
.empty());
517 // The first provider has a test keyword, so AQS should be non-empty.
518 for (size_t i
= kResultsPerProvider
; i
< kResultsPerProvider
* 2; ++i
) {
520 result_
.match_at(i
)->search_terms_args
->assisted_query_stats
.empty());
524 TEST_F(AutocompleteProviderTest
, RemoveDuplicates
) {
525 TestProvider
* provider1
= NULL
;
526 TestProvider
* provider2
= NULL
;
527 ResetControllerWithTestProviders(true, &provider1
, &provider2
);
530 // Make sure all the first provider's results were eliminated by the second
532 EXPECT_EQ(kResultsPerProvider
, result_
.size());
533 for (AutocompleteResult::const_iterator
i(result_
.begin());
534 i
!= result_
.end(); ++i
)
535 EXPECT_EQ(provider2
, i
->provider
);
538 TEST_F(AutocompleteProviderTest
, AllowExactKeywordMatch
) {
539 ResetControllerWithKeywordAndSearchProviders();
540 RunExactKeymatchTest(true);
541 RunExactKeymatchTest(false);
544 // Ensures matches from (only) the default search provider respect any extra
545 // query params set on the command line.
546 TEST_F(AutocompleteProviderTest
, ExtraQueryParams
) {
547 ResetControllerWithKeywordAndSearchProviders();
548 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
549 switches::kExtraSearchQueryParams
, "a=b");
550 RunExactKeymatchTest(true);
552 ASSERT_EQ(2U, result_
.size());
553 EXPECT_EQ("http://keyword/test",
554 result_
.match_at(0)->destination_url
.possibly_invalid_spec());
555 EXPECT_EQ("http://defaultturl/k%20test?a=b",
556 result_
.match_at(1)->destination_url
.possibly_invalid_spec());
559 // Test that redundant associated keywords are removed.
560 TEST_F(AutocompleteProviderTest
, RedundantKeywordsIgnoredInResult
) {
561 ResetControllerWithKeywordProvider();
564 KeywordTestData duplicate_url
[] = {
565 { base::ASCIIToUTF16("fo"), base::string16(), base::string16() },
566 { base::ASCIIToUTF16("foo.com"), base::string16(),
567 base::ASCIIToUTF16("foo.com") },
568 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() }
571 SCOPED_TRACE("Duplicate url");
572 RunKeywordTest(base::ASCIIToUTF16("fo"), duplicate_url
,
573 arraysize(duplicate_url
));
577 KeywordTestData keyword_match
[] = {
578 { base::ASCIIToUTF16("foo.com"), base::ASCIIToUTF16("foo.com"),
580 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() }
583 SCOPED_TRACE("Duplicate url with keyword match");
584 RunKeywordTest(base::ASCIIToUTF16("fo"), keyword_match
,
585 arraysize(keyword_match
));
589 KeywordTestData multiple_keyword
[] = {
590 { base::ASCIIToUTF16("fo"), base::string16(), base::string16() },
591 { base::ASCIIToUTF16("foo.com"), base::string16(),
592 base::ASCIIToUTF16("foo.com") },
593 { base::ASCIIToUTF16("foo.com"), base::string16(), base::string16() },
594 { base::ASCIIToUTF16("bar.com"), base::string16(),
595 base::ASCIIToUTF16("bar.com") },
598 SCOPED_TRACE("Duplicate url with multiple keywords");
599 RunKeywordTest(base::ASCIIToUTF16("fo"), multiple_keyword
,
600 arraysize(multiple_keyword
));
604 // Test that exact match keywords trump keywords associated with
606 TEST_F(AutocompleteProviderTest
, ExactMatchKeywords
) {
607 ResetControllerWithKeywordProvider();
610 KeywordTestData keyword_match
[] = {
611 { base::ASCIIToUTF16("foo.com"), base::string16(),
612 base::ASCIIToUTF16("foo.com") }
615 SCOPED_TRACE("keyword match as usual");
616 RunKeywordTest(base::ASCIIToUTF16("fo"), keyword_match
,
617 arraysize(keyword_match
));
620 // The same result set with an input of "f" (versus "fo") should get
621 // a different associated keyword because "f" is an exact match for
622 // a keyword and that should trump the keyword normally associated with
625 KeywordTestData keyword_match
[] = {
626 { base::ASCIIToUTF16("foo.com"), base::string16(),
627 base::ASCIIToUTF16("f") }
630 SCOPED_TRACE("keyword exact match");
631 RunKeywordTest(base::ASCIIToUTF16("f"), keyword_match
,
632 arraysize(keyword_match
));
636 TEST_F(AutocompleteProviderTest
, UpdateAssistedQueryStats
) {
637 ResetControllerWithTestProviders(false, NULL
, NULL
);
640 AssistedQueryStatsTestData test_data
[] = {
641 // MSVC doesn't support zero-length arrays, so supply some dummy data.
642 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
, "" }
644 SCOPED_TRACE("No matches");
645 // Note: We pass 0 here to ignore the dummy data above.
646 RunAssistedQueryStatsTest(test_data
, 0);
650 AssistedQueryStatsTestData test_data
[] = {
651 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
, "chrome..69i57" }
653 SCOPED_TRACE("One match");
654 RunAssistedQueryStatsTest(test_data
, arraysize(test_data
));
658 AssistedQueryStatsTestData test_data
[] = {
659 { AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
,
660 "chrome..69i57j69i58j5l2j0l3j69i59" },
661 { AutocompleteMatchType::URL_WHAT_YOU_TYPED
,
662 "chrome..69i57j69i58j5l2j0l3j69i59" },
663 { AutocompleteMatchType::NAVSUGGEST
,
664 "chrome.2.69i57j69i58j5l2j0l3j69i59" },
665 { AutocompleteMatchType::NAVSUGGEST
,
666 "chrome.3.69i57j69i58j5l2j0l3j69i59" },
667 { AutocompleteMatchType::SEARCH_SUGGEST
,
668 "chrome.4.69i57j69i58j5l2j0l3j69i59" },
669 { AutocompleteMatchType::SEARCH_SUGGEST
,
670 "chrome.5.69i57j69i58j5l2j0l3j69i59" },
671 { AutocompleteMatchType::SEARCH_SUGGEST
,
672 "chrome.6.69i57j69i58j5l2j0l3j69i59" },
673 { AutocompleteMatchType::SEARCH_HISTORY
,
674 "chrome.7.69i57j69i58j5l2j0l3j69i59" },
676 SCOPED_TRACE("Multiple matches");
677 RunAssistedQueryStatsTest(test_data
, arraysize(test_data
));
681 TEST_F(AutocompleteProviderTest
, GetDestinationURL
) {
682 ResetControllerWithKeywordAndSearchProviders();
684 // For the destination URL to have aqs parameters for query formulation time
685 // and the field trial triggered bit, many conditions need to be satisfied.
686 AutocompleteMatch
match(NULL
, 1100, false,
687 AutocompleteMatchType::SEARCH_SUGGEST
);
688 GURL
url(GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456)));
689 EXPECT_TRUE(url
.path().empty());
691 // The protocol needs to be https.
692 RegisterTemplateURL(base::ASCIIToUTF16(kTestTemplateURLKeyword
),
693 "https://aqs/{searchTerms}/{google:assistedQueryStats}");
694 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
695 EXPECT_TRUE(url
.path().empty());
697 // There needs to be a keyword provider.
698 match
.keyword
= base::ASCIIToUTF16(kTestTemplateURLKeyword
);
699 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
700 EXPECT_TRUE(url
.path().empty());
702 // search_terms_args needs to be set.
703 match
.search_terms_args
.reset(
704 new TemplateURLRef::SearchTermsArgs(base::string16()));
705 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
706 EXPECT_TRUE(url
.path().empty());
708 // assisted_query_stats needs to have been previously set.
709 match
.search_terms_args
->assisted_query_stats
=
710 "chrome.0.69i57j69i58j5l2j0l3j69i59";
711 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
712 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j0&", url
.path());
714 // Test field trial triggered bit set.
715 controller_
->search_provider_
->field_trial_triggered_in_session_
= true;
717 controller_
->search_provider_
->field_trial_triggered_in_session());
718 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
719 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j0&", url
.path());
721 // Test page classification set.
722 controller_
->input_
.current_page_classification_
=
723 metrics::OmniboxEventProto::OTHER
;
724 controller_
->search_provider_
->field_trial_triggered_in_session_
= false;
726 controller_
->search_provider_
->field_trial_triggered_in_session());
727 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
728 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j4&", url
.path());
730 // Test page classification and field trial triggered set.
731 controller_
->search_provider_
->field_trial_triggered_in_session_
= true;
733 controller_
->search_provider_
->field_trial_triggered_in_session());
734 url
= GetDestinationURL(match
, base::TimeDelta::FromMilliseconds(2456));
735 EXPECT_EQ("//aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j1j4&", url
.path());