Skip to content

Commit 55c1b63

Browse files
committed
fix tests
1 parent 220c4c4 commit 55c1b63

File tree

2 files changed

+101
-14
lines changed

2 files changed

+101
-14
lines changed

packages/nextjs/test/config.test.ts

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ const mockExistsSync = (path: fs.PathLike) => {
3737
};
3838
const exitsSync = jest.spyOn(fs, 'existsSync').mockImplementation(mockExistsSync);
3939

40+
// Make it so that all temporary folders, either created directly by tests or by the code they're testing, will go into
41+
// one spot that we know about, which we can then clean up when we're done
42+
const realTmpdir = jest.requireActual('os').tmpdir;
43+
const TEMP_DIR_PATH = path.join(realTmpdir(), 'sentry-nextjs-test');
44+
jest.spyOn(os, 'tmpdir').mockReturnValue(TEMP_DIR_PATH);
45+
// In theory, we should always land in the `else` here, but this saves the cases where the prior run got interrupted and
46+
// the `afterAll` below didn't happen.
47+
if (fs.existsSync(TEMP_DIR_PATH)) {
48+
rimraf.sync(path.join(TEMP_DIR_PATH, '*'));
49+
} else {
50+
fs.mkdirSync(TEMP_DIR_PATH);
51+
}
52+
53+
afterAll(() => {
54+
rimraf.sync(TEMP_DIR_PATH);
55+
});
56+
57+
// In order to know what to expect in the webpack config `entry` property, we need to know the path of the temporary
58+
// directory created when doing the file injection, so wrap the real `mkdtempSync` and store the resulting path where we
59+
// can access it
60+
let tempDir: string;
61+
const realMkdtempSync = jest.requireActual('fs').mkdtempSync;
62+
jest.spyOn(fs, 'mkdtempSync').mockImplementation(prefix => {
63+
tempDir = realMkdtempSync(prefix);
64+
return tempDir;
65+
});
66+
4067
/** Mocks of the arguments passed to `withSentryConfig` */
4168
const userNextConfig: Partial<NextConfigObject> = {
4269
publicRuntimeConfig: { location: 'dogpark', activities: ['fetch', 'chasing', 'digging'] },
@@ -103,7 +130,12 @@ function getBuildContext(
103130
dev: false,
104131
buildId: 'sItStAyLiEdOwN',
105132
dir: '/Users/Maisey/projects/squirrelChasingSimulator',
106-
config: { target: 'server', ...userNextConfig } as NextConfigObject,
133+
config: {
134+
// nextjs's default values
135+
target: 'server',
136+
distDir: '.next',
137+
...userNextConfig,
138+
} as NextConfigObject,
107139
webpack: { version: webpackVersion },
108140
isServer: buildTarget === 'server',
109141
};
@@ -279,26 +311,34 @@ describe('webpack config', () => {
279311
incomingWebpackBuildContext: serverBuildContext,
280312
});
281313

314+
const rewriteFramesHelper = path.join(tempDir, 'rewriteFramesHelper.js');
315+
282316
expect(finalWebpackConfig.entry).toEqual(
283317
expect.objectContaining({
284318
// original entry point value is a string
285319
// (was 'private-next-pages/api/dogs/[name].js')
286-
'pages/api/dogs/[name]': [serverConfigFilePath, 'private-next-pages/api/dogs/[name].js'],
320+
'pages/api/dogs/[name]': [rewriteFramesHelper, serverConfigFilePath, 'private-next-pages/api/dogs/[name].js'],
287321

288322
// original entry point value is a string array
289323
// (was ['./node_modules/smellOVision/index.js', 'private-next-pages/_app.js'])
290-
'pages/_app': [serverConfigFilePath, './node_modules/smellOVision/index.js', 'private-next-pages/_app.js'],
324+
'pages/_app': [
325+
rewriteFramesHelper,
326+
serverConfigFilePath,
327+
'./node_modules/smellOVision/index.js',
328+
'private-next-pages/_app.js',
329+
],
291330

292331
// original entry point value is an object containing a string `import` value
293332
// (`import` was 'private-next-pages/api/simulator/dogStats/[name].js')
294333
'pages/api/simulator/dogStats/[name]': {
295-
import: [serverConfigFilePath, 'private-next-pages/api/simulator/dogStats/[name].js'],
334+
import: [rewriteFramesHelper, serverConfigFilePath, 'private-next-pages/api/simulator/dogStats/[name].js'],
296335
},
297336

298337
// original entry point value is an object containing a string array `import` value
299338
// (`import` was ['./node_modules/dogPoints/converter.js', 'private-next-pages/api/simulator/leaderboard.js'])
300339
'pages/api/simulator/leaderboard': {
301340
import: [
341+
rewriteFramesHelper,
302342
serverConfigFilePath,
303343
'./node_modules/dogPoints/converter.js',
304344
'private-next-pages/api/simulator/leaderboard.js',
@@ -308,14 +348,14 @@ describe('webpack config', () => {
308348
// original entry point value is an object containg properties besides `import`
309349
// (`dependOn` remains untouched)
310350
'pages/api/tricks/[trickName]': {
311-
import: [serverConfigFilePath, 'private-next-pages/api/tricks/[trickName].js'],
351+
import: [rewriteFramesHelper, serverConfigFilePath, 'private-next-pages/api/tricks/[trickName].js'],
312352
dependOn: 'treats',
313353
},
314354
}),
315355
);
316356
});
317357

318-
it('does not inject into non-_app, non-API routes', async () => {
358+
it('does not inject anything into non-_app, non-API routes', async () => {
319359
const finalWebpackConfig = await materializeFinalWebpackConfig({
320360
userNextConfig,
321361
incomingWebpackConfig: clientWebpackConfig,
@@ -326,12 +366,60 @@ describe('webpack config', () => {
326366
expect.objectContaining({
327367
// no injected file
328368
main: './src/index.ts',
329-
// was 'next-client-pages-loader?page=%2F_app'
369+
}),
370+
);
371+
});
372+
373+
it('does not inject `RewriteFrames` helper into client routes', async () => {
374+
const finalWebpackConfig = await materializeFinalWebpackConfig({
375+
userNextConfig,
376+
incomingWebpackConfig: clientWebpackConfig,
377+
incomingWebpackBuildContext: clientBuildContext,
378+
});
379+
380+
expect(finalWebpackConfig.entry).toEqual(
381+
expect.objectContaining({
382+
// was 'next-client-pages-loader?page=%2F_app', and now has client config but not`RewriteFrames` helper injected
330383
'pages/_app': [clientConfigFilePath, 'next-client-pages-loader?page=%2F_app'],
331384
}),
332385
);
333386
});
334387
});
388+
389+
describe('`distDir` value in default server-side `RewriteFrames` integration', () => {
390+
it.each([
391+
['no custom `distDir`', undefined, '.next'],
392+
['custom `distDir`', 'dist', 'dist'],
393+
])(
394+
'creates file injecting `distDir` value into `global` - %s',
395+
async (_name, customDistDir, expectedInjectedValue) => {
396+
// Note: the fact that the file tested here gets injected correctly is covered in the 'webpack `entry` property
397+
// config' tests above
398+
399+
const userNextConfigDistDir = {
400+
...userNextConfig,
401+
...(customDistDir && { distDir: customDistDir }),
402+
};
403+
await materializeFinalWebpackConfig({
404+
userNextConfig: userNextConfigDistDir,
405+
incomingWebpackConfig: serverWebpackConfig,
406+
incomingWebpackBuildContext: getBuildContext('server', userNextConfigDistDir),
407+
});
408+
const rewriteFramesHelper = path.join(tempDir, 'rewriteFramesHelper.js');
409+
410+
expect(fs.existsSync(rewriteFramesHelper)).toBe(true);
411+
412+
const injectedCode = fs.readFileSync(rewriteFramesHelper).toString();
413+
expect(injectedCode).toEqual(`global.__rewriteFramesDistDir__ = '${expectedInjectedValue}';\n`);
414+
},
415+
);
416+
417+
describe('`RewriteFrames` ends up with correct `distDir` value', () => {
418+
// TODO: this, along with any number of other parts of the build process, should be tested with an integration
419+
// test which actually runs webpack and inspects the resulting bundles (and that integration test should test
420+
// custom `distDir` values with and without a `.`, to make sure the regex escaping is working)
421+
});
422+
});
335423
});
336424

337425
describe('Sentry webpack plugin config', () => {
@@ -580,19 +668,15 @@ describe('Sentry webpack plugin config', () => {
580668
});
581669

582670
describe('getUserConfigFile', () => {
583-
let tempDir: string;
584-
585671
beforeAll(() => {
586672
exitsSync.mockImplementation(realExistsSync);
587673
});
588674

589675
beforeEach(() => {
676+
// these will get cleaned up by the file's overall `afterAll` function, and the `mkdtempSync` mock above ensures
677+
// that the location of the created folder is stored in `tempDir`
590678
const tempDirPathPrefix = path.join(os.tmpdir(), 'sentry-nextjs-test-');
591-
tempDir = fs.mkdtempSync(tempDirPathPrefix);
592-
});
593-
594-
afterEach(() => {
595-
rimraf.sync(tempDir);
679+
fs.mkdtempSync(tempDirPathPrefix);
596680
});
597681

598682
afterAll(() => {

packages/nextjs/test/index.server.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ const { Integrations } = SentryNode;
1010

1111
const global = getGlobalObject();
1212

13+
// normally this is set as part of the build process, so mock it here
14+
(global as typeof global & { __rewriteFramesDistDir__: string }).__rewriteFramesDistDir__ = '.next';
15+
1316
let configureScopeCallback: (scope: Scope) => void = () => undefined;
1417
jest.spyOn(SentryNode, 'configureScope').mockImplementation(callback => (configureScopeCallback = callback));
1518
const nodeInit = jest.spyOn(SentryNode, 'init');

0 commit comments

Comments
 (0)