// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/ntp_snippets/content_suggestions_service.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/mock_callback.h"
#include "base/time/default_clock.h"
#include "components/ntp_snippets/category_info.h"
#include "components/ntp_snippets/category_rankers/constant_category_ranker.h"
#include "components/ntp_snippets/category_rankers/fake_category_ranker.h"
#include "components/ntp_snippets/category_rankers/mock_category_ranker.h"
#include "components/ntp_snippets/category_status.h"
#include "components/ntp_snippets/content_suggestion.h"
#include "components/ntp_snippets/content_suggestions_provider.h"
#include "components/ntp_snippets/logger.h"
#include "components/ntp_snippets/mock_content_suggestions_provider.h"
#include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h"
#include "components/ntp_snippets/user_classifier.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image.h"

using testing::_;
using testing::ElementsAre;
using testing::Eq;
using testing::InvokeWithoutArgs;
using testing::IsEmpty;
using testing::Mock;
using testing::Property;
using testing::Return;
using testing::SizeIs;
using testing::StrictMock;
using testing::UnorderedElementsAre;

namespace ntp_snippets {

namespace {

class MockServiceObserver : public ContentSuggestionsService::Observer {
 public:
  MockServiceObserver() = default;
  ~MockServiceObserver() override = default;

  MOCK_METHOD1(OnNewSuggestions, void(Category category));
  MOCK_METHOD2(OnCategoryStatusChanged,
               void(Category changed_category, CategoryStatus new_status));
  MOCK_METHOD1(OnSuggestionInvalidated,
               void(const ContentSuggestion::ID& suggestion_id));
  MOCK_METHOD0(OnFullRefreshRequired, void());
  MOCK_METHOD0(ContentSuggestionsServiceShutdown, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockServiceObserver);
};

}  // namespace

class ContentSuggestionsServiceTest : public testing::Test {
 public:
  ContentSuggestionsServiceTest()
      : pref_service_(std::make_unique<TestingPrefServiceSimple>()),
        category_ranker_(std::make_unique<ConstantCategoryRanker>()) {}

  void SetUp() override {
    RegisterPrefs();
    CreateContentSuggestionsService(ContentSuggestionsService::State::ENABLED);
  }

  void TearDown() override {
    service_->Shutdown();
    service_.reset();
  }

  // Verifies that exactly the suggestions with the given |numbers| are
  // returned by the service for the given |category|.
  void ExpectThatSuggestionsAre(Category category, std::vector<int> numbers) {
    std::vector<Category> categories = service()->GetCategories();
    auto position = std::find(categories.begin(), categories.end(), category);
    if (!numbers.empty()) {
      EXPECT_NE(categories.end(), position);
    }

    for (const auto& suggestion :
         service()->GetSuggestionsForCategory(category)) {
      std::string id_within_category = suggestion.id().id_within_category();
      int id;
      ASSERT_TRUE(base::StringToInt(id_within_category, &id));
      auto position = std::find(numbers.begin(), numbers.end(), id);
      if (position == numbers.end()) {
        ADD_FAILURE() << "Unexpected suggestion with ID " << id;
      } else {
        numbers.erase(position);
      }
    }
    for (int number : numbers) {
      ADD_FAILURE() << "Suggestion number " << number
                    << " not present, though expected";
    }
  }

  const std::map<Category, ContentSuggestionsProvider*, Category::CompareByID>&
  providers() {
    return service()->providers_by_category_;
  }

  const std::map<Category, ContentSuggestionsProvider*, Category::CompareByID>&
  dismissed_providers() {
    return service()->dismissed_providers_by_category_;
  }

  MockContentSuggestionsProvider* MakeRegisteredMockProvider(
      Category provided_category) {
    return MakeRegisteredMockProvider(
        std::vector<Category>({provided_category}));
  }

