Commit 961d1f7c authored by Moe Ahmadi's avatar Moe Ahmadi Committed by Commit Bot

Looks up keyword search terms table for local history ZPS

Swaps the existing implementation with one that queries the keyword search
terms table in the in-memory URLDatabase instead of the URLs table.

- This table is smaller so querying it is likely faster.
- The step to parse URLs is avoided.
- Is more consistent with how SearchProvider offers local search history
  matches.

Also improves and re-enables LocalHistoryZeroSuggestProviderTest.Delete
which was failing for Linux ChromiumOS MSAN, likely due to using an
uninitialized |history_db_task_id_| which no longer exists.

Bug: 996516,1010944
Change-Id: I183fb7367285dcb453fb42e46651550baf0e3036
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1835182
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTommy Li <tommycli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704062}
parent fc5ad208
...@@ -669,6 +669,19 @@ bool URLDatabase::DeleteKeywordSearchTerm(const base::string16& term) { ...@@ -669,6 +669,19 @@ bool URLDatabase::DeleteKeywordSearchTerm(const base::string16& term) {
return statement.Run(); return statement.Run();
} }
bool URLDatabase::DeleteKeywordSearchTermForNormalizedTerm(
KeywordID keyword_id,
const base::string16& normalized_term) {
sql::Statement statement(
GetDB().GetCachedStatement(SQL_FROM_HERE,
"DELETE FROM keyword_search_terms WHERE "
"keyword_id = ? AND normalized_term=?"));
statement.BindInt64(0, keyword_id);
statement.BindString16(1, normalized_term);
return statement.Run();
}
bool URLDatabase::DeleteKeywordSearchTermForURL(URLID url_id) { bool URLDatabase::DeleteKeywordSearchTermForURL(URLID url_id) {
sql::Statement statement(GetDB().GetCachedStatement( sql::Statement statement(GetDB().GetCachedStatement(
SQL_FROM_HERE, "DELETE FROM keyword_search_terms WHERE url_id=?")); SQL_FROM_HERE, "DELETE FROM keyword_search_terms WHERE url_id=?"));
......
...@@ -233,6 +233,11 @@ class URLDatabase { ...@@ -233,6 +233,11 @@ class URLDatabase {
// Deletes all searches matching |term|. // Deletes all searches matching |term|.
bool DeleteKeywordSearchTerm(const base::string16& term); bool DeleteKeywordSearchTerm(const base::string16& term);
// Deletes any search corresponding to |normalized_term|.
bool DeleteKeywordSearchTermForNormalizedTerm(
KeywordID keyword_id,
const base::string16& normalized_term);
// Deletes any search corresponding to |url_id|. // Deletes any search corresponding to |url_id|.
bool DeleteKeywordSearchTermForURL(URLID url_id); bool DeleteKeywordSearchTermForURL(URLID url_id);
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "components/google/core/common/google_util.h" #include "components/google/core/common/google_util.h"
#include "components/history/core/browser/history_database.h" #include "components/history/core/browser/history_database.h"
#include "components/history/core/browser/history_db_task.h"
#include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/keyword_search_term.h"
#include "components/history/core/browser/url_database.h" #include "components/history/core/browser/url_database.h"
#include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_match.h"
...@@ -36,68 +36,6 @@ namespace { ...@@ -36,68 +36,6 @@ namespace {
// Default relevance for the LocalHistoryZeroSuggestProvider query suggestions. // Default relevance for the LocalHistoryZeroSuggestProvider query suggestions.
const int kLocalHistoryZeroSuggestRelevance = 500; const int kLocalHistoryZeroSuggestRelevance = 500;
// ProviderHistoryDBTask wraps two non-null callbacks into a HistoryDBTask to
// passed to HistoryService::ScheduleDBTask. |request_callback| gets invoked on
// the history backend thread when the on-disk history database becomes
// available in order to query the database and populate |url_matches_|.
// |result_callback_| is then invoked with |url_matches_| back on the main
// thread.
class ProviderHistoryDBTask : public history::HistoryDBTask {
public:
using RequestCallback =
base::OnceCallback<history::URLRows(history::URLDatabase* url_db)>;
using ResultCallback = base::OnceCallback<void(const history::URLRows&)>;
ProviderHistoryDBTask(RequestCallback request_callback,
ResultCallback result_callback)
: request_callback_(std::move(request_callback)),
result_callback_(std::move(result_callback)) {
DCHECK(!request_callback_.is_null());
DCHECK(!result_callback_.is_null());
}
~ProviderHistoryDBTask() override {}
private:
// history::HistoryDBTask
bool RunOnDBThread(history::HistoryBackend* history_backend,
history::HistoryDatabase* db) override {
// Query the database.
if (db)
url_matches_ = std::move(request_callback_).Run(db);
return true;
}
void DoneRunOnMainThread() override {
// Return the query results to the originating thread.
std::move(result_callback_).Run(url_matches_);
}
RequestCallback request_callback_;
ResultCallback result_callback_;
history::URLRows url_matches_;
DISALLOW_COPY_AND_ASSIGN(ProviderHistoryDBTask);
};
// Queries |url_db| for URLs matching |google_search_url| prefix and returns
// the results. |url_db| must not be null. May be called on the history backend
// thread.
history::URLRows QueryURLDatabaseOnHistoryThread(
const std::string& google_search_url,
const size_t provider_max_matches,
history::URLDatabase* url_db) {
DCHECK(url_db);
// Request 5x more URLs than the number of matches the provider intends to
// return hoping to have enough URLs to work with once duplicates are filtered
// out.
history::URLRows url_matches;
url_db->AutocompleteForPrefix(google_search_url, 5 * provider_max_matches,
false, &url_matches);
return url_matches;
}
// Extracts the search terms from |url|. Collapses whitespaces, converts them to // Extracts the search terms from |url|. Collapses whitespaces, converts them to
// lowercase and returns them. |template_url_service| must not be null. // lowercase and returns them. |template_url_service| must not be null.
base::string16 GetSearchTermsFromURL(const GURL& url, base::string16 GetSearchTermsFromURL(const GURL& url,
...@@ -126,7 +64,6 @@ void LocalHistoryZeroSuggestProvider::Start(const AutocompleteInput& input, ...@@ -126,7 +64,6 @@ void LocalHistoryZeroSuggestProvider::Start(const AutocompleteInput& input,
bool minimal_changes) { bool minimal_changes) {
TRACE_EVENT0("omnibox", "LocalHistoryZeroSuggestProvider::Start"); TRACE_EVENT0("omnibox", "LocalHistoryZeroSuggestProvider::Start");
history_task_tracker_.TryCancel(history_db_task_id_);
done_ = true; done_ = true;
matches_.clear(); matches_.clear();
...@@ -159,34 +96,7 @@ void LocalHistoryZeroSuggestProvider::Start(const AutocompleteInput& input, ...@@ -159,34 +96,7 @@ void LocalHistoryZeroSuggestProvider::Start(const AutocompleteInput& input,
return; return;
} }
history::HistoryService* const history_service = client_->GetHistoryService(); QueryURLDatabase(input);
if (!history_service)
return;
GURL google_base_url(
template_url_service->search_terms_data().GoogleBaseURLValue());
std::string google_search_url =
google_util::GetGoogleSearchURL(google_base_url).spec();
// Query the in-memory URL database, if available. Otherwise, schedule a
// task to query the on-disk history database on the history backend thread.
history::URLDatabase* url_db = history_service->InMemoryDatabase();
if (url_db) {
const auto url_matches = QueryURLDatabaseOnHistoryThread(
google_search_url, max_matches_, url_db);
OnQueryURLDatabaseComplete(input, std::move(url_matches));
} else {
done_ = false;
history_db_task_id_ = history_service->ScheduleDBTask(
FROM_HERE,
std::make_unique<ProviderHistoryDBTask>(
base::BindOnce(QueryURLDatabaseOnHistoryThread, google_search_url,
max_matches_),
base::BindOnce(
&LocalHistoryZeroSuggestProvider::OnQueryURLDatabaseComplete,
weak_ptr_factory_.GetWeakPtr(), input)),
&history_task_tracker_);
}
} }
void LocalHistoryZeroSuggestProvider::DeleteMatch( void LocalHistoryZeroSuggestProvider::DeleteMatch(
...@@ -201,40 +111,36 @@ void LocalHistoryZeroSuggestProvider::DeleteMatch( ...@@ -201,40 +111,36 @@ void LocalHistoryZeroSuggestProvider::DeleteMatch(
return; return;
} }
// Generate a Google search URL for the suggestion by replacing the search history::URLDatabase* url_db = history_service->InMemoryDatabase();
// terms in the Google search URL template. Note that the suggestion's if (!url_db)
// original search URL cannot be used here as it is unique due to the assisted return;
// query stats (aka AQS) query param which contains impressions of
// autocomplete matches shown at query submission time. // Deletes all the search terms matching the query suggestion.
GURL google_search_url; url_db->DeleteKeywordSearchTermForNormalizedTerm(
TemplateURLRef::SearchTermsArgs search_terms_args(match.contents); template_url_service->GetDefaultSearchProvider()->id(), match.contents);
const auto* default_search_provider =
template_url_service->GetDefaultSearchProvider(); // Generate a Google search URL. Note that the search URL returned by
const auto& search_terms_data = template_url_service->search_terms_data(); // TemplateURL::GenerateSearchURL() cannot be used here as it contains
default_search_provider->ReplaceSearchTermsInURL( // Chrome specific query params and therefore only matches search queries
default_search_provider->GenerateSearchURL(search_terms_data), // issued from Chrome and not those from the Web.
search_terms_args, search_terms_data, &google_search_url); GURL google_base_url(
template_url_service->search_terms_data().GoogleBaseURLValue());
// Query the HistoryService for URLs matching the Google search URL. Note that std::string google_search_url =
// this step is necessary here because 1) there may be matching fresh URLs google_util::GetGoogleSearchURL(google_base_url).spec();
// that were not encountered in the suggestion creation phase due to looking
// up a maximum number of URLs in that phase. and 2) the performance overhead // Query the HistoryService for fresh Google search URLs. Note that the
// of requerying the HistoryService cannot be tolerated in the suggestion // performance overhead of querying the HistoryService can be tolerated here
// creation phase. Here on the other hand it can due to the small percentage // due to the small percentage of suggestions getting deleted relative to the
// of suggestions getting deleted relative to the number of suggestions shown. // number of suggestions shown and the async nature of this lookup.
history::QueryOptions opts; history::QueryOptions opts;
opts.duplicate_policy = history::QueryOptions::KEEP_ALL_DUPLICATES; opts.duplicate_policy = history::QueryOptions::KEEP_ALL_DUPLICATES;
opts.begin_time = history::AutocompleteAgeThreshold(); opts.begin_time = history::AutocompleteAgeThreshold();
history_service->QueryHistory( history_service->QueryHistory(
base::ASCIIToUTF16(google_search_url.spec()), opts, base::ASCIIToUTF16(google_search_url), opts,
base::BindOnce(&LocalHistoryZeroSuggestProvider::OnHistoryQueryResults, base::BindOnce(&LocalHistoryZeroSuggestProvider::OnHistoryQueryResults,
weak_ptr_factory_.GetWeakPtr(), match.contents), weak_ptr_factory_.GetWeakPtr(), match.contents),
&history_task_tracker_); &history_task_tracker_);
// Prevent the deleted suggestion from being resuggested until the
// corresponding URLs are asynchronously deleted.
deleted_suggestions_set_.insert(match.contents);
// Immediately update the list of matches to reflect the match was deleted. // Immediately update the list of matches to reflect the match was deleted.
base::EraseIf(matches_, [&](const auto& item) { base::EraseIf(matches_, [&](const auto& item) {
return match.contents == item.contents; return match.contents == item.contents;
...@@ -252,35 +158,43 @@ LocalHistoryZeroSuggestProvider::LocalHistoryZeroSuggestProvider( ...@@ -252,35 +158,43 @@ LocalHistoryZeroSuggestProvider::LocalHistoryZeroSuggestProvider(
LocalHistoryZeroSuggestProvider::~LocalHistoryZeroSuggestProvider() {} LocalHistoryZeroSuggestProvider::~LocalHistoryZeroSuggestProvider() {}
void LocalHistoryZeroSuggestProvider::OnQueryURLDatabaseComplete( void LocalHistoryZeroSuggestProvider::QueryURLDatabase(
const AutocompleteInput& input, const AutocompleteInput& input) {
const history::URLRows& url_matches) {
done_ = true; done_ = true;
matches_.clear(); matches_.clear();
// Fail if we can't extract the search terms from the URL matches. history::HistoryService* const history_service = client_->GetHistoryService();
if (!history_service)
return;
// Fail if the in-memory URL database is not available.
history::URLDatabase* url_db = history_service->InMemoryDatabase();
if (!url_db)
return;
// Fail if we can't set the clickthrough URL for query suggestions.
TemplateURLService* template_url_service = client_->GetTemplateURLService(); TemplateURLService* template_url_service = client_->GetTemplateURLService();
if (!template_url_service || if (!template_url_service ||
!template_url_service->GetDefaultSearchProvider()) { !template_url_service->GetDefaultSearchProvider()) {
return; return;
} }
// Request 5x more search terms than the number of matches the provider
// intends to return hoping to have enough left once ineligible ones are
// filtered out.
const auto& results = url_db->GetMostRecentKeywordSearchTerms(
template_url_service->GetDefaultSearchProvider()->id(), max_matches_ * 5);
// Used to filter out duplicate query suggestions. // Used to filter out duplicate query suggestions.
std::set<base::string16> seen_suggestions_set; std::set<base::string16> seen_suggestions_set;
int relevance = kLocalHistoryZeroSuggestRelevance; int relevance = kLocalHistoryZeroSuggestRelevance;
for (size_t i = 0; i < url_matches.size(); i++) { for (const auto& result : results) {
const history::URLRow& url_row = url_matches[i]; // Discard the result if it is fresh enough.
const GURL& url = url_row.url(); if (result.time < history::AutocompleteAgeThreshold())
// Discard the URL if it is not valid or fresh enough.
if (!url.is_valid() ||
url_row.last_visit() < history::AutocompleteAgeThreshold()) {
continue; continue;
}
base::string16 search_terms = base::string16 search_terms = result.normalized_term;
GetSearchTermsFromURL(url, template_url_service);
if (search_terms.empty()) if (search_terms.empty())
continue; continue;
...@@ -289,10 +203,6 @@ void LocalHistoryZeroSuggestProvider::OnQueryURLDatabaseComplete( ...@@ -289,10 +203,6 @@ void LocalHistoryZeroSuggestProvider::OnQueryURLDatabaseComplete(
continue; continue;
seen_suggestions_set.insert(search_terms); seen_suggestions_set.insert(search_terms);
// Filter out deleted query suggestions.
if (deleted_suggestions_set_.count(search_terms))
continue;
SearchSuggestionParser::SuggestResult suggestion( SearchSuggestionParser::SuggestResult suggestion(
/*suggestion=*/search_terms, AutocompleteMatchType::SEARCH_HISTORY, /*suggestion=*/search_terms, AutocompleteMatchType::SEARCH_HISTORY,
/*subtype_identifier=*/0, /*from_keyword=*/false, relevance--, /*subtype_identifier=*/0, /*from_keyword=*/false, relevance--,
......
...@@ -15,7 +15,6 @@ class AutocompleteProviderClient; ...@@ -15,7 +15,6 @@ class AutocompleteProviderClient;
class AutocompleteProviderListener; class AutocompleteProviderListener;
namespace history { namespace history {
class HistoryDBTask;
class QueryResults; class QueryResults;
} // namespace history } // namespace history
...@@ -42,9 +41,9 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider { ...@@ -42,9 +41,9 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider {
AutocompleteProviderListener* listener); AutocompleteProviderListener* listener);
~LocalHistoryZeroSuggestProvider() override; ~LocalHistoryZeroSuggestProvider() override;
// Creates autocomplete matches from |url_matches| and notifies |listener_|. // Queries the keyword search terms table of the in-memory URLDatabase for the
void OnQueryURLDatabaseComplete(const AutocompleteInput& input, // recent search terms submitted to the default search provider.
const history::URLRows& url_matches); void QueryURLDatabase(const AutocompleteInput& input);
// Called when the query results from HistoryService::QueryHistory are ready. // Called when the query results from HistoryService::QueryHistory are ready.
// Deletes URLs in |results| that would generate |suggestion|. // Deletes URLs in |results| that would generate |suggestion|.
...@@ -54,10 +53,6 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider { ...@@ -54,10 +53,6 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider {
// The maximum number of matches to return. // The maximum number of matches to return.
const size_t max_matches_; const size_t max_matches_;
// Used to filter out deleted query suggestions in order to prevent them from
// reappearing before the corresponding URLs are asynchronously deleted.
std::set<base::string16> deleted_suggestions_set_;
// Client for accessing TemplateUrlService, prefs, etc. // Client for accessing TemplateUrlService, prefs, etc.
AutocompleteProviderClient* const client_; AutocompleteProviderClient* const client_;
...@@ -67,9 +62,6 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider { ...@@ -67,9 +62,6 @@ class LocalHistoryZeroSuggestProvider : public AutocompleteProvider {
// Used for the async tasks querying the HistoryService. // Used for the async tasks querying the HistoryService.
base::CancelableTaskTracker history_task_tracker_; base::CancelableTaskTracker history_task_tracker_;
// Task ID for the history::HistoryDBTask running on history backend thread.
base::CancelableTaskTracker::TaskId history_db_task_id_;
base::WeakPtrFactory<LocalHistoryZeroSuggestProvider> weak_ptr_factory_{this}; base::WeakPtrFactory<LocalHistoryZeroSuggestProvider> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(LocalHistoryZeroSuggestProvider); DISALLOW_COPY_AND_ASSIGN(LocalHistoryZeroSuggestProvider);
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include "components/omnibox/browser/local_history_zero_suggest_provider.h" #include "components/omnibox/browser/local_history_zero_suggest_provider.h"
#include <memory> #include <memory>
#include <vector>
#include "base/i18n/case_conversion.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
...@@ -13,6 +15,7 @@ ...@@ -13,6 +15,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/keyword_search_term.h"
#include "components/history/core/browser/url_database.h" #include "components/history/core/browser/url_database.h"
#include "components/history/core/test/history_service_test_util.h" #include "components/history/core/test/history_service_test_util.h"
#include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_match.h"
...@@ -70,6 +73,14 @@ class LocalHistoryZeroSuggestProviderTest ...@@ -70,6 +73,14 @@ class LocalHistoryZeroSuggestProviderTest
metrics::OmniboxEventProto::NTP_REALBOX, metrics::OmniboxEventProto::NTP_REALBOX,
LocalHistoryZeroSuggestProvider::kZeroSuggestLocalVariant); LocalHistoryZeroSuggestProvider::kZeroSuggestLocalVariant);
// Add the fallback default search provider to the TemplateURLService so
// that it gets a valid unique identifier. Make the newly added provider the
// user selected default search provider.
TemplateURL* default_provider = client_->GetTemplateURLService()->Add(
std::make_unique<TemplateURL>(default_search_provider()->data()));
client_->GetTemplateURLService()->SetUserSelectedDefaultSearchProvider(
default_provider);
// Verify that Google is the default search provider. // Verify that Google is the default search provider.
ASSERT_EQ(SEARCH_ENGINE_GOOGLE, ASSERT_EQ(SEARCH_ENGINE_GOOGLE,
default_search_provider()->GetEngineType( default_search_provider()->GetEngineType(
...@@ -132,7 +143,6 @@ void LocalHistoryZeroSuggestProviderTest::SetZeroSuggestVariant( ...@@ -132,7 +143,6 @@ void LocalHistoryZeroSuggestProviderTest::SetZeroSuggestVariant(
void LocalHistoryZeroSuggestProviderTest::LoadURLs( void LocalHistoryZeroSuggestProviderTest::LoadURLs(
std::vector<TestURLData> url_data_list) { std::vector<TestURLData> url_data_list) {
const Time now = Time::Now(); const Time now = Time::Now();
history::URLRows rows;
for (const auto& entry : url_data_list) { for (const auto& entry : url_data_list) {
TemplateURLRef::SearchTermsArgs search_terms_args( TemplateURLRef::SearchTermsArgs search_terms_args(
base::UTF8ToUTF16(entry.search_terms)); base::UTF8ToUTF16(entry.search_terms));
...@@ -141,17 +151,15 @@ void LocalHistoryZeroSuggestProviderTest::LoadURLs( ...@@ -141,17 +151,15 @@ void LocalHistoryZeroSuggestProviderTest::LoadURLs(
std::string search_url = std::string search_url =
entry.search_provider->url_ref().ReplaceSearchTerms(search_terms_args, entry.search_provider->url_ref().ReplaceSearchTerms(search_terms_args,
search_terms_data); search_terms_data);
history::URLRow row(GURL{search_url}); client_->GetHistoryService()->AddPageWithDetails(
row.set_title(base::UTF8ToUTF16(entry.title)); GURL(search_url), base::UTF8ToUTF16(entry.title), entry.visit_count,
row.set_visit_count(entry.visit_count); entry.typed_count, now - TimeDelta::FromDays(entry.age_in_days),
row.set_typed_count(entry.typed_count); entry.hidden, history::SOURCE_BROWSED);
row.set_last_visit(now - TimeDelta::FromDays(entry.age_in_days)); client_->GetHistoryService()->SetKeywordSearchTermsForURL(
row.set_hidden(entry.hidden); GURL(search_url), entry.search_provider->id(),
rows.push_back(row); base::UTF8ToUTF16(entry.search_terms));
}
client_->GetHistoryService()->AddPagesWithDetails(rows,
history::SOURCE_BROWSED);
WaitForHistoryService(); WaitForHistoryService();
}
} }
void LocalHistoryZeroSuggestProviderTest::WaitForHistoryService() { void LocalHistoryZeroSuggestProviderTest::WaitForHistoryService() {
...@@ -259,7 +267,6 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, DefaultSearchProvider) { ...@@ -259,7 +267,6 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, DefaultSearchProvider) {
std::make_unique<TemplateURL>(*GenerateDummyTemplateURLData("other"))); std::make_unique<TemplateURL>(*GenerateDummyTemplateURLData("other")));
LoadURLs({ LoadURLs({
{default_search_provider(), "hello world", "&foo=bar", 1}, {default_search_provider(), "hello world", "&foo=bar", 1},
{default_search_provider(), "", "&foo=bar", 1},
{other_search_provider, "does not matter", "&foo=bar", 1}, {other_search_provider, "does not matter", "&foo=bar", 1},
}); });
...@@ -277,16 +284,14 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, DefaultSearchProvider) { ...@@ -277,16 +284,14 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, DefaultSearchProvider) {
} }
// Tests that search terms are extracted with the correct encoding, whitespaces // Tests that search terms are extracted with the correct encoding, whitespaces
// are collapsed, search terms are lowercased and duplicated, and empty searches // are collapsed, and are lowercased and deduplicated.
// are ignored.
TEST_F(LocalHistoryZeroSuggestProviderTest, SearchTerms) { TEST_F(LocalHistoryZeroSuggestProviderTest, SearchTerms) {
LoadURLs({ LoadURLs({
{default_search_provider(), "hello world", "&foo=bar", 1}, {default_search_provider(), "hello world", "&foo=bar", 1},
{default_search_provider(), "hello world", "&foo=bar", 1}, {default_search_provider(), "hello world", "&foo=bar", 1},
{default_search_provider(), "hello world", "&foo=bar", 1}, {default_search_provider(), "hello world", "&foo=bar", 1},
{default_search_provider(), "hello world", "&foo=bar", 1}, {default_search_provider(), "hello world", "&foo=bar", 1},
{default_search_provider(), "HELLO WORLD", "&foo=bar", 1}, {default_search_provider(), "HELLO WORLD ", "&foo=bar", 1},
{default_search_provider(), " ", "&foo=bar", 1},
{default_search_provider(), "سلام دنیا", "&foo=bar", 2}, {default_search_provider(), "سلام دنیا", "&foo=bar", 2},
}); });
...@@ -318,32 +323,53 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, Suggestions_Freshness) { ...@@ -318,32 +323,53 @@ TEST_F(LocalHistoryZeroSuggestProviderTest, Suggestions_Freshness) {
ExpectMatches({{"fresh search", 500}}); ExpectMatches({{"fresh search", 500}});
} }
// Tests that all the search URLs that would produce a given suggestion get // Tests that the provider supports deletion of matches.
// deleted when the autocomplete match is deleted. TEST_F(LocalHistoryZeroSuggestProviderTest, Delete) {
TEST_F(LocalHistoryZeroSuggestProviderTest, DISABLED_Delete) { auto* template_url_service = client_->GetTemplateURLService();
auto* other_search_provider = template_url_service->Add(
std::make_unique<TemplateURL>(*GenerateDummyTemplateURLData("other")));
LoadURLs({ LoadURLs({
{default_search_provider(), "hello world", "&foo=bar&aqs=1", 1}, {default_search_provider(), "hello world", "&foo=bar&aqs=1", 1},
{default_search_provider(), "HELLO WORLD", "&foo=bar&aqs=12", 1}, {default_search_provider(), "HELLO WORLD ", "&foo=bar&aqs=12", 1},
{default_search_provider(), "hello world", "&foo=bar&aqs=123", 1}, {default_search_provider(), "hello world", "&foo=bar&aqs=123", 1},
{default_search_provider(), "hello world", "&foo=bar&aqs=1234", 1}, {default_search_provider(), "hello world", "&foo=bar&aqs=1234", 1},
{default_search_provider(), "not to be deleted", "&foo=bar&aqs=12345", 1},
{other_search_provider, "hello world", "&foo=bar&aqs=123456", 1},
}); });
StartProviderAndWaitUntilDone(); StartProviderAndWaitUntilDone();
ExpectMatches({{"hello world", 500}}); ExpectMatches({{"hello world", 500}, {"not to be deleted", 499}});
provider_->DeleteMatch(provider_->matches()[0]); provider_->DeleteMatch(provider_->matches()[0]);
// Make sure the deletion takes effect immediately in the provider before the // Make sure the deletion takes effect immediately in the provider before the
// history service asynchronously performs the deletion or even before the // history service asynchronously performs the deletion or even before the
// provider is started again. // provider is started again.
ExpectMatches({}); ExpectMatches({{"not to be deleted", 499}});
StartProviderAndWaitUntilDone(); StartProviderAndWaitUntilDone();
ExpectMatches({}); ExpectMatches({{"not to be deleted", 500}});
// Wait until the history service performs the deletion. // Wait until the history service performs the deletion.
WaitForHistoryService(); WaitForHistoryService();
StartProviderAndWaitUntilDone(); StartProviderAndWaitUntilDone();
ExpectMatches({}); ExpectMatches({{"not to be deleted", 500}});
// Make sure all the search terms for the default search provider that would
// produce the deleted match are deleted.
history::URLDatabase* url_db =
client_->GetHistoryService()->InMemoryDatabase();
std::vector<history::KeywordSearchTermVisit> visits =
url_db->GetMostRecentKeywordSearchTerms(default_search_provider()->id(),
/*max_count=*/10);
EXPECT_EQ(1U, visits.size());
EXPECT_EQ(base::ASCIIToUTF16("not to be deleted"), visits[0].term);
// Make sure search terms from other search providers that would produce the
// deleted match are not deleted.
visits = url_db->GetMostRecentKeywordSearchTerms(other_search_provider->id(),
/*max_count=*/10);
EXPECT_EQ(1U, visits.size());
EXPECT_EQ(base::ASCIIToUTF16("hello world"), visits[0].term);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment