Index: chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc |
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3ffcc76d4123aaf818d3a0e0086e204bb14813e1 |
--- /dev/null |
+++ b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc |
@@ -0,0 +1,327 @@ |
+// Copyright 2015 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 "chrome/browser/android/contextualsearch/contextual_search_delegate.h" |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "chrome/browser/android/contextualsearch/contextual_search_context.h" |
+#include "components/search_engines/template_url_service.h" |
+#include "net/url_request/test_url_fetcher_factory.h" |
+#include "net/url_request/url_request_test_util.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+const char kSomeSpecificBasePage[] = "http://some.specific.host.name.com"; |
+ |
+} // namespace |
+ |
+class ContextualSearchDelegateTest : public testing::Test { |
+ public: |
+ ContextualSearchDelegateTest() {} |
+ ~ContextualSearchDelegateTest() override {} |
+ |
+ protected: |
+ void SetUp() override { |
+ request_context_ = new net::TestURLRequestContextGetter( |
+ io_message_loop_.message_loop_proxy()); |
+ template_url_service_.reset(CreateTemplateURLService()); |
+ delegate_.reset(new ContextualSearchDelegate( |
+ request_context_.get(), template_url_service_.get(), |
+ base::Bind( |
+ &ContextualSearchDelegateTest::recordSearchTermResolutionResponse, |
+ base::Unretained(this)), |
+ base::Bind(&ContextualSearchDelegateTest::recordSurroundingText, |
+ base::Unretained(this)), |
+ base::Bind(&ContextualSearchDelegateTest::recordIcingSelectionAvailable, |
+ base::Unretained(this)))); |
+ } |
+ |
+ void TearDown() override { |
+ fetcher_ = NULL; |
+ is_invalid_ = true; |
+ response_code_ = -1; |
+ search_term_ = "invalid"; |
+ display_text_ = "unknown"; |
+ } |
+ |
+ TemplateURLService* CreateTemplateURLService() { |
+ // Set a default search provider that supports Contextual Search. |
+ TemplateURLData data; |
+ data.SetURL("https://foobar.com/url?bar={searchTerms}"); |
+ data.contextual_search_url = "https://foobar.com/_/contextualsearch?" |
+ "{google:contextualSearchVersion}{google:contextualSearchContextData}"; |
+ TemplateURL* template_url = new TemplateURL(data); |
+ // Takes ownership of |template_url|. |
+ TemplateURLService* template_url_service = new TemplateURLService(NULL, 0); |
+ template_url_service->Add(template_url); |
+ template_url_service->SetUserSelectedDefaultSearchProvider(template_url); |
+ return template_url_service; |
+ } |
+ |
+ void CreateDefaultSearchContextAndRequestSearchTerm() { |
+ test_context_ = new ContextualSearchContext( |
+ "Barack Obama", true, GURL(kSomeSpecificBasePage), "utf-8"); |
+ // ContextualSearchDelegate class takes ownership of the context. |
+ delegate_->set_context_for_testing(test_context_); |
+ RequestSearchTerm(); |
+ } |
+ |
+ void SetSurroundingContext(const base::string16& surrounding_text, |
+ int start_offset, |
+ int end_offset) { |
+ test_context_ = new ContextualSearchContext( |
+ "Bogus", true, GURL(kSomeSpecificBasePage), "utf-8"); |
+ test_context_->surrounding_text = surrounding_text; |
+ test_context_->start_offset = start_offset; |
+ test_context_->end_offset = end_offset; |
+ // ContextualSearchDelegate class takes ownership of the context. |
+ delegate_->set_context_for_testing(test_context_); |
+ } |
+ |
+ void RequestSearchTerm() { |
+ test_context_->start_offset = 0; |
+ test_context_->end_offset = 6; |
+ test_context_->surrounding_text = |
+ base::UTF8ToUTF16("Barack Obama just spoke."); |
+ delegate_->ContinueSearchTermResolutionRequest(); |
+ fetcher_ = test_factory_.GetFetcherByID( |
+ ContextualSearchDelegate::kContextualSearchURLFetcherID); |
+ ASSERT_TRUE(fetcher_); |
+ ASSERT_TRUE(fetcher()); |
+ } |
+ |
+ bool DoesRequestContainOurSpecificBasePage() { |
+ return fetcher()->GetOriginalURL().spec().find( |
+ specific_base_page_URL_escaped()) != std::string::npos; |
+ } |
+ |
+ std::string specific_base_page_URL_escaped() { |
+ return net::EscapeQueryParamValue(kSomeSpecificBasePage, true); |
+ } |
+ |
+ net::TestURLFetcher* fetcher() { return fetcher_; } |
+ bool is_invalid() { return is_invalid_; } |
+ int response_code() { return response_code_; } |
+ std::string search_term() { return search_term_; } |
+ std::string display_text() { return display_text_; } |
+ std::string alternate_term() { return alternate_term_; } |
+ bool do_prevent_preload() { return prevent_preload_; } |
+ std::string before_text() { return before_text_; } |
+ std::string after_text() { return after_text_; } |
+ |
+ // The delegate under test. |
+ scoped_ptr<ContextualSearchDelegate> delegate_; |
+ |
+ private: |
+ void recordSearchTermResolutionResponse(bool is_invalid, |
+ int response_code, |
+ const std::string& search_term, |
+ const std::string& display_text, |
+ const std::string& alternate_term, |
+ bool prevent_preload) { |
+ is_invalid_ = is_invalid; |
+ response_code_ = response_code; |
+ search_term_ = search_term; |
+ display_text_ = display_text; |
+ alternate_term_ = alternate_term; |
+ prevent_preload_ = prevent_preload; |
+ } |
+ |
+ void recordSurroundingText(const std::string& before_text, |
+ const std::string& after_text) { |
+ before_text_ = before_text; |
+ after_text_ = after_text; |
+ } |
+ |
+ void recordIcingSelectionAvailable(const std::string& encoding, |
+ const base::string16& surrounding_text, |
+ size_t start_offset, |
+ size_t end_offset) { |
+ // unused. |
+ } |
+ |
+ bool is_invalid_; |
+ int response_code_; |
+ std::string search_term_; |
+ std::string display_text_; |
+ std::string alternate_term_; |
+ bool prevent_preload_; |
+ std::string before_text_; |
+ std::string after_text_; |
+ |
+ base::MessageLoopForIO io_message_loop_; |
+ net::TestURLFetcherFactory test_factory_; |
+ net::TestURLFetcher* fetcher_; |
+ scoped_ptr<TemplateURLService> template_url_service_; |
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
+ |
+ // Will be owned by the delegate. |
+ ContextualSearchContext* test_context_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ContextualSearchDelegateTest); |
+}; |
+ |
+TEST_F(ContextualSearchDelegateTest, NormalFetchWithXssiEscape) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(200); |
+ fetcher()->SetResponseString( |
+ ")]}'\n" |
+ "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
+ "\"info_text\":\"44th U.S. President\"," |
+ "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
+ "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(is_invalid()); |
+ EXPECT_EQ(200, response_code()); |
+ EXPECT_EQ("obama", search_term()); |
+ EXPECT_EQ("Barack Obama", display_text()); |
+ EXPECT_FALSE(do_prevent_preload()); |
+ EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, NormalFetchWithoutXssiEscape) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(200); |
+ fetcher()->SetResponseString( |
+ "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
+ "\"info_text\":\"44th U.S. President\"," |
+ "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
+ "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(is_invalid()); |
+ EXPECT_EQ(200, response_code()); |
+ EXPECT_EQ("obama", search_term()); |
+ EXPECT_EQ("Barack Obama", display_text()); |
+ EXPECT_FALSE(do_prevent_preload()); |
+ EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, ResponseWithNoDisplayText) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(200); |
+ fetcher()->SetResponseString( |
+ "{\"mid\":\"/m/02mjmr\",\"search_term\":\"obama\"," |
+ "\"mentions\":[0,15]}"); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(is_invalid()); |
+ EXPECT_EQ(200, response_code()); |
+ EXPECT_EQ("obama", search_term()); |
+ EXPECT_EQ("obama", display_text()); |
+ EXPECT_FALSE(do_prevent_preload()); |
+ EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, ResponseWithPreventPreload) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(200); |
+ fetcher()->SetResponseString( |
+ "{\"mid\":\"/m/02mjmr\",\"search_term\":\"obama\"," |
+ "\"mentions\":[0,15],\"prevent_preload\":\"1\"}"); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(is_invalid()); |
+ EXPECT_EQ(200, response_code()); |
+ EXPECT_EQ("obama", search_term()); |
+ EXPECT_EQ("obama", display_text()); |
+ EXPECT_TRUE(do_prevent_preload()); |
+ EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, NonJsonResponse) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(200); |
+ fetcher()->SetResponseString("Non-JSON Response"); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(is_invalid()); |
+ EXPECT_EQ(200, response_code()); |
+ EXPECT_EQ("", search_term()); |
+ EXPECT_EQ("", display_text()); |
+ EXPECT_FALSE(do_prevent_preload()); |
+ EXPECT_TRUE(DoesRequestContainOurSpecificBasePage()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, InvalidResponse) { |
+ CreateDefaultSearchContextAndRequestSearchTerm(); |
+ fetcher()->set_response_code(net::URLFetcher::RESPONSE_CODE_INVALID); |
+ fetcher()->delegate()->OnURLFetchComplete(fetcher()); |
+ |
+ EXPECT_FALSE(do_prevent_preload()); |
+ EXPECT_TRUE(is_invalid()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, SurroundingTextHighMaximum) { |
+ base::string16 surrounding = base::ASCIIToUTF16("aa bb Bogus dd ee"); |
+ SetSurroundingContext(surrounding, 6, 11); |
+ delegate_->SendSurroundingText(30); // High maximum # of surrounding chars. |
+ EXPECT_EQ("aa bb", before_text()); |
+ EXPECT_EQ("dd ee", after_text()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, SurroundingTextLowMaximum) { |
+ base::string16 surrounding = base::ASCIIToUTF16("aa bb Bogus dd ee"); |
+ SetSurroundingContext(surrounding, 6, 11); |
+ delegate_->SendSurroundingText(3); // Low maximum # of surrounding chars. |
+ // Whitespaces are trimmed. |
+ EXPECT_EQ("bb", before_text()); |
+ EXPECT_EQ("dd", after_text()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, SurroundingTextNoBeforeText) { |
+ base::string16 surrounding = base::ASCIIToUTF16("Bogus ee ff gg"); |
+ SetSurroundingContext(surrounding, 0, 5); |
+ delegate_->SendSurroundingText(5); |
+ EXPECT_EQ("", before_text()); |
+ EXPECT_EQ("ee f", after_text()); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, SurroundingTextForIcing) { |
+ base::string16 sample = base::ASCIIToUTF16("this is Barack Obama in office."); |
+ int limit_each_side = 3; |
+ size_t start = 8; |
+ size_t end = 20; |
+ base::string16 result = |
+ delegate_->SurroundingTextForIcing(sample, limit_each_side, &start, &end); |
+ EXPECT_EQ(static_cast<size_t>(3), start); |
+ EXPECT_EQ(static_cast<size_t>(15), end); |
+ EXPECT_EQ(base::ASCIIToUTF16("is Barack Obama in"), result); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, SurroundingTextForIcingNegativeLimit) { |
+ base::string16 sample = base::ASCIIToUTF16("this is Barack Obama in office."); |
+ int limit_each_side = -2; |
+ size_t start = 8; |
+ size_t end = 20; |
+ base::string16 result = |
+ delegate_->SurroundingTextForIcing(sample, limit_each_side, &start, &end); |
+ EXPECT_EQ(static_cast<size_t>(0), start); |
+ EXPECT_EQ(static_cast<size_t>(12), end); |
+ EXPECT_EQ(base::ASCIIToUTF16("Barack Obama"), result); |
+} |
+ |
+TEST_F(ContextualSearchDelegateTest, DecodeSearchTermsFromJsonResponse) { |
+ std::string json_with_escape = |
+ ")]}'\n" |
+ "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\"," |
+ "\"info_text\":\"44th U.S. President\"," |
+ "\"display_text\":\"Barack Obama\", \"mentions\":[0,15]," |
+ "\"selected_text\":\"obama\", \"resolved_term\":\"barack obama\"}"; |
+ std::string search_term; |
+ std::string display_text; |
+ std::string alternate_term; |
+ std::string prevent_preload; |
+ delegate_->DecodeSearchTermsFromJsonResponse(json_with_escape, &search_term, |
+ &display_text, &alternate_term, |
+ &prevent_preload); |
+ EXPECT_EQ("obama", search_term); |
+ EXPECT_EQ("Barack Obama", display_text); |
+ EXPECT_EQ("barack obama", alternate_term); |
+ EXPECT_EQ("", prevent_preload); |
+} |