UNPKG

chrome-devtools-frontend

Version:
295 lines (259 loc) • 12.5 kB
// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import * as Protocol from '../../generated/protocol.js'; import * as SDK from './sdk.js'; describe('Cookie', () => { it('can be instantiated without issues', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); assert.strictEqual(cookie.key(), '- name - -'); assert.strictEqual(cookie.name(), 'name'); assert.strictEqual(cookie.value(), 'value'); assert.isUndefined(cookie.type()); assert.isFalse(cookie.httpOnly()); assert.isFalse(cookie.secure()); assert.isUndefined(cookie.sameSite()); assert.strictEqual(cookie.priority(), 'Medium'); assert.isTrue(cookie.session()); assert.isUndefined(cookie.path()); assert.isUndefined(cookie.domain()); assert.isUndefined(cookie.expires()); assert.isUndefined(cookie.maxAge()); assert.strictEqual(cookie.size(), 0); assert.isNull(cookie.url()); assert.isUndefined(cookie.partitionKey()); assert.isNull(cookie.getCookieLine()); }); it('can be created from a protocol Cookie with all optional fields set', () => { const expires = new Date().getTime() + 3600 * 1000; const cookie = SDK.Cookie.Cookie.fromProtocolCookie({ domain: '.example.com', expires: expires / 1000, httpOnly: true, name: 'name', path: '/test', sameSite: Protocol.Network.CookieSameSite.Strict, sameParty: false, secure: true, session: false, size: 23, value: 'value', priority: Protocol.Network.CookiePriority.High, sourcePort: 443, sourceScheme: Protocol.Network.CookieSourceScheme.Secure, partitionKey: {topLevelSite: 'https://a.com', hasCrossSiteAncestor: false}, partitionKeyOpaque: false, }); assert.strictEqual(cookie.key(), '.example.com name /test https://a.com same_site'); assert.strictEqual(cookie.name(), 'name'); assert.strictEqual(cookie.value(), 'value'); assert.isNull(cookie.type()); assert.isTrue(cookie.httpOnly()); assert.isTrue(cookie.secure()); assert.strictEqual(cookie.sameSite(), 'Strict'); assert.isFalse(cookie.session()); assert.strictEqual(cookie.path(), '/test'); assert.strictEqual(cookie.domain(), '.example.com'); assert.strictEqual(cookie.expires(), expires); assert.isUndefined(cookie.maxAge()); assert.strictEqual(cookie.size(), 23); assert.strictEqual(String(cookie.url()), 'https://.example.com/test'); assert.isNull(cookie.getCookieLine()); assert.strictEqual(cookie.sourcePort(), 443); assert.strictEqual(cookie.sourceScheme(), Protocol.Network.CookieSourceScheme.Secure); assert.strictEqual(cookie.partitionKey().topLevelSite, 'https://a.com'); assert.isFalse(cookie.partitionKey().hasCrossSiteAncestor); assert.isFalse(cookie.partitionKeyOpaque()); assert.isTrue(cookie.partitioned()); }); // The jsdoc states that the fields are required, not optional it('can be created from a protocol Cookie with no optional fields set', () => { const cookie = SDK.Cookie.Cookie.fromProtocolCookie({ domain: '.example.com', name: 'name', path: '/test', size: 23, value: 'value', expires: 0, httpOnly: false, sameParty: false, secure: false, session: true, priority: Protocol.Network.CookiePriority.Medium, sourcePort: 80, sourceScheme: Protocol.Network.CookieSourceScheme.NonSecure, }); assert.strictEqual(cookie.key(), '.example.com name /test -'); assert.strictEqual(cookie.name(), 'name'); assert.strictEqual(cookie.value(), 'value'); assert.isNull(cookie.type()); assert.isFalse(cookie.httpOnly()); assert.isFalse(cookie.secure()); assert.isUndefined(cookie.sameSite()); assert.strictEqual(cookie.priority(), 'Medium'); // Session cookie status is derived from the presence of max-age or expires fields. assert.isTrue(cookie.session()); assert.strictEqual(cookie.path(), '/test'); assert.strictEqual(cookie.domain(), '.example.com'); assert.isUndefined(cookie.maxAge()); assert.strictEqual(cookie.size(), 23); assert.strictEqual(String(cookie.url()), 'http://.example.com/test'); assert.isNull(cookie.getCookieLine()); assert.strictEqual(cookie.sourcePort(), 80); assert.strictEqual(cookie.sourceScheme(), Protocol.Network.CookieSourceScheme.NonSecure); }); it('can be created from a protocol Cookie with no optional fields set and non-standard port', () => { const cookie = SDK.Cookie.Cookie.fromProtocolCookie({ domain: '.example.com', name: 'name', path: '/test', size: 23, value: 'value', expires: 0, httpOnly: false, sameParty: false, secure: false, session: true, priority: Protocol.Network.CookiePriority.Medium, sourcePort: 8000, sourceScheme: Protocol.Network.CookieSourceScheme.NonSecure, }); assert.strictEqual(cookie.key(), '.example.com name /test -'); assert.strictEqual(cookie.name(), 'name'); assert.strictEqual(cookie.value(), 'value'); assert.isNull(cookie.type()); assert.isFalse(cookie.httpOnly()); assert.isFalse(cookie.secure()); assert.isUndefined(cookie.sameSite()); assert.strictEqual(cookie.priority(), 'Medium'); // Session cookie status is derived from the presence of max-age or expires fields. assert.isTrue(cookie.session()); assert.strictEqual(cookie.path(), '/test'); assert.strictEqual(cookie.domain(), '.example.com'); assert.isUndefined(cookie.maxAge()); assert.strictEqual(cookie.size(), 23); assert.strictEqual(String(cookie.url()), 'http://.example.com:8000/test'); assert.isNull(cookie.getCookieLine()); assert.strictEqual(cookie.sourcePort(), 8000); assert.strictEqual(cookie.sourceScheme(), Protocol.Network.CookieSourceScheme.NonSecure); }); it('can handle secure urls', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.SECURE); cookie.addAttribute(SDK.Cookie.Attribute.DOMAIN, 'example.com'); cookie.addAttribute(SDK.Cookie.Attribute.PATH, '/test'); assert.strictEqual(String(cookie.url()), 'https://example.com/test'); }); it('can handle insecure urls', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.DOMAIN, 'example.com'); cookie.addAttribute(SDK.Cookie.Attribute.PATH, '/test'); assert.strictEqual(String(cookie.url()), 'http://example.com/test'); }); it('can set SDK.Cookie.Attribute used as flags', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.HTTP_ONLY); assert.isTrue(cookie.httpOnly()); }); it('can set SDK.Cookie.Attribute used as key=value', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.PATH, '/test'); assert.strictEqual(cookie.path(), '/test'); }); it('can set initialize with a different priority', () => { const cookie = new SDK.Cookie.Cookie('name', 'value', null, Protocol.Network.CookiePriority.High); assert.strictEqual(cookie.priority(), 'High'); }); it('can change the priority', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.PRIORITY, 'Low'); assert.strictEqual(cookie.priority(), 'Low'); }); it('can set the cookie line', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.setCookieLine('name=value'); assert.strictEqual(cookie.getCookieLine(), 'name=value'); }); it('can calculate the expiration date for session cookies', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); assert.isNull(cookie.expiresDate(new Date())); }); it('can calculate the expiration date for max age cookies', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); const now = new Date(); const expires = Math.floor(now.getTime()) + 3600 * 1000; cookie.addAttribute(SDK.Cookie.Attribute.MAX_AGE, '3600'); const expiresDate = cookie.expiresDate(now); assert.strictEqual(expiresDate!.toISOString(), new Date(expires).toISOString()); }); it('can calculate the expiration date for cookies with expires attribute', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); const now = new Date(); const expires = Math.floor(now.getTime()) + 3600 * 1000; cookie.addAttribute(SDK.Cookie.Attribute.EXPIRES, expires); const expiresDate = cookie.expiresDate(now); assert.strictEqual(expiresDate!.toISOString(), new Date(expires).toISOString()); }); it('can check if a cookie domain matches a given host', () => { assert.isTrue(SDK.Cookie.Cookie.isDomainMatch('example.com', 'example.com')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('www.example.com', 'example.com')); assert.isTrue(SDK.Cookie.Cookie.isDomainMatch('.example.com', 'example.com')); assert.isTrue(SDK.Cookie.Cookie.isDomainMatch('.example.com', 'www.example.com')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('.www.example.com', 'example.com')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('example.com', 'example.de')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('.example.com', 'example.de')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('.example.de', 'example.de.vu')); assert.isFalse(SDK.Cookie.Cookie.isDomainMatch('example.com', 'notexample.com')); }); it('detects the Partitioned attribute in the Set-Cookie header', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.addAttribute(SDK.Cookie.Attribute.PARTITIONED); assert.isTrue(cookie.partitioned()); assert.isFalse(cookie.hasCrossSiteAncestor()); assert.strictEqual(cookie.topLevelSite(), ''); }); it('can modify partition key', () => { const cookie = new SDK.Cookie.Cookie('name', 'value'); cookie.setPartitionKey('https://a.com', true); assert.isTrue(cookie.partitioned()); assert.isTrue(cookie.hasCrossSiteAncestor()); assert.strictEqual(cookie.topLevelSite(), 'https://a.com'); // set crossSiteAncestor cookie.setHasCrossSiteAncestor(false); assert.isFalse(cookie.hasCrossSiteAncestor()); // set topLevelSite cookie.setTopLevelSite('https://b.com', true); assert.isTrue(cookie.hasCrossSiteAncestor()); assert.strictEqual(cookie.topLevelSite(), 'https://b.com'); }); it('can compare partition keys', () => { const unpartitionedCookie = new SDK.Cookie.Cookie('name', 'value'); assert.isFalse(unpartitionedCookie.partitioned()); assert.isFalse(Boolean(unpartitionedCookie.partitionKey())); const partitionedCookie = new SDK.Cookie.Cookie('name', 'value'); partitionedCookie.setPartitionKey('https://a.com', true); assert.isTrue(partitionedCookie.partitioned()); assert.isTrue(Boolean(partitionedCookie.partitionKey())); assert.notStrictEqual(unpartitionedCookie.partitionKey(), partitionedCookie.partitionKey()); assert.strictEqual(partitionedCookie.partitionKey(), partitionedCookie.partitionKey()); const differentHasCrossSiteAncestor = new SDK.Cookie.Cookie('name', 'value'); differentHasCrossSiteAncestor.setPartitionKey('https://a.com', false); assert.isTrue(differentHasCrossSiteAncestor.partitioned()); assert.notStrictEqual(differentHasCrossSiteAncestor.partitionKey(), partitionedCookie.partitionKey()); const differentTopLevel = new SDK.Cookie.Cookie('name', 'value'); differentTopLevel.setPartitionKey('https://b.com', true); assert.isTrue(differentTopLevel.partitioned()); assert.notStrictEqual(differentTopLevel.partitionKey(), partitionedCookie.partitionKey()); }); it('can set opaque partition key', () => { const partitionedCookie = new SDK.Cookie.Cookie('name', 'value'); partitionedCookie.setPartitionKey('https://a.com', true); assert.isTrue(partitionedCookie.partitioned()); assert.isTrue(partitionedCookie.hasCrossSiteAncestor()); assert.isFalse(partitionedCookie.partitionKeyOpaque()); // Set key to opaque and confirm the the key is opaque and cross site. partitionedCookie.setPartitionKeyOpaque(); assert.isTrue(partitionedCookie.partitionKeyOpaque()); assert.isFalse(partitionedCookie.hasCrossSiteAncestor()); }); });