• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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/isolation_info.h"
6 
7 #include <iostream>
8 #include <optional>
9 
10 #include "base/strings/strcat.h"
11 #include "base/test/gtest_util.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/unguessable_token.h"
14 #include "isolation_info.h"
15 #include "net/base/features.h"
16 #include "net/base/network_anonymization_key.h"
17 #include "net/base/network_isolation_key.h"
18 #include "net/base/schemeful_site.h"
19 #include "net/cookies/site_for_cookies.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
22 #include "url/origin.h"
23 #include "url/url_util.h"
24 
25 namespace net {
26 
27 namespace {
28 
29 class IsolationInfoTest : public testing::Test {
30  public:
31   const url::Origin kOrigin1 = url::Origin::Create(GURL("https://a.foo.test"));
32   const url::Origin kSite1 = url::Origin::Create(GURL("https://foo.test"));
33   const url::Origin kOrigin2 = url::Origin::Create(GURL("https://b.bar.test"));
34   const url::Origin kSite2 = url::Origin::Create(GURL("https://bar.test"));
35   const url::Origin kOrigin3 = url::Origin::Create(GURL("https://c.baz.test"));
36   const url::Origin kOpaqueOrigin;
37 
38   const base::UnguessableToken kNonce1 = base::UnguessableToken::Create();
39   const base::UnguessableToken kNonce2 = base::UnguessableToken::Create();
40 };
41 
DuplicateAndCompare(const IsolationInfo & isolation_info)42 void DuplicateAndCompare(const IsolationInfo& isolation_info) {
43   std::optional<IsolationInfo> duplicate_isolation_info =
44       IsolationInfo::CreateIfConsistent(
45           isolation_info.request_type(), isolation_info.top_frame_origin(),
46           isolation_info.frame_origin(), isolation_info.site_for_cookies(),
47           isolation_info.nonce());
48 
49   ASSERT_TRUE(duplicate_isolation_info);
50   EXPECT_TRUE(isolation_info.IsEqualForTesting(*duplicate_isolation_info));
51 }
52 
TEST_F(IsolationInfoTest,DebugString)53 TEST_F(IsolationInfoTest, DebugString) {
54   IsolationInfo isolation_info = IsolationInfo::Create(
55       IsolationInfo::RequestType::kMainFrame, kOrigin1, kOrigin2,
56       SiteForCookies::FromOrigin(kOrigin1), kNonce1);
57   std::vector<std::string> parts;
58   parts.push_back(
59       "request_type: kMainFrame; top_frame_origin: https://a.foo.test; ");
60   parts.push_back("frame_origin: https://b.bar.test; ");
61   parts.push_back("network_anonymization_key: ");
62   parts.push_back(isolation_info.network_anonymization_key().ToDebugString());
63   parts.push_back("; network_isolation_key: ");
64   parts.push_back(isolation_info.network_isolation_key().ToDebugString());
65   parts.push_back("; nonce: ");
66   parts.push_back(isolation_info.nonce().value().ToString());
67   parts.push_back(
68       "; site_for_cookies: SiteForCookies: {site=https://foo.test; "
69       "schemefully_same=true}");
70   EXPECT_EQ(isolation_info.DebugString(), base::StrCat(parts));
71 }
72 
TEST_F(IsolationInfoTest,RequestTypeMainFrame)73 TEST_F(IsolationInfoTest, RequestTypeMainFrame) {
74   IsolationInfo isolation_info =
75       IsolationInfo::Create(IsolationInfo::RequestType::kMainFrame, kOrigin1,
76                             kOrigin1, SiteForCookies::FromOrigin(kOrigin1));
77   EXPECT_EQ(IsolationInfo::RequestType::kMainFrame,
78             isolation_info.request_type());
79   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
80 
81   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
82   EXPECT_EQ("https://foo.test https://foo.test",
83             isolation_info.network_isolation_key().ToCacheKeyString());
84   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
85   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
86   EXPECT_TRUE(
87       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
88   EXPECT_FALSE(isolation_info.nonce().has_value());
89 
90   DuplicateAndCompare(isolation_info);
91 
92   IsolationInfo redirected_isolation_info =
93       isolation_info.CreateForRedirect(kOrigin3);
94   EXPECT_EQ(IsolationInfo::RequestType::kMainFrame,
95             redirected_isolation_info.request_type());
96   EXPECT_EQ(kOrigin3, redirected_isolation_info.top_frame_origin());
97   EXPECT_EQ(kOrigin3, redirected_isolation_info.frame_origin());
98   EXPECT_TRUE(
99       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
100   EXPECT_FALSE(redirected_isolation_info.network_isolation_key().IsTransient());
101   EXPECT_EQ(
102       "https://baz.test https://baz.test",
103       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
104 
105   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
106       kOrigin3.GetURL()));
107   EXPECT_FALSE(redirected_isolation_info.nonce().has_value());
108 }
109 
TEST_F(IsolationInfoTest,RequestTypeSubFrame)110 TEST_F(IsolationInfoTest, RequestTypeSubFrame) {
111   IsolationInfo isolation_info =
112       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
113                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1));
114   EXPECT_EQ(IsolationInfo::RequestType::kSubFrame,
115             isolation_info.request_type());
116   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
117   EXPECT_EQ(kOrigin2, isolation_info.frame_origin());
118   EXPECT_EQ("https://foo.test https://bar.test",
119             isolation_info.network_isolation_key().ToCacheKeyString());
120   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
121   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
122   EXPECT_TRUE(
123       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
124   EXPECT_FALSE(isolation_info.nonce().has_value());
125 
126   DuplicateAndCompare(isolation_info);
127 
128   IsolationInfo redirected_isolation_info =
129       isolation_info.CreateForRedirect(kOrigin3);
130   EXPECT_EQ(IsolationInfo::RequestType::kSubFrame,
131             redirected_isolation_info.request_type());
132   EXPECT_EQ(kOrigin1, redirected_isolation_info.top_frame_origin());
133 
134   EXPECT_EQ(kOrigin3, redirected_isolation_info.frame_origin());
135   EXPECT_EQ(
136       "https://foo.test https://baz.test",
137       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
138 
139   EXPECT_TRUE(
140       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
141   EXPECT_FALSE(redirected_isolation_info.network_isolation_key().IsTransient());
142   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
143       kOrigin1.GetURL()));
144   EXPECT_FALSE(redirected_isolation_info.nonce().has_value());
145 }
146 
TEST_F(IsolationInfoTest,RequestTypeMainFrameWithNonce)147 TEST_F(IsolationInfoTest, RequestTypeMainFrameWithNonce) {
148   IsolationInfo isolation_info = IsolationInfo::Create(
149       IsolationInfo::RequestType::kMainFrame, kOrigin1, kOrigin1,
150       SiteForCookies::FromOrigin(kOrigin1), kNonce1);
151   EXPECT_EQ(IsolationInfo::RequestType::kMainFrame,
152             isolation_info.request_type());
153   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
154   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
155   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
156   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
157   EXPECT_EQ(std::nullopt,
158             isolation_info.network_isolation_key().ToCacheKeyString());
159   EXPECT_TRUE(
160       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
161   EXPECT_EQ(kNonce1, isolation_info.nonce().value());
162 
163   DuplicateAndCompare(isolation_info);
164 
165   IsolationInfo redirected_isolation_info =
166       isolation_info.CreateForRedirect(kOrigin3);
167   EXPECT_EQ(IsolationInfo::RequestType::kMainFrame,
168             redirected_isolation_info.request_type());
169   EXPECT_EQ(kOrigin3, redirected_isolation_info.top_frame_origin());
170   EXPECT_EQ(kOrigin3, redirected_isolation_info.frame_origin());
171   EXPECT_TRUE(
172       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
173   EXPECT_TRUE(redirected_isolation_info.network_isolation_key().IsTransient());
174   EXPECT_EQ(
175       std::nullopt,
176       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
177   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
178       kOrigin3.GetURL()));
179   EXPECT_EQ(kNonce1, redirected_isolation_info.nonce().value());
180 }
181 
TEST_F(IsolationInfoTest,RequestTypeSubFrameWithNonce)182 TEST_F(IsolationInfoTest, RequestTypeSubFrameWithNonce) {
183   IsolationInfo isolation_info = IsolationInfo::Create(
184       IsolationInfo::RequestType::kSubFrame, kOrigin1, kOrigin2,
185       SiteForCookies::FromOrigin(kOrigin1), kNonce1);
186   EXPECT_EQ(IsolationInfo::RequestType::kSubFrame,
187             isolation_info.request_type());
188   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
189   EXPECT_EQ(kOrigin2, isolation_info.frame_origin());
190   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
191   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
192   EXPECT_EQ(std::nullopt,
193             isolation_info.network_isolation_key().ToCacheKeyString());
194   EXPECT_TRUE(
195       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
196   EXPECT_EQ(kNonce1, isolation_info.nonce().value());
197 
198   DuplicateAndCompare(isolation_info);
199 
200   IsolationInfo redirected_isolation_info =
201       isolation_info.CreateForRedirect(kOrigin3);
202   EXPECT_EQ(IsolationInfo::RequestType::kSubFrame,
203             redirected_isolation_info.request_type());
204   EXPECT_EQ(kOrigin1, redirected_isolation_info.top_frame_origin());
205   EXPECT_EQ(kOrigin3, redirected_isolation_info.frame_origin());
206   EXPECT_TRUE(
207       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
208   EXPECT_TRUE(redirected_isolation_info.network_isolation_key().IsTransient());
209   EXPECT_EQ(
210       std::nullopt,
211       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
212   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
213       kOrigin1.GetURL()));
214   EXPECT_EQ(kNonce1, redirected_isolation_info.nonce().value());
215 }
216 
TEST_F(IsolationInfoTest,RequestTypeOther)217 TEST_F(IsolationInfoTest, RequestTypeOther) {
218   IsolationInfo isolation_info;
219   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
220   EXPECT_FALSE(isolation_info.top_frame_origin());
221   EXPECT_FALSE(isolation_info.frame_origin());
222   EXPECT_TRUE(isolation_info.network_isolation_key().IsEmpty());
223   EXPECT_TRUE(isolation_info.site_for_cookies().IsNull());
224   EXPECT_FALSE(isolation_info.nonce());
225 
226   DuplicateAndCompare(isolation_info);
227 
228   IsolationInfo redirected_isolation_info =
229       isolation_info.CreateForRedirect(kOrigin3);
230   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
231 }
232 
TEST_F(IsolationInfoTest,RequestTypeOtherWithSiteForCookies)233 TEST_F(IsolationInfoTest, RequestTypeOtherWithSiteForCookies) {
234   IsolationInfo isolation_info =
235       IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin1,
236                             kOrigin1, SiteForCookies::FromOrigin(kOrigin1));
237   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
238   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
239   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
240   EXPECT_EQ("https://foo.test https://foo.test",
241             isolation_info.network_isolation_key().ToCacheKeyString());
242   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
243   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
244   EXPECT_TRUE(
245       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
246   EXPECT_FALSE(isolation_info.nonce());
247 
248   DuplicateAndCompare(isolation_info);
249 
250   IsolationInfo redirected_isolation_info =
251       isolation_info.CreateForRedirect(kOrigin3);
252   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
253 }
254 
255 // Test case of a subresource for cross-site subframe (which has an empty
256 // site-for-cookies).
TEST_F(IsolationInfoTest,RequestTypeOtherWithEmptySiteForCookies)257 TEST_F(IsolationInfoTest, RequestTypeOtherWithEmptySiteForCookies) {
258   IsolationInfo isolation_info = IsolationInfo::Create(
259       IsolationInfo::RequestType::kOther, kOrigin1, kOrigin2, SiteForCookies());
260   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
261   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
262   EXPECT_EQ(kOrigin2, isolation_info.frame_origin());
263   EXPECT_EQ("https://foo.test https://bar.test",
264             isolation_info.network_isolation_key().ToCacheKeyString());
265 
266   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
267   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
268   EXPECT_TRUE(isolation_info.site_for_cookies().IsNull());
269   EXPECT_FALSE(isolation_info.nonce());
270 
271   DuplicateAndCompare(isolation_info);
272 
273   IsolationInfo redirected_isolation_info =
274       isolation_info.CreateForRedirect(kOrigin3);
275   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
276 }
277 
TEST_F(IsolationInfoTest,CreateTransient)278 TEST_F(IsolationInfoTest, CreateTransient) {
279   IsolationInfo isolation_info = IsolationInfo::CreateTransient();
280   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
281   EXPECT_TRUE(isolation_info.top_frame_origin()->opaque());
282   EXPECT_TRUE(isolation_info.frame_origin()->opaque());
283   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
284   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
285   EXPECT_TRUE(isolation_info.site_for_cookies().IsNull());
286   EXPECT_FALSE(isolation_info.nonce());
287 
288   DuplicateAndCompare(isolation_info);
289 
290   IsolationInfo redirected_isolation_info =
291       isolation_info.CreateForRedirect(kOrigin3);
292   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
293 }
294 
TEST_F(IsolationInfoTest,CreateTransientWithNonce)295 TEST_F(IsolationInfoTest, CreateTransientWithNonce) {
296   IsolationInfo isolation_info =
297       IsolationInfo::CreateTransientWithNonce(kNonce1);
298   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
299   EXPECT_TRUE(isolation_info.top_frame_origin()->opaque());
300   EXPECT_TRUE(isolation_info.frame_origin()->opaque());
301   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
302   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
303   EXPECT_TRUE(isolation_info.site_for_cookies().IsNull());
304   ASSERT_TRUE(isolation_info.nonce().has_value());
305   EXPECT_EQ(isolation_info.nonce().value(), kNonce1);
306 
307   DuplicateAndCompare(isolation_info);
308 
309   IsolationInfo redirected_isolation_info =
310       isolation_info.CreateForRedirect(kOrigin3);
311   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
312 
313   IsolationInfo new_info_same_nonce =
314       IsolationInfo::CreateTransientWithNonce(kNonce1);
315   ASSERT_TRUE(new_info_same_nonce.nonce().has_value());
316   EXPECT_EQ(new_info_same_nonce.nonce().value(), kNonce1);
317 
318   // The new NIK is distinct from the first one because it uses a new opaque
319   // origin, even if the nonce is the same.
320   EXPECT_NE(isolation_info.network_isolation_key(),
321             new_info_same_nonce.network_isolation_key());
322 }
323 
TEST_F(IsolationInfoTest,CreateForInternalRequest)324 TEST_F(IsolationInfoTest, CreateForInternalRequest) {
325   IsolationInfo isolation_info =
326       IsolationInfo::CreateForInternalRequest(kOrigin1);
327   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
328   EXPECT_EQ(kOrigin1, isolation_info.top_frame_origin());
329   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
330   EXPECT_EQ("https://foo.test https://foo.test",
331             isolation_info.network_isolation_key().ToCacheKeyString());
332 
333   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
334   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
335   EXPECT_TRUE(
336       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
337   EXPECT_FALSE(isolation_info.nonce());
338 
339   DuplicateAndCompare(isolation_info);
340 
341   IsolationInfo redirected_isolation_info =
342       isolation_info.CreateForRedirect(kOrigin3);
343   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
344 }
345 
346 // Test that in the UpdateNothing case, the SiteForCookies does not have to
347 // match the frame origin, unlike in the HTTP/HTTPS case.
TEST_F(IsolationInfoTest,CustomSchemeRequestTypeOther)348 TEST_F(IsolationInfoTest, CustomSchemeRequestTypeOther) {
349   // Have to register the scheme, or url::Origin::Create() will return an
350   // opaque origin.
351   url::ScopedSchemeRegistryForTests scoped_registry;
352   url::AddStandardScheme("foo", url::SCHEME_WITH_HOST);
353 
354   const GURL kCustomOriginUrl = GURL("foo://a.foo.com");
355   const url::Origin kCustomOrigin = url::Origin::Create(kCustomOriginUrl);
356 
357   IsolationInfo isolation_info = IsolationInfo::Create(
358       IsolationInfo::RequestType::kOther, kCustomOrigin, kOrigin1,
359       SiteForCookies::FromOrigin(kCustomOrigin));
360   EXPECT_EQ(IsolationInfo::RequestType::kOther, isolation_info.request_type());
361   EXPECT_EQ(kCustomOrigin, isolation_info.top_frame_origin());
362   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
363   EXPECT_EQ("foo://a.foo.com https://foo.test",
364             isolation_info.network_isolation_key().ToCacheKeyString());
365 
366   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
367   EXPECT_FALSE(isolation_info.network_isolation_key().IsTransient());
368   EXPECT_TRUE(isolation_info.site_for_cookies().IsFirstParty(kCustomOriginUrl));
369   EXPECT_FALSE(isolation_info.nonce());
370 
371   DuplicateAndCompare(isolation_info);
372 
373   IsolationInfo redirected_isolation_info =
374       isolation_info.CreateForRedirect(kOrigin2);
375   EXPECT_TRUE(isolation_info.IsEqualForTesting(redirected_isolation_info));
376 }
377 
378 // Success cases are covered by other tests, so only need a separate test to
379 // cover the failure cases.
TEST_F(IsolationInfoTest,CreateIfConsistentFails)380 TEST_F(IsolationInfoTest, CreateIfConsistentFails) {
381   // Main frames with inconsistent SiteForCookies.
382   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
383       IsolationInfo::RequestType::kMainFrame, kOrigin1, kOrigin1,
384       SiteForCookies::FromOrigin(kOrigin2)));
385   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
386       IsolationInfo::RequestType::kMainFrame, kOpaqueOrigin, kOpaqueOrigin,
387       SiteForCookies::FromOrigin(kOrigin1)));
388 
389   // Sub frame with inconsistent SiteForCookies.
390   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
391       IsolationInfo::RequestType::kSubFrame, kOrigin1, kOrigin2,
392       SiteForCookies::FromOrigin(kOrigin2)));
393 
394   // Sub resources with inconsistent SiteForCookies.
395   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
396       IsolationInfo::RequestType::kOther, kOrigin1, kOrigin2,
397       SiteForCookies::FromOrigin(kOrigin2)));
398 
399   // Correctly have empty/non-empty origins:
400   EXPECT_TRUE(IsolationInfo::CreateIfConsistent(
401       IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
402       SiteForCookies()));
403 
404   // Incorrectly have empty/non-empty origins:
405   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
406       IsolationInfo::RequestType::kOther, std::nullopt, kOrigin1,
407       SiteForCookies()));
408   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
409       IsolationInfo::RequestType::kSubFrame, std::nullopt, kOrigin2,
410       SiteForCookies()));
411 
412   // Empty frame origins are incorrect.
413   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
414       IsolationInfo::RequestType::kOther, kOrigin1, std::nullopt,
415       SiteForCookies()));
416   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
417       IsolationInfo::RequestType::kSubFrame, kOrigin1, std::nullopt,
418       SiteForCookies()));
419   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
420       IsolationInfo::RequestType::kMainFrame, kOrigin1, std::nullopt,
421       SiteForCookies::FromOrigin(kOrigin1)));
422   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
423       IsolationInfo::RequestType::kOther, kOrigin1, kOrigin2,
424       SiteForCookies::FromOrigin(kOrigin1)));
425 
426   // No origins with non-null SiteForCookies.
427   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
428       IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
429       SiteForCookies::FromOrigin(kOrigin1)));
430 
431   // No origins with non-null nonce.
432   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
433       IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
434       SiteForCookies(), kNonce1));
435 }
436 
TEST_F(IsolationInfoTest,Serialization)437 TEST_F(IsolationInfoTest, Serialization) {
438   EXPECT_FALSE(IsolationInfo::Deserialize(""));
439   EXPECT_FALSE(IsolationInfo::Deserialize("garbage"));
440 
441   const IsolationInfo kPositiveTestCases[] = {
442       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
443                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1)),
444       // Null party context
445       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
446                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1)),
447       // Empty party context
448       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
449                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1)),
450       // Multiple party context entries.
451       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
452                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1)),
453       // Without SiteForCookies
454       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
455                             kOrigin2, SiteForCookies()),
456       // Request type kOther
457       IsolationInfo::Create(IsolationInfo::RequestType::kOther, kOrigin1,
458                             kOrigin1, SiteForCookies::FromOrigin(kOrigin1)),
459       // Request type kMainframe
460       IsolationInfo::Create(IsolationInfo::RequestType::kMainFrame, kOrigin1,
461                             kOrigin1, SiteForCookies::FromOrigin(kOrigin1)),
462   };
463   for (const auto& info : kPositiveTestCases) {
464     auto rt = IsolationInfo::Deserialize(info.Serialize());
465     ASSERT_TRUE(rt);
466     EXPECT_TRUE(rt->IsEqualForTesting(info));
467   }
468 
469   const IsolationInfo kNegativeTestCases[] = {
470       IsolationInfo::CreateTransient(),
471       // With nonce (i.e transient).
472       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
473                             kOrigin2, SiteForCookies::FromOrigin(kOrigin1),
474                             kNonce1),
475       // With an opaque frame origin. The opaque frame site will cause it to be
476       // considered transient and fail to serialize.
477       IsolationInfo::Create(IsolationInfo::RequestType::kSubFrame, kOrigin1,
478                             url::Origin(),
479                             SiteForCookies::FromOrigin(kOrigin1)),
480   };
481   for (const auto& info : kNegativeTestCases) {
482     EXPECT_TRUE(info.Serialize().empty());
483   }
484 }
485 
486 }  // namespace
487 
488 }  // namespace net
489