AbstractFilterTest::testIsAbstract()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DanBettles\Defence\Tests\Filter;
6
7
use DanBettles\Defence\Envelope;
8
use DanBettles\Defence\Filter\AbstractFilter;
9
use DanBettles\Defence\Filter\FilterInterface;
10
use PHPUnit\Framework\TestCase;
11
use Psr\Log\LoggerInterface;
12
use Psr\Log\LogLevel;
13
use ReflectionClass;
14
use ReflectionMethod;
15
use Symfony\Component\HttpFoundation\Request;
16
17
use function gethostname;
18
19
use const true;
20
21
class AbstractFilterTest extends TestCase
22
{
23
    public function testIsAbstract(): void
24
    {
25
        $reflectionClass = new ReflectionClass(AbstractFilter::class);
26
27
        $this->assertTrue($reflectionClass->isAbstract());
28
    }
29
30
    public function testImplementsFilterinterface(): void
31
    {
32
        $reflectionClass = new ReflectionClass(AbstractFilter::class);
33
34
        $this->assertTrue($reflectionClass->implementsInterface(FilterInterface::class));
35
    }
36
37
    public function testConstructor(): void
38
    {
39
        $filterMock = $this->getMockForAbstractClass(AbstractFilter::class, [
40
            'options' => [
41
                'foo' => 'bar',
42
                'baz' => 'qux',
43
            ],
44
        ]);
45
46
        $this->assertSame([
47
            'log_level' => LogLevel::WARNING,
48
            'foo' => 'bar',
49
            'baz' => 'qux',
50
        ], $filterMock->getOptions());
51
    }
52
53
    public function testOptionsAreOptional(): void
54
    {
55
        $filterMock = $this->getMockForAbstractClass(AbstractFilter::class);
56
57
        $this->assertSame([
58
            'log_level' => LogLevel::WARNING,
59
        ], $filterMock->getOptions());
60
    }
61
62
    public function testAddlogentryIsProtected(): void
63
    {
64
        $reflectionMethod = new ReflectionMethod(AbstractFilter::class, 'envelopeAddLogEntry');
65
66
        $this->assertTrue($reflectionMethod->isProtected());
67
    }
68
69
    /** @return array<mixed[]> */
70
    public function providesFiltersAndTheLogEntriesTheyAdd(): array
71
    {
72
        $returnValue = [];
73
74
        $expectedLogLevel = LogLevel::EMERGENCY;
75
        $filterOptions = ['log_level' => $expectedLogLevel];
76
77
        $returnValue[] = [
78
            'expectedLogLevel' => $expectedLogLevel,
79
            'expectedLogMessage' => 'System is unusable.',
80
            'filter' => new class ($filterOptions) extends AbstractFilter {
81
                public function __invoke(Envelope $envelope): bool
82
                {
83
                    $this->envelopeAddLogEntry($envelope, 'System is unusable.');
84
85
                    return true;
86
                }
87
            },
88
        ];
89
90
        $returnValue[] = [
91
            'expectedLogLevel' => LogLevel::WARNING,
92
            'expectedLogMessage' => 'Exceptional occurrence that is not an error.',
93
            'filter' => new class extends AbstractFilter {
94
                public function __invoke(Envelope $envelope): bool
95
                {
96
                    $this->envelopeAddLogEntry($envelope, 'Exceptional occurrence that is not an error.');
97
98
                    return true;
99
                }
100
            },
101
        ];
102
103
        return $returnValue;
104
    }
105
106
    /** @dataProvider providesFiltersAndTheLogEntriesTheyAdd */
107
    public function testAddlogentryAddsALogEntryToTheLogger(
108
        string $expectedLogLevel,
109
        string $expectedLogMessage,
110
        AbstractFilter $filter
111
    ): void {
112
        $minimalRequest = new Request([], [], [], [], [], [
113
            'HTTP_HOST' => 'foo.com',
114
            'REQUEST_METHOD' => 'GET',
115
            'QUERY_STRING' => 'bar=baz&qux=quux',
116
        ]);
117
118
        $loggerMock = $this
119
            ->getMockBuilder(LoggerInterface::class)
120
            ->getMock()
121
        ;
122
123
        $loggerMock
124
            ->expects($this->once())
125
            ->method('log')
126
            ->with($expectedLogLevel, $expectedLogMessage, [
127
                'host_name' => gethostname(),
128
                'request_method' => 'GET',
129
                'uri' => 'http://foo.com/?bar=baz&qux=quux',
130
            ])
131
        ;
132
133
        /** @var LoggerInterface $loggerMock */
134
135
        $filter(new Envelope($minimalRequest, $loggerMock));
136
    }
137
}
138