Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions packages/cloudflare/test/instrumentations/instrumentEnv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,56 @@ describe('instrumentEnv', () => {
expect(instrumentDurableObjectNamespace).toHaveBeenCalledWith(doNamespace);
});

describe('mTLS Fetcher bindings', () => {
function createMtlsFetcherProxy(mockFetch: ReturnType<typeof vi.fn>) {
return new Proxy(
{ fetch: mockFetch },
{
get(target, prop) {
if (prop in target) {
return Reflect.get(target, prop);
}
return () => {};
},
},
);
}

it('does not instrument mTLS Fetcher when enableRpcTracePropagation is disabled', () => {
const mockFetch = vi.fn();
const mtlsFetcher = createMtlsFetcherProxy(mockFetch);
const env = { MY_CERT: mtlsFetcher };
const instrumented = instrumentEnv(env);

expect(instrumented.MY_CERT).toBe(mtlsFetcher);
});

it('preserves existing headers and response on mTLS Fetcher fetch', async () => {
vi.spyOn(SentryCore, '_INTERNAL_getTracingHeadersForFetchRequest').mockReturnValue({
Authorization: 'Bearer client-cert-token',
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
baggage: 'sentry-environment=production',
});

const mockFetch = vi.fn().mockResolvedValue(new Response('mtls-response'));
const mtlsFetcher = createMtlsFetcherProxy(mockFetch);
const env = { MY_CERT: mtlsFetcher };
const instrumented = instrumentEnv(env, { enableRpcTracePropagation: true });

const response = await instrumented.MY_CERT.fetch('https://example.com/api', {
headers: { Authorization: 'Bearer client-cert-token' },
});

const [, init] = mockFetch.mock.calls[0]!;
const headers = new Headers(init?.headers);

expect(instrumented.MY_CERT).not.toBe(mtlsFetcher);
expect(headers.get('Authorization')).toBe('Bearer client-cert-token');
expect(headers.get('sentry-trace')).toBe('12345678901234567890123456789012-1234567890123456-1');
expect(await response.text()).toBe('mtls-response');
});
});

describe('JSRPC RPC method instrumentation', () => {
it('does not inject Sentry RPC meta by default (enableRpcTracePropagation not set)', () => {
vi.spyOn(SentryCore, 'getTraceData').mockReturnValue({
Expand All @@ -238,7 +288,7 @@ describe('instrumentEnv', () => {
const env = { SERVICE: jsrpcProxy };
const instrumented = instrumentEnv(env);

(instrumented.SERVICE as any).myRpcMethod('arg1', 42);
instrumented.SERVICE.myRpcMethod('arg1', 42);

// Without enableRpcTracePropagation, no metadata should be injected
expect(rpcMethod).toHaveBeenCalledWith('arg1', 42);
Expand All @@ -265,7 +315,7 @@ describe('instrumentEnv', () => {
const env = { SERVICE: jsrpcProxy };
const instrumented = instrumentEnv(env, { enableRpcTracePropagation: true });

(instrumented.SERVICE as any).myRpcMethod('arg1', 42);
instrumented.SERVICE.myRpcMethod('arg1', 42);

expect(rpcMethod).toHaveBeenCalledWith('arg1', 42, {
__sentry_rpc_meta__: {
Expand Down Expand Up @@ -296,7 +346,7 @@ describe('instrumentEnv', () => {
const env = { SERVICE: jsrpcProxy };
const instrumented = instrumentEnv(env, { enableRpcTracePropagation: true });

(instrumented.SERVICE as any).fetch('https://example.com');
instrumented.SERVICE.fetch('https://example.com');

// fetch should use HTTP header injection, not trailing arg
const callArgs = mockFetch.mock.calls[0];
Expand All @@ -321,7 +371,7 @@ describe('instrumentEnv', () => {
const env = { SERVICE: jsrpcProxy };
const instrumented = instrumentEnv(env, { enableRpcTracePropagation: true });

(instrumented.SERVICE as any).myRpcMethod('arg1');
instrumented.SERVICE.myRpcMethod('arg1');

expect(rpcMethod).toHaveBeenCalledWith('arg1');
});
Expand Down
Loading