Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

CrudPanelColumnsTest   F
last analyzed

Complexity

Total Complexity 67

Size/Duplication

Total Lines 970
Duplicated Lines 0 %

Importance

Changes 6
Bugs 4 Features 2
Metric Value
wmc 67
eloc 578
c 6
b 4
f 2
dl 0
loc 970
rs 3.04

63 Methods

Rating   Name   Duplication   Size   Complexity  
A testAddColumnsByName() 0 6 1
A testAddColumnNotArray() 0 7 2
A testAddColumnsAsArray() 0 6 1
A testAddRelationsByName() 0 11 2
A testAddColumnByName() 0 5 1
A testAddColumnAsArray() 0 5 1
A setUp() 0 5 1
A testAddRelationByNameWithMutator() 0 34 2
A testItThrowsExceptionIfRouteNotFound() 0 6 1
A testOrderColumnsEmptyList() 0 7 1
A testRemoveColumnByName() 0 9 1
A testItCanAddAFluentColumn() 0 18 1
A testItDoesNotChangeThePriorityIfDeveloperDefinedIt() 0 5 1
A testMoveColumnBefore() 0 11 1
A testAddRelationColumn() 0 6 1
A testMoveColumnAfter() 0 11 1
A testItCanMakeAColumnFirstFluently() 0 7 1
A testItCanChangeTheColumnKey() 0 9 1
A testItCanRemoveColumnFluently() 0 6 1
A testColumnLinkToAutoInferAnySingleParameter() 0 9 1
A testItCanSetColumnDetails() 0 14 1
A testAddNestedRelationColumn() 0 10 2
A testItCanRemoveAllColumns() 0 7 1
A testItCanAddAFluentColumnUsingArray() 0 4 1
A testItCanInferFieldAttributesFromADynamicRelation() 0 15 1
A testItCanGetAndSetColumnsRemovingPreviouslySet() 0 18 1
A testOrderColumnsUnknownList() 0 7 1
A testItCanRemoveColumnAttributesFluently() 0 6 1
A testItCanMakeAColumnLastFluently() 0 8 1
A testItDoesNotAttemptToGetEntityWhenColumnNameIsArray() 0 4 1
A testItCanGetTheColumnTypeFromModelDates() 0 5 1
A testItAlwaysHasDatabaseColumnWhenDriverIsNotSql() 0 6 1
A testRemoveColumnsByName() 0 9 1
A testItCanAddADefaultTypeToTheColumn() 0 5 1
A testRemoveUnknownColumnName() 0 10 1
A testColumnLinkToWithRouteNameOnly() 0 11 1
A testItCanGetTheColumnTypeFromModelCasts() 0 15 1
A itCanSetTheUploadAttributeOnColumn() 0 5 1
A testOrderColumns() 0 7 1
A testColumnLinkToThrowsExceptionWhenNotAllRequiredParametersAreFilled() 0 5 1
A testMoveColumnAfterUnknownColumnName() 0 7 1
A testItCanGetAndSetActionsColumnPriority() 0 5 1
A testMakeFirstColumnReturnFalseWhenNoColumnsExist() 0 5 1
A testItSetsTextColumnTypeForTranslatableColumns() 0 6 1
A testItCanFindAColumnById() 0 7 1
A testItCanPlaceColumnsFluently() 0 16 1
A testMoveColumnBeforeUnknownColumnName() 0 7 1
A testItReturnFalseWhenTryingToAddTypeToAColumnWithoutName() 0 5 1
A testItCanInferTheEntityFromColumnNameUsingEntity_idConvention() 0 5 1
A testRemoveUnknownColumnsByName() 0 10 1
A testOrderColumnsMixedList() 0 7 1
A testItCanAddAFluentColumnUsingArrayWithoutName() 0 4 1
A testColumnLinkToDontAutoInferParametersIfAllProvided() 0 9 1
A testColumnLinkToWithCustomParameters() 0 7 1
A testItThrowsAnErrorWhenAttemptingToChangeTheKeyInAColumnWithoutName() 0 4 1
A testItCanAddAColumnToCrudFromClass() 0 4 1
A testOrderColumnsIncompleteList() 0 7 1
A testColumnLinkToWithCustomClosureParameters() 0 9 1
A testColumnLinkToWithClosure() 0 9 1
A testColumnArrayDefinitionLinkToRouteNameAndAdditionalParameters() 0 22 1
A testColumnLinkToWithRouteNameAndAdditionalParameters() 0 11 1
A testColumnArrayDefinitionLinkToRouteAsClosure() 0 12 1
A testColumnArrayDefinitionLinkToRouteNameOnly() 0 12 1

How to fix   Complexity   

Complex Class

Complex classes like CrudPanelColumnsTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CrudPanelColumnsTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Backpack\CRUD\Tests\Unit\CrudPanel;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudColumn;
6
use Backpack\CRUD\Tests\config\Models\User;
7
8
/**
9
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\Columns
10
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\ColumnsProtectedMethods
11
 * @covers Backpack\CRUD\app\Library\CrudPanel\CrudColumn
12
 * @covers Backpack\CRUD\app\Library\CrudPanel\CrudPanel
13
 */