  MockContentSuggestionsProvider* MakeRegisteredMockProvider(
      const std::vector<Category>& provided_categories) {
    auto provider =
        std::make_unique<testing::StrictMock<MockContentSuggestionsProvider>>(
            service(), provided_categories);
    MockContentSuggestionsProvider* result = provider.get();
    service()->RegisterProvider(std::move(provider));
    return result;
  }

  void SetCategoryRanker(std::unique_ptr<CategoryRanker> category_ranker) {
    category_ranker_ = std::move(category_ranker);
  }

  MOCK_METHOD1(OnImageFetched, void(const gfx::Image&));

 protected:
  void RegisterPrefs() {
    ContentSuggestionsService::RegisterProfilePrefs(pref_service_->registry());
    RemoteSuggestionsProviderImpl::RegisterProfilePrefs(
        pref_service_->registry());
    UserClassifier::RegisterProfilePrefs(pref_service_->registry());
  }

  void CreateContentSuggestionsService(
      ContentSuggestionsService::State enabled) {
    ASSERT_FALSE(service_);

    // TODO(jkrcal): Replace by a mock.
    auto user_classifier = std::make_unique<UserClassifier>(
        pref_service_.get(), base::DefaultClock::GetInstance());

    service_ = std::make_unique<ContentSuggestionsService>(
        enabled, /*identity_manager=*/nullptr, /*history_service=*/nullptr,
        /*large_icon_service=*/nullptr, pref_service_.get(),
        std::move(category_ranker_), std::move(user_classifier),
        /*scheduler=*/nullptr, /*debug_logger=*/std::make_unique<Logger>());
  }

  void ResetService() {
    service_->Shutdown();
    service_.reset();
    CreateContentSuggestionsService(ContentSuggestionsService::State::ENABLED);
  }

  ContentSuggestionsService* service() { return service_.get(); }

  // Returns a suggestion instance for testing.
  ContentSuggestion CreateSuggestion(Category category, int number) {
    return ContentSuggestion(
        category, base::IntToString(number),
        GURL("http://testsuggestion/" + base::IntToString(number)));
  }

  std::vector<ContentSuggestion> CreateSuggestions(
      Category category,
      const std::vector<int>& numbers) {
    std::vector<ContentSuggestion> result;
    for (int number : numbers) {
      result.push_back(CreateSuggestion(category, number));
    }
    return result;
  }

 private:
  std::unique_ptr<ContentSuggestionsService> service_;
  std::unique_ptr<TestingPrefServiceSimple> pref_service_;
  std::unique_ptr<CategoryRanker> category_ranker_;

  DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsServiceTest);
};

class ContentSuggestionsServiceDisabledTest
    : public ContentSuggestionsServiceTest {
 public:
  void SetUp() override {
    RegisterPrefs();
    CreateContentSuggestionsService(ContentSuggestionsService::State::DISABLED);
  }
};

TEST_F(ContentSuggestionsServiceTest, ShouldRegisterProviders) {
  EXPECT_THAT(service()->state(),
              Eq(ContentSuggestionsService::State::ENABLED));
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  Category offline_pages_category =
      Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  ASSERT_THAT(providers(), IsEmpty());
  EXPECT_THAT(service()->GetCategories(), IsEmpty());
  EXPECT_THAT(service()->GetCategoryStatus(articles_category),
              Eq(CategoryStatus::NOT_PROVIDED));
  EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category),
              Eq(CategoryStatus::NOT_PROVIDED));

  MockContentSuggestionsProvider* provider1 =
      MakeRegisteredMockProvider(articles_category);
  provider1->FireCategoryStatusChangedWithCurrentStatus(articles_category);
  EXPECT_THAT(providers().count(offline_pages_category), Eq(0ul));
  ASSERT_THAT(providers().count(articles_category), Eq(1ul));
  EXPECT_THAT(providers().at(articles_category), Eq(provider1));
  EXPECT_THAT(providers().size(), Eq(1ul));
  EXPECT_THAT(service()->GetCategories(),
              UnorderedElementsAre(articles_category));
  EXPECT_THAT(service()->GetCategoryStatus(articles_category),
              Eq(CategoryStatus::AVAILABLE));
  EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category),
              Eq(CategoryStatus::NOT_PROVIDED));

  MockContentSuggestionsProvider* provider2 =
      MakeRegisteredMockProvider(offline_pages_category);
  provider2->FireCategoryStatusChangedWithCurrentStatus(offline_pages_category);
  ASSERT_THAT(providers().count(offline_pages_category), Eq(1ul));
  EXPECT_THAT(providers().at(articles_category), Eq(provider1));
  ASSERT_THAT(providers().count(articles_category), Eq(1ul));
  EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2));
  EXPECT_THAT(providers().size(), Eq(2ul));
  EXPECT_THAT(service()->GetCategories(),
              UnorderedElementsAre(offline_pages_category, articles_category));
  EXPECT_THAT(service()->GetCategoryStatus(articles_category),
              Eq(CategoryStatus::AVAILABLE));
  EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category),
              Eq(CategoryStatus::AVAILABLE));
}

