@@ -6,6 +6,9 @@ import io.sentry.SentryReplayOptions.SentryReplayQuality.LOW
66import io.sentry.protocol.SdkVersion
77import io.sentry.protocol.SerializationUtils
88import kotlin.test.assertEquals
9+ import kotlin.test.assertFalse
10+ import kotlin.test.assertTrue
11+ import kotlin.test.assertContentEquals
912import org.junit.Test
1013import org.mockito.kotlin.mock
1114
@@ -48,4 +51,99 @@ class RRWebOptionsEventSerializationTest {
4851 val actualJson = SerializationUtils .serializeToString(actual, fixture.logger)
4952 assertEquals(expectedJson, actualJson)
5053 }
54+
55+ @Test
56+ fun `network detail fields are not included when networkDetailAllowUrls is empty` () {
57+ val options = SentryOptions ().apply {
58+ sessionReplay.setNetworkDetailAllowUrls(emptyArray())
59+
60+ // Any config is ignored when no allowUrls are specified.
61+ sessionReplay.setNetworkDetailDenyUrls(arrayOf(" https://internal.example.com/*" ))
62+ sessionReplay.setNetworkRequestHeaders(listOf (" Authorization" , " X-Custom" ))
63+ sessionReplay.setNetworkResponseHeaders(listOf (" X-RateLimit" , " Content-Type" ))
64+ }
65+ val event = RRWebOptionsEvent (options)
66+
67+ val payload = event.optionsPayload
68+ assertFalse(payload.containsKey(" networkDetailAllowUrls" ))
69+ assertFalse(payload.containsKey(" networkDetailDenyUrls" ))
70+ assertFalse(payload.containsKey(" networkRequestHeaders" ))
71+ assertFalse(payload.containsKey(" networkResponseHeaders" ))
72+ assertFalse(payload.containsKey(" networkCaptureBodies" ))
73+ assertEquals(false , payload[" networkDetailHasUrls" ])
74+ }
75+
76+ @Test
77+ fun `networkDetailAllowUrls and headers are included when networkDetailAllowUrls is configured` () {
78+ val options = SentryOptions ().apply {
79+ sessionReplay.setNetworkDetailAllowUrls(arrayOf(" https://api.example.com/*" ))
80+ sessionReplay.setNetworkRequestHeaders(listOf (" Authorization" , " X-Custom" ))
81+ sessionReplay.setNetworkResponseHeaders(listOf (" X-RateLimit" , " Content-Type" ))
82+ }
83+ val event = RRWebOptionsEvent (options)
84+
85+ val payload = event.optionsPayload
86+ assertTrue(payload.containsKey(" networkDetailAllowUrls" ))
87+ assertTrue(payload.containsKey(" networkRequestHeaders" ))
88+ assertTrue(payload.containsKey(" networkResponseHeaders" ))
89+ assertEquals(true , payload[" networkDetailHasUrls" ])
90+ assertContentEquals(arrayOf(" https://api.example.com/*" ), payload[" networkDetailAllowUrls" ] as Array <String >)
91+ assertContentEquals(arrayOf(" Content-Type" , " Content-Length" , " Accept" , " Authorization" , " X-Custom" ), payload[" networkRequestHeaders" ] as Array <String >)
92+ assertContentEquals(arrayOf(" Content-Type" , " Content-Length" , " Accept" , " X-RateLimit" ), payload[" networkResponseHeaders" ] as Array <String >)
93+ }
94+
95+ @Test
96+ fun `networkDetailDenyUrls are included when networkDetailAllowUrls is configured` () {
97+ val options = SentryOptions ().apply {
98+ sessionReplay.setNetworkDetailAllowUrls(arrayOf(" https://api.example.com/*" ))
99+ sessionReplay.setNetworkDetailDenyUrls(arrayOf(" https://internal.example.com/*" ))
100+ }
101+ val event = RRWebOptionsEvent (options)
102+
103+ val payload = event.optionsPayload
104+ assertTrue(payload.containsKey(" networkDetailAllowUrls" ))
105+ assertTrue(payload.containsKey(" networkDetailDenyUrls" ))
106+ assertContentEquals(arrayOf(" https://api.example.com/*" ), payload[" networkDetailAllowUrls" ] as Array <String >)
107+ assertContentEquals(arrayOf(" https://internal.example.com/*" ), payload[" networkDetailDenyUrls" ] as Array <String >)
108+ }
109+
110+ @Test
111+ fun `networkCaptureBodies is included when networkDetailAllowUrls is configured` () {
112+ val options = SentryOptions ().apply {
113+ sessionReplay.setNetworkDetailAllowUrls(arrayOf(" https://api.example.com/*" ))
114+ sessionReplay.setNetworkCaptureBodies(false )
115+ }
116+ val event = RRWebOptionsEvent (options)
117+
118+ val payload = event.optionsPayload
119+ assertTrue(payload.containsKey(" networkCaptureBodies" ))
120+ assertEquals(false , payload[" networkCaptureBodies" ])
121+ }
122+
123+ @Test
124+ fun `default networkCaptureBodies is included when networkDetailAllowUrls is configured` () {
125+ val options = SentryOptions ().apply {
126+ sessionReplay.setNetworkDetailAllowUrls(arrayOf(" https://api.example.com/*" ))
127+ }
128+ val event = RRWebOptionsEvent (options)
129+
130+ val payload = event.optionsPayload
131+ assertTrue(payload.containsKey(" networkCaptureBodies" ))
132+ assertEquals(true , payload[" networkCaptureBodies" ])
133+ }
134+
135+ @Test
136+ fun `default network request and response headers are included when networkDetailAllowUrls is configured but no custom headers set` () {
137+ val options = SentryOptions ().apply {
138+ sessionReplay.setNetworkDetailAllowUrls(arrayOf(" https://api.example.com/*" ))
139+ // No custom headers set, should use defaults only
140+ }
141+ val event = RRWebOptionsEvent (options)
142+
143+ val payload = event.optionsPayload
144+ assertTrue(payload.containsKey(" networkRequestHeaders" ))
145+ assertTrue(payload.containsKey(" networkResponseHeaders" ))
146+ assertContentEquals(arrayOf(" Content-Type" , " Content-Length" , " Accept" ), payload[" networkRequestHeaders" ] as Array <String >)
147+ assertContentEquals(arrayOf(" Content-Type" , " Content-Length" , " Accept" ), payload[" networkResponseHeaders" ] as Array <String >)
148+ }
51149}
0 commit comments