1
+ 'use strict' ;
2
+
3
+ const test = require ( 'tap' ) . test ;
4
+ const os = require ( 'os' ) ;
5
+
6
+ test ( 'network interface display handles both string and numeric family values' , ( t ) => {
7
+ t . plan ( 4 ) ;
8
+
9
+ // Store original function to restore later
10
+ const originalNetworkInterfaces = os . networkInterfaces ;
11
+
12
+ // Mock data with string family values (Node < 18)
13
+ const mockInterfacesString = {
14
+ 'eth0' : [
15
+ { family : 'IPv4' , address : '192.168.1.100' , internal : false } ,
16
+ { family : 'IPv6' , address : '::1' , internal : false }
17
+ ] ,
18
+ 'lo' : [
19
+ { family : 'IPv4' , address : '127.0.0.1' , internal : true }
20
+ ]
21
+ } ;
22
+
23
+ // Mock data with numeric family values (Node >= 18)
24
+ const mockInterfacesNumeric = {
25
+ 'eth0' : [
26
+ { family : 4 , address : '192.168.1.100' , internal : false } ,
27
+ { family : 6 , address : '::1' , internal : false }
28
+ ] ,
29
+ 'lo' : [
30
+ { family : 4 , address : '127.0.0.1' , internal : true }
31
+ ]
32
+ } ;
33
+
34
+ // Test the logic that filters IPv4 interfaces (extracted from bin/http-server)
35
+ function getIPv4Addresses ( interfaces ) {
36
+ const addresses = [ ] ;
37
+ Object . keys ( interfaces ) . forEach ( function ( dev ) {
38
+ interfaces [ dev ] . forEach ( function ( details ) {
39
+ // This is the fix: handle both string and numeric family values
40
+ if ( details . family === 'IPv4' || details . family === 4 ) {
41
+ addresses . push ( details . address ) ;
42
+ }
43
+ } ) ;
44
+ } ) ;
45
+ return addresses ;
46
+ }
47
+
48
+ // Test with string family values
49
+ let addresses = getIPv4Addresses ( mockInterfacesString ) ;
50
+ t . equal ( addresses . length , 2 , 'Should find 2 IPv4 addresses with string family' ) ;
51
+ t . ok ( addresses . includes ( '192.168.1.100' ) , 'Should include external IPv4 address' ) ;
52
+
53
+ // Test with numeric family values
54
+ addresses = getIPv4Addresses ( mockInterfacesNumeric ) ;
55
+ t . equal ( addresses . length , 2 , 'Should find 2 IPv4 addresses with numeric family' ) ;
56
+ t . ok ( addresses . includes ( '192.168.1.100' ) , 'Should include external IPv4 address' ) ;
57
+
58
+ // Restore original function
59
+ os . networkInterfaces = originalNetworkInterfaces ;
60
+ } ) ;
61
+
62
+ test ( 'network interface filtering excludes IPv6 link-local addresses' , ( t ) => {
63
+ t . plan ( 2 ) ;
64
+
65
+ const mockInterfaces = {
66
+ 'eth0' : [
67
+ { family : 4 , address : '192.168.1.100' , internal : false } ,
68
+ { family : 6 , address : '2001:db8::1' , internal : false } ,
69
+ { family : 6 , address : 'fe80::1' , internal : false } // link-local, should be excluded
70
+ ]
71
+ } ;
72
+
73
+ // Extract the IPv6 filtering logic from bin/http-server
74
+ const ipv6Addresses = [ ] ;
75
+ const ipv4Addresses = [ ] ;
76
+
77
+ Object . keys ( mockInterfaces ) . forEach ( function ( dev ) {
78
+ mockInterfaces [ dev ] . forEach ( function ( details ) {
79
+ if ( details . family === 'IPv4' || details . family === 4 ) {
80
+ ipv4Addresses . push ( details . address ) ;
81
+ }
82
+ if ( ( details . family === 'IPv6' || details . family === 6 ) &&
83
+ ! details . address . startsWith ( "fe80" ) ) {
84
+ ipv6Addresses . push ( details . address ) ;
85
+ }
86
+ } ) ;
87
+ } ) ;
88
+
89
+ t . equal ( ipv4Addresses . length , 1 , 'Should find 1 IPv4 address' ) ;
90
+ t . equal ( ipv6Addresses . length , 1 , 'Should find 1 non-link-local IPv6 address' ) ;
91
+ } ) ;
0 commit comments