TEST_F(ContentSuggestionsServiceDisabledTest, ShouldDoNothingWhenDisabled) {
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  Category offline_pages_category =
      Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  EXPECT_THAT(service()->state(),
              Eq(ContentSuggestionsService::State::DISABLED));
  EXPECT_THAT(providers(), IsEmpty());
  EXPECT_THAT(service()->GetCategoryStatus(articles_category),
              Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED));
  EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category),
              Eq(CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED));
  EXPECT_THAT(service()->GetCategories(), IsEmpty());
  EXPECT_THAT(service()->GetSuggestionsForCategory(articles_category),
              IsEmpty());
}

TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) {
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  Category offline_pages_category =
      Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider1 =
      MakeRegisteredMockProvider(articles_category);
  MockContentSuggestionsProvider* provider2 =
      MakeRegisteredMockProvider(offline_pages_category);

  provider1->FireSuggestionsChanged(articles_category,
                                    CreateSuggestions(articles_category, {1}));
  ContentSuggestion::ID suggestion_id(articles_category, "1");

  EXPECT_CALL(*provider1, FetchSuggestionImageMock(suggestion_id, _));
  EXPECT_CALL(*provider2, FetchSuggestionImageMock(_, _)).Times(0);
  service()->FetchSuggestionImage(
      suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched,
                                base::Unretained(this)));
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldCallbackEmptyImageForUnavailableProvider) {
  // Setup the current thread's MessageLoop.
  base::MessageLoop message_loop;

  base::RunLoop run_loop;
  // Assuming there will never be a category with the id below.
  ContentSuggestion::ID suggestion_id(Category::FromIDValue(21563), "TestID");
  EXPECT_CALL(*this, OnImageFetched(Property(&gfx::Image::IsEmpty, Eq(true))))
      .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  service()->FetchSuggestionImage(
      suggestion_id, base::Bind(&ContentSuggestionsServiceTest::OnImageFetched,
                                base::Unretained(this)));
  run_loop.Run();
}

TEST_F(ContentSuggestionsServiceTest, ShouldRedirectDismissSuggestion) {
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  Category offline_pages_category =
      Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider1 =
      MakeRegisteredMockProvider(articles_category);
  MockContentSuggestionsProvider* provider2 =
      MakeRegisteredMockProvider(offline_pages_category);

  provider2->FireSuggestionsChanged(
      offline_pages_category, CreateSuggestions(offline_pages_category, {11}));
  ContentSuggestion::ID suggestion_id(offline_pages_category, "11");

  EXPECT_CALL(*provider1, DismissSuggestion(_)).Times(0);
  EXPECT_CALL(*provider2, DismissSuggestion(suggestion_id));
  service()->DismissSuggestion(suggestion_id);
}

