UNPKG

@exodus/networking-spec

Version:

Platform-agnostic test suites for networking related features

164 lines (163 loc) 7.36 kB
import { CONTROL_CHARACTERS, SEPARATORS } from '@exodus/networking-common/cookie/constants'; export function testsuite(getInstance, unrestrictedAccess = true) { describe('CookieJar', () => { let cookieJar; beforeEach(async () => { cookieJar = getInstance(); await cookieJar.removeAll(); }); function normalize(value) { if (Array.isArray(value)) return value; return [value]; } const url = 'https://my-domain.com'; it('should set a cookie', async () => { const cookie = { name: 'csrf', httpOnly: false, value: 'abcd1234', }; await cookieJar.set(cookie, url); const actual = normalize(await cookieJar.get({ url, name: 'csrf' })); expect(actual[0]?.value).toEqual(cookie.value); }); describe('invalid characters', () => { describe('name', () => { const forbidden = new Set([...CONTROL_CHARACTERS, ...SEPARATORS]); forbidden.forEach((character) => { it(`should throw when it contains ${character}`, async () => { const cookie = { name: `name${character}`, value: 'abcdefgh', }; try { await cookieJar.set(cookie, url); expect(true).toEqual(false); } catch (e) { expect(e.message).toContain('invalid character'); } }); }); }); describe('value', () => { const forbidden = new Set([...CONTROL_CHARACTERS, ' ', '"', ',', ';', '\\']); forbidden.forEach((character) => { it(`should throw when it contains ${character}`, async () => { const cookie = { name: 'csrf', value: `value${character}`, }; try { await cookieJar.set(cookie, url); expect(true).toEqual(false); } catch (e) { expect(e.message).toContain('invalid character'); } }); }); }); }); it('should set a cookie with = in its value', async () => { const cookie = { name: 'csrf', value: 'abc=def', }; await cookieJar.set(cookie, url); const actual = normalize(await cookieJar.get({ url, name: 'csrf' })); expect(actual[0]?.value).toEqual(cookie.value); }); it('should set a cookie from response header', async () => { const headerValue = 'name=bruce; SameSite=Lax'; await cookieJar.set(headerValue, url); const [actual] = normalize(await cookieJar.get({ url, name: 'name' })); expect(actual?.value).toEqual('bruce'); }); describe('with cookies', () => { const cookies = [ { name: 'csrf', httpOnly: false, value: 'abcd1234', maxAge: 100, version: '0.1', }, { name: 'session_id', httpOnly: false, value: 'abcd1234', secure: true, }, ]; beforeEach(async () => { await Promise.all(cookies.map((cookie) => cookieJar.set(cookie, url))); }); if (unrestrictedAccess) { describe('unrestricted access', () => { describe('get', () => { it('should get cookies for url and name', async () => { const actual = await cookieJar.get({ url, name: 'csrf' }); expect(actual).toEqual([cookies[0]]); }); it('should get no cookies for other domain and name', async () => { expect(await cookieJar.get({ url: 'https://visit-arkham.com', name: 'csrf' })).toEqual([]); }); it('should get no cookies for other name', async () => { expect(await cookieJar.get({ url, name: 'dr. who' })).toEqual([]); }); }); describe('getAll', () => { it('should return all cookies', async () => { const actual = await cookieJar.getAll(); expect(actual).toEqual(cookies); }); it('should return all cookies for a url', async () => { const otherUrl = 'https://wayne-foundation.com'; const veryTastyCookie = { name: 'recipe', value: 'bat-cookie-blend-heat-ready' }; await cookieJar.set(veryTastyCookie, otherUrl); const actual = await cookieJar.getAll({ url }); expect(actual).toEqual(cookies); }); }); }); } else { describe('restricted access', () => { let jar; beforeEach(() => { jar = cookieJar; }); describe('get', () => { it('should get cookie by name', async () => { const { name, value } = cookies[0] ?? {}; const actual = await jar.get({ name: 'csrf' }); expect(actual).toEqual({ name, value }); }); it('should get no cookies for other name', async () => { expect(await jar.get({ name: 'dr. who' })).toBeUndefined(); }); }); describe('getAll', () => { it('should return all cookies', async () => { const actual = await cookieJar.getAll(); expect(actual).toEqual(cookies.map(({ name, value }) => ({ name, value }))); }); }); }); } it('should remove a cookie', async () => { await cookieJar.remove({ url, name: 'session_id' }); const remaining = await cookieJar.getAll({ url }); expect(remaining.length).toEqual(1); expect(remaining[0]?.name).toEqual('csrf'); }); it('should remove all cookies', async () => { await cookieJar.removeAll(); const cookies = await cookieJar.getAll({ url }); expect(cookies.length).toEqual(0); }); }); }); }