1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/daily_event.h"
6
7 #include <optional>
8
9 #include "base/memory/ptr_util.h"
10 #include "base/memory/raw_ptr.h"
11 #include "components/prefs/testing_pref_service.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace metrics {
15
16 namespace {
17
18 const char kTestPrefName[] = "TestPref";
19 const char kTestMetricName[] = "TestMetric";
20
21 class TestDailyObserver : public DailyEvent::Observer {
22 public:
23 TestDailyObserver() = default;
24
25 TestDailyObserver(const TestDailyObserver&) = delete;
26 TestDailyObserver& operator=(const TestDailyObserver&) = delete;
27
fired() const28 bool fired() const { return type_.has_value(); }
type() const29 DailyEvent::IntervalType type() const { return type_.value(); }
30
OnDailyEvent(DailyEvent::IntervalType type)31 void OnDailyEvent(DailyEvent::IntervalType type) override { type_ = type; }
32
Reset()33 void Reset() { type_ = {}; }
34
35 private:
36 // Last-received type, or unset if OnDailyEvent() hasn't been called.
37 std::optional<DailyEvent::IntervalType> type_;
38 };
39
40 class DailyEventTest : public testing::Test {
41 public:
DailyEventTest()42 DailyEventTest() : event_(&prefs_, kTestPrefName, kTestMetricName) {
43 DailyEvent::RegisterPref(prefs_.registry(), kTestPrefName);
44 auto observer = std::make_unique<TestDailyObserver>();
45 observer_ = observer.get();
46 event_.AddObserver(std::move(observer));
47 }
48
49 DailyEventTest(const DailyEventTest&) = delete;
50 DailyEventTest& operator=(const DailyEventTest&) = delete;
51
52 protected:
53 TestingPrefServiceSimple prefs_;
54 DailyEvent event_; // Owns and outlives `observer_`
55 raw_ptr<TestDailyObserver> observer_;
56 };
57
58 } // namespace
59
60 // The event should fire if the preference is not available.
TEST_F(DailyEventTest,TestNewFires)61 TEST_F(DailyEventTest, TestNewFires) {
62 event_.CheckInterval();
63 ASSERT_TRUE(observer_->fired());
64 EXPECT_EQ(DailyEvent::IntervalType::FIRST_RUN, observer_->type());
65 }
66
67 // The event should fire if the preference is more than a day old.
TEST_F(DailyEventTest,TestOldFires)68 TEST_F(DailyEventTest, TestOldFires) {
69 base::Time last_time = base::Time::Now() - base::Hours(25);
70 prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds());
71 event_.CheckInterval();
72 ASSERT_TRUE(observer_->fired());
73 EXPECT_EQ(DailyEvent::IntervalType::DAY_ELAPSED, observer_->type());
74 }
75
76 // The event should fire if the preference is more than a day in the future.
TEST_F(DailyEventTest,TestFutureFires)77 TEST_F(DailyEventTest, TestFutureFires) {
78 base::Time last_time = base::Time::Now() + base::Hours(25);
79 prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds());
80 event_.CheckInterval();
81 ASSERT_TRUE(observer_->fired());
82 EXPECT_EQ(DailyEvent::IntervalType::CLOCK_CHANGED, observer_->type());
83 }
84
85 // The event should not fire if the preference is more recent than a day.
TEST_F(DailyEventTest,TestRecentNotFired)86 TEST_F(DailyEventTest, TestRecentNotFired) {
87 base::Time last_time = base::Time::Now() - base::Minutes(2);
88 prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds());
89 event_.CheckInterval();
90 EXPECT_FALSE(observer_->fired());
91 }
92
93 // The event should not fire if the preference is less than a day in the future.
TEST_F(DailyEventTest,TestSoonNotFired)94 TEST_F(DailyEventTest, TestSoonNotFired) {
95 base::Time last_time = base::Time::Now() + base::Minutes(2);
96 prefs_.SetInt64(kTestPrefName, last_time.since_origin().InMicroseconds());
97 event_.CheckInterval();
98 EXPECT_FALSE(observer_->fired());
99 }
100
101 } // namespace metrics
102