@@ -188,3 +188,273 @@ impl From<IpAddr> for Host {
188
188
}
189
189
}
190
190
}
191
+
192
+ #[ cfg( test) ]
193
+ mod tests {
194
+ //! Unit tests for Host address resolution and parsing
195
+ //!
196
+ //! Run these tests with:
197
+ //! ```bash
198
+ //! cargo test -p p2p webrtc::host::tests
199
+ //! ```
200
+
201
+ use super :: * ;
202
+ use std:: net:: { Ipv4Addr , Ipv6Addr } ;
203
+
204
+ #[ test]
205
+ fn test_resolve_ipv4_unchanged ( ) {
206
+ let host = Host :: Ipv4 ( Ipv4Addr :: new ( 192 , 168 , 1 , 1 ) ) ;
207
+ let resolved = host. resolve ( ) . unwrap ( ) ;
208
+
209
+ match resolved {
210
+ Host :: Ipv4 ( addr) => assert_eq ! ( addr, Ipv4Addr :: new( 192 , 168 , 1 , 1 ) ) ,
211
+ _ => panic ! ( "Expected IPv4 variant unchanged" ) ,
212
+ }
213
+ }
214
+
215
+ #[ test]
216
+ fn test_resolve_ipv6_unchanged ( ) {
217
+ let host = Host :: Ipv6 ( Ipv6Addr :: LOCALHOST ) ;
218
+ let resolved = host. resolve ( ) . unwrap ( ) ;
219
+
220
+ match resolved {
221
+ Host :: Ipv6 ( addr) => assert_eq ! ( addr, Ipv6Addr :: LOCALHOST ) ,
222
+ _ => panic ! ( "Expected IPv6 variant unchanged" ) ,
223
+ }
224
+ }
225
+
226
+ #[ test]
227
+ fn test_resolve_localhost_domain ( ) {
228
+ let host = Host :: Domain ( "localhost" . to_string ( ) ) ;
229
+ let resolved = host. resolve ( ) ;
230
+
231
+ // localhost should resolve to either 127.0.0.1 or ::1
232
+ assert ! ( resolved. is_some( ) ) ;
233
+ let resolved = resolved. unwrap ( ) ;
234
+
235
+ match resolved {
236
+ Host :: Ipv4 ( addr) => {
237
+ // Should be 127.0.0.1 or similar loopback
238
+ assert ! ( addr. is_loopback( ) ) ;
239
+ }
240
+ Host :: Ipv6 ( addr) => {
241
+ // Should be ::1 or similar loopback
242
+ assert ! ( addr. is_loopback( ) ) ;
243
+ }
244
+ Host :: Domain ( _) => panic ! ( "Expected domain to resolve to IP address" ) ,
245
+ }
246
+ }
247
+
248
+ #[ test]
249
+ fn test_resolve_invalid_domain ( ) {
250
+ let host = Host :: Domain ( "invalid.domain.that.should.not.exist.xyz123" . to_string ( ) ) ;
251
+ let resolved = host. resolve ( ) ;
252
+
253
+ // Invalid domain should return None
254
+ assert ! ( resolved. is_none( ) ) ;
255
+ }
256
+
257
+ #[ test]
258
+ fn test_resolve_empty_domain ( ) {
259
+ let host = Host :: Domain ( "" . to_string ( ) ) ;
260
+ let resolved = host. resolve ( ) ;
261
+
262
+ // Empty domain should return None
263
+ assert ! ( resolved. is_none( ) ) ;
264
+ }
265
+
266
+ #[ test]
267
+ fn test_from_str_ipv4 ( ) {
268
+ let host: Host = "192.168.1.1" . parse ( ) . unwrap ( ) ;
269
+ match host {
270
+ Host :: Ipv4 ( addr) => assert_eq ! ( addr, Ipv4Addr :: new( 192 , 168 , 1 , 1 ) ) ,
271
+ _ => panic ! ( "Expected IPv4 variant" ) ,
272
+ }
273
+ }
274
+
275
+ #[ test]
276
+ fn test_from_str_ipv6 ( ) {
277
+ let host: Host = "[::1]" . parse ( ) . unwrap ( ) ;
278
+ match host {
279
+ Host :: Ipv6 ( addr) => assert_eq ! ( addr, Ipv6Addr :: LOCALHOST ) ,
280
+ _ => panic ! ( "Expected IPv6 variant" ) ,
281
+ }
282
+ }
283
+
284
+ #[ test]
285
+ fn test_from_str_ipv6_brackets ( ) {
286
+ let host: Host = "[::1]" . parse ( ) . unwrap ( ) ;
287
+ match host {
288
+ Host :: Ipv6 ( addr) => assert_eq ! ( addr, Ipv6Addr :: LOCALHOST ) ,
289
+ _ => panic ! ( "Expected IPv6 variant" ) ,
290
+ }
291
+ }
292
+
293
+ #[ test]
294
+ fn test_from_str_domain ( ) {
295
+ let host: Host = "example.com" . parse ( ) . unwrap ( ) ;
296
+ match host {
297
+ Host :: Domain ( domain) => assert_eq ! ( domain, "example.com" ) ,
298
+ _ => panic ! ( "Expected Domain variant" ) ,
299
+ }
300
+ }
301
+
302
+ #[ test]
303
+ fn test_from_str_invalid ( ) {
304
+ let result: Result < Host , _ > = "not a valid host" . parse ( ) ;
305
+ assert ! ( result. is_err( ) ) ;
306
+ }
307
+
308
+ #[ test]
309
+ fn test_display_ipv4 ( ) {
310
+ let host = Host :: Ipv4 ( Ipv4Addr :: new ( 10 , 0 , 0 , 1 ) ) ;
311
+ assert_eq ! ( host. to_string( ) , "10.0.0.1" ) ;
312
+ }
313
+
314
+ #[ test]
315
+ fn test_display_ipv6 ( ) {
316
+ let host = Host :: Ipv6 ( Ipv6Addr :: LOCALHOST ) ;
317
+ assert_eq ! ( host. to_string( ) , "[::1]" ) ;
318
+ }
319
+
320
+ #[ test]
321
+ fn test_display_domain ( ) {
322
+ let host = Host :: Domain ( "test.example.org" . to_string ( ) ) ;
323
+ assert_eq ! ( host. to_string( ) , "test.example.org" ) ;
324
+ }
325
+
326
+ #[ test]
327
+ fn test_roundtrip_ipv4 ( ) {
328
+ let original = Host :: Ipv4 ( Ipv4Addr :: new ( 203 , 0 , 113 , 42 ) ) ;
329
+ let serialized = original. to_string ( ) ;
330
+ let deserialized: Host = serialized. parse ( ) . unwrap ( ) ;
331
+ assert_eq ! ( original, deserialized) ;
332
+ }
333
+
334
+ #[ test]
335
+ fn test_roundtrip_ipv6 ( ) {
336
+ let original = Host :: Ipv6 ( Ipv6Addr :: new ( 0x2001 , 0xdb8 , 0 , 0 , 0 , 0 , 0 , 1 ) ) ;
337
+ let serialized = original. to_string ( ) ;
338
+ let deserialized: Host = serialized. parse ( ) . unwrap ( ) ;
339
+ assert_eq ! ( original, deserialized) ;
340
+ }
341
+
342
+ #[ test]
343
+ fn test_roundtrip_domain ( ) {
344
+ let original = Host :: Domain ( "api.example.net" . to_string ( ) ) ;
345
+ let serialized = original. to_string ( ) ;
346
+ let deserialized: Host = serialized. parse ( ) . unwrap ( ) ;
347
+ assert_eq ! ( original, deserialized) ;
348
+ }
349
+
350
+ #[ test]
351
+ fn test_from_ipaddr_v4 ( ) {
352
+ let ip = IpAddr :: V4 ( Ipv4Addr :: new ( 172 , 16 , 0 , 1 ) ) ;
353
+ let host = Host :: from ( ip) ;
354
+ match host {
355
+ Host :: Ipv4 ( addr) => assert_eq ! ( addr, Ipv4Addr :: new( 172 , 16 , 0 , 1 ) ) ,
356
+ _ => panic ! ( "Expected IPv4 variant" ) ,
357
+ }
358
+ }
359
+
360
+ #[ test]
361
+ fn test_from_ipaddr_v6 ( ) {
362
+ let ip = IpAddr :: V6 ( Ipv6Addr :: new ( 0xfe80 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ) ;
363
+ let host = Host :: from ( ip) ;
364
+ match host {
365
+ Host :: Ipv6 ( addr) => assert_eq ! ( addr, Ipv6Addr :: new( 0xfe80 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ) ,
366
+ _ => panic ! ( "Expected IPv6 variant" ) ,
367
+ }
368
+ }
369
+
370
+ #[ test]
371
+ fn test_from_array_ipv4 ( ) {
372
+ let bytes = [ 10 , 0 , 0 , 1 ] ;
373
+ let host = Host :: from ( bytes) ;
374
+ match host {
375
+ Host :: Ipv4 ( addr) => assert_eq ! ( addr, Ipv4Addr :: new( 10 , 0 , 0 , 1 ) ) ,
376
+ _ => panic ! ( "Expected IPv4 variant" ) ,
377
+ }
378
+ }
379
+
380
+ #[ test]
381
+ fn test_ord_comparison ( ) {
382
+ let host1 = Host :: Domain ( "a.example.com" . to_string ( ) ) ;
383
+ let host2 = Host :: Domain ( "b.example.com" . to_string ( ) ) ;
384
+ let host3 = Host :: Ipv4 ( Ipv4Addr :: new ( 1 , 1 , 1 , 1 ) ) ;
385
+ let host4 = Host :: Ipv4 ( Ipv4Addr :: new ( 2 , 2 , 2 , 2 ) ) ;
386
+
387
+ assert ! ( host1 < host2) ;
388
+ assert ! ( host3 < host4) ;
389
+ // Domain variants should have consistent ordering with IP variants
390
+ assert ! ( host1. partial_cmp( & host3) . is_some( ) ) ;
391
+ }
392
+
393
+ #[ test]
394
+ fn test_clone_and_equality ( ) {
395
+ let original = Host :: Domain ( "clone-test.example.com" . to_string ( ) ) ;
396
+ let cloned = original. clone ( ) ;
397
+ assert_eq ! ( original, cloned) ;
398
+
399
+ let different = Host :: Domain ( "different.example.com" . to_string ( ) ) ;
400
+ assert_ne ! ( original, different) ;
401
+ }
402
+
403
+ #[ test]
404
+ fn test_multiaddr_protocol_conversion ( ) {
405
+ use multiaddr:: Protocol ;
406
+
407
+ let domain_host = Host :: Domain ( "test.com" . to_string ( ) ) ;
408
+ let protocol = Protocol :: from ( & domain_host) ;
409
+ if let Protocol :: Dns4 ( cow_str) = protocol {
410
+ assert_eq ! ( cow_str, "test.com" ) ;
411
+ } else {
412
+ panic ! ( "Expected Dns4 protocol" ) ;
413
+ }
414
+
415
+ let ipv4_host = Host :: Ipv4 ( Ipv4Addr :: new ( 1 , 2 , 3 , 4 ) ) ;
416
+ let protocol = Protocol :: from ( & ipv4_host) ;
417
+ if let Protocol :: Ip4 ( addr) = protocol {
418
+ assert_eq ! ( addr, Ipv4Addr :: new( 1 , 2 , 3 , 4 ) ) ;
419
+ } else {
420
+ panic ! ( "Expected Ip4 protocol" ) ;
421
+ }
422
+
423
+ let ipv6_host = Host :: Ipv6 ( Ipv6Addr :: LOCALHOST ) ;
424
+ let protocol = Protocol :: from ( & ipv6_host) ;
425
+ if let Protocol :: Ip6 ( addr) = protocol {
426
+ assert_eq ! ( addr, Ipv6Addr :: LOCALHOST ) ;
427
+ } else {
428
+ panic ! ( "Expected Ip6 protocol" ) ;
429
+ }
430
+ }
431
+
432
+ #[ test]
433
+ fn test_serde_serialization ( ) {
434
+ let host = Host :: Domain ( "serialize-test.example.com" . to_string ( ) ) ;
435
+ let serialized = serde_json:: to_string ( & host) . unwrap ( ) ;
436
+ let deserialized: Host = serde_json:: from_str ( & serialized) . unwrap ( ) ;
437
+ assert_eq ! ( host, deserialized) ;
438
+ }
439
+
440
+ #[ test]
441
+ fn test_special_domains ( ) {
442
+ // Test some special/edge case domains
443
+ let cases = vec ! [
444
+ ( "localhost" , true ) , // Should resolve
445
+ ( "127.0.0.1" , true ) , // Already an IP, but valid as domain too
446
+ ( "0.0.0.0" , true ) , // Valid IP
447
+ ( "255.255.255.255" , true ) , // Valid IP
448
+ ] ;
449
+
450
+ for ( domain_str, should_parse) in cases {
451
+ let result: Result < Host , _ > = domain_str. parse ( ) ;
452
+ assert_eq ! (
453
+ result. is_ok( ) ,
454
+ should_parse,
455
+ "Failed for domain: {}" ,
456
+ domain_str
457
+ ) ;
458
+ }
459
+ }
460
+ }
0 commit comments