14
class CrudPanelColumnsTest extends \Backpack\CRUD\Tests\config\CrudPanel\BaseCrudPanel
15
{
16
    private $oneColumnArray = [
17
        'name' => 'column1',
18
        'label' => 'Column1',
19
    ];
20
21
    private $expectedOneColumnArray = [
22
        'column1' => [
23
            'label' => 'Column1',
24
            'name' => 'column1',
25
            'key' => 'column1',
26
            'type' => 'text',
27
            'tableColumn' => false,
28
            'orderable' => false,
29
            'searchLogic' => false,
30
            'priority' => 0,
31
        ],
32
    ];
33
34
    private $otherOneColumnArray = [
35
        'name' => 'column4',
36
        'label' => 'Column4',
37
    ];
38
39
    private $twoColumnsArray = [
40
        [
41
            'name' => 'column1',
42
            'label' => 'Column1',
43
        ],
44
        [
45
            'name' => 'column2',
46
            'label' => 'Column2',
47
        ],
48
    ];
49
50
    private $expectedTwoColumnsArray = [
51
        'column1' => [
52
            'name' => 'column1',
53
            'key' => 'column1',
54
            'label' => 'Column1',
55
            'type' => 'text',
56
            'tableColumn' => false,
57
            'orderable' => false,
58
            'searchLogic' => false,
59
            'priority' => 0,
60
61
        ],
62
        'column2' => [
63
            'name' => 'column2',
64
            'key' => 'column2',
65
            'label' => 'Column2',
66
            'type' => 'text',
67
            'tableColumn' => false,
68
            'orderable' => false,
69
            'searchLogic' => false,
70
            'priority' => 1,
71
        ],
72
    ];
73
74
    private $threeColumnsArray = [
75
        [
76
            'name' => 'column1',
77
            'label' => 'Column1',
78
        ],
79
        [
80
            'name' => 'column2',
81
            'label' => 'Column2',
82
        ],
83
        [
84
            'name' => 'column3',
85
            'label' => 'Column3',
86
        ],
87
    ];
88
89
    private $expectedThreeColumnsArray = [
90
        'column1' => [
91
            'name' => 'column1',
92
            'key' => 'column1',
93
            'label' => 'Column1',
94
            'type' => 'text',
95
            'tableColumn' => false,
96
            'orderable' => false,
97
            'searchLogic' => false,
98
            'priority' => 0,
99
        ],
100
        'column2' => [
101
            'name' => 'column2',
102
            'key' => 'column2',
103
            'label' => 'Column2',
104
            'type' => 'text',
105
            'tableColumn' => false,
106
            'orderable' => false,
107
            'searchLogic' => false,
108
            'priority' => 1,
109
        ],
110
        'column3' => [
111
            'name' => 'column3',
112
            'key' => 'column3',
113
            'label' => 'Column3',
114
            'type' => 'text',
115
            'tableColumn' => false,
116
            'orderable' => false,
117
            'searchLogic' => false,
118
            'priority' => 2,
119
        ],
120
    ];
121
122
    private $expectedRelationColumnsArrayWithoutPro = [
123
        'accountDetails' => [
124
            'name' => 'accountDetails',
125
            'label' => 'AccountDetails',
126
            'type' => 'text',
127
            'key' => 'accountDetails',
128
            'priority' => 0,
129
            'tableColumn' => false,
130
            'orderable' => false,
131
            'searchLogic' => false,
132
            'entity' => 'accountDetails',
133
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
134
            'relation_type' => 'HasOne',
135
            'attribute' => 'nickname',
136
        ],
137
        'accountDetails__nickname' => [
138
            'name' => 'accountDetails.nickname',
139
            'label' => 'AccountDetails.nickname',
140
            'type' => 'text',
141
            'key' => 'accountDetails__nickname',
142
            'priority' => 1,
143
            'attribute' => 'nickname',
144
            'tableColumn' => false,
145
            'orderable' => false,
146
            'searchLogic' => false,
147
            'relation_type' => 'HasOne',
148
            'entity' => 'accountDetails.nickname',
149
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
150
        ],
151
        'accountDetails__user' => [
152
            'name' => 'accountDetails.user',
153
            'label' => 'AccountDetails.user',
154
            'type' => 'select',
155
            'key' => 'accountDetails__user',
156
            'priority' => 2,
157
            'tableColumn' => false,
158
            'orderable' => false,
159
            'searchLogic' => false,
160
            'relation_type' => 'BelongsTo',
161
            'entity' => 'accountDetails.user',
162
            'model' => 'Backpack\CRUD\Tests\Config\Models\User',
163
            'attribute' => 'name',
164
        ],
165
    ];
166
167
    private $expectedRelationColumnsArrayWithPro = [
168
        'accountDetails' => [
169
            'name' => 'accountDetails',
170
            'label' => 'AccountDetails',
171
            'type' => 'relationship',
172
            'key' => 'accountDetails',
173
            'priority' => 0,
174
            'tableColumn' => false,
175
            'orderable' => false,
176
            'searchLogic' => false,
177
            'entity' => 'accountDetails',
178
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
179
            'relation_type' => 'HasOne',
180
            'attribute' => 'nickname',
181
        ],
182
        'accountDetails__nickname' => [
183
            'name' => 'accountDetails.nickname',
184
            'label' => 'AccountDetails.nickname',
185
            'type' => 'relationship',
186
            'key' => 'accountDetails__nickname',
187
            'priority' => 1,
188
            'attribute' => 'nickname',
189
            'tableColumn' => false,
190
            'orderable' => false,
191
            'searchLogic' => false,
192
            'relation_type' => 'HasOne',
193
            'entity' => 'accountDetails.nickname',
194
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
195
        ],
196
        'accountDetails__user' => [
197
            'name' => 'accountDetails.user',
198
            'label' => 'AccountDetails.user',
199
            'type' => 'relationship',
200
            'key' => 'accountDetails__user',
201
            'priority' => 2,
202
            'tableColumn' => false,
203
            'orderable' => false,
204
            'searchLogic' => false,
205
            'relation_type' => 'BelongsTo',
206
            'entity' => 'accountDetails.user',
207
            'model' => 'Backpack\CRUD\Tests\Config\Models\User',
208
            'attribute' => 'name',
209
        ],
210
    ];
211
212
    private $relationColumnArray = [
213
        'name' => 'nickname',
214
        'type' => 'select',
215
        'entity' => 'accountDetails',
216
        'attribute' => 'nickname',
217
    ];
218
219
    private $expectedRelationColumnArray = [
220
        'nickname' => [
221
            'name' => 'nickname',
222
            'type' => 'select',
223
            'entity' => 'accountDetails',
224
            'attribute' => 'nickname',
225
            'label' => 'Nickname',
226
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
227
            'key' => 'nickname',
228
            'tableColumn' => false,
229
            'orderable' => false,
230
            'searchLogic' => false,
231
            'priority' => 0,
232
            'relation_type' => 'HasOne',
233
        ],
234
    ];
235
236
    private $nestedRelationColumnArray = [
237
        'name' => 'accountDetails.article',
238
    ];
239
240
    private $secondNestedRelationColumnArray = [
241
        'name' => 'accountDetails.article',
242
        'attribute' => 'content',
243
        'key' => 'ac_article_content',
244
    ];
245
246
    private $expectedNestedRelationColumnArrayWithPro = [
247
        'accountDetails__article' => [
248
            'name' => 'accountDetails.article',
249
            'type' => 'relationship',
250
            'entity' => 'accountDetails.article',
251
            'label' => 'AccountDetails.article',
252
            'model' => 'Backpack\CRUD\Tests\Config\Models\Article',
253
            'key' => 'accountDetails__article',
254
            'tableColumn' => false,
255
            'orderable' => false,
256
            'searchLogic' => false,
257
            'priority' => 0,
258
            'relation_type' => 'BelongsTo',
259
            'attribute' => 'content',
260
        ],
261
        'ac_article_content' => [
262
            'name' => 'accountDetails.article',
263
            'type' => 'relationship',
264
            'entity' => 'accountDetails.article',
265
            'label' => 'AccountDetails.article',
266
            'model' => 'Backpack\CRUD\Tests\Config\Models\Article',
267
            'key' => 'ac_article_content',
268
            'tableColumn' => false,
269
            'orderable' => false,
270
            'searchLogic' => false,
271
            'priority' => 1,
272
            'relation_type' => 'BelongsTo',
273
            'attribute' => 'content',
274
        ],
275
    ];
276
277
    private $expectedNestedRelationColumnArrayWithoutPro = [
278
        'accountDetails__article' => [
279
            'name' => 'accountDetails.article',
280
            'type' => 'select',
281
            'entity' => 'accountDetails.article',
282
            'label' => 'AccountDetails.article',
283
            'model' => 'Backpack\CRUD\Tests\Config\Models\Article',
284
            'key' => 'accountDetails__article',
285
            'tableColumn' => false,
286
            'orderable' => false,
287
            'searchLogic' => false,
288
            'priority' => 0,
289
            'relation_type' => 'BelongsTo',
290
            'attribute' => 'content',
291
        ],
292
        'ac_article_content' => [
293
            'name' => 'accountDetails.article',
294
            'type' => 'select',
295
            'entity' => 'accountDetails.article',
296
            'label' => 'AccountDetails.article',
297
            'model' => 'Backpack\CRUD\Tests\Config\Models\Article',
298
            'key' => 'ac_article_content',
299
            'tableColumn' => false,
300
            'orderable' => false,
301
            'searchLogic' => false,
302
            'priority' => 1,
303
            'relation_type' => 'BelongsTo',
304
            'attribute' => 'content',
305
        ],
306
    ];
307
308
    /**
309
     * Setup the test environment.
310
     *
311
     * @return void
312
     */
313
    protected function setUp(): void
314
    {
315
        parent::setUp();
316
317
        $this->crudPanel->setOperation('list');
318
    }
319
320
    public function testAddColumnByName()
321
    {
322
        $this->crudPanel->addColumn('column1');
323
324
        $this->assertEquals($this->expectedOneColumnArray, $this->crudPanel->columns());
325
    }
326
327
    public function testAddColumnsByName()
328
    {
329
        $this->crudPanel->addColumns(['column1', 'column2']);
330
331
        $this->assertEquals(2, count($this->crudPanel->columns()));
332
        $this->assertEquals($this->expectedTwoColumnsArray, $this->crudPanel->columns());
333
    }
334
335
    public function testAddColumnAsArray()
336
    {
337
        $this->crudPanel->addColumn($this->oneColumnArray);
338
339
        $this->assertEquals($this->expectedOneColumnArray, $this->crudPanel->columns());
340
    }
341
342
    public function testAddColumnsAsArray()
343
    {
344
        $this->crudPanel->addColumns($this->twoColumnsArray);
345
346
        $this->assertEquals(2, count($this->crudPanel->columns()));
347
        $this->assertEquals($this->expectedTwoColumnsArray, $this->crudPanel->columns());
348
    }
349
350
    public function testAddColumnNotArray()
351
    {
352
        $this->expectException(PHP_MAJOR_VERSION == 7 ? \ErrorException::class : \TypeError::class);
353
        // Why? When calling count() on a non-countable entity,
354
        // PHP 7.x will through ErrorException, but PHP 8.x will throw TypeError.
355
356
        $this->crudPanel->addColumns('column1');
0 ignored issues
show
Bug introduced by
'column1' of type string is incompatible with the type array expected by parameter $columns of Backpack\CRUD\app\Librar...CrudPanel::addColumns(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

356
        $this->crudPanel->addColumns(/** @scrutinizer ignore-type */ 'column1');
Loading history...
357
    }
358
359
    public function testAddRelationsByName()
360
    {
361
        $this->crudPanel->setModel(User::class);
362
        $this->crudPanel->addColumn('accountDetails');
363
        $this->crudPanel->addColumn('accountDetails.nickname');
364
        $this->crudPanel->addColumn('accountDetails.user');
365
366
        if (backpack_pro()) {
367
            $this->assertEquals($this->expectedRelationColumnsArrayWithPro, $this->crudPanel->columns());
368
        } else {
369
            $this->assertEquals($this->expectedRelationColumnsArrayWithoutPro, $this->crudPanel->columns());
370
        }
371
    }
372
373
    public function testAddRelationByNameWithMutator()
374
    {
375
        $this->crudPanel->setModel(User::class);
376
        $this->crudPanel->addColumn('accountDetails.nicknamutator');
377
        if (backpack_pro()) {
378
            $this->assertEquals(['accountDetails__nicknamutator' => [
379
                'name' => 'accountDetails.nicknamutator',
380
                'label' => 'AccountDetails.nicknamutator',
381
                'type' => 'relationship',
382
                'key' => 'accountDetails__nicknamutator',
383
                'priority' => 0,
384
                'attribute' => 'nicknamutator',
385
                'tableColumn' => false,
386
                'orderable' => false,
387
                'searchLogic' => false,
388
                'relation_type' => 'HasOne',
389
                'entity' => 'accountDetails.nicknamutator',
390
                'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
391
            ]], $this->crudPanel->columns());
392
        } else {
393
            $this->assertEquals(['accountDetails__nicknamutator' => [
394
                'name' => 'accountDetails.nicknamutator',
395
                'label' => 'AccountDetails.nicknamutator',
396
                'type' => 'text',
397
                'key' => 'accountDetails__nicknamutator',
398
                'priority' => 0,
399
                'attribute' => 'nicknamutator',
400
                'tableColumn' => false,
401
                'orderable' => false,
402
                'searchLogic' => false,
403
                'relation_type' => 'HasOne',
404
                'entity' => 'accountDetails.nicknamutator',
405
                'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
406
            ]], $this->crudPanel->columns());
407
        }
408
    }
409
410
    public function testAddRelationColumn()
411
    {
412
        $this->crudPanel->setModel(User::class);
413
        $this->crudPanel->addColumn($this->relationColumnArray);
414
415
        $this->assertEquals($this->expectedRelationColumnArray, $this->crudPanel->columns());
416
    }
417
418
    public function testAddNestedRelationColumn()
419
    {
420
        $this->crudPanel->setModel(User::class);
421
        $this->crudPanel->addColumn($this->nestedRelationColumnArray);
422
        $this->crudPanel->addColumn($this->secondNestedRelationColumnArray);
423
424
        if (backpack_pro()) {
425
            $this->assertEquals($this->expectedNestedRelationColumnArrayWithPro, $this->crudPanel->columns());
426
        } else {
427
            $this->assertEquals($this->expectedNestedRelationColumnArrayWithoutPro, $this->crudPanel->columns());
428
        }
429
    }
430
431
    public function testMoveColumnBefore()
432
    {
433
        $this->crudPanel->addColumns($this->twoColumnsArray);
434
435
        $this->crudPanel->beforeColumn('column1');
436
437
        $keys = array_keys($this->crudPanel->columns());
438
        $expected = $this->expectedTwoColumnsArray['column2'];
439
        $expected['priority'] = 0;
440
        $this->assertEquals($expected, $this->crudPanel->columns()[$keys[0]]);
441
        $this->assertEquals(['column2', 'column1'], $keys);
442
    }
443
444
    public function testItDoesNotChangeThePriorityIfDeveloperDefinedIt()
445
    {
446
        $this->crudPanel->addColumn('column1');
447
        $this->crudPanel->addColumn(['name' => 'column2', 'priority' => 5])->beforeColumn('column1');
448
        $this->assertEquals(5, $this->crudPanel->firstColumnWhere('name', 'column2')['priority']);
449
    }
450
451
    public function testMoveColumnBeforeUnknownColumnName()
452
    {
453
        $this->crudPanel->addColumns($this->twoColumnsArray);
454
455
        $this->crudPanel->beforeColumn('column3');
456
457
        $this->assertEquals(array_keys($this->expectedTwoColumnsArray), array_keys($this->crudPanel->columns()));
458
    }
459
460
    public function testMoveColumnAfter()
461
    {
462
        $this->crudPanel->addColumns($this->threeColumnsArray);
463
464
        $this->crudPanel->afterColumn('column1');
465
466
        $keys = array_keys($this->crudPanel->columns());
467
        $expected = $this->expectedThreeColumnsArray['column3'];
468
        $expected['priority'] = 1;
469
        $this->assertEquals($expected, $this->crudPanel->columns()[$keys[1]]);
470
        $this->assertEquals(['column1', 'column3', 'column2'], $keys);
471
    }
472
473
    public function testMoveColumnAfterUnknownColumnName()
474
    {
475
        $this->crudPanel->addColumns($this->twoColumnsArray);
476
477
        $this->crudPanel->afterColumn('column3');
478
479
        $this->assertEquals(array_keys($this->expectedTwoColumnsArray), array_keys($this->crudPanel->columns()));
480
    }
481
482
    public function testRemoveColumnByName()
483
    {
484
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
485
486
        $this->crudPanel->removeColumn('column1');
487
488
        $this->assertEquals(2, count($this->crudPanel->columns()));
489
        $this->assertEquals(['column2', 'column3'], array_keys($this->crudPanel->columns()));
490
        $this->assertNotContains($this->oneColumnArray, $this->crudPanel->columns());
491
    }
492
493
    public function testItCanRemoveAllColumns()
494
    {
495
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
496
497
        $this->crudPanel->removeAllColumns();
498
499
        $this->assertEmpty($this->crudPanel->columns());
500
    }
501
502
    public function testItCanSetColumnDetails()
503
    {
504
        $this->crudPanel->addColumns(['column1', 'column2', 'column3', 'column4', 'column5']);
505
506
        $this->crudPanel->setColumnsDetails(['column1', 'column2'], ['label' => 'New Label']);
507
        $this->crudPanel->setColumnDetails('column3', ['label' => 'Old Label']);
508
        $this->crudPanel->modifyColumn('column4', ['label' => 'Alias Label']);
509
        $this->crudPanel->setColumnLabel('column5', 'Setting Label');
510
511
        $this->assertEquals('New Label', $this->crudPanel->columns()['column1']['label']);
512
        $this->assertEquals('New Label', $this->crudPanel->columns()['column2']['label']);
513
        $this->assertEquals('Old Label', $this->crudPanel->columns()['column3']['label']);
514
        $this->assertEquals('Alias Label', $this->crudPanel->columns()['column4']['label']);
515
        $this->assertEquals('Setting Label', $this->crudPanel->columns()['column5']['label']);
516
    }
517
518
    public function testItCanFindAColumnById()
519
    {
520
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
521
522
        $column = $this->crudPanel->findColumnById(1);
523
524
        $this->assertEquals('column2', $column['name']);
525
    }
526
527
    public function testItCanGetAndSetActionsColumnPriority()
528
    {
529
        $this->assertEquals(1, $this->crudPanel->getActionsColumnPriority());
530
        $this->crudPanel->setActionsColumnPriority(2);
531
        $this->assertEquals(2, $this->crudPanel->getActionsColumnPriority());
532
    }
533
534
    public function testItCanGetAndSetColumnsRemovingPreviouslySet()
535
    {
536
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
537
538
        $this->crudPanel->setColumns('column4');
539
540
        $this->assertEquals(1, count($this->crudPanel->columns()));
541
        $this->assertEquals(['column4'], array_keys($this->crudPanel->columns()));
542
543
        $this->crudPanel->setColumns(['column5', 'column6']);
544
        $this->assertEquals(2, count($this->crudPanel->columns()));
545
        $this->assertEquals(['column5', 'column6'], array_keys($this->crudPanel->columns()));
546
547
        $this->crudPanel->setColumns(['column7', [
548
            'name' => 'column8',
549
        ]]);
550
        $this->assertEquals(2, count($this->crudPanel->columns()));
551
        $this->assertEquals(['column7', 'column8'], array_keys($this->crudPanel->columns()));
552
    }
553
554
    public function testRemoveUnknownColumnName()
555
    {
556
        $unknownColumnName = 'column4';
557
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
558
559
        $this->crudPanel->removeColumn($unknownColumnName);
560
561
        $this->assertEquals(3, count($this->crudPanel->columns()));
562
        $this->assertEquals(['column1', 'column2', 'column3'], array_keys($this->crudPanel->columns()));
563
        $this->assertNotContains($this->otherOneColumnArray, $this->crudPanel->columns());
564
    }
565
566
    public function testRemoveColumnsByName()
567
    {
568
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
569
570
        $this->crudPanel->removeColumns($this->twoColumnsArray);
571
572
        $this->assertEquals(1, count($this->crudPanel->columns()));
573
        $this->assertEquals(['column3'], array_keys($this->crudPanel->columns()));
574
        $this->assertNotEquals($this->expectedThreeColumnsArray, $this->crudPanel->columns());
575
    }
576
577
    public function testRemoveUnknownColumnsByName()
578
    {
579
        $unknownColumnNames = ['column4', 'column5'];
580
        $this->crudPanel->addColumns(['column1', 'column2', 'column3']);
581
582
        $this->crudPanel->removeColumns($unknownColumnNames);
583
584
        $this->assertEquals(3, count($this->crudPanel->columns()));
585
        $this->assertEquals(['column1', 'column2', 'column3'], array_keys($this->crudPanel->columns()));
586
        $this->assertNotContains($this->otherOneColumnArray, $this->crudPanel->columns());
587
    }
588
589
    public function testItThrowsAnErrorWhenAttemptingToChangeTheKeyInAColumnWithoutName()
590
    {
591
        $this->expectException(\Exception::class);
592
        $this->crudPanel->addColumn(['type' => 'text'])->key('new_key');
593
    }
594
595
    public function itCanSetTheUploadAttributeOnColumn()
596
    {
597
        $this->crudPanel->addColumn('column1')->upload();
598
599
        $this->assertEquals(true, $this->crudPanel->columns()['column1']['upload']);
600
    }
601
602
    public function testOrderColumns()
603
    {
604
        $this->crudPanel->addColumns($this->threeColumnsArray);
605
606
        $this->crudPanel->orderColumns(['column2', 'column1', 'column3']);
607
608
        $this->assertEquals(['column2', 'column1', 'column3'], array_keys($this->crudPanel->columns()));
609
    }
610
611
    public function testOrderColumnsIncompleteList()
612
    {
613
        $this->crudPanel->addColumns($this->threeColumnsArray);
614
615
        $this->crudPanel->orderColumns(['column2', 'column3']);
616
617
        $this->assertEquals(['column2', 'column3', 'column1'], array_keys($this->crudPanel->columns()));
618
    }
619
620
    public function testOrderColumnsEmptyList()
621
    {
622
        $this->crudPanel->addColumns($this->threeColumnsArray);
623
624
        $this->crudPanel->orderColumns([]);
625
626
        $this->assertEquals($this->expectedThreeColumnsArray, $this->crudPanel->columns());
627
    }
628
629
    public function testOrderColumnsUnknownList()
630
    {
631
        $this->crudPanel->addColumns($this->threeColumnsArray);
632
633
        $this->crudPanel->orderColumns(['column4', 'column5', 'column6']);
634
635
        $this->assertEquals($this->expectedThreeColumnsArray, $this->crudPanel->columns());
636
    }
637
638
    public function testOrderColumnsMixedList()
639
    {
640
        $this->crudPanel->addColumns($this->threeColumnsArray);
641
642
        $this->crudPanel->orderColumns(['column2', 'column5', 'column6']);
643
644
        $this->assertEquals(['column2', 'column1', 'column3'], array_keys($this->crudPanel->columns()));
645
    }
646
647
    public function testItDoesNotAttemptToGetEntityWhenColumnNameIsArray()
648
    {
649
        $this->crudPanel->addColumn(['name' => ['test1', 'test2'], 'label' => 'Column1', 'type' => 'text', 'key' => 'column1']);
650
        $this->assertArrayNotHasKey('entity', $this->crudPanel->firstColumnWhere('key', 'column1'));
0 ignored issues
show
Bug introduced by
$this->crudPanel->firstC...Where('key', 'column1') of type boolean is incompatible with the type ArrayAccess|array expected by parameter $array of PHPUnit\Framework\Assert::assertArrayNotHasKey(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

650
        $this->assertArrayNotHasKey('entity', /** @scrutinizer ignore-type */ $this->crudPanel->firstColumnWhere('key', 'column1'));
Loading history...
651
    }
652
653
    public function testItCanInferTheEntityFromColumnNameUsingEntity_idConvention()
654
    {
655
        $this->crudPanel->addColumn('article_id');
656
657
        $this->assertEquals('article', $this->crudPanel->firstColumnWhere('name', 'article_id')['entity']);
658
    }
659
660
    public function testItAlwaysHasDatabaseColumnWhenDriverIsNotSql()
661
    {
662
        $this->crudPanel = new \Backpack\CRUD\Tests\config\CrudPanel\NoSqlDriverCrudPanel();
663
        $this->crudPanel->setModel(User::class);
664
665
        $this->assertTrue($this->invokeMethod($this->crudPanel, 'hasDatabaseColumn', ['test', 'test']));
666
    }
667
668
    public function testItCanGetTheColumnTypeFromModelCasts()
669
    {
670
        $this->crudPanel->addColumn('arrayCast');
671
        $this->crudPanel->addColumn('jsonCast');
672
        $this->crudPanel->addColumn('dateCast');
673
        $this->crudPanel->addColumn('booleanCast');
674
        $this->crudPanel->addColumn('datetimeCast');
675
        $this->crudPanel->addColumn('numberCast');
676
677
        $this->assertEquals('array', $this->crudPanel->firstColumnWhere('name', 'arrayCast')['type']);
678
        $this->assertEquals('json', $this->crudPanel->firstColumnWhere('name', 'jsonCast')['type']);
679
        $this->assertEquals('date', $this->crudPanel->firstColumnWhere('name', 'dateCast')['type']);
680
        $this->assertEquals('check', $this->crudPanel->firstColumnWhere('name', 'booleanCast')['type']);
681
        $this->assertEquals('datetime', $this->crudPanel->firstColumnWhere('name', 'datetimeCast')['type']);
682
        $this->assertEquals('number', $this->crudPanel->firstColumnWhere('name', 'numberCast')['type']);
683
    }
684
685
    public function testItCanGetTheColumnTypeFromModelDates()
686
    {
687
        $this->crudPanel->addColumn('created_at');
688
689
        $this->assertEquals('datetime', $this->crudPanel->firstColumnWhere('name', 'created_at')['type']);
690
    }
691
692
    public function testMakeFirstColumnReturnFalseWhenNoColumnsExist()
693
    {
694
        $this->assertEmpty($this->crudPanel->columns());
695
        $column = $this->crudPanel->makeFirstColumn();
696
        $this->assertFalse($column);
697
    }
698
699
    public function testItSetsTextColumnTypeForTranslatableColumns()
700
    {
701
        $this->crudPanel->setModel(\Backpack\CRUD\Tests\config\Models\TestModelWithTranslations::class);
702
        $this->crudPanel->addColumn('translatableColumn');
703
704
        $this->assertEquals('text', $this->crudPanel->firstColumnWhere('name', 'translatableColumn')['type']);
705
    }
706
707
    public function testItCanAddADefaultTypeToTheColumn()
708
    {
709
        $column = $this->crudPanel->addDefaultTypeToColumn(['name' => 'name']);
710
711
        $this->assertEquals('text', $column['type']);
712
    }
713
714
    public function testItReturnFalseWhenTryingToAddTypeToAColumnWithoutName()
715
    {
716
        $column = $this->crudPanel->addDefaultTypeToColumn(['attribute' => 'name']);
717
718
        $this->assertFalse($column);
719
    }
720
721
    public function testItCanChangeTheColumnKey()
722
    {
723
        $this->crudPanel->column('test');
724
725
        $this->assertEquals('test', $this->crudPanel->columns()['test']['key']);
726
727
        $this->crudPanel->column('test')->key('new_key');
728
729
        $this->assertEquals('new_key', $this->crudPanel->columns()['new_key']['key']);
730
    }
731
732
    public function testItCanAddAFluentColumn()
733
    {
734
        $this->crudPanel->setModel(User::class);
735
736
        $this->crudPanel->column('my_column')->label('my_column');
737
738
        $this->assertCount(1, $this->crudPanel->columns());
739
740
        $this->assertEquals([
741
            'name' => 'my_column',
742
            'type' => 'text',
743
            'label' => 'my_column',
744
            'key' => 'my_column',
745
            'priority' => 0,
746
            'tableColumn' => false,
747
            'orderable' => false,
748
            'searchLogic' => false,
749
        ], $this->crudPanel->columns()['my_column']);
750
    }
751
752
    public function testItCanMakeAColumnFirstFluently()
753
    {
754
        $this->crudPanel->column('test1');
755
        $this->crudPanel->column('test2')->makeFirst();
756
        $crudColumns = $this->crudPanel->columns();
757
        $firstColumn = reset($crudColumns);
758
        $this->assertEquals($firstColumn['name'], 'test2');
759
    }
760
761
    public function testItCanMakeAColumnLastFluently()
762
    {
763
        $this->crudPanel->column('test1');
764
        $this->crudPanel->column('test2');
765
        $this->crudPanel->column('test1')->makeLast();
766
        $crudColumns = $this->crudPanel->columns();
767
        $firstColumn = reset($crudColumns);
768
        $this->assertEquals($firstColumn['name'], 'test2');
769
    }
770
771
    public function testItCanPlaceColumnsFluently()
772
    {
773
        $this->crudPanel->column('test1');
774
        $this->crudPanel->column('test2');
775
        $this->crudPanel->column('test3')->after('test1');
776
777
        $crudColumnsNames = array_column($this->crudPanel->columns(), 'name');
778
        $this->assertEquals($crudColumnsNames, ['test1', 'test3', 'test2']);
779
780
        $this->crudPanel->column('test4')->before('test1');
781
        $crudColumnsNames = array_column($this->crudPanel->columns(), 'name');
782
        $this->assertEquals($crudColumnsNames, ['test4', 'test1', 'test3', 'test2']);
783
784
        $this->crudPanel->column('test5')->afterColumn('test1');
785
        $crudColumnsNames = array_column($this->crudPanel->columns(), 'name');
786
        $this->assertEquals($crudColumnsNames, ['test4', 'test1', 'test5', 'test3', 'test2']);
787
    }
788
789
    public function testItCanRemoveColumnAttributesFluently()
790
    {
791
        $this->crudPanel->column('test1')->type('test');
792
        $this->assertEquals($this->crudPanel->columns()['test1']['type'], 'test');
793
        $this->crudPanel->column('test1')->forget('type');
794
        $this->assertNull($this->crudPanel->columns()['test1']['type'] ?? null);
795
    }
796
797
    public function testItCanRemoveColumnFluently()
798
    {
799
        $this->crudPanel->column('test1')->type('test');
800
        $this->assertCount(1, $this->crudPanel->columns());
801
        $this->crudPanel->column('test1')->remove();
802
        $this->assertCount(0, $this->crudPanel->columns());
803
    }
804
805
    public function testItCanAddAColumnToCrudFromClass()
806
    {
807
        CrudColumn::name('test');
808
        $this->assertCount(1, $this->crudPanel->columns());
809
    }
810
811
    public function testItCanAddAFluentColumnUsingArray()
812
    {
813
        $this->crudPanel->column($this->oneColumnArray);
814
        $this->assertCount(1, $this->crudPanel->columns());
815
    }
816
817
    public function testItCanAddAFluentColumnUsingArrayWithoutName()
818
    {
819
        $this->crudPanel->column(['type' => 'text']);
820
        $this->assertCount(1, $this->crudPanel->columns());
821
    }
822
823
    public function testColumnLinkToThrowsExceptionWhenNotAllRequiredParametersAreFilled()
824
    {
825
        $this->expectException(\Exception::class);
826
        $this->expectExceptionMessage('Route [article.show.detail] expects parameters [id, detail]. Insufficient parameters provided in column: [articles].');
827
        $this->crudPanel->column('articles')->entity('articles')->linkTo('article.show.detail', ['test' => 'testing']);
0 ignored issues
show
Bug introduced by
The method entity() does not exist on Backpack\CRUD\app\Library\CrudPanel\CrudColumn. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

827
        $this->crudPanel->column('articles')->/** @scrutinizer ignore-call */ entity('articles')->linkTo('article.show.detail', ['test' => 'testing']);
Loading history...
828
    }
829
830
    public function testItThrowsExceptionIfRouteNotFound()
831
    {
832
        $this->expectException(\Exception::class);
833
        $this->expectExceptionMessage('Route [users.route.doesnt.exist] not found while building the link for column [id].');
834
835
        CrudColumn::name('id')->linkTo('users.route.doesnt.exist')->toArray();
0 ignored issues
show
Bug introduced by
The method toArray() does not exist on Backpack\CRUD\app\Library\CrudPanel\CrudColumn. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

835
        CrudColumn::name('id')->linkTo('users.route.doesnt.exist')->/** @scrutinizer ignore-call */ toArray();
Loading history...
836
    }
837
838
    public function testColumnLinkToWithRouteNameOnly()
839
    {
840
        $this->crudPanel->column('articles')->entity('articles')->linkTo('articles.show');
841
        $columnArray = $this->crudPanel->columns()['articles'];
842
        $reflection = new \ReflectionFunction($columnArray['wrapper']['href']);
843
        $arguments = $reflection->getClosureUsedVariables();
0 ignored issues
show
Bug introduced by
The method getClosureUsedVariables() does not exist on ReflectionFunction. Did you maybe mean getClosure()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

843
        /** @scrutinizer ignore-call */ 
844
        $arguments = $reflection->getClosureUsedVariables();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
844
        $this->crudPanel->entry = $this->makeAnArticleModel();
845
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
846
        $this->assertEquals('articles.show', $arguments['route']);
847
        $this->assertCount(1, $arguments['parameters']);
848
        $this->assertEquals('http://localhost/admin/articles/1/show', $url);
849
    }
850
851
    public function testColumnLinkToWithRouteNameAndAdditionalParameters()
852
    {
853
        $this->crudPanel->column('articles')->entity('articles')->linkTo('articles.show', ['test' => 'testing', 'test2' => 'testing2']);
854
        $columnArray = $this->crudPanel->columns()['articles'];
855
        $reflection = new \ReflectionFunction($columnArray['wrapper']['href']);
856
        $arguments = $reflection->getClosureUsedVariables();
857
        $this->assertEquals('articles.show', $arguments['route']);
858
        $this->assertCount(3, $arguments['parameters']);
859
        $this->crudPanel->entry = $this->makeAnArticleModel();
860
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
861
        $this->assertEquals('http://localhost/admin/articles/1/show?test=testing&test2=testing2', $url);
862
    }
863
864
    public function testColumnLinkToWithCustomParameters()
865
    {
866
        $this->crudPanel->column('articles')->entity('articles')->linkTo('article.show.detail', ['detail' => 'testing', 'otherParam' => 'test']);
867
        $columnArray = $this->crudPanel->columns()['articles'];
868
        $this->crudPanel->entry = $this->makeAnArticleModel();
869
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
870
        $this->assertEquals('http://localhost/admin/articles/1/show/testing?otherParam=test', $url);
871
    }
872
873
    public function testColumnLinkToWithCustomClosureParameters()
874
    {
875
        $this->crudPanel->column('articles')
876
                        ->entity('articles')
877
                        ->linkTo('article.show.detail', ['detail' => fn ($entry, $related_key) => $related_key, 'otherParam' => fn ($entry) => $entry->content]);
878
        $columnArray = $this->crudPanel->columns()['articles'];
879
        $this->crudPanel->entry = $this->makeAnArticleModel();
880
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
881
        $this->assertEquals('http://localhost/admin/articles/1/show/1?otherParam=Some%20Content', $url);
882
    }
883
884
    public function testColumnLinkToDontAutoInferParametersIfAllProvided()
885
    {
886
        $this->crudPanel->column('articles')
887
                        ->entity('articles')
888
                        ->linkTo('article.show.detail', ['id' => 123, 'detail' => fn ($entry, $related_key) => $related_key, 'otherParam' => fn ($entry) => $entry->content]);
889
        $columnArray = $this->crudPanel->columns()['articles'];
890
        $this->crudPanel->entry = $this->makeAnArticleModel();
891
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
892
        $this->assertEquals('http://localhost/admin/articles/123/show/1?otherParam=Some%20Content', $url);
893
    }
894
895
    public function testColumnLinkToAutoInferAnySingleParameter()
896
    {
897
        $this->crudPanel->column('articles')
898
                        ->entity('articles')
899
                        ->linkTo('article.show.detail', ['id' => 123, 'otherParam' => fn ($entry) => $entry->content]);
900
        $columnArray = $this->crudPanel->columns()['articles'];
901
        $this->crudPanel->entry = $this->makeAnArticleModel();
902
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
903
        $this->assertEquals('http://localhost/admin/articles/123/show/1?otherParam=Some%20Content', $url);
904
    }
905
906
    public function testColumnLinkToWithClosure()
907
    {
908
        $this->crudPanel->column('articles')
909
                        ->entity('articles')
910
                        ->linkTo(fn ($entry) => route('articles.show', $entry->content));
0 ignored issues
show
Bug introduced by
function(...) { /* ... */ } of type callable is incompatible with the type string expected by parameter $routeName of Backpack\CRUD\app\Librar...el\CrudColumn::linkTo(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

910
                        ->linkTo(/** @scrutinizer ignore-type */ fn ($entry) => route('articles.show', $entry->content));
Loading history...
911
        $columnArray = $this->crudPanel->columns()['articles'];
912
        $this->crudPanel->entry = $this->makeAnArticleModel();
913
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
914
        $this->assertEquals('http://localhost/admin/articles/Some%20Content/show', $url);
915
    }
916
917
    public function testColumnArrayDefinitionLinkToRouteAsClosure()
918
    {
919
        $this->crudPanel->setModel(User::class);
920
        $this->crudPanel->column([
921
            'name' => 'articles',
922
            'entity' => 'articles',
923
            'linkTo' => fn ($entry) => route('articles.show', ['id' => $entry->id, 'test' => 'testing']),
924
        ]);
925
        $columnArray = $this->crudPanel->columns()['articles'];
926
        $this->crudPanel->entry = $this->makeAnArticleModel();
927
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
928
        $this->assertEquals('http://localhost/admin/articles/1/show?test=testing', $url);
929
    }
930
931
    public function testColumnArrayDefinitionLinkToRouteNameOnly()
932
    {
933
        $this->crudPanel->setModel(User::class);
934
        $this->crudPanel->column([
935
            'name' => 'articles',
936
            'entity' => 'articles',
937
            'linkTo' => 'articles.show',
938
        ]);
939
        $columnArray = $this->crudPanel->columns()['articles'];
940
        $this->crudPanel->entry = $this->makeAnArticleModel();
941
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
942
        $this->assertEquals('http://localhost/admin/articles/1/show', $url);
943
    }
944
945
    public function testColumnArrayDefinitionLinkToRouteNameAndAdditionalParameters()
946
    {
947
        $this->crudPanel->setModel(User::class);
948
        $this->crudPanel->column([
949
            'name' => 'articles',
950
            'entity' => 'articles',
951
            'linkTo' => [
952
                'route' => 'articles.show',
953
                'parameters' => [
954
                    'test' => 'testing',
955
                    'test2' => fn ($entry) => $entry->content,
956
                ],
957
            ],
958
        ]);
959
        $columnArray = $this->crudPanel->columns()['articles'];
960
        $reflection = new \ReflectionFunction($columnArray['wrapper']['href']);
961
        $arguments = $reflection->getClosureUsedVariables();
962
        $this->assertEquals('articles.show', $arguments['route']);
963
        $this->assertCount(3, $arguments['parameters']);
964
        $this->crudPanel->entry = $this->makeAnArticleModel();
965
        $url = $columnArray['wrapper']['href']($this->crudPanel, $columnArray, $this->crudPanel->entry, 1);
966
        $this->assertEquals('http://localhost/admin/articles/1/show?test=testing&test2=Some%20Content', $url);
967
    }
968
969
    public function testItCanInferFieldAttributesFromADynamicRelation()
970
    {
971
        User::resolveRelationUsing('dynamicRelation', function ($user) {
972
            return $user->belongsTo(\Backpack\CRUD\Tests\config\Models\Bang::class);
973
        });
974
975
        $this->crudPanel->setModel(User::class);
976
        $this->crudPanel->addColumn('dynamicRelation');
977
978
        $column = $this->crudPanel->columns()['dynamicRelation'];
979
980
        $this->assertEquals('dynamicRelation', $column['name']);
981
        $this->assertEquals('name', $column['attribute']);
982
        $this->assertEquals('relationship', $column['type']);
983
        $this->assertEquals('BelongsTo', $column['relation_type']);
984
    }
985
}
986