OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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/android/contextualsearch/contextual_search_delegate.h" |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/android/contextualsearch/contextual_search_context.h" |
| 11 #include "components/search_engines/template_url_service.h" |
| 12 #include "net/url_request/test_url_fetcher_factory.h" |
| 13 #include "net/url_request/url_request_test_util.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 |
| 16 namespace { |
| 17 |
| 18 const char kSomeSpecificBasePage[] = "http://some.specific.host.name.com"; |
| 19 |
| 20 } // namespace |
| 21 |
| 22 class ContextualSearchDelegateTest : public testing::Test { |
| 23 public: |
| 24 ContextualSearchDelegateTest() {} |
| 25 ~ContextualSearchDelegateTest() override {} |
| 26 |
| 27 protected: |
| 28 void SetUp() override { |
| 29 request_context_ = new net::TestURLRequestContextGetter( |
| 30 io_message_loop_.message_loop_proxy()); |
| 31 template_url_service_.reset(CreateTemplateURLService()); |
| 32 delegate_.reset(new ContextualSearchDelegate( |
| 33 request_context_.get(), template_url_service_.get(), |
| 34 base::Bind( |
| 35 &ContextualSearchDelegateTest::recordSearchTermResolutionResponse, |
| 36 base::Unretained(this)), |
| 37 base::Bind(&ContextualSearchDelegateTest::recordSurroundingText, |
| 38 base::Unretained(this)), |
| 39 base::Bind(&ContextualSearchDelegateTest::recordIcingSelectionAvailable, |
| 40 base::Unretained(this)))); |
| 41 } |
| 42 |
| 43 void TearDown() override { |
| 44 fetcher_ = NULL; |
| 45 is_invalid_ = true; |
| 46 response_code_ = -1; |
| 47 search_term_ = "invalid"; |
| 48 display_text_ = "unknown"; |
| 49 } |
| 50 |
| 51 TemplateURLService* CreateTemplateURLService() { |
| 52 // Set a default search provider that supports Contextual Search. |
| 53 TemplateURLData data; |
| 54 data.SetURL("https://foobar.com/url?bar={searchTerms}"); |
| 55 data.contextual_search_url = "https://foobar.com/_/contextualsearch?" |
| 56 "{google:contextualSearchVersion}{google:contextualSearchContextData}"; |
| 57 TemplateURL* template_url = new TemplateURL(data); |
| 58 // Takes ownership of |template_url|. |
| 59 TemplateURLService* template_url_service = new TemplateURLService(NULL, 0); |
| 60 template_url_service->Add(template_url); |
| 61 template_url_service->SetUserSelectedDefaultSearchProvider(template_url); |
| 62 return template_url_service; |
| 63 } |
| 64 |
| 65 void CreateDefaultSearchContextAndRequestSearchTerm() { |
| 66 test_context_ = new ContextualSearchContext( |
| 67 "Barack Obama", true, GURL(kSomeSpecificBasePage), "utf-8"); |
| 68 // ContextualSearchDelegate class takes ownership of the context. |
| 69 delegate_->set_context_for_testing(test_context_); |
| 70 RequestSearchTerm(); |
| 71 } |
| 72 |
| 73 void SetSurroundingContext(const base::string16& surrounding_text, |
| 74 int start_offset, |
| 75 int end_offset) { |
| 76 test_context_ = new ContextualSearchContext( |
| 77 "Bogus", true, GURL(kSomeSpecificBasePage), "utf-8"); |
| 78 test_context_->surrounding_text = surrounding_text; |
| 79 test_context_->start_offset = start_offset; |
| 80 test_context_->end_offset = end_offset; |
| 81 // ContextualSearchDelegate class takes ownership of the context. |
| 82 delegate_->set_context_for_testing(test_context_); |
| 83 } |
| 84 |
| 85 void RequestSearchTerm() { |
| 86 test_context_->start_offset = 0; |
| 87 test_context_->end_offset = 6; |
| 88 test_context_->surrounding_text = |
| 89 base::UTF8ToUTF16("Barack Obama just spoke."); |
| 90 delegate_->ContinueSearchTermResolutionRequest(); |
| 91 fetcher_ = test_factory_.GetFetcherByID( |
| 92 ContextualSearchDelegate::kContextualSearchURLFetcherID); |
| 93 ASSERT_TRUE(fetcher_); |
| 94 ASSERT_TRUE(fetcher()); |
| 95 } |
| 96 |
| 97 bool DoesRequestContainOurSpecificBasePage() { |
| 98 return fetcher()->GetOriginalURL().spec().find( |
| 99 specific_base_page_URL_escaped()) != std::string::npos; |
| 100 } |
| 101 |
| 102 std::string specific_base_page_URL_escaped() { |
| 103 return net::EscapeQueryParamValue(kSomeSpecificBasePage, true); |
| 104 } |
| 105 |
| 106 net::TestURLFetcher* fetcher() { return fetcher_; } |
| 107 bool is_invalid() { return is_invalid_; } |
| 108 int response_code() { return response_code_; } |
| 109 std::string search_term() { return search_term_; } |
| 110 std::string display_text() { return display_text_; } |
| 111 std::string alternate_term() { return alternate_term_; } |
| 112 bool do_prevent_preload() { return prevent_preload_; } |
| 113 std::string before_text() { return before_text_; } |
| 114 std::string after_text() { return after_text_; } |
| 115 |
| 116 // The delegate under test. |
| 117 scoped_ptr<ContextualSearchDelegate> delegate_; |
| 118 |
| 119 private: |
| 120 void recordSearchTermResolutionResponse(bool is_invalid, |
| 121 int response_code, |
| 122 const std::string& search_term, |
| 123 const std::string& display_text, |
| 124 const std::string& alternate_term, |
| 125 bool prevent_preload) { |
| 126 is_invalid_ = is_invalid; |
| 127 response_code_ = response_code; |
| 128 search_term_ = search_term; |
| 129 display_text_ = display_text; |
| 130 alternate_term_ = alternate_term; |
| 131 prevent_preload_ = prevent_preload; |
| 132 } |
| 133 |
| 134 void recordSurroundingText(const std::string& before_text, |
| 135 const std::string& after_text) { |
| 136 before_text_ = before_text; |
| 137 after_text_ = after_text; |
| 138 } |
| 139 |
| 140 void recordIcingSelectionAvailable(const std::string& encoding, |
| 141 const base::string16& surrounding_text, |
| 142 size_t start_offset, |
| 143 size_t end_offset) { |
| 144 // unused. |
| 145 } |
| 146 |
| 147 bool is_invalid_; |
| 148 int response_code_; |
| 149 std::string search_term_; |
| 150 std::string display_text_; |
| 151 std::string alternate_term_; |
| 152 bool prevent_preload_; |
| 153 std::string before_text_; |
| 154 std::string after_text_; |
| 155 |
| 156 base::MessageLoopForIO io_message_loop_; |
| 157 net::TestURLFetcherFactory test_factory_; |
| 158 net::TestURLFetcher* fetcher_; |
| 159 scoped_ptr<TemplateURLService> template_url_service_; |
| 160 scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
| 161 |
| 162 // Will be owned by the delegate. |
| 163 ContextualSearchContext* test_context_; |
| 164 |
| 165 DISALLOW_COPY_AND_ASSIGN(ContextualSearchDelegateTest); |
| 166 }; |
| 167 |
| 168 TEST_F(ContextualSearchDelegateTest, NormalFetchWithXssiEscape) { |
| 169 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 170 fetcher()->set_response_code(200); |
| 171 fetcher()->SetResponseString( |
| 172 ")]}'\n" |
| 173 "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
| 174 "\"info_text\":\"44th U.S. President\"," |
| 175 "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
| 176 "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"); |
| 177 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 178 |
| 179 EXPECT_FALSE(is_invalid()); |
| 180 EXPECT_EQ(200, response_code()); |
| 181 EXPECT_EQ("obama", search_term()); |
| 182 EXPECT_EQ("Barack Obama", display_text()); |
| 183 EXPECT_FALSE(do_prevent_preload()); |
| 184 EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
| 185 } |
| 186 |
| 187 TEST_F(ContextualSearchDelegateTest, NormalFetchWithoutXssiEscape) { |
| 188 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 189 fetcher()->set_response_code(200); |
| 190 fetcher()->SetResponseString( |
| 191 "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
| 192 "\"info_text\":\"44th U.S. President\"," |
| 193 "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
| 194 "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"); |
| 195 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 196 |
| 197 EXPECT_FALSE(is_invalid()); |
| 198 EXPECT_EQ(200, response_code()); |
| 199 EXPECT_EQ("obama", search_term()); |
| 200 EXPECT_EQ("Barack Obama", display_text()); |
| 201 EXPECT_FALSE(do_prevent_preload()); |
| 202 EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
| 203 } |
| 204 |
| 205 TEST_F(ContextualSearchDelegateTest, ResponseWithNoDisplayText) { |
| 206 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 207 fetcher()->set_response_code(200); |
| 208 fetcher()->SetResponseString( |
| 209 "{\"mid\":\"/m/02mjmr\",\"search_term\":\"obama\"," |
| 210 "\"mentions\":[0,15]}"); |
| 211 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 212 |
| 213 EXPECT_FALSE(is_invalid()); |
| 214 EXPECT_EQ(200, response_code()); |
| 215 EXPECT_EQ("obama", search_term()); |
| 216 EXPECT_EQ("obama", display_text()); |
| 217 EXPECT_FALSE(do_prevent_preload()); |
| 218 EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
| 219 } |
| 220 |
| 221 TEST_F(ContextualSearchDelegateTest, ResponseWithPreventPreload) { |
| 222 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 223 fetcher()->set_response_code(200); |
| 224 fetcher()->SetResponseString( |
| 225 "{\"mid\":\"/m/02mjmr\",\"search_term\":\"obama\"," |
| 226 "\"mentions\":[0,15],\"prevent_preload\":\"1\"}"); |
| 227 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 228 |
| 229 EXPECT_FALSE(is_invalid()); |
| 230 EXPECT_EQ(200, response_code()); |
| 231 EXPECT_EQ("obama", search_term()); |
| 232 EXPECT_EQ("obama", display_text()); |
| 233 EXPECT_TRUE(do_prevent_preload()); |
| 234 EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
| 235 } |
| 236 |
| 237 TEST_F(ContextualSearchDelegateTest, NonJsonResponse) { |
| 238 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 239 fetcher()->set_response_code(200); |
| 240 fetcher()->SetResponseString("Non-JSON Response"); |
| 241 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 242 |
| 243 EXPECT_FALSE(is_invalid()); |
| 244 EXPECT_EQ(200, response_code()); |
| 245 EXPECT_EQ("", search_term()); |
| 246 EXPECT_EQ("", display_text()); |
| 247 EXPECT_FALSE(do_prevent_preload()); |
| 248 EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
| 249 } |
| 250 |
| 251 TEST_F(ContextualSearchDelegateTest, InvalidResponse) { |
| 252 CreateDefaultSearchContextAndRequestSearchTerm(); |
| 253 fetcher()->set_response_code(net::URLFetcher::RESPONSE_CODE_INVALID); |
| 254 fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
| 255 |
| 256 EXPECT_FALSE(do_prevent_preload()); |
| 257 EXPECT_TRUE(is_invalid()); |
| 258 } |
| 259 |
| 260 TEST_F(ContextualSearchDelegateTest, SurroundingTextHighMaximum) { |
| 261 base::string16 surrounding = base::ASCIIToUTF16("aa bb Bogus dd ee"); |
| 262 SetSurroundingContext(surrounding, 6, 11); |
| 263 delegate_->SendSurroundingText(30); // High maximum # of surrounding chars. |
| 264 EXPECT_EQ("aa bb", before_text()); |
| 265 EXPECT_EQ("dd ee", after_text()); |
| 266 } |
| 267 |
| 268 TEST_F(ContextualSearchDelegateTest, SurroundingTextLowMaximum) { |
| 269 base::string16 surrounding = base::ASCIIToUTF16("aa bb Bogus dd ee"); |
| 270 SetSurroundingContext(surrounding, 6, 11); |
| 271 delegate_->SendSurroundingText(3); // Low maximum # of surrounding chars. |
| 272 // Whitespaces are trimmed. |
| 273 EXPECT_EQ("bb", before_text()); |
| 274 EXPECT_EQ("dd", after_text()); |
| 275 } |
| 276 |
| 277 TEST_F(ContextualSearchDelegateTest, SurroundingTextNoBeforeText) { |
| 278 base::string16 surrounding = base::ASCIIToUTF16("Bogus ee ff gg"); |
| 279 SetSurroundingContext(surrounding, 0, 5); |
| 280 delegate_->SendSurroundingText(5); |
| 281 EXPECT_EQ("", before_text()); |
| 282 EXPECT_EQ("ee f", after_text()); |
| 283 } |
| 284 |
| 285 TEST_F(ContextualSearchDelegateTest, SurroundingTextForIcing) { |
| 286 base::string16 sample = base::ASCIIToUTF16("this is Barack Obama in office."); |
| 287 int limit_each_side = 3; |
| 288 size_t start = 8; |
| 289 size_t end = 20; |
| 290 base::string16 result = |
| 291 delegate_->SurroundingTextForIcing(sample, limit_each_side, &start, &end); |
| 292 EXPECT_EQ(static_cast<size_t>(3), start); |
| 293 EXPECT_EQ(static_cast<size_t>(15), end); |
| 294 EXPECT_EQ(base::ASCIIToUTF16("is Barack Obama in"), result); |
| 295 } |
| 296 |
| 297 TEST_F(ContextualSearchDelegateTest, SurroundingTextForIcingNegativeLimit) { |
| 298 base::string16 sample = base::ASCIIToUTF16("this is Barack Obama in office."); |
| 299 int limit_each_side = -2; |
| 300 size_t start = 8; |
| 301 size_t end = 20; |
| 302 base::string16 result = |
| 303 delegate_->SurroundingTextForIcing(sample, limit_each_side, &start, &end); |
| 304 EXPECT_EQ(static_cast<size_t>(0), start); |
| 305 EXPECT_EQ(static_cast<size_t>(12), end); |
| 306 EXPECT_EQ(base::ASCIIToUTF16("Barack Obama"), result); |
| 307 } |
| 308 |
| 309 TEST_F(ContextualSearchDelegateTest, DecodeSearchTermsFromJsonResponse) { |
| 310 std::string json_with_escape = |
| 311 ")]}'\n" |
| 312 "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
| 313 "\"info_text\":\"44th U.S. President\"," |
| 314 "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
| 315 "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"; |
| 316 std::string search_term; |
| 317 std::string display_text; |
| 318 std::string alternate_term; |
| 319 std::string prevent_preload; |
| 320 delegate_->DecodeSearchTermsFromJsonResponse(json_with_escape, &search_term, |
| 321 &display_text, &alternate_term, |
| 322 &prevent_preload); |
| 323 EXPECT_EQ("obama", search_term); |
| 324 EXPECT_EQ("Barack Obama", display_text); |
| 325 EXPECT_EQ("barack obama", alternate_term); |
| 326 EXPECT_EQ("", prevent_preload); |
| 327 } |
OLD | NEW |