Completed
Push — master ( 79027c...8f1f38 )
by Oleg
03:47
created

BuilderTest::testDisplayRules()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 24
nc 1
nop 0
dl 0
loc 41
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace Malezha\Menu\Tests;
3
4
use Malezha\Menu\Contracts\Attributes;
5
use Malezha\Menu\Contracts\Builder;
6
use Malezha\Menu\Element\Link;
7
use Malezha\Menu\Element\SubMenu;
8
use Malezha\Menu\Element\Text;
9
use Malezha\Menu\Factory\LinkFactory;
10
use Malezha\Menu\Factory\SubMenuFactory;
11
use Malezha\Menu\Factory\TextFactory;
12
13
/**
14
 * Class BuilderTest
15
 * @package Malezha\Menu\Tests
16
 */
17
class BuilderTest extends TestCase
18
{
19
    /**
20
     * @return Builder
21
     */
22
    protected function builderFactory()
23
    {
24
        return $this->app->makeWith(Builder::class, [
25
            'activeAttributes' => $this->app->makeWith(Attributes::class, ['attributes' => ['class' => 'active']]),
26
            'attributes' => $this->app->makeWith(Attributes::class, ['attributes' => ['class' => 'menu']]),
27
        ]);
28
    }
29
    
30
    protected function serializeStub()
31
    {
32
        return $this->getStub('serialized/builder.txt');
33
    }
34
    
35
    protected function toArrayStub()
36
    {
37
        return [
38
            'type' => 'ul',
39
            'view' => 'menu::view',
40
            'attributes' => [
41
                'class' => 'menu',
42
            ],
43
            'activeAttributes' => [
44
                'class' => 'active',
45
            ],
46
            'elements' => [
47
                'index' => [
48
                    'view' => 'menu::elements.link',
49
                    'title' => 'Index',
50
                    'url' => 'http://localhost',
51
                    'attributes' => [],
52
                    'activeAttributes' => [
53
                        'class' => 'active',
54
                    ],
55
                    'linkAttributes' => [],
56
                    'displayRule' => true,
57
                    'type' => 'link',
58
                ],
59
                'submenu' => [
60
                    'view' => 'menu::elements.submenu',
61
                    'title' => '',
62
                    'url' => '#',
63
                    'attributes' => [],
64
                    'activeAttributes' => [
65
                        'class' => 'active',
66
                    ],
67
                    'linkAttributes' => [],
68
                    'displayRule' => true,
69
                    'builder' => [
70
                        'type' => 'ul',
71
                        'view' => 'menu::view',
72
                        'attributes' => [],
73
                        'activeAttributes' => [],
74
                        'elements' => [
75
                            'item_1' => [
76
                                'view' => 'menu::elements.link',
77
                                'title' => 'Item 1',
78
                                'url' => 'http://localhost/item/1',
79
                                'attributes' => [],
80
                                'activeAttributes' => [],
81
                                'linkAttributes' => [],
82
                                'displayRule' => true,
83
                                'type' => 'link',
84
                            ],
85
                            'item_2' => [
86
                                'view' => 'menu::elements.link',
87
                                'title' => 'Item 2',
88
                                'url' => 'http://localhost/item/2',
89
                                'attributes' => [],
90
                                'activeAttributes' => [],
91
                                'linkAttributes' => [],
92
                                'displayRule' => true,
93
                                'type' => 'link',
94
                            ],
95
                            'item_3' => [
96
                                'view' => 'menu::elements.link',
97
                                'title' => 'Item 3',
98
                                'url' => 'http://localhost/item/3',
99
                                'attributes' => [],
100
                                'activeAttributes' => [],
101
                                'linkAttributes' => [],
102
                                'displayRule' => true,
103
                                'type' => 'link',
104
                            ],
105
                        ],
106
                    ],
107
                    'type' => 'submenu',
108
                ],
109
            ],
110
        ];
111
    }
112
    
113
    public function testConstructor()
114
    {
115
        $builder = $this->builderFactory();
116
117
        $this->assertAttributeEquals($this->app, 'app', $builder);
118
        $this->assertAttributeEquals(Builder::UL, 'type', $builder);
119
        $this->assertAttributeInstanceOf(Attributes::class, 'attributes', $builder);
120
        $this->assertAttributeInternalType('array', 'elements', $builder);
121
        $this->assertAttributeInstanceOf(Attributes::class, 'activeAttributes', $builder);
122
    }
123
124
    public function testCreate()
125
    {
126
        $builder = $this->builderFactory();
127
128
        /** @var Link $item */
129
        $item = $builder->create('index', Link::class, function(LinkFactory $factory) {
130
            $factory->title = 'Home';
131
            $factory->url = '/';
132
133
            return $factory->build();
134
        });
135
136
        $this->assertInstanceOf(Link::class, $item);
137
        $this->assertAttributeEquals('Home', 'title', $item);
138
        $this->assertAttributeEquals('/', 'url', $item);
139
    }
140
141
    public function testCreateIfExists()
142
    {
143
        $this->expectException(\RuntimeException::class);
144
        
145
        $builder = $this->builderFactory();
146
147
        $builder->create('index', Link::class, function (LinkFactory $factory) {
148
            return $factory->build();
149
        });
150
151
        $builder->create('index', SubMenu::class, function (SubMenuFactory $factory) {
152
            return $factory->build();
153
        }); // Duplicate
154
    }
155
    
156
    public function testGet()
157
    {
158
        $builder = $this->builderFactory();
159
        
160
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
161
            return $factory->build();
162
        });