TEST_F(ContentSuggestionsServiceTest, ShouldRedirectSuggestionInvalidated) {
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);

  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(articles_category);
  MockServiceObserver observer;
  service()->AddObserver(&observer);

  provider->FireSuggestionsChanged(
      articles_category, CreateSuggestions(articles_category, {11, 12, 13}));
  ExpectThatSuggestionsAre(articles_category, {11, 12, 13});

  ContentSuggestion::ID suggestion_id(articles_category, "12");
  EXPECT_CALL(observer, OnSuggestionInvalidated(suggestion_id));
  provider->FireSuggestionInvalidated(suggestion_id);
  ExpectThatSuggestionsAre(articles_category, {11, 13});
  Mock::VerifyAndClearExpectations(&observer);

  // Unknown IDs must be forwarded (though no change happens to the service's
  // internal data structures) because previously opened UIs, which can still
  // show the invalidated suggestion, must be notified.
  ContentSuggestion::ID unknown_id(articles_category, "1234");
  EXPECT_CALL(observer, OnSuggestionInvalidated(unknown_id));
  provider->FireSuggestionInvalidated(unknown_id);
  ExpectThatSuggestionsAre(articles_category, {11, 13});
  Mock::VerifyAndClearExpectations(&observer);

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) {
  Category articles_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  Category offline_pages_category =
      Category::FromKnownCategory(KnownCategories::DOWNLOADS);

  // Create and register providers
  MockContentSuggestionsProvider* provider1 =
      MakeRegisteredMockProvider(articles_category);
  provider1->FireCategoryStatusChangedWithCurrentStatus(articles_category);
  MockContentSuggestionsProvider* provider2 =
      MakeRegisteredMockProvider(offline_pages_category);
  provider2->FireCategoryStatusChangedWithCurrentStatus(offline_pages_category);
  ASSERT_THAT(providers().count(articles_category), Eq(1ul));
  EXPECT_THAT(providers().at(articles_category), Eq(provider1));
  ASSERT_THAT(providers().count(offline_pages_category), Eq(1ul));
  EXPECT_THAT(providers().at(offline_pages_category), Eq(provider2));

  // Create and register observer
  MockServiceObserver observer;
  service()->AddObserver(&observer);

  // Send suggestions 1 and 2
  EXPECT_CALL(observer, OnNewSuggestions(articles_category));
  provider1->FireSuggestionsChanged(
      articles_category, CreateSuggestions(articles_category, {1, 2}));
  ExpectThatSuggestionsAre(articles_category, {1, 2});
  Mock::VerifyAndClearExpectations(&observer);

  // Send them again, make sure they're not reported twice
  EXPECT_CALL(observer, OnNewSuggestions(articles_category));
  provider1->FireSuggestionsChanged(
      articles_category, CreateSuggestions(articles_category, {1, 2}));
  ExpectThatSuggestionsAre(articles_category, {1, 2});
  ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>());
  Mock::VerifyAndClearExpectations(&observer);

  // Send suggestions 13 and 14
  EXPECT_CALL(observer, OnNewSuggestions(offline_pages_category));
  provider2->FireSuggestionsChanged(
      offline_pages_category, CreateSuggestions(articles_category, {13, 14}));
  ExpectThatSuggestionsAre(articles_category, {1, 2});
  ExpectThatSuggestionsAre(offline_pages_category, {13, 14});
  Mock::VerifyAndClearExpectations(&observer);

  // Send suggestion 1 only
  EXPECT_CALL(observer, OnNewSuggestions(articles_category));
  provider1->FireSuggestionsChanged(articles_category,
                                    CreateSuggestions(articles_category, {1}));
  ExpectThatSuggestionsAre(articles_category, {1});
  ExpectThatSuggestionsAre(offline_pages_category, {13, 14});
  Mock::VerifyAndClearExpectations(&observer);

  // provider2 reports BOOKMARKS as unavailable
  EXPECT_CALL(observer, OnCategoryStatusChanged(
                            offline_pages_category,
                            CategoryStatus::CATEGORY_EXPLICITLY_DISABLED));
  provider2->FireCategoryStatusChanged(
      offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED);
  EXPECT_THAT(service()->GetCategoryStatus(articles_category),
              Eq(CategoryStatus::AVAILABLE));
  EXPECT_THAT(service()->GetCategoryStatus(offline_pages_category),
              Eq(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED));
  ExpectThatSuggestionsAre(articles_category, {1});
  ExpectThatSuggestionsAre(offline_pages_category, std::vector<int>());
  Mock::VerifyAndClearExpectations(&observer);

  // Shutdown the service
  EXPECT_CALL(observer, ContentSuggestionsServiceShutdown());
  service()->Shutdown();
  service()->RemoveObserver(&observer);
  // The service will receive two Shutdown() calls.
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldNotReturnCategoryInfoForNonexistentCategory) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  base::Optional<CategoryInfo> result = service()->GetCategoryInfo(category);
  EXPECT_FALSE(result.has_value());
}

