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

#include "net/base/network_anonymization_key.h"

#include <optional>

#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/unguessable_token.h"
#include "base/values.h"
#include "net/base/features.h"
#include "net/base/network_isolation_key.h"
#include "net/base/network_isolation_partition.h"
#include "net/base/schemeful_site.h"
#include "network_anonymization_key.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/url_util.h"

namespace net {

class NetworkAnonymizationKeyTest : public testing::Test {
 protected:
  const SchemefulSite kTestSiteA = SchemefulSite(GURL("http://a.test/"));
  const SchemefulSite kTestSiteB = SchemefulSite(GURL("http://b.test/"));
  const SchemefulSite kDataSite = SchemefulSite(GURL("data:foo"));
  const base::UnguessableToken kNonce = base::UnguessableToken::Create();
};

TEST_F(NetworkAnonymizationKeyTest, CreateFromNetworkIsolationKey) {
  SchemefulSite site_a = SchemefulSite(GURL("http://a.test/"));
  SchemefulSite site_b = SchemefulSite(GURL("http://b.test/"));
  SchemefulSite opaque = SchemefulSite(url::Origin());
  base::UnguessableToken nik_nonce = base::UnguessableToken::Create();

  NetworkIsolationKey populated_cross_site_nik(site_a, site_b, nik_nonce);
  NetworkIsolationKey populated_same_site_nik(site_a, site_a, nik_nonce);
  NetworkIsolationKey populated_same_site_opaque_nik(opaque, opaque, nik_nonce);
  NetworkIsolationKey populated_same_site_nik_network_partition(
      site_a, site_a, /*nonce=*/std::nullopt,
      NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  NetworkIsolationKey empty_nik;

  NetworkAnonymizationKey nak_from_same_site_nik =
      NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
          populated_same_site_nik);
  NetworkAnonymizationKey nak_from_cross_site_nik =
      NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
          populated_cross_site_nik);
  NetworkAnonymizationKey nak_from_same_site_opaque_nik =
      NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
          populated_same_site_opaque_nik);
  NetworkAnonymizationKey nak_from_same_site_nik_network_partition =
      NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
          populated_same_site_nik_network_partition);
  NetworkAnonymizationKey nak_from_empty_nik =
      NetworkAnonymizationKey::CreateFromNetworkIsolationKey(empty_nik);

  // NAKs created when there is no top frame site on the NIK should create an
  // empty NAK.
  EXPECT_TRUE(nak_from_empty_nik.IsEmpty());

  // Top site should be populated correctly.
  EXPECT_EQ(nak_from_same_site_nik.GetTopFrameSite(), site_a);
  EXPECT_EQ(nak_from_cross_site_nik.GetTopFrameSite(), site_a);
  EXPECT_EQ(nak_from_same_site_opaque_nik.GetTopFrameSite(), opaque);
  EXPECT_EQ(nak_from_same_site_nik_network_partition.GetTopFrameSite(), site_a);

  // Nonce should be populated correctly.
  EXPECT_EQ(nak_from_same_site_nik.GetNonce(), nik_nonce);
  EXPECT_EQ(nak_from_cross_site_nik.GetNonce(), nik_nonce);
  EXPECT_EQ(nak_from_same_site_opaque_nik.GetNonce(), nik_nonce);
  EXPECT_EQ(nak_from_same_site_nik_network_partition.GetNonce(), std::nullopt);

  // Is cross site boolean should be populated correctly.
  EXPECT_TRUE(nak_from_same_site_nik.IsSameSite());
  EXPECT_TRUE(nak_from_cross_site_nik.IsCrossSite());
  EXPECT_TRUE(nak_from_same_site_opaque_nik.IsSameSite());
  EXPECT_TRUE(nak_from_same_site_nik_network_partition.IsSameSite());

  // NetworkIsolationPartition should be populated correctly.
  EXPECT_EQ(nak_from_same_site_nik.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);
  EXPECT_EQ(nak_from_cross_site_nik.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);
  EXPECT_EQ(nak_from_same_site_opaque_nik.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);
  EXPECT_EQ(
      nak_from_same_site_nik_network_partition.network_isolation_partition(),
      NetworkIsolationPartition::kProtectedAudienceSellerWorklet);

  // Double-keyed + cross site bit NAKs created from different third party
  // cross site contexts should be the different.
  EXPECT_FALSE(nak_from_same_site_nik == nak_from_cross_site_nik);
}

