blob: 505d3fc16688d858861955e09aa864ca684cfef7 [file] [log] [blame]
// Copyright 2020 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.
#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_TEST_UTILS_H_
#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_TEST_UTILS_H_
#include <stdint.h>
#include <iosfwd>
#include <vector>
#include "base/compiler_specific.h"
#include "base/guid.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/observer_list.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "content/browser/attribution_reporting/attribution_manager.h"
#include "content/browser/attribution_reporting/attribution_manager_impl.h"
#include "content/browser/attribution_reporting/attribution_policy.h"
#include "content/browser/attribution_reporting/attribution_report.h"
#include "content/browser/attribution_reporting/attribution_storage.h"
#include "content/browser/attribution_reporting/rate_limit_table.h"
#include "content/browser/attribution_reporting/sent_report_info.h"
#include "content/browser/attribution_reporting/storable_source.h"
#include "content/browser/attribution_reporting/storable_trigger.h"
#include "content/test/test_content_browser_client.h"
#include "net/base/schemeful_site.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"
namespace content {
class StorableTrigger;
class MockAttributionReportingContentBrowserClient
: public TestContentBrowserClient {
public:
MockAttributionReportingContentBrowserClient();
~MockAttributionReportingContentBrowserClient() override;
// ContentBrowserClient:
MOCK_METHOD(bool,
IsConversionMeasurementOperationAllowed,
(content::BrowserContext * browser_context,
ConversionMeasurementOperation operation,
const url::Origin* impression_origin,
const url::Origin* conversion_origin,
const url::Origin* reporting_origin),
(override));
};
base::GUID DefaultExternalReportID();
class ConfigurableStorageDelegate : public AttributionStorage::Delegate {
public:
ConfigurableStorageDelegate();
~ConfigurableStorageDelegate() override;
// AttributionStorage::Delegate
base::Time GetReportTime(const StorableSource& source,
base::Time trigger_time) const override;
int GetMaxAttributionsPerSource(
StorableSource::SourceType source_type) const override;
int GetMaxSourcesPerOrigin() const override;
int GetMaxAttributionsPerOrigin() const override;
RateLimitConfig GetRateLimits(
AttributionStorage::AttributionType attribution_type) const override;
int GetMaxAttributionDestinationsPerEventSource() const override;
uint64_t GetFakeEventSourceTriggerData() const override;
base::TimeDelta GetDeleteExpiredSourcesFrequency() const override;
base::TimeDelta GetDeleteExpiredRateLimitsFrequency() const override;
base::GUID NewReportID() const override;
void set_max_attributions_per_source(int max) {
max_attributions_per_source_ = max;
}
void set_max_sources_per_origin(int max) { max_sources_per_origin_ = max; }
void set_max_attributions_per_origin(int max) {
max_attributions_per_origin_ = max;
}
void set_max_attribution_destinations_per_event_source(int max) {
max_attribution_destinations_per_event_source_ = max;
}
void set_rate_limits(RateLimitConfig c) { rate_limits_ = c; }
void set_fake_event_source_trigger_data(uint64_t data) {
fake_event_source_trigger_data_ = data;
}
void set_delete_expired_sources_frequency(base::TimeDelta frequency) {
delete_expired_sources_frequency_ = frequency;
}
void set_delete_expired_rate_limits_frequency(base::TimeDelta frequency) {
delete_expired_rate_limits_frequency_ = frequency;
}
void set_report_time_ms(int report_time_ms) {
report_time_ms_ = report_time_ms;
}
private:
int max_attributions_per_source_ = INT_MAX;
int max_sources_per_origin_ = INT_MAX;
int max_attributions_per_origin_ = INT_MAX;
int max_attribution_destinations_per_event_source_ = INT_MAX;
RateLimitConfig rate_limits_ = {
.time_window = base::TimeDelta::Max(),
.max_contributions_per_window = INT_MAX,
};
uint64_t fake_event_source_trigger_data_ = 0;
base::TimeDelta delete_expired_sources_frequency_;
base::TimeDelta delete_expired_rate_limits_frequency_;
int report_time_ms_ = 0;
};
// Test manager provider which can be used to inject a fake AttributionManager.
class TestManagerProvider : public AttributionManager::Provider {
public:
explicit TestManagerProvider(AttributionManager* manager)
: manager_(manager) {}
~TestManagerProvider() override = default;
AttributionManager* GetManager(WebContents* web_contents) const override;
private:
raw_ptr<AttributionManager> manager_ = nullptr;
};
// Test AttributionManager which can be injected into tests to monitor calls to
// a AttributionManager instance.
class TestAttributionManager : public AttributionManager {
public:
TestAttributionManager();
~TestAttributionManager() override;
// AttributionManager:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
void HandleSource(StorableSource source) override;
void HandleTrigger(StorableTrigger trigger) override;
void GetActiveSourcesForWebUI(
base::OnceCallback<void(std::vector<StorableSource>)> callback) override;
void GetPendingReportsForWebUI(
base::OnceCallback<void(std::vector<AttributionReport>)> callback)
override;
void SendReportsForWebUI(base::OnceClosure done) override;
const AttributionPolicy& GetAttributionPolicy() const override;
void ClearData(base::Time delete_begin,
base::Time delete_end,
base::RepeatingCallback<bool(const url::Origin&)> filter,
base::OnceClosure done) override;
void SetActiveSourcesForWebUI(std::vector<StorableSource> sources);
void SetReportsForWebUI(std::vector<AttributionReport> reports);
void NotifySourcesChanged();
void NotifyReportsChanged();
void NotifySourceDeactivated(
const AttributionStorage::DeactivatedSource& source);
void NotifyReportSent(const SentReportInfo& info);
void NotifyReportDropped(
const AttributionStorage::CreateReportResult& result);
// Resets all counters on this.
void Reset();
const std::vector<StorableSource>& handled_sources() const
WARN_UNUSED_RESULT {
return handled_sources_;
}
const std::vector<StorableTrigger>& handled_triggers() const
WARN_UNUSED_RESULT {
return handled_triggers_;
}
private:
AttributionPolicy policy_;
std::vector<StorableSource> handled_sources_;
std::vector<StorableTrigger> handled_triggers_;
std::vector<StorableSource> sources_;
std::vector<AttributionReport> reports_;
base::ObserverList<Observer, /*check_empty=*/true> observers_;
};
// Helper class to construct a StorableSource for tests using default data.
// StorableSource members are not mutable after construction requiring a
// builder pattern.
class SourceBuilder {
public:
explicit SourceBuilder(base::Time time);
~SourceBuilder();
SourceBuilder& SetExpiry(base::TimeDelta delta) WARN_UNUSED_RESULT;
SourceBuilder& SetSourceEventId(uint64_t source_event_id) WARN_UNUSED_RESULT;
SourceBuilder& SetImpressionOrigin(url::Origin origin) WARN_UNUSED_RESULT;
SourceBuilder& SetConversionOrigin(url::Origin domain) WARN_UNUSED_RESULT;
SourceBuilder& SetReportingOrigin(url::Origin origin) WARN_UNUSED_RESULT;
SourceBuilder& SetSourceType(StorableSource::SourceType source_type)
WARN_UNUSED_RESULT;
SourceBuilder& SetPriority(int64_t priority) WARN_UNUSED_RESULT;
SourceBuilder& SetAttributionLogic(
StorableSource::AttributionLogic attribution_logic) WARN_UNUSED_RESULT;
SourceBuilder& SetImpressionId(
absl::optional<StorableSource::Id> impression_id) WARN_UNUSED_RESULT;
SourceBuilder& SetDedupKeys(std::vector<int64_t> dedup_keys)
WARN_UNUSED_RESULT;
StorableSource Build() const WARN_UNUSED_RESULT;
private:
uint64_t source_event_id_ = 123;
base::Time impression_time_;
base::TimeDelta expiry_;
url::Origin impression_origin_;
url::Origin conversion_origin_;
url::Origin reporting_origin_;
StorableSource::SourceType source_type_ =
StorableSource::SourceType::kNavigation;
int64_t priority_ = 0;
StorableSource::AttributionLogic attribution_logic_ =
StorableSource::AttributionLogic::kTruthfully;
absl::optional<StorableSource::Id> impression_id_;
std::vector<int64_t> dedup_keys_;
};
// Returns a StorableTrigger with default data which matches the default
// impressions created by SourceBuilder.
StorableTrigger DefaultTrigger() WARN_UNUSED_RESULT;
// Helper class to construct a StorableTrigger for tests using default data.
// StorableTrigger members are not mutable after construction requiring a
// builder pattern.
class TriggerBuilder {
public:
TriggerBuilder();
~TriggerBuilder();
TriggerBuilder& SetTriggerData(uint64_t trigger_data) WARN_UNUSED_RESULT;
TriggerBuilder& SetEventSourceTriggerData(uint64_t event_source_trigger_data)
WARN_UNUSED_RESULT;
TriggerBuilder& SetConversionDestination(
net::SchemefulSite conversion_destination) WARN_UNUSED_RESULT;
TriggerBuilder& SetReportingOrigin(url::Origin reporting_origin)
WARN_UNUSED_RESULT;
TriggerBuilder& SetPriority(int64_t priority) WARN_UNUSED_RESULT;
TriggerBuilder& SetDedupKey(absl::optional<int64_t> dedup_key)
WARN_UNUSED_RESULT;
StorableTrigger Build() const WARN_UNUSED_RESULT;
private:
uint64_t trigger_data_ = 111;
uint64_t event_source_trigger_data_ = 0;
net::SchemefulSite conversion_destination_;
url::Origin reporting_origin_;
int64_t priority_ = 0;
absl::optional<int64_t> dedup_key_ = absl::nullopt;
};
// Helper class to construct an `AttributionReport` for tests using default
// data.
class ReportBuilder {
public:
explicit ReportBuilder(StorableSource source);
~ReportBuilder();
ReportBuilder& SetTriggerData(uint64_t trigger_data) WARN_UNUSED_RESULT;
ReportBuilder& SetConversionTime(base::Time time) WARN_UNUSED_RESULT;
ReportBuilder& SetReportTime(base::Time time) WARN_UNUSED_RESULT;
ReportBuilder& SetPriority(int64_t priority) WARN_UNUSED_RESULT;
ReportBuilder& SetExternalReportId(base::GUID external_report_id)
WARN_UNUSED_RESULT;
ReportBuilder& SetReportId(absl::optional<AttributionReport::Id> id)
WARN_UNUSED_RESULT;
AttributionReport Build() const WARN_UNUSED_RESULT;
private:
StorableSource source_;
uint64_t trigger_data_ = 0;
base::Time conversion_time_;
base::Time report_time_;
int64_t priority_ = 0;
base::GUID external_report_id_;
absl::optional<AttributionReport::Id> report_id_;
};
bool operator==(const StorableSource& a, const StorableSource& b);
bool operator==(const AttributionReport& a, const AttributionReport& b);
bool operator==(const SentReportInfo& a, const SentReportInfo& b);
bool operator==(const AttributionStorage::DeactivatedSource& a,
const AttributionStorage::DeactivatedSource& b);
std::ostream& operator<<(std::ostream& out,
AttributionStorage::CreateReportResult::Status status);
std::ostream& operator<<(std::ostream& out,
AttributionStorage::DeactivatedSource::Reason reason);
std::ostream& operator<<(std::ostream& out,
RateLimitTable::AttributionAllowedStatus status);
std::ostream& operator<<(std::ostream& out,
StorableSource::SourceType source_type);
std::ostream& operator<<(std::ostream& out, const StorableTrigger& conversion);
std::ostream& operator<<(std::ostream& out, const StorableSource& impression);
std::ostream& operator<<(std::ostream& out, const AttributionReport& report);
std::ostream& operator<<(std::ostream& out, SentReportInfo::Status status);
std::ostream& operator<<(std::ostream& out, const SentReportInfo& info);
std::ostream& operator<<(std::ostream& out,
StorableSource::AttributionLogic attribution_logic);
std::ostream& operator<<(
std::ostream& out,
const AttributionStorage::DeactivatedSource& deactivated_source);
std::vector<AttributionReport> GetAttributionsToReportForTesting(
AttributionManagerImpl* manager,
base::Time max_report_time) WARN_UNUSED_RESULT;
} // namespace content
#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_TEST_UTILS_H_