#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/history/core/browser/history_backend.h"
#include <stddef.h>
#include <iterator>
#include <limits>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/favicon/core/favicon_backend.h"
#include "components/favicon_base/favicon_usage_data.h"
#include "components/history/core/browser/features.h"
#include "components/history/core/browser/history_backend_client.h"
#include "components/history/core/browser/history_constants.h"
#include "components/history/core/browser/history_database_params.h"
#include "components/history/core/browser/history_db_task.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/history/core/browser/history_types.h"
#include "components/history/core/browser/in_memory_database.h"
#include "components/history/core/browser/in_memory_history_backend.h"
#include "components/history/core/browser/keyword_search_term.h"
#include "components/history/core/browser/keyword_search_term_util.h"
#include "components/history/core/browser/page_usage_data.h"
#include "components/history/core/test/database_test_utils.h"
#include "components/history/core/test/history_client_fake_bookmarks.h"
#include "components/history/core/test/test_history_database.h"
#include "components/history/core/test/visit_annotations_test_utils.h"
#include "components/sync/base/features.h"
#include "sql/sqlite_result_code_values.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "url/gurl.h"
namespace history {
namespace {
FaviconBitmap;
FaviconBitmapType;
IconMapping;
IconType;
IconTypeSet;
ElementsAre;
UnorderedElementsAre;
UnorderedElementsAreArray;
const int kSmallEdgeSize = …;
const int kLargeEdgeSize = …;
const gfx::Size kSmallSize = …;
const gfx::Size kLargeSize = …;
MATCHER_P(HasVisitID, visit_id, "") { … }
struct ClusterExpectation { … };
SimulateNotificationCallback;
void SimulateNotificationURLVisited(HistoryServiceObserver* observer,
const URLRow* row1,
const URLRow* row2,
const URLRow* row3) { … }
void SimulateNotificationURLsModified(HistoryServiceObserver* observer,
const URLRow* row1,
const URLRow* row2,
const URLRow* row3) { … }
VisitContextAnnotations MakeContextAnnotations(bool omnibox_url_copied) { … }
#if BUILDFLAG(IS_IOS)
SyncDeviceInfoMap MakeSyncDeviceInfo(
const std::vector<std::string>& android_phone_originator_cache_guids,
const std::vector<std::string>& ios_phone_originator_cache_guids,
const std::string& local_ios_phone_originator_cache_guid = "") {
SyncDeviceInfoMap sync_device_info;
for (const auto& android_phone_originator_cache_guid :
android_phone_originator_cache_guids) {
sync_device_info[android_phone_originator_cache_guid] =
std::make_pair(syncer::DeviceInfo::OsType::kAndroid,
syncer::DeviceInfo::FormFactor::kPhone);
}
for (const auto& ios_phone_originator_cache_guid :
ios_phone_originator_cache_guids) {
sync_device_info[ios_phone_originator_cache_guid] =
std::make_pair(syncer::DeviceInfo::OsType::kIOS,
syncer::DeviceInfo::FormFactor::kPhone);
}
if (!local_ios_phone_originator_cache_guid.empty()) {
sync_device_info[local_ios_phone_originator_cache_guid] =
std::make_pair(syncer::DeviceInfo::OsType::kIOS,
syncer::DeviceInfo::FormFactor::kPhone);
}
return sync_device_info;
}
#endif
}
class HistoryBackendTestBase;
class HistoryBackendTestDelegate : public HistoryBackend::Delegate { … };
class TestHistoryBackend : public HistoryBackend { … };
class HistoryBackendTestBase : public testing::Test { … };
bool HistoryBackendTestDelegate::CanAddURL(const GURL& url) const { … }
void HistoryBackendTestDelegate::SetInMemoryBackend(
std::unique_ptr<InMemoryHistoryBackend> backend) { … }
void HistoryBackendTestDelegate::NotifyFaviconsChanged(
const std::set<GURL>& page_urls,
const GURL& icon_url) { … }
void HistoryBackendTestDelegate::NotifyURLVisited(
const URLRow& url_row,
const VisitRow& new_visit,
std::optional<int64_t> local_navigation_id) { … }
void HistoryBackendTestDelegate::NotifyURLsModified(
const URLRows& changed_urls) { … }
void HistoryBackendTestDelegate::NotifyDeletions(DeletionInfo deletion_info) { … }
void HistoryBackendTestDelegate::NotifyVisitedLinksAdded(
const HistoryAddPageArgs& args) { … }
void HistoryBackendTestDelegate::NotifyVisitedLinksDeleted(
const std::vector<DeletedVisitedLink>& links) { … }
void HistoryBackendTestDelegate::NotifyKeywordSearchTermUpdated(
const URLRow& row,
KeywordID keyword_id,
const std::u16string& term) { … }
void HistoryBackendTestDelegate::NotifyKeywordSearchTermDeleted(URLID url_id) { … }
void HistoryBackendTestDelegate::DBLoaded() { … }
class HistoryBackendTest : public HistoryBackendTestBase { … };
class InMemoryHistoryBackendTest : public HistoryBackendTestBase { … };
const KeywordID InMemoryHistoryBackendTest::kTestKeywordId = …;
const char16_t InMemoryHistoryBackendTest::kTestSearchTerm1[] = …;
const char16_t InMemoryHistoryBackendTest::kTestSearchTerm2[] = …;
#if BUILDFLAG(IS_WIN)
#define MAYBE_Loaded …
#else
#define MAYBE_Loaded …
#endif
TEST_F(HistoryBackendTest, MAYBE_Loaded) { … }
TEST_F(HistoryBackendTest, DeleteAll) { … }
TEST_F(HistoryBackendTest, DeleteAllURLPreviouslyDeleted) { … }
TEST_F(HistoryBackendTest, DeleteAllThenAddData) { … }
TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) { … }
TEST_F(HistoryBackendTest, KeywordGenerated) { … }
TEST_F(HistoryBackendTest, OpenerWithRedirect) { … }
TEST_F(HistoryBackendTest, ClientRedirect) { … }
TEST_F(HistoryBackendTest, FormSubmitRedirect) { … }
TEST_F(HistoryBackendTest, AddPagesWithDetails) { … }
TEST_F(HistoryBackendTest, SetPageTitleFiresNotificationWithCorrectDetails) { … }
#if !BUILDFLAG(IS_ANDROID)
TEST_F(HistoryBackendTest, ImportedFaviconsTest) { … }
#endif
TEST_F(HistoryBackendTest, StripUsernamePasswordTest) { … }
TEST_F(HistoryBackendTest, AddPageVisitBackForward) { … }
TEST_F(HistoryBackendTest, AddPageVisitRedirectBackForward) { … }
TEST_F(HistoryBackendTest, AddPageVisitSource) { … }
TEST_F(HistoryBackendTest, AddPageVisitNotLastVisit) { … }
TEST_F(HistoryBackendTest, AddPageVisitFiresNotificationWithCorrectDetails) { … }
TEST_F(HistoryBackendTest, AddPageArgsSource) { … }
TEST_F(HistoryBackendTest, AddPageArgsConsiderForNewTabPageMostVisited) { … }
TEST_F(HistoryBackendTest, AddContentModelAnnotationsWithNoEntryInVisitTable) { … }
TEST_F(HistoryBackendTest, AddRelatedSearchesWithNoEntryInVisitTable) { … }
TEST_F(HistoryBackendTest, AddSearchMetadataWithNoEntryInVisitTable) { … }
TEST_F(HistoryBackendTest, SetBrowsingTopicsAllowed) { … }
TEST_F(HistoryBackendTest, AddContentModelAnnotations) { … }
TEST_F(HistoryBackendTest, AddRelatedSearches) { … }
TEST_F(HistoryBackendTest, AddSearchMetadata) { … }
TEST_F(HistoryBackendTest, AddPageMetadata) { … }
TEST_F(HistoryBackendTest, SetHasUrlKeyedImage) { … }
TEST_F(HistoryBackendTest, MixedContentAnnotationsRequestTypes) { … }
TEST_F(HistoryBackendTest, GetMostRecentVisits) { … }
TEST_F(HistoryBackendTest, RemoveVisitsTransitions) { … }
TEST_F(HistoryBackendTest, RemoveVisitsSource) { … }
TEST_F(HistoryBackendTest, MigrationVisitSource) { … }
TEST_F(HistoryBackendTest, RecentRedirectsForClientRedirects) { … }
TEST_F(HistoryBackendTest, FaviconChangedNotificationNewFavicon) { … }
TEST_F(HistoryBackendTest, FaviconChangedNotificationBitmapDataChanged) { … }
TEST_F(HistoryBackendTest, FaviconChangedNotificationIconMappingChanged) { … }
TEST_F(HistoryBackendTest,
FaviconChangedNotificationIconMappingChangedForMultiplePages) { … }
TEST_F(HistoryBackendTest,
FaviconChangedNotificationIconMappingAndBitmapDataChanged) { … }
TEST_F(HistoryBackendTest, FaviconChangedNotificationsMergeCopy) { … }
TEST_F(HistoryBackendTest, NoFaviconChangedNotifications) { … }
TEST_F(HistoryBackendTest, CloneFaviconMappingsForPages) { … }
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoDB) { … }
TEST_F(HistoryBackendTest, GetCountsAndLastVisitForOrigins) { … }
TEST_F(HistoryBackendTest, UpdateVisitDuration) { … }
TEST_F(HistoryBackendTest, MarkVisitAsKnownToSync) { … }
TEST_F(HistoryBackendTest, MigrationVisitDuration) { … }
TEST_F(HistoryBackendTest, AddPageNoVisitForBookmark) { … }
TEST_F(HistoryBackendTest, ExpireHistoryForTimes) { … }
TEST_F(HistoryBackendTest, ExpireHistory) { … }
TEST_F(HistoryBackendTest, DeleteMatchingUrlsForKeyword) { … }
TEST_F(HistoryBackendTest, DeleteFTSIndexDatabases) { … }
TEST_F(HistoryBackendTest, DatabaseError) { … }
TEST_F(HistoryBackendTest, DatabaseErrorSynchronouslyKillAndNotifyBridge) { … }
TEST_F(HistoryBackendTest, RedirectScoring) { … }
TEST_F(HistoryBackendTest, RedirectWithQualifiers) { … }
TEST_F(HistoryBackendTest, ClientRedirectScoring) { … }
void InMemoryHistoryBackendTest::TestAddingAndChangingURLRows(
const SimulateNotificationCallback& callback) { … }
TEST_F(InMemoryHistoryBackendTest, OnURLsModified) { … }
TEST_F(InMemoryHistoryBackendTest, OnURLsVisisted) { … }
TEST_F(InMemoryHistoryBackendTest, OnURLsDeletedPiecewise) { … }
TEST_F(InMemoryHistoryBackendTest, OnURLsDeletedEnMasse) { … }
void InMemoryHistoryBackendTest::PopulateTestURLsAndSearchTerms(
URLRow* row1,
URLRow* row2,
const std::u16string& term1,
const std::u16string& term2) { … }
TEST_F(InMemoryHistoryBackendTest, SetKeywordSearchTerms) { … }
TEST_F(InMemoryHistoryBackendTest, DeleteKeywordSearchTerms) { … }
TEST_F(InMemoryHistoryBackendTest, DeleteAllSearchTermsForKeyword) { … }
TEST_F(InMemoryHistoryBackendTest, OnURLsDeletedWithSearchTerms) { … }
TEST_F(HistoryBackendTest, QueryMostVisitedURLs) { … }
TEST_F(HistoryBackendTest, ExpireSegmentData) { … }
TEST_F(HistoryBackendTest, QueryMostRepeatedQueriesForKeyword) { … }
TEST(FormatUrlForRedirectComparisonTest, TestUrlFormatting) { … }
TEST_F(HistoryBackendTest, ExpireVisitDeletes) { … }
TEST_F(HistoryBackendTest, AddPageWithContextAnnotations) { … }
TEST_F(HistoryBackendTest, GetAnnotatedVisits) { … }
TEST_F(HistoryBackendTest, GetAnnotatedVisits_Unclustered) { … }
TEST_F(HistoryBackendTest, PreservesAllContextAnnotationsFields) { … }
TEST_F(HistoryBackendTest, FindMostRecentClusteredTime) { … }
TEST_F(HistoryBackendTest, ReplaceClusters) { … }
TEST_F(HistoryBackendTest, GetMostRecentClusters) { … }
TEST_F(HistoryBackendTest, AddClusters_GetCluster) { … }
TEST_F(HistoryBackendTest, AddClusters_UpdateVisitsInteractionState) { … }
TEST_F(HistoryBackendTest, ReserveNextClusterIdWithVisit_GetCluster) { … }
TEST_F(
HistoryBackendTest,
ReserveNextClusterId_AddVisitsToCluster_GetCluster_GetClusterIdContainingVisit) { … }
TEST_F(
HistoryBackendTest,
ReserveNextClusterId_AddVisitsToCluster_UpdateClusterTriggerability_GetCluster) { … }
TEST_F(HistoryBackendTest,
AddVisitToSyncedCluster_GetCluster_UpdateClusterVisit) { … }
TEST_F(HistoryBackendTest, UpdateClusterVisit_NoClusterAssigned) { … }
TEST_F(HistoryBackendTest, GetRedirectChainStart) { … }
TEST_F(HistoryBackendTest, GetRedirectChain) { … }
TEST_F(HistoryBackendTest, AddSyncedVisitAddsOnlyValidURLs) { … }
TEST_F(HistoryBackendTest, AddSyncedVisitWritesIsKnownToSync) { … }
#if BUILDFLAG(IS_IOS)
TEST_F(HistoryBackendTest,
UpdateVisitReferrerOpenerIDs_DoesNotDoubleCountVisitInSegments) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info =
MakeSyncDeviceInfo({"foreign"}, {}, "local");
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local");
VisitRow foreign_visit_1;
foreign_visit_1.visit_time = base::Time::Now();
foreign_visit_1.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit_1.originator_cache_guid = "foreign";
foreign_visit_1.is_known_to_sync = true;
foreign_visit_1.consider_for_ntp_most_visited = true;
VisitID foreign_visit_1_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit_1,
std::nullopt, std::nullopt);
const ui::PageTransition kLink = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
VisitRow foreign_visit_2;
foreign_visit_2.visit_time = base::Time::Now();
foreign_visit_2.referring_visit = foreign_visit_1_id;
foreign_visit_2.transition = kLink;
foreign_visit_2.originator_cache_guid = "foreign";
foreign_visit_2.is_known_to_sync = true;
foreign_visit_2.consider_for_ntp_most_visited = true;
backend_->AddSyncedVisit(GURL("https://foobar.url"), u"Foobar",
false, foreign_visit_2, std::nullopt,
std::nullopt);
VisitVector all_visits;
backend_->db_->GetAllVisitsInRange(base::Time(), base::Time(), kNoAppIdFilter,
0, &all_visits);
ASSERT_EQ(2U, all_visits.size());
EXPECT_TRUE(HasSegmentWithID(all_visits[0].segment_id));
EXPECT_TRUE(HasSegmentWithID(all_visits[1].segment_id));
EXPECT_EQ(all_visits[0].segment_id, all_visits[1].segment_id);
EXPECT_EQ(TotalNumVisitsForSegment(all_visits[0].segment_id), 2);
backend_->UpdateVisitReferrerOpenerIDs(all_visits[1].visit_id, 0, 0);
VisitVector updated_visits;
backend_->db_->GetAllVisitsInRange(base::Time(), base::Time(), kNoAppIdFilter,
0, &updated_visits);
EXPECT_NE(updated_visits[0].segment_id, updated_visits[1].segment_id);
EXPECT_EQ(updated_visits[1].segment_id, 0);
EXPECT_EQ(TotalNumVisitsForSegment(updated_visits[0].segment_id), 1);
EXPECT_EQ(TotalNumVisitsForSegment(updated_visits[1].segment_id), 0);
}
TEST_F(HistoryBackendTest,
UpdateSyncedVisit_DoesNotDoubleCountVisitInSegments) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info =
MakeSyncDeviceInfo({"foreign"}, {}, "local");
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local");
VisitRow foreign_visit_1;
foreign_visit_1.visit_time = base::Time::Now();
foreign_visit_1.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit_1.originator_cache_guid = "foreign";
foreign_visit_1.is_known_to_sync = true;
foreign_visit_1.consider_for_ntp_most_visited = true;
VisitID foreign_visit_1_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit_1,
std::nullopt, std::nullopt);
const ui::PageTransition kLink = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
VisitRow foreign_visit_2;
foreign_visit_2.visit_time = base::Time::Now();
foreign_visit_2.referring_visit = foreign_visit_1_id;
foreign_visit_2.transition = kLink;
foreign_visit_2.originator_cache_guid = "foreign";
foreign_visit_2.is_known_to_sync = true;
foreign_visit_2.consider_for_ntp_most_visited = true;
backend_->AddSyncedVisit(GURL("https://foobar.url"), u"Foobar",
false, foreign_visit_2, std::nullopt,
std::nullopt);
VisitVector all_visits;
backend_->db_->GetAllVisitsInRange(base::Time(), base::Time(), kNoAppIdFilter,
0, &all_visits);
ASSERT_EQ(2U, all_visits.size());
EXPECT_TRUE(HasSegmentWithID(all_visits[0].segment_id));
EXPECT_TRUE(HasSegmentWithID(all_visits[1].segment_id));
EXPECT_EQ(all_visits[0].segment_id, all_visits[1].segment_id);
EXPECT_EQ(TotalNumVisitsForSegment(all_visits[0].segment_id), 2);
foreign_visit_2.transition = ui::PAGE_TRANSITION_TYPED;
backend_->UpdateSyncedVisit(GURL("https://foobar.url"), u"Foobar",
false, foreign_visit_2, std::nullopt,
std::nullopt);
VisitVector updated_visits;
backend_->db_->GetAllVisitsInRange(base::Time(), base::Time(), kNoAppIdFilter,
0, &updated_visits);
EXPECT_NE(updated_visits[0].segment_id, updated_visits[1].segment_id);
EXPECT_EQ(TotalNumVisitsForSegment(updated_visits[0].segment_id), 1);
EXPECT_EQ(TotalNumVisitsForSegment(updated_visits[1].segment_id), 1);
}
TEST_F(HistoryBackendTest,
AddSyncedVisit_AddsVisitWithValidOriginatorCacheGuidToSegments) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info =
MakeSyncDeviceInfo({"foreign"}, {}, "local");
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local");
VisitRow foreign_visit;
foreign_visit.visit_time = base::Time::Now();
foreign_visit.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit.originator_cache_guid = "foreign";
foreign_visit.is_known_to_sync = true;
foreign_visit.consider_for_ntp_most_visited = true;
VisitID added_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit,
std::nullopt, std::nullopt);
ASSERT_NE(added_id, kInvalidVisitID);
VisitRow added_visit;
ASSERT_TRUE(backend_->GetVisitByID(added_id, &added_visit));
EXPECT_TRUE(added_visit.consider_for_ntp_most_visited);
EXPECT_NE(added_visit.segment_id, 0);
}
TEST_F(
HistoryBackendTest,
AddSyncedVisit_DoesNotAddVisitToSegmentsWithMissingForeignDeviceInformation) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info = MakeSyncDeviceInfo({}, {}, "local");
sync_device_info["foreign-invalid"] =
std::make_pair(syncer::DeviceInfo::OsType::kAndroid,
syncer::DeviceInfo::FormFactor::kTablet);
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local");
VisitRow foreign_visit;
foreign_visit.visit_time = base::Time::Now();
foreign_visit.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit.originator_cache_guid = "foreign-invalid";
foreign_visit.is_known_to_sync = true;
foreign_visit.consider_for_ntp_most_visited = true;
VisitID added_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit,
std::nullopt, std::nullopt);
ASSERT_NE(added_id, kInvalidVisitID);
VisitRow added_visit;
ASSERT_TRUE(backend_->GetVisitByID(added_id, &added_visit));
EXPECT_TRUE(added_visit.consider_for_ntp_most_visited);
EXPECT_EQ(added_visit.segment_id, 0);
}
TEST_F(
HistoryBackendTest,
AddSyncedVisit_DoesNotAddVisitToSegmentsWithInvalidLocalDeviceInformation) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info = MakeSyncDeviceInfo({"foreign"}, {});
sync_device_info["local-invalid"] =
std::make_pair(syncer::DeviceInfo::OsType::kIOS,
syncer::DeviceInfo::FormFactor::kTablet);
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local-invalid");
VisitRow foreign_visit;
foreign_visit.visit_time = base::Time::Now();
foreign_visit.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit.originator_cache_guid = "foreign";
foreign_visit.is_known_to_sync = true;
foreign_visit.consider_for_ntp_most_visited = true;
VisitID added_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit,
std::nullopt, std::nullopt);
ASSERT_NE(added_id, kInvalidVisitID);
VisitRow added_visit;
ASSERT_TRUE(backend_->GetVisitByID(added_id, &added_visit));
EXPECT_TRUE(added_visit.consider_for_ntp_most_visited);
EXPECT_EQ(added_visit.segment_id, 0);
}
TEST_F(HistoryBackendTest,
AddSyncedVisit_DoesNotAddVisitToSegmentsWithInvalidDeviceInformation) {
backend_->SetCanAddForeignVisitsToSegments(true);
SyncDeviceInfoMap sync_device_info = MakeSyncDeviceInfo({}, {});
sync_device_info["foreign-invalid"] =
std::make_pair(syncer::DeviceInfo::OsType::kAndroid,
syncer::DeviceInfo::FormFactor::kTablet);
sync_device_info["local-invalid"] =
std::make_pair(syncer::DeviceInfo::OsType::kIOS,
syncer::DeviceInfo::FormFactor::kTablet);
backend_->SetSyncDeviceInfo(std::move(sync_device_info));
backend_->SetLocalDeviceOriginatorCacheGuid("local-invalid");
VisitRow foreign_visit;
foreign_visit.visit_time = base::Time::Now();
foreign_visit.transition = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_CHAIN_START |
ui::PAGE_TRANSITION_CHAIN_END);
foreign_visit.originator_cache_guid = "foreign-invalid";
foreign_visit.is_known_to_sync = true;
foreign_visit.consider_for_ntp_most_visited = true;
VisitID added_id = backend_->AddSyncedVisit(
GURL("https://some.url"), u"Title", false, foreign_visit,
std::nullopt, std::nullopt);
ASSERT_NE(added_id, kInvalidVisitID);
VisitRow added_visit;
ASSERT_TRUE(backend_->GetVisitByID(added_id, &added_visit));
EXPECT_TRUE(added_visit.consider_for_ntp_most_visited);
EXPECT_EQ(added_visit.segment_id, 0);
}
#endif
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsDoesNotDeleteLocalVisits) { … }
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsWorksInBatches) { … }
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsPendingAtShutdown) { … }
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsDoesNotDeleteFutureVisits) { … }
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsAlsoDeletesChains) { … }
TEST_F(HistoryBackendTest, DeleteAllForeignVisitsResetsIsKnownToSyncFlag) { … }
TEST_F(HistoryBackendTest, InternalAndExternalReferrer) { … }
TEST_F(HistoryBackendTest, QueryURLs) { … }
TEST_F(HistoryBackendTest, GetMostRecentVisitForEachURL) { … }
enum TestMode { … };
class HistoryBackendTestForVisitedLinks
: public HistoryBackendTest,
public ::testing::WithParamInterface<TestMode> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(HistoryBackendTestForVisitedLinks, AddPageAndSyncedVisit) { … }
TEST_P(HistoryBackendTestForVisitedLinks, IncreaseVisitCount) { … }
TEST_P(HistoryBackendTestForVisitedLinks, OnlyAddValidVisitedLinks) { … }
TEST_P(HistoryBackendTestForVisitedLinks, AddWholeRedirectChain) { … }
TEST_P(HistoryBackendTestForVisitedLinks, DecreaseVisitCount) { … }
TEST_P(HistoryBackendTestForVisitedLinks, DeleteAllVisitedLinksHistory) { … }
TEST_P(HistoryBackendTestForVisitedLinks, NotifyVisitedLinksAdded) { … }
class RepeatingDBTask : public HistoryDBTask { … };
TEST_F(HistoryBackendTest, ProcessDBTaskWithMultipleIterations) { … }
}