@@ -21,7 +21,6 @@ class SentryReplayNetworkDetailsBodyTests: XCTestCase {
2121 let body = Body ( data: bodyData, contentType: " application/json " )
2222
2323 // -- Assert --
24- XCTAssertNotNil ( body)
2524 if case . json( let value) = body? . content {
2625 let dict = value as? [ String : Any ]
2726 XCTAssertEqual ( dict ? [ " key " ] as? String , " value " )
@@ -45,7 +44,6 @@ class SentryReplayNetworkDetailsBodyTests: XCTestCase {
4544 let body = Body ( data: bodyData, contentType: " application/json " )
4645
4746 // -- Assert --
48- XCTAssertNotNil ( body)
4947 if case . json( let value) = body? . content {
5048 let array = value as? [ String ]
5149 XCTAssertEqual ( array? . count, 3 )
@@ -84,28 +82,6 @@ class SentryReplayNetworkDetailsBodyTests: XCTestCase {
8482 XCTAssertNil ( body)
8583 }
8684
87- func testInit_withFormURLEncoded_shouldParseAsForm( ) {
88- // -- Arrange --
89- let formString = " key1=value1&key2=value2&key3=value%20with%20spaces "
90- guard let bodyData = formString. data ( using: . utf8) else {
91- return XCTFail ( " Failed to create form data " )
92- }
93-
94- // -- Act --
95- let body = Body ( data: bodyData, contentType: " application/x-www-form-urlencoded " )
96-
97- // -- Assert --
98- XCTAssertNotNil ( body)
99- if case . json( let value) = body? . content {
100- let dict = value as? [ String : String ]
101- XCTAssertEqual ( dict ? [ " key1 " ] , " value1 " )
102- XCTAssertEqual ( dict ? [ " key2 " ] , " value2 " )
103- XCTAssertEqual ( dict ? [ " key3 " ] , " value with spaces " )
104- } else {
105- XCTFail ( " Expected .json content for form data " )
106- }
107- }
108-
10985 func testInit_withInvalidJSON_shouldFallbackToString( ) {
11086 // -- Arrange --
11187 let invalidJSON = " { invalid json } "
@@ -216,6 +192,108 @@ class SentryReplayNetworkDetailsBodyTests: XCTestCase {
216192 XCTFail ( " Expected .text content with placeholder description " )
217193 }
218194 }
195+
196+ // MARK: - Form URL-Encoded Parsing
197+
198+ func testInit_withFormURLEncoded_shouldParseAsForm( ) {
199+ // -- Arrange --
200+ let formString = " key1=value1&key2=value2&key3=value%20with%20spaces "
201+ guard let bodyData = formString. data ( using: . utf8) else {
202+ return XCTFail ( " Failed to create form data " )
203+ }
204+
205+ // -- Act --
206+ let body = Body ( data: bodyData, contentType: " application/x-www-form-urlencoded " )
207+
208+ // -- Assert --
209+ if case . json( let value) = body? . content {
210+ let dict = value as? [ String : String ]
211+ XCTAssertEqual ( dict ? [ " key1 " ] , " value1 " )
212+ XCTAssertEqual ( dict ? [ " key2 " ] , " value2 " )
213+ XCTAssertEqual ( dict ? [ " key3 " ] , " value with spaces " )
214+ } else {
215+ XCTFail ( " Expected .json content for form data " )
216+ }
217+ }
218+
219+ func testInit_withFormURLEncoded_duplicateKeys_shouldPromoteToArray( ) throws {
220+ // -- Act --
221+ let body = try XCTUnwrap ( Body (
222+ data: " color=red&color=blue&color=green " . data ( using: . utf8) !,
223+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
224+ ) )
225+
226+ // -- Assert --
227+ let dict = try XCTUnwrap ( body. serialize ( ) [ " body " ] as? [ String : Any ] )
228+ XCTAssertEqual ( dict [ " color " ] as? [ String ] , [ " red " , " blue " , " green " ] )
229+ }
230+
231+ func testInit_withFormURLEncoded_emptyValue_shouldParseAsEmptyString( ) throws {
232+ // -- Act --
233+ let body = try XCTUnwrap ( Body (
234+ data: " key1=&key2=value2 " . data ( using: . utf8) !,
235+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
236+ ) )
237+
238+ // -- Assert --
239+ let dict = try XCTUnwrap ( body. serialize ( ) [ " body " ] as? [ String : Any ] )
240+ XCTAssertEqual ( dict [ " key1 " ] as? String , " " )
241+ XCTAssertEqual ( dict [ " key2 " ] as? String , " value2 " )
242+ }
243+
244+ func testInit_withFormURLEncoded_missingEquals_shouldFallbackToText( ) throws {
245+ // -- Act --
246+ let body = try XCTUnwrap ( Body (
247+ data: " key1=value1&malformed&key2=value2 " . data ( using: . utf8) !,
248+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
249+ ) )
250+
251+ // -- Assert --
252+ let serialized = body. serialize ( )
253+ let text = try XCTUnwrap ( serialized [ " body " ] as? String )
254+ XCTAssertEqual ( text, " key1=value1&malformed&key2=value2 " )
255+ let warnings = try XCTUnwrap ( serialized [ " warnings " ] as? [ String ] )
256+ XCTAssertTrue ( warnings. contains ( " BODY_PARSE_ERROR " ) )
257+ }
258+
259+ func testInit_withFormURLEncoded_emptyKeys_shouldBeSkipped( ) throws {
260+ // -- Act --
261+ let body = try XCTUnwrap ( Body (
262+ data: " =value1&key2=value2 " . data ( using: . utf8) !,
263+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
264+ ) )
265+
266+ // -- Assert --
267+ let dict = try XCTUnwrap ( body. serialize ( ) [ " body " ] as? [ String : Any ] )
268+ XCTAssertNil ( dict [ " " ] )
269+ XCTAssertEqual ( dict [ " key2 " ] as? String , " value2 " )
270+ }
271+
272+ func testInit_withFormURLEncoded_equalsInValue_shouldPreserve( ) throws {
273+ // -- Act --
274+ let body = try XCTUnwrap ( Body (
275+ data: " query=a=1&token=abc " . data ( using: . utf8) !,
276+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
277+ ) )
278+
279+ // -- Assert --
280+ let dict = try XCTUnwrap ( body. serialize ( ) [ " body " ] as? [ String : Any ] )
281+ XCTAssertEqual ( dict [ " query " ] as? String , " a=1 " )
282+ XCTAssertEqual ( dict [ " token " ] as? String , " abc " )
283+ }
284+
285+ func testInit_withFormURLEncoded_plusAsSpace_shouldDecode( ) throws {
286+ // -- Act --
287+ let body = try XCTUnwrap ( Body (
288+ data: " greeting=hello+world&name=Jane+Doe " . data ( using: . utf8) !,
289+ contentType: " application/x-www-form-urlencoded; charset=utf-8 "
290+ ) )
291+
292+ // -- Assert --
293+ let dict = try XCTUnwrap ( body. serialize ( ) [ " body " ] as? [ String : Any ] )
294+ XCTAssertEqual ( dict [ " greeting " ] as? String , " hello world " )
295+ XCTAssertEqual ( dict [ " name " ] as? String , " Jane Doe " )
296+ }
219297
220298 // MARK: - Serialization Tests
221299
0 commit comments