TEST_F(ContentSuggestionsServiceTest, ShouldReturnCategoryInfo) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  base::Optional<CategoryInfo> result = service()->GetCategoryInfo(category);
  ASSERT_TRUE(result.has_value());
  CategoryInfo expected = provider->GetCategoryInfo(category);
  const CategoryInfo& actual = result.value();
  EXPECT_THAT(expected.title(), Eq(actual.title()));
  EXPECT_THAT(expected.card_layout(), Eq(actual.card_layout()));
  EXPECT_THAT(expected.additional_action(), Eq(actual.additional_action()));
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldRegisterNewCategoryOnNewSuggestions) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  MockServiceObserver observer;
  service()->AddObserver(&observer);

  // Provider starts providing |new_category| without calling
  // |OnCategoryStatusChanged|. This is supported for now until further
  // reconsideration.
  Category new_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  provider->SetProvidedCategories(
      std::vector<Category>({category, new_category}));

  EXPECT_CALL(observer, OnNewSuggestions(new_category));
  EXPECT_CALL(observer,
              OnCategoryStatusChanged(new_category, CategoryStatus::AVAILABLE));
  provider->FireSuggestionsChanged(new_category,
                                   CreateSuggestions(new_category, {1, 2}));

  ExpectThatSuggestionsAre(new_category, {1, 2});
  ASSERT_THAT(providers().count(category), Eq(1ul));
  EXPECT_THAT(providers().at(category), Eq(provider));
  EXPECT_THAT(service()->GetCategoryStatus(category),
              Eq(CategoryStatus::AVAILABLE));
  ASSERT_THAT(providers().count(new_category), Eq(1ul));
  EXPECT_THAT(providers().at(new_category), Eq(provider));
  EXPECT_THAT(service()->GetCategoryStatus(new_category),
              Eq(CategoryStatus::AVAILABLE));

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldRegisterNewCategoryOnCategoryStatusChanged) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  MockServiceObserver observer;
  service()->AddObserver(&observer);

  // Provider starts providing |new_category| and calls
  // |OnCategoryStatusChanged|, but the category is not yet available.
  Category new_category =
      Category::FromKnownCategory(KnownCategories::ARTICLES);
  provider->SetProvidedCategories(
      std::vector<Category>({category, new_category}));
  EXPECT_CALL(observer, OnCategoryStatusChanged(new_category,
                                                CategoryStatus::INITIALIZING));
  provider->FireCategoryStatusChanged(new_category,
                                      CategoryStatus::INITIALIZING);

  ASSERT_THAT(providers().count(new_category), Eq(1ul));
  EXPECT_THAT(providers().at(new_category), Eq(provider));
  ExpectThatSuggestionsAre(new_category, std::vector<int>());
  EXPECT_THAT(service()->GetCategoryStatus(new_category),
              Eq(CategoryStatus::INITIALIZING));
  EXPECT_THAT(service()->GetCategories(),
              UnorderedElementsAre(category, new_category));

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldRemoveCategoryWhenNotProvided) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  MockServiceObserver observer;
  service()->AddObserver(&observer);

  provider->FireSuggestionsChanged(category,
                                   CreateSuggestions(category, {1, 2}));
  ExpectThatSuggestionsAre(category, {1, 2});

  EXPECT_CALL(observer,
              OnCategoryStatusChanged(category, CategoryStatus::NOT_PROVIDED));
  provider->FireCategoryStatusChanged(category, CategoryStatus::NOT_PROVIDED);

  EXPECT_THAT(service()->GetCategoryStatus(category),
              Eq(CategoryStatus::NOT_PROVIDED));
  EXPECT_TRUE(service()->GetCategories().empty());
  ExpectThatSuggestionsAre(category, std::vector<int>());

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldForwardClearHistoryToProviders) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  base::Time begin = base::Time::FromTimeT(123);
  base::Time end = base::Time::FromTimeT(456);
  EXPECT_CALL(*provider, ClearHistory(begin, end, _));
  base::Callback<bool(const GURL& url)> filter;
  service()->ClearHistory(begin, end, filter);
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldForwardClearHistoryToCategoryRanker) {
  auto mock_ranker = std::make_unique<MockCategoryRanker>();
  MockCategoryRanker* raw_mock_ranker = mock_ranker.get();
  SetCategoryRanker(std::move(mock_ranker));

  // The service is recreated to pick up the new ranker.
  ResetService();

  base::Time begin = base::Time::FromTimeT(123),
             end = base::Time::FromTimeT(456);
  EXPECT_CALL(*raw_mock_ranker, ClearHistory(begin, end));
  base::Callback<bool(const GURL& url)> filter;
  service()->ClearHistory(begin, end, filter);
}

