Passed
Push — html ( b1eefd...a59423 )
by Peter
02:57
created

NavigationTest::testGetExtendedWithWrapper()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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