11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/base_search_provider.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string16.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/utf_string_conversions.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/autocomplete_match.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/autocomplete_match_type.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/autocomplete_provider_client.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/autocomplete_scheme_classifier.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/search_suggestion_parser.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/search_engines/search_terms_data.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/search_engines/template_url_service.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/search_engines/template_url_service_client.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gmock/include/gmock/gmock.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::NiceMock;
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::Return;
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::_;
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MockAutocompleteProviderClient : public AutocompleteProviderClient {
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MockAutocompleteProviderClient() {}
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(RequestContext, net::URLRequestContextGetter*());
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(IsOffTheRecord, bool());
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(AcceptLanguages, std::string());
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(SearchSuggestEnabled, bool());
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(ShowBookmarkBar, bool());
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(SchemeClassifier, const AutocompleteSchemeClassifier&());
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD6(
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Classify,
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      void(const base::string16& text,
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           bool prefer_keyword,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           bool allow_exact_keyword_match,
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           metrics::OmniboxEventProto::PageClassification page_classification,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           AutocompleteMatch* match,
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           GURL* alternate_nav_url));
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(InMemoryDatabase, history::URLDatabase*());
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD2(DeleteMatchingURLsForKeywordFromHistory,
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(history::KeywordID keyword_id, const base::string16& term));
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD0(TabSyncEnabledAndUnencrypted, bool());
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(PrefetchImage, void(const GURL& url));
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(MockAutocompleteProviderClient);
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestBaseSearchProvider : public BaseSearchProvider {
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef BaseSearchProvider::MatchMap MatchMap;
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: Takes ownership of client. scoped_ptr<> would be the right way to
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // express that, but NiceMock<> can't forward a scoped_ptr.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestBaseSearchProvider(TemplateURLService* template_url_service,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         AutocompleteProviderClient* client,
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         AutocompleteProvider::Type type)
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : BaseSearchProvider(template_url_service,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           scoped_ptr<AutocompleteProviderClient>(client),
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           type) {}
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(DeleteMatch, void(const AutocompleteMatch& match));
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_CONST_METHOD1(AddProviderInfo, void(ProvidersInfo* provider_info));
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_CONST_METHOD1(GetTemplateURL, const TemplateURL*(bool is_keyword));
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_CONST_METHOD1(GetInput, const AutocompleteInput(bool is_keyword));
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_CONST_METHOD1(ShouldAppendExtraParams,
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     bool(const SearchSuggestionParser::SuggestResult& result));
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(RecordDeletionResult, void(bool success));
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD2(Start,
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(const AutocompleteInput& input, bool minimal_changes));
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AddMatchToMap(const SearchSuggestionParser::SuggestResult& result,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     const std::string& metadata,
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     int accepted_suggestion,
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     bool mark_as_deletable,
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     bool in_keyword_mode,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     MatchMap* map) {
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BaseSearchProvider::AddMatchToMap(result,
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      metadata,
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      accepted_suggestion,
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      mark_as_deletable,
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      in_keyword_mode,
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      map);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~TestBaseSearchProvider() {}
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(TestBaseSearchProvider);
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass BaseSearchProviderTest : public testing::Test {
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~BaseSearchProviderTest() {}
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SetUp() {
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    service_.reset(
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new TemplateURLService(NULL,
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               scoped_ptr<SearchTermsData>(new SearchTermsData),
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               scoped_ptr<TemplateURLServiceClient>(),
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               base::Closure()));
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    provider_ = new NiceMock<TestBaseSearchProvider>(
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        service_.get(),
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new NiceMock<MockAutocompleteProviderClient>,
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        AutocompleteProvider::TYPE_SEARCH);
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<NiceMock<TestBaseSearchProvider> > provider_;
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TemplateURLService> service_;
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(BaseSearchProviderTest, PreserveAnswersWhenDeduplicating) {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TemplateURLData data;
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  data.SetURL("http://foo.com/url?bar={searchTerms}");
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TemplateURL> template_url(new TemplateURL(data));
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestBaseSearchProvider::MatchMap map;
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::string16 query = base::ASCIIToUTF16("weather los angeles");
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::string16 answer_contents = base::ASCIIToUTF16("some answer content");
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::string16 answer_type = base::ASCIIToUTF16("2334");
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*provider_, GetInput(_))
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillRepeatedly(Return(AutocompleteInput()));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*provider_, GetTemplateURL(_))
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillRepeatedly(Return(template_url.get()));
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SearchSuggestionParser::SuggestResult more_relevant(
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      query, AutocompleteMatchType::SEARCH_HISTORY, query, base::string16(),
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16(), base::string16(), base::string16(), std::string(),
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      std::string(), false, 1300, true, false, query);
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider_->AddMatchToMap(
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      more_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN,
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false, false, &map);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SearchSuggestionParser::SuggestResult less_relevant(
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      query, AutocompleteMatchType::SEARCH_SUGGEST, query, base::string16(),
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16(), answer_contents, answer_type, std::string(),
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      std::string(), false, 850, true, false, query);
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider_->AddMatchToMap(
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      less_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN,
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false, false, &map);
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, map.size());
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AutocompleteMatch match = map.begin()->second;
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, match.duplicate_matches.size());
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AutocompleteMatch duplicate = match.duplicate_matches[0];
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_contents, match.answer_contents);
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_type, match.answer_type);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(AutocompleteMatchType::SEARCH_HISTORY, match.type);
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1300, match.relevance);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_contents, duplicate.answer_contents);
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_type, duplicate.answer_type);
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(AutocompleteMatchType::SEARCH_SUGGEST, duplicate.type);
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(850, duplicate.relevance);
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Ensure answers are not copied over existing answers.
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  map.clear();
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::string16 answer_contents2 = base::ASCIIToUTF16("different answer");
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  more_relevant = SearchSuggestionParser::SuggestResult(
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      query, AutocompleteMatchType::SEARCH_HISTORY, query, base::string16(),
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::string16(), answer_contents2, answer_type, std::string(),
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      std::string(), false, 1300, true, false, query);
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider_->AddMatchToMap(
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      more_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN,
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false, false, &map);
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider_->AddMatchToMap(
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      less_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN,
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false, false, &map);
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, map.size());
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  match = map.begin()->second;
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, match.duplicate_matches.size());
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  duplicate = match.duplicate_matches[0];
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_contents2, match.answer_contents);
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_type, match.answer_type);
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(AutocompleteMatchType::SEARCH_HISTORY, match.type);
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1300, match.relevance);
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_contents, duplicate.answer_contents);
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(answer_type, duplicate.answer_type);
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(AutocompleteMatchType::SEARCH_SUGGEST, duplicate.type);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(850, duplicate.relevance);
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
193