chromium/content/browser/interest_group/ad_auction_service_impl_unittest.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 "content/browser/interest_group/ad_auction_service_impl.h"

#include <stddef.h>

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/barrier_closure.h"
#include "base/base64.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/rust_buildflags.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "components/aggregation_service/aggregation_coordinator_utils.h"
#include "components/cbor/diagnostic_writer.h"
#include "components/cbor/reader.h"
#include "components/services/storage/shared_storage/shared_storage_manager.h"
#include "content/browser/aggregation_service/aggregatable_report.h"
#include "content/browser/fenced_frame/fenced_frame_url_mapping.h"
#include "content/browser/interest_group/ad_auction_page_data.h"
#include "content/browser/interest_group/auction_process_manager.h"
#include "content/browser/interest_group/interest_group_caching_storage.h"
#include "content/browser/interest_group/interest_group_features.h"
#include "content/browser/interest_group/interest_group_manager_impl.h"
#include "content/browser/interest_group/interest_group_storage.h"
#include "content/browser/interest_group/storage_interest_group.h"
#include "content/browser/private_aggregation/private_aggregation_budgeter.h"
#include "content/browser/private_aggregation/private_aggregation_manager_impl.h"
#include "content/browser/private_aggregation/private_aggregation_test_utils.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/privacy_sandbox_invoking_api.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/services/auction_worklet/auction_v8_helper.h"
#include "content/services/auction_worklet/auction_worklet_service_impl.h"
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "content/test/fenced_frame_test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "crypto/sha2.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "net/base/isolation_info.h"
#include "net/third_party/quiche/src/quiche/oblivious_http/oblivious_http_gateway.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"
#include "third_party/blink/public/common/interest_group/test/interest_group_test_utils.h"
#include "third_party/blink/public/common/interest_group/test_interest_group_builder.h"
#include "third_party/blink/public/common/permissions_policy/permissions_policy_features.h"
#include "third_party/blink/public/mojom/interest_group/ad_auction_service.mojom.h"
#include "third_party/blink/public/mojom/interest_group/interest_group_types.mojom.h"
#include "third_party/blink/public/mojom/parakeet/ad_request.mojom.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace content {

class BrowserContext;

namespace {

IgExpectEqualsForTesting;
IgExpectNotEqualsForTesting;

RealTimeReportingType;

const size_t kEncryptionOverhead =;

constexpr char kInterestGroupName[] =;
constexpr char kOriginStringA[] =;
constexpr char kOriginStringB[] =;
constexpr char kOriginStringC[] =;
constexpr char kOriginStringD[] =;
constexpr char kOriginStringE[] =;
constexpr char kOriginStringF[] =;
constexpr char kOriginStringG[] =;
constexpr char kOriginStringNoUpdate[] =;
constexpr char kBiddingUrlPath[] =;
constexpr char kNewBiddingUrlPath[] =;
constexpr char kDecisionUrlPath[] =;
constexpr char kTrustedBiddingSignalsUrlPath[] =;
constexpr char kTrustedScoringSignalsUrlPath[] =;
constexpr char kUpdateUrlPath[] =;
constexpr char kUpdateUrlPath2[] =;
constexpr char kUpdateUrlPath3[] =;
constexpr char kUpdateUrlPath4[] =;
constexpr char kUpdateUrlPathB[] =;
constexpr char kUpdateUrlPathC[] =;
constexpr char kBAndAKeyPath[] =;

// These keys were randomly generated as follows:
// EVP_HPKE_KEY keys;
// EVP_HPKE_KEY_generate(&keys, EVP_hpke_x25519_hkdf_sha256());
// and then EVP_HPKE_KEY_public_key and EVP_HPKE_KEY_private_key were used to
// extract the keys.
const uint8_t kTestPrivateKey[] =;

const uint8_t kTestPublicKey[] =;

// Returns kTestPublicKey as a JSON response to be returned by kBAndAKeyPath.
std::string JSONSerializedKeys() {}

// Returns a basic bidder script that sends reports to
// kOriginStringA/report_bidder.
std::string BasicBiddingReportScript() {}

// Returns a basic seller script that sends reports to
// kOriginStringA/report_seller.
std::string BasicSellerReportScript(bool send_report = true) {}

class AllowInterestGroupContentBrowserClient : public TestContentBrowserClient {};

constexpr char kFledgeUpdateHeaders[] =;

constexpr char kFledgeScriptHeaders[] =;

constexpr char kFledgeReportHeaders[] =;

constexpr char kFledgeSignalsHeaders[] =;

// Allows registering network responses to update and scoring / bidding script
// requests; *must* be destroyed before the task environment is shutdown (which
// happens in RenderViewHostTestHarness::TearDown()).
//
// Updates and script serving have different requirements, but unfortunately
// it's not possible to simultaneously instantiate 2 classes that both use their
// own URLLoaderInterceptor...so these are combined in this same class.
class NetworkResponder {};

// AuctionProcessManager that allows running auctions in-proc.
class SameProcessAuctionProcessManager : public AuctionProcessManager {};

class TestKAnonymityServiceDelegate : public KAnonymityServiceDelegate {};

class TestPrivateAggregationManagerImpl : public PrivateAggregationManagerImpl {};

// Add a mock to intercept calls to the PrivateAggregationHost.
class MockPrivateAggregationHostForTest : public PrivateAggregationHost {};

}  // namespace

// Tests the interest group management functionality of AdAuctionServiceImpl --
// this particular functionality used to be in a separate interface called
// RestrictedInterestStore. The interfaces were combined so so that they'd share
// a Mojo pipe (for message ordering consistency).
class AdAuctionServiceImplTest : public RenderViewHostTestHarness {};

