1+ <?php
2+
3+ namespace Tests \Unit ;
4+
5+ use Neuron \Routing \DefaultIpResolver ;
6+ use PHPUnit \Framework \TestCase ;
7+
8+ class DefaultIpResolverTest extends TestCase
9+ {
10+ private DefaultIpResolver $ resolver ;
11+
12+ protected function setUp (): void
13+ {
14+ parent ::setUp ();
15+ $ this ->resolver = new DefaultIpResolver ();
16+ }
17+
18+ public function testResolveDirectConnection (): void
19+ {
20+ $ server = [
21+ 'REMOTE_ADDR ' => '192.168.1.100 '
22+ ];
23+
24+ $ ip = $ this ->resolver ->resolve ( $ server );
25+
26+ $ this ->assertEquals ( '192.168.1.100 ' , $ ip );
27+ }
28+
29+ public function testResolveCloudflareHeader (): void
30+ {
31+ $ server = [
32+ 'HTTP_CF_CONNECTING_IP ' => '203.0.113.42 ' ,
33+ 'HTTP_X_FORWARDED_FOR ' => '10.0.0.1 ' ,
34+ 'REMOTE_ADDR ' => '172.71.255.1 ' // Cloudflare IP
35+ ];
36+
37+ $ ip = $ this ->resolver ->resolve ( $ server );
38+
39+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
40+ }
41+
42+ public function testResolveXForwardedFor (): void
43+ {
44+ $ server = [
45+ 'HTTP_X_FORWARDED_FOR ' => '203.0.113.42 ' ,
46+ 'REMOTE_ADDR ' => '10.0.0.1 '
47+ ];
48+
49+ $ ip = $ this ->resolver ->resolve ( $ server );
50+
51+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
52+ }
53+
54+ public function testResolveXForwardedForWithProxyChain (): void
55+ {
56+ $ server = [
57+ 'HTTP_X_FORWARDED_FOR ' => '203.0.113.42, 10.0.0.1, 172.16.0.1 ' ,
58+ 'REMOTE_ADDR ' => '192.168.1.1 '
59+ ];
60+
61+ $ ip = $ this ->resolver ->resolve ( $ server );
62+
63+ // Should return the first IP (original client)
64+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
65+ }
66+
67+ public function testResolveXRealIp (): void
68+ {
69+ $ server = [
70+ 'HTTP_X_REAL_IP ' => '203.0.113.42 ' ,
71+ 'REMOTE_ADDR ' => '10.0.0.1 '
72+ ];
73+
74+ $ ip = $ this ->resolver ->resolve ( $ server );
75+
76+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
77+ }
78+
79+ public function testResolveClientIp (): void
80+ {
81+ $ server = [
82+ 'HTTP_CLIENT_IP ' => '203.0.113.42 ' ,
83+ 'REMOTE_ADDR ' => '10.0.0.1 '
84+ ];
85+
86+ $ ip = $ this ->resolver ->resolve ( $ server );
87+
88+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
89+ }
90+
91+ public function testResolveInvalidIpFallsBackToRemoteAddr (): void
92+ {
93+ $ server = [
94+ 'HTTP_X_FORWARDED_FOR ' => 'not-an-ip ' ,
95+ 'HTTP_X_REAL_IP ' => 'invalid ' ,
96+ 'REMOTE_ADDR ' => '192.168.1.100 '
97+ ];
98+
99+ $ ip = $ this ->resolver ->resolve ( $ server );
100+
101+ $ this ->assertEquals ( '192.168.1.100 ' , $ ip );
102+ }
103+
104+ public function testResolveMissingRemoteAddr (): void
105+ {
106+ $ server = [
107+ 'HTTP_X_FORWARDED_FOR ' => 'invalid '
108+ ];
109+
110+ $ ip = $ this ->resolver ->resolve ( $ server );
111+
112+ $ this ->assertEquals ( '0.0.0.0 ' , $ ip );
113+ }
114+
115+ public function testResolveEmptyServer (): void
116+ {
117+ $ server = [];
118+
119+ $ ip = $ this ->resolver ->resolve ( $ server );
120+
121+ $ this ->assertEquals ( '0.0.0.0 ' , $ ip );
122+ }
123+
124+ public function testResolveHeaderPriority (): void
125+ {
126+ // All headers present - should use CF-Connecting-IP first
127+ $ server = [
128+ 'HTTP_CF_CONNECTING_IP ' => '1.1.1.1 ' ,
129+ 'HTTP_X_FORWARDED_FOR ' => '2.2.2.2 ' ,
130+ 'HTTP_X_REAL_IP ' => '3.3.3.3 ' ,
131+ 'HTTP_CLIENT_IP ' => '4.4.4.4 ' ,
132+ 'REMOTE_ADDR ' => '5.5.5.5 '
133+ ];
134+
135+ $ ip = $ this ->resolver ->resolve ( $ server );
136+
137+ $ this ->assertEquals ( '1.1.1.1 ' , $ ip );
138+ }
139+
140+ public function testResolveIpv6 (): void
141+ {
142+ $ server = [
143+ 'HTTP_X_FORWARDED_FOR ' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334 ' ,
144+ 'REMOTE_ADDR ' => '192.168.1.1 '
145+ ];
146+
147+ $ ip = $ this ->resolver ->resolve ( $ server );
148+
149+ $ this ->assertEquals ( '2001:0db8:85a3:0000:0000:8a2e:0370:7334 ' , $ ip );
150+ }
151+
152+ public function testResolveIpv6Compressed (): void
153+ {
154+ $ server = [
155+ 'HTTP_X_FORWARDED_FOR ' => '2001:db8::8a2e:370:7334 ' ,
156+ 'REMOTE_ADDR ' => '192.168.1.1 '
157+ ];
158+
159+ $ ip = $ this ->resolver ->resolve ( $ server );
160+
161+ $ this ->assertEquals ( '2001:db8::8a2e:370:7334 ' , $ ip );
162+ }
163+
164+ public function testResolveTrimmedIp (): void
165+ {
166+ $ server = [
167+ 'HTTP_X_FORWARDED_FOR ' => ' 203.0.113.42 ' ,
168+ 'REMOTE_ADDR ' => '192.168.1.1 '
169+ ];
170+
171+ $ ip = $ this ->resolver ->resolve ( $ server );
172+
173+ $ this ->assertEquals ( '203.0.113.42 ' , $ ip );
174+ }
175+ }
0 commit comments