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

Side by Side Diff: components/omnibox/browser/physical_web_provider_unittest.cc

Issue 2319033006: Include a page title in the Physical Web omnibox overflow item (Closed)
Patch Set: move kPhysicalWebMaxMatches declaration Created 4 years, 3 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
« no previous file with comments | « components/omnibox/browser/physical_web_provider.cc ('k') | components/omnibox_strings.grdp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/omnibox/browser/physical_web_provider.h" 5 #include "components/omnibox/browser/physical_web_provider.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "components/metrics/proto/omnibox_event.pb.h" 14 #include "components/metrics/proto/omnibox_event.pb.h"
15 #include "components/omnibox/browser/mock_autocomplete_provider_client.h" 15 #include "components/omnibox/browser/mock_autocomplete_provider_client.h"
16 #include "components/omnibox/browser/test_scheme_classifier.h" 16 #include "components/omnibox/browser/test_scheme_classifier.h"
17 #include "components/physical_web/data_source/physical_web_data_source.h" 17 #include "components/physical_web/data_source/physical_web_data_source.h"
18 #include "components/physical_web/data_source/physical_web_listener.h" 18 #include "components/physical_web/data_source/physical_web_listener.h"
19 #include "grit/components_strings.h" 19 #include "grit/components_strings.h"
20 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/gfx/text_elider.h"
23 #include "url/gurl.h" 24 #include "url/gurl.h"
24 25
25 namespace { 26 namespace {
26 27
27 // A mock implementation of the Physical Web data source that allows setting 28 // A mock implementation of the Physical Web data source that allows setting
28 // metadata for nearby URLs directly. 29 // metadata for nearby URLs directly.
29 class MockPhysicalWebDataSource : public PhysicalWebDataSource { 30 class MockPhysicalWebDataSource : public PhysicalWebDataSource {
30 public: 31 public:
31 MockPhysicalWebDataSource() : metadata_(new base::ListValue()) {} 32 MockPhysicalWebDataSource() : metadata_(new base::ListValue()) {}
32 ~MockPhysicalWebDataSource() override {} 33 ~MockPhysicalWebDataSource() override {}
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 // Convenience method to avoid downcasts when accessing the mock data source. 78 // Convenience method to avoid downcasts when accessing the mock data source.
78 MockPhysicalWebDataSource* GetMockPhysicalWebDataSource() { 79 MockPhysicalWebDataSource* GetMockPhysicalWebDataSource() {
79 return physical_web_data_source_.get(); 80 return physical_web_data_source_.get();
80 } 81 }
81 82
82 private: 83 private:
83 std::unique_ptr<MockPhysicalWebDataSource> physical_web_data_source_; 84 std::unique_ptr<MockPhysicalWebDataSource> physical_web_data_source_;
84 TestSchemeClassifier scheme_classifier_; 85 TestSchemeClassifier scheme_classifier_;
85 }; 86 };
86 87
88 } // namespace
89
87 class PhysicalWebProviderTest : public testing::Test { 90 class PhysicalWebProviderTest : public testing::Test {
88 protected: 91 protected:
89 PhysicalWebProviderTest() : provider_(NULL) {} 92 PhysicalWebProviderTest() : provider_(NULL) {}
90 ~PhysicalWebProviderTest() override {} 93 ~PhysicalWebProviderTest() override {}
91 94
92 void SetUp() override { 95 void SetUp() override {
93 client_.reset(new FakeAutocompleteProviderClient()); 96 client_.reset(new FakeAutocompleteProviderClient());
94 provider_ = PhysicalWebProvider::Create(client_.get(), nullptr); 97 provider_ = PhysicalWebProvider::Create(client_.get(), nullptr);
95 } 98 }
96 99
(...skipping 25 matching lines...) Expand all
122 static AutocompleteInput CreateInputForNTP() { 125 static AutocompleteInput CreateInputForNTP() {
123 return AutocompleteInput( 126 return AutocompleteInput(
124 base::string16(), base::string16::npos, std::string(), GURL(), 127 base::string16(), base::string16::npos, std::string(), GURL(),
125 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, 128 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS,
126 false, false, true, true, true, TestSchemeClassifier()); 129 false, false, true, true, true, TestSchemeClassifier());
127 } 130 }
128 131
129 // Construct an AutocompleteInput to represent tapping the omnibox with |url| 132 // Construct an AutocompleteInput to represent tapping the omnibox with |url|
130 // as the current web page. 133 // as the current web page.
131 static AutocompleteInput CreateInputWithCurrentUrl(const std::string& url) { 134 static AutocompleteInput CreateInputWithCurrentUrl(const std::string& url) {
132 return AutocompleteInput(base::ASCIIToUTF16(url), base::string16::npos, 135 return AutocompleteInput(base::UTF8ToUTF16(url), base::string16::npos,
133 std::string(), GURL(url), 136 std::string(), GURL(url),
134 metrics::OmniboxEventProto::OTHER, false, false, 137 metrics::OmniboxEventProto::OTHER, false, false,
135 true, true, true, TestSchemeClassifier()); 138 true, true, true, TestSchemeClassifier());
136 } 139 }
137 140
141 // For a given |match|, check that the destination URL, contents string,
142 // description string, and default match state agree with the values specified
143 // in |url|, |contents|, |description|, and |allowed_to_be_default_match|.
144 static void ValidateMatch(const AutocompleteMatch& match,
145 const std::string& url,
146 const std::string& contents,
147 const std::string& description,
148 bool allowed_to_be_default_match) {
149 EXPECT_EQ(url, match.destination_url.spec());
150 EXPECT_EQ(contents, base::UTF16ToUTF8(match.contents));
151 EXPECT_EQ(description, base::UTF16ToUTF8(match.description));
152 EXPECT_EQ(allowed_to_be_default_match, match.allowed_to_be_default_match);
153 }
154
155 // Returns the contents string for an overflow item. Use |truncated_title|
156 // as the title of the first match, |match_count_without_default| as the
157 // total number of matches (not counting the default match), and
158 // |metadata_count| as the number of nearby Physical Web URLs for which we
159 // have metadata.
160 static std::string ConstructOverflowItemContents(
161 const std::string& truncated_title,
162 size_t match_count_without_default,
163 size_t metadata_count) {
164 // Don't treat the overflow item as a metadata match.
165 const size_t metadata_match_count = match_count_without_default - 1;
166 // Determine how many URLs we didn't create match items for.
167 const size_t additional_url_count = metadata_count - metadata_match_count;
168
169 // Build the contents string.
170 if (truncated_title.empty()) {
171 return l10n_util::GetPluralStringFUTF8(
172 IDS_PHYSICAL_WEB_OVERFLOW_EMPTY_TITLE, additional_url_count);
173 } else {
174 // Subtract one from the additional URL count because the first item is
175 // represented by its title.
176 std::string contents_suffix = l10n_util::GetPluralStringFUTF8(
177 IDS_PHYSICAL_WEB_OVERFLOW, additional_url_count - 1);
178 return truncated_title + " " + contents_suffix;
179 }
180 }
181
182 // Run a test case using |input| as the simulated state of the omnibox input
183 // field, |metadata_list| as the list of simulated Physical Web metadata,
184 // and |title_truncated| as the truncated title of the first match. In
185 // addition to checking the fields of the overflow item, this will also check
186 // that the total number of matches is equal to |expected_match_count| and
187 // that a default match and overflow item are only present when
188 // |should_expect_default_match| or |should_expect_overflow_item| are true.
189 // Metadata matches are not checked.
190 void OverflowItemTestCase(const AutocompleteInput& input,
191 std::unique_ptr<base::ListValue> metadata_list,
192 const std::string& title_truncated,
193 size_t expected_match_count,
194 bool should_expect_default_match,
195 bool should_expect_overflow_item) {
196 const size_t metadata_count = metadata_list->GetSize();
197
198 MockPhysicalWebDataSource* data_source =
199 client_->GetMockPhysicalWebDataSource();
200 EXPECT_TRUE(data_source);
201
202 data_source->SetMetadata(std::move(metadata_list));
203
204 provider_->Start(input, false);
205
206 const size_t match_count = provider_->matches().size();
207 EXPECT_EQ(expected_match_count, match_count);
208
209 const size_t match_count_without_default =
210 should_expect_default_match ? match_count - 1 : match_count;
211
212 if (should_expect_overflow_item) {
213 EXPECT_LT(match_count_without_default, metadata_count);
214 } else {
215 EXPECT_EQ(match_count_without_default, metadata_count);
216 }
217
218 size_t overflow_match_count = 0;
219 size_t default_match_count = 0;
220 for (const auto& match : provider_->matches()) {
221 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) {
222 std::string contents = ConstructOverflowItemContents(
223 title_truncated, match_count_without_default, metadata_count);
224 ValidateMatch(
225 match, "chrome://physical-web/", contents,
226 l10n_util::GetStringUTF8(IDS_PHYSICAL_WEB_OVERFLOW_DESCRIPTION),
227 false);
228 ++overflow_match_count;
229 } else if (match.allowed_to_be_default_match) {
230 ++default_match_count;
231 }
232 }
233 EXPECT_EQ(should_expect_overflow_item ? 1U : 0U, overflow_match_count);
234 EXPECT_EQ(should_expect_default_match ? 1U : 0U, default_match_count);
235 }
236
138 std::unique_ptr<FakeAutocompleteProviderClient> client_; 237 std::unique_ptr<FakeAutocompleteProviderClient> client_;
139 scoped_refptr<PhysicalWebProvider> provider_; 238 scoped_refptr<PhysicalWebProvider> provider_;
140 239
141 private: 240 private:
142 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest); 241 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest);
143 }; 242 };
144 243
145 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) { 244 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) {
146 MockPhysicalWebDataSource* data_source = 245 MockPhysicalWebDataSource* data_source =
147 client_->GetMockPhysicalWebDataSource(); 246 client_->GetMockPhysicalWebDataSource();
(...skipping 27 matching lines...) Expand all
175 274
176 data_source->SetMetadata(std::move(metadata_list)); 275 data_source->SetMetadata(std::move(metadata_list));
177 276
178 // Run the test with no text in the omnibox input to simulate NTP. 277 // Run the test with no text in the omnibox input to simulate NTP.
179 provider_->Start(CreateInputForNTP(), false); 278 provider_->Start(CreateInputForNTP(), false);
180 279
181 // Check that there is only one match item and its fields are correct. 280 // Check that there is only one match item and its fields are correct.
182 EXPECT_EQ(1U, provider_->matches().size()); 281 EXPECT_EQ(1U, provider_->matches().size());
183 const AutocompleteMatch& metadata_match = provider_->matches().front(); 282 const AutocompleteMatch& metadata_match = provider_->matches().front();
184 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type); 283 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type);
185 EXPECT_EQ(resolved_url, metadata_match.destination_url.spec()); 284 ValidateMatch(metadata_match, resolved_url, resolved_url, title, false);
186 EXPECT_EQ(resolved_url, base::UTF16ToASCII(metadata_match.contents));
187 EXPECT_EQ(title, base::UTF16ToASCII(metadata_match.description));
188 EXPECT_FALSE(metadata_match.allowed_to_be_default_match);
189 285
190 // Run the test again with a URL in the omnibox input. An additional match 286 // Run the test again with a URL in the omnibox input. An additional match
191 // should be added as a default match. 287 // should be added as a default match.
192 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); 288 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false);
193 289
194 size_t metadata_match_count = 0; 290 size_t metadata_match_count = 0;
195 size_t default_match_count = 0; 291 size_t default_match_count = 0;
196 for (const auto& match : provider_->matches()) { 292 for (const auto& match : provider_->matches()) {
197 if (match.type == AutocompleteMatchType::PHYSICAL_WEB) { 293 if (match.type == AutocompleteMatchType::PHYSICAL_WEB) {
198 EXPECT_EQ(resolved_url, match.destination_url.spec()); 294 ValidateMatch(match, resolved_url, resolved_url, title, false);
199 EXPECT_EQ(resolved_url, base::UTF16ToASCII(match.contents));
200 EXPECT_EQ(title, base::UTF16ToASCII(match.description));
201 EXPECT_FALSE(match.allowed_to_be_default_match);
202 ++metadata_match_count; 295 ++metadata_match_count;
203 } else { 296 } else {
204 EXPECT_TRUE(match.allowed_to_be_default_match); 297 EXPECT_TRUE(match.allowed_to_be_default_match);
205 ++default_match_count; 298 ++default_match_count;
206 } 299 }
207 } 300 }
208 EXPECT_EQ(2U, provider_->matches().size()); 301 EXPECT_EQ(2U, provider_->matches().size());
209 EXPECT_EQ(1U, metadata_match_count); 302 EXPECT_EQ(1U, metadata_match_count);
210 EXPECT_EQ(1U, default_match_count); 303 EXPECT_EQ(1U, default_match_count);
211 } 304 }
212 305
213 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) {
214 // This test is intended to verify that an overflow item is created when the
215 // number of nearby Physical Web URLs exceeds the maximum allowable matches
216 // for this provider. The actual limit for the PhysicalWebProvider may be
217 // changed in the future, so create enough metadata to exceed the
218 // AutocompleteProvider's limit.
219 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1;
220
221 MockPhysicalWebDataSource* data_source =
222 client_->GetMockPhysicalWebDataSource();
223 EXPECT_TRUE(data_source);
224
225 data_source->SetMetadata(CreateMetadata(metadata_count));
226
227 {
228 // Run the test with no text in the omnibox input to simulate NTP.
229 provider_->Start(CreateInputForNTP(), false);
230
231 const size_t match_count = provider_->matches().size();
232 EXPECT_LT(match_count, metadata_count);
233
234 // Check that the overflow item is present and its fields are correct. There
235 // may be additional match items, but none should be marked as default.
236 size_t overflow_match_count = 0;
237 for (const auto& match : provider_->matches()) {
238 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) {
239 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec());
240 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents));
241 const size_t metadata_matches = match_count - 1;
242 std::string description = l10n_util::GetPluralStringFUTF8(
243 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches);
244 EXPECT_EQ(description, base::UTF16ToASCII(match.description));
245 ++overflow_match_count;
246 }
247 EXPECT_FALSE(match.allowed_to_be_default_match);
248 }
249 EXPECT_EQ(1U, overflow_match_count);
250 }
251
252 {
253 // Run the test again with a URL in the omnibox input. An additional match
254 // should be added as a default match.
255 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false);
256
257 const size_t match_count = provider_->matches().size();
258 EXPECT_LT(match_count - 1, metadata_count);
259
260 // Check that the overflow item and default match are present and their
261 // fields are correct.
262 size_t overflow_match_count = 0;
263 size_t default_match_count = 0;
264 for (const auto& match : provider_->matches()) {
265 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) {
266 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec());
267 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents));
268 const size_t metadata_matches = match_count - 2;
269 std::string description = l10n_util::GetPluralStringFUTF8(
270 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches);
271 EXPECT_EQ(description, base::UTF16ToASCII(match.description));
272 EXPECT_FALSE(match.allowed_to_be_default_match);
273 ++overflow_match_count;
274 } else if (match.allowed_to_be_default_match) {
275 ++default_match_count;
276 }
277 }
278 EXPECT_EQ(1U, overflow_match_count);
279 EXPECT_EQ(1U, default_match_count);
280 }
281 }
282
283 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) { 306 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) {
284 MockPhysicalWebDataSource* data_source = 307 MockPhysicalWebDataSource* data_source =
285 client_->GetMockPhysicalWebDataSource(); 308 client_->GetMockPhysicalWebDataSource();
286 EXPECT_TRUE(data_source); 309 EXPECT_TRUE(data_source);
287 310
288 data_source->SetMetadata(CreateMetadata(1)); 311 data_source->SetMetadata(CreateMetadata(1));
289 312
290 // Construct an AutocompleteInput to simulate user input in the omnibox input 313 // Construct an AutocompleteInput to simulate user input in the omnibox input
291 // field. The provider should not generate any matches. 314 // field. The provider should not generate any matches.
292 std::string text("user input"); 315 std::string text("user input");
293 const AutocompleteInput input(base::ASCIIToUTF16(text), text.length(), 316 const AutocompleteInput input(
294 std::string(), GURL(), 317 base::UTF8ToUTF16(text), text.length(), std::string(), GURL(),
295 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, 318 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS,
296 true, false, true, true, false, TestSchemeClassifier()); 319 true, false, true, true, false, TestSchemeClassifier());
297 provider_->Start(input, false); 320 provider_->Start(input, false);
298 321
299 EXPECT_TRUE(provider_->matches().empty()); 322 EXPECT_TRUE(provider_->matches().empty());
300 } 323 }
301 324
325 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) {
326 // Create enough metadata to guarantee an overflow item will be created.
327 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1;
328
329 // Run the test with no text in the omnibox input to simulate NTP.
330 OverflowItemTestCase(
331 CreateInputForNTP(), CreateMetadata(metadata_count), "Example title 0",
332 PhysicalWebProvider::kPhysicalWebMaxMatches, false, true);
333
334 // Run the test again with a URL in the omnibox input. An additional match
335 // should be added as a default match.
336 OverflowItemTestCase(CreateInputWithCurrentUrl("http://www.cnn.com"),
337 CreateMetadata(metadata_count), "Example title 0",
338 PhysicalWebProvider::kPhysicalWebMaxMatches + 1, true,
339 true);
302 } 340 }
341
342 TEST_F(PhysicalWebProviderTest, TestLongPageTitleIsTruncatedInOverflowItem) {
343 // Set a long title for the first item. The page title for this item will
344 // appear in the overflow item's content string.
345 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1);
346 base::DictionaryValue* metadata_item;
347 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item));
348 metadata_item->SetString("title", "Extra long example title 0");
349
350 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list),
351 "Extra long exa" + std::string(gfx::kEllipsis),
352 PhysicalWebProvider::kPhysicalWebMaxMatches, false,
353 true);
354 }
355
356 TEST_F(PhysicalWebProviderTest, TestEmptyPageTitleInOverflowItem) {
357 // Set an empty title for the first item. Because the title is empty, we will
358 // display an alternate string in the overflow item's contents.
359 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1);
360 base::DictionaryValue* metadata_item;
361 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item));
362 metadata_item->SetString("title", "");
363
364 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list), "",
365 PhysicalWebProvider::kPhysicalWebMaxMatches, false,
366 true);
367 }
368
369 TEST_F(PhysicalWebProviderTest, TestRTLPageTitleInOverflowItem) {
370 // Set a Hebrew title for the first item.
371 auto metadata_list = CreateMetadata(AutocompleteProvider::kMaxMatches + 1);
372 base::DictionaryValue* metadata_item;
373 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item));
374 metadata_item->SetString("title", "ויקיפדיה");
375
376 OverflowItemTestCase(CreateInputForNTP(), std::move(metadata_list),
377 "ויקיפדיה", PhysicalWebProvider::kPhysicalWebMaxMatches,
378 false, true);
379 }
OLDNEW
« no previous file with comments | « components/omnibox/browser/physical_web_provider.cc ('k') | components/omnibox_strings.grdp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698