// Check basic success case.
TEST_F(AdAuctionServiceImplTest, JoinInterestGroupBasic) {}

// Non-HTTPS frames should not be able to join interest groups.
TEST_F(AdAuctionServiceImplTest, JoinInterestGroupFrameNotHttps) {}

// Try to join a non-HTTPS interest group.
TEST_F(AdAuctionServiceImplTest, JoinInterestGroupOwnerNotHttps) {}

// Test joining an interest group with a disallowed URL. Doesn't
// exhaustively test all cases, as the validation function has its own unit
// tests. This is just to make sure those are hooked up.
TEST_F(AdAuctionServiceImplTest, JoinInterestGroupDisallowedUrls) {}

// Successful join. Duplicate allowed reporting origins are removed.
TEST_F(AdAuctionServiceImplTest,
       JoinInterestGroupDeduplicateAllowedReportingOrigins) {}

// Attempt to join an interest group whose allowed reporting origins are not all
// attested. No join should happen.
TEST_F(AdAuctionServiceImplTest,
       JoinInterestGroupNotAttestedAllowedReportingOrigins) {}

// Attempt to join an interest group whose size is very large. No join should
// happen -- it should fail and close the pipe.
TEST_F(AdAuctionServiceImplTest, JoinMassiveInterestGroupFails) {}

// Trying to leave Non-HTTPS interest groups should not be possible, and result
// in the pipe being closed. Can't check there's an HTTP group that isn't left,
// since it should be impossible to join one in the first place.
TEST_F(AdAuctionServiceImplTest, LeaveClearInterestGroupOriginNotHttps) {}

// Non-HTTPS interest origins should not be able to leave groups should be
// rejected, and result in the pipe being closed.
TEST_F(AdAuctionServiceImplTest, LeaveClearInterestGroupFrameNotHttps) {}

TEST_F(AdAuctionServiceImplTest, FixExpiryOnJoin) {}

// These tests validate the `updateURL` and navigator.updateAdInterestGroups()
// functionality.

// The server JSON updates all fields that can be updated.
TEST_F(AdAuctionServiceImplTest, UpdateAllUpdatableFields) {}

TEST_F(AdAuctionServiceImplTest, UpdateExecutionModeToGroupByOrigin) {}

TEST_F(AdAuctionServiceImplTest, UpdateExecutionModeToFrozenContext) {}

TEST_F(AdAuctionServiceImplTest, UpdateExecutionModeToCompatibilityMode) {}

TEST_F(AdAuctionServiceImplTest,
       UpdateUnrecognizedExecutionModeToCompatibility) {}

// Only set the ads field -- the other fields shouldn't be changed.
TEST_F(AdAuctionServiceImplTest, UpdatePartialPerformsMerge) {}

// The update shouldn't change the expiration time of the interest group.
TEST_F(AdAuctionServiceImplTest, UpdateDoesntChangeExpiration) {}

// Updates should succeed even when updating interest groups with no ads.
TEST_F(AdAuctionServiceImplTest, UpdateGroupWithNoAds) {}

// Only set the ads field -- the other fields shouldn't be changed.
TEST_F(AdAuctionServiceImplTest, UpdateSucceedsIfOptionalNameOwnerMatch) {}

// An unrecognized trustedBiddingSignalsSlotSizeMode should be treated as if it
// were "none".
TEST_F(AdAuctionServiceImplTest,
       UnrecognizedTrustedBiddingSignalsSlotSizeMode) {}

// For forward compatibility we should silently ignore fields that we don't
// know about.
TEST_F(AdAuctionServiceImplTest, UpdateIgnoresUnknownFields) {}

// Try to set the name -- for security, name and owner shouldn't be
// allowed to change. If they don't match the interest group (update URLs are
// registered per interest group), fail the update and don't update anything.
TEST_F(AdAuctionServiceImplTest, NoUpdateIfOptionalNameDoesntMatch) {}

// Try to set the owner -- for security, name and owner shouldn't be
// allowed to change. If they don't match the interest group (update URLs are
// registered per interest group), fail the update and don't update anything.
TEST_F(AdAuctionServiceImplTest, NoUpdateIfOptionalOwnerDoesntMatch) {}

TEST_F(AdAuctionServiceImplTest, UpdatePriorityVector) {}

TEST_F(AdAuctionServiceImplTest, AddTrustedBiddingSignalsCoordinator) {}

TEST_F(AdAuctionServiceImplTest, RemoveTrustedBiddingSignalsCoordinator) {}

TEST_F(AdAuctionServiceImplTest,
       UppdateWithNonStringTrustedBiddingSignalsCoordinator) {}

TEST_F(AdAuctionServiceImplTest,
       UppdateWithInvalidGURLTrustedBiddingSignalsCoordinator) {}

TEST_F(AdAuctionServiceImplTest,
       UppdateWithNonHTTPSTrustedBiddingSignalsCoordinator) {}

class AdAuctionServiceImplTestDisabledDealSupport
    : public AdAuctionServiceImplTest {};
// TODO (b/356654297) Test updating selectableBuyerAndSellerReportingIds, when
// it is implemented.
TEST_F(AdAuctionServiceImplTestDisabledDealSupport,
       UpdateSelectableBuyerAndSellerReportingIds) {}

TEST_F(AdAuctionServiceImplTest, UpdatePrioritySignalsOverrides) {}

// Join 2 interest groups, each with the same owner, but with different update
// URLs. Both interest groups should be updated correctly.
TEST_F(AdAuctionServiceImplTest, UpdateMultipleInterestGroups) {}

class AdAuctionServiceImplDifferentNIKDuringUpdateTest
    : public AdAuctionServiceImplTest {};