TEST_F(ContentSuggestionsServiceTest, ShouldForwardDeleteAllHistoryURLs) {
  StrictMock<MockServiceObserver> observer;
  service()->AddObserver(&observer);
  EXPECT_CALL(observer, OnFullRefreshRequired());

  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  EXPECT_CALL(*provider, ClearHistory(base::Time(), base::Time::Max(), _));
  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr, history::DeletionInfo::ForAllHistory());

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldIgnoreExpiredURLDeletions) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MakeRegisteredMockProvider(category);
  // Create an observer to make sure OnFullRefresh() does not get triggered.
  StrictMock<MockServiceObserver> observer;
  service()->AddObserver(&observer);

  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr,
      history::DeletionInfo(history::DeletionTimeRange::AllTime(),
                            /*expired=*/true, history::URLRows(),
                            /*favicon_urls=*/std::set<GURL>(),
                            /*restrict_urls=*/base::nullopt));
  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr,
      history::DeletionInfo(history::DeletionTimeRange::Invalid(),
                            /*expired=*/true,
                            {history::URLRow(GURL("http://google.com")),
                             history::URLRow(GURL("http://maps.google.com"))},
                            /*favicon_urls=*/std::set<GURL>(),
                            /*restrict_urls=*/base::nullopt));

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldIgnoreEmptyURLDeletions) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MakeRegisteredMockProvider(category);
  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr, history::DeletionInfo::ForUrls({}, {}));
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldNotClearHistoryOnSingleURLDeletion) {
  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MakeRegisteredMockProvider(category);
  // Single URLs should not trigger
  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr,
      history::DeletionInfo::ForUrls(
          {history::URLRow(GURL("http://google.com"))},
          /*favicon_urls=*/std::set<GURL>()));
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldClearHistoryForMultipleURLDeletion) {
  StrictMock<MockServiceObserver> observer;
  service()->AddObserver(&observer);
  EXPECT_CALL(observer, OnFullRefreshRequired());

  Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  EXPECT_CALL(*provider, ClearHistory(base::Time(), base::Time::Max(), _));

  static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
      /*history_service=*/nullptr,
      history::DeletionInfo::ForUrls(
          {history::URLRow(GURL("http://google.com")),
           history::URLRow(GURL("http://youtube.com"))},
          /*favicon_urls=*/std::set<GURL>()));

  service()->RemoveObserver(&observer);
}

