chromium/chromeos/dbus/missive/history_tracker_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/dbus/missive/history_tracker.h"

#include "base/test/task_environment.h"
#include "components/reporting/proto/synced/health.pb.h"
#include "components/reporting/proto/synced/record_constants.pb.h"
#include "components/reporting/util/test_support_callbacks.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::StrEq;

namespace reporting {
namespace {

class HistoryTrackerTest : public ::testing::Test {
 protected:
  base::test::TaskEnvironment task_environment_;

  const raw_ptr<HistoryTracker> tracker_{HistoryTracker::Get()};
};

TEST_F(HistoryTrackerTest, DebugStateTest) {
  // False by default.
  EXPECT_FALSE(tracker_->debug_state());

  // Enable and check.
  tracker_->set_debug_state(true);
  EXPECT_TRUE(tracker_->debug_state());

  // Disable and check
  tracker_->set_debug_state(false);
  EXPECT_FALSE(tracker_->debug_state());
}

TEST_F(HistoryTrackerTest, CollectHistoryTest) {
  ERPHealthData data;
  auto* const enqueue_record =
      data.add_history()->mutable_enqueue_record_call();
  enqueue_record->set_priority(Priority::FAST_BATCH);
  enqueue_record->set_destination(Destination::HEARTBEAT_EVENTS);
  auto* const upload_record =
      data.add_history()->mutable_upload_encrypted_record_call();
  upload_record->add_items()->mutable_record();
  upload_record->add_items()->mutable_gap();
  upload_record->set_upload_reason("PERIODIC");
  upload_record->set_priority(Priority::SLOW_BATCH);

  std::string expected_result;
  ASSERT_TRUE(data.SerializeToString(&expected_result));

  {
    test::TestCallbackAutoWaiter waiter;
    tracker_->set_data(std::move(data),
                       base::BindOnce(&test::TestCallbackAutoWaiter::Signal,
                                      base::Unretained(&waiter)));
  }

  {
    test::TestEvent<const ERPHealthData&> received;
    tracker_->retrieve_data(received.cb());
    const auto& result = received.ref_result();
    std::string actual_result;
    ASSERT_TRUE(result.SerializeToString(&actual_result));
    EXPECT_THAT(actual_result, StrEq(expected_result));
  }
}

TEST_F(HistoryTrackerTest, ObserversTest) {
  class MockObserver : public HistoryTracker::Observer {
   public:
    MOCK_METHOD(void, OnNewData, (const ERPHealthData& data), (const override));
  };

  ::testing::StrictMock<MockObserver> observer1;
  ::testing::StrictMock<MockObserver> observer2;
  ::testing::StrictMock<MockObserver> observer3;

  tracker_->AddObserver(&observer1);

  EXPECT_CALL(observer1, OnNewData).Times(1);
  EXPECT_CALL(observer2, OnNewData).Times(0);
  EXPECT_CALL(observer3, OnNewData).Times(0);

  {
    ERPHealthData data;
    test::TestCallbackAutoWaiter waiter;
    tracker_->set_data(std::move(data),
                       base::BindOnce(&test::TestCallbackAutoWaiter::Signal,
                                      base::Unretained(&waiter)));
  }

  tracker_->AddObserver(&observer2);
  tracker_->AddObserver(&observer3);

  EXPECT_CALL(observer1, OnNewData).Times(1);
  EXPECT_CALL(observer2, OnNewData).Times(1);
  EXPECT_CALL(observer3, OnNewData).Times(1);

  {
    ERPHealthData data;
    test::TestCallbackAutoWaiter waiter;
    tracker_->set_data(std::move(data),
                       base::BindOnce(&test::TestCallbackAutoWaiter::Signal,
                                      base::Unretained(&waiter)));
  }

  tracker_->RemoveObserver(&observer2);

  EXPECT_CALL(observer1, OnNewData).Times(1);
  EXPECT_CALL(observer2, OnNewData).Times(0);
  EXPECT_CALL(observer3, OnNewData).Times(1);

  {
    ERPHealthData data;
    test::TestCallbackAutoWaiter waiter;
    tracker_->set_data(std::move(data),
                       base::BindOnce(&test::TestCallbackAutoWaiter::Signal,
                                      base::Unretained(&waiter)));
  }

  tracker_->RemoveObserver(&observer1);
  tracker_->RemoveObserver(&observer3);

  EXPECT_CALL(observer1, OnNewData).Times(0);
  EXPECT_CALL(observer2, OnNewData).Times(0);
  EXPECT_CALL(observer3, OnNewData).Times(0);

  {
    ERPHealthData data;
    test::TestCallbackAutoWaiter waiter;
    tracker_->set_data(std::move(data),
                       base::BindOnce(&test::TestCallbackAutoWaiter::Signal,
                                      base::Unretained(&waiter)));
  }

  task_environment_.RunUntilIdle();  // Drain possible unfinished tasks.
}
}  // namespace
}  // namespace reporting