// Join two interest groups with two different owners but one joining origin.
// Check if they reuse same isolation info.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateCheckNIKForTwoOwnersOneJoiningOrigin) {}

// Join two interest groups with one owner but two different joining origins.
// Check if they use different isolation info.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateCheckNIKForOneOwnerTwoJoiningOrigins) {}

// Join two interest groups with two different owners but one joining origin.
// Ensure the second one join after all updating work completes and the queue is
// popped empty. Check that the isolation info is different.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdatePopOwnerQueueToEmptyTriggerClearIsolationMap) {}

// Join two interest groups with two different owners but one joining origin.
// Ensure the owner queue gets cleared before the second interest group join.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateClearOwnerQueueTriggerClearIsolationMap) {}

// If there are two groups with joining origin A, two groups with joining origin
// C, and batch limitation size as three, it cannot mix different joining
// origins together in one batch.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateMultipleJoiningOriginsAllLessThanBatchSize) {}

// If there are three groups with joining origin A, one group with joining
// origin C, and batch limitation size as three, it can send three groups with
// joining origin A in one batch.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateMultipleJoiningOriginsAndOneEqualToBatchSize) {}

// If there are three groups with joining origin A, one group with joining
// origin C, and batch limitation size as two, it can send two groups with
// joining origin A in the first batch, and remain two groups with different
// joining origins together in the second batch.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateMultipleJoiningOriginsAndOneMoreThanBatchSize) {}

// Test if the interest group can still be able to update after delaying once.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateMultipleBatches) {}

// Join two interest groups with different joining origins and defer the update.
// Later, join another group with the same origin as the second one during the
// deferment. Verify that the second and third groups use different isolation
// information.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateIsolationMapIsClearedWithMixedJoiningOriginsAndNewJoinedGroup) {}

// Join an interest group with joining origin C update it, then join two more
// groups with joining origin A and C almost 24 hours later. Delay the update
// until the first group is ready for updating again. Confirm that the two
// C-joining_origin groups use different isolation info.
TEST_F(AdAuctionServiceImplDifferentNIKDuringUpdateTest,
       UpdateIsolationMapIsClearedWithMixedJoiningOriginsAndNewValidGroup) {}

// Join 2 interest groups, each with a different owner. When updating interest
// groups, only the 1 interest group owned by the origin of the frame that
// called navigator.updateAdInterestGroups() gets updated.
TEST_F(AdAuctionServiceImplTest, UpdateOnlyOwnOrigin) {}

// Test updating an interest group with a cross-site owner.
TEST_F(AdAuctionServiceImplTest, UpdateFromCrossSiteIFrame) {}

// The `ads` field is valid, but one of its fields is invalid. The entire update
// should get cancelled, since updates are atomic.
TEST_F(AdAuctionServiceImplTest, UpdateInvalidFieldCancelsAllUpdates) {}

// The `ads` field is valid, but one of its allowed reporting origins is not
// attested. The entire update should get cancelled.
TEST_F(AdAuctionServiceImplTest,
       UpdateNotAttestedAllowedReportingOriginsCancelsAllUpdates) {}

// The `priority` field is not a valid number. The entire update should get
// cancelled, since updates are atomic.
TEST_F(AdAuctionServiceImplTest, UpdateInvalidPriorityCancelsAllUpdates) {}

// The `sellerCapabilities` field has an invalid capability. The invalid
// capability gets skipped, but the rest of the update proceeds.
TEST_F(AdAuctionServiceImplTest, UpdateInvalidSellerCapabilitiesIgnored) {}

// The server response can't be parsed as valid JSON. The update is cancelled.
TEST_F(AdAuctionServiceImplTest, UpdateInvalidJSONIgnored) {}

// UpdateJSONParserCrash fails on Android or with the Rust parser because in
// those conditions the data decoder doesn't use a separate process to parse
// JSON. On other platforms, the C++ parser runs out-of-proc for safety.
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(BUILD_RUST_JSON_READER)

// The server response is valid, but we simulate the JSON parser (which may
// run in a separate process) crashing, so the update doesn't happen.
TEST_F(AdAuctionServiceImplTest, UpdateJSONParserCrash) {
  network_responder_->RegisterUpdateResponse(kUpdateUrlPath, R"({
"ads": [{"renderURL": "https://example.com/new_render"
        }]
})");

  blink::InterestGroup interest_group = CreateInterestGroup();
  // Set a long expiration delta so that we can advance to the next rate limit
  // period without the interest group expiring.
  interest_group.expiry = base::Time::Now() + base::Days(30);
  interest_group.update_url = kUpdateUrlA;
  interest_group.bidding_url = kBiddingLogicUrlA;
  interest_group.trusted_bidding_signals_url = kTrustedBiddingSignalsUrlA;
  interest_group.trusted_bidding_signals_keys.emplace();
  interest_group.trusted_bidding_signals_keys->push_back("key1");
  interest_group.ads.emplace();
  blink::InterestGroup::Ad ad(
      /*render_url=*/GURL("https://example.com/render"),
      /*metadata=*/std::nullopt);
  interest_group.ads->emplace_back(std::move(ad));
  JoinInterestGroupAndFlush(interest_group);
  EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName));

  // Simulate the JSON service crashing instead of returning a result.
  data_decoder::test::InProcessDataDecoder in_process_data_decoder;
  in_process_data_decoder.SimulateJsonParserCrash(
      /*drop=*/true);

  UpdateInterestGroupNoFlush();
  task_environment()->RunUntilIdle();

  // Check that the ads didn't change.
  scoped_refptr<StorageInterestGroups> groups =
      GetInterestGroupsForOwner(kOriginA);
  ASSERT_EQ(groups->size(), 1u);
  auto group = groups->GetInterestGroups()[0]->interest_group;
  ASSERT_TRUE(group.ads.has_value());
  ASSERT_EQ(group.ads->size(), 1u);
  EXPECT_EQ(group.ads.value()[0].render_url(), "https://example.com/render");

  // Try another IG update, this time with no crash. It should succceed.
  // (We need to advance time since this next attempt is rate-limited).
  in_process_data_decoder.SimulateJsonParserCrash(
      /*drop=*/false);
  task_environment()->FastForwardBy(
      InterestGroupStorage::kUpdateSucceededBackoffPeriod);
  UpdateInterestGroupNoFlush();
  task_environment()->RunUntilIdle();

  // Check that the ads *did* change this time.
  groups = GetInterestGroupsForOwner(kOriginA);
  ASSERT_EQ(groups->size(), 1u);
  group = groups->GetInterestGroups()[0]->interest_group;
  ASSERT_TRUE(group.ads.has_value());
  ASSERT_EQ(group.ads->size(), 1u);
  EXPECT_EQ(group.ads.value()[0].render_url(),
            "https://example.com/new_render");
}

