Passed
Push — html ( 4d98c2...e7bfd2 )
by Peter
03:09
created

testRenderDisplaysItemsInProperOrder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
nc 2
nop 0
dl 0
loc 19
rs 9.9
c 2
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Navigation;
6
7
use AbterPhp\Framework\Html\Helper\Attributes;
8
use AbterPhp\Framework\Html\ITag;
9
use AbterPhp\Framework\Html\Tag;
10
use AbterPhp\Framework\I18n\ITranslator;
11
use Casbin\Enforcer;
12
use InvalidArgumentException;
13
use PHPUnit\Framework\MockObject\MockObject;
14
use PHPUnit\Framework\TestCase;
15
16
class NavigationTest extends TestCase
17
{
18
    protected const INTENTS    = ['bar', 'baz'];
19
    protected const ATTRIBUTES = ['data-quix' => ['quix']];
20
    protected const RESOURCE   = 'quint';
21
22
    /** @var Enforcer|MockObject */
23
    protected $enforcerMock;
24
25
    public function setUp(): void
26
    {
27
        parent::setUp();
28
29
        $this->enforcerMock = $this->createMock(Enforcer::class);
30
    }
31
32
    public function testDefaultGetExtended(): void
33
    {
34
        $sut = new Navigation();
35
36
        $expectedResult = [$sut->getPrefix(), $sut->getPostfix()];
37
38
        $actualResult = $sut->getExtendedNodes();
39
40
        $this->assertSame($expectedResult, $actualResult);
41
    }
42
43
    public function testSetContent(): void
44
    {
45
        $this->expectException(\LogicException::class);
46
47
        $sut = new Navigation();
48
49
        /** @scrutinizer ignore-deprecated */
50
        $sut->setContent('');
51
    }
52
53
    public function testSetContentReturnsSelfIfContentIsNull(): void
54
    {
55
        $sut = new Navigation();
56
57
        $actualResult = $sut->setContent(null);
58
59
        $this->assertSame($sut, $actualResult);
60
    }
61
62
    public function testDefaultToString(): void
63
    {
64
        $expectedResult = '<ul></ul>';
65
66
        $sut = new Navigation();
67
68
        $actualResult = (string)$sut;
69
70
        $this->assertSame($expectedResult, $actualResult);
71
    }
72
73
    public function testToStringWithOptionalsModified(): void
74
    {
75
        $sut = new Navigation();
76
77
        $sut->setWrapper(new Tag('YYY', [], null, 'foo'));
78
        $sut->getPrefix()->setContent(new Tag('XXX', [], null, 'bar'));
79
        $sut->getPostfix()->setContent(new Tag('ZZZ', [], null, 'baz'));
80
81
        $this->assertSame('<bar>XXX</bar><foo><ul></ul></foo><baz>ZZZ</baz>', (string)$sut);
82
    }
83
84
    public function testRenderDisplaysItemsInProperOrder(): void
85
    {
86
        $rawItems   = [new Item('AAA'), new Item('BBB'), new Item('CCC'), new Item('DDD')];
87
        $items      = [
88
            100 => [$rawItems[0], $rawItems[1]],
89
            50  => [$rawItems[2]],
90
            75  => [$rawItems[3]],
91
        ];
92
        $attributes = Attributes::fromArray(static::ATTRIBUTES);
93
94
        $sut = new Navigation(static::INTENTS, $attributes);
95
96
        foreach ($items as $weight => $itemsByWeight) {
97
            $sut->addWithWeight($weight, ...$itemsByWeight);
98
        }
99
100
        $rendered = (string)$sut;
101
102
        $this->assertMatchesRegularExpression('/^\s*\<ul.*CCC.*DDD.*AAA.*BBB.*\<\/ul\>\s*$/Ums', $rendered);
103
    }
104
105
    public function testGetWrapperReturnsNullByDefault(): void
106
    {
107
        $sut = new Navigation();
108
109
        $actualResult = $sut->getWrapper();
110
111
        $this->assertNull($actualResult);
112
    }
113
114
    public function testGetWrapperReturnsLastLestWrapper(): void
115
    {
116
        $sut = new Navigation();
117
118
        /** @var ITag $tagMock */
119
        $tagMock = $this->createMock(ITag::class);
120
121
        $sut->setWrapper($tagMock);
122
123
        $actualResult = $sut->getWrapper();
124
125
        $this->assertSame($tagMock, $actualResult);
126
    }
127
128
    public function testSetTranslatorSetsTranslatorOnNodes(): void
129
    {
130
        $sut = new Navigation();
131
132
        /** @var ITranslator $translatorMock */
133
        $translatorMock = $this->createMock(ITranslator::class);
134
135
        /** @var Item|MockObject $itemMock */
136
        $itemMock = $this->createMock(Item::class);
137
138
        $itemMock
139
            ->expects($this->atLeastOnce())
140
            ->method('setTranslator')
141
            ->with($translatorMock)
142
            ->willReturn($sut);
143
144
        $sut[] = $itemMock;
145
146
        $sut->setTranslator($translatorMock);
147
    }
148
149
    public function testOffsetSetThrowsExceptionOnInvalidOffset(): void
150
    {
151
        $this->expectException(InvalidArgumentException::class);
152
153
        $sut = new Navigation();
154
155
        /** @var Item|MockObject $itemMock */
156
        $itemMock = $this->createMock(Item::class);
157
158
        $sut[1] = $itemMock;
159
    }
160
161
    public function testOffsetSetCanUseWeightIfNeeded(): void
162
    {
163
        $sut = $this->createNavigation();
164
165
        $itemMock = $this->createMock(Item::class);
166
        $itemMock->expects($this->any())->method('__toString')->willReturn('!');
167
        $sut[4] = $itemMock;
168
169
        $expectedResult = "<ul>ax\nay\naz\nbx\n!\nbz</ul>";
170
        $actualResult   = (string)$sut;
171
172
        $this->assertEquals($expectedResult, $actualResult);
173
    }
174
175
    public function testOffsetUnSetCanUseWeightIfNeeded(): void
176
    {
177
        $sut = $this->createNavigation();
178
179
        unset($sut[4]);
180
181
        $expectedResult = "<ul>ax\nay\naz\nbx\nbz</ul>";
182
        $actualResult   = (string)$sut;
183
184
        $this->assertEquals($expectedResult, $actualResult);
185
    }
186
187
    public function testOffsetGetCanUseWeightIfNeeded(): void
188
    {
189
        $sut            = $this->createNavigation();
190
        $expectedResult = "by";
191
        $actualResult   = (string)$sut[4];
192
193
        $this->assertEquals($expectedResult, $actualResult);
194
    }
195
196
    public function testCount(): void
197
    {
198
        $sut = $this->createNavigation();
199
200
        $expectedResult = 6;
201
        $actualResult   = count($sut);
202
203
        $this->assertEquals($expectedResult, $actualResult);
204
    }
205
206
    public function testForeach(): void
207
    {
208
        $sut = $this->createNavigation();
209
210
        $expectedResults = ['ax', 'ay', 'az', 'bx', 'by', 'bz'];
211
212
        foreach ($sut as $key => $item) {
213
            $this->assertEquals($expectedResults[$key], (string)$item);
214
        }
215
    }
216
217
    /**
218
     * @param array|string[] $weightGroups
219
     * @param array|string[] $itemGroups
220
     *
221
     * @return Navigation
222
     */
223
    protected function createNavigation(
224
        array $weightGroups = ['a', 'b'],
225
        array $itemGroups = ['x', 'y', 'z']
226
    ): Navigation {
227
        $sut = new Navigation();
228
        foreach ($weightGroups as $w) {
229
            foreach ($itemGroups as $n) {
230
                $itemMock = $this->createMock(Item::class);
231
                $itemMock->expects($this->any())->method('__toString')->willReturn("$w$n");
232
                $sut->addWithWeight(ord($w) - ord('a'), $itemMock);
233
            }
234
        }
235
236
        return $sut;
237
    }
238
}
239