Skip to content

Commit 3268548

Browse files
committed
add new tests
1 parent 6b3ee74 commit 3268548

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

packages/node-core/test/integrations/console.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import {
1212
} from '@sentry/core';
1313
import { consoleIntegration } from '../../src/integrations/console';
1414

15+
// Capture the real native method before any patches are installed.
16+
// This simulates external code doing `const log = console.log` before Sentry init.
17+
// oxlint-disable-next-line no-console
18+
const nativeConsoleLog = console.log;
19+
1520
afterAll(() => {
1621
delete process.env.LAMBDA_TASK_ROOT;
1722
});
@@ -183,6 +188,38 @@ describe('consoleIntegration in Lambda (patchWithDefineProperty)', () => {
183188
expect(handler).toHaveBeenCalledWith(expect.objectContaining({ args: ['should not overflow'], level: 'log' }));
184189
});
185190

191+
it('fires the handler exactly once on re-entrant calls', () => {
192+
const handler = vi.fn();
193+
addConsoleInstrumentationHandler(handler);
194+
handler.mockClear();
195+
196+
const callOrder: string[] = [];
197+
198+
const prevLog = GLOBAL_OBJ.console.log;
199+
GLOBAL_OBJ.console.log = (...args: any[]) => {
200+
callOrder.push('delegate-before-prev');
201+
prevLog(...args);
202+
callOrder.push('delegate-after-prev');
203+
};
204+
205+
handler.mockImplementation(() => {
206+
callOrder.push('handler');
207+
});
208+
209+
GLOBAL_OBJ.console.log('re-entrant test');
210+
211+
// The handler fires exactly once — on the first (outer) entry.
212+
// The re-entrant call through prev() must NOT trigger it a second time.
213+
expect(handler).toHaveBeenCalledTimes(1);
214+
215+
// Verify the full call order:
216+
// 1. wrapper enters → triggerHandlers → handler fires
217+
// 2. wrapper calls consoleDelegate (third-party fn)
218+
// 3. third-party fn calls prev() → re-enters wrapper → nativeMethod (no handler)
219+
// 4. third-party fn continues after prev()
220+
expect(callOrder).toEqual(['handler', 'delegate-before-prev', 'delegate-after-prev']);
221+
});
222+
186223
it('consoleSandbox still bypasses the handler after third-party wrapping', () => {
187224
const handler = vi.fn();
188225
addConsoleInstrumentationHandler(handler);
@@ -199,5 +236,24 @@ describe('consoleIntegration in Lambda (patchWithDefineProperty)', () => {
199236

200237
expect(handler).not.toHaveBeenCalled();
201238
});
239+
240+
it('keeps firing the handler when console.log is set back to the original native method', () => {
241+
const handler = vi.fn();
242+
addConsoleInstrumentationHandler(handler);
243+
244+
// Simulate Lambda-style replacement
245+
GLOBAL_OBJ.console.log = vi.fn();
246+
handler.mockClear();
247+
248+
// Simulate external code restoring a native method reference it captured
249+
// before Sentry init — this should NOT clobber the wrapper.
250+
GLOBAL_OBJ.console.log = nativeConsoleLog;
251+
252+
GLOBAL_OBJ.console.log('after restore to original');
253+
254+
expect(handler).toHaveBeenCalledWith(
255+
expect.objectContaining({ args: ['after restore to original'], level: 'log' }),
256+
);
257+
});
202258
});
203259
});

0 commit comments

Comments
 (0)