Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc

Issue 2947283002: Unit-testing AnswerCardSearchProvider. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "chrome/browser/ui/app_list/search/app_search_provider.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10 #include <string>
11 #include <utility>
12
13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/field_trial_params.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/test/scoped_feature_list.h"
18 #include "chrome/browser/ui/app_list/app_list_test_util.h"
19 #include "chrome/browser/ui/app_list/search/answer_card/answer_card_search_provi der.h"
20 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "content/test/mock_navigation_handle.h"
23 #include "net/http/http_response_headers.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/app_list/app_list_features.h"
26 #include "ui/app_list/app_list_model.h"
27 #include "ui/app_list/search_result.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 views::View* const kView = reinterpret_cast<views::View*>(123456);
xiyuan 2017/06/22 16:43:21 Can we create a real views::View owned by AnswerCa
vadimt 2017/06/22 19:48:03 Done.
39 constexpr char kCatCardId[] = "http://meow.org/meow";
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 } // namespace
61
62 class AnswerCardSearchProviderTest : public AppListTestBase {
63 public:
64 AnswerCardSearchProviderTest() : field_trial_list_(nullptr) {}
65
66 void SetMockHeaders(std::string has_result,
67 std::string open_url,
68 std::string title) {
69 headers_->RemoveHeader("SearchAnswer-HasResult");
70 headers_->RemoveHeader("SearchAnswer-OpenResultUrl");
71 headers_->RemoveHeader("SearchAnswer-Title");
72
73 if (!has_result.empty())
74 headers_->AddHeader("SearchAnswer-HasResult: " + has_result);
75 if (!open_url.empty())
76 headers_->AddHeader("SearchAnswer-OpenResultUrl: " + open_url);
77 if (!title.empty())
78 headers_->AddHeader("SearchAnswer-Title: " + title);
79 }
80
81 void TestHeadersParsing(std::string has_result,
82 std::string open_url,
83 std::string title,
84 std::size_t expected_result_count) {
85 SetMockHeaders(has_result, open_url, title);
86
87 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat")));
88 provider()->Start(false, base::UTF8ToUTF16("cat"));
89
90 GURL url("http://beasts.org/search?q=cat");
91 EXPECT_CALL(*navigation_handle_.get(), GetURL()).WillOnce(ReturnRef(url));
92 provider()->DidFinishNavigation(navigation_handle_.get());
93
94 provider()->DidStopLoading();
95 provider()->UpdatePreferredSize(GetMaxValidCardSize());
96
97 EXPECT_EQ(expected_result_count, results().size());
xiyuan 2017/06/22 16:43:21 We might need a testing::Mock::VerifyAndClearE
vadimt 2017/06/22 19:48:03 Done.
98 }
99
100 AppListModel* model() const { return model_.get(); }
101
102 const SearchProvider::Results& results() { return provider()->results(); }
103
104 MockAnswerCardContents* contents() const { return contents_; }
105
106 AnswerCardSearchProvider* provider() const { return provider_.get(); }
107
108 content::MockNavigationHandle* navigation_handle() const {
109 return navigation_handle_.get();
110 }
111
112 // AppListTestBase overrides:
113 void SetUp() override {
114 AppListTestBase::SetUp();
115
116 model_ = base::MakeUnique<app_list::AppListModel>();
117 model_->SetSearchEngineIsGoogle(true);
118
119 controller_ = base::MakeUnique<::test::TestAppListControllerDelegate>();
120
121 // Set up card server URL.
122 std::map<std::string, std::string> params;
123 params["ServerUrl"] = "http://beasts.org/search";
124 base::AssociateFieldTrialParams("TestTrial", "TestGroup", params);
125 scoped_refptr<base::FieldTrial> trial =
126 base::FieldTrialList::CreateFieldTrial("TestTrial", "TestGroup");
127 std::unique_ptr<base::FeatureList> feature_list =
128 base::MakeUnique<base::FeatureList>();
129 feature_list->RegisterFieldTrialOverride(
130 features::kEnableAnswerCard.name,
131 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
132 scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
133
134 contents_ = new MockAnswerCardContents;
135 std::unique_ptr<AnswerCardContents> contents(contents_);
xiyuan 2017/06/22 16:43:22 Would presubmit script complains about using std::
vadimt 2017/06/22 19:48:03 No, presubmit is fine.
136 // Provider will own the MockAnswerCardContents instance.
137 provider_ = base::MakeUnique<AnswerCardSearchProvider>(
138 profile_.get(), model_.get(), nullptr, std::move(contents));
139
140 headers_ = new net::HttpResponseHeaders("");
141 SetMockHeaders("true", kCatCardId, kCatCardTitle);
142
143 navigation_handle_ = base::MakeUnique<content::MockNavigationHandle>();
144 ON_CALL(*navigation_handle_.get(), HasCommitted())
145 .WillByDefault(Return(true));
146 ON_CALL(*navigation_handle_.get(), IsErrorPage())
147 .WillByDefault(Return(false));
148 ON_CALL(*navigation_handle_.get(), IsInMainFrame())
149 .WillByDefault(Return(true));
150 ON_CALL(*navigation_handle_.get(), GetResponseHeaders())
151 .WillByDefault(Return(headers_.get()));
152
153 ON_CALL(*contents_, GetView()).WillByDefault(Return(kView));
154 }
155
156 private:
157 std::unique_ptr<app_list::AppListModel> model_;
158 std::unique_ptr<AnswerCardSearchProvider> provider_;
159 std::unique_ptr<::test::TestAppListControllerDelegate> controller_;
160 MockAnswerCardContents* contents_ = nullptr; // Unowned.
161 base::FieldTrialList field_trial_list_;
162 base::test::ScopedFeatureList scoped_feature_list_;
163 scoped_refptr<net::HttpResponseHeaders> headers_;
164 std::unique_ptr<content::MockNavigationHandle> navigation_handle_;
165
166 DISALLOW_COPY_AND_ASSIGN(AnswerCardSearchProviderTest);
167 };
168
169 // Basic event sequence.
170 TEST_F(AnswerCardSearchProviderTest, Basic) {
171 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat")));
172 provider()->Start(false, base::UTF8ToUTF16("cat"));
173 GURL url("http://beasts.org/search?q=cat");
174 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
175 provider()->DidFinishNavigation(navigation_handle());
176 provider()->DidStopLoading();
177 provider()->UpdatePreferredSize(GetMaxValidCardSize());
178
179 EXPECT_EQ(1UL, results().size());
180 SearchResult* result = results()[0].get();
181 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type());
182 EXPECT_EQ(kCatCardId, result->id());
183 EXPECT_EQ(1, result->relevance());
184 EXPECT_EQ(kView, result->view());
185 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title());
186 }
187
188 // Voice queries are ignored.
189 TEST_F(AnswerCardSearchProviderTest, VoiceQuery) {
190 EXPECT_CALL(*contents(), LoadURL(_)).Times(0);
191 provider()->Start(true, base::UTF8ToUTF16("cat"));
192 }
193
194 // Queries to non-Google search engines are ignored.
195 TEST_F(AnswerCardSearchProviderTest, NotGoogle) {
196 model()->SetSearchEngineIsGoogle(false);
197 EXPECT_CALL(*contents(), LoadURL(_)).Times(0);
198 provider()->Start(false, base::UTF8ToUTF16("cat"));
199 }
200
201 // Zero-query is ignored.
202 TEST_F(AnswerCardSearchProviderTest, EmptyQuery) {
203 EXPECT_CALL(*contents(), LoadURL(_)).Times(0);
204 provider()->Start(false, base::UTF8ToUTF16(""));
205 }
206
207 // Two queries, the second produces a card of exactly same size, so
208 // UpdatePreferredSize() doesn't come. The second query should still produce a
209 // result.
210 TEST_F(AnswerCardSearchProviderTest, TwoResultsSameSize) {
211 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat")));
212 provider()->Start(false, base::UTF8ToUTF16("cat"));
213 GURL url("http://beasts.org/search?q=cat");
214 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
215 provider()->DidFinishNavigation(navigation_handle());
216 provider()->DidStopLoading();
217 provider()->UpdatePreferredSize(GetMaxValidCardSize());
218
219 EXPECT_EQ(1UL, results().size());
220 SearchResult* result = results()[0].get();
221 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type());
222 EXPECT_EQ(kCatCardId, result->id());
223 EXPECT_EQ(1, result->relevance());
224 EXPECT_EQ(kView, result->view());
225 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title());
226
227 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=dog")));
228 provider()->Start(false, base::UTF8ToUTF16("dog"));
229 EXPECT_EQ(0UL, results().size());
230
231 url = GURL("http://beasts.org/search?q=dog");
232 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
233 SetMockHeaders("true", "http://woof.org/woof", "Dog is a friendly beast.");
234 provider()->DidFinishNavigation(navigation_handle());
235 provider()->DidStopLoading();
236 // No UpdatePreferredSize().
237
238 EXPECT_EQ(1UL, results().size());
239 result = results()[0].get();
240 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type());
241 EXPECT_EQ("http://woof.org/woof", result->id());
242 EXPECT_EQ(1, result->relevance());
243 EXPECT_EQ(kView, result->view());
244 EXPECT_EQ(base::UTF8ToUTF16("Dog is a friendly beast."), result->title());
245 }
246
247 // User enters a query character by character, so that each next query generates
248 // a web request while the previous one is still in progress. Only the last
249 // query should produce a result.
250 TEST_F(AnswerCardSearchProviderTest, InterruptedRequest) {
251 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=c")));
252 provider()->Start(false, base::UTF8ToUTF16("c"));
253 EXPECT_EQ(0UL, results().size());
254
255 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=ca")));
256 provider()->Start(false, base::UTF8ToUTF16("ca"));
257 EXPECT_EQ(0UL, results().size());
258
259 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat")));
260 provider()->Start(false, base::UTF8ToUTF16("cat"));
261 EXPECT_EQ(0UL, results().size());
262
263 SetMockHeaders("true", "http://c-meow", "Title c");
264 GURL url = GURL("http://beasts.org/search?q=c");
265 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
266 provider()->DidFinishNavigation(navigation_handle());
267 provider()->DidStopLoading();
268 EXPECT_EQ(0UL, results().size());
269
270 SetMockHeaders("true", "http://ca-meow", "Title ca");
271 url = GURL("http://beasts.org/search?q=ca");
272 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
273 provider()->DidFinishNavigation(navigation_handle());
274 provider()->DidStopLoading();
275 provider()->UpdatePreferredSize(gfx::Size(1, 1));
276 EXPECT_EQ(0UL, results().size());
277
278 SetMockHeaders("true", kCatCardId, kCatCardTitle);
279 url = GURL("http://beasts.org/search?q=cat");
280 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
281 provider()->DidFinishNavigation(navigation_handle());
282 provider()->DidStopLoading();
283 provider()->UpdatePreferredSize(GetMaxValidCardSize());
284 EXPECT_EQ(1UL, results().size());
285
286 SearchResult* result = results()[0].get();
287 EXPECT_EQ(SearchResult::DISPLAY_CARD, result->display_type());
288 EXPECT_EQ(kCatCardId, result->id());
289 EXPECT_EQ(base::UTF8ToUTF16(kCatCardTitle), result->title());
290 }
291
292 // Due to, for example, JS activity in the card, it can change its size after
293 // loading. We should hide the result while its size if larger than the allowed
294 // maximum.
295 TEST_F(AnswerCardSearchProviderTest, ChangingSize) {
296 EXPECT_CALL(*contents(), LoadURL(GURL("http://beasts.org/search?q=cat")));
297 provider()->Start(false, base::UTF8ToUTF16("cat"));
298 GURL url("http://beasts.org/search?q=cat");
299 EXPECT_CALL(*navigation_handle(), GetURL()).WillOnce(ReturnRef(url));
300 provider()->DidFinishNavigation(navigation_handle());
301 provider()->UpdatePreferredSize(gfx::Size(features::AnswerCardMaxWidth() + 1,
302 features::AnswerCardMaxHeight()));
303 provider()->DidStopLoading();
304 EXPECT_EQ(0UL, results().size());
305
306 provider()->UpdatePreferredSize(GetMaxValidCardSize());
307 EXPECT_EQ(1UL, results().size());
308
309 provider()->UpdatePreferredSize(gfx::Size(
310 features::AnswerCardMaxWidth(), features::AnswerCardMaxHeight() + 1));
311 EXPECT_EQ(0UL, results().size());
312
313 provider()->UpdatePreferredSize(GetMaxValidCardSize());
314 EXPECT_EQ(1UL, results().size());
315 }
316
317 // The result is generated only when all headers exist, and indicate presence of
318 // the result.
319 TEST_F(AnswerCardSearchProviderTest, Headers) {
320 TestHeadersParsing("true", kCatCardId, kCatCardTitle, 1UL);
321 TestHeadersParsing("false", kCatCardId, kCatCardTitle, 0UL);
322 TestHeadersParsing("", kCatCardId, kCatCardTitle, 0UL);
323 TestHeadersParsing("true", "", kCatCardTitle, 0UL);
324 TestHeadersParsing("true", kCatCardId, "", 0UL);
325 TestHeadersParsing("true", kCatCardId, kCatCardTitle, 1UL);
326 }
327
328 } // namespace test
329 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698