Passed
Pull Request — master (#72)
by Wilmer
11:03
created

IpTest::testValidateIPvBoth()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 42
nc 1
nop 0
dl 0
loc 50
rs 9.248
c 1
b 0
f 0
1
<?php
2
3
namespace Yiisoft\Validator\Tests\Rule;
4
5
use PHPUnit\Framework\TestCase;
6
use Yiisoft\Validator\Rule\Ip;
7
8
/**
9
 * @group validators
10
 */
11
class IpTest extends TestCase
12
{
13
    public function testInitException(): void
14
    {
15
        $this->expectException(\RuntimeException::class);
16
        $this->expectExceptionMessage('Both IPv4 and IPv6 checks can not be disabled at the same time');
17
        (new Ip())->disallowIpv4()->disallowIpv6()->validate('');
18
    }
19
20
    public function provideRangesForSubstitution(): array
21
    {
22
        return [
23
            'ipv4' => [['10.0.0.1'], ['10.0.0.1']],
24
            'any' => [['192.168.0.32', 'fa::/32', 'any'], ['192.168.0.32', 'fa::/32', '0.0.0.0/0', '::/0']],
25
            'ipv4+!private' => [
26
                ['10.0.0.1', '!private'],
27
                ['10.0.0.1', '!10.0.0.0/8', '!172.16.0.0/12', '!192.168.0.0/16', '!fd00::/8']
28
            ],
29
            'private+!system' => [
30
                ['private', '!system'],
31
                [
32
                    '10.0.0.0/8',
33
                    '172.16.0.0/12',
34
                    '192.168.0.0/16',
35
                    'fd00::/8',
36
                    '!224.0.0.0/4',
37
                    '!ff00::/8',
38
                    '!169.254.0.0/16',
39
                    '!fe80::/10',
40
                    '!127.0.0.0/8',
41
                    '!::1',
42
                    '!192.0.2.0/24',
43
                    '!198.51.100.0/24',
44
                    '!203.0.113.0/24',
45
                    '!2001:db8::/32'
46
                ]
47
            ],
48
        ];
49
    }
50
51
    /**
52
     * @dataProvider provideRangesForSubstitution
53
     */
54
    public function testRangesSubstitution(array $range, array $expectedRange): void
55
    {
56
        $validator = (new Ip())->ranges($range);
57
        $this->assertEquals($expectedRange, $validator->getRanges());
58
    }
59
60
61
    public function testValidateOrder(): void
62
    {
63
        $validator = (new Ip())->ranges(['10.0.0.1', '!10.0.0.0/8', '!babe::/8', 'any']);
64
65
        $this->assertTrue($validator->validate('10.0.0.1')->isValid());
66
        $this->assertFalse($validator->validate('10.0.0.2')->isValid());
67
        $this->assertTrue($validator->validate('192.168.5.101')->isValid());
68
        $this->assertTrue($validator->validate('cafe::babe')->isValid());
69
        $this->assertFalse($validator->validate('babe::cafe')->isValid());
70
    }
71
72
    public function provideBadIps(): array
73
    {
74
        return [
75
            'notIpString' => ['not.an.ip'],
76
            'notIpString2' => ['bad:forSure'],
77
            'array' => [['what an array', '??']],
78
            'int' => [123456],
79
            'boolTrue' => [true],
80
            'boolFalse' => [false],
81
        ];
82
    }
83
84
    /**
85
     * @dataProvider provideBadIps
86
     */
87
    public function testValidateNotAnIP($badIp): void
88
    {
89
        $validator = new Ip();
90
        $this->assertFalse($validator->validate($badIp)->isValid());
91
    }
92
93
    public function testValidateIPv4(): void
94
    {
95
        $validator = new Ip();
96
97
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
98
        $this->assertFalse($validator->validate('192.168.005.001')->isValid()); // leading zero not supported
99
        $this->assertFalse($validator->validate('192.168.5.321')->isValid());
100
        $this->assertFalse($validator->validate('!192.168.5.32')->isValid());
101
        $this->assertFalse($validator->validate('192.168.5.32/11')->isValid());
102
103
        $validator = $validator->disallowIpv4();
104
        $this->assertFalse($validator->validate('192.168.10.11')->isValid());
105
106
        $validator = $validator->allowIpv4()->allowSubnet();
107
        $this->assertTrue($validator->validate('192.168.5.32/11')->isValid());
108
        $this->assertTrue($validator->validate('192.168.5.32/32')->isValid());
109
        $this->assertTrue($validator->validate('0.0.0.0/0')->isValid());
110
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
111
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
112
        $this->assertFalse($validator->validate('192.168.5.32/af')->isValid());
113
        $this->assertFalse($validator->validate('192.168.5.32/11/12')->isValid());
114
115
        $validator = $validator->requireSubnet();
116
        $this->assertTrue($validator->validate('10.0.0.1/24')->isValid());
117
        $this->assertTrue($validator->validate('10.0.0.1/0')->isValid());
118
        $this->assertFalse($validator->validate('10.0.0.1')->isValid());
119
120
        $validator = $validator->allowNegation();
121
        $this->assertTrue($validator->validate('!192.168.5.32/32')->isValid());
122
        $this->assertFalse($validator->validate('!!192.168.5.32/32')->isValid());
123
    }
124
125
126
    public function testValidateIPv6(): void
127
    {
128
        $validator = new Ip();
129
130
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
131
        $this->assertTrue($validator->validate('2008:00fa::0001')->isValid());
132
        $this->assertFalse($validator->validate('2008:fz::0')->isValid());
133
        $this->assertFalse($validator->validate('2008:fa::0::1')->isValid());
134
        $this->assertFalse($validator->validate('!2008:fa::0::1')->isValid());
135
        $this->assertFalse($validator->validate('2008:fa::0:1/64')->isValid());
136
137
        $validator = $validator->disallowIpv4();
138
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
139
140
        $validator = $validator->allowIpv6()->allowSubnet();
141
        $this->assertTrue($validator->validate('2008:fa::0:1/64')->isValid());
142
        $this->assertTrue($validator->validate('2008:fa::0:1/128')->isValid());
143
        $this->assertTrue($validator->validate('2008:fa::0:1/0')->isValid());
144
        $this->assertFalse($validator->validate('!2008:fa::0:1/0')->isValid());
145
        $this->assertFalse($validator->validate('2008:fz::0/129')->isValid());
146
147
        $validator = $validator->requireSubnet();
148
        $this->assertTrue($validator->validate('2008:db0::1/64')->isValid());
149
        $this->assertFalse($validator->validate('2008:db0::1')->isValid());
150
151
        $validator = $validator->allowNegation();
152
        $this->assertTrue($validator->validate('!2008:fa::0:1/64')->isValid());
153
        $this->assertFalse($validator->validate('!!2008:fa::0:1/64')->isValid());
154
    }
155
156
    public function testValidateIPvBoth(): void
157
    {
158
        $validator = new Ip();
159
160
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
161
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
162
        $this->assertTrue($validator->validate('2008:00fa::0001')->isValid());
163
        $this->assertFalse($validator->validate('192.168.005.001')->isValid()); // leading zero not allowed
164
        $this->assertFalse($validator->validate('192.168.5.321')->isValid());
165
        $this->assertFalse($validator->validate('!192.168.5.32')->isValid());
166
        $this->assertFalse($validator->validate('192.168.5.32/11')->isValid());
167
        $this->assertFalse($validator->validate('2008:fz::0')->isValid());
168
        $this->assertFalse($validator->validate('2008:fa::0::1')->isValid());
169
        $this->assertFalse($validator->validate('!2008:fa::0::1')->isValid());
170
        $this->assertFalse($validator->validate('2008:fa::0:1/64')->isValid());
171
172
        $validator = $validator->disallowIpv4();
173
        $this->assertFalse($validator->validate('192.168.10.11')->isValid());
174
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
175
176
        $validator = $validator->disallowIpv6()->allowIpv4();
177
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
178
        $this->assertFalse($validator->validate('2008:fa::1')->isValid());
179
180
        $validator = $validator->allowIpv6()->requireSubnet();
181
        $this->assertTrue($validator->validate('192.168.5.32/11')->isValid());
182
        $this->assertTrue($validator->validate('192.168.5.32/32')->isValid());
183
        $this->assertTrue($validator->validate('0.0.0.0/0')->isValid());
184
        $this->assertTrue($validator->validate('2008:fa::0:1/64')->isValid());
185
        $this->assertTrue($validator->validate('2008:fa::0:1/128')->isValid());
186
        $this->assertTrue($validator->validate('2008:fa::0:1/0')->isValid());
187
        $this->assertFalse($validator->validate('!2008:fa::0:1/0')->isValid());
188
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
189
        $this->assertFalse($validator->validate('2008:fz::0/129')->isValid());
190
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
191
        $this->assertFalse($validator->validate('192.168.5.32/af')->isValid());
192
        $this->assertFalse($validator->validate('192.168.5.32/11/12')->isValid());
193
194
        $validator = $validator->requireSubnet();
195
        $this->assertTrue($validator->validate('10.0.0.1/24')->isValid());
196
        $this->assertTrue($validator->validate('10.0.0.1/0')->isValid());
197
        $this->assertTrue($validator->validate('2008:db0::1/64')->isValid());
198
        $this->assertFalse($validator->validate('2008:db0::1')->isValid());
199
        $this->assertFalse($validator->validate('10.0.0.1')->isValid());
200
201
        $validator = $validator->allowNegation();
202
        $this->assertTrue($validator->validate('!192.168.5.32/32')->isValid());
203
        $this->assertTrue($validator->validate('!2008:fa::0:1/64')->isValid());
204
        $this->assertFalse($validator->validate('!!192.168.5.32/32')->isValid());
205
        $this->assertFalse($validator->validate('!!2008:fa::0:1/64')->isValid());
206
    }
207
208
    public function testValidateRangeIPv4(): void
209
    {
210
        $validator = (new Ip())->ranges(['10.0.1.0/24']);
211
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
212
        $this->assertFalse($validator->validate('192.5.1.1')->isValid());
213
214
        $validator = $validator->ranges(['10.0.1.0/24']);
215
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
216
        $this->assertFalse($validator->validate('10.0.3.2')->isValid());
217
218
        $validator = $validator->ranges(['!10.0.1.0/24', '10.0.0.0/8', 'localhost']);
219
        $this->assertFalse($validator->validate('10.0.1.2')->isValid());
220
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
221
222
        $validator = $validator->allowSubnet()->ranges(['10.0.1.0/24', '!10.0.0.0/8', 'localhost']);
223
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
224
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
225
        $this->assertTrue($validator->validate('10.0.1.28/28')->isValid());
226
        $this->assertFalse($validator->validate('10.2.2.2')->isValid());
227
        $this->assertFalse($validator->validate('10.0.1.1/22')->isValid());
228
    }
229
230
    public function testValidateRangeIPv6(): void
231
    {
232
        $validator = (new Ip())->ranges(['2001:db0:1:1::/64']);
233
        $this->assertTrue($validator->validate('2001:db0:1:1::6')->isValid());
234
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
235
236
        $validator = $validator->ranges(['2001:db0:1:2::/64']);
237
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
238
239
        $validator = $validator->ranges(['!2001:db0::/32', '2001:db0:1:2::/64']);
240
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
241
242
        $validator = $validator->allowSubnet()->ranges(array_reverse($validator->getRanges()));
243
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
244
    }
245
246
    public function testValidateRangeIPvBoth(): void
247
    {
248
        $validator = (new Ip())->ranges(['10.0.1.0/24']);
249
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
250
        $this->assertFalse($validator->validate('192.5.1.1')->isValid());
251
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
252
253
        $validator = $validator->ranges(['10.0.1.0/24', '2001:db0:1:2::/64', '127.0.0.1']);
254
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
255
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
256
        $this->assertFalse($validator->validate('10.0.3.2')->isValid());
257
258
        $validator = $validator->ranges(['!system', 'any']);
259
        $this->assertFalse($validator->validate('127.0.0.1')->isValid());
260
        $this->assertFalse($validator->validate('fe80::face')->isValid());
261
        $this->assertTrue($validator->validate('8.8.8.8')->isValid());
262
263
        $validator = $validator->allowSubnet()->ranges(['10.0.1.0/24', '2001:db0:1:2::/64', 'localhost', '!any']);
264
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
265
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
266
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
267
        $this->assertTrue($validator->validate('10.0.1.28/28')->isValid());
268
        $this->assertFalse($validator->validate('10.2.2.2')->isValid());
269
        $this->assertFalse($validator->validate('10.0.1.1/22')->isValid());
270
    }
271
272
    public function testIpv4LeadingZero(): void
273
    {
274
        $this->assertFalse((new Ip())->validate('01.01.01.01')->isValid());
275
        $this->assertFalse((new Ip())->validate('010.010.010.010')->isValid());
276
        $this->assertFalse((new Ip())->validate('001.001.001.001')->isValid());
277
    }
278
279
    public function testNetworkAlias(): void
280
    {
281
        $validator = (new Ip())->network('myNetworkEu', ['1.2.3.4/10', '5.6.7.8'])
282
            ->ranges(['myNetworkEu']);
283
        $this->assertTrue($validator->validate('1.2.3.4')->isValid());
284
        $this->assertTrue($validator->validate('5.6.7.8')->isValid());
285
    }
286
287
    public function testNetworkAliasException(): void
288
    {
289
        $validator = (new Ip())->network('myNetworkEu', ['1.2.3.4/10', '5.6.7.8'])
290
            ->ranges(['myNetworkEu']);
291
292
        $this->expectException(\RuntimeException::class);
293
        $this->expectExceptionMessage('Network alias "myNetworkEu" already set');
294
        $validator->network('myNetworkEu', ['!1.2.3.4/10', '!5.6.7.8']);
295
    }
296
}
297