#endif  // !BUILDFLAG(IS_ANDROID)

// Trigger an update, but block it via ContentBrowserClient policy.
// The update shouldn't happen.
TEST_F(AdAuctionServiceImplTest, UpdateBlockedByContentBrowserClient) {}

// The network request fails (not implemented), so the update is cancelled.
TEST_F(AdAuctionServiceImplTest, UpdateNetworkFailure) {}

// The network request for updating interest groups times out, so the update
// fails.
TEST_F(AdAuctionServiceImplTest, UpdateTimeout) {}

// Start an update, and delay the server response so that the interest group
// expires before the interest group updates. Don't advance time enough for DB
// maintenance tasks to run -- that is the interest group will only exist on
// disk in an expired state, and not appear in queries.
TEST_F(AdAuctionServiceImplTest,
       UpdateDuringInterestGroupExpirationNoDbMaintenence) {}

// Start an update, and delay the server response so that the interest group
// expires before the interest group updates. Advance time enough for DB
// maintenance tasks to run -- that is the interest group will be deleted from
// the database.
TEST_F(AdAuctionServiceImplTest,
       UpdateDuringInterestGroupExpirationWithDbMaintenence) {}

// Start an update, and delay the server response so that the test ends before
// the interest group finishes updating. Nothing should crash.
TEST_F(AdAuctionServiceImplTest, UpdateNeverFinishesBeforeDestruction) {}

// The update doesn't happen because the update URL isn't specified at
// Join() time.
TEST_F(AdAuctionServiceImplTest, DoesntChangeGroupsWithNoUpdateUrl) {}

// Register a bid and a win, then perform a successful update. The bid and win
// stats shouldn't change.
TEST_F(AdAuctionServiceImplTest, UpdateDoesntChangeBrowserSignals) {}

// Join an interest group.
// Update interest group successfully.
// Change update response to different value.
// Update attempt does nothing (rate limited).
// Advance to just before time limit drops, update does nothing (rate limited).
// Advance after time limit. Update should work.
TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterSuccessfulUpdate) {}

// Join an interest group.
// Set up update to fail (return invalid server response).
// Update interest group fails.
// Change update response to different value that will succeed.
// Update does nothing (rate limited).
// Advance to just before rate limit drops (which for bad response is the longer
// "successful" duration), update does nothing (rate limited).
// Advance after time limit. Update should work.
TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterBadUpdateResponse) {}

// Just like AdAuctionServiceImplTest.UpdateRateLimitedAfterBadUpdateResponse,
// except server returns a valid JSON response for update but with un-enrolled
// allowedReportingOrigins.
//
// Join an interest group.
// Set up update to fail (return server response with un-enrolled origins).
// Update interest group fails.
// Change update response to different value that will succeed.
// Update does nothing (rate limited).
// Advance to just before rate limit drops (which for bad response is the longer
// "successful" duration), update does nothing (rate limited).
// Advance after time limit. Update should work.
TEST_F(AdAuctionServiceImplTest,
       UpdateRateLimitedAfterGotNotAttestedAllowedReportingOrigins) {}

// Join an interest group.
// Make interest group update fail with net::ERR_CONNECTION_RESET.
// Update interest group fails.
// Change update response to succeed.
// Update does nothing (rate limited).
// Advance to just before rate limit drops, update does nothing (rate limited).
// Advance after time limit. Update should work.
TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedAfterFailedUpdate) {}

// net::ERR_INTERNET_DISCONNECTED skips rate limiting, unlike other errors.
//
// Join an interest group.
// Make interest group update fail with net::ERR_INTERNET_DISCONNECTED.
// Update interest group fails.
// Change update response to different value that will succeed.
// Update succeeds (not rate limited).
TEST_F(AdAuctionServiceImplTest, UpdateNotRateLimitedIfDisconnected) {}

// Nothing crashes if we have a disconnect and a successful update in-flight at
// the same time.
//
// Join 2 interest groups that have the same owner.
//
// Update both interest groups; the first has a delayed response, and the second
// fails with net::ERR_INTERNET_DISCONNECTED. After that, the first update
// response arrives.
//
// Check that the second interest group is not updated. Intentionally don't
// whether the first interest group updates or not.
//
// Nothing should crash.
//
// Afterwards, updating should successfully update both interest groups, without
// rate limiting.
TEST_F(AdAuctionServiceImplTest, DisconnectedAndSuccessInFlightTogether) {}

