@@ -217,3 +217,188 @@ impl<'de> serde::Deserialize<'de> for HttpSignalingInfo {
217
217
s. parse ( ) . map_err ( serde:: de:: Error :: custom)
218
218
}
219
219
}
220
+
221
+ #[ cfg( test) ]
222
+ mod tests {
223
+ //! Unit tests for HttpSignalingInfo parsing
224
+ //!
225
+ //! Run these tests with:
226
+ //! ```bash
227
+ //! cargo test -p p2p signaling_method::http::tests
228
+ //! ```
229
+
230
+ use super :: * ;
231
+ use crate :: webrtc:: Host ;
232
+ use std:: net:: Ipv4Addr ;
233
+
234
+ #[ test]
235
+ fn test_from_str_valid_domain_and_port ( ) {
236
+ let info: HttpSignalingInfo = "example.com/8080" . parse ( ) . unwrap ( ) ;
237
+ assert_eq ! ( info. host, Host :: Domain ( "example.com" . to_string( ) ) ) ;
238
+ assert_eq ! ( info. port, 8080 ) ;
239
+ }
240
+
241
+ #[ test]
242
+ fn test_from_str_valid_domain_and_port_with_leading_slash ( ) {
243
+ let info: HttpSignalingInfo = "/example.com/8080" . parse ( ) . unwrap ( ) ;
244
+ assert_eq ! ( info. host, Host :: Domain ( "example.com" . to_string( ) ) ) ;
245
+ assert_eq ! ( info. port, 8080 ) ;
246
+ }
247
+
248
+ #[ test]
249
+ fn test_from_str_valid_ipv4_and_port ( ) {
250
+ let info: HttpSignalingInfo = "192.168.1.1/443" . parse ( ) . unwrap ( ) ;
251
+ assert_eq ! ( info. host, Host :: Ipv4 ( Ipv4Addr :: new( 192 , 168 , 1 , 1 ) ) ) ;
252
+ assert_eq ! ( info. port, 443 ) ;
253
+ }
254
+
255
+ #[ test]
256
+ fn test_from_str_valid_ipv6_and_port ( ) {
257
+ let info: HttpSignalingInfo = "[::1]/8080" . parse ( ) . unwrap ( ) ;
258
+ assert ! ( matches!( info. host, Host :: Ipv6 ( _) ) ) ;
259
+ assert_eq ! ( info. port, 8080 ) ;
260
+ }
261
+
262
+ #[ test]
263
+ fn test_from_str_valid_localhost_and_standard_ports ( ) {
264
+ let info: HttpSignalingInfo = "localhost/80" . parse ( ) . unwrap ( ) ;
265
+ assert_eq ! ( info. host, Host :: Domain ( "localhost" . to_string( ) ) ) ;
266
+ assert_eq ! ( info. port, 80 ) ;
267
+
268
+ let info: HttpSignalingInfo = "localhost/443" . parse ( ) . unwrap ( ) ;
269
+ assert_eq ! ( info. host, Host :: Domain ( "localhost" . to_string( ) ) ) ;
270
+ assert_eq ! ( info. port, 443 ) ;
271
+ }
272
+
273
+ #[ test]
274
+ fn test_from_str_valid_high_port_number ( ) {
275
+ let info: HttpSignalingInfo = "example.com/65535" . parse ( ) . unwrap ( ) ;
276
+ assert_eq ! ( info. host, Host :: Domain ( "example.com" . to_string( ) ) ) ;
277
+ assert_eq ! ( info. port, 65535 ) ;
278
+ }
279
+
280
+ #[ test]
281
+ fn test_from_str_missing_host ( ) {
282
+ let result: Result < HttpSignalingInfo , _ > = "/8080" . parse ( ) ;
283
+ assert ! ( result. is_err( ) ) ;
284
+ assert ! ( matches!(
285
+ result. unwrap_err( ) ,
286
+ SignalingMethodParseError :: NotEnoughArgs
287
+ ) ) ;
288
+ }
289
+
290
+ #[ test]
291
+ fn test_from_str_missing_port ( ) {
292
+ let result: Result < HttpSignalingInfo , _ > = "example.com" . parse ( ) ;
293
+ assert ! ( result. is_err( ) ) ;
294
+ assert ! ( matches!(
295
+ result. unwrap_err( ) ,
296
+ SignalingMethodParseError :: NotEnoughArgs
297
+ ) ) ;
298
+ }
299
+
300
+ #[ test]
301
+ fn test_from_str_empty_string ( ) {
302
+ let result: Result < HttpSignalingInfo , _ > = "" . parse ( ) ;
303
+ assert ! ( result. is_err( ) ) ;
304
+ assert ! ( matches!(
305
+ result. unwrap_err( ) ,
306
+ SignalingMethodParseError :: NotEnoughArgs
307
+ ) ) ;
308
+ }
309
+
310
+ #[ test]
311
+ fn test_from_str_only_slashes ( ) {
312
+ let result: Result < HttpSignalingInfo , _ > = "///" . parse ( ) ;
313
+ assert ! ( result. is_err( ) ) ;
314
+ assert ! ( matches!(
315
+ result. unwrap_err( ) ,
316
+ SignalingMethodParseError :: NotEnoughArgs
317
+ ) ) ;
318
+ }
319
+
320
+ #[ test]
321
+ fn test_from_str_invalid_port_not_number ( ) {
322
+ let result: Result < HttpSignalingInfo , _ > = "example.com/abc" . parse ( ) ;
323
+ assert ! ( result. is_err( ) ) ;
324
+ assert ! ( matches!(
325
+ result. unwrap_err( ) ,
326
+ SignalingMethodParseError :: PortParseError ( _)
327
+ ) ) ;
328
+ }
329
+
330
+ #[ test]
331
+ fn test_from_str_invalid_port_too_large ( ) {
332
+ let result: Result < HttpSignalingInfo , _ > = "example.com/99999" . parse ( ) ;
333
+ assert ! ( result. is_err( ) ) ;
334
+ assert ! ( matches!(
335
+ result. unwrap_err( ) ,
336
+ SignalingMethodParseError :: PortParseError ( _)
337
+ ) ) ;
338
+ }
339
+
340
+ #[ test]
341
+ fn test_from_str_invalid_port_negative ( ) {
342
+ let result: Result < HttpSignalingInfo , _ > = "example.com/-1" . parse ( ) ;
343
+ assert ! ( result. is_err( ) ) ;
344
+ assert ! ( matches!(
345
+ result. unwrap_err( ) ,
346
+ SignalingMethodParseError :: PortParseError ( _)
347
+ ) ) ;
348
+ }
349
+
350
+ #[ test]
351
+ fn test_from_str_invalid_host_empty ( ) {
352
+ let result: Result < HttpSignalingInfo , _ > = "/8080" . parse ( ) ;
353
+ assert ! ( result. is_err( ) ) ;
354
+ assert ! ( matches!(
355
+ result. unwrap_err( ) ,
356
+ SignalingMethodParseError :: NotEnoughArgs
357
+ ) ) ;
358
+ }
359
+
360
+ #[ test]
361
+ fn test_from_str_extra_components_ignored ( ) {
362
+ // Should only use first two non-empty components
363
+ let info: HttpSignalingInfo = "example.com/8080/extra/stuff" . parse ( ) . unwrap ( ) ;
364
+ assert_eq ! ( info. host, Host :: Domain ( "example.com" . to_string( ) ) ) ;
365
+ assert_eq ! ( info. port, 8080 ) ;
366
+ }
367
+
368
+ #[ test]
369
+ fn test_from_str_whitespace_in_components ( ) {
370
+ // Components with whitespace should be trimmed by the split filter
371
+ let result: Result < HttpSignalingInfo , _ > = " / /8080" . parse ( ) ;
372
+ assert ! ( result. is_err( ) ) ;
373
+ assert ! ( matches!(
374
+ result. unwrap_err( ) ,
375
+ SignalingMethodParseError :: NotEnoughArgs
376
+ ) ) ;
377
+ }
378
+
379
+ #[ test]
380
+ fn test_roundtrip_display_and_from_str ( ) {
381
+ let original = HttpSignalingInfo {
382
+ host : Host :: Domain ( "signal.example.com" . to_string ( ) ) ,
383
+ port : 443 ,
384
+ } ;
385
+
386
+ let serialized = original. to_string ( ) ;
387
+ let deserialized: HttpSignalingInfo = serialized. parse ( ) . unwrap ( ) ;
388
+
389
+ assert_eq ! ( original, deserialized) ;
390
+ }
391
+
392
+ #[ test]
393
+ fn test_roundtrip_ipv4 ( ) {
394
+ let original = HttpSignalingInfo {
395
+ host : Host :: Ipv4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) ,
396
+ port : 8080 ,
397
+ } ;
398
+
399
+ let serialized = original. to_string ( ) ;
400
+ let deserialized: HttpSignalingInfo = serialized. parse ( ) . unwrap ( ) ;
401
+
402
+ assert_eq ! ( original, deserialized) ;
403
+ }
404
+ }
0 commit comments