blob: 8d509a2a5ea53e117182385a7c5ea620d729d40a [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/feature_engagement/internal/single_event_model_provider.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "components/feature_engagement/internal/event_model.h"
#include "components/feature_engagement/internal/proto/feature_event.pb.h"
#include "components/feature_engagement/internal/test/event_util.h"
#include "components/feature_engagement/public/configuration.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
using testing::Return;
using testing::ReturnArg;
using testing::Sequence;
namespace feature_engagement {
class MockEventModel : public EventModel {
public:
MockEventModel() = default;
MockEventModel(const MockEventModel&) = delete;
MockEventModel& operator=(const MockEventModel&) = delete;
~MockEventModel() override = default;
// EventModel implementation.
MOCK_METHOD2(Initialize, void(OnModelInitializationFinished, uint32_t));
MOCK_CONST_METHOD0(IsReady, bool());
MOCK_CONST_METHOD1(GetEvent, Event*(const std::string&));
MOCK_CONST_METHOD3(GetEventCount,
uint32_t(const std::string&, uint32_t, uint32_t));
MOCK_METHOD2(IncrementEvent, void(const std::string&, uint32_t));
MOCK_METHOD1(ClearEvent, void(const std::string&));
MOCK_METHOD3(IncrementSnooze, void(const std::string&, uint32_t, base::Time));
MOCK_METHOD1(DismissSnooze, void(const std::string&));
MOCK_CONST_METHOD1(GetLastSnoozeTimestamp, base::Time(const std::string&));
MOCK_CONST_METHOD3(GetSnoozeCount,
uint32_t(const std::string&, uint32_t, uint32_t));
MOCK_CONST_METHOD1(IsSnoozeDismissed, bool(const std::string&));
};
class SingleEventModelProviderTest : public testing::Test {
public:
SingleEventModelProviderTest() {
load_callback_ =
base::BindOnce(&SingleEventModelProviderTest::OnModelInitialized,
base::Unretained(this));
}
SingleEventModelProviderTest(const SingleEventModelProviderTest&) = delete;
SingleEventModelProviderTest& operator=(const SingleEventModelProviderTest&) =
delete;
~SingleEventModelProviderTest() override = default;
void SetUp() override {
auto mocked_model = std::make_unique<MockEventModel>();
mocked_model_ = mocked_model.get();
provider_ =
std::make_unique<SingleEventModelProvider>(std::move(mocked_model));
}
protected:
void OnModelInitialized(bool success) { load_success_ = success; }
base::test::TaskEnvironment task_environment_;
std::unique_ptr<SingleEventModelProvider> provider_;
raw_ptr<MockEventModel> mocked_model_;
// Load callback tracking.
std::optional<bool> load_success_;
EventModel::OnModelInitializationFinished load_callback_;
};
TEST_F(SingleEventModelProviderTest, SuccessfulInitializationForEventProvider) {
EventModel::OnModelInitializationFinished callback;
EXPECT_CALL(*mocked_model_, Initialize(_, _))
.WillOnce([](EventModel::OnModelInitializationFinished cb,
uint32_t /*day*/) { std::move(cb).Run(true); });
provider_->Initialize(std::move(load_callback_), 2U);
EXPECT_TRUE(load_success_.value());
}
TEST_F(SingleEventModelProviderTest,
EventProviderIsReadyWhenEventModelIsReady) {
EXPECT_CALL(*mocked_model_, IsReady()).Times(1).WillOnce(Return(true));
EXPECT_TRUE(provider_->IsReady());
}
TEST_F(SingleEventModelProviderTest, EventProviderReturnsReaderForGetEvent) {
Event foo;
foo.set_name("foo");
test::SetEventCountForDay(&foo, 1, 1);
FeatureConfig config;
EXPECT_CALL(*mocked_model_, GetEvent(foo.name()))
.Times(1)
.WillRepeatedly(Return(&foo));
test::VerifyEventsEqual(
&foo,
provider_->GetEventModelReaderForFeature(config)->GetEvent(foo.name()));
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsReaderForGetEventCount) {
FeatureConfig config;
EXPECT_CALL(*mocked_model_, GetEventCount("foo", _, _))
.WillRepeatedly(ReturnArg<1>());
EXPECT_EQ(2u, provider_->GetEventModelReaderForFeature(config)->GetEventCount(
"foo", 2, 1));
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsReaderForGetLastSnoozeTimestamp) {
base::Time time = base::Time::Now();
FeatureConfig config;
EXPECT_CALL(*mocked_model_, GetLastSnoozeTimestamp("bar"))
.Times(1)
.WillOnce(Return(time));
EXPECT_EQ(time, provider_->GetEventModelReaderForFeature(config)
->GetLastSnoozeTimestamp("bar"));
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsReaderForGetSnoozeCount) {
FeatureConfig config;
EXPECT_CALL(*mocked_model_, GetSnoozeCount("foo", _, _))
.WillRepeatedly(ReturnArg<1>());
EXPECT_EQ(2u,
provider_->GetEventModelReaderForFeature(config)->GetSnoozeCount(
"foo", 2, 1));
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsReaderForIsSnoozeDismissed) {
FeatureConfig config;
EXPECT_CALL(*mocked_model_, IsSnoozeDismissed("foo"))
.Times(1)
.WillOnce(Return(true));
EXPECT_TRUE(
provider_->GetEventModelReaderForFeature(config)->IsSnoozeDismissed(
"foo"));
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsWriterForIncrementEvent) {
Sequence sequence;
EXPECT_CALL(*mocked_model_, IncrementEvent("bar", 1U))
.Times(1)
.InSequence(sequence);
provider_->GetEventModelWriter()->IncrementEvent("bar", 1U);
}
TEST_F(SingleEventModelProviderTest, EventProviderReturnsWriterForClearEvent) {
Sequence sequence;
EXPECT_CALL(*mocked_model_, ClearEvent("bar")).Times(1).InSequence(sequence);
provider_->GetEventModelWriter()->ClearEvent("bar");
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsWriterForIncrementSnooze) {
Sequence sequence;
EXPECT_CALL(*mocked_model_, IncrementSnooze("bar", _, _))
.Times(1)
.InSequence(sequence);
provider_->GetEventModelWriter()->IncrementSnooze("bar", 1U,
base::Time::Now());
}
TEST_F(SingleEventModelProviderTest,
EventProviderReturnsWriterForDismissSnooze) {
Sequence sequence;
EXPECT_CALL(*mocked_model_, DismissSnooze("bar"))
.Times(1)
.InSequence(sequence);
provider_->GetEventModelWriter()->DismissSnooze("bar");
}
} // namespace feature_engagement