import { isAllowedTracingUrl, type PropagatorType } from '../__mocks__'; import { buildAllowedTracingUrls } from '../build-allowed-tracing-urls'; import type { ServiceEntry, State } from '../types'; describe(`[datadog-rum] ${buildAllowedTracingUrls.name}`, () => { let serviceEntry: ServiceEntry; let state: State; beforeEach(() => { serviceEntry = {}; state = { services: new Map() }; state.services.set('foo', serviceEntry); }); const subject = () => buildAllowedTracingUrls(state); test('returns matchers for propagatorTypes', () => { expect(subject()).toEqual( expect.arrayContaining( ['datadog', 'tracecontext', 'b3', 'b3multi'].map(type => ({ match: expect.any(Function), propagatorTypes: [type], })) ) ); }); describe.each(['datadog', 'tracecontext', 'b3', 'b3multi'] as PropagatorType[])( 'with %s matcher', type => { test('traces no URLs', () => { expect(isAllowedTracingUrl(subject(), 'https://example.com', type)).toBe(false); }); describe('when service entry contains string (prefix) matcher', () => { const prefix = 'https://prefix.example.com'; beforeEach(() => { serviceEntry.allowedTracingUrls = { [type]: [prefix] }; }); test('traces URLs starting with the prefix', () => { expect(isAllowedTracingUrl(subject(), `${prefix}/foo`, type)).toBe(true); }); }); describe('when service entry contains RegExp matcher', () => { const regex = /bar/; beforeEach(() => { serviceEntry.allowedTracingUrls = { [type]: [regex] }; }); test('traces URLs that match the pattern', () => { expect( isAllowedTracingUrl( subject(), `https://example.com/${regex.toString()}`, type ) ).toBe(true); }); }); describe('when service entry contains function matcher', () => { const predicate = 'baz'; beforeEach(() => { serviceEntry.allowedTracingUrls = { [type]: [(url: string) => url.includes(predicate)], }; }); test('traces URLs for which the predicate returns true', () => { expect( isAllowedTracingUrl(subject(), `https://example.com/${predicate}`, type) ).toBe(true); }); }); } ); describe('with multiple matchers', () => { let matcher: (url: string) => boolean; beforeEach(() => { matcher = (url: string) => url.includes('foo'); serviceEntry.allowedTracingUrls = { tracecontext: [url => matcher(url)], b3: [/\/b3\//], }; }); test('traces URLs matched under tracecontext', () => { expect(isAllowedTracingUrl(subject(), 'https://foo.com', 'tracecontext')).toBe(true); }); test('traces URLs matched under b3', () => { expect(isAllowedTracingUrl(subject(), 'https://example.com/b3/x', 'b3')).toBe(true); }); describe('when function matcher throws', () => { beforeEach(() => { matcher = () => { throw new Error('Oops!'); }; }); test('does not trace URLs from failing matcher', () => { expect(isAllowedTracingUrl(subject(), 'https://foo.com', 'tracecontext')).toBe( false ); }); test('traces URLs from healthy matcher', () => { expect(isAllowedTracingUrl(subject(), 'https://example.com/b3/x', 'b3')).toBe(true); }); }); }); });