UNPKG

livekit-client

Version:

JavaScript/TypeScript client SDK for LiveKit

178 lines (149 loc) 6.61 kB
import { describe, expect, it } from 'vitest'; import { extractMaxAgeFromRequestHeaders, splitUtf8, toWebsocketUrl } from './utils'; describe('toWebsocketUrl', () => { it('leaves wss urls alone', () => { expect(toWebsocketUrl('ws://mywebsite.com')).toEqual('ws://mywebsite.com'); }); it('converts https to wss', () => { expect(toWebsocketUrl('https://mywebsite.com')).toEqual('wss://mywebsite.com'); }); it('does not convert other parts of URL', () => { expect(toWebsocketUrl('https://httpsmywebsite.com')).toEqual('wss://httpsmywebsite.com'); }); }); describe('splitUtf8', () => { it('splits a string into chunks of the given size', () => { expect(splitUtf8('hello world', 5)).toEqual([ new TextEncoder().encode('hello'), new TextEncoder().encode(' worl'), new TextEncoder().encode('d'), ]); }); it('splits a string with special characters into chunks of the given size', () => { expect(splitUtf8('héllo wörld', 5)).toEqual([ new TextEncoder().encode('héll'), new TextEncoder().encode('o wö'), new TextEncoder().encode('rld'), ]); }); it('splits a string with multi-byte utf8 characters correctly', () => { expect(splitUtf8('こんにちは世界', 5)).toEqual([ new TextEncoder().encode('こ'), new TextEncoder().encode('ん'), new TextEncoder().encode('に'), new TextEncoder().encode('ち'), new TextEncoder().encode('は'), new TextEncoder().encode('世'), new TextEncoder().encode('界'), ]); }); it('handles a string with a single multi-byte utf8 character', () => { expect(splitUtf8('😊', 5)).toEqual([new TextEncoder().encode('😊')]); }); it('handles a string with mixed single and multi-byte utf8 characters', () => { expect(splitUtf8('a😊b', 4)).toEqual([ new TextEncoder().encode('a'), new TextEncoder().encode('😊'), new TextEncoder().encode('b'), ]); }); it('handles an empty string', () => { expect(splitUtf8('', 5)).toEqual([]); }); }); describe('extractMaxAgeFromRequestHeaders', () => { it('extracts max-age from valid Cache-Control header', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=3600'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(3600); }); it('extracts max-age from Cache-Control header with multiple directives', () => { const headers = new Headers(); headers.set('Cache-Control', 'public, max-age=7200, must-revalidate'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(7200); }); it('extracts max-age when it appears at the beginning', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=1800, public, no-cache'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(1800); }); it('extracts max-age when it appears in the middle', () => { const headers = new Headers(); headers.set('Cache-Control', 'public, max-age=900, no-store'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(900); }); it('handles max-age with value 0', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=0'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(0); }); it('handles large max-age values', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=31536000'); // 1 year expect(extractMaxAgeFromRequestHeaders(headers)).toBe(31536000); }); it('returns undefined when Cache-Control header is missing', () => { const headers = new Headers(); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('returns undefined when Cache-Control header exists but has no max-age', () => { const headers = new Headers(); headers.set('Cache-Control', 'public, no-cache, must-revalidate'); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('returns undefined when Cache-Control header is empty', () => { const headers = new Headers(); headers.set('Cache-Control', ''); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('handles Cache-Control header with extra whitespace', () => { const headers = new Headers(); headers.set('Cache-Control', ' public, max-age=1200 , no-cache '); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(1200); }); it('returns undefined for malformed max-age values', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=abc, public'); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('handles max-age with leading zeros', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=0003600'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(3600); }); it('takes the first max-age value when multiple are present', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=1800, public, max-age=3600'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(1800); }); it('handles case-insensitive Cache-Control header name', () => { const headers = new Headers(); headers.set('cache-control', 'max-age=2400'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(2400); }); it('handles Cache-Control with s-maxage (should ignore s-maxage)', () => { const headers = new Headers(); headers.set('Cache-Control', 's-maxage=1800, max-age=3600'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(3600); }); it('returns undefined when only s-maxage is present (no max-age)', () => { const headers = new Headers(); headers.set('Cache-Control', 's-maxage=1800, public'); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('returns undefined for negative max-age values (regex only matches positive digits)', () => { const headers = new Headers(); headers.set('Cache-Control', 'max-age=-100'); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('ignores non standard cache control custom-max-age values', () => { const headers = new Headers(); headers.set('Cache-Control', 'custom-max-age=7200'); expect(extractMaxAgeFromRequestHeaders(headers)).toBeUndefined(); }); it('still works with comma separated non standard cache control custom-max-age values', () => { const headers = new Headers(); headers.set('Cache-Control', 'custom-max-age=7200,max-age=3600'); expect(extractMaxAgeFromRequestHeaders(headers)).toBe(3600); }); });