1
+ import { afterEach , describe , expect , it , test , vi } from 'vitest' ;
2
+
3
+ import * as cryptoMod from 'node:crypto' ;
4
+
1
5
import type { Event , Mechanism , StackFrame } from '@sentry/types' ;
2
6
3
7
import {
@@ -6,9 +10,26 @@ import {
6
10
arrayify ,
7
11
checkOrSetAlreadyCaught ,
8
12
getEventDescription ,
13
+ parseSemver ,
9
14
uuid4 ,
10
15
} from '../src/misc' ;
11
16
17
+ const NODE_VERSION = parseSemver ( process . versions . node ) ;
18
+ /**
19
+ * Returns`describe` or `describe.skip` depending on allowed major versions of Node.
20
+ *
21
+ * @param {{ min?: number; max?: number } } allowedVersion
22
+ */
23
+ export const conditionalTest = ( allowedVersion : { min ?: number ; max ?: number } ) => {
24
+ if ( ! NODE_VERSION ) {
25
+ return test . skip ;
26
+ }
27
+
28
+ return NODE_VERSION < ( allowedVersion . min || - Infinity ) || NODE_VERSION > ( allowedVersion . max || Infinity )
29
+ ? test . skip
30
+ : test ;
31
+ } ;
32
+
12
33
describe ( 'getEventDescription()' , ( ) => {
13
34
test ( 'message event' , ( ) => {
14
35
expect (
@@ -290,6 +311,10 @@ describe('checkOrSetAlreadyCaught()', () => {
290
311
} ) ;
291
312
292
313
describe ( 'uuid4 generation' , ( ) => {
314
+ afterEach ( ( ) => {
315
+ vi . unstubAllGlobals ( ) ;
316
+ } ) ;
317
+
293
318
const uuid4Regex = / ^ [ 0 - 9 A - F ] { 12 } [ 4 ] [ 0 - 9 A - F ] { 3 } [ 8 9 A B ] [ 0 - 9 A - F ] { 15 } $ / i;
294
319
// Jest messes with the global object, so there is no global crypto object in any node version
295
320
// For this reason we need to create our own crypto object for each test to cover all the code paths
@@ -299,45 +324,39 @@ describe('uuid4 generation', () => {
299
324
}
300
325
} ) ;
301
326
302
- it ( 'returns valid uuid v4 ids via crypto.getRandomValues' , ( ) => {
303
- // eslint-disable-next-line @typescript-eslint/no-var-requires
304
- const cryptoMod = require ( 'crypto' ) ;
305
-
306
- ( global as any ) . crypto = { getRandomValues : cryptoMod . getRandomValues } ;
327
+ conditionalTest ( { min : 17 } ) ( 'returns valid uuid v4 ids via crypto.getRandomValues' , ( ) => {
328
+ vi . stubGlobal ( 'crypto' , { getRandomValues : ( cryptoMod as any ) . getRandomValues } ) ;
307
329
308
330
for ( let index = 0 ; index < 1_000 ; index ++ ) {
309
331
expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
310
332
}
311
333
} ) ;
312
334
313
335
it ( 'returns valid uuid v4 ids via crypto.randomUUID' , ( ) => {
314
- // eslint-disable-next-line @typescript-eslint/no-var-requires
315
- const cryptoMod = require ( 'crypto' ) ;
316
-
317
- ( global as any ) . crypto = { randomUUID : cryptoMod . randomUUID } ;
336
+ vi . stubGlobal ( 'crypto' , { getRandomValues : cryptoMod . randomUUID } ) ;
318
337
319
338
for ( let index = 0 ; index < 1_000 ; index ++ ) {
320
339
expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
321
340
}
322
341
} ) ;
323
342
324
343
it ( "return valid uuid v4 even if crypto doesn't exists" , ( ) => {
325
- ( global as any ) . crypto = { getRandomValues : undefined , randomUUID : undefined } ;
344
+ vi . stubGlobal ( ' crypto' , { getRandomValues : undefined , randomUUID : undefined } ) ;
326
345
327
346
for ( let index = 0 ; index < 1_000 ; index ++ ) {
328
347
expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
329
348
}
330
349
} ) ;
331
350
332
351
it ( 'return valid uuid v4 even if crypto invoked causes an error' , ( ) => {
333
- ( global as any ) . crypto = {
352
+ vi . stubGlobal ( ' crypto' , {
334
353
getRandomValues : ( ) => {
335
354
throw new Error ( 'yo' ) ;
336
355
} ,
337
356
randomUUID : ( ) => {
338
357
throw new Error ( 'yo' ) ;
339
358
} ,
340
- } ;
359
+ } ) ;
341
360
342
361
for ( let index = 0 ; index < 1_000 ; index ++ ) {
343
362
expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
@@ -346,22 +365,22 @@ describe('uuid4 generation', () => {
346
365
347
366
// Corner case related to crypto.getRandomValues being only
348
367
// semi-implemented (e.g. Chromium 23.0.1235.0 (151422))
349
- it ( 'returns valid uuid v4 even if crypto.getRandomValues does not return a typed array' , ( ) => {
350
- // eslint-disable-next-line @typescript-eslint/no-var-requires
351
- const cryptoMod = require ( 'crypto' ) ;
352
-
353
- const getRandomValues = ( typedArray : Uint8Array ) => {
354
- if ( cryptoMod . getRandomValues ) {
355
- cryptoMod . getRandomValues ( typedArray ) ;
368
+ conditionalTest ( { min : 17 } ) (
369
+ 'returns valid uuid v4 even if crypto.getRandomValues does not return a typed array' ,
370
+ ( ) => {
371
+ const getRandomValues = ( typedArray : Uint8Array ) => {
372
+ if ( ( cryptoMod as any ) . getRandomValues ) {
373
+ ( cryptoMod as any ) . getRandomValues ( typedArray ) ;
374
+ }
375
+ } ;
376
+
377
+ vi . stubGlobal ( 'crypto' , { getRandomValues } ) ;
378
+
379
+ for ( let index = 0 ; index < 1_000 ; index ++ ) {
380
+ expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
356
381
}
357
- } ;
358
-
359
- ( global as any ) . crypto = { getRandomValues } ;
360
-
361
- for ( let index = 0 ; index < 1_000 ; index ++ ) {
362
- expect ( uuid4 ( ) ) . toMatch ( uuid4Regex ) ;
363
- }
364
- } ) ;
382
+ } ,
383
+ ) ;
365
384
} ) ;
366
385
367
386
describe ( 'arrayify()' , ( ) => {
0 commit comments