@@ -14,11 +14,15 @@ jest.mock('@sentry/browser', () => ({
1414 addBreadcrumb : mockAddBreadcrumb ,
1515 setContext : mockSetContext ,
1616 } ) ,
17+ addGlobalEventProcessor : jest . fn ( ) ,
1718} ) ) ;
1819
20+ const mockAddGlobalEventProcessor = Sentry . addGlobalEventProcessor as jest . Mock ;
21+
1922afterEach ( ( ) => {
2023 mockAddBreadcrumb . mockReset ( ) ;
2124 mockSetContext . mockReset ( ) ;
25+ mockAddGlobalEventProcessor . mockReset ( ) ;
2226} ) ;
2327
2428describe ( 'createReduxEnhancer' , ( ) => {
@@ -243,4 +247,170 @@ describe('createReduxEnhancer', () => {
243247 value : 'latest' ,
244248 } ) ;
245249 } ) ;
250+
251+ describe ( 'Redux State Attachments' , ( ) => {
252+ it ( 'attaches Redux state to Sentry scope' , ( ) => {
253+ const enhancer = createReduxEnhancer ( ) ;
254+
255+ const initialState = {
256+ value : 'initial' ,
257+ } ;
258+
259+ Redux . createStore ( ( state = initialState ) => state , enhancer ) ;
260+
261+ expect ( mockAddGlobalEventProcessor ) . toHaveBeenCalledTimes ( 1 ) ;
262+
263+ const callbackFunction = mockAddGlobalEventProcessor . mock . calls [ 0 ] [ 0 ] ;
264+
265+ const mockEvent = {
266+ contexts : {
267+ state : {
268+ state : {
269+ type : 'redux' ,
270+ value : 'UPDATED_VALUE' ,
271+ } ,
272+ } ,
273+ } ,
274+ } ;
275+
276+ const mockHint = {
277+ attachments : [ ] ,
278+ } ;
279+
280+ const result = callbackFunction ( mockEvent , mockHint ) ;
281+
282+ expect ( result ) . toEqual ( {
283+ ...mockEvent ,
284+ contexts : {
285+ state : {
286+ state : {
287+ type : 'redux' ,
288+ value : 'UPDATED_VALUE' ,
289+ } ,
290+ } ,
291+ } ,
292+ } ) ;
293+
294+ expect ( mockHint . attachments ) . toHaveLength ( 1 ) ;
295+ expect ( mockHint . attachments [ 0 ] ) . toEqual ( {
296+ filename : 'redux_state.json' ,
297+ data : JSON . stringify ( 'UPDATED_VALUE' ) ,
298+ } ) ;
299+ } ) ;
300+
301+ it ( 'does not attach when attachReduxState is false' , ( ) => {
302+ const enhancer = createReduxEnhancer ( { attachReduxState : false } ) ;
303+
304+ const initialState = {
305+ value : 'initial' ,
306+ } ;
307+
308+ Redux . createStore ( ( state = initialState ) => state , enhancer ) ;
309+
310+ expect ( mockAddGlobalEventProcessor ) . toHaveBeenCalledTimes ( 0 ) ;
311+ } ) ;
312+
313+ it ( 'does not attach when state.type is not redux' , ( ) => {
314+ const enhancer = createReduxEnhancer ( ) ;
315+
316+ const initialState = {
317+ value : 'initial' ,
318+ } ;
319+
320+ Redux . createStore ( ( state = initialState ) => state , enhancer ) ;
321+
322+ expect ( mockAddGlobalEventProcessor ) . toHaveBeenCalledTimes ( 1 ) ;
323+
324+ const callbackFunction = mockAddGlobalEventProcessor . mock . calls [ 0 ] [ 0 ] ;
325+
326+ const mockEvent = {
327+ contexts : {
328+ state : {
329+ state : {
330+ type : 'not_redux' ,
331+ value : 'UPDATED_VALUE' ,
332+ } ,
333+ } ,
334+ } ,
335+ } ;
336+
337+ const mockHint = {
338+ attachments : [ ] ,
339+ } ;
340+
341+ const result = callbackFunction ( mockEvent , mockHint ) ;
342+
343+ expect ( result ) . toEqual ( mockEvent ) ;
344+
345+ expect ( mockHint . attachments ) . toHaveLength ( 0 ) ;
346+ } ) ;
347+
348+ it ( 'does not attach when state is undefined' , ( ) => {
349+ const enhancer = createReduxEnhancer ( ) ;
350+
351+ const initialState = {
352+ value : 'initial' ,
353+ } ;
354+
355+ Redux . createStore ( ( state = initialState ) => state , enhancer ) ;
356+
357+ expect ( mockAddGlobalEventProcessor ) . toHaveBeenCalledTimes ( 1 ) ;
358+
359+ const callbackFunction = mockAddGlobalEventProcessor . mock . calls [ 0 ] [ 0 ] ;
360+
361+ const mockEvent = {
362+ contexts : {
363+ state : {
364+ state : undefined ,
365+ } ,
366+ } ,
367+ } ;
368+
369+ const mockHint = {
370+ attachments : [ ] ,
371+ } ;
372+
373+ const result = callbackFunction ( mockEvent , mockHint ) ;
374+
375+ expect ( result ) . toEqual ( mockEvent ) ;
376+
377+ expect ( mockHint . attachments ) . toHaveLength ( 0 ) ;
378+ } ) ;
379+
380+ it ( 'does not attach when event type is not undefined' , ( ) => {
381+ const enhancer = createReduxEnhancer ( ) ;
382+
383+ const initialState = {
384+ value : 'initial' ,
385+ } ;
386+
387+ Redux . createStore ( ( state = initialState ) => state , enhancer ) ;
388+
389+ expect ( mockAddGlobalEventProcessor ) . toHaveBeenCalledTimes ( 1 ) ;
390+
391+ const callbackFunction = mockAddGlobalEventProcessor . mock . calls [ 0 ] [ 0 ] ;
392+
393+ const mockEvent = {
394+ type : 'not_redux' ,
395+ contexts : {
396+ state : {
397+ state : {
398+ type : 'redux' ,
399+ value : 'UPDATED_VALUE' ,
400+ } ,
401+ } ,
402+ } ,
403+ } ;
404+
405+ const mockHint = {
406+ attachments : [ ] ,
407+ } ;
408+
409+ const result = callbackFunction ( mockEvent , mockHint ) ;
410+
411+ expect ( result ) . toEqual ( mockEvent ) ;
412+
413+ expect ( mockHint . attachments ) . toHaveLength ( 0 ) ;
414+ } ) ;
415+ } ) ;
246416} ) ;
0 commit comments