OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 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 <stddef.h> |
| 6 |
| 7 #include <memory> |
| 8 #include <string> |
| 9 #include <utility> |
| 10 |
| 11 #include "base/macros.h" |
| 12 #include "base/metrics/field_trial.h" |
| 13 #include "base/metrics/field_trial_params.h" |
| 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/test/scoped_feature_list.h" |
| 16 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 17 #include "chrome/browser/ui/app_list/app_list_test_util.h" |
| 18 #include "chrome/browser/ui/app_list/search/answer_card/answer_card_search_provi
der.h" |
| 19 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" |
| 20 #include "chrome/test/base/testing_profile.h" |
| 21 #include "components/search_engines/template_url_service.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 #include "ui/app_list/app_list_features.h" |
| 25 #include "ui/app_list/app_list_model.h" |
| 26 #include "ui/app_list/search_result.h" |
| 27 #include "ui/views/view.h" |
| 28 |
| 29 using ::testing::_; |
| 30 using ::testing::Return; |
| 31 using ::testing::ReturnRef; |
| 32 |
| 33 namespace app_list { |
| 34 namespace test { |
| 35 |
| 36 namespace { |
| 37 |
| 38 constexpr char kCatCardId[] = |
| 39 "https://www.google.com/search?q=cat&sourceid=chrome&ie=UTF-8"; |
| 40 constexpr char kCatCardTitle[] = "Cat is a furry beast."; |
| 41 |
| 42 class MockAnswerCardContents : public AnswerCardContents { |
| 43 public: |
| 44 MockAnswerCardContents() {} |
| 45 |
| 46 // AnswerCardContents overrides: |
| 47 MOCK_METHOD1(LoadURL, void(const GURL& url)); |
| 48 MOCK_CONST_METHOD0(IsLoading, bool()); |
| 49 MOCK_METHOD0(GetView, views::View*()); |
| 50 |
| 51 private: |
| 52 DISALLOW_COPY_AND_ASSIGN(MockAnswerCardContents); |
| 53 }; |
| 54 |
| 55 gfx::Size GetMaxValidCardSize() { |
| 56 return gfx::Size(features::AnswerCardMaxWidth(), |
| 57 features::AnswerCardMaxHeight()); |
| 58 } |
| 59 |
| 60 std::unique_ptr<KeyedService> CreateTemplateURLService( |
| 61 content::BrowserContext* context) { |
| 62 return base::MakeUnique<TemplateURLService>(nullptr, 0); |
| 63 } |
| 64 |
| 65 } // namespace |
| 66 |
| 67 class AnswerCardSearchProviderTest : public AppListTestBase { |
| 68 public: |
| 69 AnswerCardSearchProviderTest() : field_trial_list_(nullptr) {} |
| 70 |
| 71 void TestDidFinishNavigation(bool has_error, |
| 72 bool has_result, |
| 73 std::string title, |
| 74 std::size_t expected_result_count) { |
| 75 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat"))); |
| 76 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 77 |
| 78 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=cat"), |
| 79 has_error, has_result, title, ""); |
| 80 |
| 81 provider()->DidStopLoading(); |
| 82 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 83 |
| 84 EXPECT_EQ(expected_result_count, results().size()); |
| 85 |
| 86 testing::Mock::VerifyAndClearExpectations(contents()); |
| 87 } |
| 88 |
| 89 AppListModel* model() const { return model_.get(); } |
| 90 |
| 91 const SearchProvider::Results& results() { return provider()->results(); } |
| 92 |
| 93 MockAnswerCardContents* contents() const { return contents_; } |
| 94 |
| 95 AnswerCardSearchProvider* provider() const { return provider_.get(); } |
| 96 |
| 97 views::View* view() { return &view_; } |
| 98 |
| 99 // AppListTestBase overrides: |
| 100 void SetUp() override { |
| 101 AppListTestBase::SetUp(); |
| 102 |
| 103 model_ = base::MakeUnique<app_list::AppListModel>(); |
| 104 model_->SetSearchEngineIsGoogle(true); |
| 105 |
| 106 controller_ = base::MakeUnique<::test::TestAppListControllerDelegate>(); |
| 107 |
| 108 // Set up card server URL. |
| 109 std::map<std::string, std::string> params; |
| 110 params["ServerUrl"] = "http://beasts.org/search"; |
| 111 base::AssociateFieldTrialParams("TestTrial", "TestGroup", params); |
| 112 scoped_refptr<base::FieldTrial> trial = |
| 113 base::FieldTrialList::CreateFieldTrial("TestTrial", "TestGroup"); |
| 114 std::unique_ptr<base::FeatureList> feature_list = |
| 115 base::MakeUnique<base::FeatureList>(); |
| 116 feature_list->RegisterFieldTrialOverride( |
| 117 features::kEnableAnswerCard.name, |
| 118 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); |
| 119 scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); |
| 120 |
| 121 contents_ = new MockAnswerCardContents; |
| 122 std::unique_ptr<AnswerCardContents> contents(contents_); |
| 123 TemplateURLServiceFactory::GetInstance()->SetTestingFactory( |
| 124 profile_.get(), CreateTemplateURLService); |
| 125 // Provider will own the MockAnswerCardContents instance. |
| 126 provider_ = base::MakeUnique<AnswerCardSearchProvider>( |
| 127 profile_.get(), model_.get(), nullptr, std::move(contents)); |
| 128 |
| 129 ON_CALL(*contents_, GetView()).WillByDefault(Return(view())); |
| 130 } |
| 131 |
| 132 private: |
| 133 std::unique_ptr<app_list::AppListModel> model_; |
| 134 std::unique_ptr<AnswerCardSearchProvider> provider_; |
| 135 std::unique_ptr<::test::TestAppListControllerDelegate> controller_; |
| 136 MockAnswerCardContents* contents_ = nullptr; // Unowned. |
| 137 base::FieldTrialList field_trial_list_; |
| 138 base::test::ScopedFeatureList scoped_feature_list_; |
| 139 views::View view_; |
| 140 |
| 141 DISALLOW_COPY_AND_ASSIGN(AnswerCardSearchProviderTest); |
| 142 }; |
| 143 |
| 144 // Basic event sequence. |
| 145 TEST_F(AnswerCardSearchProviderTest, Basic) { |
| 146 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat"))); |
| 147 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 148 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=cat"), false, |
| 149 true, kCatCardTitle, "cat"); |
| 150 provider()->DidStopLoading(); |
| 151 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 152 |
| 153 EXPECT_EQ(1UL, results().size()); |
| 154 SearchResult* result = results()[0].get(); |
| 155 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type()); |
| 156 EXPECT_EQ(kCatCardId, result->id()); |
| 157 EXPECT_EQ(1, result->relevance()); |
| 158 EXPECT_EQ(view(), result->view()); |
| 159 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title()); |
| 160 } |
| 161 |
| 162 // Voice queries are ignored. |
| 163 TEST_F(AnswerCardSearchProviderTest, VoiceQuery) { |
| 164 EXPECT_CALL(*contents(), LoadURL(_)).Times(0); |
| 165 provider()->Start(true, base::UTF8ToUTF16("cat")); |
| 166 } |
| 167 |
| 168 // Queries to non-Google search engines are ignored. |
| 169 TEST_F(AnswerCardSearchProviderTest, NotGoogle) { |
| 170 model()->SetSearchEngineIsGoogle(false); |
| 171 EXPECT_CALL(*contents(), LoadURL(_)).Times(0); |
| 172 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 173 } |
| 174 |
| 175 // Zero-query is ignored. |
| 176 TEST_F(AnswerCardSearchProviderTest, EmptyQuery) { |
| 177 EXPECT_CALL(*contents(), LoadURL(_)).Times(0); |
| 178 provider()->Start(false, base::UTF8ToUTF16("")); |
| 179 } |
| 180 |
| 181 // Two queries, the second produces a card of exactly same size, so |
| 182 // UpdatePreferredSize() doesn't come. The second query should still produce a |
| 183 // result. |
| 184 TEST_F(AnswerCardSearchProviderTest, TwoResultsSameSize) { |
| 185 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat"))); |
| 186 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 187 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=cat"), false, |
| 188 true, kCatCardTitle, "cat"); |
| 189 provider()->DidStopLoading(); |
| 190 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 191 |
| 192 EXPECT_EQ(1UL, results().size()); |
| 193 SearchResult* result = results()[0].get(); |
| 194 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type()); |
| 195 EXPECT_EQ(kCatCardId, result->id()); |
| 196 EXPECT_EQ(1, result->relevance()); |
| 197 EXPECT_EQ(view(), result->view()); |
| 198 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title()); |
| 199 |
| 200 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=dog"))); |
| 201 provider()->Start(false, base::UTF8ToUTF16("dog")); |
| 202 EXPECT_EQ(0UL, results().size()); |
| 203 |
| 204 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=dog"), false, |
| 205 true, "Dog is a friendly beast.", "dog"); |
| 206 provider()->DidStopLoading(); |
| 207 // No UpdatePreferredSize(). |
| 208 |
| 209 EXPECT_EQ(1UL, results().size()); |
| 210 result = results()[0].get(); |
| 211 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type()); |
| 212 EXPECT_EQ("https://www.google.com/search?q=dog&sourceid=chrome&ie=UTF-8", |
| 213 result->id()); |
| 214 EXPECT_EQ(1, result->relevance()); |
| 215 EXPECT_EQ(view(), result->view()); |
| 216 EXPECT_EQ(base::UTF8ToUTF16("Dog is a friendly beast."), result->title()); |
| 217 } |
| 218 |
| 219 // User enters a query character by character, so that each next query generates |
| 220 // a web request while the previous one is still in progress. Only the last |
| 221 // query should produce a result. |
| 222 TEST_F(AnswerCardSearchProviderTest, InterruptedRequest) { |
| 223 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=c"))); |
| 224 provider()->Start(false, base::UTF8ToUTF16("c")); |
| 225 EXPECT_EQ(0UL, results().size()); |
| 226 |
| 227 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=ca"))); |
| 228 provider()->Start(false, base::UTF8ToUTF16("ca")); |
| 229 EXPECT_EQ(0UL, results().size()); |
| 230 |
| 231 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat"))); |
| 232 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 233 EXPECT_EQ(0UL, results().size()); |
| 234 |
| 235 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=c"), false, |
| 236 true, "Title c", "c"); |
| 237 provider()->DidStopLoading(); |
| 238 EXPECT_EQ(0UL, results().size()); |
| 239 |
| 240 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=ca"), false, |
| 241 true, "Title ca", "ca"); |
| 242 provider()->DidStopLoading(); |
| 243 provider()->UpdatePreferredSize(gfx::Size(1, 1)); |
| 244 EXPECT_EQ(0UL, results().size()); |
| 245 |
| 246 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=cat"), false, |
| 247 true, kCatCardTitle, "cat"); |
| 248 provider()->DidStopLoading(); |
| 249 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 250 EXPECT_EQ(1UL, results().size()); |
| 251 |
| 252 SearchResult* result = results()[0].get(); |
| 253 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type()); |
| 254 EXPECT_EQ(kCatCardId, result->id()); |
| 255 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title()); |
| 256 } |
| 257 |
| 258 // Due to, for example, JS activity in the card, it can change its size after |
| 259 // loading. We should hide the result while its size if larger than the allowed |
| 260 // maximum. |
| 261 TEST_F(AnswerCardSearchProviderTest, ChangingSize) { |
| 262 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat"))); |
| 263 provider()->Start(false, base::UTF8ToUTF16("cat")); |
| 264 provider()->DidFinishNavigation(GURL("http://beasts.org/search?q=cat"), false, |
| 265 true, kCatCardTitle, "cat"); |
| 266 provider()->UpdatePreferredSize(gfx::Size(features::AnswerCardMaxWidth() + 1, |
| 267 features::AnswerCardMaxHeight())); |
| 268 provider()->DidStopLoading(); |
| 269 EXPECT_EQ(0UL, results().size()); |
| 270 |
| 271 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 272 EXPECT_EQ(1UL, results().size()); |
| 273 |
| 274 provider()->UpdatePreferredSize(gfx::Size( |
| 275 features::AnswerCardMaxWidth(), features::AnswerCardMaxHeight() + 1)); |
| 276 EXPECT_EQ(0UL, results().size()); |
| 277 |
| 278 provider()->UpdatePreferredSize(GetMaxValidCardSize()); |
| 279 EXPECT_EQ(1UL, results().size()); |
| 280 } |
| 281 |
| 282 // Various values for DidFinishNavigation params. |
| 283 TEST_F(AnswerCardSearchProviderTest, DidFinishNavigation) { |
| 284 TestDidFinishNavigation(false, true, kCatCardTitle, 1UL); |
| 285 TestDidFinishNavigation(true, true, kCatCardTitle, 0UL); |
| 286 TestDidFinishNavigation(false, false, kCatCardTitle, 0UL); |
| 287 TestDidFinishNavigation(false, true, "", 0UL); |
| 288 } |
| 289 |
| 290 } // namespace test |
| 291 } // namespace app_list |
OLD | NEW |