import { v5 as uuidv5, v3 as uuidv3, v4 as uuidv4, v1 as uuidv1 } from 'uuid'; import { ANONYMIZATION_CHARACTER as CHAR, getDomainBase, getDomainPath, } from '../src/TelemetryHelpers'; describe('getDomainBase should return protocol plus domain', () => { test('in valid URLs', () => { for (const url of validUrls(numericId)) { const { full, protocolPlusDomain } = url; expect(getDomainBase(full)).toBe(protocolPlusDomain); } }); test('in malformed URLs', () => { for (const url of malformedUrls(numericId)) { const { full, protocolPlusDomain } = url; expect(getDomainBase(full)).toBe(protocolPlusDomain); } }); }); describe('getDomainPath should return pathname, excluding query string', () => { describe('anonymizing strings containing at least one number', () => { test('in valid URLs', () => { for (const url of validUrls(alphanumericId)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); test('in malformed URLs', () => { for (const url of malformedUrls(alphanumericId)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); }); describe('anonymizing UUIDs', () => { test('in valid URLs', () => { for (const url of uuidUrls(validUrls)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); test('in malformed URLs', () => { for (const url of uuidUrls(malformedUrls)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); }); describe('anonymizing emails', () => { test('in valid URLs', () => { for (const url of validUrls(email)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); test('in malformed URLs', () => { for (const url of malformedUrls(email)) { const { full, pathname } = url; expect(getDomainPath(full)).toBe(pathname); } }); }); }); function validUrls(idMaker: typeof alphanumericId | typeof email, char = CHAR) { const firstId = idMaker(); const secondId = idMaker(); const firstIdObscured = char.repeat(firstId.length); const secondIdObscured = char.repeat(secondId.length); return [ { full: `https://test.com/api/v1/users/${firstId}`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}`, }, { full: `https://test.com/api/v1/users/${firstId}/`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}/`, }, { full: `https://test.com/api/v1/users/${firstId}/posts/${secondId}`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}`, }, { full: `https://test.com/api/v1/users/${firstId}/posts/${secondId}/`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}/`, }, { full: `https://test.com/api/v1/users/${firstId}/posts/${secondId}/`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}/`, }, { full: `https://test.com/api/v1/users?id=${firstId}`, protocolPlusDomain: 'https://test.com', pathname: '/api/v1/users', }, { full: `https://test.com/api/v1/users?id=${firstId}&post=${secondId}`, protocolPlusDomain: 'https://test.com', pathname: '/api/v1/users', }, { full: `https://test.com/api/v1/users/${firstId}/posts/${secondId}`, protocolPlusDomain: 'https://test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}`, }, ]; } function malformedUrls(idMaker: typeof numericId | typeof email, char = CHAR) { const firstId = idMaker(); const secondId = idMaker(); const firstIdObscured = char.repeat(firstId.length); const secondIdObscured = char.repeat(secondId.length); return [ { full: `test.com/api/v1/users/${firstId}/posts/${secondId}/`, protocolPlusDomain: 'test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}/`, }, { full: `htp://test.com/api/v1/users/${firstId}/posts/${secondId}/`, protocolPlusDomain: 'htp://test.com', pathname: `/api/v1/users/${firstIdObscured}/posts/${secondIdObscured}/`, }, { full: `test.com/api/v1/users?id=${firstId}`, protocolPlusDomain: 'test.com', pathname: '/api/v1/users', }, { full: `test.com/api/v1/users?id=${firstId}&post=${secondId}`, protocolPlusDomain: 'test.com', pathname: '/api/v1/users', }, ]; } const email = () => encodeURIComponent('test@test.com'); function uuidUrls( urlsMaker: typeof validUrls | typeof malformedUrls, baseName = 'test', namespaceUuid = uuidv4(), ) { return [ ...urlsMaker(() => uuidv5(baseName, namespaceUuid)), ...urlsMaker(uuidv4), ...urlsMaker(() => uuidv3(baseName, namespaceUuid)), ...urlsMaker(uuidv1), ]; } function digit() { return Math.floor(Math.random() * 10); } function positiveDigit(): number { const d = digit(); return d === 0 ? positiveDigit() : d; } function numericId(length = positiveDigit()) { return Array.from({ length }, digit).join(''); } function alphanumericId() { return chooseRandomly([ `john${numericId()}`, `title${numericId(1)}`, numericId(), ]); } const chooseRandomly = (array: T[]) => array[Math.floor(Math.random() * array.length)];