163
        
164
        $this->assertEquals($item, $builder->get('test'));
165
        $this->assertEquals(null, $builder->get('notFound'));
166
        $this->assertEquals($item, $builder['test']);
167
        $this->assertEquals(null, $builder['notFound']);
168
    }
169
170
    public function testGetByIndex()
171
    {
172
        $builder = $this->builderFactory();
173
174
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
175
            return $factory->build();
176
        });
177
178
        $this->assertEquals($item, $builder->getByIndex(0));
179
        $this->assertEquals(null, $builder->getByIndex(1));
180
        $this->assertEquals($item, $builder[0]);
181
        $this->assertEquals(null, $builder[1]);
182
    }
183
    
184
    public function testHas()
185
    {
186
        $builder = $this->builderFactory();
187
188
        $this->assertFalse($builder->has('test'));
189
        $this->assertFalse(isset($builder['test']));
190
    }
191
    
192
    public function testType()
193
    {
194
        $builder = $this->builderFactory();
195
        
196
        $this->assertEquals(Builder::UL, $builder->getType());
197
        $builder->setType(Builder::OL);
198
        $this->assertAttributeEquals(Builder::OL, 'type', $builder);
199
    }
200
    
201
    public function testAll()
202
    {
203
        $builder = $this->builderFactory();
204
        
205
        $this->assertEquals([], $builder->all());
206
207
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
208
            return $factory->build();
209
        });
210
211
        $this->assertEquals(['test' => $item], $builder->all());
212
    }
213
    
214
    public function testForget()
215
    {
216
        $builder = $this->builderFactory();
217
218
        $builder->create('test', Link::class, function (LinkFactory $factory) {
219
            return $factory->build();
220
        });
221
        $builder->create('another', Text::class, function (TextFactory $factory) {
222
            return $factory->build();
223
        });
224
        
225
        $this->assertTrue($builder->has('test'));
226
        $builder->forget('test');
227
        $this->assertFalse($builder->has('test'));
228
        
229
        $this->assertTrue($builder->has('another'));
230
        unset($builder['another']);
231
        $this->assertFalse($builder->has('another'));
232
    }
233
    
234
    public function testActiveAttributes()
235
    {
236
        $builder = $this->builderFactory();
237
        $activeAttributes = $builder->getActiveAttributes();
238
        
239
        $this->assertInstanceOf(Attributes::class, $activeAttributes);
240
241
        $result = $builder->getActiveAttributes(function(Attributes $attributes) {
242
            $this->assertInstanceOf(Attributes::class, $attributes);
243
            
244
            return $attributes->get('class');
245
        });
246
        
247
        $this->assertEquals('active', $result);
248
    }
