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/ntp_snippets/content_suggestions_service.h" | 5 #include "components/ntp_snippets/content_suggestions_service.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 | 80 |
81 void FireSuggestionsChanged(Category category, std::vector<int> numbers) { | 81 void FireSuggestionsChanged(Category category, std::vector<int> numbers) { |
82 observer()->OnNewSuggestions(this, category, CreateSuggestions(numbers)); | 82 observer()->OnNewSuggestions(this, category, CreateSuggestions(numbers)); |
83 } | 83 } |
84 | 84 |
85 void FireCategoryStatusChanged(Category category, CategoryStatus new_status) { | 85 void FireCategoryStatusChanged(Category category, CategoryStatus new_status) { |
86 statuses_[category.id()] = new_status; | 86 statuses_[category.id()] = new_status; |
87 observer()->OnCategoryStatusChanged(this, category, new_status); | 87 observer()->OnCategoryStatusChanged(this, category, new_status); |
88 } | 88 } |
89 | 89 |
90 void FireSuggestionInvalidated(Category category, | |
91 const std::string& suggestion_id) { | |
92 observer()->OnSuggestionInvalidated(this, category, suggestion_id); | |
93 } | |
94 | |
90 MOCK_METHOD1(ClearCachedSuggestionsForDebugging, void(Category category)); | 95 MOCK_METHOD1(ClearCachedSuggestionsForDebugging, void(Category category)); |
91 MOCK_METHOD1(GetDismissedSuggestionsForDebugging, | 96 MOCK_METHOD1(GetDismissedSuggestionsForDebugging, |
92 std::vector<ContentSuggestion>(Category category)); | 97 std::vector<ContentSuggestion>(Category category)); |
93 MOCK_METHOD1(ClearDismissedSuggestionsForDebugging, void(Category category)); | 98 MOCK_METHOD1(ClearDismissedSuggestionsForDebugging, void(Category category)); |
94 MOCK_METHOD1(DismissSuggestion, void(const std::string& suggestion_id)); | 99 MOCK_METHOD1(DismissSuggestion, void(const std::string& suggestion_id)); |
95 MOCK_METHOD2(FetchSuggestionImage, | 100 MOCK_METHOD2(FetchSuggestionImage, |
96 void(const std::string& suggestion_id, | 101 void(const std::string& suggestion_id, |
97 const ImageFetchedCallback& callback)); | 102 const ImageFetchedCallback& callback)); |
98 | 103 |
99 private: | 104 private: |
100 std::vector<Category> provided_categories_; | 105 std::vector<Category> provided_categories_; |
101 std::map<int, CategoryStatus> statuses_; | 106 std::map<int, CategoryStatus> statuses_; |
102 }; | 107 }; |
103 | 108 |
104 class MockServiceObserver : public ContentSuggestionsService::Observer { | 109 class MockServiceObserver : public ContentSuggestionsService::Observer { |
105 public: | 110 public: |
106 MOCK_METHOD1(OnNewSuggestions, void(Category category)); | 111 MOCK_METHOD1(OnNewSuggestions, void(Category category)); |
107 MOCK_METHOD2(OnCategoryStatusChanged, | 112 MOCK_METHOD2(OnCategoryStatusChanged, |
108 void(Category changed_category, CategoryStatus new_status)); | 113 void(Category changed_category, CategoryStatus new_status)); |
114 MOCK_METHOD2(OnSuggestionInvalidated, | |
115 void(Category category, const std::string& suggestion_id)); | |
109 MOCK_METHOD0(ContentSuggestionsServiceShutdown, void()); | 116 MOCK_METHOD0(ContentSuggestionsServiceShutdown, void()); |
110 ~MockServiceObserver() override {} | 117 ~MockServiceObserver() override {} |
111 }; | 118 }; |
112 | 119 |
113 } // namespace | 120 } // namespace |
114 | 121 |
115 class ContentSuggestionsServiceTest : public testing::Test { | 122 class ContentSuggestionsServiceTest : public testing::Test { |
116 public: | 123 public: |
117 ContentSuggestionsServiceTest() {} | 124 ContentSuggestionsServiceTest() {} |
118 | 125 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) { | 263 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) { |
257 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 264 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
258 Category offline_pages_category = | 265 Category offline_pages_category = |
259 FromKnownCategory(KnownCategories::BOOKMARKS); | 266 FromKnownCategory(KnownCategories::BOOKMARKS); |
260 MockProvider* provider1 = MakeProvider(articles_category); | 267 MockProvider* provider1 = MakeProvider(articles_category); |
261 MockProvider* provider2 = MakeProvider(offline_pages_category); | 268 MockProvider* provider2 = MakeProvider(offline_pages_category); |
262 | 269 |
263 provider1->FireSuggestionsChanged(articles_category, {1}); | 270 provider1->FireSuggestionsChanged(articles_category, {1}); |
264 std::string suggestion_id = CreateSuggestion(1).id(); | 271 std::string suggestion_id = CreateSuggestion(1).id(); |
265 | 272 |
266 EXPECT_CALL(*provider1, FetchSuggestionImage(suggestion_id, _)).Times(1); | 273 EXPECT_CALL(*provider1, FetchSuggestionImage(suggestion_id, _)); |
267 EXPECT_CALL(*provider2, FetchSuggestionImage(_, _)).Times(0); | 274 EXPECT_CALL(*provider2, FetchSuggestionImage(_, _)).Times(0); |
268 service()->FetchSuggestionImage( | 275 service()->FetchSuggestionImage( |
269 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, | 276 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, |
270 base::Unretained(this))); | 277 base::Unretained(this))); |
271 } | 278 } |
272 | 279 |
273 TEST_F(ContentSuggestionsServiceTest, | 280 TEST_F(ContentSuggestionsServiceTest, |
274 ShouldCallbackEmptyImageForUnavailableProvider) { | 281 ShouldCallbackEmptyImageForUnavailableProvider) { |
275 // Setup the current thread's MessageLoop. | 282 // Setup the current thread's MessageLoop. |
276 base::MessageLoop message_loop; | 283 base::MessageLoop message_loop; |
(...skipping 13 matching lines...) Expand all Loading... | |
290 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 297 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
291 Category offline_pages_category = | 298 Category offline_pages_category = |
292 FromKnownCategory(KnownCategories::BOOKMARKS); | 299 FromKnownCategory(KnownCategories::BOOKMARKS); |
293 MockProvider* provider1 = MakeProvider(articles_category); | 300 MockProvider* provider1 = MakeProvider(articles_category); |
294 MockProvider* provider2 = MakeProvider(offline_pages_category); | 301 MockProvider* provider2 = MakeProvider(offline_pages_category); |
295 | 302 |
296 provider2->FireSuggestionsChanged(offline_pages_category, {11}); | 303 provider2->FireSuggestionsChanged(offline_pages_category, {11}); |
297 std::string suggestion_id = CreateSuggestion(11).id(); | 304 std::string suggestion_id = CreateSuggestion(11).id(); |
298 | 305 |
299 EXPECT_CALL(*provider1, DismissSuggestion(_)).Times(0); | 306 EXPECT_CALL(*provider1, DismissSuggestion(_)).Times(0); |
300 EXPECT_CALL(*provider2, DismissSuggestion(suggestion_id)).Times(1); | 307 EXPECT_CALL(*provider2, DismissSuggestion(suggestion_id)); |
301 service()->DismissSuggestion(suggestion_id); | 308 service()->DismissSuggestion(suggestion_id); |
302 } | 309 } |
303 | 310 |
311 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectSuggestionInvalidated) { | |
312 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | |
313 | |
314 MockProvider* provider = MakeProvider(articles_category); | |
315 MockServiceObserver observer; | |
316 service()->AddObserver(&observer); | |
317 | |
318 provider->FireSuggestionsChanged(articles_category, {11, 12, 13}); | |
319 ExpectThatSuggestionsAre(articles_category, {11, 12, 13}); | |
320 std::string suggestion_id = CreateSuggestion(12).id(); | |
Marc Treib
2016/08/16 11:40:10
nitty nit: Move this after the empty line?
Philipp Keck
2016/08/16 11:51:03
Done.
| |
321 | |
322 EXPECT_CALL(observer, | |
323 OnSuggestionInvalidated(articles_category, suggestion_id)); | |
324 provider->FireSuggestionInvalidated(articles_category, suggestion_id); | |
325 ExpectThatSuggestionsAre(articles_category, {11, 13}); | |
326 Mock::VerifyAndClearExpectations(&observer); | |
327 | |
328 std::string unknown_id = CreateSuggestion(1234).id(); | |
Marc Treib
2016/08/16 11:40:09
nit: Add a comment explaining why? Otherwise the n
Philipp Keck
2016/08/16 11:51:03
Done.
| |
329 EXPECT_CALL(observer, OnSuggestionInvalidated(articles_category, unknown_id)); | |
330 provider->FireSuggestionInvalidated(articles_category, unknown_id); | |
331 ExpectThatSuggestionsAre(articles_category, {11, 13}); | |
332 Mock::VerifyAndClearExpectations(&observer); | |
333 | |
334 service()->RemoveObserver(&observer); | |
335 } | |
336 | |
304 TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) { | 337 TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) { |
305 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 338 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
306 Category offline_pages_category = | 339 Category offline_pages_category = |
307 FromKnownCategory(KnownCategories::BOOKMARKS); | 340 FromKnownCategory(KnownCategories::BOOKMARKS); |
308 | 341 |
309 // Create and register providers | 342 // Create and register providers |
310 MockProvider* provider1 = MakeProvider(articles_category); | 343 MockProvider* provider1 = MakeProvider(articles_category); |
311 MockProvider* provider2 = MakeProvider(offline_pages_category); | 344 MockProvider* provider2 = MakeProvider(offline_pages_category); |
312 EXPECT_THAT(providers().at(articles_category), Eq(provider1)); | 345 EXPECT_THAT(providers().at(articles_category), Eq(provider1)); |
313 EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2)); | 346 EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2)); |
314 | 347 |
315 // Create and register observer | 348 // Create and register observer |
316 MockServiceObserver observer; | 349 MockServiceObserver observer; |
317 service()->AddObserver(&observer); | 350 service()->AddObserver(&observer); |
318 | 351 |
319 // Send suggestions 1 and 2 | 352 // Send suggestions 1 and 2 |
320 EXPECT_CALL(observer, OnNewSuggestions(articles_category)).Times(1); | 353 EXPECT_CALL(observer, OnNewSuggestions(articles_category)); |
321 provider1->FireSuggestionsChanged(articles_category, {1, 2}); | 354 provider1->FireSuggestionsChanged(articles_category, {1, 2}); |
322 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 355 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
323 Mock::VerifyAndClearExpectations(&observer); | 356 Mock::VerifyAndClearExpectations(&observer); |
324 | 357 |
325 // Send them again, make sure they're not reported twice | 358 // Send them again, make sure they're not reported twice |
326 EXPECT_CALL(observer, OnNewSuggestions(articles_category)).Times(1); | 359 EXPECT_CALL(observer, OnNewSuggestions(articles_category)); |
327 provider1->FireSuggestionsChanged(articles_category, {1, 2}); | 360 provider1->FireSuggestionsChanged(articles_category, {1, 2}); |
328 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 361 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
329 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); | 362 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); |
330 Mock::VerifyAndClearExpectations(&observer); | 363 Mock::VerifyAndClearExpectations(&observer); |
331 | 364 |
332 // Send suggestions 13 and 14 | 365 // Send suggestions 13 and 14 |
333 EXPECT_CALL(observer, OnNewSuggestions(offline_pages_category)).Times(1); | 366 EXPECT_CALL(observer, OnNewSuggestions(offline_pages_category)); |
334 provider2->FireSuggestionsChanged(offline_pages_category, {13, 14}); | 367 provider2->FireSuggestionsChanged(offline_pages_category, {13, 14}); |
335 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 368 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
336 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); | 369 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); |
337 Mock::VerifyAndClearExpectations(&observer); | 370 Mock::VerifyAndClearExpectations(&observer); |
338 | 371 |
339 // Send suggestion 1 only | 372 // Send suggestion 1 only |
340 EXPECT_CALL(observer, OnNewSuggestions(articles_category)).Times(1); | 373 EXPECT_CALL(observer, OnNewSuggestions(articles_category)); |
341 provider1->FireSuggestionsChanged(articles_category, {1}); | 374 provider1->FireSuggestionsChanged(articles_category, {1}); |
342 ExpectThatSuggestionsAre(articles_category, {1}); | 375 ExpectThatSuggestionsAre(articles_category, {1}); |
343 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); | 376 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); |
344 Mock::VerifyAndClearExpectations(&observer); | 377 Mock::VerifyAndClearExpectations(&observer); |
345 | 378 |
346 // provider2 reports BOOKMARKS as unavailable | 379 // provider2 reports BOOKMARKS as unavailable |
347 EXPECT_CALL(observer, OnCategoryStatusChanged( | 380 EXPECT_CALL(observer, OnCategoryStatusChanged( |
348 offline_pages_category, | 381 offline_pages_category, |
349 CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)) | 382 CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); |
350 .Times(1); | |
351 provider2->FireCategoryStatusChanged( | 383 provider2->FireCategoryStatusChanged( |
352 offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); | 384 offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); |
353 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 385 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
354 Eq(CategoryStatus::AVAILABLE)); | 386 Eq(CategoryStatus::AVAILABLE)); |
355 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 387 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
356 Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); | 388 Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); |
357 ExpectThatSuggestionsAre(articles_category, {1}); | 389 ExpectThatSuggestionsAre(articles_category, {1}); |
358 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); | 390 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); |
359 Mock::VerifyAndClearExpectations(&observer); | 391 Mock::VerifyAndClearExpectations(&observer); |
360 | 392 |
361 // Shutdown the service | 393 // Shutdown the service |
362 EXPECT_CALL(observer, ContentSuggestionsServiceShutdown()); | 394 EXPECT_CALL(observer, ContentSuggestionsServiceShutdown()); |
363 service()->Shutdown(); | 395 service()->Shutdown(); |
364 service()->RemoveObserver(&observer); | 396 service()->RemoveObserver(&observer); |
365 // The service will receive two Shutdown() calls. | 397 // The service will receive two Shutdown() calls. |
366 } | 398 } |
367 | 399 |
368 } // namespace ntp_snippets | 400 } // namespace ntp_snippets |
OLD | NEW |