TEST_F(ContentSuggestionsServiceTest, ShouldForwardFetch) {
  Category category = Category::FromKnownCategory(KnownCategories::ARTICLES);
  std::set<std::string> known_suggestions;
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  EXPECT_CALL(*provider, FetchMock(category, known_suggestions, _));
  service()->Fetch(category, known_suggestions, FetchDoneCallback());
}

TEST_F(ContentSuggestionsServiceTest, DismissAndRestoreCategory) {
  // Register a category with one suggestion.
  Category category = Category::FromKnownCategory(KnownCategories::ARTICLES);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  provider->FireSuggestionsChanged(category, CreateSuggestions(category, {42}));

  EXPECT_THAT(service()->GetCategories(), UnorderedElementsAre(category));
  EXPECT_THAT(service()->GetCategoryStatus(category),
              Eq(CategoryStatus::AVAILABLE));
  ExpectThatSuggestionsAre(category, {42});
  EXPECT_THAT(providers().count(category), Eq(1ul));
  EXPECT_THAT(dismissed_providers(), IsEmpty());

  // Dismissing the category clears the suggestions for it.
  service()->DismissCategory(category);

  EXPECT_THAT(service()->GetCategories(), IsEmpty());
  EXPECT_THAT(service()->GetCategoryStatus(category),
              Eq(CategoryStatus::NOT_PROVIDED));
  EXPECT_THAT(service()->GetSuggestionsForCategory(category), IsEmpty());
  EXPECT_THAT(providers(), IsEmpty());
  EXPECT_THAT(dismissed_providers().count(category), Eq(1ul));

  // Restoring the dismissed category makes it available again but it is still
  // empty.
  service()->RestoreDismissedCategories();

  EXPECT_THAT(service()->GetCategories(), UnorderedElementsAre(category));
  EXPECT_THAT(service()->GetCategoryStatus(category),
              Eq(CategoryStatus::AVAILABLE));
  EXPECT_THAT(service()->GetSuggestionsForCategory(category), IsEmpty());
  EXPECT_THAT(providers().count(category), Eq(1ul));
  EXPECT_THAT(dismissed_providers(), IsEmpty());
}

TEST_F(ContentSuggestionsServiceTest, ShouldRestoreDismissedCategories) {
  // Create and register provider.
  Category category1 = Category::FromIDValue(1);
  Category category2 = Category::FromIDValue(2);

  // Setup and verify initial state.
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider({category1, category2});
  provider->FireCategoryStatusChangedWithCurrentStatus(category1);
  provider->FireCategoryStatusChangedWithCurrentStatus(category2);

  ASSERT_THAT(service()->GetCategoryStatus(category1),
              Eq(CategoryStatus::AVAILABLE));
  ASSERT_THAT(service()->GetCategoryStatus(category2),
              Eq(CategoryStatus::AVAILABLE));

  // Dismiss all the categories. None should be provided now.
  service()->DismissCategory(category1);
  service()->DismissCategory(category2);

  ASSERT_THAT(service()->GetCategoryStatus(category1),
              Eq(CategoryStatus::NOT_PROVIDED));
  ASSERT_THAT(service()->GetCategoryStatus(category2),
              Eq(CategoryStatus::NOT_PROVIDED));

  // Receiving a status change notification should not change anything.
  provider->FireCategoryStatusChanged(category1, CategoryStatus::AVAILABLE);

  EXPECT_THAT(service()->GetCategoryStatus(category1),
              Eq(CategoryStatus::NOT_PROVIDED));
  EXPECT_THAT(service()->GetCategoryStatus(category2),
              Eq(CategoryStatus::NOT_PROVIDED));

  // Receiving a notification without suggestions should not change anything.
  provider->FireSuggestionsChanged(category1, std::vector<ContentSuggestion>());

  EXPECT_THAT(service()->GetCategoryStatus(category1),
              Eq(CategoryStatus::NOT_PROVIDED));
  EXPECT_THAT(service()->GetCategoryStatus(category2),
              Eq(CategoryStatus::NOT_PROVIDED));

  // Receiving suggestions should make the notified category available.
  provider->FireSuggestionsChanged(category1,
                                   CreateSuggestions(category1, {1, 2}));

  EXPECT_THAT(service()->GetCategoryStatus(category1),
              Eq(CategoryStatus::AVAILABLE));
  EXPECT_THAT(service()->GetCategoryStatus(category2),
              Eq(CategoryStatus::NOT_PROVIDED));
}

