diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-23 16:37:58 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-23 16:37:58 +0000 |
commit | b547666db3afc16f7749db7a71255fbf4bcb7af4 (patch) | |
tree | 90ac231bc949f0c6ed2db7894bf93b52fe2afae2 | |
parent | e98e82ac535ece8199fc0607b337b6cc1767e305 (diff) | |
download | chromium_src-b547666db3afc16f7749db7a71255fbf4bcb7af4.zip chromium_src-b547666db3afc16f7749db7a71255fbf4bcb7af4.tar.gz chromium_src-b547666db3afc16f7749db7a71255fbf4bcb7af4.tar.bz2 |
A basic search provider unit test. This tests asserts a handful of things:
. The default/keyword suggest providers are queried appropriately.
. History results are asked for default/keyword providers.
More assertions can be added over time, but we have to start some
where.
This uncovered one bug in SearchProvider, we were never marking the
provider as properly done.
BUG=3636
TEST=none
Review URL: http://codereview.chromium.org/87062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14315 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/search_provider.cc | 32 | ||||
-rw-r--r-- | chrome/browser/autocomplete/search_provider.h | 19 | ||||
-rw-r--r-- | chrome/browser/autocomplete/search_provider_unittest.cc | 246 | ||||
-rw-r--r-- | chrome/test/unit/unittests.vcproj | 4 |
4 files changed, 291 insertions, 10 deletions
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc index 1099efc..13d393c 100644 --- a/chrome/browser/autocomplete/search_provider.cc +++ b/chrome/browser/autocomplete/search_provider.cc @@ -26,6 +26,14 @@ using base::Time; using base::TimeDelta; +// static +const int SearchProvider::kDefaultProviderURLFetcherID = 1; +// static +const int SearchProvider::kKeywordProviderURLFetcherID = 2; + +// static +bool SearchProvider::query_suggest_immediately_ = false; + void SearchProvider::Providers::Set(const TemplateURL* default_provider, const TemplateURL* keyword_provider) { // TODO(pkasting): http://b/1162970 We shouldn't need to structure-copy @@ -115,13 +123,15 @@ void SearchProvider::Run() { if (providers_.valid_suggest_for_keyword_provider()) { suggest_results_pending_++; keyword_fetcher_.reset( - CreateSuggestFetcher(providers_.keyword_provider(), + CreateSuggestFetcher(kKeywordProviderURLFetcherID, + providers_.keyword_provider(), keyword_input_text_)); } if (providers_.valid_suggest_for_default_provider()) { suggest_results_pending_++; default_fetcher_.reset( - CreateSuggestFetcher(providers_.default_provider(), input_.text())); + CreateSuggestFetcher(kDefaultProviderURLFetcherID, + providers_.default_provider(), input_.text())); } // We should only get here if we have a suggest url for the keyword or default // providers. @@ -239,8 +249,8 @@ void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { // Kick off a timer that will start the URL fetch if it completes before // the user types another character. - timer_.Start(TimeDelta::FromMilliseconds(kQueryDelayMs), this, - &SearchProvider::Run); + int delay = query_suggest_immediately_ ? 0 : kQueryDelayMs; + timer_.Start(TimeDelta::FromMilliseconds(delay), this, &SearchProvider::Run); } bool SearchProvider::IsQuerySuitableForSuggest() const { @@ -334,8 +344,6 @@ void SearchProvider::OnGotMostRecentKeywordSearchTerms( } else { default_history_results_ = *results; } - ConvertResultsToAutocompleteMatches(); - listener_->OnProviderUpdate(!results->empty()); if (history_request_consumer_.PendingRequestCount() == 1) { // Requests are removed AFTER the callback is invoked. If the count == 1, @@ -343,14 +351,20 @@ void SearchProvider::OnGotMostRecentKeywordSearchTerms( history_request_pending_ = false; have_history_results_ = true; } + + ConvertResultsToAutocompleteMatches(); + listener_->OnProviderUpdate(!results->empty()); } -URLFetcher* SearchProvider::CreateSuggestFetcher(const TemplateURL& provider, +URLFetcher* SearchProvider::CreateSuggestFetcher(int id, + const TemplateURL& provider, const std::wstring& text) { const TemplateURLRef* const suggestions_url = provider.suggestions_url(); DCHECK(suggestions_url->SupportsReplacement()); - URLFetcher* fetcher = new URLFetcher(suggestions_url->ReplaceSearchTerms( - provider, text, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()), + URLFetcher* fetcher = URLFetcher::Create(id, + suggestions_url->ReplaceSearchTerms( + provider, text, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, + std::wstring()), URLFetcher::GET, this); fetcher->set_request_context(profile_->GetRequestContext()); fetcher->Start(); diff --git a/chrome/browser/autocomplete/search_provider.h b/chrome/browser/autocomplete/search_provider.h index 06e0352..6515bc7 100644 --- a/chrome/browser/autocomplete/search_provider.h +++ b/chrome/browser/autocomplete/search_provider.h @@ -48,6 +48,12 @@ class SearchProvider : public AutocompleteProvider, have_suggest_results_(false) { } +#if defined(UNIT_TEST) + static void set_query_suggest_immediately(bool value) { + query_suggest_immediately_ = value; + } +#endif + // AutocompleteProvider virtual void Start(const AutocompleteInput& input, bool minimal_changes); @@ -61,6 +67,12 @@ class SearchProvider : public AutocompleteProvider, const ResponseCookies& cookies, const std::string& data); + // ID used in creating URLFetcher for default provider's suggest results. + static const int kDefaultProviderURLFetcherID; + + // ID used in creating URLFetcher for keyword provider's suggest results. + static const int kKeywordProviderURLFetcherID; + private: // Manages the providers (TemplateURLs) used by SearchProvider. Two providers // may be used: @@ -179,7 +191,8 @@ class SearchProvider : public AutocompleteProvider, // Creates a URLFetcher requesting suggest results for the specified // TemplateURL. Ownership of the returned URLFetchet passes to the caller. - URLFetcher* CreateSuggestFetcher(const TemplateURL& provider, + URLFetcher* CreateSuggestFetcher(int id, + const TemplateURL& provider, const std::wstring& text); // Parses the results from the Suggest server and stores up to kMaxMatches of @@ -252,6 +265,10 @@ class SearchProvider : public AutocompleteProvider, // TODO(kochi): this is duplicate from history_autocomplete static size_t TrimHttpPrefix(std::wstring* url); + // Should we query for suggest results immediately? This is normally false, + // but may be set to true during testing. + static bool query_suggest_immediately_; + // Maintains the TemplateURLs used. Providers providers_; diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc new file mode 100644 index 0000000..530e7ee --- /dev/null +++ b/chrome/browser/autocomplete/search_provider_unittest.cc @@ -0,0 +1,246 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/time.h" +#include "chrome/browser/autocomplete/search_provider.h" +#include "chrome/browser/history/history.h" +#include "chrome/browser/net/test_url_fetcher_factory.h" +#include "chrome/browser/search_engines/template_url.h" +#include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/test/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + +// The following environment is configured for these tests: +// . The TemplateURL default_t_url_ is set as the default provider. +// . The TemplateURL keyword_t_url_ is added to the TemplateURLModel. This +// TemplateURL has a valid suggest and search URL. +// . The URL created by using the search term term1_ with default_t_url_ is +// added to history. +// . The URL created by using the search term keyword_term_ with keyword_t_url_ +// is added to history. +// . test_factory_ is set as the URLFetcher::Factory. +class SearchProviderTest : public testing::Test, + public AutocompleteProvider::ACProviderListener { + public: + SearchProviderTest() + : default_t_url_(NULL), + term1_(L"term1"), + keyword_t_url_(NULL), + keyword_term_(L"keyword"), + quit_when_done_(false) {} + + // See description above class for what this registers. + virtual void SetUp(); + + virtual void TearDown(); + + protected: + // Returns an AutocompleteMatch in provider_'s set of matches that matches + // |url|. If there is no matching URL, an empty match is returned. + AutocompleteMatch FindMatchWithDestination(const GURL& url); + + // ACProviderListener method. If we're waiting for the provider to finish, + // this exits the message loop. + virtual void OnProviderUpdate(bool updated_matches); + + // Runs a nested message loop until provider_ is done. The message loop is + // exited by way of OnProviderUPdate. + void RunTillProviderDone(); + + // Invokes Start on provider_, then runs all pending tasks. + void QueryForInput(const std::wstring& text); + + // See description above class for details of these fields. + TemplateURL* default_t_url_; + const std::wstring term1_; + GURL term1_url_; + TemplateURL* keyword_t_url_; + const std::wstring keyword_term_; + GURL keyword_url_; + + // URLFetcher::Factory implementation registered. + TestURLFetcherFactory test_factory_; + + MessageLoopForUI message_loop_; + + // Profile we use. + TestingProfile profile_; + + // The provider. + scoped_refptr<SearchProvider> provider_; + + // If true, OnProviderUpdate exits out of the current message loop. + bool quit_when_done_; + + DISALLOW_COPY_AND_ASSIGN(SearchProviderTest); +}; + +void SearchProviderTest::SetUp() { + SearchProvider::set_query_suggest_immediately(true); + + // We need both the history service and template url model loaded. + profile_.CreateHistoryService(true); + profile_.CreateTemplateURLModel(); + + TemplateURLModel* turl_model = profile_.GetTemplateURLModel(); + + // Reset the default TemplateURL. + default_t_url_ = new TemplateURL(); + default_t_url_->SetURL(L"http://defaultturl/{searchTerms}", 0, 0); + default_t_url_->SetSuggestionsURL(L"http://defaultturl2/{searchTerms}", 0, 0); + turl_model->Add(default_t_url_); + turl_model->SetDefaultSearchProvider(default_t_url_); + TemplateURL::IDType default_provider_id = default_t_url_->id(); + ASSERT_NE(0, default_provider_id); + + // Add url1, with search term term1_. + HistoryService* history = + profile_.GetHistoryService(Profile::EXPLICIT_ACCESS); + term1_url_ = default_t_url_->url()->ReplaceSearchTerms( + *default_t_url_, term1_, 0, std::wstring()); + history->AddPageWithDetails(term1_url_, std::wstring(), 1, 1, + base::Time::Now(), false); + history->SetKeywordSearchTermsForURL(term1_url_, default_t_url_->id(), + term1_); + + // Create another TemplateURL. + keyword_t_url_ = new TemplateURL(); + keyword_t_url_->set_keyword(L"k"); + keyword_t_url_->SetURL(L"http://keyword/{searchTerms}", 0, 0); + keyword_t_url_->SetSuggestionsURL(L"http://suggest_keyword/{searchTerms}", 0, + 0); + profile_.GetTemplateURLModel()->Add(keyword_t_url_); + ASSERT_NE(0, keyword_t_url_->id()); + + // Add a page and search term for keyword_t_url_. + keyword_url_ = keyword_t_url_->url()->ReplaceSearchTerms( + *keyword_t_url_, keyword_term_, 0, std::wstring()); + history->AddPageWithDetails(keyword_url_, std::wstring(), 1, 1, + base::Time::Now(), false); + history->SetKeywordSearchTermsForURL(keyword_url_, keyword_t_url_->id(), + keyword_term_); + + provider_ = new SearchProvider(this, &profile_); + + URLFetcher::set_factory(&test_factory_); +} + +void SearchProviderTest::OnProviderUpdate(bool updated_matches) { + SearchProvider::set_query_suggest_immediately(false); + if (quit_when_done_ && provider_->done()) { + quit_when_done_ = false; + message_loop_.Quit(); + } +} + +void SearchProviderTest::RunTillProviderDone() { + if (provider_->done()) + return; + + quit_when_done_ = true; + message_loop_.Run(NULL); +} + +void SearchProviderTest::QueryForInput(const std::wstring& text) { + // Start a query. + AutocompleteInput input(text, std::wstring(), false, false, false); + provider_->Start(input, false); + + // RunAllPending so that the task scheduled by SearchProvider to create the + // URLFetchers runs. + message_loop_.RunAllPending(); +} + +void SearchProviderTest::TearDown() { + message_loop_.RunAllPending(); + + URLFetcher::set_factory(NULL); + + // Shutdown the provider before the profile. + provider_ = NULL; +} + +AutocompleteMatch SearchProviderTest::FindMatchWithDestination(const GURL& url) { + for (ACMatches::const_iterator i = provider_->matches().begin(); + i != provider_->matches().end(); ++i) { + if (i->destination_url == url) + return *i; + } + return AutocompleteMatch(NULL, 1, false, AutocompleteMatch::HISTORY_URL); +} + +// Tests ----------------------------------------------------------------------- + +// Make sure we query history for the default provider and a URLFetcher is +// created for the default provider suggest results. +TEST_F(SearchProviderTest, QueryDefaultProvider) { + std::wstring term = term1_.substr(0, term1_.size() - 1); + QueryForInput(term); + + // Make sure the default providers suggest service was queried. + TestURLFetcher* fetcher = test_factory_.GetFetcherByID( + SearchProvider::kDefaultProviderURLFetcherID); + ASSERT_TRUE(fetcher); + + // And the URL matches what we expected. + GURL expected_url = default_t_url_->suggestions_url()->ReplaceSearchTerms( + *default_t_url_, term, 0, std::wstring()); + ASSERT_TRUE(fetcher->original_url() == expected_url); + + // Tell the SearchProvider the suggest query is done. + fetcher->delegate()->OnURLFetchComplete( + fetcher, GURL(), URLRequestStatus(), 200, ResponseCookies(), + std::string()); + fetcher = NULL; + + // Run till the history results complete. + RunTillProviderDone(); + + // The SearchProvider is done. Make sure it has a result for the history + // term term1. + AutocompleteMatch match = FindMatchWithDestination(term1_url_); + ASSERT_TRUE(!match.destination_url.is_empty()); +} + +// Issues a query that matches the registered keyword and makes sure history +// is queried as well as URLFetchers getting created. +TEST_F(SearchProviderTest, QueryKeywordProvider) { + std::wstring term = keyword_term_.substr(0, keyword_term_.size() - 1); + QueryForInput(keyword_t_url_->keyword() + L" " + term); + + // Make sure the default providers suggest service was queried. + TestURLFetcher* default_fetcher = test_factory_.GetFetcherByID( + SearchProvider::kDefaultProviderURLFetcherID); + ASSERT_TRUE(default_fetcher); + + // Tell the SearchProvider the default suggest query is done. + default_fetcher->delegate()->OnURLFetchComplete( + default_fetcher, GURL(), URLRequestStatus(), 200, ResponseCookies(), + std::string()); + default_fetcher = NULL; + + // Make sure the keyword providers suggest service was queried. + TestURLFetcher* keyword_fetcher = test_factory_.GetFetcherByID( + SearchProvider::kKeywordProviderURLFetcherID); + ASSERT_TRUE(keyword_fetcher); + + // And the URL matches what we expected. + GURL expected_url = keyword_t_url_->suggestions_url()->ReplaceSearchTerms( + *keyword_t_url_, term, 0, std::wstring()); + ASSERT_TRUE(keyword_fetcher->original_url() == expected_url); + + // Tell the SearchProvider the keyword suggest query is done. + keyword_fetcher->delegate()->OnURLFetchComplete( + keyword_fetcher, GURL(), URLRequestStatus(), 200, ResponseCookies(), + std::string()); + keyword_fetcher = NULL; + + // Run till the history results complete. + RunTillProviderDone(); + + // The SearchProvider is done. Make sure it has a result for the history + // term keyword. + AutocompleteMatch match = FindMatchWithDestination(keyword_url_); + ASSERT_TRUE(!match.destination_url.is_empty()); +} diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj index 0a05218..8900642 100644 --- a/chrome/test/unit/unittests.vcproj +++ b/chrome/test/unit/unittests.vcproj @@ -568,6 +568,10 @@ > </File> <File + RelativePath="..\..\browser\autocomplete\search_provider_unittest.cc" + > + </File> + <File RelativePath="..\..\browser\login_prompt_unittest.cc" > </File> |