ResourceRecordTest::testSettersAndGetters()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.6
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\A;
18
use Badcow\DNS\Rdata\Factory;
19
use Badcow\DNS\ResourceRecord;
20
use Badcow\DNS\UnsetValueException;
21
use Exception;
22
use InvalidArgumentException;
23
use PHPUnit\Framework\TestCase;
24
25
class ResourceRecordTest extends TestCase
26
{
27
    public function testSetClass(): void
28
    {
29
        $rr = new ResourceRecord();
30
        $rr->setClass(Classes::INTERNET);
31
        $this->assertEquals(Classes::INTERNET, $rr->getClass());
32
33
        $this->expectException(InvalidArgumentException::class);
34
        $rr->setClass('XX');
35
    }
36
37
    /**
38
     * Tests the getter and setter methods.
39
     */
40
    public function testSettersAndGetters(): void
41
    {
42
        $rr = new ResourceRecord();
43
        $name = 'test';
44
        $ttl = 3500;
45
        $comment = 'Hello';
46
        $a = Factory::A('192.168.7.7');
47
48
        $rr->setName($name);
49
        $rr->setClass(Classes::INTERNET);
50
        $rr->setRdata($a);
51
        $rr->setTtl($ttl);
52
        $rr->setComment($comment);
53
54
        $this->assertEquals($a, $rr->getRdata());
55
        $this->assertEquals($name, $rr->getName());
56
        $this->assertEquals($ttl, $rr->getTtl());
57
        $this->assertEquals($comment, $rr->getComment());
58
        $this->assertEquals($a->getType(), $rr->getType());
59
    }
60
61
    public function testUnsetTtl(): void
62
    {
63
        $rr = new ResourceRecord();
64
        $rr->setName('example.com.');
65
        $ttl = 10800;
66
67
        $this->assertNull($rr->getTtl());
68
        $rr->setTtl($ttl);
69
        $this->assertEquals($ttl, $rr->getTtl());
70
        $rr->setTtl(null);
71
        $this->assertNull($rr->getTtl());
72
    }
73
74
    /**
75
     * @throws Exception
76
     */
77
    public function testToWire(): void
78
    {
79
        $expectation = pack('C*',
80
            0x03, 0x61, 0x62, 0x63, 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, //(3)abc(7)example(3)com(NULL)
81
            0x00, 0x01, //A (1)
82
            0x00, 0x01, //IN (1)
83
            0x00, 0x00, 0x0E, 0x10, //3600
84
            0x00, 0x04, //4 (RDLENGTH)
85
            0xC0, 0xA8, 0x01, 0x01 //192.168.1.1
86
        );
87
88
        $a = Factory::A('192.168.1.1');
89
        $rr = new ResourceRecord();
90
        $rr->setName('abc.example.com.');
91
        $rr->setClass(Classes::INTERNET);
92
        $rr->setRdata($a);
93
        $rr->setTtl(3600);
94
95
        $this->assertEquals($expectation, $rr->toWire());
96
    }
97
98
    public function dataProviderForTestToWireThrowsExceptionsIfValuesAreNotSet(): array
99
    {
100
        $rr_noName = new ResourceRecord();
101
        $rr_noName->setClass(null);
102
103
        $rr_noRdata = clone $rr_noName;
104
        $rr_noRdata->setName('@');
105
106
        $rr_noClass = clone $rr_noRdata;
107
        $rr_noClass->setRdata(new A());
108
109
        $rr_noTtl = clone $rr_noClass;
110
        $rr_noTtl->setClass('CLASS42');
111
112
        $rr_unqualifiedName = clone $rr_noTtl;
113
        $rr_unqualifiedName->setTtl(4242);
114
115
        return [
116
            [$rr_noName, UnsetValueException::class, 'ResourceRecord name has not been set.'],
117
            [$rr_noRdata, UnsetValueException::class, 'ResourceRecord rdata has not been set.'],
118
            [$rr_noClass, UnsetValueException::class, 'ResourceRecord class has not been set.'],
119
            [$rr_noTtl, UnsetValueException::class, 'ResourceRecord TTL has not been set.'],
120
            [$rr_unqualifiedName, \InvalidArgumentException::class, '"@" is not a fully qualified domain name.'],
121
        ];
122
    }
123
124
    /**
125
     * @dataProvider dataProviderForTestToWireThrowsExceptionsIfValuesAreNotSet
126
     *
127
     * @throws UnsetValueException
128
     */
129
    public function testToWireThrowsExceptionsIfValuesAreNotSet(ResourceRecord $rr, string $exception, string $exceptionMessage): void
130
    {
131
        $this->expectException($exception);
132
        $this->expectExceptionMessage($exceptionMessage);
133
        $rr->toWire();
134
    }
135
136
    /**
137
     * @throws Exception
138
     */
139
    public function testFromWire(): void
140
    {
141
        $encoded = pack('C*',
142
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, //8-bytes to test the offset
143
            0x03, 0x61, 0x62, 0x63, 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, //(3)abc(7)example(3)com(NULL)
144
            0x00, 0x01, //A (1)
145
            0x00, 0x01, //IN (1)
146
            0x00, 0x00, 0x0E, 0x10, //3600
147
            0x00, 0x04, //4 (RDLENGTH)
148
            0xC0, 0xA8, 0x01, 0x01 //192.168.1.1
149
        );
150
151
        $offset = 8;
152
        $a = Factory::A('192.168.1.1');
153
        $expectation = new ResourceRecord();
154
        $expectation->setName('abc.example.com.');
155
        $expectation->setClass(Classes::INTERNET);
156
        $expectation->setRdata($a);
157
        $expectation->setTtl(3600);
158
159
        $this->assertEquals($expectation, ResourceRecord::fromWire($encoded, $offset));
160
        $this->assertEquals(39, $offset);
161
    }
162
}
163