| 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" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "components/ntp_snippets/category_status.h" | 14 #include "components/ntp_snippets/category_status.h" |
| 14 #include "components/ntp_snippets/content_suggestion.h" | 15 #include "components/ntp_snippets/content_suggestion.h" |
| 15 #include "components/ntp_snippets/content_suggestions_provider.h" | 16 #include "components/ntp_snippets/content_suggestions_provider.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "ui/gfx/image/image.h" | 19 #include "ui/gfx/image/image.h" |
| 19 | 20 |
| 20 using testing::Eq; | 21 using testing::Eq; |
| 21 using testing::IsNull; | 22 using testing::IsNull; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 42 std::vector<ContentSuggestion> CreateSuggestions(std::vector<int> numbers) { | 43 std::vector<ContentSuggestion> CreateSuggestions(std::vector<int> numbers) { |
| 43 std::vector<ContentSuggestion> result; | 44 std::vector<ContentSuggestion> result; |
| 44 for (int number : numbers) { | 45 for (int number : numbers) { |
| 45 result.emplace_back(CreateSuggestion(number)); | 46 result.emplace_back(CreateSuggestion(number)); |
| 46 } | 47 } |
| 47 return result; | 48 return result; |
| 48 } | 49 } |
| 49 | 50 |
| 50 class MockProvider : public ContentSuggestionsProvider { | 51 class MockProvider : public ContentSuggestionsProvider { |
| 51 public: | 52 public: |
| 52 MockProvider(CategoryFactory* category_factory, Category provided_category) | 53 MockProvider(Observer* observer, |
| 53 : MockProvider(category_factory, | 54 CategoryFactory* category_factory, |
| 54 std::vector<Category>({provided_category})){}; | |
| 55 | |
| 56 MockProvider(CategoryFactory* category_factory, | |
| 57 std::vector<Category> provided_categories) | 55 std::vector<Category> provided_categories) |
| 58 : ContentSuggestionsProvider(category_factory), | 56 : ContentSuggestionsProvider(observer, category_factory), |
| 59 observer_(nullptr), | |
| 60 provided_categories_(provided_categories) { | 57 provided_categories_(provided_categories) { |
| 61 for (Category category : provided_categories) { | 58 for (Category category : provided_categories) { |
| 62 statuses_[category.id()] = CategoryStatus::AVAILABLE; | 59 statuses_[category.id()] = CategoryStatus::AVAILABLE; |
| 63 } | 60 } |
| 64 } | 61 } |
| 65 | 62 |
| 66 std::vector<Category> GetProvidedCategories() override { | 63 std::vector<Category> GetProvidedCategories() override { |
| 67 return provided_categories_; | 64 return provided_categories_; |
| 68 } | 65 } |
| 69 | 66 |
| 70 Observer* observer() { return observer_; } | |
| 71 | |
| 72 void SetObserver(Observer* observer) override { observer_ = observer; } | |
| 73 | |
| 74 CategoryStatus GetCategoryStatus(Category category) { | 67 CategoryStatus GetCategoryStatus(Category category) { |
| 75 return statuses_[category.id()]; | 68 return statuses_[category.id()]; |
| 76 } | 69 } |
| 77 | 70 |
| 78 void FireSuggestionsChanged(Category category, std::vector<int> numbers) { | 71 void FireSuggestionsChanged(Category category, std::vector<int> numbers) { |
| 79 observer_->OnNewSuggestions(this, category, CreateSuggestions(numbers)); | 72 observer()->OnNewSuggestions(this, category, CreateSuggestions(numbers)); |
| 80 } | 73 } |
| 81 | 74 |
| 82 void FireCategoryStatusChanged(Category category, CategoryStatus new_status) { | 75 void FireCategoryStatusChanged(Category category, CategoryStatus new_status) { |
| 83 statuses_[category.id()] = new_status; | 76 statuses_[category.id()] = new_status; |
| 84 observer_->OnCategoryStatusChanged(this, category, new_status); | 77 observer()->OnCategoryStatusChanged(this, category, new_status); |
| 85 } | |
| 86 | |
| 87 void FireShutdown() { | |
| 88 observer_->OnProviderShutdown(this); | |
| 89 observer_ = nullptr; | |
| 90 } | 78 } |
| 91 | 79 |
| 92 MOCK_METHOD0(ClearCachedSuggestionsForDebugging, void()); | 80 MOCK_METHOD0(ClearCachedSuggestionsForDebugging, void()); |
| 93 MOCK_METHOD0(ClearDismissedSuggestionsForDebugging, void()); | 81 MOCK_METHOD0(ClearDismissedSuggestionsForDebugging, void()); |
| 94 MOCK_METHOD1(DismissSuggestion, void(const std::string& suggestion_id)); | 82 MOCK_METHOD1(DismissSuggestion, void(const std::string& suggestion_id)); |
| 95 MOCK_METHOD2(FetchSuggestionImage, | 83 MOCK_METHOD2(FetchSuggestionImage, |
| 96 void(const std::string& suggestion_id, | 84 void(const std::string& suggestion_id, |
| 97 const ImageFetchedCallback& callback)); | 85 const ImageFetchedCallback& callback)); |
| 98 | 86 |
| 99 private: | 87 private: |
| 100 Observer* observer_; | |
| 101 std::vector<Category> provided_categories_; | 88 std::vector<Category> provided_categories_; |
| 102 std::map<int, CategoryStatus> statuses_; | 89 std::map<int, CategoryStatus> statuses_; |
| 103 }; | 90 }; |
| 104 | 91 |
| 105 class MockServiceObserver : public ContentSuggestionsService::Observer { | 92 class MockServiceObserver : public ContentSuggestionsService::Observer { |
| 106 public: | 93 public: |
| 107 MOCK_METHOD0(OnNewSuggestions, void()); | 94 MOCK_METHOD0(OnNewSuggestions, void()); |
| 108 MOCK_METHOD2(OnCategoryStatusChanged, | 95 MOCK_METHOD2(OnCategoryStatusChanged, |
| 109 void(Category changed_category, CategoryStatus new_status)); | 96 void(Category changed_category, CategoryStatus new_status)); |
| 110 MOCK_METHOD0(ContentSuggestionsServiceShutdown, void()); | 97 MOCK_METHOD0(ContentSuggestionsServiceShutdown, void()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 providers() { | 145 providers() { |
| 159 return service()->providers_by_category_; | 146 return service()->providers_by_category_; |
| 160 } | 147 } |
| 161 | 148 |
| 162 CategoryFactory* category_factory() { return service()->category_factory(); } | 149 CategoryFactory* category_factory() { return service()->category_factory(); } |
| 163 | 150 |
| 164 Category FromKnownCategory(KnownCategories known_category) { | 151 Category FromKnownCategory(KnownCategories known_category) { |
| 165 return service()->category_factory()->FromKnownCategory(known_category); | 152 return service()->category_factory()->FromKnownCategory(known_category); |
| 166 } | 153 } |
| 167 | 154 |
| 155 MockProvider* MakeProvider(Category provided_category) { |
| 156 return MakeProvider(std::vector<Category>({provided_category})); |
| 157 } |
| 158 |
| 159 MockProvider* MakeProvider(std::vector<Category> provided_categories) { |
| 160 std::unique_ptr<MockProvider> provider = base::MakeUnique<MockProvider>( |
| 161 service(), category_factory(), provided_categories); |
| 162 MockProvider* result = provider.get(); |
| 163 service()->RegisterProvider(std::move(provider)); |
| 164 return result; |
| 165 } |
| 166 |
| 168 MOCK_METHOD2(OnImageFetched, | 167 MOCK_METHOD2(OnImageFetched, |
| 169 void(const std::string& suggestion_id, const gfx::Image&)); | 168 void(const std::string& suggestion_id, const gfx::Image&)); |
| 170 | 169 |
| 171 protected: | 170 protected: |
| 172 void CreateContentSuggestionsService( | 171 void CreateContentSuggestionsService( |
| 173 ContentSuggestionsService::State enabled) { | 172 ContentSuggestionsService::State enabled) { |
| 174 ASSERT_FALSE(service_); | 173 ASSERT_FALSE(service_); |
| 175 service_.reset(new ContentSuggestionsService(enabled)); | 174 service_.reset(new ContentSuggestionsService(enabled)); |
| 176 } | 175 } |
| 177 | 176 |
| 178 ContentSuggestionsService* service() { return service_.get(); } | 177 ContentSuggestionsService* service() { return service_.get(); } |
| 179 | 178 |
| 180 private: | 179 private: |
| 181 std::unique_ptr<ContentSuggestionsService> service_; | 180 std::unique_ptr<ContentSuggestionsService> service_; |
| 182 | 181 |
| 183 DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsServiceTest); | 182 DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsServiceTest); |
| 184 }; | 183 }; |
| 185 | 184 |
| 186 class ContentSuggestionsServiceDisabledTest | 185 class ContentSuggestionsServiceDisabledTest |
| 187 : public ContentSuggestionsServiceTest { | 186 : public ContentSuggestionsServiceTest { |
| 188 public: | 187 public: |
| 189 void SetUp() override { | 188 void SetUp() override { |
| 190 CreateContentSuggestionsService(ContentSuggestionsService::State::DISABLED); | 189 CreateContentSuggestionsService(ContentSuggestionsService::State::DISABLED); |
| 191 } | 190 } |
| 192 }; | 191 }; |
| 193 | 192 |
| 194 TEST_F(ContentSuggestionsServiceTest, ShouldRegisterProvidersAndShutdown) { | 193 TEST_F(ContentSuggestionsServiceTest, ShouldRegisterProviders) { |
| 195 EXPECT_THAT(service()->state(), | 194 EXPECT_THAT(service()->state(), |
| 196 Eq(ContentSuggestionsService::State::ENABLED)); | 195 Eq(ContentSuggestionsService::State::ENABLED)); |
| 197 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 196 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
| 198 Category offline_pages_category = | 197 Category offline_pages_category = |
| 199 FromKnownCategory(KnownCategories::OFFLINE_PAGES); | 198 FromKnownCategory(KnownCategories::OFFLINE_PAGES); |
| 200 MockProvider provider1(category_factory(), articles_category); | |
| 201 MockProvider provider2(category_factory(), offline_pages_category); | |
| 202 ASSERT_THAT(provider1.observer(), IsNull()); | |
| 203 ASSERT_THAT(provider2.observer(), IsNull()); | |
| 204 ASSERT_THAT(providers(), IsEmpty()); | 199 ASSERT_THAT(providers(), IsEmpty()); |
| 205 EXPECT_THAT(service()->GetCategories(), IsEmpty()); | 200 EXPECT_THAT(service()->GetCategories(), IsEmpty()); |
| 206 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 201 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
| 207 Eq(CategoryStatus::NOT_PROVIDED)); | 202 Eq(CategoryStatus::NOT_PROVIDED)); |
| 208 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 203 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
| 209 Eq(CategoryStatus::NOT_PROVIDED)); | 204 Eq(CategoryStatus::NOT_PROVIDED)); |
| 210 | 205 |
| 211 service()->RegisterProvider(&provider1); | 206 MockProvider* provider1 = MakeProvider(articles_category); |
| 212 EXPECT_THAT(provider1.observer(), NotNull()); | |
| 213 EXPECT_THAT(providers().count(offline_pages_category), Eq(0ul)); | 207 EXPECT_THAT(providers().count(offline_pages_category), Eq(0ul)); |
| 214 EXPECT_THAT(providers().at(articles_category), Eq(&provider1)); | 208 EXPECT_THAT(providers().at(articles_category), Eq(provider1)); |
| 215 EXPECT_THAT(providers().size(), Eq(1ul)); | 209 EXPECT_THAT(providers().size(), Eq(1ul)); |
| 216 EXPECT_THAT(service()->GetCategories(), ElementsAre(articles_category)); | 210 EXPECT_THAT(service()->GetCategories(), ElementsAre(articles_category)); |
| 217 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 211 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
| 218 Eq(CategoryStatus::AVAILABLE)); | 212 Eq(CategoryStatus::AVAILABLE)); |
| 219 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 213 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
| 220 Eq(CategoryStatus::NOT_PROVIDED)); | 214 Eq(CategoryStatus::NOT_PROVIDED)); |
| 221 | 215 |
| 222 service()->RegisterProvider(&provider2); | 216 MockProvider* provider2 = MakeProvider(offline_pages_category); |
| 223 EXPECT_THAT(provider1.observer(), NotNull()); | 217 EXPECT_THAT(providers().at(articles_category), Eq(provider1)); |
| 224 EXPECT_THAT(provider2.observer(), NotNull()); | 218 EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2)); |
| 225 EXPECT_THAT(providers().at(articles_category), Eq(&provider1)); | |
| 226 EXPECT_THAT(providers().at(offline_pages_category), Eq(&provider2)); | |
| 227 EXPECT_THAT(providers().size(), Eq(2ul)); | 219 EXPECT_THAT(providers().size(), Eq(2ul)); |
| 228 EXPECT_THAT(service()->GetCategories(), | 220 EXPECT_THAT(service()->GetCategories(), |
| 229 ElementsAre(offline_pages_category, articles_category)); | 221 ElementsAre(offline_pages_category, articles_category)); |
| 230 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 222 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
| 231 Eq(CategoryStatus::AVAILABLE)); | 223 Eq(CategoryStatus::AVAILABLE)); |
| 232 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 224 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
| 233 Eq(CategoryStatus::AVAILABLE)); | 225 Eq(CategoryStatus::AVAILABLE)); |
| 234 | |
| 235 provider1.FireShutdown(); | |
| 236 EXPECT_THAT(providers().count(articles_category), Eq(0ul)); | |
| 237 EXPECT_THAT(providers().at(offline_pages_category), Eq(&provider2)); | |
| 238 EXPECT_THAT(providers().size(), Eq(1ul)); | |
| 239 EXPECT_THAT(service()->GetCategories(), ElementsAre(offline_pages_category)); | |
| 240 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | |
| 241 CategoryStatus::NOT_PROVIDED); | |
| 242 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | |
| 243 CategoryStatus::AVAILABLE); | |
| 244 | |
| 245 provider2.FireShutdown(); | |
| 246 EXPECT_THAT(providers(), IsEmpty()); | |
| 247 EXPECT_THAT(service()->GetCategories(), IsEmpty()); | |
| 248 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | |
| 249 Eq(CategoryStatus::NOT_PROVIDED)); | |
| 250 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | |
| 251 Eq(CategoryStatus::NOT_PROVIDED)); | |
| 252 } | 226 } |
| 253 | 227 |
| 254 TEST_F(ContentSuggestionsServiceDisabledTest, ShouldDoNothingWhenDisabled) { | 228 TEST_F(ContentSuggestionsServiceDisabledTest, ShouldDoNothingWhenDisabled) { |
| 255 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 229 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
| 256 Category offline_pages_category = | 230 Category offline_pages_category = |
| 257 FromKnownCategory(KnownCategories::OFFLINE_PAGES); | 231 FromKnownCategory(KnownCategories::OFFLINE_PAGES); |
| 258 EXPECT_THAT(service()->state(), | 232 EXPECT_THAT(service()->state(), |
| 259 Eq(ContentSuggestionsService::State::DISABLED)); | 233 Eq(ContentSuggestionsService::State::DISABLED)); |
| 260 MockProvider provider1(category_factory(), articles_category); | |
| 261 service()->RegisterProvider(&provider1); | |
| 262 EXPECT_THAT(providers(), IsEmpty()); | 234 EXPECT_THAT(providers(), IsEmpty()); |
| 263 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 235 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
| 264 Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED)); | 236 Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED)); |
| 265 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 237 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
| 266 Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED)); | 238 Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED)); |
| 267 EXPECT_THAT(service()->GetCategories(), IsEmpty()); | 239 EXPECT_THAT(service()->GetCategories(), IsEmpty()); |
| 268 EXPECT_THAT(service()->GetSuggestionsForCategory(articles_category), | 240 EXPECT_THAT(service()->GetSuggestionsForCategory(articles_category), |
| 269 IsEmpty()); | 241 IsEmpty()); |
| 270 } | 242 } |
| 271 | 243 |
| 272 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) { | 244 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) { |
| 273 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 245 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
| 274 Category offline_pages_category = | 246 Category offline_pages_category = |
| 275 FromKnownCategory(KnownCategories::OFFLINE_PAGES); | 247 FromKnownCategory(KnownCategories::OFFLINE_PAGES); |
| 276 MockProvider provider1(category_factory(), articles_category); | 248 MockProvider* provider1 = MakeProvider(articles_category); |
| 277 MockProvider provider2(category_factory(), offline_pages_category); | 249 MockProvider* provider2 = MakeProvider(offline_pages_category); |
| 278 service()->RegisterProvider(&provider1); | |
| 279 service()->RegisterProvider(&provider2); | |
| 280 | 250 |
| 281 provider1.FireSuggestionsChanged(articles_category, {1}); | 251 provider1->FireSuggestionsChanged(articles_category, {1}); |
| 282 std::string suggestion_id = CreateSuggestion(1).id(); | 252 std::string suggestion_id = CreateSuggestion(1).id(); |
| 283 | 253 |
| 284 EXPECT_CALL(provider1, FetchSuggestionImage(suggestion_id, _)).Times(1); | 254 EXPECT_CALL(*provider1, FetchSuggestionImage(suggestion_id, _)).Times(1); |
| 285 EXPECT_CALL(provider2, FetchSuggestionImage(_, _)).Times(0); | 255 EXPECT_CALL(*provider2, FetchSuggestionImage(_, _)).Times(0); |
| 286 service()->FetchSuggestionImage( | 256 service()->FetchSuggestionImage( |
| 287 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, | 257 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, |
| 288 base::Unretained(this))); | 258 base::Unretained(this))); |
| 289 provider1.FireShutdown(); | |
| 290 provider2.FireShutdown(); | |
| 291 } | 259 } |
| 292 | 260 |
| 293 TEST_F(ContentSuggestionsServiceTest, | 261 TEST_F(ContentSuggestionsServiceTest, |
| 294 ShouldCallbackEmptyImageForUnavailableProvider) { | 262 ShouldCallbackEmptyImageForUnavailableProvider) { |
| 295 std::string suggestion_id = "TestID"; | 263 std::string suggestion_id = "TestID"; |
| 296 EXPECT_CALL(*this, OnImageFetched(suggestion_id, | 264 EXPECT_CALL(*this, OnImageFetched(suggestion_id, |
| 297 Property(&gfx::Image::IsEmpty, Eq(true)))); | 265 Property(&gfx::Image::IsEmpty, Eq(true)))); |
| 298 service()->FetchSuggestionImage( | 266 service()->FetchSuggestionImage( |
| 299 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, | 267 suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched, |
| 300 base::Unretained(this))); | 268 base::Unretained(this))); |
| 301 } | 269 } |
| 302 | 270 |
| 303 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectDismissSuggestion) { | 271 TEST_F(ContentSuggestionsServiceTest, ShouldRedirectDismissSuggestion) { |
| 304 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 272 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
| 305 Category offline_pages_category = | 273 Category offline_pages_category = |
| 306 FromKnownCategory(KnownCategories::OFFLINE_PAGES); | 274 FromKnownCategory(KnownCategories::OFFLINE_PAGES); |
| 307 MockProvider provider1(category_factory(), articles_category); | 275 MockProvider* provider1 = MakeProvider(articles_category); |
| 308 MockProvider provider2(category_factory(), offline_pages_category); | 276 MockProvider* provider2 = MakeProvider(offline_pages_category); |
| 309 service()->RegisterProvider(&provider1); | |
| 310 service()->RegisterProvider(&provider2); | |
| 311 | 277 |
| 312 provider2.FireSuggestionsChanged(offline_pages_category, {11}); | 278 provider2->FireSuggestionsChanged(offline_pages_category, {11}); |
| 313 std::string suggestion_id = CreateSuggestion(11).id(); | 279 std::string suggestion_id = CreateSuggestion(11).id(); |
| 314 | 280 |
| 315 EXPECT_CALL(provider1, DismissSuggestion(_)).Times(0); | 281 EXPECT_CALL(*provider1, DismissSuggestion(_)).Times(0); |
| 316 EXPECT_CALL(provider2, DismissSuggestion(suggestion_id)).Times(1); | 282 EXPECT_CALL(*provider2, DismissSuggestion(suggestion_id)).Times(1); |
| 317 service()->DismissSuggestion(suggestion_id); | 283 service()->DismissSuggestion(suggestion_id); |
| 318 provider1.FireShutdown(); | |
| 319 provider2.FireShutdown(); | |
| 320 } | 284 } |
| 321 | 285 |
| 322 TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) { | 286 TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) { |
| 323 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); | 287 Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); |
| 324 Category offline_pages_category = | 288 Category offline_pages_category = |
| 325 FromKnownCategory(KnownCategories::OFFLINE_PAGES); | 289 FromKnownCategory(KnownCategories::OFFLINE_PAGES); |
| 326 | 290 |
| 327 // Create and register providers | 291 // Create and register providers |
| 328 MockProvider provider1(category_factory(), articles_category); | 292 MockProvider* provider1 = MakeProvider(articles_category); |
| 329 MockProvider provider2(category_factory(), offline_pages_category); | 293 MockProvider* provider2 = MakeProvider(offline_pages_category); |
| 330 service()->RegisterProvider(&provider1); | 294 EXPECT_THAT(providers().at(articles_category), Eq(provider1)); |
| 331 service()->RegisterProvider(&provider2); | 295 EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2)); |
| 332 EXPECT_THAT(providers().at(articles_category), Eq(&provider1)); | |
| 333 EXPECT_THAT(providers().at(offline_pages_category), Eq(&provider2)); | |
| 334 | 296 |
| 335 // Create and register observer | 297 // Create and register observer |
| 336 MockServiceObserver observer; | 298 MockServiceObserver observer; |
| 337 service()->AddObserver(&observer); | 299 service()->AddObserver(&observer); |
| 338 | 300 |
| 339 // Send suggestions 1 and 2 | 301 // Send suggestions 1 and 2 |
| 340 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); | 302 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); |
| 341 provider1.FireSuggestionsChanged(articles_category, {1, 2}); | 303 provider1->FireSuggestionsChanged(articles_category, {1, 2}); |
| 342 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 304 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
| 343 Mock::VerifyAndClearExpectations(&observer); | 305 Mock::VerifyAndClearExpectations(&observer); |
| 344 | 306 |
| 345 // Send them again, make sure they're not reported twice | 307 // Send them again, make sure they're not reported twice |
| 346 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); | 308 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); |
| 347 provider1.FireSuggestionsChanged(articles_category, {1, 2}); | 309 provider1->FireSuggestionsChanged(articles_category, {1, 2}); |
| 348 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 310 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
| 349 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); | 311 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); |
| 350 Mock::VerifyAndClearExpectations(&observer); | 312 Mock::VerifyAndClearExpectations(&observer); |
| 351 | 313 |
| 352 // Send suggestions 13 and 14 | 314 // Send suggestions 13 and 14 |
| 353 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); | 315 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); |
| 354 provider2.FireSuggestionsChanged(offline_pages_category, {13, 14}); | 316 provider2->FireSuggestionsChanged(offline_pages_category, {13, 14}); |
| 355 ExpectThatSuggestionsAre(articles_category, {1, 2}); | 317 ExpectThatSuggestionsAre(articles_category, {1, 2}); |
| 356 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); | 318 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); |
| 357 Mock::VerifyAndClearExpectations(&observer); | 319 Mock::VerifyAndClearExpectations(&observer); |
| 358 | 320 |
| 359 // Send suggestion 1 only | 321 // Send suggestion 1 only |
| 360 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); | 322 EXPECT_CALL(observer, OnNewSuggestions()).Times(1); |
| 361 provider1.FireSuggestionsChanged(articles_category, {1}); | 323 provider1->FireSuggestionsChanged(articles_category, {1}); |
| 362 ExpectThatSuggestionsAre(articles_category, {1}); | 324 ExpectThatSuggestionsAre(articles_category, {1}); |
| 363 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); | 325 ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); |
| 364 Mock::VerifyAndClearExpectations(&observer); | 326 Mock::VerifyAndClearExpectations(&observer); |
| 365 | 327 |
| 366 // provider2 reports OFFLINE_PAGEs as unavailable | 328 // provider2 reports OFFLINE_PAGES as unavailable |
| 367 EXPECT_CALL(observer, OnCategoryStatusChanged( | 329 EXPECT_CALL(observer, OnCategoryStatusChanged( |
| 368 offline_pages_category, | 330 offline_pages_category, |
| 369 CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)) | 331 CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)) |
| 370 .Times(1); | 332 .Times(1); |
| 371 provider2.FireCategoryStatusChanged( | 333 provider2->FireCategoryStatusChanged( |
| 372 offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); | 334 offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); |
| 373 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | 335 EXPECT_THAT(service()->GetCategoryStatus(articles_category), |
| 374 Eq(CategoryStatus::AVAILABLE)); | 336 Eq(CategoryStatus::AVAILABLE)); |
| 375 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | 337 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), |
| 376 Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); | 338 Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); |
| 377 ExpectThatSuggestionsAre(articles_category, {1}); | 339 ExpectThatSuggestionsAre(articles_category, {1}); |
| 378 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); | 340 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); |
| 379 Mock::VerifyAndClearExpectations(&observer); | 341 Mock::VerifyAndClearExpectations(&observer); |
| 380 | 342 |
| 381 // Let provider1 shut down | |
| 382 EXPECT_CALL(observer, OnCategoryStatusChanged(articles_category, | |
| 383 CategoryStatus::NOT_PROVIDED)) | |
| 384 .Times(1); | |
| 385 provider1.FireShutdown(); | |
| 386 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | |
| 387 Eq(CategoryStatus::NOT_PROVIDED)); | |
| 388 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | |
| 389 Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)); | |
| 390 ExpectThatSuggestionsAre(articles_category, std::vector<int>()); | |
| 391 ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>()); | |
| 392 Mock::VerifyAndClearExpectations(&observer); | |
| 393 | |
| 394 // Let provider2 shut down | |
| 395 provider2.FireShutdown(); | |
| 396 EXPECT_TRUE(providers().empty()); | |
| 397 EXPECT_THAT(service()->GetCategoryStatus(articles_category), | |
| 398 Eq(CategoryStatus::NOT_PROVIDED)); | |
| 399 EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category), | |
| 400 Eq(CategoryStatus::NOT_PROVIDED)); | |
| 401 | |
| 402 // Shutdown the service | 343 // Shutdown the service |
| 403 EXPECT_CALL(observer, ContentSuggestionsServiceShutdown()); | 344 EXPECT_CALL(observer, ContentSuggestionsServiceShutdown()); |
| 404 service()->Shutdown(); | 345 service()->Shutdown(); |
| 405 service()->RemoveObserver(&observer); | 346 service()->RemoveObserver(&observer); |
| 406 // The service will receive two Shutdown() calls. | 347 // The service will receive two Shutdown() calls. |
| 407 } | 348 } |
| 408 | 349 |
| 409 } // namespace ntp_snippets | 350 } // namespace ntp_snippets |
| OLD | NEW |