// Copyright 2024 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/agent_cluster_key.h" #include <sstream> #include "base/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" namespace content { using AgentClusterKeyTest = testing::Test; TEST_F(AgentClusterKeyTest, SiteKeyed) { GURL url = GURL("https://a.com"); AgentClusterKey key = AgentClusterKey::CreateSiteKeyed(url); EXPECT_TRUE(key.IsSiteKeyed()); EXPECT_FALSE(key.IsOriginKeyed()); EXPECT_EQ(url, key.GetSite()); EXPECT_EQ(std::nullopt, key.GetCrossOriginIsolationKey()); ASSERT_DCHECK_DEATH(key.GetOrigin()); } TEST_F(AgentClusterKeyTest, OriginKeyed) { url::Origin origin = url::Origin::CreateFromNormalizedTuple("https", "example.com", 443); AgentClusterKey key = AgentClusterKey::CreateOriginKeyed(origin); EXPECT_FALSE(key.IsSiteKeyed()); EXPECT_TRUE(key.IsOriginKeyed()); EXPECT_EQ(origin, key.GetOrigin()); EXPECT_EQ(std::nullopt, key.GetCrossOriginIsolationKey()); ASSERT_DCHECK_DEATH(key.GetSite()); } TEST_F(AgentClusterKeyTest, WithCrossOriginIsolationKey) { url::Origin origin = url::Origin::CreateFromNormalizedTuple("https", "example.com", 443); url::Origin common_coi_origin = url::Origin::CreateFromNormalizedTuple( "https", "isolation.example.com", 443); AgentClusterKey::CrossOriginIsolationKey isolation_key( common_coi_origin, CrossOriginIsolationMode::kConcrete); AgentClusterKey key = AgentClusterKey::CreateWithCrossOriginIsolationKey(origin, isolation_key); EXPECT_FALSE(key.IsSiteKeyed()); EXPECT_TRUE(key.IsOriginKeyed()); EXPECT_EQ(origin, key.GetOrigin()); EXPECT_EQ(isolation_key, key.GetCrossOriginIsolationKey()); ASSERT_DCHECK_DEATH(key.GetSite()); } TEST_F(AgentClusterKeyTest, Comparisons) { // Site-keyed GURL site_a = GURL("https://a.com"); GURL site_b = GURL("https://b.com"); AgentClusterKey key_site_a = AgentClusterKey::CreateSiteKeyed(site_a); AgentClusterKey key_site_b = AgentClusterKey::CreateSiteKeyed(site_b); EXPECT_EQ(key_site_a, key_site_a); EXPECT_NE(key_site_a, key_site_b); // Origin-keyed url::Origin origin_a = url::Origin::Create(site_a); url::Origin origin_b = url::Origin::Create(site_b); AgentClusterKey key_origin_a = AgentClusterKey::CreateOriginKeyed(origin_a); AgentClusterKey key_origin_b = AgentClusterKey::CreateOriginKeyed(origin_b); EXPECT_EQ(key_origin_a, key_origin_a); EXPECT_NE(key_origin_a, key_origin_b); EXPECT_NE(key_origin_a, key_site_a); // With isolation key AgentClusterKey::CrossOriginIsolationKey coi_a( origin_a, CrossOriginIsolationMode::kConcrete); AgentClusterKey::CrossOriginIsolationKey coi_b( origin_b, CrossOriginIsolationMode::kConcrete); AgentClusterKey::CrossOriginIsolationKey non_coi_a( origin_a, CrossOriginIsolationMode::kLogical); AgentClusterKey::CrossOriginIsolationKey non_coi_b( origin_b, CrossOriginIsolationMode::kLogical); EXPECT_EQ(coi_a, coi_a); EXPECT_EQ(non_coi_a, non_coi_a); EXPECT_NE(coi_a, coi_b); EXPECT_NE(coi_a, non_coi_a); EXPECT_NE(non_coi_a, non_coi_b); AgentClusterKey key_origin_a_coi_a = AgentClusterKey::CreateWithCrossOriginIsolationKey(origin_a, coi_a); AgentClusterKey key_origin_b_coi_a = AgentClusterKey::CreateWithCrossOriginIsolationKey(origin_b, coi_a); AgentClusterKey key_origin_a_coi_b = AgentClusterKey::CreateWithCrossOriginIsolationKey(origin_a, coi_b); AgentClusterKey key_origin_a_non_coi_a = AgentClusterKey::CreateWithCrossOriginIsolationKey(origin_a, non_coi_a); EXPECT_EQ(key_origin_a_coi_a, key_origin_a_coi_a); EXPECT_NE(key_origin_a_coi_a, key_origin_b_coi_a); EXPECT_NE(key_origin_a_coi_a, key_origin_a_coi_b); EXPECT_NE(key_origin_a_coi_a, key_origin_a_non_coi_a); EXPECT_NE(key_origin_a_coi_a, key_origin_a); EXPECT_NE(key_origin_a_coi_a, key_site_a); EXPECT_NE(key_origin_a_non_coi_a, key_origin_a); EXPECT_NE(key_origin_a_non_coi_a, key_site_a); } TEST_F(AgentClusterKeyTest, StreamOutput) { std::stringstream dump; GURL url_a("https://a.com"); url::Origin origin_a = url::Origin::Create(url_a); url::Origin origin_b = url::Origin::Create(GURL("https://b.com")); AgentClusterKey key_site_a = AgentClusterKey::CreateSiteKeyed(url_a); dump << key_site_a; EXPECT_EQ(dump.str(), "{site_: https://a.com/}"); dump.str(""); AgentClusterKey key_origin_a = AgentClusterKey::CreateOriginKeyed(origin_a); dump << key_origin_a; EXPECT_EQ(dump.str(), "{origin_: https://a.com}"); dump.str(""); AgentClusterKey key_origin_a_coi_b = AgentClusterKey::CreateWithCrossOriginIsolationKey( origin_a, AgentClusterKey::CrossOriginIsolationKey( origin_b, CrossOriginIsolationMode::kConcrete)); dump << key_origin_a_coi_b; EXPECT_EQ(dump.str(), "{origin_: https://a.com, cross_origin_isolation_key_: " "{common_coi_origin: " "https://b.com, cross_origin_isolation_mode: concrete}}"); dump.str(""); } } // namespace content