| OLD | NEW |
| 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" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 TestSchemeClassifier scheme_classifier_; | 84 TestSchemeClassifier scheme_classifier_; |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 class PhysicalWebProviderTest : public testing::Test { | 87 class PhysicalWebProviderTest : public testing::Test { |
| 88 protected: | 88 protected: |
| 89 PhysicalWebProviderTest() : provider_(NULL) {} | 89 PhysicalWebProviderTest() : provider_(NULL) {} |
| 90 ~PhysicalWebProviderTest() override {} | 90 ~PhysicalWebProviderTest() override {} |
| 91 | 91 |
| 92 void SetUp() override { | 92 void SetUp() override { |
| 93 client_.reset(new FakeAutocompleteProviderClient()); | 93 client_.reset(new FakeAutocompleteProviderClient()); |
| 94 provider_ = PhysicalWebProvider::Create(client_.get()); | 94 provider_ = PhysicalWebProvider::Create(client_.get(), NULL); |
| 95 } | 95 } |
| 96 | 96 |
| 97 void TearDown() override { | 97 void TearDown() override { |
| 98 provider_ = NULL; | 98 provider_ = NULL; |
| 99 } | 99 } |
| 100 | 100 |
| 101 // Create a dummy metadata list with |metadata_count| items. Each item is | 101 // Create a dummy metadata list with |metadata_count| items. Each item is |
| 102 // populated with a unique scanned URL and page metadata. | 102 // populated with a unique scanned URL and page metadata. |
| 103 static std::unique_ptr<base::ListValue> CreateMetadata( | 103 static std::unique_ptr<base::ListValue> CreateMetadata( |
| 104 size_t metadata_count) { | 104 size_t metadata_count) { |
| 105 auto metadata_list = base::MakeUnique<base::ListValue>(); | 105 auto metadata_list = base::MakeUnique<base::ListValue>(); |
| 106 for (size_t i = 0; i < metadata_count; ++i) { | 106 for (size_t i = 0; i < metadata_count; ++i) { |
| 107 std::string item_id = base::SizeTToString(i); | 107 std::string item_id = base::SizeTToString(i); |
| 108 std::string url = "https://example.com/" + item_id; | 108 std::string url = "https://example.com/" + item_id; |
| 109 auto metadata_item = base::MakeUnique<base::DictionaryValue>(); | 109 auto metadata_item = base::MakeUnique<base::DictionaryValue>(); |
| 110 metadata_item->SetString("scannedUrl", url); | 110 metadata_item->SetString("scannedUrl", url); |
| 111 metadata_item->SetString("resolvedUrl", url); | 111 metadata_item->SetString("resolvedUrl", url); |
| 112 metadata_item->SetString("icon", url); | 112 metadata_item->SetString("icon", url); |
| 113 metadata_item->SetString("title", "Example title " + item_id); | 113 metadata_item->SetString("title", "Example title " + item_id); |
| 114 metadata_item->SetString("description", "Example description " + item_id); | 114 metadata_item->SetString("description", "Example description " + item_id); |
| 115 metadata_list->Append(std::move(metadata_item)); | 115 metadata_list->Append(std::move(metadata_item)); |
| 116 } | 116 } |
| 117 return metadata_list; | 117 return metadata_list; |
| 118 } | 118 } |
| 119 | 119 |
| 120 // Construct an AutocompleteInput to represent tapping the omnibox from the |
| 121 // new tab page. |
| 122 static AutocompleteInput CreateInputForNTP() { |
| 123 return AutocompleteInput(base::string16(), base::string16::npos, |
| 124 std::string(), GURL(), |
| 125 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, |
| 126 false, false, true, true, true, TestSchemeClassifier()); |
| 127 } |
| 128 |
| 129 // Construct an AutocompleteInput to represent tapping the omnibox with |url| |
| 130 // as the current web page. |
| 131 static AutocompleteInput CreateInputWithCurrentUrl(const std::string& url) { |
| 132 return AutocompleteInput(base::ASCIIToUTF16(url), base::string16::npos, |
| 133 std::string(), GURL(url), metrics::OmniboxEventProto::OTHER, |
| 134 false, false, true, true, true, TestSchemeClassifier()); |
| 135 } |
| 136 |
| 120 std::unique_ptr<FakeAutocompleteProviderClient> client_; | 137 std::unique_ptr<FakeAutocompleteProviderClient> client_; |
| 121 scoped_refptr<PhysicalWebProvider> provider_; | 138 scoped_refptr<PhysicalWebProvider> provider_; |
| 122 | 139 |
| 123 private: | 140 private: |
| 124 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest); | 141 DISALLOW_COPY_AND_ASSIGN(PhysicalWebProviderTest); |
| 125 }; | 142 }; |
| 126 | 143 |
| 127 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) { | 144 TEST_F(PhysicalWebProviderTest, TestEmptyMetadataListCreatesNoMatches) { |
| 128 MockPhysicalWebDataSource* data_source = | 145 MockPhysicalWebDataSource* data_source = |
| 129 client_->GetMockPhysicalWebDataSource(); | 146 client_->GetMockPhysicalWebDataSource(); |
| 130 EXPECT_TRUE(data_source); | 147 EXPECT_TRUE(data_source); |
| 131 | 148 |
| 132 data_source->SetMetadata(CreateMetadata(0)); | 149 data_source->SetMetadata(CreateMetadata(0)); |
| 133 | 150 |
| 134 // Construct an AutocompleteInput representing a typical "zero-suggest" | 151 // Run the test with no text in the omnibox input to simulate NTP. |
| 135 // case. The provider will verify that the content of the omnibox input field | 152 provider_->Start(CreateInputForNTP(), false); |
| 136 // was not entered by the user. | 153 EXPECT_TRUE(provider_->matches().empty()); |
| 137 std::string url("http://www.cnn.com/"); | |
| 138 const AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, | |
| 139 std::string(), GURL(url), metrics::OmniboxEventProto::OTHER, | |
| 140 true, false, true, true, true, TestSchemeClassifier()); | |
| 141 provider_->Start(input, false); | |
| 142 | 154 |
| 155 // Run the test again with a URL in the omnibox input. |
| 156 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); |
| 143 EXPECT_TRUE(provider_->matches().empty()); | 157 EXPECT_TRUE(provider_->matches().empty()); |
| 144 } | 158 } |
| 145 | 159 |
| 146 TEST_F(PhysicalWebProviderTest, TestSingleMetadataItemCreatesOneMatch) { | 160 TEST_F(PhysicalWebProviderTest, TestSingleMetadataItemCreatesOneMatch) { |
| 147 MockPhysicalWebDataSource* data_source = | 161 MockPhysicalWebDataSource* data_source = |
| 148 client_->GetMockPhysicalWebDataSource(); | 162 client_->GetMockPhysicalWebDataSource(); |
| 149 EXPECT_TRUE(data_source); | 163 EXPECT_TRUE(data_source); |
| 150 | 164 |
| 151 // Extract the URL and title before inserting the metadata into the data | 165 // Extract the URL and title before inserting the metadata into the data |
| 152 // source. | 166 // source. |
| 153 std::unique_ptr<base::ListValue> metadata_list = CreateMetadata(1); | 167 std::unique_ptr<base::ListValue> metadata_list = CreateMetadata(1); |
| 154 base::DictionaryValue* metadata_item; | 168 base::DictionaryValue* metadata_item; |
| 155 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item)); | 169 EXPECT_TRUE(metadata_list->GetDictionary(0, &metadata_item)); |
| 156 std::string resolved_url; | 170 std::string resolved_url; |
| 157 EXPECT_TRUE(metadata_item->GetString("resolvedUrl", &resolved_url)); | 171 EXPECT_TRUE(metadata_item->GetString("resolvedUrl", &resolved_url)); |
| 158 std::string title; | 172 std::string title; |
| 159 EXPECT_TRUE(metadata_item->GetString("title", &title)); | 173 EXPECT_TRUE(metadata_item->GetString("title", &title)); |
| 160 | 174 |
| 161 data_source->SetMetadata(std::move(metadata_list)); | 175 data_source->SetMetadata(std::move(metadata_list)); |
| 162 | 176 |
| 163 // Construct an AutocompleteInput representing a typical "zero-suggest" | 177 // Run the test with no text in the omnibox input to simulate NTP. |
| 164 // case. The provider will verify that the content of the omnibox input field | 178 provider_->Start(CreateInputForNTP(), false); |
| 165 // was not entered by the user. | |
| 166 std::string url("http://www.cnn.com/"); | |
| 167 const AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, | |
| 168 std::string(), GURL(url), metrics::OmniboxEventProto::OTHER, | |
| 169 true, false, true, true, true, TestSchemeClassifier()); | |
| 170 provider_->Start(input, false); | |
| 171 | 179 |
| 172 // Check that there is only one match item and its fields are correct. | 180 // Check that there is only one match item and its fields are correct. |
| 173 EXPECT_EQ(1U, provider_->matches().size()); | 181 EXPECT_EQ(1U, provider_->matches().size()); |
| 174 const AutocompleteMatch& metadata_match = provider_->matches().front(); | 182 const AutocompleteMatch& metadata_match = provider_->matches().front(); |
| 175 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type); | 183 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, metadata_match.type); |
| 176 EXPECT_EQ(resolved_url, metadata_match.destination_url.spec()); | 184 EXPECT_EQ(resolved_url, metadata_match.destination_url.spec()); |
| 177 EXPECT_EQ(resolved_url, base::UTF16ToASCII(metadata_match.contents)); | 185 EXPECT_EQ(resolved_url, base::UTF16ToASCII(metadata_match.contents)); |
| 178 EXPECT_EQ(title, base::UTF16ToASCII(metadata_match.description)); | 186 EXPECT_EQ(title, base::UTF16ToASCII(metadata_match.description)); |
| 187 EXPECT_FALSE(metadata_match.allowed_to_be_default_match); |
| 188 |
| 189 // Run the test again with a URL in the omnibox input. An additional match |
| 190 // should be added as a default match. |
| 191 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); |
| 192 |
| 193 size_t metadata_match_count = 0; |
| 194 size_t default_match_count = 0; |
| 195 for (size_t i = 0; i < provider_->matches().size(); i++) { |
| 196 const AutocompleteMatch& match = provider_->matches()[i]; |
| 197 if (match.type == AutocompleteMatchType::PHYSICAL_WEB) { |
| 198 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB, match.type); |
| 199 EXPECT_EQ(resolved_url, match.destination_url.spec()); |
| 200 EXPECT_EQ(resolved_url, base::UTF16ToASCII(match.contents)); |
| 201 EXPECT_EQ(title, base::UTF16ToASCII(match.description)); |
| 202 EXPECT_FALSE(match.allowed_to_be_default_match); |
| 203 ++metadata_match_count; |
| 204 } else { |
| 205 EXPECT_TRUE(match.allowed_to_be_default_match); |
| 206 ++default_match_count; |
| 207 } |
| 208 } |
| 209 EXPECT_EQ(2U, provider_->matches().size()); |
| 210 EXPECT_EQ(1U, metadata_match_count); |
| 211 EXPECT_EQ(1U, default_match_count); |
| 179 } | 212 } |
| 180 | 213 |
| 181 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) { | 214 TEST_F(PhysicalWebProviderTest, TestManyMetadataItemsCreatesOverflowItem) { |
| 182 // This test is intended to verify that an overflow item is created when the | 215 // This test is intended to verify that an overflow item is created when the |
| 183 // number of nearby Physical Web URLs exceeds the maximum allowable matches | 216 // number of nearby Physical Web URLs exceeds the maximum allowable matches |
| 184 // for this provider. The actual limit for the PhysicalWebProvider may be | 217 // for this provider. The actual limit for the PhysicalWebProvider may be |
| 185 // changed in the future, so create enough metadata to exceed the | 218 // changed in the future, so create enough metadata to exceed the |
| 186 // AutocompleteProvider's limit. | 219 // AutocompleteProvider's limit. |
| 187 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1; | 220 const size_t metadata_count = AutocompleteProvider::kMaxMatches + 1; |
| 188 | 221 |
| 189 MockPhysicalWebDataSource* data_source = | 222 MockPhysicalWebDataSource* data_source = |
| 190 client_->GetMockPhysicalWebDataSource(); | 223 client_->GetMockPhysicalWebDataSource(); |
| 191 EXPECT_TRUE(data_source); | 224 EXPECT_TRUE(data_source); |
| 192 | 225 |
| 193 data_source->SetMetadata(CreateMetadata(metadata_count)); | 226 data_source->SetMetadata(CreateMetadata(metadata_count)); |
| 194 | 227 |
| 195 // Construct an AutocompleteInput representing a typical "zero-suggest" | 228 { |
| 196 // case. The provider will verify that the content of the omnibox input field | 229 // Run the test with no text in the omnibox input to simulate NTP. |
| 197 // was not entered by the user. | 230 provider_->Start(CreateInputForNTP(), false); |
| 198 std::string url("http://www.cnn.com/"); | |
| 199 const AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, | |
| 200 std::string(), GURL(url), metrics::OmniboxEventProto::OTHER, | |
| 201 true, false, true, true, true, TestSchemeClassifier()); | |
| 202 provider_->Start(input, false); | |
| 203 | 231 |
| 204 const size_t match_count = provider_->matches().size(); | 232 const size_t match_count = provider_->matches().size(); |
| 205 EXPECT_LT(match_count, metadata_count); | 233 EXPECT_LT(match_count, metadata_count); |
| 206 | 234 |
| 207 // Check that the overflow item is at the end of the match list and its fields | 235 // Check that the overflow item is present and its fields are correct. There |
| 208 // are correct. | 236 // may be additional match items, but none should be marked as default. |
| 209 const AutocompleteMatch& overflow_match = provider_->matches().back(); | 237 size_t overflow_match_count = 0; |
| 210 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW, overflow_match.type); | 238 for (size_t i = 0; i < match_count; i++) { |
| 211 EXPECT_EQ("chrome://physical-web/", overflow_match.destination_url.spec()); | 239 const AutocompleteMatch& match = provider_->matches()[i]; |
| 212 EXPECT_EQ("chrome://physical-web/", | 240 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) { |
| 213 base::UTF16ToASCII(overflow_match.contents)); | 241 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW, match.type); |
| 214 std::string description = l10n_util::GetPluralStringFUTF8( | 242 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec()); |
| 215 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - match_count + 1); | 243 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents)); |
| 216 EXPECT_EQ(description, base::UTF16ToASCII(overflow_match.description)); | 244 const size_t metadata_matches = match_count - 1; |
| 245 std::string description = l10n_util::GetPluralStringFUTF8( |
| 246 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches); |
| 247 EXPECT_EQ(description, base::UTF16ToASCII(match.description)); |
| 248 ++overflow_match_count; |
| 249 } |
| 250 EXPECT_FALSE(match.allowed_to_be_default_match); |
| 251 } |
| 252 EXPECT_EQ(1U, overflow_match_count); |
| 253 } |
| 254 |
| 255 { |
| 256 // Run the test again with a URL in the omnibox input. An additional match |
| 257 // should be added as a default match. |
| 258 provider_->Start(CreateInputWithCurrentUrl("http://www.cnn.com"), false); |
| 259 |
| 260 const size_t match_count = provider_->matches().size(); |
| 261 EXPECT_LT(match_count - 1, metadata_count); |
| 262 |
| 263 // Check that the overflow item and default match are present and their |
| 264 // fields are correct. |
| 265 size_t overflow_match_count = 0; |
| 266 size_t default_match_count = 0; |
| 267 for (size_t i = 0; i < match_count; i++) { |
| 268 const AutocompleteMatch& match = provider_->matches()[i]; |
| 269 if (match.type == AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW) { |
| 270 EXPECT_EQ(AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW, match.type); |
| 271 EXPECT_EQ("chrome://physical-web/", match.destination_url.spec()); |
| 272 EXPECT_EQ("chrome://physical-web/", base::UTF16ToASCII(match.contents)); |
| 273 const size_t metadata_matches = match_count - 2; |
| 274 std::string description = l10n_util::GetPluralStringFUTF8( |
| 275 IDS_PHYSICAL_WEB_OVERFLOW, metadata_count - metadata_matches); |
| 276 EXPECT_EQ(description, base::UTF16ToASCII(match.description)); |
| 277 EXPECT_FALSE(match.allowed_to_be_default_match); |
| 278 ++overflow_match_count; |
| 279 } else if (match.allowed_to_be_default_match) { |
| 280 ++default_match_count; |
| 281 } |
| 282 } |
| 283 EXPECT_EQ(1U, overflow_match_count); |
| 284 EXPECT_EQ(1U, default_match_count); |
| 285 } |
| 217 } | 286 } |
| 218 | 287 |
| 219 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) { | 288 TEST_F(PhysicalWebProviderTest, TestNoMatchesWithUserInput) { |
| 220 MockPhysicalWebDataSource* data_source = | 289 MockPhysicalWebDataSource* data_source = |
| 221 client_->GetMockPhysicalWebDataSource(); | 290 client_->GetMockPhysicalWebDataSource(); |
| 222 EXPECT_TRUE(data_source); | 291 EXPECT_TRUE(data_source); |
| 223 | 292 |
| 224 data_source->SetMetadata(CreateMetadata(1)); | 293 data_source->SetMetadata(CreateMetadata(1)); |
| 225 | 294 |
| 226 // Construct an AutocompleteInput to simulate user input in the omnibox input | 295 // Construct an AutocompleteInput to simulate user input in the omnibox input |
| 227 // field. The provider should not generate any matches. | 296 // field. The provider should not generate any matches. |
| 228 std::string text("user input"); | 297 std::string text("user input"); |
| 229 const AutocompleteInput input(base::ASCIIToUTF16(text), text.length(), | 298 const AutocompleteInput input(base::ASCIIToUTF16(text), text.length(), |
| 230 std::string(), GURL(), | 299 std::string(), GURL(), |
| 231 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, | 300 metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, |
| 232 true, false, true, true, false, TestSchemeClassifier()); | 301 true, false, true, true, false, TestSchemeClassifier()); |
| 233 provider_->Start(input, false); | 302 provider_->Start(input, false); |
| 234 | 303 |
| 235 EXPECT_TRUE(provider_->matches().empty()); | 304 EXPECT_TRUE(provider_->matches().empty()); |
| 236 } | 305 } |
| 237 | 306 |
| 238 } | 307 } |
| OLD | NEW |