TEST_F(ContentSuggestionsServiceTest, ShouldRestoreDismissalsFromPrefs) {
  // Register a category with one suggestion.
  Category category = Category::FromKnownCategory(KnownCategories::ARTICLES);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);

  // For a regular initialisation, the category is not dismissed.
  ASSERT_FALSE(service()->IsCategoryDismissed(category));

  // Dismiss the category.
  service()->DismissCategory(category);
  ASSERT_TRUE(service()->IsCategoryDismissed(category));

  // Simulate a Chrome restart. The category should still be dismissed.
  ResetService();
  EXPECT_TRUE(service()->IsCategoryDismissed(category));

  // Ensure that the provider registered at initialisation is used after
  // restoration.
  provider = MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);
  EXPECT_TRUE(service()->IsCategoryDismissed(category));

  service()->RestoreDismissedCategories();
  EXPECT_FALSE(service()->IsCategoryDismissed(category));
  EXPECT_THAT(providers().find(category)->second, Eq(provider));
}

TEST_F(ContentSuggestionsServiceTest, ShouldReturnCategoriesInOrderToDisplay) {
  const Category first_category = Category::FromRemoteCategory(1);
  const Category second_category = Category::FromRemoteCategory(2);

  auto fake_ranker = std::make_unique<FakeCategoryRanker>();
  FakeCategoryRanker* raw_fake_ranker = fake_ranker.get();
  SetCategoryRanker(std::move(fake_ranker));

  raw_fake_ranker->SetOrder({first_category, second_category});

  // The service is recreated to pick up the new ranker.
  ResetService();

  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider({first_category, second_category});
  provider->FireCategoryStatusChangedWithCurrentStatus(first_category);
  provider->FireCategoryStatusChangedWithCurrentStatus(second_category);

  EXPECT_THAT(service()->GetCategories(),
              ElementsAre(first_category, second_category));

  // The order to display (in the ranker) changes.
  raw_fake_ranker->SetOrder({second_category, first_category});

  // Categories order should reflect the new order.
  EXPECT_THAT(service()->GetCategories(),
              ElementsAre(second_category, first_category));
}

TEST_F(ContentSuggestionsServiceTest,
       ShouldForwardDismissedCategoryToCategoryRanker) {
  auto mock_ranker = std::make_unique<MockCategoryRanker>();
  MockCategoryRanker* raw_mock_ranker = mock_ranker.get();
  SetCategoryRanker(std::move(mock_ranker));

  // The service is recreated to pick up the new ranker.
  ResetService();

  Category category = Category::FromKnownCategory(KnownCategories::BOOKMARKS);
  MockContentSuggestionsProvider* provider =
      MakeRegisteredMockProvider(category);
  provider->FireCategoryStatusChangedWithCurrentStatus(category);

  EXPECT_CALL(*raw_mock_ranker, OnCategoryDismissed(category));
  service()->DismissCategory(category);
}

}  // namespace ntp_snippets
