Skip to content

Commit

Permalink
add and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lobsterkatie committed Sep 12, 2022
1 parent 3ef5afb commit a2801d8
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 9 deletions.
70 changes: 70 additions & 0 deletions packages/nextjs/test/config/wrappers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as SentryCore from '@sentry/core';
import * as SentryTracing from '@sentry/tracing';
import { IncomingMessage, ServerResponse } from 'http';

import {
withSentryGetServerSideProps,
withSentryServerSideGetInitialProps,
// TODO: Leaving `withSentryGetStaticProps` out for now until we figure out what to do with it
// withSentryGetStaticProps,
// TODO: Leaving these out for now until we figure out pages with no data fetchers
// withSentryServerSideAppGetInitialProps,
// withSentryServerSideDocumentGetInitialProps,
// withSentryServerSideErrorGetInitialProps,
} from '../../src/config/wrappers';

const startTransactionSpy = jest.spyOn(SentryCore, 'startTransaction');
const setMetadataSpy = jest.spyOn(SentryTracing.Transaction.prototype, 'setMetadata');

describe('data-fetching function wrappers', () => {
const route = '/tricks/[trickName]';
let req: IncomingMessage;
let res: ServerResponse;

describe('starts a transaction if tracing enabled', () => {
beforeEach(() => {
req = { headers: {}, url: 'http://dogs.are.great/tricks/kangaroo' } as IncomingMessage;
res = {} as ServerResponse;

jest.spyOn(SentryTracing, 'hasTracingEnabled').mockReturnValueOnce(true);
});

afterEach(() => {
jest.clearAllMocks();
});

test('withSentryGetServerSideProps', async () => {
const origFunction = jest.fn(async () => ({ props: {} }));

const wrappedOriginal = withSentryGetServerSideProps(origFunction, route);
await wrappedOriginal({ req, res } as any);

expect(startTransactionSpy).toHaveBeenCalledWith(
expect.objectContaining({
name: '/tricks/[trickName]',
op: 'nextjs.data.server',
metadata: expect.objectContaining({ source: 'route' }),
}),
);

expect(setMetadataSpy).toHaveBeenCalledWith({ request: req });
});

test('withSentryServerSideGetInitialProps', async () => {
const origFunction = jest.fn(async () => ({}));

const wrappedOriginal = withSentryServerSideGetInitialProps(origFunction);
await wrappedOriginal({ req, res, pathname: route } as any);

expect(startTransactionSpy).toHaveBeenCalledWith(
expect.objectContaining({
name: '/tricks/[trickName]',
op: 'nextjs.data.server',
metadata: expect.objectContaining({ source: 'route' }),
}),
);

expect(setMetadataSpy).toHaveBeenCalledWith({ request: req });
});
});
});
68 changes: 59 additions & 9 deletions packages/nextjs/test/index.server.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { RequestData } from '@sentry/integrations';
import * as SentryNode from '@sentry/node';
import { getCurrentHub, NodeClient } from '@sentry/node';
import { Integration } from '@sentry/types';
import { getGlobalObject, logger } from '@sentry/utils';
import * as domain from 'domain';

import { init } from '../src/index.server';
import { UserIntegrationsFunction } from '../src/utils/userIntegrations';

const { Integrations } = SentryNode;

Expand Down Expand Up @@ -143,31 +145,79 @@ describe('Server init()', () => {

describe('integrations', () => {
// Options passed by `@sentry/nextjs`'s `init` to `@sentry/node`'s `init` after modifying them
type ModifiedInitOptions = { integrations: Integration[] };
type ModifiedInitOptionsIntegrationArray = { integrations: Integration[] };
type ModifiedInitOptionsIntegrationFunction = { integrations: UserIntegrationsFunction };

it('adds default integrations', () => {
init({});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const rewriteFramesIntegration = findIntegrationByName(nodeInitOptions.integrations, 'RewriteFrames');
const requestDataFramesIntegration = findIntegrationByName(nodeInitOptions.integrations, 'RequestData');

expect(rewriteFramesIntegration).toBeDefined();
expect(requestDataFramesIntegration).toBeDefined();
});

it('supports passing unrelated integrations through options', () => {
init({ integrations: [new Integrations.Console()] });

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const consoleIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Console');

expect(consoleIntegration).toBeDefined();
});

describe('`RequestData` integration', () => {
it('forces `include.transaction = false` if user provides `RequestData` in an array', () => {
init({
integrations: [new RequestData({ include: { ip: true } })],
});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const requestDataIntegration = findIntegrationByName(nodeInitOptions.integrations, 'RequestData');

expect(requestDataIntegration).toEqual(
expect.objectContaining({
_options: expect.objectContaining({
include: expect.objectContaining({
transaction: false,
// This proves it's still the user's copy
ip: true,
}),
}),
}),
);
});

it('forces `include.transaction = false` if user provides `RequestData` in a function', () => {
init({
integrations: defaults => [...defaults, new RequestData({ include: { ip: true } })],
});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationFunction;
const materializedIntegrations = nodeInitOptions.integrations(SentryNode.defaultIntegrations);
const requestDataIntegration = findIntegrationByName(materializedIntegrations, 'RequestData');

expect(requestDataIntegration).toEqual(
expect.objectContaining({
_options: expect.objectContaining({
include: expect.objectContaining({
transaction: false,
// This proves it's still the user's copy
ip: true,
}),
}),
}),
);
});
});

describe('`Http` integration', () => {
it('adds `Http` integration with tracing enabled if `tracesSampleRate` is set', () => {
init({ tracesSampleRate: 1.0 });

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeDefined();
Expand All @@ -177,7 +227,7 @@ describe('Server init()', () => {
it('adds `Http` integration with tracing enabled if `tracesSampler` is set', () => {
init({ tracesSampler: () => true });

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeDefined();
Expand All @@ -187,7 +237,7 @@ describe('Server init()', () => {
it('does not add `Http` integration if tracing not enabled in SDK', () => {
init({});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeUndefined();
Expand All @@ -199,7 +249,7 @@ describe('Server init()', () => {
integrations: [new Integrations.Http({ tracing: false })],
});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeDefined();
Expand All @@ -212,7 +262,7 @@ describe('Server init()', () => {
integrations: [new Integrations.Http({ tracing: false })],
});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeDefined();
Expand All @@ -224,7 +274,7 @@ describe('Server init()', () => {
integrations: [new Integrations.Http({ tracing: false })],
});

const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptions;
const nodeInitOptions = nodeInit.mock.calls[0][0] as ModifiedInitOptionsIntegrationArray;
const httpIntegration = findIntegrationByName(nodeInitOptions.integrations, 'Http');

expect(httpIntegration).toBeDefined();
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/test/utils/withSentry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ describe('withSentry', () => {
metadata: {
baggage: expect.any(Array),
source: 'route',
request: expect.objectContaining({ url: 'http://dogs.are.great' }),
},
},
{ request: expect.objectContaining({ url: 'http://dogs.are.great' }) },
Expand Down

0 comments on commit a2801d8

Please sign in to comment.