xref: /aosp_15_r20/external/cronet/net/base/network_isolation_key_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/base/network_isolation_key.h"
6 
7 #include <optional>
8 
9 #include "base/test/scoped_feature_list.h"
10 #include "base/unguessable_token.h"
11 #include "base/values.h"
12 #include "net/base/features.h"
13 #include "net/base/schemeful_site.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h"
16 #include "url/url_util.h"
17 
18 namespace net {
19 
20 namespace {
21 const char kDataUrl[] = "data:text/html,<body>Hello World</body>";
22 
23 class NetworkIsolationKeyTest
24     : public testing::Test,
25       public testing::WithParamInterface<NetworkIsolationKey::Mode> {
26  public:
NetworkIsolationKeyTest()27   NetworkIsolationKeyTest() {
28     switch (GetParam()) {
29       case net::NetworkIsolationKey::Mode::kFrameSiteEnabled:
30         scoped_feature_list_.InitWithFeatures(
31             {},
32             {net::features::kEnableCrossSiteFlagNetworkIsolationKey,
33              net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey});
34         break;
35 
36       case net::NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
37         scoped_feature_list_.InitWithFeatures(
38             {net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey},
39             {
40                 net::features::kEnableCrossSiteFlagNetworkIsolationKey,
41             });
42         break;
43 
44       case net::NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
45         scoped_feature_list_.InitWithFeatures(
46             {net::features::kEnableCrossSiteFlagNetworkIsolationKey},
47             {net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey});
48         break;
49     }
50   }
51 
52  private:
53   base::test::ScopedFeatureList scoped_feature_list_;
54 };
55 INSTANTIATE_TEST_SUITE_P(
56     Tests,
57     NetworkIsolationKeyTest,
58     testing::ValuesIn(
59         {NetworkIsolationKey::Mode::kFrameSiteEnabled,
60          NetworkIsolationKey::Mode::kCrossSiteFlagEnabled,
61          NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled}),
__anonf66bbc970202(const testing::TestParamInfo<NetworkIsolationKey::Mode>& info) 62     [](const testing::TestParamInfo<NetworkIsolationKey::Mode>& info) {
63       switch (info.param) {
64         case NetworkIsolationKey::Mode::kFrameSiteEnabled:
65           return "FrameSiteEnabled";
66         case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
67           return "CrossSiteFlagEnabled";
68         case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
69           return "FrameSiteSharedOpaqueEnabled";
70       }
71     });
72 
TEST_P(NetworkIsolationKeyTest,EmptyKey)73 TEST_P(NetworkIsolationKeyTest, EmptyKey) {
74   NetworkIsolationKey key;
75   EXPECT_FALSE(key.IsFullyPopulated());
76   EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
77   EXPECT_TRUE(key.IsTransient());
78   switch (NetworkIsolationKey::GetMode()) {
79     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
80     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
81       EXPECT_EQ("null null", key.ToDebugString());
82       break;
83     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
84       EXPECT_EQ("null", key.ToDebugString());
85       break;
86   }
87 }
88 
TEST_P(NetworkIsolationKeyTest,NonEmptySameSiteKey)89 TEST_P(NetworkIsolationKeyTest, NonEmptySameSiteKey) {
90   SchemefulSite site1 = SchemefulSite(GURL("http://a.test/"));
91   NetworkIsolationKey key(site1, site1);
92   EXPECT_TRUE(key.IsFullyPopulated());
93   switch (NetworkIsolationKey::GetMode()) {
94     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
95     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
96       EXPECT_EQ(site1.Serialize() + " " + site1.Serialize(),
97                 key.ToCacheKeyString());
98       EXPECT_EQ(site1.GetDebugString() + " " + site1.GetDebugString(),
99                 key.ToDebugString());
100       break;
101     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
102       EXPECT_EQ(site1.Serialize() + " _0", key.ToCacheKeyString());
103       EXPECT_EQ(site1.GetDebugString() + " same-site", key.ToDebugString());
104       EXPECT_FALSE(*key.GetIsCrossSiteForTesting());
105       break;
106   }
107   EXPECT_FALSE(key.IsTransient());
108 }
109 
TEST_P(NetworkIsolationKeyTest,NonEmptyCrossSiteKey)110 TEST_P(NetworkIsolationKeyTest, NonEmptyCrossSiteKey) {
111   SchemefulSite site1 = SchemefulSite(GURL("http://a.test/"));
112   SchemefulSite site2 = SchemefulSite(GURL("http://b.test/"));
113   NetworkIsolationKey key(site1, site2);
114   EXPECT_TRUE(key.IsFullyPopulated());
115   switch (NetworkIsolationKey::GetMode()) {
116     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
117     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
118       EXPECT_EQ(site1.Serialize() + " " + site2.Serialize(),
119                 key.ToCacheKeyString());
120       EXPECT_EQ(site1.GetDebugString() + " " + site2.GetDebugString(),
121                 key.ToDebugString());
122       break;
123     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
124       EXPECT_EQ(site1.Serialize() + " _1", key.ToCacheKeyString());
125       EXPECT_EQ(site1.GetDebugString() + " cross-site", key.ToDebugString());
126       EXPECT_TRUE(*key.GetIsCrossSiteForTesting());
127       break;
128   }
129   EXPECT_FALSE(key.IsTransient());
130 }
131 
TEST_P(NetworkIsolationKeyTest,KeyWithNonce)132 TEST_P(NetworkIsolationKeyTest, KeyWithNonce) {
133   SchemefulSite site1 = SchemefulSite(GURL("http://a.test/"));
134   SchemefulSite site2 = SchemefulSite(GURL("http://b.test/"));
135   base::UnguessableToken nonce = base::UnguessableToken::Create();
136   NetworkIsolationKey key(site1, site2, nonce);
137   EXPECT_TRUE(key.IsFullyPopulated());
138   EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
139   EXPECT_TRUE(key.IsTransient());
140   switch (NetworkIsolationKey::GetMode()) {
141     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
142     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
143       EXPECT_EQ(site1.GetDebugString() + " " + site2.GetDebugString() +
144                     " (with nonce " + nonce.ToString() + ")",
145                 key.ToDebugString());
146       break;
147     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
148       EXPECT_EQ(site1.GetDebugString() + " cross-site (with nonce " +
149                     nonce.ToString() + ")",
150                 key.ToDebugString());
151       break;
152   }
153 
154   // Create another NetworkIsolationKey with the same input parameters, and
155   // check that it is equal.
156   NetworkIsolationKey same_key(site1, site2, nonce);
157   EXPECT_EQ(key, same_key);
158 
159   // Create another NetworkIsolationKey with a different nonce and check that
160   // it's different.
161   base::UnguessableToken nonce2 = base::UnguessableToken::Create();
162   NetworkIsolationKey key2(site1, site2, nonce2);
163   EXPECT_NE(key, key2);
164   EXPECT_NE(key.ToDebugString(), key2.ToDebugString());
165 }
166 
TEST_P(NetworkIsolationKeyTest,OpaqueOriginKey)167 TEST_P(NetworkIsolationKeyTest, OpaqueOriginKey) {
168   SchemefulSite site_data = SchemefulSite(GURL(kDataUrl));
169   NetworkIsolationKey key(site_data, site_data);
170   EXPECT_TRUE(key.IsFullyPopulated());
171   EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
172   EXPECT_TRUE(key.IsTransient());
173   switch (NetworkIsolationKey::GetMode()) {
174     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
175       EXPECT_EQ(site_data.GetDebugString() + " " + site_data.GetDebugString(),
176                 key.ToDebugString());
177       break;
178     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
179       EXPECT_EQ(site_data.GetDebugString() + " opaque-origin",
180                 key.ToDebugString());
181       break;
182     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
183       // Even though the site is opaque, it won't be considered cross-site since
184       // the top-level site and frame site have the same opaque origin.
185       EXPECT_EQ(site_data.GetDebugString() + " same-site", key.ToDebugString());
186       break;
187   }
188 
189   // Create another site with an opaque origin, and make sure it's different and
190   // has a different debug string.
191   SchemefulSite other_site = SchemefulSite(GURL(kDataUrl));
192   NetworkIsolationKey other_key(other_site, other_site);
193   EXPECT_NE(key, other_key);
194   EXPECT_NE(key.ToDebugString(), other_key.ToDebugString());
195   switch (NetworkIsolationKey::GetMode()) {
196     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
197       EXPECT_EQ(other_site.GetDebugString() + " " + other_site.GetDebugString(),
198                 other_key.ToDebugString());
199       break;
200     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
201       EXPECT_EQ(other_site.GetDebugString() + " opaque-origin",
202                 other_key.ToDebugString());
203       break;
204     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
205       EXPECT_EQ(other_site.GetDebugString() + " same-site",
206                 other_key.ToDebugString());
207       break;
208   }
209 }
210 
TEST_P(NetworkIsolationKeyTest,OpaqueOriginTopLevelSiteKey)211 TEST_P(NetworkIsolationKeyTest, OpaqueOriginTopLevelSiteKey) {
212   SchemefulSite site1 = SchemefulSite(GURL("http://a.test/"));
213   SchemefulSite site_data = SchemefulSite(GURL(kDataUrl));
214   NetworkIsolationKey key(site_data, site1);
215   EXPECT_TRUE(key.IsFullyPopulated());
216   EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
217   EXPECT_TRUE(key.IsTransient());
218   switch (NetworkIsolationKey::GetMode()) {
219     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
220     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
221       EXPECT_EQ(site_data.GetDebugString() + " " + site1.GetDebugString(),
222                 key.ToDebugString());
223       break;
224     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
225       EXPECT_EQ(site_data.GetDebugString() + " cross-site",
226                 key.ToDebugString());
227       break;
228   }
229 
230   // Create another site with an opaque origin, and make sure it's different and
231   // has a different debug string.
232   SchemefulSite other_site = SchemefulSite(GURL(kDataUrl));
233   NetworkIsolationKey other_key(other_site, site1);
234   EXPECT_NE(key, other_key);
235   EXPECT_NE(key.ToDebugString(), other_key.ToDebugString());
236   switch (NetworkIsolationKey::GetMode()) {
237     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
238     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
239       EXPECT_EQ(other_site.GetDebugString() + " " + site1.GetDebugString(),
240                 other_key.ToDebugString());
241       break;
242     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
243       EXPECT_EQ(other_site.GetDebugString() + " cross-site",
244                 other_key.ToDebugString());
245       break;
246   }
247 }
248 
TEST_P(NetworkIsolationKeyTest,OpaqueOriginIframeKey)249 TEST_P(NetworkIsolationKeyTest, OpaqueOriginIframeKey) {
250   SchemefulSite site1 = SchemefulSite(GURL("http://a.test/"));
251   SchemefulSite site_data = SchemefulSite(GURL(kDataUrl));
252   NetworkIsolationKey key(site1, site_data);
253   EXPECT_TRUE(key.IsFullyPopulated());
254   switch (NetworkIsolationKey::GetMode()) {
255     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
256       EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
257       EXPECT_TRUE(key.IsTransient());
258       EXPECT_EQ(site1.GetDebugString() + " " + site_data.GetDebugString(),
259                 key.ToDebugString());
260       break;
261     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
262       EXPECT_EQ(site1.Serialize() + " _opaque", key.ToCacheKeyString());
263       EXPECT_EQ(site1.GetDebugString() + " opaque-origin", key.ToDebugString());
264       EXPECT_FALSE(key.IsTransient());
265       break;
266 
267     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
268       EXPECT_EQ(site1.Serialize() + " _1", key.ToCacheKeyString());
269       EXPECT_EQ(site1.GetDebugString() + " cross-site", key.ToDebugString());
270       EXPECT_FALSE(key.IsTransient());
271       break;
272   }
273 
274   // Create another site with an opaque origin iframe, and make sure it's
275   // different and has a different debug string when the frame site is in use.
276   SchemefulSite other_site = SchemefulSite(GURL(kDataUrl));
277   NetworkIsolationKey other_key(site1, other_site);
278   switch (NetworkIsolationKey::GetMode()) {
279     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
280       EXPECT_NE(key, other_key);
281       EXPECT_NE(key.ToDebugString(), other_key.ToDebugString());
282       EXPECT_EQ(site1.GetDebugString() + " " + other_site.GetDebugString(),
283                 other_key.ToDebugString());
284       break;
285     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
286     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
287       EXPECT_EQ(key, other_key);
288       EXPECT_EQ(key.ToDebugString(), other_key.ToDebugString());
289       EXPECT_EQ(key.ToCacheKeyString(), other_key.ToCacheKeyString());
290       break;
291   }
292 }
293 
TEST_P(NetworkIsolationKeyTest,Operators)294 TEST_P(NetworkIsolationKeyTest, Operators) {
295   base::UnguessableToken nonce1 = base::UnguessableToken::Create();
296   base::UnguessableToken nonce2 = base::UnguessableToken::Create();
297   if (nonce2 < nonce1)
298     std::swap(nonce1, nonce2);
299   // These are in ascending order.
300   const NetworkIsolationKey kKeys[] = {
301       NetworkIsolationKey(),
302       // Site with unique origins are still sorted by scheme, so data is before
303       // file, and file before http.
304       NetworkIsolationKey(SchemefulSite(GURL(kDataUrl)),
305                           SchemefulSite(GURL(kDataUrl))),
306       NetworkIsolationKey(SchemefulSite(GURL("file:///foo")),
307                           SchemefulSite(GURL("file:///foo"))),
308       NetworkIsolationKey(SchemefulSite(GURL("http://a.test/")),
309                           SchemefulSite(GURL("http://a.test/"))),
310       NetworkIsolationKey(SchemefulSite(GURL("http://b.test/")),
311                           SchemefulSite(GURL("http://b.test/"))),
312       NetworkIsolationKey(SchemefulSite(GURL("https://a.test/")),
313                           SchemefulSite(GURL("https://a.test/"))),
314       NetworkIsolationKey(SchemefulSite(GURL("https://a.test/")),
315                           SchemefulSite(GURL("https://a.test/")), nonce1),
316       NetworkIsolationKey(SchemefulSite(GURL("https://a.test/")),
317                           SchemefulSite(GURL("https://a.test/")), nonce2),
318   };
319 
320   for (size_t first = 0; first < std::size(kKeys); ++first) {
321     NetworkIsolationKey key1 = kKeys[first];
322     SCOPED_TRACE(key1.ToDebugString());
323 
324     EXPECT_TRUE(key1 == key1);
325     EXPECT_FALSE(key1 != key1);
326     EXPECT_FALSE(key1 < key1);
327 
328     // Make sure that copying a key doesn't change the results of any operation.
329     // This check is a bit more interesting with unique origins.
330     NetworkIsolationKey key1_copy = key1;
331     EXPECT_TRUE(key1 == key1_copy);
332     EXPECT_FALSE(key1 < key1_copy);
333     EXPECT_FALSE(key1_copy < key1);
334 
335     for (size_t second = first + 1; second < std::size(kKeys); ++second) {
336       NetworkIsolationKey key2 = kKeys[second];
337       SCOPED_TRACE(key2.ToDebugString());
338 
339       EXPECT_TRUE(key1 < key2);
340       EXPECT_FALSE(key2 < key1);
341       EXPECT_FALSE(key1 == key2);
342       EXPECT_FALSE(key2 == key1);
343     }
344   }
345 }
346 
TEST_P(NetworkIsolationKeyTest,UniqueOriginOperators)347 TEST_P(NetworkIsolationKeyTest, UniqueOriginOperators) {
348   const auto kSite1 = SchemefulSite(GURL(kDataUrl));
349   const auto kSite2 = SchemefulSite(GURL(kDataUrl));
350   NetworkIsolationKey key1(kSite1, kSite1);
351   NetworkIsolationKey key2(kSite2, kSite2);
352 
353   EXPECT_TRUE(key1 == key1);
354   EXPECT_TRUE(key2 == key2);
355 
356   // Creating copies shouldn't affect comparison result.
357   EXPECT_TRUE(NetworkIsolationKey(key1) == NetworkIsolationKey(key1));
358   EXPECT_TRUE(NetworkIsolationKey(key2) == NetworkIsolationKey(key2));
359 
360   EXPECT_FALSE(key1 == key2);
361   EXPECT_FALSE(key2 == key1);
362 
363   // Order of Nonces isn't predictable, but they should have an ordering.
364   EXPECT_TRUE(key1 < key2 || key2 < key1);
365   EXPECT_TRUE(!(key1 < key2) || !(key2 < key1));
366 }
367 
TEST_P(NetworkIsolationKeyTest,OpaqueSiteKeyBoth)368 TEST_P(NetworkIsolationKeyTest, OpaqueSiteKeyBoth) {
369   SchemefulSite site_data_1 = SchemefulSite(GURL(kDataUrl));
370   SchemefulSite site_data_2 = SchemefulSite(GURL(kDataUrl));
371   SchemefulSite site_data_3 = SchemefulSite(GURL(kDataUrl));
372 
373   NetworkIsolationKey key1(site_data_1, site_data_2);
374   NetworkIsolationKey key2(site_data_1, site_data_2);
375   NetworkIsolationKey key3(site_data_1, site_data_3);
376 
377   // All the keys should be fully populated and transient.
378   EXPECT_TRUE(key1.IsFullyPopulated());
379   EXPECT_TRUE(key2.IsFullyPopulated());
380   EXPECT_TRUE(key3.IsFullyPopulated());
381   EXPECT_TRUE(key1.IsTransient());
382   EXPECT_TRUE(key2.IsTransient());
383   EXPECT_TRUE(key3.IsTransient());
384 
385   // Test the equality/comparisons of the various keys
386   EXPECT_TRUE(key1 == key2);
387   EXPECT_FALSE(key1 < key2 || key2 < key1);
388   switch (NetworkIsolationKey::GetMode()) {
389     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
390       EXPECT_FALSE(key1 == key3);
391       EXPECT_TRUE(key1 < key3 || key3 < key1);
392       EXPECT_NE(key1.ToDebugString(), key3.ToDebugString());
393       break;
394     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
395     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
396       EXPECT_TRUE(key1 == key3);
397       EXPECT_FALSE(key1 < key3 || key3 < key1);
398       EXPECT_EQ(key1.ToDebugString(), key3.ToDebugString());
399       break;
400   }
401 
402   // Test the ToString and ToDebugString
403   EXPECT_EQ(key1.ToDebugString(), key2.ToDebugString());
404   EXPECT_EQ(std::nullopt, key1.ToCacheKeyString());
405   EXPECT_EQ(std::nullopt, key2.ToCacheKeyString());
406   EXPECT_EQ(std::nullopt, key3.ToCacheKeyString());
407 }
408 
409 // Make sure that the logic to extract the registerable domain from an origin
410 // does not affect the host when using a non-standard scheme.
TEST_P(NetworkIsolationKeyTest,NonStandardScheme)411 TEST_P(NetworkIsolationKeyTest, NonStandardScheme) {
412   // Have to register the scheme, or SchemefulSite() will return an opaque
413   // origin.
414   url::ScopedSchemeRegistryForTests scoped_registry;
415   url::AddStandardScheme("foo", url::SCHEME_WITH_HOST);
416 
417   SchemefulSite site = SchemefulSite(GURL("foo://a.foo.com"));
418   NetworkIsolationKey key(site, site);
419   EXPECT_FALSE(key.GetTopFrameSite()->opaque());
420   switch (NetworkIsolationKey::GetMode()) {
421     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
422     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
423       EXPECT_EQ("foo://a.foo.com foo://a.foo.com", key.ToCacheKeyString());
424       break;
425     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
426       EXPECT_EQ("foo://a.foo.com _0", key.ToCacheKeyString());
427       break;
428   }
429 }
430 
TEST_P(NetworkIsolationKeyTest,CreateWithNewFrameSite)431 TEST_P(NetworkIsolationKeyTest, CreateWithNewFrameSite) {
432   SchemefulSite site_a = SchemefulSite(GURL("http://a.com"));
433   SchemefulSite site_b = SchemefulSite(GURL("http://b.com"));
434   SchemefulSite site_c = SchemefulSite(GURL("http://c.com"));
435 
436   NetworkIsolationKey key(site_a, site_b);
437   NetworkIsolationKey key_c = key.CreateWithNewFrameSite(site_c);
438   switch (NetworkIsolationKey::GetMode()) {
439     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
440     case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
441       EXPECT_EQ(site_c, key_c.GetFrameSiteForTesting());
442       EXPECT_NE(key_c, key);
443       break;
444     case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
445       NetworkIsolationKey same_site_key(site_a, site_a);
446       EXPECT_EQ(key_c, key);
447       EXPECT_NE(key_c, same_site_key);
448       break;
449   }
450   EXPECT_EQ(site_a, key_c.GetTopFrameSite());
451 
452   // Ensure that `CreateWithNewFrameSite()` preserves the nonce if one exists.
453   base::UnguessableToken nonce = base::UnguessableToken::Create();
454   NetworkIsolationKey key_with_nonce(site_a, site_b, nonce);
455   NetworkIsolationKey key_with_nonce_c =
456       key_with_nonce.CreateWithNewFrameSite(site_c);
457   EXPECT_EQ(key_with_nonce.GetNonce(), key_with_nonce_c.GetNonce());
458   EXPECT_TRUE(key_with_nonce_c.IsTransient());
459 
460   // If `CreateWithNewFrameSite()` causes a key to go from cross site to same
461   // site, ensure that is reflected internally.
462   NetworkIsolationKey key_a = key.CreateWithNewFrameSite(site_a);
463   if (NetworkIsolationKey::GetMode() ==
464       NetworkIsolationKey::Mode::kCrossSiteFlagEnabled) {
465     NetworkIsolationKey same_site_key(site_a, site_a);
466     EXPECT_EQ(key_a, same_site_key);
467     EXPECT_NE(key_a, key);
468   }
469 }
470 
TEST_P(NetworkIsolationKeyTest,CreateTransientForTesting)471 TEST_P(NetworkIsolationKeyTest, CreateTransientForTesting) {
472   NetworkIsolationKey transient_key =
473       NetworkIsolationKey::CreateTransientForTesting();
474   EXPECT_TRUE(transient_key.IsFullyPopulated());
475   EXPECT_TRUE(transient_key.IsTransient());
476   EXPECT_FALSE(transient_key.IsEmpty());
477   EXPECT_EQ(transient_key, transient_key);
478 
479   // Make sure that subsequent calls don't return the same NIK.
480   for (int i = 0; i < 1000; ++i) {
481     EXPECT_NE(transient_key, NetworkIsolationKey::CreateTransientForTesting());
482   }
483 }
484 
485 }  // namespace
486 
487 }  // namespace net
488