// Copyright 2014 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/metrics/daily_event.h" #include #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace metrics { namespace { const char kTestPrefName[] = "TestPref"; const char kTestMetricName[] = "TestMetric"; class TestDailyObserver : public DailyEvent::Observer { public: TestDailyObserver() = default; TestDailyObserver(const TestDailyObserver&) = delete; TestDailyObserver& operator=(const TestDailyObserver&) = delete; bool fired() const { return type_.has_value(); } DailyEvent::IntervalType type() const { return type_.value(); } void OnDailyEvent(DailyEvent::IntervalType type) override { type_ = type; } void Reset() { type_ = {}; } private: // Last-received type, or unset if OnDailyEvent() hasn't been called. std::optional type_; }; class DailyEventTest : public testing::Test { public: DailyEventTest() : event_(&prefs_, kTestPrefName, kTestMetricName) { DailyEvent::RegisterPref(prefs_.registry(), kTestPrefName); auto observer = std::make_unique(); observer_ = observer.get(); event_.AddObserver(std::move(observer)); } DailyEventTest(const DailyEventTest&) = delete; DailyEventTest& operator=(const DailyEventTest&) = delete; protected: TestingPrefServiceSimple prefs_; DailyEvent event_; // Owns and outlives `observer_` raw_ptr observer_; }; } // namespace // The event should fire if the preference is not available. TEST_F(DailyEventTest, TestNewFires) { event_.CheckInterval(); ASSERT_TRUE(observer_->fired()); EXPECT_EQ(DailyEvent::IntervalType::FIRST_RUN, observer_->type()); } // The event should fire if the preference is more than a day old. TEST_F(DailyEventTest, TestOldFires) { base::Time last_time = base::Time::Now() - base::Hours(25); prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds()); event_.CheckInterval(); ASSERT_TRUE(observer_->fired()); EXPECT_EQ(DailyEvent::IntervalType::DAY_ELAPSED, observer_->type()); } // The event should fire if the preference is more than a day in the future. TEST_F(DailyEventTest, TestFutureFires) { base::Time last_time = base::Time::Now() + base::Hours(25); prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds()); event_.CheckInterval(); ASSERT_TRUE(observer_->fired()); EXPECT_EQ(DailyEvent::IntervalType::CLOCK_CHANGED, observer_->type()); } // The event should not fire if the preference is more recent than a day. TEST_F(DailyEventTest, TestRecentNotFired) { base::Time last_time = base::Time::Now() - base::Minutes(2); prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds()); event_.CheckInterval(); EXPECT_FALSE(observer_->fired()); } // The event should not fire if the preference is less than a day in the future. TEST_F(DailyEventTest, TestSoonNotFired) { base::Time last_time = base::Time::Now() + base::Minutes(2); prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds()); event_.CheckInterval(); EXPECT_FALSE(observer_->fired()); } } // namespace metrics