chromium/content/browser/attribution_reporting/attribution_os_level_manager_android_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 "content/browser/attribution_reporting/attribution_os_level_manager_android.h"

#include <memory>
#include <optional>
#include <set>
#include <string>

#include "base/functional/callback.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "components/attribution_reporting/os_registration.h"
#include "components/attribution_reporting/registrar.h"
#include "content/browser/attribution_reporting/attribution_input_event.h"
#include "content/browser/attribution_reporting/attribution_os_level_manager.h"
#include "content/browser/attribution_reporting/os_registration.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace content {
namespace {

using ::attribution_reporting::Registrar;

class AttributionOsLevelManagerAndroidTest : public ::testing::Test {
 public:
  void SetUp() override {
    manager_ = std::make_unique<AttributionOsLevelManagerAndroid>();
  }

 protected:
  BrowserTaskEnvironment task_environment_;
  base::HistogramTester histogram_tester_;
  std::unique_ptr<AttributionOsLevelManager> manager_;
};

TEST_F(AttributionOsLevelManagerAndroidTest, GetMeasurementStatusTimeMetric) {
  static constexpr char kGetMeasurementStatusTimeMetric[] =
      "Conversions.GetMeasurementStatusTime";

  task_environment_.RunUntilIdle();

  // The task is run from a background thread, wait for it.
  while (histogram_tester_.GetAllSamples(kGetMeasurementStatusTimeMetric)
             .empty()) {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }

  histogram_tester_.ExpectTotalCount(kGetMeasurementStatusTimeMetric, 1);
}

// Simple test to ensure that JNI calls work properly.
TEST_F(AttributionOsLevelManagerAndroidTest, Register) {
  const struct {
    const char* desc;
    std::optional<AttributionInputEvent> input_event;
    Registrar registrar;
    size_t items_count;
  } kTestCases[] = {
      {"os-trigger-single", std::nullopt, Registrar::kOs, 1},
      {"os-trigger-multi", std::nullopt, Registrar::kOs, 3},
      {"web-trigger-single", std::nullopt, Registrar::kWeb, 1},
      {"web-trigger-multi", std::nullopt, Registrar::kWeb, 3},
      {"web-source-single", AttributionInputEvent(), Registrar::kWeb, 1},
      {"web-source-multi", AttributionInputEvent(), Registrar::kWeb, 3},
      {"os-source-single", AttributionInputEvent(), Registrar::kOs, 1},
      {"os-source-multi", AttributionInputEvent(), Registrar::kOs, 3},
  };

  for (const auto& test_case : kTestCases) {
    SCOPED_TRACE(test_case.desc);

    base::RunLoop run_loop;

    std::vector<attribution_reporting::OsRegistrationItem> items;
    items.reserve(test_case.items_count);
    std::vector<bool> is_debug_key_allowed;
    is_debug_key_allowed.reserve(test_case.items_count);
    for (size_t i = 0; i < test_case.items_count; ++i) {
      items.emplace_back(GURL("https://r.test"), /*debug_reporting=*/false);
      is_debug_key_allowed.push_back(false);
    }
    manager_->Register(
        OsRegistration(
            std::move(items), url::Origin::Create(GURL("https://o.test")),
            test_case.input_event, /*is_within_fenced_frame=*/false,
            /*render_frame_id=*/GlobalRenderFrameHostId(), test_case.registrar),
        is_debug_key_allowed,
        base::BindLambdaForTesting([&](const OsRegistration& registration,
                                       const std::vector<bool>& success) {
          // We don't check `success` here because the measurement API may
          // or may not be available depending on the Android version.
          run_loop.Quit();
        }));

    run_loop.Run();
  }
}

// Simple test to ensure that JNI calls work properly.
TEST_F(AttributionOsLevelManagerAndroidTest, ClearData) {
  const BrowsingDataFilterBuilder::Mode kModes[] = {
      BrowsingDataFilterBuilder::Mode::kDelete,
      BrowsingDataFilterBuilder::Mode::kPreserve,
  };

  for (BrowsingDataFilterBuilder::Mode mode : kModes) {
    SCOPED_TRACE(static_cast<int>(mode));
    base::RunLoop run_loop;

    manager_->ClearData(
        /*delete_begin=*/base::Time::Min(),
        /*delete_end=*/base::Time::Max(),
        /*origins=*/{url::Origin::Create(GURL("https://o.test"))},
        /*domains=*/{"d.test"}, mode,
        /*delete_rate_limit_data=*/false, run_loop.QuitClosure());

    run_loop.Run();
  }
}

}  // namespace
}  // namespace content