// Fire off many updates rapidly in a loop. Only one update should happen.
TEST_F(AdAuctionServiceImplTest, UpdateRateLimitedTightLoop) {}

// Test that creates 3 interest groups for different origins, then runs update
// for each origin, with the first update delayed.
//
// The second and third IGs shouldn't get updated until the first is allowed to
// proceed.
TEST_F(AdAuctionServiceImplTest, OnlyOneOriginUpdatesAtATime) {}

// Set the maximum number of parallel updates to 2. Create three interest
// groups, each in origin A, and update origin A's interest groups.
//
// Check that all the interest groups updated.
TEST_F(AdAuctionServiceImplTest, UpdatesInBatches) {}

// Set the maximum number of parallel updates to 2. Create three interest
// groups, each in origin A, and update origin A's interest groups. Make one
// fail, and one timeout.
//
// Check that the interest group that didn't fail or timeout updates
// successfully.
TEST_F(AdAuctionServiceImplTest, UpdatesInBatchesWithFailuresAndTimeouts) {}

// Create an interest group in a.test, and in b.test. Defer the update response
// for a.test, and update a.test and b.test.
//
// Wait the max update round duration, then respond to the a.test update
// request. The a.test interest group should update, but the b.test update
// should be cancelled.
//
// Then, try updating b.test normally, without deferral. The update should
// complete successfully.
TEST_F(AdAuctionServiceImplTest, CancelsLongstandingUpdates) {}

// Like CancelsLongstandingUpdates, but after the cancellation, tries to update
// a different origin, c.test, that succeeds.
//
// NOTE that a.test won't qualify for update until the next day due to rate
// limiting, since it successfully updated.
TEST_F(AdAuctionServiceImplTest, CancelsLongstandingUpdates2) {}

// After a round of updates completes, the round cancellation timer should reset
// so that future updates can proceed.
//
// Create 2 interest groups in different origins. Update the first, then wait
// for more than the max update round duration, then update the second.
//
// Both interest groups should update correctly.
TEST_F(AdAuctionServiceImplTest, UpdateCancellationTimerClearedOnCompletion) {}

// Create 4 interest groups in a.test, and one in b.test.
//
// For the a.test groups, have one succeed immediately, one fail immediately
// (invalid JSON), one be delayed a duration shorter than the max update round
// duration (and succeed), and one delayed a duration more than the max update
// round duration (and succeed).
//
// For the b.test group, let it succeed immediately.
//
// Update all groups, advancing time twice to issue the 2 a.test delayed
// responses.
//
// All a.test updates except the failed update should succeed. The b.test update
// should be cancelled.
//
// Then, try updating b.test normally, without deferral. The update should
// complete successfully.
TEST_F(AdAuctionServiceImplTest, CancelsLongstandingUpdatesComplex) {}

// Add an interest group, and run an ad auction.
TEST_F(AdAuctionServiceImplTest, RunAdAuction) {}

// Add an interest group, and run an ad auction. Seller rejects the bid. Bid
// count should be updated.
TEST_F(AdAuctionServiceImplTest, RunAdAuctionSellerRejectsBid) {}

// Run ad auction when number of urn mappings has reached limit, the action
// should fail.
TEST_F(AdAuctionServiceImplTest,
       RunAdAuctionExceedNumOfUrnMappingsLimitFailsAuction) {}

// Runs an auction, and expects that the interest group that participated in
// the auction gets updated after the auction completes.
//
// Create an interest group. Run an auction with that interest group.
//
// The interest group should be updated after the auction completes.
TEST_F(AdAuctionServiceImplTest, UpdatesInterestGroupsAfterSuccessfulAuction) {}

// Like UpdatesInterestGroupsAfterSuccessfulAuction but
// kFledgeDelayPostAuctionInterestGroupUpdate is enabled.
TEST_F(AdAuctionServiceImplTest,
       UpdatesInterestGroupsAfterSuccessfulAuctionDelayedUpdate) {}

// Like UpdatesInterestGroupsAfterSuccessfulAuction, but the auction fails
// because the scoring script always returns 0. The interest group should still
// update.
TEST_F(AdAuctionServiceImplTest, UpdatesInterestGroupsAfterFailedAuction) {}

// Like UpdatesInterestGroupsAfterFailedAuction, but the auction fails because
// the decision script can't be loaded. The interest group still updates.
TEST_F(AdAuctionServiceImplTest,
       UpdatesInterestGroupsAfterFailedAuctionMissingScript) {}

// Trigger a post auction update, but block it via ContentBrowserClient policy.
// The update shouldn't happen.
TEST_F(AdAuctionServiceImplTest,
       UpdatesInterestGroupsAfterAuctionBlockedByContentBrowserClient) {}

// Like UpdatesInterestGroupsAfterAuction, but with a component auction.
//
// Create 2 interest groups, each in different origins, A and C (we can't use B
// because AllowInterestGroupContentBrowserClient doesn't allow B interest
// groups to participate in A auctions). Run a component auction where A is a
// buyer in one component auction, and C is a buyer in another component
// auction. A wins.
//
// Both interest groups should be updated after the auction completes.
TEST_F(AdAuctionServiceImplTest,
       UpdatesInterestGroupsAfterComponentAuctionWithWinner) {}

// Like UpdatesInterestGroupsAfterComponentAuctionWithWinner, but there's no
// winner, since the decision script scores every bid as 0.
//
// All participating interest groups should still be updated.
TEST_F(AdAuctionServiceImplTest,
       UpdatesInterestGroupsAfterComponentAuctionWithNoWinner) {}

// Like UpdatesInterestGroupsAfterSuccessfulAuction, but neither the interest
// group nor the update have any ads.
TEST_F(AdAuctionServiceImplTest, UpdatesInterestGroupsAfterAuctionNoAds) {}