249
250
    public function testRender()
251
    {
252
        $builder = $this->builderFactory();
253
254
        $builder->create('index', Link::class, function(LinkFactory $factory) {
255
            $factory->title = 'Index Page';
256
            $factory->url = url('/');
257
            $factory->linkAttributes->push(['class' => 'menu-link']);
258
259
            return $factory->build();
260
        });
261
        
262
        $builder->create('orders', SubMenu::class, function(SubMenuFactory $factory) {
263
            $factory->attributes->push(['class' => 'child-menu']);
264
            $factory->title = 'Orders';
265
            $factory->url = 'javascript:;';
266
            
267
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
268
                $factory->title = 'All';
269
                $factory->url = url('/orders/all');
270
271
                return $factory->build();
272
            });
273
274
            $factory->builder->create('type_1', Link::class, function(LinkFactory $factory) {
275
                $factory->title = 'Type 1';
276
                $factory->url = url('/orders/1');
277
                $factory->linkAttributes->push(['class' => 'text-color-red']);
278
279
                return $factory->build();
280
            });
281
282
            $factory->builder->create('type_2', Link::class, function(LinkFactory $factory) {
283
                $factory->title = 'Type 2';
284
                $factory->url = url('/orders/2');
285
                $factory->linkAttributes->push(['data-attribute' => 'value']);
286
287
                return $factory->build();
288
            });
289
290
            return $factory->build();
291
        });
292
        
293
        $html = $builder->render();
294
        
295
        $this->assertEquals($this->getStub('menu.html'), $html);
296
    }
297
    
298
    public function testDisplayRules()
299
    {
300
        $builder = $this->builderFactory();
301
302
        $builder->create('index', Link::class, function(LinkFactory $factory) {
303
            $factory->title = 'Index Page';
304
            $factory->url = url('/');
305
306
            return $factory->build();
307
        });
308
309
        $builder->create('login', Link::class, function(LinkFactory $factory) {
310
            $factory->title = 'Login';
311
            $factory->url = url('/login');
312
            $factory->displayRule = function() {
313
                return true;
314
            };
315
316
            return $factory->build();
317
        });
318
319
        $builder->create('admin', Link::class, function(LinkFactory $factory) {
320
            $factory->title = 'Admin';
321
            $factory->url = url('/admin');
322
            $factory->displayRule = false;
323
324
            return $factory->build();
325
        });
326
327
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
328
            $factory->title = 'Logout';
329
            $factory->url = url('/logout');
330
            $factory->displayRule = null;
331
332
            return $factory->build();
333
        });
334
335
        $html = $builder->render();
336
337
        $this->assertEquals($this->getStub('display_rules.html'), $html);
338
    }
339
340
    public function testAnotherViewRender()
341
    {
342
        view()->addLocation(__DIR__ . '/stub');
343
        $this->app['config']->prepend('menu.paths', __DIR__ . '/stub');
344
        
345
        $builder = $this->builderFactory();
346
        $builder->create('index', Link::class, function(LinkFactory $factory) {
347
            $factory->title = 'Index Page';
348
            $factory->url = url('/');
349
350
            return $factory->build();
351
        });
352
353
        $builder->create('group', SubMenu::class, function(SubMenuFactory $factory) {
354
            $factory->builder->create('one', Link::class, function(LinkFactory $factory) {
355
                $factory->title = 'One';
356
                $factory->url = url('/one');
357
358
                return $factory->build();
359
            });
360
361
            return $factory->build();
362
        });
363
        
364
        $this->assertEquals($this->getStub('another_menu.html'), $builder->render('another'));
365
366
        $builder->get('group')->getBuilder()->setView('another');
367
        $this->assertEquals($this->getStub('another_sub_menu.html'), $builder->render());
368
369
        $builder->setView('another');
370
        $builder->get('group')->getBuilder()->setView('menu::view');
371
        $this->assertEquals($this->getStub('another_set_view_menu.html'), $builder->render());
372
    }
373
    
374
    public function testInsert()
