OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/autocomplete/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 | 49 |
50 // Returns the first match in |matches| with |allowed_to_be_default_match| | 50 // Returns the first match in |matches| with |allowed_to_be_default_match| |
51 // set to true. | 51 // set to true. |
52 ACMatches::const_iterator FindDefaultMatch(const ACMatches& matches) { | 52 ACMatches::const_iterator FindDefaultMatch(const ACMatches& matches) { |
53 ACMatches::const_iterator it = matches.begin(); | 53 ACMatches::const_iterator it = matches.begin(); |
54 while ((it != matches.end()) && !it->allowed_to_be_default_match) | 54 while ((it != matches.end()) && !it->allowed_to_be_default_match) |
55 ++it; | 55 ++it; |
56 return it; | 56 return it; |
57 } | 57 } |
58 | 58 |
59 class SuggestionDeletionHandler; | |
60 class SearchProviderForTest : public SearchProvider { | |
61 public: | |
62 SearchProviderForTest( | |
63 AutocompleteProviderListener* listener, | |
64 Profile* profile); | |
65 bool is_success() { return is_success_; }; | |
66 | |
67 protected: | |
68 virtual ~SearchProviderForTest(); | |
69 | |
70 private: | |
71 virtual void RecordDeletionResult(bool success) OVERRIDE; | |
72 bool is_success_; | |
73 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, TestDeleteMatch_FakeProvider); | |
Peter Kasting
2013/12/03 00:33:51
Nit: This declaration seems useless?
Maria
2013/12/03 01:00:26
Done.
| |
74 DISALLOW_COPY_AND_ASSIGN(SearchProviderForTest); | |
75 }; | |
76 | |
77 SearchProviderForTest::SearchProviderForTest( | |
78 AutocompleteProviderListener* listener, | |
79 Profile* profile) : SearchProvider(listener, profile), | |
Peter Kasting
2013/12/03 00:33:51
Nit: Wrap ":" and following to next line
Maria
2013/12/03 01:00:26
Done.
| |
80 is_success_(false) { | |
81 } | |
82 | |
83 SearchProviderForTest::~SearchProviderForTest() { | |
84 } | |
85 | |
86 void SearchProviderForTest::RecordDeletionResult(bool success) { | |
87 is_success_ = success; | |
88 } | |
89 | |
59 } // namespace | 90 } // namespace |
60 | 91 |
61 // SearchProviderTest --------------------------------------------------------- | 92 // SearchProviderTest --------------------------------------------------------- |
62 | 93 |
63 // The following environment is configured for these tests: | 94 // The following environment is configured for these tests: |
64 // . The TemplateURL default_t_url_ is set as the default provider. | 95 // . The TemplateURL default_t_url_ is set as the default provider. |
65 // . The TemplateURL keyword_t_url_ is added to the TemplateURLService. This | 96 // . The TemplateURL keyword_t_url_ is added to the TemplateURLService. This |
66 // TemplateURL has a valid suggest and search URL. | 97 // TemplateURL has a valid suggest and search URL. |
67 // . The URL created by using the search term term1_ with default_t_url_ is | 98 // . The URL created by using the search term term1_ with default_t_url_ is |
68 // added to history. | 99 // added to history. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 | 211 |
181 content::TestBrowserThreadBundle thread_bundle_; | 212 content::TestBrowserThreadBundle thread_bundle_; |
182 | 213 |
183 // URLFetcherFactory implementation registered. | 214 // URLFetcherFactory implementation registered. |
184 net::TestURLFetcherFactory test_factory_; | 215 net::TestURLFetcherFactory test_factory_; |
185 | 216 |
186 // Profile we use. | 217 // Profile we use. |
187 TestingProfile profile_; | 218 TestingProfile profile_; |
188 | 219 |
189 // The provider. | 220 // The provider. |
190 scoped_refptr<SearchProvider> provider_; | 221 scoped_refptr<SearchProviderForTest> provider_; |
191 | 222 |
192 // If non-NULL, OnProviderUpdate quits the current |run_loop_|. | 223 // If non-NULL, OnProviderUpdate quits the current |run_loop_|. |
193 base::RunLoop* run_loop_; | 224 base::RunLoop* run_loop_; |
194 | 225 |
195 DISALLOW_COPY_AND_ASSIGN(SearchProviderTest); | 226 DISALLOW_COPY_AND_ASSIGN(SearchProviderTest); |
196 }; | 227 }; |
197 | 228 |
198 // static | 229 // static |
199 const std::string SearchProviderTest::kNotApplicable = "Not Applicable"; | 230 const std::string SearchProviderTest::kNotApplicable = "Not Applicable"; |
200 | 231 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 ASSERT_NE(0, keyword_t_url_->id()); | 269 ASSERT_NE(0, keyword_t_url_->id()); |
239 | 270 |
240 // Add a page and search term for keyword_t_url_. | 271 // Add a page and search term for keyword_t_url_. |
241 keyword_url_ = AddSearchToHistory(keyword_t_url_, keyword_term_, 1); | 272 keyword_url_ = AddSearchToHistory(keyword_t_url_, keyword_term_, 1); |
242 | 273 |
243 // Keywords are updated by the InMemoryHistoryBackend only after the message | 274 // Keywords are updated by the InMemoryHistoryBackend only after the message |
244 // has been processed on the history thread. Block until history processes all | 275 // has been processed on the history thread. Block until history processes all |
245 // requests to ensure the InMemoryDatabase is the state we expect it. | 276 // requests to ensure the InMemoryDatabase is the state we expect it. |
246 profile_.BlockUntilHistoryProcessesPendingRequests(); | 277 profile_.BlockUntilHistoryProcessesPendingRequests(); |
247 | 278 |
248 provider_ = new SearchProvider(this, &profile_); | 279 provider_ = new SearchProviderForTest(this, &profile_); |
249 provider_->kMinimumTimeBetweenSuggestQueriesMs = 0; | 280 provider_->kMinimumTimeBetweenSuggestQueriesMs = 0; |
250 } | 281 } |
251 | 282 |
252 void SearchProviderTest::TearDown() { | 283 void SearchProviderTest::TearDown() { |
253 base::RunLoop().RunUntilIdle(); | 284 base::RunLoop().RunUntilIdle(); |
254 | 285 |
255 // Shutdown the provider before the profile. | 286 // Shutdown the provider before the profile. |
256 provider_ = NULL; | 287 provider_ = NULL; |
257 } | 288 } |
258 | 289 |
(...skipping 3088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3347 if (suggestion == kNotApplicable) | 3378 if (suggestion == kNotApplicable) |
3348 break; | 3379 break; |
3349 if (cases[i].results[j].is_navigation_result) { | 3380 if (cases[i].results[j].is_navigation_result) { |
3350 provider_->default_results_.navigation_results.push_back( | 3381 provider_->default_results_.navigation_results.push_back( |
3351 SearchProvider::NavigationResult( | 3382 SearchProvider::NavigationResult( |
3352 *provider_.get(), GURL(suggestion), string16(), false, | 3383 *provider_.get(), GURL(suggestion), string16(), false, |
3353 cases[i].results[j].relevance, false)); | 3384 cases[i].results[j].relevance, false)); |
3354 } else { | 3385 } else { |
3355 provider_->default_results_.suggest_results.push_back( | 3386 provider_->default_results_.suggest_results.push_back( |
3356 SearchProvider::SuggestResult(ASCIIToUTF16(suggestion), string16(), | 3387 SearchProvider::SuggestResult(ASCIIToUTF16(suggestion), string16(), |
3357 string16(), std::string(), false, | 3388 string16(), std::string(), |
3389 std::string(), false, | |
3358 cases[i].results[j].relevance, | 3390 cases[i].results[j].relevance, |
3359 false, false)); | 3391 false, false)); |
3360 } | 3392 } |
3361 } | 3393 } |
3362 | 3394 |
3363 provider_->input_ = AutocompleteInput( | 3395 provider_->input_ = AutocompleteInput( |
3364 ASCIIToUTF16(cases[i].omnibox_input), string16::npos, string16(), | 3396 ASCIIToUTF16(cases[i].omnibox_input), string16::npos, string16(), |
3365 GURL(), AutocompleteInput::INVALID_SPEC, false, false, true, | 3397 GURL(), AutocompleteInput::INVALID_SPEC, false, false, true, |
3366 AutocompleteInput::ALL_MATCHES); | 3398 AutocompleteInput::ALL_MATCHES); |
3367 provider_->RemoveAllStaleResults(); | 3399 provider_->RemoveAllStaleResults(); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3749 } | 3781 } |
3750 | 3782 |
3751 // A basic test that verifies that the XSSI guarded JSON response is parsed | 3783 // A basic test that verifies that the XSSI guarded JSON response is parsed |
3752 // correctly. | 3784 // correctly. |
3753 TEST_F(SearchProviderTest, XSSIGuardedJSONParsing) { | 3785 TEST_F(SearchProviderTest, XSSIGuardedJSONParsing) { |
3754 struct Match { | 3786 struct Match { |
3755 std::string contents; | 3787 std::string contents; |
3756 AutocompleteMatchType::Type type; | 3788 AutocompleteMatchType::Type type; |
3757 }; | 3789 }; |
3758 const Match kEmptyMatch = { kNotApplicable, | 3790 const Match kEmptyMatch = { kNotApplicable, |
3759 AutocompleteMatchType::NUM_TYPES}; | 3791 AutocompleteMatchType::NUM_TYPES |
3792 }; | |
Peter Kasting
2013/12/03 00:33:51
Nit: Wrapping the } is fine, but in that case, als
Maria
2013/12/03 01:00:26
Done.
| |
3760 | 3793 |
3761 struct { | 3794 struct { |
3762 const std::string input_text; | 3795 const std::string input_text; |
3763 const std::string default_provider_response_json; | 3796 const std::string default_provider_response_json; |
3764 const Match matches[4]; | 3797 const Match matches[4]; |
3765 } cases[] = { | 3798 } cases[] = { |
3766 // No XSSI guard. | 3799 // No XSSI guard. |
3767 { "a", | 3800 { "a", |
3768 "[\"a\",[\"b\", \"c\"],[],[]," | 3801 "[\"a\",[\"b\", \"c\"],[],[]," |
3769 "{\"google:suggesttype\":[\"QUERY\",\"QUERY\"]," | 3802 "{\"google:suggesttype\":[\"QUERY\",\"QUERY\"]," |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3828 EXPECT_EQ(cases[i].matches[j].type, matches[j].type); | 3861 EXPECT_EQ(cases[i].matches[j].type, matches[j].type); |
3829 } | 3862 } |
3830 for (; j < ARRAYSIZE_UNSAFE(cases[i].matches); ++j) { | 3863 for (; j < ARRAYSIZE_UNSAFE(cases[i].matches); ++j) { |
3831 SCOPED_TRACE("and match: " + base::IntToString(j)); | 3864 SCOPED_TRACE("and match: " + base::IntToString(j)); |
3832 EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable); | 3865 EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable); |
3833 EXPECT_EQ(cases[i].matches[j].type, AutocompleteMatchType::NUM_TYPES); | 3866 EXPECT_EQ(cases[i].matches[j].type, AutocompleteMatchType::NUM_TYPES); |
3834 } | 3867 } |
3835 } | 3868 } |
3836 } | 3869 } |
3837 | 3870 |
3871 // Test that deletion url gets set on an AutocompleteMatch when available for a | |
3872 // personalized query. | |
3873 TEST_F(SearchProviderTest, ParseDeletionUrl) { | |
3874 struct Match { | |
3875 std::string contents; | |
3876 std::string deletion_url; | |
3877 AutocompleteMatchType::Type type; | |
3878 }; | |
3879 | |
3880 const Match kEmptyMatch = { | |
3881 kNotApplicable, "", AutocompleteMatchType::NUM_TYPES | |
3882 }; | |
3883 | |
3884 const char url[] = "https://www.google.com/complete/deleteitems" | |
3885 "?delq=ab&client=chrome&deltok=xsrf123"; | |
3886 | |
3887 struct { | |
3888 const std::string input_text; | |
3889 const std::string response_json; | |
3890 const Match matches[4]; | |
3891 } cases[] = { | |
3892 // A deletion URL on a personalized query should be reflected in the | |
3893 // resulting AutocompleteMatch. | |
3894 { "a", | |
3895 "[\"a\",[\"ab\", \"ac\"],[],[]," | |
3896 "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\"]," | |
3897 "\"google:suggestrelevance\":[1, 2]," | |
3898 "\"google:suggestdetail\":[{\"du\":" | |
3899 "\"https://www.google.com/complete/deleteitems?delq=ab&client=chrome" | |
3900 "&deltok=xsrf123\"}, {}]}]", | |
3901 { { "a", "", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED }, | |
3902 { "ac", "", AutocompleteMatchType::SEARCH_SUGGEST }, | |
3903 { "ab", url, AutocompleteMatchType::SEARCH_SUGGEST }, | |
3904 kEmptyMatch, | |
3905 }, | |
3906 }, | |
3907 // Personalized queries without deletion URLs shouldn't cause errors. | |
3908 { "a", | |
3909 "[\"a\",[\"ab\", \"ac\"],[],[]," | |
3910 "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\"]," | |
3911 "\"google:suggestrelevance\":[1, 2]," | |
3912 "\"google:suggestdetail\":[{}, {}]}]", | |
3913 { { "a", "", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED }, | |
3914 { "ac", "", AutocompleteMatchType::SEARCH_SUGGEST }, | |
3915 { "ab", "", AutocompleteMatchType::SEARCH_SUGGEST }, | |
3916 kEmptyMatch, | |
3917 }, | |
3918 }, | |
3919 }; | |
3920 | |
3921 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { | |
3922 QueryForInput(ASCIIToUTF16(cases[i].input_text), false, false); | |
3923 | |
3924 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID( | |
3925 SearchProvider::kDefaultProviderURLFetcherID); | |
3926 ASSERT_TRUE(fetcher); | |
3927 fetcher->set_response_code(200); | |
3928 fetcher->SetResponseString(cases[i].response_json); | |
3929 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
3930 | |
3931 RunTillProviderDone(); | |
3932 | |
3933 const ACMatches& matches = provider_->matches(); | |
3934 ASSERT_FALSE(matches.empty()); | |
3935 | |
3936 SCOPED_TRACE("for input with json = " + cases[i].response_json); | |
3937 | |
3938 for (size_t j = 0; j < matches.size(); ++j) { | |
3939 const Match& match = cases[i].matches[j]; | |
3940 SCOPED_TRACE(" and match index: " + base::IntToString(j)); | |
3941 EXPECT_EQ(match.contents, UTF16ToUTF8(matches[j].contents)); | |
3942 EXPECT_EQ(match.deletion_url, matches[j].GetAdditionalInfo( | |
3943 "deletion_url")); | |
3944 } | |
3945 } | |
3946 } | |
3838 | 3947 |
3839 TEST_F(SearchProviderTest, ReflectsBookmarkBarState) { | 3948 TEST_F(SearchProviderTest, ReflectsBookmarkBarState) { |
3840 profile_.GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); | 3949 profile_.GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); |
3841 string16 term = term1_.substr(0, term1_.length() - 1); | 3950 string16 term = term1_.substr(0, term1_.length() - 1); |
3842 QueryForInput(term, true, false); | 3951 QueryForInput(term, true, false); |
3843 ASSERT_FALSE(provider_->matches().empty()); | 3952 ASSERT_FALSE(provider_->matches().empty()); |
3844 EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, | 3953 EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
3845 provider_->matches()[0].type); | 3954 provider_->matches()[0].type); |
3846 ASSERT_TRUE(provider_->matches()[0].search_terms_args != NULL); | 3955 ASSERT_TRUE(provider_->matches()[0].search_terms_args != NULL); |
3847 EXPECT_FALSE(provider_->matches()[0].search_terms_args->bookmark_bar_pinned); | 3956 EXPECT_FALSE(provider_->matches()[0].search_terms_args->bookmark_bar_pinned); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3974 AutocompleteInput::OTHER, &profile_)); | 4083 AutocompleteInput::OTHER, &profile_)); |
3975 encrypted_types.Remove(syncer::SESSIONS); | 4084 encrypted_types.Remove(syncer::SESSIONS); |
3976 service->OnEncryptedTypesChanged(encrypted_types, false); | 4085 service->OnEncryptedTypesChanged(encrypted_types, false); |
3977 | 4086 |
3978 // Check that there were no side effects from previous tests. | 4087 // Check that there were no side effects from previous tests. |
3979 EXPECT_TRUE(SearchProvider::CanSendURL( | 4088 EXPECT_TRUE(SearchProvider::CanSendURL( |
3980 GURL("http://www.google.com/search"), | 4089 GURL("http://www.google.com/search"), |
3981 GURL("https://www.google.com/complete/search"), &google_template_url, | 4090 GURL("https://www.google.com/complete/search"), &google_template_url, |
3982 AutocompleteInput::OTHER, &profile_)); | 4091 AutocompleteInput::OTHER, &profile_)); |
3983 } | 4092 } |
4093 | |
4094 TEST_F(SearchProviderTest, TestDeleteMatch_HasDeletionUrlSuccess) { | |
Anuj
2013/12/03 01:25:47
I think TestDeleteMatch_Success is sufficient. Has
| |
4095 AutocompleteMatch match(provider_, 0, true, | |
4096 AutocompleteMatchType::SEARCH_SUGGEST); | |
4097 match.RecordAdditionalInfo( | |
4098 SearchProvider::kDeletionUrlKey, | |
4099 "https://www.google.com/complete/deleteitem?q=foo"); | |
4100 provider_->matches_.push_back(match); | |
4101 provider_->DeleteMatch(match); | |
Anuj
2013/12/03 01:25:47
An empty line before this to create separation bet
Maria
2013/12/03 01:40:15
Done.
| |
4102 ASSERT_FALSE(provider_->deletion_handlers_.empty()); | |
4103 ASSERT_TRUE(provider_->matches_.empty()); | |
4104 // Set up a default fetcher with provided results. | |
4105 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID( | |
4106 SearchProvider::kDeletionURLFetcherID); | |
4107 ASSERT_TRUE(fetcher); | |
Anuj
2013/12/03 01:25:47
Omit this? It doesn't seem particularly useful.
Maria
2013/12/03 01:40:15
All the other tests in this class do it. It's usef
| |
4108 fetcher->set_response_code(200); | |
Anuj
2013/12/03 01:25:47
Move the fetcher set up code before the call to De
Maria
2013/12/03 01:40:15
That's not possible because GetFetcherByID relies
| |
4109 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
4110 ASSERT_TRUE(provider_->deletion_handlers_.empty()); | |
4111 ASSERT_TRUE(provider_->is_success()); | |
4112 } | |
4113 | |
4114 TEST_F(SearchProviderTest, TestDeleteMatch_HasDeletionUrlFailure) { | |
4115 AutocompleteMatch match(provider_, 0, true, | |
4116 AutocompleteMatchType::SEARCH_SUGGEST); | |
4117 match.RecordAdditionalInfo( | |
4118 SearchProvider::kDeletionUrlKey, | |
4119 "https://www.google.com/complete/deleteitem?q=foo"); | |
Peter Kasting
2013/12/03 00:33:51
Nit: If we combine these two tests into one, we ca
Maria
2013/12/03 01:00:26
We could, but I'd rather have two separate test ca
Peter Kasting
2013/12/03 01:03:22
They shouldn't depend on each other's passing. Wh
Anuj
2013/12/03 01:25:47
I have been told that the assert/expects should no
| |
4120 provider_->matches_.push_back(match); | |
4121 provider_->DeleteMatch(match); | |
4122 ASSERT_FALSE(provider_->deletion_handlers_.empty()); | |
4123 ASSERT_TRUE(provider_->matches_.empty()); | |
4124 // Set up a default fetcher with provided results. | |
4125 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID( | |
4126 SearchProvider::kDeletionURLFetcherID); | |
4127 ASSERT_TRUE(fetcher); | |
4128 fetcher->set_response_code(500); | |
4129 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
4130 ASSERT_TRUE(provider_->deletion_handlers_.empty()); | |
4131 ASSERT_FALSE(provider_->is_success()); | |
4132 } | |
OLD | NEW |