chromium/chrome/browser/metrics/structured/lacros_structured_metrics_delegate_browsertest.cc

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

#include "chrome/browser/metrics/structured/lacros_structured_metrics_delegate.h"

#include <memory>
#include <utility>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/scoped_run_loop_timeout.h"
#include "chrome/browser/metrics/structured/chrome_structured_metrics_delegate.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/metrics/structured/event.h"
#include "components/metrics/structured/structured_events.h"
#include "components/metrics/structured/structured_metrics_client.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace metrics::structured {

namespace {

using FlushCallback = base::RepeatingCallback<void()>;
using RecordCallback = base::OnceCallback<void(const Event& event)>;

using testing::Eq;

}  // namespace

// TODO(jongahn): Improve test checkers once callback API is implemented to
// verify that events sent to Ash-Chrome have been verified.
class LacrosStructuredMetricsDelegateTest : public InProcessBrowserTest {
 public:
  LacrosStructuredMetricsDelegateTest() = default;
  ~LacrosStructuredMetricsDelegateTest() override = default;

  class TestObserver : public LacrosStructuredMetricsDelegate::Observer {
   public:
    TestObserver() = default;
    ~TestObserver() override = default;

    void SetFlushCallback(FlushCallback callback) {
      flush_callback_ = std::move(callback);
    }

    void SetRecordCallback(RecordCallback callback) {
      record_callback_ = std::move(callback);
    }

    void OnRecord(const Event& event) override {
      std::move(record_callback_).Run(event);
    }

    void OnFlush() override { std::move(flush_callback_).Run(); }

   private:
    FlushCallback flush_callback_;
    RecordCallback record_callback_;
  };

  void TearDownInProcessBrowserTestFixture() override {
    if (observer_) {
      recorder_->RemoveObserver(observer_.get());
    }

    StructuredMetricsClient::Get()->UnsetDelegate();
    InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
  }

  TestObserver* InitTestObserver() {
    observer_ = std::make_unique<TestObserver>();
    recorder_ = static_cast<LacrosStructuredMetricsDelegate*>(
        ChromeStructuredMetricsDelegate::Get()->delegate_.get());
    recorder_->AddObserver(observer_.get());
    return observer_.get();
  }

  void RemoveObserver(TestObserver* observer) {
    recorder_->RemoveObserver(observer);
  }

  LacrosStructuredMetricsDelegate* recorder() { return recorder_; }

 private:
  raw_ptr<LacrosStructuredMetricsDelegate> recorder_;
  std::unique_ptr<TestObserver> observer_;
};

IN_PROC_BROWSER_TEST_F(LacrosStructuredMetricsDelegateTest,
                       SendValidEventSuccessfully) {
  auto* observer = InitTestObserver();
  RecordCallback record_callback =
      base::BindLambdaForTesting([](const Event& event) {
        EXPECT_THAT(event.project_name(), "TestProjectOne");
        EXPECT_THAT(event.event_name(), "TestEventOne");
      });
  observer->SetRecordCallback(std::move(record_callback));

  FlushCallback flush_callback = base::BindLambdaForTesting([]() { FAIL(); });
  observer->SetFlushCallback(std::move(flush_callback));

  events::v2::test_project_one::TestEventOne test_event;
  test_event.SetTestMetricOne("hash").SetTestMetricTwo(1);
  StructuredMetricsClient::Record(std::move(test_event));
}

IN_PROC_BROWSER_TEST_F(LacrosStructuredMetricsDelegateTest,
                       EventIgnoredIfSequenceNotSet) {
  auto* observer = InitTestObserver();
  RecordCallback record_callback =
      base::BindLambdaForTesting([](const Event& event) { FAIL(); });
  observer->SetRecordCallback(std::move(record_callback));

  events::v2::test_project_one::TestEventOne test_event;
  test_event.SetTestMetricOne("hash").SetTestMetricTwo(1);

  // Reset the sequence.
  recorder()->SetSequence(nullptr);

  // Record before sequence is set.
  StructuredMetricsClient::Record(std::move(test_event));

  // SUCCESS() if callback not triggered.
}

}  // namespace metrics::structured