123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710 |
- // Copyright 2015 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_tiles/most_visited_sites.h"
- #include <stddef.h>
- #include <map>
- #include <memory>
- #include <ostream>
- #include <string>
- #include <tuple>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_list.h"
- #include "base/command_line.h"
- #include "base/feature_list.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/task/cancelable_task_tracker.h"
- #include "base/test/gmock_callback_support.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "build/build_config.h"
- #include "components/history/core/browser/top_sites.h"
- #include "components/history/core/browser/top_sites_observer.h"
- #include "components/ntp_tiles/custom_links_manager.h"
- #include "components/ntp_tiles/features.h"
- #include "components/ntp_tiles/icon_cacher.h"
- #include "components/ntp_tiles/popular_sites_impl.h"
- #include "components/ntp_tiles/pref_names.h"
- #include "components/ntp_tiles/section_type.h"
- #include "components/ntp_tiles/switches.h"
- #include "components/sync_preferences/testing_pref_service_syncable.h"
- #include "components/webapps/common/constants.h"
- #include "extensions/buildflags/buildflags.h"
- #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
- #include "services/network/public/cpp/shared_url_loader_factory.h"
- #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
- #include "services/network/test/test_url_loader_factory.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace ntp_tiles {
- // Defined for googletest. Must be defined in the same namespace.
- void PrintTo(const NTPTile& tile, std::ostream* os) {
- *os << "{\"" << tile.title << "\", \"" << tile.url << "\", "
- << static_cast<int>(tile.source) << "}";
- }
- namespace {
- using history::MostVisitedURL;
- using history::MostVisitedURLList;
- using history::TopSites;
- using testing::_;
- using testing::AllOf;
- using testing::AnyNumber;
- using testing::AtLeast;
- using testing::ByMove;
- using testing::Contains;
- using testing::DoAll;
- using testing::ElementsAre;
- using testing::Eq;
- using testing::Ge;
- using testing::InSequence;
- using testing::Invoke;
- using testing::IsEmpty;
- using testing::Key;
- using testing::Mock;
- using testing::Not;
- using testing::Pair;
- using testing::Return;
- using testing::ReturnRef;
- using testing::SaveArg;
- using testing::SizeIs;
- using testing::StrictMock;
- const char kHomepageUrl[] = "http://homepa.ge/";
- const char16_t kHomepageTitle[] = u"Homepage";
- const char kTestExploreUrl[] = "https://example.com/";
- const char16_t kTestExploreTitle[] = u"Example";
- std::string PrintTile(const std::u16string& title,
- const std::string& url,
- TileSource source) {
- return std::string("has title \"") + base::UTF16ToUTF8(title) +
- std::string("\" and url \"") + url + std::string("\" and source ") +
- testing::PrintToString(static_cast<int>(source));
- }
- MATCHER_P3(MatchesTile, title, url, source, PrintTile(title, url, source)) {
- return arg.title == title && arg.url == GURL(url) && arg.source == source;
- }
- std::string PrintTileSource(TileSource source) {
- return std::string("has source ") +
- testing::PrintToString(static_cast<int>(source));
- }
- MATCHER_P(TileWithSource, source, PrintTileSource(source)) {
- return arg.source == source;
- }
- MATCHER_P3(LastTileIs,
- title,
- url,
- source,
- std::string("last tile ") + PrintTile(title, url, source)) {
- const NTPTilesVector& tiles = arg.at(SectionType::PERSONALIZED);
- if (tiles.empty())
- return false;
- const NTPTile& last = tiles.back();
- return last.title == title && last.url == GURL(url) && last.source == source;
- }
- MATCHER_P3(FirstPersonalizedTileIs,
- title,
- url,
- source,
- std::string("first tile ") + PrintTile(title, url, source)) {
- if (arg.count(SectionType::PERSONALIZED) == 0) {
- return false;
- }
- const NTPTilesVector& tiles = arg.at(SectionType::PERSONALIZED);
- return !tiles.empty() && tiles[0].title == title &&
- tiles[0].url == GURL(url) && tiles[0].source == source;
- }
- NTPTile MakeTile(const std::u16string& title,
- const std::string& url,
- TileSource source) {
- NTPTile tile;
- tile.title = title;
- tile.url = GURL(url);
- tile.source = source;
- return tile;
- }
- MostVisitedURL MakeMostVisitedURL(const std::u16string& title,
- const std::string& url) {
- MostVisitedURL result;
- result.title = title;
- result.url = GURL(url);
- return result;
- }
- class MockTopSites : public TopSites {
- public:
- MOCK_METHOD0(ShutdownOnUIThread, void());
- MOCK_METHOD1(GetMostVisitedURLs, void(GetMostVisitedURLsCallback callback));
- MOCK_METHOD0(SyncWithHistory, void());
- MOCK_CONST_METHOD0(HasBlockedUrls, bool());
- MOCK_METHOD1(AddBlockedUrl, void(const GURL& url));
- MOCK_METHOD1(RemoveBlockedUrl, void(const GURL& url));
- MOCK_METHOD1(IsBlocked, bool(const GURL& url));
- MOCK_METHOD0(ClearBlockedUrls, void());
- MOCK_METHOD0(StartQueryForMostVisited, base::CancelableTaskTracker::TaskId());
- MOCK_METHOD1(IsKnownURL, bool(const GURL& url));
- MOCK_CONST_METHOD1(GetCanonicalURLString,
- const std::string&(const GURL& url));
- MOCK_METHOD0(IsFull, bool());
- MOCK_CONST_METHOD0(loaded, bool());
- MOCK_METHOD0(GetPrepopulatedPages, history::PrepopulatedPageList());
- MOCK_METHOD1(OnNavigationCommitted, void(const GURL& url));
- // Publicly expose notification to observers, since the implementation cannot
- // be overriden.
- using TopSites::NotifyTopSitesChanged;
- protected:
- ~MockTopSites() override = default;
- };
- class MockMostVisitedSitesObserver : public MostVisitedSites::Observer {
- public:
- MOCK_METHOD1(OnURLsAvailable,
- void(const std::map<SectionType, NTPTilesVector>& sections));
- MOCK_METHOD1(OnIconMadeAvailable, void(const GURL& site_url));
- };
- class FakeHomepageClient : public MostVisitedSites::HomepageClient {
- public:
- FakeHomepageClient()
- : homepage_tile_enabled_(false), homepage_url_(kHomepageUrl) {}
- ~FakeHomepageClient() override {}
- bool IsHomepageTileEnabled() const override { return homepage_tile_enabled_; }
- GURL GetHomepageUrl() const override { return homepage_url_; }
- void QueryHomepageTitle(TitleCallback title_callback) override {
- std::move(title_callback).Run(homepage_title_);
- }
- void SetHomepageTileEnabled(bool homepage_tile_enabled) {
- homepage_tile_enabled_ = homepage_tile_enabled;
- }
- void SetHomepageUrl(GURL homepage_url) { homepage_url_ = homepage_url; }
- void SetHomepageTitle(const absl::optional<std::u16string>& homepage_title) {
- homepage_title_ = homepage_title;
- }
- private:
- bool homepage_tile_enabled_;
- GURL homepage_url_;
- absl::optional<std::u16string> homepage_title_;
- };
- class FakeExploreSitesClient : public MostVisitedSites::ExploreSitesClient {
- public:
- ~FakeExploreSitesClient() override = default;
- GURL GetExploreSitesUrl() const override { return GURL(kTestExploreUrl); }
- std::u16string GetExploreSitesTitle() const override {
- return kTestExploreTitle;
- }
- };
- class MockIconCacher : public IconCacher {
- public:
- MOCK_METHOD3(StartFetchPopularSites,
- void(PopularSites::Site site,
- base::OnceClosure icon_available,
- base::OnceClosure preliminary_icon_available));
- MOCK_METHOD2(StartFetchMostLikely,
- void(const GURL& page_url, base::OnceClosure icon_available));
- };
- class MockCustomLinksManager : public CustomLinksManager {
- public:
- MOCK_METHOD1(Initialize, bool(const NTPTilesVector& tiles));
- MOCK_METHOD0(Uninitialize, void());
- MOCK_CONST_METHOD0(IsInitialized, bool());
- MOCK_CONST_METHOD0(GetLinks, const std::vector<CustomLinksManager::Link>&());
- MOCK_METHOD2(AddLink, bool(const GURL& url, const std::u16string& title));
- MOCK_METHOD3(UpdateLink,
- bool(const GURL& url,
- const GURL& new_url,
- const std::u16string& new_title));
- MOCK_METHOD2(ReorderLink, bool(const GURL& url, size_t new_pos));
- MOCK_METHOD1(DeleteLink, bool(const GURL& url));
- MOCK_METHOD0(UndoAction, bool());
- MOCK_METHOD1(RegisterCallbackForOnChanged,
- base::CallbackListSubscription(base::RepeatingClosure callback));
- };
- class PopularSitesFactoryForTest {
- public:
- explicit PopularSitesFactoryForTest(
- sync_preferences::TestingPrefServiceSyncable* pref_service)
- : prefs_(pref_service) {
- test_shared_loader_factory_ =
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_);
- PopularSitesImpl::RegisterProfilePrefs(pref_service->registry());
- }
- void SeedWithSampleData() {
- prefs_->SetString(prefs::kPopularSitesOverrideCountry, "IN");
- prefs_->SetString(prefs::kPopularSitesOverrideVersion, "5");
- test_url_loader_factory_.ClearResponses();
- test_url_loader_factory_.AddResponse(
- "https://www.gstatic.com/chrome/ntp/suggested_sites_IN_5.json",
- R"([{
- "title": "PopularSite1",
- "url": "http://popularsite1/",
- "favicon_url": "http://popularsite1/favicon.ico"
- },
- {
- "title": "PopularSite2",
- "url": "http://popularsite2/",
- "favicon_url": "http://popularsite2/favicon.ico"
- }
- ])");
- test_url_loader_factory_.AddResponse(
- "https://www.gstatic.com/chrome/ntp/suggested_sites_US_5.json",
- R"([{
- "title": "ESPN",
- "url": "http://www.espn.com",
- "favicon_url": "http://www.espn.com/favicon.ico"
- }, {
- "title": "Mobile",
- "url": "http://www.mobile.de",
- "favicon_url": "http://www.mobile.de/favicon.ico"
- }, {
- "title": "Google News",
- "url": "http://news.google.com",
- "favicon_url": "http://news.google.com/favicon.ico"
- }
- ])");
- test_url_loader_factory_.AddResponse(
- "https://www.gstatic.com/chrome/ntp/suggested_sites_IN_6.json",
- R"([{
- "section": 1, // PERSONALIZED
- "sites": [{
- "title": "PopularSite1",
- "url": "http://popularsite1/",
- "favicon_url": "http://popularsite1/favicon.ico"
- },
- {
- "title": "PopularSite2",
- "url": "http://popularsite2/",
- "favicon_url": "http://popularsite2/favicon.ico"
- },
- ]
- },
- {
- "section": 4, // NEWS
- "sites": [{
- "large_icon_url": "https://news.google.com/icon.ico",
- "title": "Google News",
- "url": "https://news.google.com/"
- },
- {
- "favicon_url": "https://news.google.com/icon.ico",
- "title": "Google News Germany",
- "url": "https://news.google.de/"
- }]
- },
- {
- "section": 2, // SOCIAL
- "sites": [{
- "large_icon_url": "https://ssl.gstatic.com/icon.png",
- "title": "Google+",
- "url": "https://plus.google.com/"
- }]
- },
- {
- "section": 3, // ENTERTAINMENT
- "sites": [
- // Intentionally empty site list.
- ]
- }
- ])");
- }
- std::unique_ptr<PopularSites> New() {
- return std::make_unique<PopularSitesImpl>(prefs_,
- /*template_url_service=*/nullptr,
- /*variations_service=*/nullptr,
- test_shared_loader_factory_);
- }
- private:
- raw_ptr<PrefService> prefs_;
- network::TestURLLoaderFactory test_url_loader_factory_;
- scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
- };
- } // namespace
- // Param specifies whether Popular Sites is enabled via variations.
- class MostVisitedSitesTest : public ::testing::TestWithParam<bool> {
- protected:
- using TopSitesCallbackList =
- base::OnceCallbackList<TopSites::GetMostVisitedURLsCallback::RunType>;
- MostVisitedSitesTest() {
- MostVisitedSites::RegisterProfilePrefs(pref_service_.registry());
- std::vector<base::Feature> enabled_features;
- // Disable FaviconServer in most tests and override in specific tests.
- std::vector<base::Feature> disabled_features = {
- kNtpMostLikelyFaviconsFromServerFeature};
- if (IsPopularSitesFeatureEnabled()) {
- enabled_features.push_back(kUsePopularSitesSuggestions);
- } else {
- disabled_features.push_back(kUsePopularSitesSuggestions);
- }
- // Updating list value in pref with default gmail URL for unit testing.
- // Also adding migration feature to be enabled for unit test.
- base::Value::List defaults;
- defaults.Append("pjkljhegncpnkpknbcohdijeoejaedia");
- pref_service_.registry()->RegisterListPref(
- webapps::kWebAppsMigratedPreinstalledApps,
- base::Value(std::move(defaults)));
- feature_list_.InitWithFeatures(enabled_features, disabled_features);
- if (IsPopularSitesFeatureEnabled())
- popular_sites_factory_.SeedWithSampleData();
- RecreateMostVisitedSites();
- }
- void RecreateMostVisitedSites() {
- // We use StrictMock to make sure the object is not used unless Popular
- // Sites is enabled.
- auto icon_cacher = std::make_unique<StrictMock<MockIconCacher>>();
- icon_cacher_ = icon_cacher.get();
- // Custom links needs to be nullptr when MostVisitedSites is created, unless
- // the custom links feature is enabled. Custom links is disabled for
- // Android, iOS, and third-party NTPs.
- std::unique_ptr<StrictMock<MockCustomLinksManager>> mock_custom_links;
- if (is_custom_links_enabled_) {
- mock_custom_links =
- std::make_unique<StrictMock<MockCustomLinksManager>>();
- mock_custom_links_ = mock_custom_links.get();
- }
- if (IsPopularSitesFeatureEnabled()) {
- // Populate Popular Sites' internal cache by mimicking a past usage of
- // PopularSitesImpl.
- auto tmp_popular_sites = popular_sites_factory_.New();
- base::RunLoop loop;
- bool save_success = false;
- tmp_popular_sites->MaybeStartFetch(
- /*force_download=*/true,
- base::BindOnce(
- [](bool* save_success, base::RunLoop* loop, bool success) {
- *save_success = success;
- loop->Quit();
- },
- &save_success, &loop));
- loop.Run();
- EXPECT_TRUE(save_success);
- // With PopularSites enabled, blocked urls is exercised.
- EXPECT_CALL(*mock_top_sites_, IsBlocked(_)).WillRepeatedly(Return(false));
- // Mock icon cacher never replies, and we also don't verify whether the
- // code uses it correctly.
- EXPECT_CALL(*icon_cacher, StartFetchPopularSites(_, _, _))
- .Times(AtLeast(0));
- }
- EXPECT_CALL(*icon_cacher, StartFetchMostLikely(_, _)).Times(AtLeast(0));
- most_visited_sites_ = std::make_unique<MostVisitedSites>(
- &pref_service_, mock_top_sites_, popular_sites_factory_.New(),
- std::move(mock_custom_links), std::move(icon_cacher),
- /*supervisor=*/nullptr, true);
- }
- bool IsPopularSitesFeatureEnabled() const { return GetParam(); }
- bool VerifyAndClearExpectations() {
- base::RunLoop().RunUntilIdle();
- const bool success =
- Mock::VerifyAndClearExpectations(mock_top_sites_.get()) &&
- Mock::VerifyAndClearExpectations(&mock_observer_);
- // For convenience, restore the expectations for IsBlocked().
- if (IsPopularSitesFeatureEnabled()) {
- EXPECT_CALL(*mock_top_sites_, IsBlocked(_)).WillRepeatedly(Return(false));
- }
- return success;
- }
- FakeHomepageClient* RegisterNewHomepageClient() {
- auto homepage_client = std::make_unique<FakeHomepageClient>();
- FakeHomepageClient* raw_client_ptr = homepage_client.get();
- most_visited_sites_->SetHomepageClient(std::move(homepage_client));
- return raw_client_ptr;
- }
- FakeExploreSitesClient* RegisterNewExploreSitesClient() {
- auto explore_sites_client = std::make_unique<FakeExploreSitesClient>();
- FakeExploreSitesClient* raw_client_ptr = explore_sites_client.get();
- most_visited_sites_->SetExploreSitesClient(std::move(explore_sites_client));
- return raw_client_ptr;
- }
- void EnableCustomLinks() { is_custom_links_enabled_ = true; }
- bool is_custom_links_enabled_ = false;
- TopSitesCallbackList top_sites_callbacks_;
- base::test::SingleThreadTaskEnvironment task_environment_;
- data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
- sync_preferences::TestingPrefServiceSyncable pref_service_;
- PopularSitesFactoryForTest popular_sites_factory_{&pref_service_};
- scoped_refptr<StrictMock<MockTopSites>> mock_top_sites_ =
- base::MakeRefCounted<StrictMock<MockTopSites>>();
- StrictMock<MockMostVisitedSitesObserver> mock_observer_;
- StrictMock<MockMostVisitedSitesObserver> mock_other_observer_;
- std::unique_ptr<MostVisitedSites> most_visited_sites_;
- base::test::ScopedFeatureList feature_list_;
- raw_ptr<MockCustomLinksManager> mock_custom_links_;
- raw_ptr<MockIconCacher> icon_cacher_;
- };
- TEST_P(MostVisitedSitesTest, ShouldStartNoCallInConstructor) {
- // No call to mocks expected by the mere fact of instantiating
- // MostVisitedSites.
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldRefreshBackends) {
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- most_visited_sites_->Refresh();
- }
- TEST_P(MostVisitedSitesTest, ShouldIncludeTileForHomepage) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(FirstPersonalizedTileIs(
- u"", kHomepageUrl, TileSource::HOMEPAGE)));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageWithoutClient) {
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldIncludeHomeTileWithUrlBeforeQueryingName) {
- // Because the query time for the real name might take a while, provide the
- // home tile with URL as title immediately and update the tiles as soon as the
- // real title was found.
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- homepage_client->SetHomepageTitle(kHomepageTitle);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- {
- testing::Sequence seq;
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(kHomepageTitle, kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- }
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldUpdateHomepageTileWhenRefreshHomepageTile) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- // Ensure that home tile is available as usual.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(FirstPersonalizedTileIs(
- u"", kHomepageUrl, TileSource::HOMEPAGE)));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- VerifyAndClearExpectations();
- // Disable home page and rebuild _without_ Resync. The tile should be gone.
- homepage_client->SetHomepageTileEnabled(false);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory()).Times(0);
- EXPECT_CALL(mock_observer_, OnURLsAvailable(Not(FirstPersonalizedTileIs(
- u"", kHomepageUrl, TileSource::HOMEPAGE))));
- most_visited_sites_->RefreshTiles();
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfNoTileRequested) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(
- mock_observer_,
- OnURLsAvailable(Contains(Pair(SectionType::PERSONALIZED, IsEmpty()))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/0);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldReturnHomepageIfOneTileRequested) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>((
- MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/")})));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(
- mock_observer_,
- OnURLsAvailable(Contains(Pair(
- SectionType::PERSONALIZED,
- ElementsAre(MatchesTile(u"", kHomepageUrl, TileSource::HOMEPAGE))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldHaveHomepageFirstInListWhenFull) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>((MostVisitedURLList{
- MakeMostVisitedURL(u"Site 1", "http://site1/"),
- MakeMostVisitedURL(u"Site 2", "http://site2/"),
- MakeMostVisitedURL(u"Site 3", "http://site3/"),
- MakeMostVisitedURL(u"Site 4", "http://site4/"),
- MakeMostVisitedURL(u"Site 5", "http://site5/"),
- })));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- std::map<SectionType, NTPTilesVector> sections;
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/4);
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(sections, Contains(Key(SectionType::PERSONALIZED)));
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(4ul));
- // Assert that the home page is appended as the final tile.
- EXPECT_THAT(tiles[0], MatchesTile(u"", kHomepageUrl, TileSource::HOMEPAGE));
- }
- // The following test exercises behavior with a preinstalled chrome app; this
- // is only relevant if extensions and apps are enabled.
- #if BUILDFLAG(ENABLE_EXTENSIONS)
- TEST_P(MostVisitedSitesTest, ShouldNotContainDefaultPreinstalledApp) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- const char kGmailUrl[] =
- "chrome-extension://pjkljhegncpnkpknbcohdijeoejaedia/index.html";
- const char16_t kGmailTitle[] = u"Gmail";
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kGmailTitle, kGmailUrl),
- MakeMostVisitedURL(kTestTitle, kTestUrl)}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- std::map<SectionType, NTPTilesVector> sections;
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillRepeatedly(SaveArg<0>(§ions));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/2);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(sections.at(SectionType::PERSONALIZED),
- AllOf(Not(Contains(MatchesTile(kGmailTitle, kGmailUrl,
- TileSource::TOP_SITES))),
- Contains(MatchesTile(kTestTitle, kTestUrl,
- TileSource::TOP_SITES))));
- }
- #endif // BUILDFLAG(ENABLE_EXTENSIONS)
- TEST_P(MostVisitedSitesTest, ShouldHaveHomepageFirstInListWhenNotFull) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>((MostVisitedURLList{
- MakeMostVisitedURL(u"Site 1", "http://site1/"),
- MakeMostVisitedURL(u"Site 2", "http://site2/"),
- MakeMostVisitedURL(u"Site 3", "http://site3/"),
- MakeMostVisitedURL(u"Site 4", "http://site4/"),
- MakeMostVisitedURL(u"Site 5", "http://site5/"),
- })));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- std::map<SectionType, NTPTilesVector> sections;
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/8);
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(sections, Contains(Key(SectionType::PERSONALIZED)));
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(6ul));
- // Assert that the home page is the first tile.
- EXPECT_THAT(tiles[0], MatchesTile(u"", kHomepageUrl, TileSource::HOMEPAGE));
- }
- TEST_P(MostVisitedSitesTest, ShouldDeduplicateHomepageWithTopSites) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- (MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/"),
- MakeMostVisitedURL(u"", kHomepageUrl)})));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(
- mock_observer_,
- OnURLsAvailable(Contains(Pair(
- SectionType::PERSONALIZED,
- AllOf(Contains(MatchesTile(u"", kHomepageUrl, TileSource::HOMEPAGE)),
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::TOP_SITES))))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfThereIsNone) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(false);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfEmptyUrl) {
- const std::string kEmptyHomepageUrl;
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- homepage_client->SetHomepageUrl(GURL(kEmptyHomepageUrl));
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(kEmptyHomepageUrl)))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Not(FirstPersonalizedTileIs(
- u"", kEmptyHomepageUrl, TileSource::HOMEPAGE))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomepageIfBlocked) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- (MostVisitedURLList{MakeMostVisitedURL(u"", kHomepageUrl)})));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AnyNumber())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AtLeast(1))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldPinHomepageAgainIfBlockedUndone) {
- FakeHomepageClient* homepage_client = RegisterNewHomepageClient();
- homepage_client->SetHomepageTileEnabled(true);
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillOnce(base::test::RunOnceCallback<0>(
- (MostVisitedURLList{MakeMostVisitedURL(u"", kHomepageUrl)})));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AtLeast(1))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- Not(Contains(MatchesTile(u"", kHomepageUrl,
- TileSource::HOMEPAGE)))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- VerifyAndClearExpectations();
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillOnce(base::test::RunOnceCallback<0>(MostVisitedURLList{}));
- EXPECT_CALL(*mock_top_sites_, IsBlocked(Eq(GURL(kHomepageUrl))))
- .Times(AtLeast(1))
- .WillRepeatedly(Return(false));
- EXPECT_CALL(
- mock_observer_,
- OnURLsAvailable(Contains(Pair(
- SectionType::PERSONALIZED,
- Contains(MatchesTile(u"", kHomepageUrl, TileSource::HOMEPAGE))))));
- most_visited_sites_->OnBlockedSitesChanged();
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldNotIncludeTileForExploreSitesIfNoClient) {
- // Does not register an explore sites client.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{
- MakeMostVisitedURL(u"ESPN", "http://espn.com/"),
- MakeMostVisitedURL(u"Mobile", "http://m.mobile.de/"),
- MakeMostVisitedURL(u"Google", "http://www.google.com/")}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Not(Contains(
- Pair(SectionType::PERSONALIZED,
- Contains(TileWithSource(TileSource::EXPLORE)))))));
- // Note that 5 sites are requested, this means that there should be the 3 from
- // top sites and two from popular sites.
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/5);
- base::RunLoop().RunUntilIdle();
- }
- // Tests that the explore sites tile appears when there is a mix of top sites
- // and popular sites.
- TEST_P(MostVisitedSitesTest, ShouldIncludeTileForExploreSites) {
- RegisterNewExploreSitesClient();
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{
- MakeMostVisitedURL(u"ESPN", "http://espn.com/"),
- MakeMostVisitedURL(u"Mobile", "http://m.mobile.de/"),
- MakeMostVisitedURL(u"Google", "http://www.google.com/")}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(LastTileIs(kTestExploreTitle, kTestExploreUrl,
- TileSource::EXPLORE)));
- // Note that 5 sites are requested, this means that there should be the 3 from
- // top sites, one from popular sites, and one explore tile.
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/5);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, RemovesPersonalSiteIfExploreSitesTilePresent) {
- RegisterNewExploreSitesClient();
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{
- MakeMostVisitedURL(u"ESPN", "http://espn.com/"),
- MakeMostVisitedURL(u"Mobile", "http://m.mobile.de/"),
- MakeMostVisitedURL(u"Google", "http://www.google.com/")}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(Pair(
- SectionType::PERSONALIZED,
- ElementsAre(MatchesTile(u"ESPN", "http://espn.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Mobile", "http://m.mobile.de/",
- TileSource::TOP_SITES),
- MatchesTile(kTestExploreTitle, kTestExploreUrl,
- TileSource::EXPLORE))))));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesTest, ShouldInformSuggestionSourcesWhenBlocked) {
- EXPECT_CALL(*mock_top_sites_, AddBlockedUrl(Eq(GURL(kHomepageUrl)))).Times(1);
- most_visited_sites_->AddOrRemoveBlockedUrl(GURL(kHomepageUrl),
- /*add_url=*/true);
- EXPECT_CALL(*mock_top_sites_, RemoveBlockedUrl(Eq(GURL(kHomepageUrl))))
- .Times(1);
- most_visited_sites_->AddOrRemoveBlockedUrl(GURL(kHomepageUrl),
- /*add_url=*/false);
- }
- TEST_P(MostVisitedSitesTest,
- ShouldDeduplicatePopularSitesWithMostVisitedIffHostAndTitleMatches) {
- pref_service_.SetString(prefs::kPopularSitesOverrideCountry, "US");
- RecreateMostVisitedSites(); // Refills cache with ESPN and Google News.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{
- MakeMostVisitedURL(u"ESPN", "http://espn.com/"),
- MakeMostVisitedURL(u"Mobile", "http://m.mobile.de/"),
- MakeMostVisitedURL(u"Google", "http://www.google.com/")}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- std::map<SectionType, NTPTilesVector> sections;
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/6);
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(sections, Contains(Key(SectionType::PERSONALIZED)));
- EXPECT_THAT(sections.at(SectionType::PERSONALIZED),
- Contains(MatchesTile(u"Google", "http://www.google.com/",
- TileSource::TOP_SITES)));
- if (IsPopularSitesFeatureEnabled()) {
- EXPECT_THAT(sections.at(SectionType::PERSONALIZED),
- Contains(MatchesTile(u"Google News", "http://news.google.com/",
- TileSource::POPULAR)));
- }
- EXPECT_THAT(sections.at(SectionType::PERSONALIZED),
- AllOf(Contains(MatchesTile(u"ESPN", "http://espn.com/",
- TileSource::TOP_SITES)),
- Contains(MatchesTile(u"Mobile", "http://m.mobile.de/",
- TileSource::TOP_SITES)),
- Not(Contains(MatchesTile(u"ESPN", "http://www.espn.com/",
- TileSource::POPULAR))),
- Not(Contains(MatchesTile(u"Mobile", "http://www.mobile.de/",
- TileSource::POPULAR)))));
- }
- TEST_P(MostVisitedSitesTest, ShouldHandleTopSitesCacheHit) {
- // If cached, TopSites returns the tiles synchronously, running the callback
- // even before the function returns.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(u"Site 1", "http://site1/")}));
- InSequence seq;
- if (IsPopularSitesFeatureEnabled()) {
- EXPECT_CALL(
- mock_observer_,
- OnURLsAvailable(Contains(Pair(
- SectionType::PERSONALIZED,
- ElementsAre(
- MatchesTile(u"Site 1", "http://site1/", TileSource::TOP_SITES),
- MatchesTile(u"PopularSite1", "http://popularsite1/",
- TileSource::POPULAR),
- MatchesTile(u"PopularSite2", "http://popularsite2/",
- TileSource::POPULAR))))));
- } else {
- EXPECT_CALL(mock_observer_,
- OnURLsAvailable(Contains(
- Pair(SectionType::PERSONALIZED,
- ElementsAre(MatchesTile(u"Site 1", "http://site1/",
- TileSource::TOP_SITES))))));
- }
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- VerifyAndClearExpectations();
- CHECK(top_sites_callbacks_.empty());
- // Update by TopSites is propagated.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillOnce(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(u"Site 2", "http://site2/")}));
- if (IsPopularSitesFeatureEnabled()) {
- EXPECT_CALL(*mock_top_sites_, IsBlocked(_)).WillRepeatedly(Return(false));
- }
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_));
- mock_top_sites_->NotifyTopSitesChanged(
- history::TopSitesObserver::ChangeReason::MOST_VISITED);
- base::RunLoop().RunUntilIdle();
- }
- // Tests that multiple observers can be added to the MostVisitedSites.
- TEST_P(MostVisitedSitesTest, MultipleObservers) {
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(MostVisitedURLList{
- MakeMostVisitedURL(u"ESPN", "http://espn.com/"),
- MakeMostVisitedURL(u"Mobile", "http://m.mobile.de/"),
- MakeMostVisitedURL(u"Google", "http://www.google.com/")}));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- std::map<SectionType, NTPTilesVector> sections;
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/2);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- sections.at(SectionType::PERSONALIZED),
- AllOf(Contains(MatchesTile(u"ESPN", "http://espn.com/",
- TileSource::TOP_SITES)),
- Contains(MatchesTile(u"Mobile", "http://m.mobile.de/",
- TileSource::TOP_SITES)),
- Not(Contains(MatchesTile(u"Google", "http://www.google.com/",
- TileSource::TOP_SITES)))));
- // Verifies that multiple observers can be added.
- sections.clear();
- std::map<SectionType, NTPTilesVector> sections_other;
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory()).Times(1);
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillRepeatedly(SaveArg<0>(§ions));
- EXPECT_CALL(mock_other_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions_other));
- most_visited_sites_->RefreshTiles();
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_other_observer_,
- /*max_num_sites=*/2);
- base::RunLoop().RunUntilIdle();
- // Verifies that two observers will be notified with the same suggestions.
- EXPECT_TRUE(sections == sections_other);
- ASSERT_THAT(sections, Contains(Key(SectionType::PERSONALIZED)));
- EXPECT_THAT(
- sections.at(SectionType::PERSONALIZED),
- AllOf(Contains(MatchesTile(u"ESPN", "http://espn.com/",
- TileSource::TOP_SITES)),
- Contains(MatchesTile(u"Mobile", "http://m.mobile.de/",
- TileSource::TOP_SITES)),
- Not(Contains(MatchesTile(u"Google", "http://www.google.com/",
- TileSource::TOP_SITES)))));
- }
- INSTANTIATE_TEST_SUITE_P(MostVisitedSitesTest,
- MostVisitedSitesTest,
- ::testing::Bool());
- TEST(MostVisitedSitesTest, ShouldDeduplicateDomainWithNoWwwDomain) {
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"www.mobile.de"},
- "mobile.de"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"mobile.de"},
- "www.mobile.de"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"mobile.co.uk"},
- "www.mobile.co.uk"));
- }
- TEST(MostVisitedSitesTest, ShouldDeduplicateDomainByRemovingMobilePrefixes) {
- EXPECT_TRUE(
- MostVisitedSites::IsHostOrMobilePageKnown({"bbc.co.uk"}, "m.bbc.co.uk"));
- EXPECT_TRUE(
- MostVisitedSites::IsHostOrMobilePageKnown({"m.bbc.co.uk"}, "bbc.co.uk"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"cnn.com"},
- "edition.cnn.com"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"edition.cnn.com"},
- "cnn.com"));
- EXPECT_TRUE(
- MostVisitedSites::IsHostOrMobilePageKnown({"cnn.com"}, "mobile.cnn.com"));
- EXPECT_TRUE(
- MostVisitedSites::IsHostOrMobilePageKnown({"mobile.cnn.com"}, "cnn.com"));
- }
- TEST(MostVisitedSitesTest, ShouldDeduplicateDomainByReplacingMobilePrefixes) {
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"www.bbc.co.uk"},
- "m.bbc.co.uk"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"m.mobile.de"},
- "www.mobile.de"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"www.cnn.com"},
- "edition.cnn.com"));
- EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"mobile.cnn.com"},
- "www.cnn.com"));
- }
- #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
- class MostVisitedSitesWithCustomLinksTest : public MostVisitedSitesTest {
- public:
- MostVisitedSitesWithCustomLinksTest() {
- EnableCustomLinks();
- RecreateMostVisitedSites();
- }
- void ExpectBuildWithTopSites(
- const MostVisitedURLList& expected_list,
- std::map<SectionType, NTPTilesVector>* sections) {
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(expected_list));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(sections));
- }
- void ExpectBuildWithCustomLinks(
- const std::vector<CustomLinksManager::Link>& expected_links,
- std::map<SectionType, NTPTilesVector>* sections) {
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillOnce(ReturnRef(expected_links));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(sections));
- }
- };
- TEST_P(MostVisitedSitesWithCustomLinksTest, ChangeVisibility) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles when custom links is not initialized. Tiles should be Top
- // Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- EXPECT_TRUE(most_visited_sites_->IsCustomLinksEnabled());
- EXPECT_TRUE(most_visited_sites_->IsShortcutsVisible());
- // Hide shortcuts. Observer should get notified.
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->SetShortcutsVisible(false);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(most_visited_sites_->IsCustomLinksEnabled());
- EXPECT_FALSE(most_visited_sites_->IsShortcutsVisible());
- // Attempt to hide the shortcuts again. This should be ignored.
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0);
- most_visited_sites_->SetShortcutsVisible(false);
- base::RunLoop().RunUntilIdle();
- // Make the shortcuts visible. Observer should get notified.
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->SetShortcutsVisible(true);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(most_visited_sites_->IsCustomLinksEnabled());
- EXPECT_TRUE(most_visited_sites_->IsShortcutsVisible());
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- ShouldOnlyBuildCustomLinksWhenInitialized) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles when custom links is not initialized. Tiles should be Top
- // Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- // Initialize custom links and rebuild tiles. Tiles should be custom links.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- ExpectBuildWithCustomLinks(expected_links, §ions);
- most_visited_sites_->InitializeCustomLinks();
- most_visited_sites_->RefreshTiles();
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::CUSTOM_LINKS)));
- // Uninitialize custom links and rebuild tiles. Tiles should be Top Sites.
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->UninitializeCustomLinks();
- base::RunLoop().RunUntilIdle();
- tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- ShouldFavorCustomLinksOverTopSites) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles when custom links is not initialized. Tiles should be Top
- // Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- // Initialize custom links and rebuild tiles. Tiles should be custom links.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- ExpectBuildWithCustomLinks(expected_links, §ions);
- most_visited_sites_->InitializeCustomLinks();
- most_visited_sites_->RefreshTiles();
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(
- sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::CUSTOM_LINKS)));
- // Initiate notification for new Top Sites. This should be ignored.
- VerifyAndClearExpectations();
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(0);
- top_sites_callbacks_.Notify(
- MostVisitedURLList({MakeMostVisitedURL(u"Site 2", "http://site2/")}));
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- DisableCustomLinksWhenNotInitialized) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle16[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle16}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles when custom links is not initialized. Tiles should be from
- // Top Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)},
- §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle16, kTestUrl, TileSource::TOP_SITES));
- // Disable custom links. Tiles should rebuild.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)}));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->EnableCustomLinks(false);
- base::RunLoop().RunUntilIdle();
- // Try to disable custom links again. This should not rebuild the tiles.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_)).Times(0);
- EXPECT_CALL(*mock_custom_links_, GetLinks()).Times(0);
- most_visited_sites_->EnableCustomLinks(false);
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest, DisableCustomLinksWhenInitialized) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle16[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle16}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles when custom links is initialized and not disabled. Tiles should
- // be custom links.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
- ExpectBuildWithCustomLinks(expected_links, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle16, kTestUrl,
- TileSource::CUSTOM_LINKS)));
- // Disable custom links. Tiles should rebuild and return Top Sites.
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle16, kTestUrl)}));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->EnableCustomLinks(false);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle16, kTestUrl, TileSource::TOP_SITES)));
- // Re-enable custom links. Tiles should rebuild and return custom links.
- ExpectBuildWithCustomLinks(expected_links, §ions);
- most_visited_sites_->EnableCustomLinks(true);
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle16, kTestUrl,
- TileSource::CUSTOM_LINKS)));
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- ShouldGenerateShortTitleForTopSites) {
- std::string kTestUrl1 = "https://www.imdb.com/";
- std::u16string kTestTitle1 = u"IMDb - Movies, TV and Celebrities - IMDb";
- std::string kTestUrl2 = "https://drive.google.com/";
- std::u16string kTestTitle2 =
- u"Google Drive - Cloud Storage & File Backup for Photos, Docs & More";
- std::string kTestUrl3 = "https://amazon.com/";
- std::u16string kTestTitle3 =
- u"Amazon.com: Online Shopping for Electronics, Apparel, Computers, "
- u"Books, "
- u"DVDs & more";
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles from Top Sites. The tiles should have short titles.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle1, kTestUrl1),
- MakeMostVisitedURL(kTestTitle2, kTestUrl2),
- MakeMostVisitedURL(kTestTitle3, kTestUrl3)},
- §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/3);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(3ul));
- ASSERT_THAT(
- tiles[0],
- MatchesTile(/* The short title generated by the heuristic */ u"IMDb",
- kTestUrl1, TileSource::TOP_SITES));
- ASSERT_THAT(
- tiles[1],
- MatchesTile(
- /* The short title generated by the heuristic */ u"Google Drive",
- kTestUrl2, TileSource::TOP_SITES));
- ASSERT_THAT(
- tiles[2],
- MatchesTile(
- /* The short title generated by the heuristic */ u"Amazon.com",
- kTestUrl3, TileSource::TOP_SITES));
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- ShouldNotCrashIfReceiveAnEmptyTitle) {
- std::string kTestUrl1 = "https://site1/";
- std::u16string kTestTitle1 = u""; // Empty title
- std::string kTestUrl2 = "https://site2/";
- std::u16string kTestTitle2 = u" "; // Title only contains spaces
- std::map<SectionType, NTPTilesVector> sections;
- // Build tiles from Top Sites. The tiles should have short titles.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle1, kTestUrl1),
- MakeMostVisitedURL(kTestTitle2, kTestUrl2)},
- §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/2);
- base::RunLoop().RunUntilIdle();
- // Both cases should not crash and generate an empty title tile.
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(2ul));
- ASSERT_THAT(tiles[0], MatchesTile(u"", kTestUrl1, TileSource::TOP_SITES));
- ASSERT_THAT(tiles[1], MatchesTile(u"", kTestUrl2, TileSource::TOP_SITES));
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- UninitializeCustomLinksOnUndoAfterFirstAction) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build initial tiles with Top Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- // Initialize custom links and complete a custom link action.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, AddLink(_, _)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillRepeatedly(ReturnRef(expected_links));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->AddCustomLink(GURL("test.com"), u"test");
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(
- sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::CUSTOM_LINKS)));
- // Undo the action. This should uninitialize custom links.
- EXPECT_CALL(*mock_custom_links_, UndoAction()).Times(0);
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- most_visited_sites_->UndoCustomLinkAction();
- base::RunLoop().RunUntilIdle();
- tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- DontUninitializeCustomLinksOnUndoAfterMultipleActions) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build initial tiles with Top Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- // Initialize custom links and complete a custom link action.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, UpdateLink(_, _, _)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillRepeatedly(ReturnRef(expected_links));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillRepeatedly(SaveArg<0>(§ions));
- most_visited_sites_->UpdateCustomLink(GURL("test.com"), GURL("test.com"),
- u"test");
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(
- sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle, kTestUrl, TileSource::CUSTOM_LINKS)));
- // Complete a second custom link action.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(false));
- EXPECT_CALL(*mock_custom_links_, DeleteLink(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillOnce(ReturnRef(expected_links));
- most_visited_sites_->DeleteCustomLink(GURL("test.com"));
- base::RunLoop().RunUntilIdle();
- // Undo the second action. This should not uninitialize custom links.
- EXPECT_CALL(*mock_custom_links_, UndoAction()).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, Uninitialize()).Times(0);
- EXPECT_CALL(*mock_custom_links_, IsInitialized()).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillOnce(ReturnRef(expected_links));
- most_visited_sites_->UndoCustomLinkAction();
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest,
- UninitializeCustomLinksIfFirstActionFails) {
- const char kTestUrl[] = "http://site1/";
- const char16_t kTestTitle[] = u"Site 1";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl), kTestTitle}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build initial tiles with Top Sites.
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle, kTestUrl)}, §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle, kTestUrl, TileSource::TOP_SITES));
- // Fail to add a custom link. This should not initialize custom links but
- // notify.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, AddLink(_, _)).WillOnce(Return(false));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->AddCustomLink(GURL(kTestUrl), u"test");
- base::RunLoop().RunUntilIdle();
- // Fail to edit a custom link. This should not initialize custom links but
- // notify.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, UpdateLink(_, _, _)).WillOnce(Return(false));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->UpdateCustomLink(GURL("test.com"), GURL("test2.com"),
- u"test");
- base::RunLoop().RunUntilIdle();
- // Fail to reorder a custom link. This should not initialize custom links but
- // notify.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, ReorderLink(_, _)).WillOnce(Return(false));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->ReorderCustomLink(GURL("test.com"), 1);
- base::RunLoop().RunUntilIdle();
- // Fail to delete a custom link. This should not initialize custom links but
- // notify.
- EXPECT_CALL(*mock_custom_links_, Initialize(_)).WillOnce(Return(true));
- EXPECT_CALL(*mock_custom_links_, DeleteLink(_)).WillOnce(Return(false));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_custom_links_, Uninitialize());
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_)).Times(1);
- most_visited_sites_->DeleteCustomLink(GURL("test.com"));
- base::RunLoop().RunUntilIdle();
- }
- TEST_P(MostVisitedSitesWithCustomLinksTest, RebuildTilesOnCustomLinksChanged) {
- const char kTestUrl1[] = "http://site1/";
- const char kTestUrl2[] = "http://site2/";
- const char16_t kTestTitle1[] = u"Site 1";
- const char16_t kTestTitle2[] = u"Site 2";
- std::vector<CustomLinksManager::Link> expected_links(
- {CustomLinksManager::Link{GURL(kTestUrl2), kTestTitle2}});
- std::map<SectionType, NTPTilesVector> sections;
- // Build initial tiles with Top Sites.
- base::RepeatingClosure custom_links_callback;
- EXPECT_CALL(*mock_custom_links_, RegisterCallbackForOnChanged(_))
- .WillOnce(DoAll(SaveArg<0>(&custom_links_callback),
- Return(ByMove(base::CallbackListSubscription()))));
- ExpectBuildWithTopSites(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle1, kTestUrl1)},
- §ions);
- most_visited_sites_->AddMostVisitedURLsObserver(&mock_observer_,
- /*max_num_sites=*/1);
- base::RunLoop().RunUntilIdle();
- NTPTilesVector tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle1, kTestUrl1, TileSource::TOP_SITES));
- // Notify that there is a new set of custom links. This should replace the
- // current tiles with custom links.
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_custom_links_, GetLinks())
- .WillRepeatedly(ReturnRef(expected_links));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- custom_links_callback.Run();
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(sections.at(SectionType::PERSONALIZED),
- ElementsAre(MatchesTile(kTestTitle2, kTestUrl2,
- TileSource::CUSTOM_LINKS)));
- // Notify that custom links have been uninitialized. This should rebuild the
- // tiles with Top Sites.
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_))
- .WillRepeatedly(base::test::RunOnceCallback<0>(
- MostVisitedURLList{MakeMostVisitedURL(kTestTitle1, kTestUrl1)}));
- EXPECT_CALL(*mock_custom_links_, IsInitialized())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_observer_, OnURLsAvailable(_))
- .WillOnce(SaveArg<0>(§ions));
- custom_links_callback.Run();
- base::RunLoop().RunUntilIdle();
- tiles = sections.at(SectionType::PERSONALIZED);
- ASSERT_THAT(tiles.size(), Ge(1ul));
- ASSERT_THAT(tiles[0],
- MatchesTile(kTestTitle1, kTestUrl1, TileSource::TOP_SITES));
- }
- // These exclude Android and iOS.
- INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithCustomLinksTest,
- MostVisitedSitesWithCustomLinksTest,
- ::testing::Bool());
- #endif
- // This a test for MostVisitedSites::MergeTiles(...) method, and thus has the
- // same scope as the method itself. This tests merging popular sites with
- // personal tiles.
- // More important things out of the scope of testing presently:
- // - Removing blocked tiles.
- // - Correct host extraction from the URL.
- // - Ensuring personal tiles are not duplicated in popular tiles.
- TEST(MostVisitedSitesMergeTest, ShouldMergeTilesWithPersonalOnly) {
- std::vector<NTPTile> personal_tiles{
- MakeTile(u"Site 1", "https://www.site1.com/", TileSource::TOP_SITES),
- MakeTile(u"Site 2", "https://www.site2.com/", TileSource::TOP_SITES),
- MakeTile(u"Site 3", "https://www.site3.com/", TileSource::TOP_SITES),
- MakeTile(u"Site 4", "https://www.site4.com/", TileSource::TOP_SITES),
- };
- // Without any popular tiles, the result after merge should be the personal
- // tiles.
- EXPECT_THAT(MostVisitedSites::MergeTiles(std::move(personal_tiles),
- /*popular_tiles=*/NTPTilesVector(),
- /*explore_tile=*/absl::nullopt),
- ElementsAre(MatchesTile(u"Site 1", "https://www.site1.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Site 2", "https://www.site2.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Site 3", "https://www.site3.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Site 4", "https://www.site4.com/",
- TileSource::TOP_SITES)));
- }
- TEST(MostVisitedSitesMergeTest, ShouldMergeTilesWithPopularOnly) {
- std::vector<NTPTile> popular_tiles{
- MakeTile(u"Site 1", "https://www.site1.com/", TileSource::POPULAR),
- MakeTile(u"Site 2", "https://www.site2.com/", TileSource::POPULAR),
- MakeTile(u"Site 3", "https://www.site3.com/", TileSource::POPULAR),
- MakeTile(u"Site 4", "https://www.site4.com/", TileSource::POPULAR),
- };
- // Without any personal tiles, the result after merge should be the popular
- // tiles.
- EXPECT_THAT(
- MostVisitedSites::MergeTiles(/*personal_tiles=*/NTPTilesVector(),
- /*popular_tiles=*/std::move(popular_tiles),
- /*explore_tile=*/absl::nullopt),
- ElementsAre(
- MatchesTile(u"Site 1", "https://www.site1.com/", TileSource::POPULAR),
- MatchesTile(u"Site 2", "https://www.site2.com/", TileSource::POPULAR),
- MatchesTile(u"Site 3", "https://www.site3.com/", TileSource::POPULAR),
- MatchesTile(u"Site 4", "https://www.site4.com/",
- TileSource::POPULAR)));
- }
- TEST(MostVisitedSitesMergeTest, ShouldMergeTilesFavoringPersonalOverPopular) {
- std::vector<NTPTile> popular_tiles{
- MakeTile(u"Site 1", "https://www.site1.com/", TileSource::POPULAR),
- MakeTile(u"Site 2", "https://www.site2.com/", TileSource::POPULAR),
- };
- std::vector<NTPTile> personal_tiles{
- MakeTile(u"Site 3", "https://www.site3.com/", TileSource::TOP_SITES),
- MakeTile(u"Site 4", "https://www.site4.com/", TileSource::TOP_SITES),
- };
- absl::optional<NTPTile> explore_tile{
- MakeTile(u"Explore", "https://explore.example.com/", TileSource::EXPLORE),
- };
- EXPECT_THAT(
- MostVisitedSites::MergeTiles(std::move(personal_tiles),
- /*popular_tiles=*/std::move(popular_tiles),
- /*explore_tiles=*/explore_tile),
- ElementsAre(
- MatchesTile(u"Site 3", "https://www.site3.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Site 4", "https://www.site4.com/",
- TileSource::TOP_SITES),
- MatchesTile(u"Site 1", "https://www.site1.com/", TileSource::POPULAR),
- MatchesTile(u"Site 2", "https://www.site2.com/", TileSource::POPULAR),
- MatchesTile(u"Explore", "https://explore.example.com/",
- TileSource::EXPLORE)));
- }
- } // namespace ntp_tiles
|