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