[go: nahoru, domu]

blob: 971146234f48701f94afccca81dee451c1065b03 [file] [log] [blame]
// Copyright (c) 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/browsing_data/core/counters/history_counter.h"
#include <memory>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/web_history_service_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/web_history_service.h"
#include "components/history/core/test/fake_web_history_service.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_test.h"
#include "net/http/http_status_code.h"
#include "url/gurl.h"
namespace {
using browsing_data::BrowsingDataCounter;
using browsing_data::HistoryCounter;
class HistoryCounterTest : public InProcessBrowserTest {
public:
HistoryCounterTest() {}
~HistoryCounterTest() override {}
void SetUpOnMainThread() override {
time_ = base::Time::Now();
history_service_ = HistoryServiceFactory::GetForProfileWithoutCreating(
browser()->profile());
fake_web_history_service_ =
std::make_unique<history::FakeWebHistoryService>();
SetHistoryDeletionPref(true);
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
}
void AddVisit(const std::string url) {
history_service_->AddPage(GURL(url), time_, history::SOURCE_BROWSED);
}
const base::Time& GetCurrentTime() {
return time_;
}
void SetTime(base::Time time) { time_ = time; }
void RevertTimeInDays(int days) { time_ -= base::Days(days); }
void SetHistoryDeletionPref(bool value) {
browser()->profile()->GetPrefs()->SetBoolean(
browsing_data::prefs::kDeleteBrowsingHistory, value);
}
void SetDeletionPeriodPref(browsing_data::TimePeriod period) {
browser()->profile()->GetPrefs()->SetInteger(
browsing_data::prefs::kDeleteTimePeriod, static_cast<int>(period));
}
void WaitForCounting() {
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
BrowsingDataCounter::ResultInt GetLocalResult() {
DCHECK(finished_);
return local_result_;
}
bool HasSyncedVisits() {
DCHECK(finished_);
return has_synced_visits_;
}
void Callback(std::unique_ptr<BrowsingDataCounter::Result> result) {
finished_ = result->Finished();
if (finished_) {
auto* history_result =
static_cast<HistoryCounter::HistoryResult*>(result.get());
local_result_ = history_result->Value();
has_synced_visits_ = history_result->has_synced_visits();
}
if (run_loop_ && finished_)
run_loop_->Quit();
}
history::WebHistoryService* GetFakeWebHistoryService(Profile* profile,
bool check_sync_status) {
// |check_sync_status| is true when the factory should check if
// history sync is enabled.
if (!check_sync_status ||
WebHistoryServiceFactory::GetForProfile(profile)) {
return fake_web_history_service_.get();
}
return nullptr;
}
history::WebHistoryService* GetRealWebHistoryService(Profile* profile) {
return WebHistoryServiceFactory::GetForProfile(profile);
}
history::HistoryService* GetHistoryService() { return history_service_; }
private:
std::unique_ptr<base::RunLoop> run_loop_;
raw_ptr<history::HistoryService> history_service_;
std::unique_ptr<history::FakeWebHistoryService> fake_web_history_service_;
base::Time time_;
bool finished_;
BrowsingDataCounter::ResultInt local_result_;
bool has_synced_visits_;
};
// Tests that the counter considers duplicate visits from the same day
// to be a single item.
IN_PROC_BROWSER_TEST_F(HistoryCounterTest, DuplicateVisits) {
// Start at a fixed day to avoid flakiness due to timezone changes.
base::Time time;
ASSERT_TRUE(base::Time::FromUTCString("1 Jul 2020 10:00 GMT", &time));
SetTime(time);
AddVisit("https://www.google.com"); // 1 item
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com"); // 2 items
AddVisit("https://www.chrome.com");
AddVisit("https://www.chrome.com");
AddVisit("https://www.example.com"); // 3 items
RevertTimeInDays(1);
AddVisit("https://www.google.com"); // 4 items
AddVisit("https://www.example.com"); // 5 items
AddVisit("https://www.example.com");
RevertTimeInDays(1);
AddVisit("https://www.chrome.com"); // 6 items
AddVisit("https://www.chrome.com");
AddVisit("https://www.google.com"); // 7 items
AddVisit("https://www.chrome.com");
AddVisit("https://www.google.com");
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com");
Profile* profile = browser()->profile();
HistoryCounter counter(
GetHistoryService(),
base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
base::Unretained(this), base::Unretained(profile)),
SyncServiceFactory::GetForProfile(profile));
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::BindRepeating(&HistoryCounterTest::Callback,
base::Unretained(this)));
counter.Restart();
WaitForCounting();
EXPECT_EQ(7u, GetLocalResult());
}
// Tests that the counter works without |web_history_service_callback| and
// |sync_service|.
IN_PROC_BROWSER_TEST_F(HistoryCounterTest, WithoutSyncService) {
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com");
Profile* profile = browser()->profile();
browsing_data::HistoryCounter counter(
GetHistoryService(),
browsing_data::HistoryCounter::GetUpdatedWebHistoryServiceCallback(),
nullptr /* sync_service */);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::BindRepeating(&HistoryCounterTest::Callback,
base::Unretained(this)));
counter.Restart();
WaitForCounting();
EXPECT_EQ(2u, GetLocalResult());
}
// Tests that the counter starts counting automatically when the deletion
// pref changes to true.
IN_PROC_BROWSER_TEST_F(HistoryCounterTest, PrefChanged) {
SetHistoryDeletionPref(false);
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com");
Profile* profile = browser()->profile();
HistoryCounter counter(
GetHistoryService(),
base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
base::Unretained(this), base::Unretained(profile)),
SyncServiceFactory::GetForProfile(profile));
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::BindRepeating(&HistoryCounterTest::Callback,
base::Unretained(this)));
SetHistoryDeletionPref(true);
WaitForCounting();
EXPECT_EQ(2u, GetLocalResult());
}
// Tests that changing the deletion period restarts the counting, and that
// the result takes visit dates into account.
IN_PROC_BROWSER_TEST_F(HistoryCounterTest, PeriodChanged) {
AddVisit("https://www.google.com");
RevertTimeInDays(2);
AddVisit("https://www.google.com");
AddVisit("https://www.example.com");
RevertTimeInDays(4);
AddVisit("https://www.chrome.com");
AddVisit("https://www.chrome.com");
AddVisit("https://www.example.com");
RevertTimeInDays(20);
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com");
AddVisit("https://www.example.com");
RevertTimeInDays(10);
AddVisit("https://www.example.com");
AddVisit("https://www.example.com");
AddVisit("https://www.example.com");
RevertTimeInDays(100);
AddVisit("https://www.google.com");
AddVisit("https://www.example.com");
AddVisit("https://www.example.com");
Profile* profile = browser()->profile();
HistoryCounter counter(
GetHistoryService(),
base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
base::Unretained(this), base::Unretained(profile)),
SyncServiceFactory::GetForProfile(profile));
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::BindRepeating(&HistoryCounterTest::Callback,
base::Unretained(this)));
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
WaitForCounting();
EXPECT_EQ(1u, GetLocalResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_DAY);
WaitForCounting();
EXPECT_EQ(1u, GetLocalResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_WEEK);
WaitForCounting();
EXPECT_EQ(5u, GetLocalResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::FOUR_WEEKS);
WaitForCounting();
EXPECT_EQ(8u, GetLocalResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
WaitForCounting();
EXPECT_EQ(11u, GetLocalResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::OLDER_THAN_30_DAYS);
WaitForCounting();
EXPECT_EQ(3u, GetLocalResult());
}
// Test the behavior for a profile that syncs history.
IN_PROC_BROWSER_TEST_F(HistoryCounterTest, Synced) {
// WebHistoryService makes network requests, so we need to use a fake one
// for testing.
Profile* profile = browser()->profile();
HistoryCounter counter(
GetHistoryService(),
base::BindRepeating(&HistoryCounterTest::GetFakeWebHistoryService,
base::Unretained(this), base::Unretained(profile),
false),
SyncServiceFactory::GetForProfile(profile));
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::BindRepeating(&HistoryCounterTest::Callback,
base::Unretained(this)));
history::FakeWebHistoryService* service =
static_cast<history::FakeWebHistoryService*>(GetFakeWebHistoryService(
profile, false));
// No entries locally and no entries in Sync.
service->SetupFakeResponse(true /* success */, net::HTTP_OK);
counter.Restart();
WaitForCounting();
EXPECT_EQ(0u, GetLocalResult());
EXPECT_FALSE(HasSyncedVisits());
// No entries locally. There are some entries in Sync, but they are out of the
// time range.
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
service->AddSyncedVisit("www.google.com", GetCurrentTime() - base::Hours(2));
service->AddSyncedVisit("www.chrome.com", GetCurrentTime() - base::Hours(2));
service->SetupFakeResponse(true /* success */, net::HTTP_OK);
counter.Restart();
WaitForCounting();
EXPECT_EQ(0u, GetLocalResult());
EXPECT_FALSE(HasSyncedVisits());
// No entries locally, but some entries in Sync.
service->AddSyncedVisit("www.google.com", GetCurrentTime());
service->SetupFakeResponse(true /* success */, net::HTTP_OK);
counter.Restart();
WaitForCounting();
EXPECT_EQ(0u, GetLocalResult());
EXPECT_TRUE(HasSyncedVisits());
// To err on the safe side, if the server request fails, we assume that there
// might be some items on the server.
service->SetupFakeResponse(true /* success */,
net::HTTP_INTERNAL_SERVER_ERROR);
counter.Restart();
WaitForCounting();
EXPECT_EQ(0u, GetLocalResult());
EXPECT_TRUE(HasSyncedVisits());
// Same when the entire query fails.
service->SetupFakeResponse(false /* success */,
net::HTTP_INTERNAL_SERVER_ERROR);
counter.Restart();
WaitForCounting();
EXPECT_EQ(0u, GetLocalResult());
EXPECT_TRUE(HasSyncedVisits());
// Nonzero local count, nonempty sync.
AddVisit("https://www.google.com");
AddVisit("https://www.chrome.com");
service->SetupFakeResponse(true /* success */, net::HTTP_OK);
counter.Restart();
WaitForCounting();
EXPECT_EQ(2u, GetLocalResult());
EXPECT_TRUE(HasSyncedVisits());
// Nonzero local count, empty sync.
service->ClearSyncedVisits();
service->SetupFakeResponse(true /* success */, net::HTTP_OK);
counter.Restart();
WaitForCounting();
EXPECT_EQ(2u, GetLocalResult());
EXPECT_FALSE(HasSyncedVisits());
}
} // namespace