TEST_F(NetworkAnonymizationKeyTest, CreateSameSite) {
  SchemefulSite site = SchemefulSite(GURL("http://a.test/"));
  SchemefulSite opaque = SchemefulSite(url::Origin());
  NetworkAnonymizationKey key;

  key = NetworkAnonymizationKey::CreateSameSite(site);
  EXPECT_EQ(key.GetTopFrameSite(), site);
  EXPECT_FALSE(key.GetNonce().has_value());
  EXPECT_TRUE(key.IsSameSite());

  key = NetworkAnonymizationKey::CreateSameSite(opaque);
  EXPECT_EQ(key.GetTopFrameSite(), opaque);
  EXPECT_FALSE(key.GetNonce().has_value());
  EXPECT_TRUE(key.IsSameSite());
}

TEST_F(NetworkAnonymizationKeyTest, CreateCrossSite) {
  SchemefulSite site = SchemefulSite(GURL("http://a.test/"));
  SchemefulSite opaque = SchemefulSite(url::Origin());
  NetworkAnonymizationKey key;

  key = NetworkAnonymizationKey::CreateCrossSite(site);
  EXPECT_EQ(key.GetTopFrameSite(), site);
  EXPECT_FALSE(key.GetNonce().has_value());
  EXPECT_TRUE(key.IsCrossSite());

  key = NetworkAnonymizationKey::CreateCrossSite(opaque);
  EXPECT_EQ(key.GetTopFrameSite(), opaque);
  EXPECT_FALSE(key.GetNonce().has_value());
  EXPECT_TRUE(key.IsCrossSite());
}

TEST_F(NetworkAnonymizationKeyTest, CreateFromFrameSite) {
  SchemefulSite site_a = SchemefulSite(GURL("http://a.test/"));
  SchemefulSite site_b = SchemefulSite(GURL("http://b.test/"));
  SchemefulSite opaque_1 = SchemefulSite(url::Origin());
  SchemefulSite opaque_2 = SchemefulSite(url::Origin());
  base::UnguessableToken nonce = base::UnguessableToken::Create();

  NetworkAnonymizationKey nak_from_same_site =
      NetworkAnonymizationKey::CreateFromFrameSite(
          site_a, site_a, nonce,
          NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  NetworkAnonymizationKey nak_from_cross_site =
      NetworkAnonymizationKey::CreateFromFrameSite(
          site_a, site_b, nonce,
          NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  NetworkAnonymizationKey nak_from_same_site_opaque =
      NetworkAnonymizationKey::CreateFromFrameSite(opaque_1, opaque_1, nonce);
  NetworkAnonymizationKey nak_from_cross_site_opaque =
      NetworkAnonymizationKey::CreateFromFrameSite(opaque_1, opaque_2, nonce);

  // Top site should be populated correctly.
  EXPECT_EQ(nak_from_same_site.GetTopFrameSite(), site_a);
  EXPECT_EQ(nak_from_cross_site.GetTopFrameSite(), site_a);
  EXPECT_EQ(nak_from_same_site_opaque.GetTopFrameSite(), opaque_1);
  EXPECT_EQ(nak_from_cross_site_opaque.GetTopFrameSite(), opaque_1);

  // Nonce should be populated correctly.
  EXPECT_EQ(nak_from_same_site.GetNonce(), nonce);
  EXPECT_EQ(nak_from_cross_site.GetNonce(), nonce);
  EXPECT_EQ(nak_from_same_site_opaque.GetNonce(), nonce);
  EXPECT_EQ(nak_from_cross_site_opaque.GetNonce(), nonce);

  // Is cross site boolean should be populated correctly.
  EXPECT_TRUE(nak_from_same_site.IsSameSite());
  EXPECT_TRUE(nak_from_cross_site.IsCrossSite());
  EXPECT_TRUE(nak_from_same_site_opaque.IsSameSite());
  EXPECT_TRUE(nak_from_cross_site_opaque.IsCrossSite());

  // NetworkIsolationPartition should be populated correctly.
  EXPECT_EQ(nak_from_same_site.network_isolation_partition(),
            NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  EXPECT_EQ(nak_from_cross_site.network_isolation_partition(),
            NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  EXPECT_EQ(nak_from_same_site_opaque.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);
  EXPECT_EQ(nak_from_cross_site_opaque.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);

  // NAKs created from different third party cross site contexts should be
  // different.
  EXPECT_NE(nak_from_same_site, nak_from_cross_site);
  EXPECT_NE(nak_from_same_site_opaque, nak_from_cross_site_opaque);
}

TEST_F(NetworkAnonymizationKeyTest, IsEmpty) {
  NetworkAnonymizationKey empty_key;
  NetworkAnonymizationKey populated_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false,
                                               /*nonce=*/std::nullopt);

  EXPECT_TRUE(empty_key.IsEmpty());
  EXPECT_FALSE(populated_key.IsEmpty());
}

TEST_F(NetworkAnonymizationKeyTest, CreateTransient) {
  NetworkAnonymizationKey transient_key1 =
      NetworkAnonymizationKey::CreateTransient();
  NetworkAnonymizationKey transient_key2 =
      NetworkAnonymizationKey::CreateTransient();

  EXPECT_TRUE(transient_key1.IsTransient());
  EXPECT_TRUE(transient_key2.IsTransient());
  EXPECT_FALSE(transient_key1 == transient_key2);
}

TEST_F(NetworkAnonymizationKeyTest, IsTransient) {
  NetworkAnonymizationKey empty_key;
  NetworkAnonymizationKey populated_key =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/false,
          /*nonce=*/std::nullopt);
  NetworkAnonymizationKey data_top_frame_key =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kDataSite,
          /*is_cross_site=*/false,
          /*nonce=*/std::nullopt);
  NetworkAnonymizationKey populated_key_with_nonce =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/false, base::UnguessableToken::Create());
  NetworkAnonymizationKey data_frame_key =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/false,
          /*nonce=*/std::nullopt);

  NetworkAnonymizationKey from_create_transient =
      NetworkAnonymizationKey::CreateTransient();

  EXPECT_TRUE(empty_key.IsTransient());
  EXPECT_FALSE(populated_key.IsTransient());
  EXPECT_TRUE(data_top_frame_key.IsTransient());
  EXPECT_TRUE(populated_key_with_nonce.IsTransient());
  EXPECT_TRUE(from_create_transient.IsTransient());

  NetworkAnonymizationKey populated_double_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false,
                                               /*nonce=*/std::nullopt);
  EXPECT_FALSE(data_frame_key.IsTransient());
  EXPECT_FALSE(populated_double_key.IsTransient());
}

