@@ -261,4 +261,83 @@ public function testBogonLocal6()
261261 $ this ->assertEquals ($ res ->ip , '2002:7f00:: ' );
262262 $ this ->assertTrue ($ res ->bogon );
263263 }
264+
265+ public function testIpv6Details ()
266+ {
267+ $ tok = getenv ('IPINFO_TOKEN ' );
268+ if (!$ tok ) {
269+ $ this ->markTestSkipped ('IPINFO_TOKEN env var required ' );
270+ }
271+
272+ $ h = new IPinfo ($ tok );
273+ $ ip = "2607:f8b0:4005:805::200e " ;
274+
275+ // test multiple times for cache hits
276+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
277+ $ res = $ h ->getDetails ($ ip );
278+ $ this ->assertEquals ($ res ->ip , '2607:f8b0:4005:805::200e ' );
279+ $ this ->assertEquals ($ res ->city , 'San Jose ' );
280+ $ this ->assertEquals ($ res ->region , 'California ' );
281+ $ this ->assertEquals ($ res ->country , 'US ' );
282+ $ this ->assertEquals ($ res ->loc , '37.3394,-121.8950 ' );
283+ $ this ->assertEquals ($ res ->postal , '95025 ' );
284+ $ this ->assertEquals ($ res ->timezone , 'America/Los_Angeles ' );
285+ }
286+ }
287+
288+ public function testIPv6DifferentNotations ()
289+ {
290+ $ tok = getenv ('IPINFO_TOKEN ' );
291+ if (!$ tok ) {
292+ $ this ->markTestSkipped ('IPINFO_TOKEN env var required ' );
293+ }
294+
295+ $ h = new IPinfo ($ tok );
296+
297+ // Base IPv6 address with leading zeros in the second group
298+ $ standard_ip = "2607:00:4005:805::200e " ;
299+ $ standard_result = $ h ->getDetails ($ standard_ip );
300+ $ this ->assertEquals ($ standard_result ->ip , '2607:00:4005:805::200e ' );
301+ $ this ->assertEquals ($ standard_result ->city , 'Killarney ' );
302+ $ this ->assertEquals ($ standard_result ->region , 'Manitoba ' );
303+ $ this ->assertEquals ($ standard_result ->country , 'CA ' );
304+ $ this ->assertEquals ($ standard_result ->loc , '49.1833,-99.6636 ' );
305+ $ this ->assertEquals ($ standard_result ->timezone , 'America/Winnipeg ' );
306+
307+ // Various notations of the same IPv6 address
308+ $ variations = [
309+ "2607:0:4005:805::200e " , // Removed leading zeros in second group
310+ "2607:0000:4005:805::200e " , // Full form with all zeros in second group
311+ "2607:0:4005:805:0:0:0:200e " , // Expanded form without compressed zeros
312+ "2607:0:4005:805:0000:0000:0000:200e " , // Full expanded form
313+ "2607:00:4005:805:0::200e " , // Partially expanded
314+ "2607:00:4005:805::200E " , // Uppercase hex digits
315+ "2607:00:4005:0805::200e " // Leading zero in fourth group
316+ ];
317+
318+ foreach ($ variations as $ ip ) {
319+ // Test each variation
320+ try {
321+ $ result = $ h ->getDetails ($ ip );
322+ }
323+ catch (\Exception $ e ) {
324+ $ this ->fail ("Failed to get details for IP: $ ip. Exception: " . $ e ->getMessage ());
325+ }
326+
327+ $ this ->assertEquals ($ ip , $ result ->ip );
328+ // Location data should be identical
329+ $ this ->assertEquals ($ standard_result ->city , $ result ->city , "City should match for IP: $ ip " );
330+ $ this ->assertEquals ($ standard_result ->region , $ result ->region , "Region should match for IP: $ ip " );
331+ $ this ->assertEquals ($ standard_result ->country , $ result ->country , "Country should match for IP: $ ip " );
332+ $ this ->assertEquals ($ standard_result ->loc , $ result ->loc , "Location should match for IP: $ ip " );
333+ $ this ->assertEquals ($ standard_result ->timezone , $ result ->timezone , "Timezone should match for IP: $ ip " );
334+
335+ // Binary comparison ensures the IP addresses are functionally identical
336+ $ this ->assertEquals (
337+ inet_ntop (inet_pton ($ standard_ip )),
338+ inet_ntop (inet_pton ($ result ->ip )),
339+ "Normalized binary representation should match for IP: $ ip "
340+ );
341+ }
342+ }
264343}
0 commit comments