TEST_F(AdAuctionServiceImplTest, UpdateSupportsDeprecatedNames) {}

TEST_F(AdAuctionServiceImplTest, UpdateIgnoresUnknownEnumFields) {}

TEST_F(AdAuctionServiceImplTest, UpdateRenamedFields) {}

class AdAuctionServiceImplUpdateIfOlderThanTest
    : public AdAuctionServiceImplTest {};

// Join and manually update an interest group so that it's not eligible to
// update again for the successful update period. Advance a small amount of
// time. Then, run an auction with trusted bidding signals that specify an
// updateIfOlderThanMs greater than the time advanced, but less than the
// successful update period. The group should update successfully. Then, try
// updating again without advancing time -- the update should fail.
TEST_F(AdAuctionServiceImplUpdateIfOlderThanTest, OlderThan) {}

// Like AdAuctionServiceImplUpdateIfOlderThanTest.OlderThan, but we don't
// advance time, so the updateIfOlderThanMs directive takes no effect (since
// the group has been updated too recently -- it's not "older than"), so the
// post-auction update doesn't happen.
TEST_F(AdAuctionServiceImplUpdateIfOlderThanTest, NotOlderThan) {}

// Like AdAuctionServiceImplUpdateIfOlderThanTest.OlderThan, but with a
// updateIfOlderThanMs that's under 10 minutes. This time will be clamped to 10
// minutes.
TEST_F(AdAuctionServiceImplUpdateIfOlderThanTest, Clamped10Min) {}

// When sending reports, the next report request is feteched after the previous
// report request completed (`max_active_report_requests_` is set to 1 in this
// test). Reporting should continue even after the page navigated away. Timeout
// works for report requests.
TEST_F(AdAuctionServiceImplTest, SendReports) {}

// Check that reports aren't sent until the URN to URL callback is invoked.
TEST_F(AdAuctionServiceImplTest, SendReportsWaitsForCallback) {}

// Make sure the report-sending logic can handle two auctions with a delay
// between them. This is regression test for https://crbug.com/1379234.
TEST_F(AdAuctionServiceImplTest, SendReportsTwoAuctionsWithDelay) {}

// Test that if one auction completes after another's reports have been sent,
// but before the report interval has elapsed, its requests still respect the
// report interval.
TEST_F(AdAuctionServiceImplTest, SendReportsTwoAuctionsRespectsReportInterval) {}

// Similar to SendReports() above, but with one report request failed instead of
// timed out. Following report requests should still be send after previous ones
// failed.
TEST_F(AdAuctionServiceImplTest, SendReportsOneReportFailed) {}

// Checks that all reporting in the pending queue gets canceled if the reporting
// queue max length is exceeded at the time of enqueuing a new set of reports.
TEST_F(AdAuctionServiceImplTest, ReportQueueMaxLength) {}

TEST_F(AdAuctionServiceImplTest, SendReportsMaxReportRoundDuration) {}

// Checks that extra real time reports will be dropped if it needs to be rate
// limited. Future real time reports can still be sent if it no longer needs to
// be rate limited.
TEST_F(AdAuctionServiceImplTest, RealTimeReportRateLimit) {}

// Check that running reporting worklets doesn't block auction completion. To do
// this, the bidding script is set to be deferred. The auction is started, and
// the bid script is supplied. Then the auction completes. This should trigger
// reloading the bidding script to call reportWin(). The second time, a bidding
// script is not supplied. The fact that the auction completes despite the
// second stalled load verifies that running reporting scripts does not block
// completion of an auction. The AdAuctionServiceImpl is destroyed before
// the bidding URL is downloaded the second time, which provides some test
// coverage of that as well.
TEST_F(AdAuctionServiceImplTest, ReportingWorkletsDoNotBlockCompletion) {}

// Run several auctions, some of which have a winner, and some of which do
// not. Verify that the auction result UMA is recorded correctly.
TEST_F(AdAuctionServiceImplTest,
       AddInterestGroupRunAuctionVerifyResultMetrics) {}

// Like AddInterestGroupRunAuctionVerifyResultMetrics, but with a smaller number
// of auctions -- this verifies that metrics (especially the bit metrics) are
// reported correctly in this scenario.
TEST_F(AdAuctionServiceImplTest,
       AddInterestGroupRunAuctionVerifyResultMetricsFewAuctions) {}

// Like AddInterestGroupRunAuctionVerifyResultMetricsFewAuctions, but with no
// auctions.
TEST_F(AdAuctionServiceImplTest,
       AddInterestGroupRunAuctionVerifyResultMetricsNoAuctions) {}

// The feature parameter that controls the interest group limit should default
// to off. We both check the parameter is off, and we run a number of auctions
// and make sure they all succeed.
TEST_F(AdAuctionServiceImplTest, NoInterestLimitByDefault) {}

// CreateAdRequest should reject if we have an empty config.
TEST_F(AdAuctionServiceImplTest, CreateAdRequestRejectsEmptyConfigRequest) {}

// CreateAdRequest should reject if we have an otherwise okay request but our
// request URL is not using HTTPS.
TEST_F(AdAuctionServiceImplTest, CreateAdRequestRejectsHttpUrls) {}

// CreateAdRequest should reject if we have an otherwise okay request but no ad
// properties.
TEST_F(AdAuctionServiceImplTest, CreateAdRequestRejectsMissingAds) {}

// CreateAdRequest should reject if we have an otherwise okay request but
// include an HTTP fallback URL.
TEST_F(AdAuctionServiceImplTest, CreateAdRequestRejectsHttpFallback) {}