TEST_F(NetworkAnonymizationKeyTest, IsFullyPopulated) {
  NetworkAnonymizationKey empty_key;
  NetworkAnonymizationKey populated_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false,
                                               /*nonce=*/std::nullopt);
  EXPECT_TRUE(populated_key.IsFullyPopulated());
  EXPECT_FALSE(empty_key.IsFullyPopulated());
  NetworkAnonymizationKey empty_frame_site_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false,
                                               /*nonce=*/std::nullopt);
  EXPECT_TRUE(empty_frame_site_key.IsFullyPopulated());
}

TEST_F(NetworkAnonymizationKeyTest, Getters) {
  NetworkAnonymizationKey key = NetworkAnonymizationKey::CreateFromParts(
      /*top_frame_site=*/kTestSiteA,
      /*is_cross_site=*/true, kNonce, NetworkIsolationPartition::kGeneral);

  EXPECT_EQ(key.GetTopFrameSite(), kTestSiteA);
  EXPECT_EQ(key.GetNonce(), kNonce);
  EXPECT_EQ(key.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);

  EXPECT_TRUE(key.IsCrossSite());
}

TEST_F(NetworkAnonymizationKeyTest, ToDebugString) {
  NetworkAnonymizationKey key = NetworkAnonymizationKey::CreateFromParts(
      /*top_frame_site=*/kTestSiteA,
      /*is_cross_site=*/true);
  NetworkAnonymizationKey empty_key;

  // `is_cross_site` holds the value the key is created with.
  std::string double_key_with_cross_site_flag_expected_string_value =
      kTestSiteA.GetDebugString() + " cross_site";
  EXPECT_EQ(key.ToDebugString(),
            double_key_with_cross_site_flag_expected_string_value);
  EXPECT_EQ(empty_key.ToDebugString(), "null");
}

TEST_F(NetworkAnonymizationKeyTest,
       ToDebugStringWithNonceAndNonGeneralPartition) {
  NetworkAnonymizationKey key = NetworkAnonymizationKey::CreateFromParts(
      /*top_frame_site=*/kTestSiteA,
      /*is_cross_site=*/true, kNonce,
      NetworkIsolationPartition::kProtectedAudienceSellerWorklet);

  // `is_cross_site` holds the value the key is created with.
  std::string double_key_with_cross_site_flag_expected_string_value =
      kTestSiteA.GetDebugString() + " cross_site (with nonce " +
      kNonce.ToString() + ") (protected audience seller worklet partition)";
  EXPECT_EQ(key.ToDebugString(),
            double_key_with_cross_site_flag_expected_string_value);
}

