@@ -2,8 +2,21 @@ import * as mockedtimetodisplaynative from './tracing/mockedtimetodisplaynative'
2
2
jest . mock ( '../src/js/tracing/timetodisplaynative' , ( ) => mockedtimetodisplaynative ) ;
3
3
4
4
import { defaultStackParser } from '@sentry/browser' ;
5
- import type { Envelope , Event , Outcome , Transport , TransportMakeRequestResponse } from '@sentry/core' ;
6
- import { rejectedSyncPromise , SentryError } from '@sentry/core' ;
5
+ import type {
6
+ Envelope ,
7
+ Event ,
8
+ Outcome ,
9
+ SessionAggregates ,
10
+ Transport ,
11
+ TransportMakeRequestResponse ,
12
+ } from '@sentry/core' ;
13
+ import {
14
+ addAutoIpAddressToSession ,
15
+ addAutoIpAddressToUser ,
16
+ makeSession ,
17
+ rejectedSyncPromise ,
18
+ SentryError ,
19
+ } from '@sentry/core' ;
7
20
import * as RN from 'react-native' ;
8
21
9
22
import { ReactNativeClient } from '../src/js/client' ;
@@ -625,6 +638,206 @@ describe('Tests ReactNativeClient', () => {
625
638
client . recordDroppedEvent ( 'before_send' , 'error' ) ;
626
639
}
627
640
} ) ;
641
+
642
+ describe ( 'ipAddress' , ( ) => {
643
+ let mockTransportSend : jest . Mock ;
644
+ let client : ReactNativeClient ;
645
+
646
+ beforeEach ( ( ) => {
647
+ mockTransportSend = jest . fn ( ( ) => Promise . resolve ( ) ) ;
648
+ client = new ReactNativeClient ( {
649
+ ...DEFAULT_OPTIONS ,
650
+ dsn : EXAMPLE_DSN ,
651
+ transport : ( ) => ( {
652
+ send : mockTransportSend ,
653
+ flush : jest . fn ( ) ,
654
+ } ) ,
655
+ sendDefaultPii : true ,
656
+ } ) ;
657
+ } ) ;
658
+
659
+ test ( 'preserves ip_address null' , ( ) => {
660
+ client . captureEvent ( {
661
+ user : {
662
+ ip_address : null ,
663
+ } ,
664
+ } ) ;
665
+
666
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ) . toEqual (
667
+ expect . objectContaining ( { ip_address : null } ) ,
668
+ ) ;
669
+ } ) ;
670
+
671
+ test ( 'preserves ip_address value if set' , ( ) => {
672
+ client . captureEvent ( {
673
+ user : {
674
+ ip_address : '203.45.167.89' ,
675
+ } ,
676
+ } ) ;
677
+
678
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ) . toEqual (
679
+ expect . objectContaining ( { ip_address : '203.45.167.89' } ) ,
680
+ ) ;
681
+ } ) ;
682
+
683
+ test ( 'adds ip_address {{auto}} to user if set to undefined' , ( ) => {
684
+ client . captureEvent ( {
685
+ user : {
686
+ ip_address : undefined ,
687
+ } ,
688
+ } ) ;
689
+
690
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ) . toEqual (
691
+ expect . objectContaining ( { ip_address : '{{auto}}' } ) ,
692
+ ) ;
693
+ } ) ;
694
+
695
+ test ( 'adds ip_address {{auto}} to user if not set' , ( ) => {
696
+ client . captureEvent ( {
697
+ user : { } ,
698
+ } ) ;
699
+
700
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ) . toEqual (
701
+ expect . objectContaining ( { ip_address : '{{auto}}' } ) ,
702
+ ) ;
703
+ } ) ;
704
+
705
+ test ( 'adds ip_address {{auto}} to undefined user' , ( ) => {
706
+ client . captureEvent ( { } ) ;
707
+
708
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ) . toEqual (
709
+ expect . objectContaining ( { ip_address : '{{auto}}' } ) ,
710
+ ) ;
711
+ } ) ;
712
+
713
+ test ( 'does not add ip_address {{auto}} to undefined user if sendDefaultPii is false' , ( ) => {
714
+ const { client, onSpy } = createClientWithSpy ( {
715
+ transport : ( ) => ( {
716
+ send : mockTransportSend ,
717
+ flush : jest . fn ( ) ,
718
+ } ) ,
719
+ sendDefaultPii : false ,
720
+ } ) ;
721
+
722
+ client . captureEvent ( { } ) ;
723
+
724
+ expect ( onSpy ) . not . toHaveBeenCalledWith ( 'postprocessEvent' , addAutoIpAddressToUser ) ;
725
+ expect (
726
+ mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . user ?. ip_address ,
727
+ ) . toBeUndefined ( ) ;
728
+ } ) ;
729
+
730
+ test ( 'uses ip address hooks if sendDefaultPii is true' , ( ) => {
731
+ const { onSpy } = createClientWithSpy ( {
732
+ sendDefaultPii : true ,
733
+ } ) ;
734
+
735
+ expect ( onSpy ) . toHaveBeenCalledWith ( 'postprocessEvent' , addAutoIpAddressToUser ) ;
736
+ expect ( onSpy ) . toHaveBeenCalledWith ( 'beforeSendSession' , addAutoIpAddressToSession ) ;
737
+ } ) ;
738
+
739
+ test ( 'does not add ip_address {{auto}} to session if sendDefaultPii is false' , ( ) => {
740
+ const { client, onSpy } = createClientWithSpy ( {
741
+ release : 'test' , // required for sessions to be sent
742
+ transport : ( ) => ( {
743
+ send : mockTransportSend ,
744
+ flush : jest . fn ( ) ,
745
+ } ) ,
746
+ sendDefaultPii : false ,
747
+ } ) ;
748
+
749
+ const session = makeSession ( ) ;
750
+ session . ipAddress = undefined ;
751
+ client . captureSession ( session ) ;
752
+
753
+ expect ( onSpy ) . not . toHaveBeenCalledWith ( 'beforeSendSession' , addAutoIpAddressToSession ) ;
754
+ expect (
755
+ mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . attrs . ip_address ,
756
+ ) . toBeUndefined ( ) ;
757
+ } ) ;
758
+
759
+ test ( 'does not add ip_address {{auto}} to session aggregate if sendDefaultPii is false' , ( ) => {
760
+ const { client, onSpy } = createClientWithSpy ( {
761
+ release : 'test' , // required for sessions to be sent
762
+ transport : ( ) => ( {
763
+ send : mockTransportSend ,
764
+ flush : jest . fn ( ) ,
765
+ } ) ,
766
+ sendDefaultPii : false ,
767
+ } ) ;
768
+
769
+ const session : SessionAggregates = {
770
+ aggregates : [ ] ,
771
+ } ;
772
+ client . sendSession ( session ) ;
773
+
774
+ expect ( onSpy ) . not . toHaveBeenCalledWith ( 'beforeSendSession' , addAutoIpAddressToSession ) ;
775
+ expect (
776
+ mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . attrs . ip_address ,
777
+ ) . toBeUndefined ( ) ;
778
+ } ) ;
779
+
780
+ test ( 'does not overwrite session aggregate ip_address if already set' , ( ) => {
781
+ const { client } = createClientWithSpy ( {
782
+ release : 'test' , // required for sessions to be sent
783
+ transport : ( ) => ( {
784
+ send : mockTransportSend ,
785
+ flush : jest . fn ( ) ,
786
+ } ) ,
787
+ sendDefaultPii : true ,
788
+ } ) ;
789
+
790
+ const session : SessionAggregates = {
791
+ aggregates : [ ] ,
792
+ attrs : {
793
+ ip_address : '123.45.67.89' ,
794
+ } ,
795
+ } ;
796
+ client . sendSession ( session ) ;
797
+
798
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . attrs . ip_address ) . toBe (
799
+ '123.45.67.89' ,
800
+ ) ;
801
+ } ) ;
802
+
803
+ test ( 'does add ip_address {{auto}} to session if sendDefaultPii is true' , ( ) => {
804
+ const { client } = createClientWithSpy ( {
805
+ release : 'test' , // required for sessions to be sent
806
+ transport : ( ) => ( {
807
+ send : mockTransportSend ,
808
+ flush : jest . fn ( ) ,
809
+ } ) ,
810
+ sendDefaultPii : true ,
811
+ } ) ;
812
+
813
+ const session = makeSession ( ) ;
814
+ session . ipAddress = undefined ;
815
+ client . captureSession ( session ) ;
816
+
817
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . attrs . ip_address ) . toBe (
818
+ '{{auto}}' ,
819
+ ) ;
820
+ } ) ;
821
+
822
+ test ( 'does not overwrite session ip_address if already set' , ( ) => {
823
+ const { client } = createClientWithSpy ( {
824
+ release : 'test' , // required for sessions to be sent
825
+ transport : ( ) => ( {
826
+ send : mockTransportSend ,
827
+ flush : jest . fn ( ) ,
828
+ } ) ,
829
+ sendDefaultPii : true ,
830
+ } ) ;
831
+
832
+ const session = makeSession ( ) ;
833
+ session . ipAddress = '123.45.67.89' ;
834
+ client . captureSession ( session ) ;
835
+
836
+ expect ( mockTransportSend . mock . calls [ 0 ] [ firstArg ] [ envelopeItems ] [ 0 ] [ envelopeItemPayload ] . attrs . ip_address ) . toBe (
837
+ '123.45.67.89' ,
838
+ ) ;
839
+ } ) ;
840
+ } ) ;
628
841
} ) ;
629
842
630
843
function mockedOptions ( options : Partial < ReactNativeClientOptions > ) : ReactNativeClientOptions {
@@ -638,3 +851,23 @@ function mockedOptions(options: Partial<ReactNativeClientOptions>): ReactNativeC
638
851
...options ,
639
852
} ;
640
853
}
854
+
855
+ function createClientWithSpy ( options : Partial < ReactNativeClientOptions > ) {
856
+ const onSpy = jest . fn ( ) ;
857
+ class SpyClient extends ReactNativeClient {
858
+ public on ( hook : string , callback : unknown ) : ( ) => void {
859
+ onSpy ( hook , callback ) ;
860
+ // @ts -expect-error - the public interface doesn't allow string and unknown
861
+ return super . on ( hook , callback ) ;
862
+ }
863
+ }
864
+
865
+ return {
866
+ client : new SpyClient ( {
867
+ ...DEFAULT_OPTIONS ,
868
+ dsn : EXAMPLE_DSN ,
869
+ ...options ,
870
+ } ) ,
871
+ onSpy,
872
+ } ;
873
+ }
0 commit comments