// An empty config should be treated as a bad message.
TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsEmptyConfig) {}

// An HTTP decision logic URL should be treated as a bad message.
TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsHTTPDecisionUrl) {}

// An empty GUID should be treated as a bad message.
TEST_F(AdAuctionServiceImplTest, FinalizeAdRejectsMissingGuid) {}

TEST_F(AdAuctionServiceImplTest, SetPriorityAdjustsPriority) {}

class AdAuctionServiceImplNumAuctionLimitTest
    : public AdAuctionServiceImplTest {};

// Like AddInterestGroupRunAuctionVerifyResultMetrics, but with enforcement
// limiting the number of auctions.
TEST_F(AdAuctionServiceImplNumAuctionLimitTest,
       AddInterestGroupRunAuctionWithNumAuctionLimits) {}

TEST_F(AdAuctionServiceImplNumAuctionLimitTest,
       AddInterestGroupRunAuctionStartManyAuctionsInParallel) {}

class AdAuctionServiceImplRestrictedPermissionsPolicyTest
    : public AdAuctionServiceImplTest {};

// Permissions policy feature join-ad-interest-group is enabled by default for
// top level frames under restricted permissions policy, so interest group
// APIs should succeed.
TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
       APICallsFromTopFrame) {}

// Like APICallsFromTopFrame, but API calls happens in a same site iframe
// instead of a top frame.
TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
       APICallsFromSameSiteIframe) {}

// Permissions policy feature join-ad-interest-group is disabled by default for
// cross site iframes under restricted permissions policy, so interest group
// APIs should not work, and result in the pipe being closed.
TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
       APICallsFromCrossSiteIFrame) {}

class AdAuctionServiceImplBiddingAndScoringDebugReportingAPIEnabledTest
    : public AdAuctionServiceImplTest {};

// Allowing sending multiple reports in parallel, instead of only allowing
// sending one at a time.
TEST_F(AdAuctionServiceImplBiddingAndScoringDebugReportingAPIEnabledTest,
       SendReportsMaximumActive) {}

class AdAuctionServiceImplEventReportingAttestationTest
    : public AdAuctionServiceImplBiddingAndScoringDebugReportingAPIEnabledTest {};

// Since all origins are attested in the allowlist, all reports are successfully
// sent.
TEST_F(AdAuctionServiceImplEventReportingAttestationTest, AllAllowed) {}

// Like EventReportingAttestationAllAllowed, but only some of the report
// destination origins are allowed to receive reports.
TEST_F(AdAuctionServiceImplEventReportingAttestationTest, SomeAllowed) {}

// Like EventReportingAttestationAllAllowed, but none of the report destination
// origins are allowed to receive reports.
TEST_F(AdAuctionServiceImplEventReportingAttestationTest, NoneAllowed) {}

// In some scenarios, the `PageImpl` used in auction may change in middle of the
// auction. See MainFrameDocumentAssociatedDataChangesOnSameSiteNavigation in
// SitePerProcessBrowserTest for an example. When this happens, auction must be
// able to detect the change and abort the auction.
//
// See more info about this issue in crbug.com/1422301.
//
// TODO(crbug.com/40615943): Once RenderDocument is launched, this issue will be
// resolved, remove this test.
TEST_F(AdAuctionServiceImplTest, PageImplChangedDuringAuction) {}

// Similar to PageImplChangedDuringAuction, but the `PageImpl` is changed before
// auction starts.
//
// TODO(crbug.com/40615943): Once RenderDocument is launched, remove this test.
TEST_F(AdAuctionServiceImplTest, PageImplChangedBeforeAuction) {}

// The weak pointer to the auction initiator page should be reset upon a cross-
// document navigation.
// TODO(crbug.com/40615943): Once RenderDocument is launched, remove this test.
TEST_F(AdAuctionServiceImplTest,
       ResetAuctionInitiatorPageOnCrossDocumentNavigation) {}

// The weak pointer to the auction initiator page should not be reset upon a
// same-document navigation.
// TODO(crbug.com/40615943): Once RenderDocument is launched, remove this test.
TEST_F(AdAuctionServiceImplTest,
       DoNotResetAuctionInitiatorPageOnSameDocumentNavigation) {}

class AdAuctionServiceImplSharedStorageEnabledTest
    : public AdAuctionServiceImplTest {};

TEST_F(AdAuctionServiceImplSharedStorageEnabledTest, SharedStorageWrite) {}

TEST_F(AdAuctionServiceImplSharedStorageEnabledTest,
       ScriptErrorAfterSharedStorageWrite) {}

TEST_F(AdAuctionServiceImplSharedStorageEnabledTest,
       SharedStoragePermissionsPolicyDisallowsSellerOrigin) {}

class AdAuctionServiceImplSharedStorageDisabledTest
    : public AdAuctionServiceImplTest {};

TEST_F(AdAuctionServiceImplSharedStorageDisabledTest, SharedStorageNotDefined) {}

class AdAuctionServiceImplPrivateAggregationEnabledTest
    : public AdAuctionServiceImplTest {};

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationReportsForwarded) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationPermissionsPolicyDisallowsSellerOrigin) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationPermissionsPolicyDisallowsBidderOrigin) {}

class PrivateAggregationUseCounterContentBrowserClient
    : public AllowInterestGroupContentBrowserClient {};

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationUseCountersLogged) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationExtensionsUseCounterNotLoggedOnContributeToHistogram) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationEnableDebugModeUseCounterLogged) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationFilteringIdUseCounterLogged) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationFilteringIdUseCounterNotLoggedIfFeatureDisabled) {}

// TODO(crbug.com/40236382): Update when use counter coverage is improved.
TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationUseCountersNotLoggedOnFailedInvocation) {}

