1
+ import * as fs from 'fs' ;
2
+ import * as os from 'os' ;
3
+ import * as path from 'path' ;
4
+ import * as rimraf from 'rimraf' ;
5
+
1
6
import { withSentryConfig } from '../src/config' ;
2
7
import {
3
8
BuildContext ,
@@ -7,12 +12,24 @@ import {
7
12
SentryWebpackPluginOptions ,
8
13
WebpackConfigObject ,
9
14
} from '../src/config/types' ;
10
- import {
11
- CLIENT_SDK_CONFIG_FILE ,
12
- constructWebpackConfigFunction ,
13
- SentryWebpackPlugin ,
14
- SERVER_SDK_CONFIG_FILE ,
15
- } from '../src/config/webpack' ;
15
+ import { constructWebpackConfigFunction , getUserConfigFile , SentryWebpackPlugin } from '../src/config/webpack' ;
16
+
17
+ const SERVER_SDK_CONFIG_FILE = 'sentry.server.config.js' ;
18
+ const CLIENT_SDK_CONFIG_FILE = 'sentry.client.config.js' ;
19
+
20
+ // We use `fs.existsSync()` in `getUserConfigFile()`. When we're not testing `getUserConfigFile()` specifically, all we
21
+ // need is for it to give us any valid answer, so make it always find what it's looking for. Since this is a core node
22
+ // built-in, though, which jest itself uses, otherwise let it do the normal thing. Storing the real version of the
23
+ // function also lets us restore the original when we do want to test `getUserConfigFile()`.
24
+ const realExistsSync = jest . requireActual ( 'fs' ) . existsSync ;
25
+ const mockExistsSync = ( path : fs . PathLike ) => {
26
+ if ( ( path as string ) . endsWith ( SERVER_SDK_CONFIG_FILE ) || ( path as string ) . endsWith ( CLIENT_SDK_CONFIG_FILE ) ) {
27
+ return true ;
28
+ }
29
+
30
+ return realExistsSync ( path ) ;
31
+ } ;
32
+ const exitsSync = jest . spyOn ( fs , 'existsSync' ) . mockImplementation ( mockExistsSync ) ;
16
33
17
34
/** Mocks of the arguments passed to `withSentryConfig` */
18
35
const userNextConfig = {
@@ -63,8 +80,13 @@ const clientWebpackConfig = {
63
80
target : 'web' ,
64
81
context : '/Users/Maisey/projects/squirrelChasingSimulator' ,
65
82
} ;
66
- const serverBuildContext = { isServer : true , dev : false , buildId : 'doGsaREgReaT' } ;
67
- const clientBuildContext = { isServer : false , dev : false , buildId : 'doGsaREgReaT' } ;
83
+ const baseBuildContext = {
84
+ dev : false ,
85
+ buildId : 'doGsaREgReaT' ,
86
+ dir : '/Users/Maisey/projects/squirrelChasingSimulator' ,
87
+ } ;
88
+ const serverBuildContext = { isServer : true , ...baseBuildContext } ;
89
+ const clientBuildContext = { isServer : false , ...baseBuildContext } ;
68
90
69
91
/**
70
92
* Derive the final values of all next config options, by first applying `withSentryConfig` and then, if it returns a
@@ -223,6 +245,9 @@ describe('webpack config', () => {
223
245
} ) ;
224
246
225
247
describe ( 'webpack `entry` property config' , ( ) => {
248
+ const serverConfigFilePath = `./${ SERVER_SDK_CONFIG_FILE } ` ;
249
+ const clientConfigFilePath = `./${ CLIENT_SDK_CONFIG_FILE } ` ;
250
+
226
251
it ( 'handles various entrypoint shapes' , async ( ) => {
227
252
const finalWebpackConfig = await materializeFinalWebpackConfig ( {
228
253
userNextConfig,
@@ -234,23 +259,23 @@ describe('webpack config', () => {
234
259
expect . objectContaining ( {
235
260
// original entry point value is a string
236
261
// (was 'private-next-pages/api/dogs/[name].js')
237
- 'pages/api/dogs/[name]' : [ SERVER_SDK_CONFIG_FILE , 'private-next-pages/api/dogs/[name].js' ] ,
262
+ 'pages/api/dogs/[name]' : [ serverConfigFilePath , 'private-next-pages/api/dogs/[name].js' ] ,
238
263
239
264
// original entry point value is a string array
240
265
// (was ['./node_modules/smellOVision/index.js', 'private-next-pages/_app.js'])
241
- 'pages/_app' : [ SERVER_SDK_CONFIG_FILE , './node_modules/smellOVision/index.js' , 'private-next-pages/_app.js' ] ,
266
+ 'pages/_app' : [ serverConfigFilePath , './node_modules/smellOVision/index.js' , 'private-next-pages/_app.js' ] ,
242
267
243
268
// original entry point value is an object containing a string `import` value
244
269
// (`import` was 'private-next-pages/api/simulator/dogStats/[name].js')
245
270
'pages/api/simulator/dogStats/[name]' : {
246
- import : [ SERVER_SDK_CONFIG_FILE , 'private-next-pages/api/simulator/dogStats/[name].js' ] ,
271
+ import : [ serverConfigFilePath , 'private-next-pages/api/simulator/dogStats/[name].js' ] ,
247
272
} ,
248
273
249
274
// original entry point value is an object containing a string array `import` value
250
275
// (`import` was ['./node_modules/dogPoints/converter.js', 'private-next-pages/api/simulator/leaderboard.js'])
251
276
'pages/api/simulator/leaderboard' : {
252
277
import : [
253
- SERVER_SDK_CONFIG_FILE ,
278
+ serverConfigFilePath ,
254
279
'./node_modules/dogPoints/converter.js' ,
255
280
'private-next-pages/api/simulator/leaderboard.js' ,
256
281
] ,
@@ -259,7 +284,7 @@ describe('webpack config', () => {
259
284
// original entry point value is an object containg properties besides `import`
260
285
// (`dependOn` remains untouched)
261
286
'pages/api/tricks/[trickName]' : {
262
- import : [ SERVER_SDK_CONFIG_FILE , 'private-next-pages/api/tricks/[trickName].js' ] ,
287
+ import : [ serverConfigFilePath , 'private-next-pages/api/tricks/[trickName].js' ] ,
263
288
dependOn : 'treats' ,
264
289
} ,
265
290
} ) ,
@@ -278,7 +303,7 @@ describe('webpack config', () => {
278
303
// no injected file
279
304
main : './src/index.ts' ,
280
305
// was 'next-client-pages-loader?page=%2F_app'
281
- 'pages/_app' : [ CLIENT_SDK_CONFIG_FILE , 'next-client-pages-loader?page=%2F_app' ] ,
306
+ 'pages/_app' : [ clientConfigFilePath , 'next-client-pages-loader?page=%2F_app' ] ,
282
307
} ) ,
283
308
) ;
284
309
} ) ;
@@ -340,4 +365,50 @@ describe('Sentry webpack plugin config', () => {
340
365
341
366
expect ( finalWebpackConfig ?. devtool ) . not . toEqual ( 'source-map' ) ;
342
367
} ) ;
368
+
369
+ describe ( 'getUserConfigFile' , ( ) => {
370
+ let tempDir : string ;
371
+
372
+ beforeAll ( ( ) => {
373
+ exitsSync . mockImplementation ( realExistsSync ) ;
374
+ } ) ;
375
+
376
+ beforeEach ( ( ) => {
377
+ const tempDirPathPrefix = path . join ( os . tmpdir ( ) , 'sentry-nextjs-test-' ) ;
378
+ tempDir = fs . mkdtempSync ( tempDirPathPrefix ) ;
379
+ } ) ;
380
+
381
+ afterEach ( ( ) => {
382
+ rimraf . sync ( tempDir ) ;
383
+ } ) ;
384
+
385
+ afterAll ( ( ) => {
386
+ exitsSync . mockImplementation ( mockExistsSync ) ;
387
+ } ) ;
388
+
389
+ it ( 'successfully finds js files' , ( ) => {
390
+ fs . writeFileSync ( path . resolve ( tempDir , 'sentry.server.config.js' ) , 'Dogs are great!' ) ;
391
+ fs . writeFileSync ( path . resolve ( tempDir , 'sentry.client.config.js' ) , 'Squirrel!' ) ;
392
+
393
+ expect ( getUserConfigFile ( tempDir , 'server' ) ) . toEqual ( 'sentry.server.config.js' ) ;
394
+ expect ( getUserConfigFile ( tempDir , 'client' ) ) . toEqual ( 'sentry.client.config.js' ) ;
395
+ } ) ;
396
+
397
+ it ( 'successfully finds ts files' , ( ) => {
398
+ fs . writeFileSync ( path . resolve ( tempDir , 'sentry.server.config.ts' ) , 'Sit. Stay. Lie Down.' ) ;
399
+ fs . writeFileSync ( path . resolve ( tempDir , 'sentry.client.config.ts' ) , 'Good dog!' ) ;
400
+
401
+ expect ( getUserConfigFile ( tempDir , 'server' ) ) . toEqual ( 'sentry.server.config.ts' ) ;
402
+ expect ( getUserConfigFile ( tempDir , 'client' ) ) . toEqual ( 'sentry.client.config.ts' ) ;
403
+ } ) ;
404
+
405
+ it ( 'errors when files are missing' , ( ) => {
406
+ expect ( ( ) => getUserConfigFile ( tempDir , 'server' ) ) . toThrowError (
407
+ `Cannot find 'sentry.server.config.ts' or 'sentry.server.config.js' in '${ tempDir } '` ,
408
+ ) ;
409
+ expect ( ( ) => getUserConfigFile ( tempDir , 'client' ) ) . toThrowError (
410
+ `Cannot find 'sentry.client.config.ts' or 'sentry.client.config.js' in '${ tempDir } '` ,
411
+ ) ;
412
+ } ) ;
413
+ } ) ;
343
414
} ) ;
0 commit comments