From a403986750ad685b03a13aa8fa45366dfe499b49 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 17:14:05 -0700 Subject: [PATCH 01/10] treat type errors in tests as errors rather than warnings --- jest.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 208a643187f4..8b7b7f1f5b7c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,7 +11,6 @@ module.exports = { globals: { 'ts-jest': { tsconfig: '/tsconfig.test.json', - diagnostics: false, }, }, testPathIgnorePatterns: ['/build/', '/node_modules/'], From a1a8bd6636a0dab599b51308cbc14feba981c8e8 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 21:32:45 -0700 Subject: [PATCH 02/10] fix type errors in utils tests --- packages/utils/test/clientreport.test.ts | 2 +- packages/utils/test/syncpromise.test.ts | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/utils/test/clientreport.test.ts b/packages/utils/test/clientreport.test.ts index 8d98291c3a14..156ddb95008f 100644 --- a/packages/utils/test/clientreport.test.ts +++ b/packages/utils/test/clientreport.test.ts @@ -3,7 +3,7 @@ import { ClientReport } from '@sentry/types'; import { createClientReportEnvelope } from '../src/clientreport'; import { serializeEnvelope } from '../src/envelope'; -const DEFAULT_DISCARDED_EVENTS: Array = [ +const DEFAULT_DISCARDED_EVENTS: ClientReport['discarded_events'] = [ { reason: 'before_send', category: 'event', diff --git a/packages/utils/test/syncpromise.test.ts b/packages/utils/test/syncpromise.test.ts index 6164c666d967..cdb0a7c6e0e7 100644 --- a/packages/utils/test/syncpromise.test.ts +++ b/packages/utils/test/syncpromise.test.ts @@ -1,7 +1,7 @@ import { rejectedSyncPromise, resolvedSyncPromise, SyncPromise } from '../src/syncpromise'; describe('SyncPromise', () => { - test('simple', () => { + test('simple', async () => { expect.assertions(1); return new SyncPromise(resolve => { @@ -11,7 +11,7 @@ describe('SyncPromise', () => { }); }); - test('simple chaining', () => { + test('simple chaining', async () => { expect.assertions(1); return new SyncPromise(resolve => { @@ -94,7 +94,7 @@ describe('SyncPromise', () => { ); }); - test('simple static', () => { + test('simple static', async () => { expect.assertions(1); const p = resolvedSyncPromise(10); @@ -103,7 +103,7 @@ describe('SyncPromise', () => { }); }); - test('using new Promise internally', () => { + test('using new Promise internally', async () => { expect.assertions(2); return new SyncPromise(done => { @@ -120,7 +120,7 @@ describe('SyncPromise', () => { }); }); - test('with setTimeout', () => { + test('with setTimeout', async () => { jest.useFakeTimers(); expect.assertions(1); @@ -175,7 +175,7 @@ describe('SyncPromise', () => { expect(qp).toHaveProperty('_value'); }); - test('multiple then returning undefined', () => { + test('multiple then returning undefined', async () => { expect.assertions(3); return new SyncPromise(resolve => { @@ -192,7 +192,7 @@ describe('SyncPromise', () => { }); }); - test('multiple then returning different values', () => { + test('multiple then returning different values', async () => { expect.assertions(3); return new SyncPromise(resolve => { @@ -211,7 +211,7 @@ describe('SyncPromise', () => { }); }); - test('multiple then returning different SyncPromise', () => { + test('multiple then returning different SyncPromise', async () => { expect.assertions(2); return new SyncPromise(resolve => { @@ -228,7 +228,7 @@ describe('SyncPromise', () => { }); }); - test('reject immediatly and do not call then', () => { + test('reject immediatly and do not call then', async () => { expect.assertions(1); return new SyncPromise((_, reject) => { @@ -242,7 +242,7 @@ describe('SyncPromise', () => { }); }); - test('reject', () => { + test('reject', async () => { expect.assertions(1); return new SyncPromise((_, reject) => { @@ -252,7 +252,7 @@ describe('SyncPromise', () => { }); }); - test('rejecting after first then', () => { + test('rejecting after first then', async () => { expect.assertions(2); return new SyncPromise(resolve => { From c12ff0360415fa27e62c316a63bf34d50891b88c Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:33:59 -0700 Subject: [PATCH 03/10] fix type errors in hub tests --- packages/hub/test/global.test.ts | 4 ++ packages/hub/test/hub.test.ts | 92 ++++++++++++++++++++++++-------- packages/hub/test/scope.test.ts | 22 ++++---- 3 files changed, 86 insertions(+), 32 deletions(-) diff --git a/packages/hub/test/global.test.ts b/packages/hub/test/global.test.ts index ec63679d5592..8dc32acb7fc7 100644 --- a/packages/hub/test/global.test.ts +++ b/packages/hub/test/global.test.ts @@ -1,5 +1,9 @@ +import { getGlobalObject } from '@sentry/utils'; + import { getCurrentHub, getHubFromCarrier, Hub } from '../src'; +const global = getGlobalObject(); + describe('global', () => { test('getGlobalHub', () => { expect(getCurrentHub()).toBeTruthy(); diff --git a/packages/hub/test/hub.test.ts b/packages/hub/test/hub.test.ts index 98c8dcea0636..6754ac258669 100644 --- a/packages/hub/test/hub.test.ts +++ b/packages/hub/test/hub.test.ts @@ -1,4 +1,5 @@ -import { Event } from '@sentry/types'; +/* eslint-disable @typescript-eslint/unbound-method */ +import { Client, Event } from '@sentry/types'; import { getCurrentHub, Hub, Scope } from '../src'; @@ -15,7 +16,18 @@ function makeClient() { getIntegration: jest.fn(), setupIntegrations: jest.fn(), captureMessage: jest.fn(), - }; + } as unknown as Client; +} + +/** + * Return an array containing the arguments passed to the given mocked or spied-upon function. + * + * By default, the args passed to the first call of the function are returned, but it is also possible to retrieve the + * nth call by passing `callIndex`. If the function wasn't called, an error message is returned instead. + */ +function getPassedArgs(mock: (...args: any[]) => any, callIndex: number = 0): any[] { + const asMock = mock as jest.MockedFunction<(...args: any[]) => any>; + return asMock.mock.calls[callIndex] || ["Error: Function wasn't called."]; } describe('Hub', () => { @@ -102,7 +114,7 @@ describe('Hub', () => { }); }); - test('inherit processors', () => { + test('inherit processors', async () => { expect.assertions(1); const event: Event = { extra: { b: 3 }, @@ -210,34 +222,45 @@ describe('Hub', () => { test('simple', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureException('a'); - expect(testClient.captureException).toHaveBeenCalled(); - expect(testClient.captureException.mock.calls[0][0]).toBe('a'); + const args = getPassedArgs(testClient.captureException); + + expect(args[0]).toBe('a'); }); test('should set event_id in hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureException('a'); - expect(testClient.captureException.mock.calls[0][1].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureException('a', { event_id: id }); - expect(testClient.captureException.mock.calls[0][1].event_id).toBe(id); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].event_id).toBe(id); }); test('should generate hint if not provided in the call', () => { const testClient = makeClient(); const hub = new Hub(testClient); const ex = new Error('foo'); + hub.captureException(ex); - expect(testClient.captureException.mock.calls[0][1].originalException).toBe(ex); - expect(testClient.captureException.mock.calls[0][1].syntheticException).toBeInstanceOf(Error); - expect(testClient.captureException.mock.calls[0][1].syntheticException.message).toBe('Sentry syntheticException'); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].originalException).toBe(ex); + expect(args[1].syntheticException).toBeInstanceOf(Error); + expect(args[1].syntheticException.message).toBe('Sentry syntheticException'); }); }); @@ -245,32 +268,44 @@ describe('Hub', () => { test('simple', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('a'); - expect(testClient.captureMessage.mock.calls[0][0]).toBe('a'); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[0]).toBe('a'); }); test('should set event_id in hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('a'); - expect(testClient.captureMessage.mock.calls[0][2].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureMessage('a', undefined, { event_id: id }); - expect(testClient.captureMessage.mock.calls[0][2].event_id).toBe(id); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].event_id).toBe(id); }); test('should generate hint if not provided in the call', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('foo'); - expect(testClient.captureMessage.mock.calls[0][2].originalException).toBe('foo'); - expect(testClient.captureMessage.mock.calls[0][2].syntheticException).toBeInstanceOf(Error); - expect(testClient.captureMessage.mock.calls[0][2].syntheticException.message).toBe('foo'); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].originalException).toBe('foo'); + expect(args[2].syntheticException).toBeInstanceOf(Error); + expect(args[2].syntheticException.message).toBe('foo'); }); }); @@ -281,8 +316,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][0]).toBe(event); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[0]).toBe(event); }); test('should set event_id in hint', () => { @@ -291,8 +329,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { @@ -302,8 +343,11 @@ describe('Hub', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureEvent(event, { event_id: id }); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toBe(id); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toBe(id); }); test('sets lastEventId', () => { @@ -312,8 +356,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toEqual(hub.lastEventId()); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toEqual(hub.lastEventId()); }); test('transactions do not set lastEventId', () => { @@ -323,8 +370,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).not.toEqual(hub.lastEventId()); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).not.toEqual(hub.lastEventId()); }); }); diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index 7cca748fb6f8..b734ac59fcf6 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -1,4 +1,4 @@ -import { Event, EventHint } from '@sentry/types'; +import { Event, EventHint, RequestSessionStatus } from '@sentry/types'; import { getGlobalObject } from '@sentry/utils'; import { addGlobalEventProcessor, Scope } from '../src'; @@ -194,7 +194,7 @@ describe('Scope', () => { }); describe('applyToEvent', () => { - test('basic usage', () => { + test('basic usage', async () => { expect.assertions(9); const scope = new Scope(); @@ -222,7 +222,7 @@ describe('Scope', () => { }); }); - test('merge with existing event data', () => { + test('merge with existing event data', async () => { expect.assertions(8); const scope = new Scope(); scope.setExtra('a', 2); @@ -291,7 +291,7 @@ describe('Scope', () => { }); }); - test('scope level should have priority over event level', () => { + test('scope level should have priority over event level', async () => { expect.assertions(1); const scope = new Scope(); scope.setLevel('warning'); @@ -302,7 +302,7 @@ describe('Scope', () => { }); }); - test('scope transaction should have priority over event transaction', () => { + test('scope transaction should have priority over event transaction', async () => { expect.assertions(1); const scope = new Scope(); scope.setTransactionName('/abc'); @@ -511,10 +511,10 @@ describe('Scope', () => { contexts: { bar: { id: '3' }, baz: { id: '4' } }, extra: { bar: '3', baz: '4' }, fingerprint: ['bar'], - level: 'warning', + level: 'warning' as const, tags: { bar: '3', baz: '4' }, user: { id: '42' }, - requestSession: { status: 'errored' }, + requestSession: { status: 'errored' as RequestSessionStatus }, }; const updatedScope = scope.update(localAttributes) as any; @@ -541,7 +541,7 @@ describe('Scope', () => { }); describe('addEventProcessor', () => { - test('should allow for basic event manipulation', () => { + test('should allow for basic event manipulation', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, @@ -566,7 +566,7 @@ describe('Scope', () => { }); }); - test('should work alongside global event processors', () => { + test('should work alongside global event processors', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, @@ -667,7 +667,7 @@ describe('Scope', () => { }); }); - test('should drop an event when any of processors return null', () => { + test('should drop an event when any of processors return null', async () => { expect.assertions(1); const event: Event = { extra: { b: 3 }, @@ -680,7 +680,7 @@ describe('Scope', () => { }); }); - test('should have an access to the EventHint', () => { + test('should have an access to the EventHint', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, From 7c00a179add49e403699edb0c8dca9d1ce5d8794 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:35:01 -0700 Subject: [PATCH 04/10] fix type errors in integrations tests --- .../integrations/test/captureconsole.test.ts | 54 ++++++++++--------- packages/integrations/test/debug.test.ts | 1 + packages/integrations/test/dedupe.test.ts | 14 +++-- .../integrations/test/extraerrordata.test.ts | 4 +- packages/integrations/test/offline.test.ts | 2 +- .../test/reportingobserver.test.ts | 45 ++++++++-------- .../integrations/test/rewriteframes.test.ts | 6 --- packages/integrations/tsconfig.test.json | 2 +- 8 files changed, 67 insertions(+), 61 deletions(-) diff --git a/packages/integrations/test/captureconsole.test.ts b/packages/integrations/test/captureconsole.test.ts index bb6cce8110d3..966c76879522 100644 --- a/packages/integrations/test/captureconsole.test.ts +++ b/packages/integrations/test/captureconsole.test.ts @@ -1,4 +1,5 @@ -import { Event, Integration } from '@sentry/types'; +/* eslint-disable @typescript-eslint/unbound-method */ +import { Event, Hub, Integration } from '@sentry/types'; import { CaptureConsole } from '../src/captureconsole'; @@ -16,10 +17,11 @@ const mockHub = { captureException: jest.fn(), }; -const getMockHubWithIntegration = (integration: Integration) => ({ - ...mockHub, - getIntegration: jest.fn(() => integration), -}); +const getMockHubWithIntegration = (integration: Integration) => + ({ + ...mockHub, + getIntegration: jest.fn(() => integration), + } as unknown as Hub); // We're using this to un-monkey patch the console after each test. const originalConsole = Object.assign({}, global.console); @@ -36,7 +38,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'warn'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); expect(global.console.error).toBe(originalConsole.error); // not monkey patched @@ -48,7 +50,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // expect a set of defined console levels to have been monkey patched @@ -68,7 +70,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: [] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // expect the default set of console levels not to have been monkey patched @@ -93,7 +95,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); }).not.toThrow(); @@ -105,7 +107,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -119,7 +121,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -135,7 +137,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -154,7 +156,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 3); @@ -168,7 +170,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 3, 'expression is false'); @@ -182,7 +184,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 2); @@ -192,7 +194,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); const someError = new Error('some error'); @@ -206,7 +208,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); const someError = new Error('some error'); @@ -220,7 +222,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.error('some message'); @@ -233,7 +235,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.error('some non-error message'); @@ -247,7 +249,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['info'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.info('some message'); @@ -265,7 +267,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.log('some message 1', 'some message 2'); @@ -281,11 +283,11 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'someNonExistingLevel', 'error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // The provided level should not be created - expect(global.console['someNonExistingLevel']).toBeUndefined(); + expect((global.console as any)['someNonExistingLevel']).toBeUndefined(); // Ohter levels should be wrapped as expected expect(global.console.log).not.toBe(originalConsole.log); @@ -296,7 +298,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, // simulate not having the integration registered + () => getMockHubWithIntegration(null as any), // simulate not having the integration registered ); // Console should be wrapped @@ -310,12 +312,12 @@ describe('CaptureConsole setup', () => { it("should not crash when the original console methods don't exist at time of invocation", () => { const originalConsoleLog = global.console.log; - global.console.log = undefined; // don't `delete` here, otherwise `fill` won't wrap the function + global.console.log = undefined as any; // don't `delete` here, otherwise `fill` won't wrap the function const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); expect(() => { diff --git a/packages/integrations/test/debug.test.ts b/packages/integrations/test/debug.test.ts index 5c2f84f5d1e6..768c9606a1fb 100644 --- a/packages/integrations/test/debug.test.ts +++ b/packages/integrations/test/debug.test.ts @@ -8,6 +8,7 @@ const mockGetCurrentHub = (getIntegrationResult: Integration) => ({ // Replace console log with a mock so we can check for invocations const mockConsoleLog = jest.fn(); +// eslint-disable-next-line @typescript-eslint/unbound-method const originalConsoleLog = global.console.log; global.console.log = mockConsoleLog; diff --git a/packages/integrations/test/dedupe.test.ts b/packages/integrations/test/dedupe.test.ts index c56ab59d5b82..8bc354ffa620 100644 --- a/packages/integrations/test/dedupe.test.ts +++ b/packages/integrations/test/dedupe.test.ts @@ -1,13 +1,21 @@ -import { Event } from '@sentry/types'; +import { Event as SentryEvent, Exception, StackFrame, Stacktrace } from '@sentry/types'; import { _shouldDropEvent } from '../src/dedupe'; +type EventWithException = SentryEvent & { + exception: { + values: ExceptionWithStacktrace[]; + }; +}; +type ExceptionWithStacktrace = Exception & { stacktrace: StacktraceWithFrames }; +type StacktraceWithFrames = Stacktrace & { frames: StackFrame[] }; + /** JSDoc */ function clone(data: T): T { return JSON.parse(JSON.stringify(data)); } -const messageEvent: Event = { +const messageEvent: EventWithException = { fingerprint: ['MrSnuffles'], message: 'PickleRick', exception: { @@ -34,7 +42,7 @@ const messageEvent: Event = { ], }, }; -const exceptionEvent: Event = { +const exceptionEvent: EventWithException = { exception: { values: [ { diff --git a/packages/integrations/test/extraerrordata.test.ts b/packages/integrations/test/extraerrordata.test.ts index ed76a2dc75ca..68e38720f761 100644 --- a/packages/integrations/test/extraerrordata.test.ts +++ b/packages/integrations/test/extraerrordata.test.ts @@ -71,7 +71,7 @@ describe('ExtraErrorData()', () => { event = { // @ts-ignore Allow contexts on event contexts: { - foo: 42, + foo: { bar: 42 }, }, }; const error = new TypeError('foo') as ExtendedError; @@ -85,7 +85,7 @@ describe('ExtraErrorData()', () => { TypeError: { baz: 42, }, - foo: 42, + foo: { bar: 42 }, }); }); diff --git a/packages/integrations/test/offline.test.ts b/packages/integrations/test/offline.test.ts index 1f728d835abd..9c4eb8ad2e36 100644 --- a/packages/integrations/test/offline.test.ts +++ b/packages/integrations/test/offline.test.ts @@ -169,7 +169,7 @@ function initIntegration(options: { maxStoredEvents?: number } = {}): void { jest.spyOn(utils, 'getGlobalObject').mockImplementation( () => ({ - addEventListener: (_windowEvent, callback) => { + addEventListener: (_windowEvent: any, callback: any) => { eventListeners.push(callback); }, navigator: { diff --git a/packages/integrations/test/reportingobserver.test.ts b/packages/integrations/test/reportingobserver.test.ts index 1d6417e8ccc7..91547d5572f8 100644 --- a/packages/integrations/test/reportingobserver.test.ts +++ b/packages/integrations/test/reportingobserver.test.ts @@ -1,4 +1,4 @@ -import { Integration } from '@sentry/types'; +import { Hub, Integration } from '@sentry/types'; import { ReportingObserver } from '../src/reportingobserver'; @@ -13,10 +13,11 @@ const mockHub = { captureMessage: jest.fn(), }; -const getMockHubWithIntegration = (integration: Integration) => ({ - ...mockHub, - getIntegration: jest.fn(() => integration), -}); +const getMockHubWithIntegration = (integration: Integration) => + ({ + ...mockHub, + getIntegration: jest.fn(() => integration), + } as unknown as Hub); const mockReportingObserverConstructor = jest.fn(); const mockObserve = jest.fn(); @@ -49,7 +50,7 @@ describe('ReportingObserver', () => { expect(() => { reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, + () => getMockHubWithIntegration(null as any), ); }).not.toThrow(); @@ -61,7 +62,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -75,7 +76,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver({ types: ['crash'] }); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -89,7 +90,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -103,7 +104,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockObserve).toHaveBeenCalledTimes(1); @@ -115,7 +116,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, + () => getMockHubWithIntegration(null as any), ); expect(() => { @@ -129,7 +130,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([ @@ -144,7 +145,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([ @@ -160,7 +161,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report1 = { type: 'crash', url: 'some url 1', body: { crashId: 'id1' } } as const; @@ -176,7 +177,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([{ type: 'crash', url: 'some url' }]); @@ -188,7 +189,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -207,7 +208,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -225,7 +226,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -243,7 +244,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -260,7 +261,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { type: 'crash', url: 'some url', body: { crashId: '', reason: '' } } as const; @@ -274,7 +275,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -292,7 +293,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { diff --git a/packages/integrations/test/rewriteframes.test.ts b/packages/integrations/test/rewriteframes.test.ts index ff18e16f753d..bbe0a157e44a 100644 --- a/packages/integrations/test/rewriteframes.test.ts +++ b/packages/integrations/test/rewriteframes.test.ts @@ -3,18 +3,12 @@ import { Event, StackFrame } from '@sentry/types'; import { RewriteFrames } from '../src/rewriteframes'; let rewriteFrames: RewriteFrames; -let messageEvent: Event; let exceptionEvent: Event; let windowsExceptionEvent: Event; let multipleStacktracesEvent: Event; describe('RewriteFrames', () => { beforeEach(() => { - messageEvent = { - stacktrace: { - frames: [{ filename: '/www/src/app/file1.js' }, { filename: '/www/src/app/mo\\dule/file2.js' }], - }, - }; exceptionEvent = { exception: { values: [ diff --git a/packages/integrations/tsconfig.test.json b/packages/integrations/tsconfig.test.json index af7e36ec0eda..87f6afa06b86 100644 --- a/packages/integrations/tsconfig.test.json +++ b/packages/integrations/tsconfig.test.json @@ -5,7 +5,7 @@ "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["jest"] + "types": ["node", "jest"] // other package-specific, test-specific options } From b488fcf3a8ba53a2733c794d7de019c6fcd21c67 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:35:28 -0700 Subject: [PATCH 05/10] fix type errors in browser tests --- .../test/unit/integrations/linkederrors.test.ts | 14 ++++++++++---- .../browser/test/unit/mocks/simpletransport.ts | 1 + packages/browser/test/unit/transports/base.test.ts | 6 ++++-- .../browser/test/unit/transports/new-xhr.test.ts | 10 +++++----- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 6650877ff39b..6ccd4b5975a3 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -1,4 +1,4 @@ -import { ExtendedError } from '@sentry/types'; +import { Event as SentryEvent, Exception, ExtendedError } from '@sentry/types'; import { createStackParser } from '@sentry/utils'; import { BrowserClient } from '../../../src/client'; @@ -8,6 +8,12 @@ import { setupBrowserTransport } from '../../../src/transports'; const parser = createStackParser(...defaultStackParsers); +type EventWithException = SentryEvent & { + exception: { + values: Exception[]; + }; +}; + describe('LinkedErrors', () => { describe('handler', () => { it('should bail out if event does not contain exception', () => { @@ -44,7 +50,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { originalException, - }); + }) as EventWithException; // It shouldn't include root exception, as it's already processed in the event by the main error handler expect(result.exception.values.length).toBe(3); @@ -75,7 +81,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { originalException, - }); + }) as EventWithException; expect(result.exception.values.length).toBe(3); expect(result.exception.values[0].type).toBe('SyntaxError'); @@ -103,7 +109,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, { originalException, - }); + }) as EventWithException; expect(result.exception.values.length).toBe(2); expect(result.exception.values[0].type).toBe('TypeError'); diff --git a/packages/browser/test/unit/mocks/simpletransport.ts b/packages/browser/test/unit/mocks/simpletransport.ts index 7d0b0e9498df..398feb1a3e6a 100644 --- a/packages/browser/test/unit/mocks/simpletransport.ts +++ b/packages/browser/test/unit/mocks/simpletransport.ts @@ -3,6 +3,7 @@ import { eventStatusFromHttpCode, resolvedSyncPromise } from '@sentry/utils'; import { Event, Response } from '../../../src'; import { BaseTransport } from '../../../src/transports'; +// @ts-ignore It's okay that we're not implementing the `_sendRequest()` method because we don't use it in our tests export class SimpleTransport extends BaseTransport { public sendEvent(_: Event): PromiseLike { return this._buffer.add(() => diff --git a/packages/browser/test/unit/transports/base.test.ts b/packages/browser/test/unit/transports/base.test.ts index 2f9fc26d07be..9df498352c1e 100644 --- a/packages/browser/test/unit/transports/base.test.ts +++ b/packages/browser/test/unit/transports/base.test.ts @@ -3,6 +3,8 @@ import { BaseTransport } from '../../../src/transports/base'; const testDsn = 'https://123@sentry.io/42'; const envelopeEndpoint = 'https://sentry.io/api/42/envelope/?sentry_key=123&sentry_version=7'; +// @ts-ignore We're purposely not implementing the methods of the abstract `BaseTransport` class in order to be able to +// assert on what the class provides and what it leaves to the concrete class to implement class SimpleTransport extends BaseTransport {} describe('BaseTransport', () => { @@ -111,12 +113,12 @@ describe('BaseTransport', () => { }); }); - it('doesnt provide sendEvent() implementation', () => { + it('doesnt provide sendEvent() implementation', async () => { expect.assertions(1); const transport = new SimpleTransport({ dsn: testDsn }); try { - void transport.sendEvent({}); + await transport.sendEvent({}); } catch (e) { expect(e).toBeDefined(); } diff --git a/packages/browser/test/unit/transports/new-xhr.test.ts b/packages/browser/test/unit/transports/new-xhr.test.ts index 5b3bbda313c7..603b0f6037dc 100644 --- a/packages/browser/test/unit/transports/new-xhr.test.ts +++ b/packages/browser/test/unit/transports/new-xhr.test.ts @@ -27,7 +27,7 @@ function createXHRMock() { case 'Retry-After': return '10'; case `${retryAfterSeconds}`: - return; + return null; default: return `${retryAfterSeconds}:error:scope`; } @@ -57,7 +57,7 @@ describe('NewXHRTransport', () => { expect(xhrMock.setRequestHeader).toHaveBeenCalledTimes(0); expect(xhrMock.send).toHaveBeenCalledTimes(0); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.open).toHaveBeenCalledTimes(1); expect(xhrMock.open).toHaveBeenCalledWith('POST', DEFAULT_XHR_TRANSPORT_OPTIONS.url); @@ -70,7 +70,7 @@ describe('NewXHRTransport', () => { const [res] = await Promise.all([ transport.send(ERROR_ENVELOPE), - (xhrMock as XMLHttpRequest).onreadystatechange(null), + (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event), ]); expect(res).toBeDefined(); @@ -80,7 +80,7 @@ describe('NewXHRTransport', () => { it('sets rate limit response headers', async () => { const transport = makeNewXHRTransport(DEFAULT_XHR_TRANSPORT_OPTIONS); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.getResponseHeader).toHaveBeenCalledTimes(2); expect(xhrMock.getResponseHeader).toHaveBeenCalledWith('X-Sentry-Rate-Limits'); @@ -99,7 +99,7 @@ describe('NewXHRTransport', () => { }; const transport = makeNewXHRTransport(options); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.setRequestHeader).toHaveBeenCalledTimes(3); expect(xhrMock.setRequestHeader).toHaveBeenCalledWith('referrerPolicy', headers.referrerPolicy); From 811222d6ee546a5df30349ad56b9fa9f6bc24adb Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:35:46 -0700 Subject: [PATCH 06/10] fix type errors in node tests --- packages/node/test/integrations/http.test.ts | 2 +- packages/node/test/transports/http.test.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 5a05d79e3b1b..f66f847cd298 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -168,7 +168,7 @@ describe('default protocols', () => { let nockProtocol = 'https'; const proxy = 'http://:3128'; - const agent = new HttpsProxyAgent(proxy); + const agent = HttpsProxyAgent(proxy); if (NODE_VERSION.major && NODE_VERSION.major < 9) { nockProtocol = 'http'; diff --git a/packages/node/test/transports/http.test.ts b/packages/node/test/transports/http.test.ts index e2e837fee2d3..8c7abfa2ade2 100644 --- a/packages/node/test/transports/http.test.ts +++ b/packages/node/test/transports/http.test.ts @@ -31,6 +31,7 @@ const sessionPayload: Session = { update: jest.fn(), close: jest.fn(), toJSON: jest.fn(), + ignoreDuration: false, }; const sessionsPayload: SessionAggregates = { attrs: { environment: 'test', release: '1.0' }, From 0ec822b02f5fb743011050b315b765a013f7ed69 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:36:40 -0700 Subject: [PATCH 07/10] fix type errors in tracing tests --- .../test/browser/browsertracing.test.ts | 4 +- packages/tracing/test/browser/metrics.test.ts | 12 ++---- packages/tracing/test/browser/request.test.ts | 38 +++++++++---------- packages/tracing/test/browser/router.test.ts | 3 +- packages/tracing/test/errors.test.ts | 15 ++++---- packages/tracing/test/idletransaction.test.ts | 8 ++-- packages/utils/src/instrument.ts | 4 +- 7 files changed, 41 insertions(+), 43 deletions(-) diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index 510befc29064..dfa4e0436b8c 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,7 +1,7 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; -import { getGlobalObject } from '@sentry/utils'; +import { getGlobalObject, InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; import { @@ -24,7 +24,7 @@ jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback): void => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback): void => { if (type === 'history') { // rather than actually add the navigation-change handler, grab a reference to it, so we can trigger it manually mockChangeHistory = callback; diff --git a/packages/tracing/test/browser/metrics.test.ts b/packages/tracing/test/browser/metrics.test.ts index 7133f7975221..eb79ff30df93 100644 --- a/packages/tracing/test/browser/metrics.test.ts +++ b/packages/tracing/test/browser/metrics.test.ts @@ -1,11 +1,5 @@ import { Span, Transaction } from '../../src'; -import { - _startChild, - addResourceSpans, - DEFAULT_METRICS_INSTR_OPTIONS, - MetricsInstrumentation, - ResourceEntry, -} from '../../src/browser/metrics'; +import { _startChild, addResourceSpans, MetricsInstrumentation, ResourceEntry } from '../../src/browser/metrics'; import { addDOMPropertiesToGlobal } from '../testutils'; // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-var @@ -186,7 +180,7 @@ describe('MetricsInstrumentation', () => { jest.spyOn(MetricsInstrumentation.prototype as any, tracker), ); - new MetricsInstrumentation(DEFAULT_METRICS_INSTR_OPTIONS); + new MetricsInstrumentation(); trackers.forEach(tracker => expect(tracker).not.toBeCalled()); }); @@ -200,7 +194,7 @@ describe('MetricsInstrumentation', () => { const trackers = ['_trackCLS', '_trackLCP', '_trackFID'].map(tracker => jest.spyOn(MetricsInstrumentation.prototype as any, tracker), ); - new MetricsInstrumentation(DEFAULT_METRICS_INSTR_OPTIONS); + new MetricsInstrumentation(); global.process = backup; trackers.forEach(tracker => expect(tracker).toBeCalled()); diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index a31aa10d5c8a..65823e293351 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -4,7 +4,7 @@ import { Hub, makeMain } from '@sentry/hub'; import * as utils from '@sentry/utils'; import { Span, spanStatusfromHttpCode, Transaction } from '../../src'; -import { fetchCallback, FetchData, instrumentOutgoingRequests, xhrCallback, XHRData } from '../../src/browser/request'; +import { fetchCallback, FetchData, instrumentOutgoingRequests, xhrCallback } from '../../src/browser/request'; import { addExtensionMethods } from '../../src/hubextensions'; import * as tracingUtils from '../../src/utils'; @@ -56,7 +56,7 @@ describe('callbacks', () => { fetchData: { url: 'http://dogs.are.great/', method: 'GET' }, startTimestamp, }; - const xhrHandlerData: XHRData = { + const xhrHandlerData = { xhr: { __sentry_xhr__: { method: 'GET', @@ -130,17 +130,17 @@ describe('callbacks', () => { // triggered by request being sent fetchCallback(fetchHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); expect(newSpan).toBeInstanceOf(Span); - expect(newSpan!.data).toEqual({ + expect(newSpan.data).toEqual({ method: 'GET', type: 'fetch', url: 'http://dogs.are.great/', }); - expect(newSpan!.description).toBe('GET http://dogs.are.great/'); - expect(newSpan!.op).toBe('http.client'); + expect(newSpan.description).toBe('GET http://dogs.are.great/'); + expect(newSpan.op).toBe('http.client'); expect(fetchHandlerData.fetchData?.__span).toBeDefined(); const postRequestFetchHandlerData = { @@ -151,7 +151,7 @@ describe('callbacks', () => { // triggered by response coming back fetchCallback(postRequestFetchHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.endTimestamp).toBeDefined(); + expect(newSpan.endTimestamp).toBeDefined(); }); it('sets response status on finish', () => { @@ -160,7 +160,7 @@ describe('callbacks', () => { // triggered by request being sent fetchCallback(fetchHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); @@ -173,7 +173,7 @@ describe('callbacks', () => { // triggered by response coming back fetchCallback(postRequestFetchHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.status).toBe(spanStatusfromHttpCode(404)); + expect(newSpan.status).toBe(spanStatusfromHttpCode(404)); }); it('ignores response with no associated span', () => { @@ -238,18 +238,18 @@ describe('callbacks', () => { // triggered by request being sent xhrCallback(xhrHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeInstanceOf(Span); - expect(newSpan!.data).toEqual({ + expect(newSpan.data).toEqual({ method: 'GET', type: 'xhr', url: 'http://dogs.are.great/', }); - expect(newSpan!.description).toBe('GET http://dogs.are.great/'); - expect(newSpan!.op).toBe('http.client'); - expect(xhrHandlerData.xhr!.__sentry_xhr_span_id__).toBeDefined(); - expect(xhrHandlerData.xhr!.__sentry_xhr_span_id__).toEqual(newSpan?.spanId); + expect(newSpan.description).toBe('GET http://dogs.are.great/'); + expect(newSpan.op).toBe('http.client'); + expect(xhrHandlerData.xhr.__sentry_xhr_span_id__).toBeDefined(); + expect(xhrHandlerData.xhr.__sentry_xhr_span_id__).toEqual(newSpan?.spanId); const postRequestXHRHandlerData = { ...xhrHandlerData, @@ -259,7 +259,7 @@ describe('callbacks', () => { // triggered by response coming back xhrCallback(postRequestXHRHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.endTimestamp).toBeDefined(); + expect(newSpan.endTimestamp).toBeDefined(); }); it('sets response status on finish', () => { @@ -268,7 +268,7 @@ describe('callbacks', () => { // triggered by request being sent xhrCallback(xhrHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); @@ -276,12 +276,12 @@ describe('callbacks', () => { ...xhrHandlerData, endTimestamp, }; - postRequestXHRHandlerData.xhr!.__sentry_xhr__!.status_code = 404; + postRequestXHRHandlerData.xhr.__sentry_xhr__.status_code = 404; // triggered by response coming back xhrCallback(postRequestXHRHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.status).toBe(spanStatusfromHttpCode(404)); + expect(newSpan.status).toBe(spanStatusfromHttpCode(404)); }); it('ignores response with no associated span', () => { diff --git a/packages/tracing/test/browser/router.test.ts b/packages/tracing/test/browser/router.test.ts index e340a81222fe..9d1ae86f4e01 100644 --- a/packages/tracing/test/browser/router.test.ts +++ b/packages/tracing/test/browser/router.test.ts @@ -1,3 +1,4 @@ +import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; import { instrumentRoutingWithDefaults } from '../../src/browser/router'; @@ -8,7 +9,7 @@ jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback): void => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback): void => { addInstrumentationHandlerType = type; mockChangeHistory = callback; }, diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index ca042672b595..c15825fd5480 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,18 +1,19 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; +import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { registerErrorInstrumentation } from '../src/errors'; import { _addTracingExtensions } from '../src/hubextensions'; const mockAddInstrumentationHandler = jest.fn(); -let mockErrorCallback: () => void = () => undefined; -let mockUnhandledRejectionCallback: () => void = () => undefined; +let mockErrorCallback: InstrumentHandlerCallback = () => undefined; +let mockUnhandledRejectionCallback: InstrumentHandlerCallback = () => undefined; jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback) => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback) => { if (type === 'error') { mockErrorCallback = callback; } @@ -55,10 +56,10 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); expect(transaction.status).toBe(undefined); - mockErrorCallback(); + mockErrorCallback({}); expect(transaction.status).toBe(undefined); - mockUnhandledRejectionCallback(); + mockUnhandledRejectionCallback({}); expect(transaction.status).toBe(undefined); transaction.finish(); }); @@ -68,7 +69,7 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); hub.configureScope(scope => scope.setSpan(transaction)); - mockErrorCallback(); + mockErrorCallback({}); expect(transaction.status).toBe('internal_error'); transaction.finish(); @@ -79,7 +80,7 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); hub.configureScope(scope => scope.setSpan(transaction)); - mockUnhandledRejectionCallback(); + mockUnhandledRejectionCallback({}); expect(transaction.status).toBe('internal_error'); transaction.finish(); }); diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index f2565e1c7e5f..b8029c6b92d7 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -9,7 +9,9 @@ import { } from '../src/idletransaction'; import { Span } from '../src/span'; -export class SimpleTransport extends Transports.BaseTransport {} +// @ts-ignore It's okay that we're not implementing the methods of the abstract `BaseTransport` class, because it's not +// what we're testing here +class SimpleTransport extends Transports.BaseTransport {} const dsn = 'https://123@sentry.io/42'; let hub: Hub; @@ -167,9 +169,9 @@ describe('IdleTransaction', () => { it('should record dropped transactions', async () => { const transaction = new IdleTransaction({ name: 'foo', startTimestamp: 1234, sampled: false }, hub, 1000); - const transport = hub.getClient()?.getTransport(); + const transport = hub.getClient()!.getTransport!(); - const spy = jest.spyOn(transport!, 'recordLostEvent'); + const spy = jest.spyOn(transport, 'recordLostEvent'); transaction.initSpanRecorder(10); transaction.finish(transaction.startTimestamp + 10); diff --git a/packages/utils/src/instrument.ts b/packages/utils/src/instrument.ts index 30fcef290c19..a77e0c8222f3 100644 --- a/packages/utils/src/instrument.ts +++ b/packages/utils/src/instrument.ts @@ -13,7 +13,7 @@ import { supportsHistory, supportsNativeFetch } from './supports'; const global = getGlobalObject(); -type InstrumentHandlerType = +export type InstrumentHandlerType = | 'console' | 'dom' | 'fetch' @@ -22,7 +22,7 @@ type InstrumentHandlerType = | 'xhr' | 'error' | 'unhandledrejection'; -type InstrumentHandlerCallback = (data: any) => void; +export type InstrumentHandlerCallback = (data: any) => void; /** * Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc. From 8df2e22e7d9c0c13bd3703a33b0d95d8b85678af Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sun, 10 Apr 2022 23:37:04 -0700 Subject: [PATCH 08/10] fix type errors in serverless tests --- packages/serverless/src/awslambda.ts | 2 +- packages/serverless/src/gcpfunction/http.ts | 2 +- packages/serverless/test/google-cloud-http.test.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index 0b86f560a820..bac3e1412c8b 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -279,7 +279,7 @@ export function wrapHandler( scope.setTag('timeout', humanReadableTimeout); captureMessage(`Possible function timeout: ${context.functionName}`, 'warning'); }); - }, timeoutWarningDelay); + }, timeoutWarningDelay) as unknown as NodeJS.Timeout; } // Applying `sentry-trace` to context diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts index 607656fb3dbd..2e274bad3491 100644 --- a/packages/serverless/src/gcpfunction/http.ts +++ b/packages/serverless/src/gcpfunction/http.ts @@ -86,7 +86,7 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial void), encoding?: string | (() => void), cb?: () => void): void { + res.end = function (chunk?: any | (() => void), encoding?: string | (() => void), cb?: () => void): any { transaction.setHttpStatus(res.statusCode); transaction.finish(); diff --git a/packages/serverless/test/google-cloud-http.test.ts b/packages/serverless/test/google-cloud-http.test.ts index fced84730b00..7d785462a4d9 100644 --- a/packages/serverless/test/google-cloud-http.test.ts +++ b/packages/serverless/test/google-cloud-http.test.ts @@ -62,6 +62,7 @@ describe('GoogleCloudHttp tracing', () => { op: 'gcloud.http.bigquery', description: 'POST /jobs', }); + // @ts-ignore see "Why @ts-ignore" note expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ op: 'gcloud.http.bigquery', description: expect.stringMatching(new RegExp('^GET /queries/.+')), From d1634695a08744c5eba7ec52ae8d987fe87896c6 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Tue, 12 Apr 2022 19:42:11 -0700 Subject: [PATCH 09/10] fix type errors in gatsby tests --- packages/gatsby/test/gatsby-browser.test.ts | 4 ++-- packages/gatsby/test/gatsby-node.test.ts | 6 ++++-- packages/gatsby/test/setEnvVars.ts | 4 ++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/gatsby/test/gatsby-browser.test.ts b/packages/gatsby/test/gatsby-browser.test.ts index a2044dd2c8a9..cfeb9d227a88 100644 --- a/packages/gatsby/test/gatsby-browser.test.ts +++ b/packages/gatsby/test/gatsby-browser.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-explicit-any */ -const { onClientEntry } = require('../gatsby-browser'); +import { onClientEntry } from '../gatsby-browser'; (global as any).__SENTRY_RELEASE__ = '683f3a6ab819d47d23abfca9a914c81f0524d35b'; (global as any).__SENTRY_DSN__ = 'https://examplePublicKey@o0.ingest.sentry.io/0'; @@ -153,7 +153,7 @@ describe('onClientEntry', () => { // Run this last to check for any test side effects it('does not run if plugin params are undefined', () => { - onClientEntry(); + onClientEntry(undefined, undefined); expect(sentryInit).toHaveBeenCalledTimes(0); expect(tracingAddExtensionMethods).toHaveBeenCalledTimes(0); }); diff --git a/packages/gatsby/test/gatsby-node.test.ts b/packages/gatsby/test/gatsby-node.test.ts index f09f8e5be781..8880c133b90d 100644 --- a/packages/gatsby/test/gatsby-node.test.ts +++ b/packages/gatsby/test/gatsby-node.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-explicit-any */ -const { onCreateWebpackConfig } = require('../gatsby-node'); +import { onCreateWebpackConfig } from '../gatsby-node'; describe('onCreateWebpackConfig', () => { it('sets a webpack config', () => { @@ -12,7 +12,9 @@ describe('onCreateWebpackConfig', () => { setWebpackConfig: jest.fn(), }; - onCreateWebpackConfig({ plugins, actions }); + const getConfig = jest.fn(); + + onCreateWebpackConfig({ plugins, actions, getConfig }); expect(plugins.define).toHaveBeenCalledTimes(1); expect(plugins.define).toHaveBeenLastCalledWith({ diff --git a/packages/gatsby/test/setEnvVars.ts b/packages/gatsby/test/setEnvVars.ts index c97579e924e7..bc9d45b9c84a 100644 --- a/packages/gatsby/test/setEnvVars.ts +++ b/packages/gatsby/test/setEnvVars.ts @@ -1,2 +1,6 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access process.env.SENTRY_RELEASE = '14abbb1678a2eb59d1a171ea33d630dd6c6eee70'; + +// This file needs to have an import or an export to count as a module, which is necessary when using +// the `isolatedModules` tsconfig option. +export const _ = ''; From befc9e3515774f65a9b1b675b35729d3d93ce501 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 14 Apr 2022 09:59:54 -0700 Subject: [PATCH 10/10] fix type errors in core tests --- packages/core/test/lib/base.test.ts | 2 +- packages/core/test/mocks/client.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 72c0ef63c211..1bd2750e5378 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -69,7 +69,7 @@ describe('BaseClient', () => { const options = { dsn: PUBLIC_DSN }; const client = new TestClient(options, setupTestTransport(options).transport); - expect(dsnToString(client.getDsn())).toBe(PUBLIC_DSN); + expect(dsnToString(client.getDsn()!)).toBe(PUBLIC_DSN); }); test('allows missing Dsn', () => { diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 2a49f9fea757..707513ff91b1 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -79,7 +79,7 @@ export function setupTestTransport(options: TestOptions): { transport: Transport const transportOptions = options.transportOptions ? options.transportOptions : { dsn: options.dsn }; if (options.transport) { - return { transport: new this._options.transport(transportOptions) }; + return { transport: new options.transport(transportOptions) }; } return noop;