// Tests that the use counters are logged only once, even when the API is used
// multiple times (and different functions are used).
TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationUseCountersLoggedOnlyOnce) {}

TEST_F(AdAuctionServiceImplPrivateAggregationEnabledTest,
       PrivateAggregationReportsForwardedWithCoordinator) {}

class AdAuctionServiceImplPrivateAggregationDisabledTest
    : public AdAuctionServiceImplTest {};

TEST_F(AdAuctionServiceImplPrivateAggregationDisabledTest,
       PrivateAggregationNotExposed) {}

TEST_F(AdAuctionServiceImplPrivateAggregationDisabledTest,
       PrivateAggregationUseCounterNotLogged) {}

class AdAuctionServiceImplKAnonTest
    : public AdAuctionServiceImplTest,
      public ::testing::WithParamInterface<
          auction_worklet::mojom::KAnonymityBidMode> {};

// Add an interest group with a non-k-anonymous ad and run an ad auction.
TEST_P(AdAuctionServiceImplKAnonTest, RunAdAuctionNotKAnon) {}

INSTANTIATE_TEST_SUITE_P();

class AdAuctionServiceImplBAndATest : public AdAuctionServiceImplTest {};

// Expect bad mojo message if we use an invalid coordinator origin. The
// coordinator origin must be secure.
TEST_F(AdAuctionServiceImplTest, HandlesInvalidCoordinatorOrigin) {}

// Expect bad mojo message if we use an unsupported coordinator origin. The
// coordinator origin must match one of the ones in our list.
TEST_F(AdAuctionServiceImplTest, HandlesUnsupportedCoordinatorOrigin) {}

// Test that interest_group_manager serialize the blob correctly.
TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlob) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithNoGroups) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithEmptyGroup) {}

TEST_F(AdAuctionServiceImplTest, SerializesMultipleOwnersAuctionBlob) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithoutDebugReporting) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobDebugReportingInLockout) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithDebugToken) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithOmitAds) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithFullAds) {}

TEST_F(AdAuctionServiceImplTest,
       SerializesAuctionBlobWithNoUserBiddingSignalsAndOmitAds) {}

TEST_F(AdAuctionServiceImplTest, SerializesAuctionBlobWithPerBuyerConfig) {}

TEST_F(AdAuctionServiceImplBAndATest, JoinInterestGroupPrefetchesKeys) {}

TEST_F(AdAuctionServiceImplBAndATest, EncryptsPayload) {}

TEST_F(AdAuctionServiceImplBAndATest, EncryptsPayloadWithDebugReportLockout) {}

TEST_F(AdAuctionServiceImplBAndATest, OriginNotAllowed) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuction) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuctionNoBids) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuctionServerError) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuctionWithoutCustomMediaType) {}

TEST_F(AdAuctionServiceImplBAndATest, HandlesBadResponseForBAndAAuction) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionInSingleSeller) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuctionAsMultiseller) {}

TEST_F(AdAuctionServiceImplBAndATest, RunMultiSellerBAndAAuctionWrongSeller) {}

TEST_F(AdAuctionServiceImplBAndATest, RunMultiSellerBAndAAuction) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionWithPrivateAggregation) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunBAndAAuctionWithPrivateAggregationServerFiltered) {}

// PAgg requests from B&A are correctly forwarded respecting aggregation
// coordinators.
TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionWithPrivateAggregationCoordinator) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionWithOtherPromisesResolveLater) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionWithOtherPromisesResolveFirst) {}

TEST_F(AdAuctionServiceImplBAndATest, RunMultiSellerBAndAAuctionWithLocal) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionWithWinningLocal) {}

TEST_F(AdAuctionServiceImplBAndATest, GetInterestGroupAdAuctionDataNoKeys) {}

TEST_F(AdAuctionServiceImplBAndATest,
       GetInterestGroupAdAuctionDataNoKeysAndNoInterestGroups) {}

TEST_F(AdAuctionServiceImplBAndATest,
       GetInterestGroupAdAuctionDataKeysAndNoInterestGroups) {}

TEST_F(AdAuctionServiceImplBAndATest,
       GetInterestGroupAdAuctionData_KeysLoadBeforeIGs) {}

TEST_F(AdAuctionServiceImplBAndATest,
       GetInterestGroupAdAuctionData_IGsLoadBeforeKeys) {}

TEST_F(AdAuctionServiceImplBAndATest,
       HandlesMultipleGetInterestGroupAdAuctionDataInARow) {}

TEST_F(AdAuctionServiceImplBAndATest,
       HandlesMultipleEmptyGetInterestGroupAdAuctionDataInARow) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionMatchedCurrency) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionMismatchSellerCurrency) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionMismatchAllSellerCurrency) {}

TEST_F(AdAuctionServiceImplBAndATest,
       RunMultiSellerBAndAAuctionMismatchPerSellerCurrency) {}

TEST_F(AdAuctionServiceImplBAndATest, RunServerMultiSellerBAndAAuction) {}

TEST_F(AdAuctionServiceImplBAndATest, RunBAndAAuctionWithBid) {}

class AdAuctionServiceImplBAndAKAnonTest
    : public AdAuctionServiceImplBAndATest {};

TEST_F(AdAuctionServiceImplBAndAKAnonTest, RunBAndAAuctionWithKAnon) {}

class AdAuctionServiceImplFacilitatedTestingTest
    : public AdAuctionServiceImplTest {};

TEST_F(AdAuctionServiceImplFacilitatedTestingTest,
       RunAdAuctionServesDeprecationLabelsInKVRequest) {}

}  // namespace content