TEST_F(NetworkAnonymizationKeyTest, Equality) {
  NetworkAnonymizationKey key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false, kNonce);
  NetworkAnonymizationKey key_duplicate =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false, kNonce);
  EXPECT_TRUE(key == key_duplicate);
  EXPECT_FALSE(key != key_duplicate);
  EXPECT_FALSE(key < key_duplicate);

  NetworkAnonymizationKey key_cross_site =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/true, kNonce);

  // The `is_cross_site` flag changes the NAK.
  EXPECT_FALSE(key == key_cross_site);
  EXPECT_TRUE(key != key_cross_site);
  EXPECT_TRUE(key < key_cross_site);

  NetworkAnonymizationKey key_no_nonce =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false,
                                               /*nonce=*/std::nullopt);
  EXPECT_FALSE(key == key_no_nonce);
  EXPECT_TRUE(key != key_no_nonce);
  EXPECT_FALSE(key < key_no_nonce);

  NetworkAnonymizationKey key_different_nonce =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/false,
          /*nonce=*/base::UnguessableToken::Create());
  EXPECT_FALSE(key == key_different_nonce);
  EXPECT_TRUE(key != key_different_nonce);

  NetworkAnonymizationKey key_different_frame_site =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/false, kNonce);

  EXPECT_TRUE(key == key_different_frame_site);
  EXPECT_FALSE(key != key_different_frame_site);
  EXPECT_FALSE(key < key_different_frame_site);

  NetworkAnonymizationKey key_different_top_level_site =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteB,
          /*is_cross_site=*/false, kNonce);
  EXPECT_FALSE(key == key_different_top_level_site);
  EXPECT_TRUE(key != key_different_top_level_site);
  EXPECT_TRUE(key < key_different_top_level_site);

  NetworkAnonymizationKey empty_key;
  NetworkAnonymizationKey empty_key_duplicate;
  EXPECT_TRUE(empty_key == empty_key_duplicate);
  EXPECT_FALSE(empty_key != empty_key_duplicate);
  EXPECT_FALSE(empty_key < empty_key_duplicate);

  EXPECT_FALSE(empty_key == key);
  EXPECT_TRUE(empty_key != key);
  EXPECT_TRUE(empty_key < key);
}

TEST_F(NetworkAnonymizationKeyTest, ValueRoundTripCrossSite) {
  const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
  NetworkAnonymizationKey original_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/true);
  base::Value value;
  ASSERT_TRUE(original_key.ToValue(&value));

  // Fill initial value with opaque data, to make sure it's overwritten.
  NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
  EXPECT_EQ(original_key, from_value_key);
}

TEST_F(NetworkAnonymizationKeyTest, ValueRoundTripSameSite) {
  const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
  NetworkAnonymizationKey original_key =
      NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                               /*is_cross_site=*/false);
  base::Value value;
  ASSERT_TRUE(original_key.ToValue(&value));

  // Fill initial value with opaque data, to make sure it's overwritten.
  NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
  EXPECT_EQ(original_key, from_value_key);
}

TEST_F(NetworkAnonymizationKeyTest, TransientValueRoundTrip) {
  const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
  NetworkAnonymizationKey original_key =
      NetworkAnonymizationKey::CreateTransient();
  base::Value value;
  ASSERT_FALSE(original_key.ToValue(&value));
}

TEST_F(NetworkAnonymizationKeyTest, EmptyValueRoundTrip) {
  const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
  NetworkAnonymizationKey original_key;
  base::Value value;
  ASSERT_TRUE(original_key.ToValue(&value));

  // Fill initial value with opaque data, to make sure it's overwritten.
  NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
  EXPECT_EQ(original_key, from_value_key);
}

