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