ValidatorTest::testResourceRecordName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS\Tests;
15
16
use Badcow\DNS\Classes;
17
use Badcow\DNS\Rdata\Factory;
18
use Badcow\DNS\Rdata\NS;
19
use Badcow\DNS\ResourceRecord;
20
use Badcow\DNS\Validator;
21
use PHPUnit\Framework\TestCase;
22
use RuntimeException;
23
24
class ValidatorTest extends TestCase
25
{
26
    public function dp_testValidateResourceRecordName(): array
27
    {
28
        return [
29
            [true, 'example.com.'],
30
            [true, 'www.example.com.'],
31
            [true, 'ex-ample.com.'],
32
            [true, 'ex-ampl3.com.au.'],
33
            [true, '@'],
34
            [true, 'alt2.aspmx.l.google.com.'],
35
            [true, 'www.eXAMple.cOm.'],
36
            [true, '3xample.com.'],
37
            [true, '_example.com.'],
38
            [true, 'example.com'],
39
            [true, 'www.example.com'],
40
            [true, 'example'],
41
            [true, '@'],
42
            [true, 'wWw.EXample.com'],
43
            [true, '_sip._udp.test.sx.'],
44
            [false, '-example.com.'],
45
            [false, 'exam*ple.com'],
46
            [false, 'wheres-wally?.com'],
47
        ];
48
    }
49
50
    /**
51
     * @dataProvider dp_testValidateResourceRecordName
52
     */
53
    public function testValidateResourceRecordName(bool $isValid, string $resourceName): void
54
    {
55
        $this->assertEquals($isValid, Validator::resourceRecordName($resourceName));
56
    }
57
58
    public function getIPv4TestDataSet(): array
59
    {
60
        return [
61
            ['119.15.101.102', true],
62
            ['255.0.0.255', true],
63
            ['192.168.0.0', true],
64
            ['0.0.0.0', true],
65
66
            ['192.168.1.', false],
67
            ['172.10.256.1', false],
68
            ['255.244', false],
69
            ['::1', false],
70
            ['2001:db8::ff00:42:8329', false],
71
        ];
72
    }
73
74
    /**
75
     * @dataProvider getIPv4TestDataSet
76
     */
77
    public function testValidateIpv4Address(string $address, bool $isValid): void
78
    {
79
        $this->assertEquals($isValid, Validator::ipv4($address));
80
    }
81
82
    public function getIPv6TestDataSet(): array
83
    {
84
        return [
85
            ['2001:0db8:0000:0000:0000:ff00:0042:8329', true],
86
            ['2001:db8:0:0:0:ff00:42:8329', true],
87
            ['2001:db8::ff00:42:8329', true],
88
            ['::1', true],
89
90
            ['fffff:0db8:0000:0000:0000:ff00:0042:8329', false],
91
            ['172.10.255.1', false],
92
            ['192.168.0.0', false],
93
        ];
94
    }
95
96
    /**
97
     * @dataProvider getIPv6TestDataSet
98
     */
99
    public function testValidateIpv6Address(string $address, bool $isValid): void
100
    {
101
        $this->assertEquals($isValid, Validator::ipv6($address));
102
    }
103
104
    public function getIPvTestDataSet(): array
105
    {
106
        return [
107
            ['2001:0db8:0000:0000:0000:ff00:0042:8329', true],
108
            ['2001:db8:0:0:0:ff00:42:8329', true],
109
            ['2001:db8::ff00:42:8329', true],
110
            ['::1', true],
111
            ['119.15.101.102', true],
112
            ['255.0.0.255', true],
113
            ['192.168.0.0', true],
114
            ['0.0.0.0', true],
115
116
            ['192.168.1.', false],
117
            ['172.10.256.1', false],
118
            ['255.244', false],
119
            ['fffff:0db8:0000:0000:0000:ff00:0042:8329', false],
120
        ];
121
    }
122
123
    /**
124
     * @dataProvider getIPvTestDataSet
125
     */
126
    public function testValidateIpAddress(string $address, bool $isValid): void
127
    {
128
        $this->assertEquals($isValid, Validator::ipAddress($address));
129
    }
130
131
    public function testValidateNumberOfSoa(): void
132
    {
133
        $zone = TestZone::buildTestZone();
134
        $soa = new ResourceRecord();
135
        $soa->setClass(Classes::INTERNET);
136
        $soa->setName('@');
137
        $soa->setRdata(Factory::SOA(
138
            'example.com.',
139
            'postmaster.example.com.',
140
            (int) date('Ymd01'),
141
            3600,
142
            14400,
143
            604800,
144
            3600
145
        ));
146
        $zone->addResourceRecord($soa);
147
148
        $this->assertEquals(Validator::ZONE_TOO_MANY_SOA, Validator::zone($zone));
149
    }
150
151
    public function testValidateNumberOfClasses(): void
152
    {
153
        $zone = TestZone::buildTestZone();
154
        $a = new ResourceRecord();
155
        $a->setName('test');
156
        $a->setClass(Classes::CHAOS);
157
        $a->setRdata(Factory::A('192.168.0.1'));
158
        $a->setComment('This class does not belong here');
159
        $zone->addResourceRecord($a);
160
161
        $this->assertEquals(Validator::ZONE_TOO_MANY_CLASSES, Validator::zone($zone));
162
    }
163
164
    public function testValidateZone(): void
165
    {
166
        $zone = TestZone::buildTestZone();
167
168
        //Remove the NS records.
169
        foreach ($zone as $resourceRecord) {
170
            if (NS::TYPE === $resourceRecord->getType()) {
171
                $zone->remove($resourceRecord);
172
            }
173
        }
174
175
        $soa = new ResourceRecord();
176
        $soa->setClass(Classes::INTERNET);
177
        $soa->setName('@');
178
        $soa->setRdata(Factory::SOA(
179
            'example.com.',
180
            'postmaster.example.com.',
181
            (int) date('Ymd01'),
182
            3600,
183
            14400,
184
            604800,
185
            3600
186
        ));
187
        $a = new ResourceRecord();
188
        $a->setName('test');
189
        $a->setClass(Classes::CHAOS);
190
        $a->setRdata(Factory::A('192.168.0.1'));
191
        $a->setComment('This class does not belong here');
192
193
        $zone->addResourceRecord($a);
194
        $zone->addResourceRecord($soa);
195
196
        $this->assertTrue((bool) (Validator::ZONE_TOO_MANY_CLASSES & Validator::zone($zone)));
197
        $this->assertTrue((bool) (Validator::ZONE_NO_NS & Validator::zone($zone)));
198
        $expectation = Validator::ZONE_NO_NS | Validator::ZONE_TOO_MANY_CLASSES | Validator::ZONE_TOO_MANY_SOA;
199
        $this->assertEquals($expectation, Validator::zone($zone));
200
    }
201
202
    public function testZone(): void
203
    {
204
        $zone = TestZone::buildTestZone();
205
        $this->assertEquals(Validator::ZONE_OKAY, Validator::zone($zone));
206
    }
207
208
    public function getWildcardTestData(): array
209
    {
210
        return [
211
            ['*.example.com.', true],
212
            ['*', true],
213
            ['*.sub', true],
214
            ['*.sub.domain', true],
215
            ['*.sub.example.com.', true],
216
217
            ['*abc.example.com.', false],
218
            ['domain.*.example.com.', false],
219
            ['example.com.*', false],
220
            ['*.', false],
221
        ];
222
    }
223
224
    /**
225
     * @param string $name    the wildcard domain to be validated
226
     * @param bool   $isValid whether the domain is valid
227
     *
228
     * @dataProvider getWildcardTestData
229
     */
230
    public function testWildcard(string $name, bool $isValid): void
231
    {
232
        $this->assertEquals($isValid, Validator::resourceRecordName($name));
233
    }
234
235
    public function getTestReverseIpv4DataProvider(): array
236
    {
237
        return [
238
            ['10.IN-ADDR.ARPA.', true],
239
            ['10.IN-ADDR.ARPA.', true],
240
            ['18.IN-addr.ARPA.', true],
241
            ['26.IN-ADdr.ArpA.', true],
242
            ['22.0.2.10.IN-ADDR.ARPA.', true],
243
            ['103.0.0.26.IN-ADDR.ARPA.', true],
244
            ['77.0.0.10.IN-ADDR.ARPA.', true],
245
            ['4.0.10.18.IN-ADDR.ARPA.', true],
246
            ['103.0.3.26.IN-ADDR.ARPA.', true],
247
            ['6.0.0.10.IN-ADDR.ARPA.', true],
248
249
            ['10.IN-ADDR.ARPA', false],
250
            ['10.20.ARPA.', false],
251
            ['10.123.0.1.INADDR.ARPA.', false],
252
            ['10.1.1.1.1.in-addr.arpa.', false],
253
            ['10.1.256.7.in-addr.arpa.', false],
254
        ];
255
    }
256
257
    /**
258
     * @dataProvider getTestReverseIpv4DataProvider
259
     */
260
    public function testReverseIpv4(string $ptr, bool $isValid): void
261
    {
262
        $this->assertEquals($isValid, Validator::reverseIpv4($ptr));
263
    }
264
265
    public function getTestReverseIpv6DataProvider(): array
266
    {
267
        return [
268
            ['b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.', true],
269
            ['1.0.0.0.6.8.7.0.6.5.a.0.4.0.5.1.2.0.0.3.8.f.0.1.0.0.2.ip6.arpa.', true],
270
            ['b.a.9.8.7.6.5.0.0.g.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.', false],
271
        ];
272
    }
273
274
    /**
275
     * @dataProvider getTestReverseIpv6DataProvider
276
     */
277
    public function testReverseIpv6(string $ptr, bool $isValid): void
278
    {
279
        $this->assertEquals($isValid, Validator::reverseIpv6($ptr));
280
    }
281
282
    public function testResourceRecordName(): void
283
    {
284
        $case_1 = '*.';
285
        $case_2 = '*.hello.com';
286
        $case_3 = 'www.*.hello.com';
287
288
        $this->assertFalse(Validator::resourceRecordName($case_1));
289
        $this->assertTrue(Validator::resourceRecordName($case_2));
290
        $this->assertFalse(Validator::resourceRecordName($case_3));
291
    }
292
293
    public function getTestFqdnDataProvider(): array
294
    {
295
        return [
296
            ['example.com.', true],
297
            ['www.example.com.', true],
298
            ['ex-ample.com.', true],
299
            ['ex-ampl3.com.au.', true],
300
            ['alt2.aspmx.l.google.com.', true],
301
            ['www.eXAMple.cOm.', true],
302
            ['3xample.com.', true],
303
            ['_example.com.', false],
304
            ['-example.com.', false],
305
            ['example.com', false],
306
            ['e&ample.com.', false],
307
        ];
308
    }
309
310
    /**
311
     * @dataProvider getTestFqdnDataProvider
312
     */
313
    public function testFqdn(string $domain, bool $isValid): void
314
    {
315
        $this->assertEquals($isValid, Validator::fullyQualifiedDomainName($domain));
316
    }
317
318
    public function testHostName(): void
319
    {
320
        $this->assertTrue(Validator::hostName('ya-hoo123'));
321
    }
322
323
    public function testNoAliasInZone(): void
324
    {
325
        //Pass case
326
        $txt1 = new ResourceRecord();
327
        $txt1->setName('www');
328
        $txt1->setRdata(Factory::TXT('v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.123 a -all'));
329
        $txt1->setClass(Classes::INTERNET);
330
331
        //Fail case
332
        $txt2 = new ResourceRecord();
333
        $txt2->setName('alias');
334
        $txt2->setRdata(Factory::TXT('v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.123 a -all'));
335
        $txt2->setClass(Classes::INTERNET);
336
337
        $zone = TestZone::buildTestZone();
338
339
        $this->assertTrue(Validator::noAliasInZone($zone, $txt1));
340
341
        $this->assertFalse(Validator::noAliasInZone($zone, $txt2));
342
    }
343
344
    public function testIsUnsignedInteger(): void
345
    {
346
        $this->assertFalse(Validator::isUnsignedInteger(-1, 16));
347
        $this->assertFalse(Validator::isUnsignedInteger(65536, 16));
348
        $this->assertTrue(Validator::isUnsignedInteger(65535, 16));
349
        $this->assertTrue(Validator::isUnsignedInteger(0, 16));
350
351
        $this->expectException(RuntimeException::class);
352
        Validator::isUnsignedInteger(10, 64);
353
    }
354
355
    public function testIsBase32Encoded(): void
356
    {
357
        $this->assertTrue(Validator::isBase32Encoded('JBSWY3DPFQQHI2DJOMQGS4ZAMEQGEYLTMUZTEIDFNZRW6ZDFMQQHG5DSNFXGOLQ='));
358
        $this->assertFalse(Validator::isBase32Encoded('JBSWY3DPFQQHI2DJOMQGS8ZAMEQGEYLTMUZTEIDFNZRW6ZDFMQQHG5DSNFXGOLQ='));
359
        $this->assertFalse(Validator::isBase32Encoded('JBSWY3DPFQQHI2DJOMQGS8ZAMEQGEYLTMUZTEIDFNZRW6ZDFMQQHG5DSNFXGOLQ='));
360
    }
361
362
    public function testIsBase64Encoded(): void
363
    {
364
        $this->assertTrue(Validator::isBase64Encoded('VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy4='));
365
        $this->assertFalse(Validator::isBase64Encoded('VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy4=='));
366
        $this->assertFalse(Validator::isBase64Encoded('VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGV\IHN0cmluZy4='));
367
    }
368
}
369