TEST_F(NetworkAnonymizationKeyTest,
       ValueRoundTripWithNonGeneralNetworkPartition) {
  NetworkAnonymizationKey original_key =
      NetworkAnonymizationKey::CreateFromParts(
          /*top_frame_site=*/kTestSiteA,
          /*is_cross_site=*/true,
          /*nonce=*/std::nullopt,
          NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  base::Value value;
  ASSERT_TRUE(original_key.ToValue(&value));

  // Fill initial value with opaque data, to make sure it's overwritten.
  NetworkAnonymizationKey from_value_key;
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
  EXPECT_EQ(original_key, from_value_key);
}

TEST_F(NetworkAnonymizationKeyTest,
       TransientValueRoundTripWithNonGeneralNetworkPartition) {
  NetworkAnonymizationKey key = NetworkAnonymizationKey::CreateFromParts(
      /*top_frame_site=*/kTestSiteA,
      /*is_cross_site=*/true,
      /*nonce=*/base::UnguessableToken::Create(),
      NetworkIsolationPartition::kProtectedAudienceSellerWorklet);
  base::Value value;
  ASSERT_FALSE(key.ToValue(&value));
}

TEST_F(NetworkAnonymizationKeyTest,
       FromValueOnlyAcceptsValidNetworkIsolationPartitionValues) {
  base::Value value;
  ASSERT_TRUE(NetworkAnonymizationKey::CreateFromParts(
                  /*top_frame_site=*/kTestSiteA,
                  /*is_cross_site=*/true)
                  .ToValue(&value));

  NetworkAnonymizationKey new_nak = NetworkAnonymizationKey();

  // The NetworkIsolationPartition value should be an int.
  base::Value::List& list = value.GetList();
  list[2] = base::Value("not_an_int_value");
  EXPECT_FALSE(NetworkAnonymizationKey::FromValue(value, &new_nak));

  // Don't accept a negative value.
  list[2] = base::Value(-1);
  EXPECT_FALSE(NetworkAnonymizationKey::FromValue(value, &new_nak));

  // Don't accept a value too high.
  list[2] = base::Value(
      base::strict_cast<int32_t>(NetworkIsolationPartition::kMaxValue) + 1);
  EXPECT_FALSE(NetworkAnonymizationKey::FromValue(value, &new_nak));

  // Accept the max value of NetworkIsolationPartition.
  list[2] = base::Value(
      base::strict_cast<int32_t>(NetworkIsolationPartition::kMaxValue));
  ASSERT_TRUE(NetworkAnonymizationKey::FromValue(value, &new_nak));
  EXPECT_EQ(new_nak.network_isolation_partition(),
            NetworkIsolationPartition::kMaxValue);

  // Accept the min value of NetworkIsolationPartition.
  list[2] = base::Value(0);
  ASSERT_TRUE(NetworkAnonymizationKey::FromValue(value, &new_nak));
  EXPECT_EQ(new_nak.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);

  // Accept a missing 3rd value.
  list.resize(list.size() - 1);
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &new_nak));
  EXPECT_EQ(new_nak.network_isolation_partition(),
            NetworkIsolationPartition::kGeneral);
}

TEST(NetworkAnonymizationKeyFeatureShiftTest,
     ValueRoundTripKeySchemeMissmatch) {
  base::test::ScopedFeatureList scoped_feature_list_;
  const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
  const SchemefulSite kTestSiteA = SchemefulSite(GURL("http://a.test/"));
  const SchemefulSite kTestSiteB = SchemefulSite(GURL("http://b.test/"));
  NetworkAnonymizationKey expected_failure_nak = NetworkAnonymizationKey();

  // Create a cross site double key + cross site flag NetworkAnonymizationKey.
  NetworkAnonymizationKey original_cross_site_double_key =
      NetworkAnonymizationKey::CreateFromParts(kTestSiteA, false);
  base::Value cross_site_double_key_value;
  ASSERT_TRUE(
      original_cross_site_double_key.ToValue(&cross_site_double_key_value));

  // Check that deserializing a double keyed NetworkAnonymizationKey (a
  // one-element list) fails, using the serialized site from
  // `cross_site_double_key_value` to build it.
  base::Value serialized_site =
      cross_site_double_key_value.GetList()[0].Clone();
  base::Value::List double_key_list;
  double_key_list.Append(serialized_site.Clone());
  base::Value double_key_value = base::Value(std::move(double_key_list));
  EXPECT_FALSE(NetworkAnonymizationKey::FromValue(double_key_value,
                                                  &expected_failure_nak));

  // Check that deserializing a triple keyed value (a 2-element list containing
  // two sites) fails.
  base::Value::List triple_key_list;
  triple_key_list.Append(serialized_site.Clone());
  triple_key_list.Append(std::move(serialized_site));
  base::Value triple_key_value = base::Value(std::move(triple_key_list));
  EXPECT_FALSE(NetworkAnonymizationKey::FromValue(triple_key_value,
                                                  &expected_failure_nak));

  // Convert the successful value back to a NAK and verify.
  NetworkAnonymizationKey from_value_cross_site_double_key =
      NetworkAnonymizationKey();
  EXPECT_TRUE(NetworkAnonymizationKey::FromValue(
      cross_site_double_key_value, &from_value_cross_site_double_key));
  EXPECT_EQ(original_cross_site_double_key, from_value_cross_site_double_key);
}

}  // namespace net