375
    {
376
        $builder = $this->builderFactory();
377
378
        $builder->create('index', Link::class, function(LinkFactory $factory) {
379
            $factory->title = 'Index Page';
380
            $factory->url = url('/');
381
382
            return $factory->build();
383
        });
384
385
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
386
            $factory->title = 'Logout';
387
            $factory->url = url('logout');
388
389
            return $factory->build();
390
        });
391
        
392
        $builder->insertAfter('index', function (Builder $builder) {
393
            $builder->create('users', Link::class, function(LinkFactory $factory) {
394
                $factory->title = 'Users';
395
                $factory->url = url('users');
396
397
                return $factory->build();
398
            });
399
        });
400
        
401
        $builder->insertBefore('users', function (Builder $builder) {
402
            $builder->create('profile', Link::class, function(LinkFactory $factory) {
403
                $factory->title = 'Profile';
404
                $factory->url = url('profile');
405
406
                return $factory->build();
407
            });
408
        });
409
410
        $this->assertEquals($this->getStub('insert.html'), $builder->render('another'));
411
    }
412
413
    public function testInsertExceptionHasNot()
414
    {
415
        $this->expectException(\RuntimeException::class);
416
417
        $builder = $this->builderFactory();
418
        $builder->insertBefore('not_exist', function (Builder $builder) {});
419
    }
420
421
    public function testInsertExceptionDuplicate()
422
    {
423
        $this->expectException(\RuntimeException::class);
424
425
        $builder = $this->builderFactory();
426
427
        $builder->create('home', Link::class, function(LinkFactory $factory) {
428
            $factory->title = 'Home';
429
            $factory->url = '/';
430
431
            return $factory->build();
432
        });
433
434
        $builder->create('some', Link::class, function(LinkFactory $factory) {
435
            $factory->title = 'Some';
436
            $factory->url = '/';
437
438
            return $factory->build();
439
        });
440
441
        $builder->insertAfter('home', function (Builder $builder) {
442
            $builder->create('some', Text::class, function(TextFactory $factory) {
443
                $factory->text = 'Duplicate some';
444
445
                return $factory->build();
446
            });
447
        });
448
    }
449
450
    public function testArray()
451
    {
452
        $builder = $this->builderFactory();
453
        $builder->create('index', Link::class, function(LinkFactory $factory) {
454
            $factory->title = 'Index';
455
            $factory->url = url('/');
456
457
            return $factory->build();
458
        });
459
460
        $builder->create('submenu', SubMenu::class, function(SubMenuFactory $factory) {
461
            for ($i = 1; $i <= 3; ++$i) {
462
                $factory->builder->create('item_' . $i, Link::class, function(LinkFactory $factory) use ($i) {
463
                    $factory->title = 'Item ' . $i;
464
                    $factory->url = url('/item', ['id' => $i]);
465
466
                    return $factory->build();
467
                });
468
            }
469
470
            return $factory->build();
471
        });
472
        
473
        $this->assertEquals($this->toArrayStub(), $builder->toArray());
474
475
        $builderFormArray = $builder->fromArray($builder->toArray());
476
        $this->assertEquals($builder->render(), $builderFormArray->render());
477
    }
478
    
479
    public function testSet()
480
    {
481
        $builder = $this->builderFactory();
482
        $element = (new TextFactory($this->app))->build([
483
            'text' => 'Text',
484
        ]);
485
        $notElement = [];
486
        
487
        $builder['element'] = $element;
488
        $builder['notElement'] = $notElement;
489
        
490
        $this->assertTrue($builder->has('element'));
491
        $this->assertFalse($builder->has('notElement'));
492
    }
493
494
    public function testCreateCallbackException()
495
    {
496
        $this->expectException(\RuntimeException::class);
497
498
        $builder = $this->builderFactory();
499
        $builder->create('test', Link::class, function(LinkFactory $factory) {
500
            return 'string';
501
        });
502
    }
503
504
    public function testCreateTypeWrongException()
505
    {
506
        $this->expectException(\RuntimeException::class);
507
508
        $builder = $this->builderFactory();
509
        $builder->create('test', \Exception::class);
510
    }
511
}