Mirror: Best-effort discovery of the machine's local network using just Node.js dgram sockets
at v0.1.7 4.1 kB view raw
1import os from 'node:os'; 2import { vi, describe, it, expect } from 'vitest'; 3import { 4 parseMacStr, 5 parseIpStr, 6 toIpStr, 7 interfaceAssignments, 8 matchAssignment, 9 isSameSubnet, 10} from '../network'; 11 12describe(parseMacStr, () => { 13 it('parses valid MAC addresses', () => { 14 expect(parseMacStr('11:22:33:44:55:66')).toEqual([17, 34, 51, 68, 85, 102]); 15 }); 16}); 17 18describe(parseIpStr, () => { 19 it('parses valid IP addresses', () => { 20 expect(parseIpStr('0.0.0.0').toString(16)).toBe('0'); 21 expect(parseIpStr('1.1.1.1').toString(16)).toBe('1010101'); 22 expect(parseIpStr('255.255.255.255').toString(16)).toBe('-1'); 23 expect(parseIpStr('100.1.2.3').toString(16)).toBe('64010203'); 24 }); 25}); 26 27describe(toIpStr, () => { 28 it.each([['0.0.0.0'], ['1.1.1.1'], ['255.255.255.255'], ['100.1.2.3']])( 29 'stringifies parsed IP (%s)', 30 addr => { 31 expect(toIpStr(parseIpStr(addr))).toBe(addr); 32 } 33 ); 34}); 35 36describe(isSameSubnet, () => { 37 it('returns true for same subnet', () => { 38 expect(isSameSubnet('192.168.1.1', '192.168.1.2', '255.255.255.0')).toBe( 39 true 40 ); 41 }); 42 it('returns false for different subnet', () => { 43 expect(isSameSubnet('192.168.1.1', '192.168.2.1', '255.255.255.0')).toBe( 44 false 45 ); 46 }); 47}); 48 49describe(interfaceAssignments, () => { 50 const networkInterfaces = vi 51 .spyOn(os, 'networkInterfaces') 52 .mockReturnValue([] as any); 53 54 it('returns sorted list of assignments', () => { 55 networkInterfaces.mockReturnValueOnce({ 56 lo0: [ 57 { 58 address: '127.0.0.1', 59 netmask: '255.0.0.0', 60 family: 'IPv4', 61 mac: '00:00:00:00:00:00', 62 internal: true, 63 cidr: '', 64 }, 65 ], 66 en1: [ 67 { 68 address: '10.0.0.10', 69 netmask: '255.255.255.0', 70 family: 'IPv4', 71 mac: '00:00:00:00:00:00', 72 internal: false, 73 cidr: '', 74 }, 75 ], 76 tun2: [ 77 { 78 address: '100.0.0.11', 79 netmask: '255.255.255.0', 80 family: 'IPv4', 81 mac: '00:00:00:00:00:00', 82 internal: true, 83 cidr: '', 84 }, 85 ], 86 }); 87 expect(interfaceAssignments()).toMatchInlineSnapshot(` 88 [ 89 { 90 "address": "10.0.0.10", 91 "cidr": "", 92 "family": "IPv4", 93 "iname": "en1", 94 "internal": false, 95 "mac": "00:00:00:00:00:00", 96 "netmask": "255.255.255.0", 97 }, 98 { 99 "address": "100.0.0.11", 100 "cidr": "", 101 "family": "IPv4", 102 "iname": "tun2", 103 "internal": true, 104 "mac": "00:00:00:00:00:00", 105 "netmask": "255.255.255.0", 106 }, 107 { 108 "address": "127.0.0.1", 109 "cidr": "", 110 "family": "IPv4", 111 "iname": "lo0", 112 "internal": true, 113 "mac": "00:00:00:00:00:00", 114 "netmask": "255.0.0.0", 115 }, 116 ] 117 `); 118 }); 119}); 120 121describe(matchAssignment, () => { 122 it('returns matching assignment by address', () => { 123 const assignment = { 124 iname: 'en0', 125 address: '100.0.0.11', 126 netmask: '255.255.255.0', 127 family: 'IPv4', 128 mac: '00:00:00:00:00:00', 129 internal: true, 130 cidr: '', 131 } as const; 132 expect(matchAssignment([assignment], '100.0.0.11')).toEqual({ 133 ...assignment, 134 gateway: null, 135 }); 136 }); 137 138 it('returns matching assignment by gateway', () => { 139 const assignment = { 140 iname: 'en0', 141 address: '100.0.0.11', 142 netmask: '255.255.255.0', 143 family: 'IPv4', 144 mac: '00:00:00:00:00:00', 145 internal: true, 146 cidr: '', 147 } as const; 148 expect(matchAssignment([assignment], '100.0.0.1')).toEqual({ 149 ...assignment, 150 gateway: '100.0.0.1', 151 }); 152 }); 153 154 it('returns null otherwise', () => { 155 const assignment = { 156 iname: 'en0', 157 address: '10.0.0.1', 158 netmask: '255.255.255.0', 159 family: 'IPv4', 160 mac: '00:00:00:00:00:00', 161 internal: true, 162 cidr: '', 163 } as const; 164 expect(matchAssignment([assignment], '100.0.0.1')).toBe(null); 165 }); 166});