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

CrudPanelFieldsTest::testOrderFieldsUpdateForm()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\Tests\Unit\CrudPanel;
4
5
use Arr;
6
use Backpack\CRUD\app\Library\CrudPanel\CrudField;
7
use Backpack\CRUD\Tests\config\CrudPanel\BaseCrudPanel;
8
use Backpack\CRUD\Tests\config\Models\Star;
9
use Backpack\CRUD\Tests\config\Models\User;
10
use Illuminate\Http\Request;
11
12
/**
13
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\Fields
14
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\FieldsProtectedMethods
15
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\FieldsPrivateMethods
16
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\Input
17
 * @covers Backpack\CRUD\app\Library\CrudPanel\CrudField
18
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\Input
19
 * @covers Backpack\CRUD\app\Library\CrudPanel\Traits\Views
20
 */
21
class CrudPanelFieldsTest extends BaseCrudPanel
22
{
23
    private $oneTextFieldArray = [
24
        'name' => 'field1',
25
        'label' => 'Field1',
26
        'type' => 'text',
27
    ];
28
29
    private $expectedOneTextFieldArray = [
30
        'field1' => [
31
            'name' => 'field1',
32
            'label' => 'Field1',
33
            'type' => 'text',
34
            'entity' => false,
35
        ],
36
    ];
37
38
    private $unknownFieldTypeArray = [
39
        'name' => 'field1',
40
        'type' => 'unknownType',
41
    ];
42
43
    private $invalidTwoFieldsArray = [
44
        [
45
            'keyOne' => 'field1',
46
            'keyTwo' => 'Field1',
47
        ],
48
        [
49
            'otherKey' => 'field2',
50
        ],
51
    ];
52
53
    private $twoTextFieldsArray = [
54
        [
55
            'name' => 'field1',
56
            'label' => 'Field1',
57
            'type' => 'text',
58
        ],
59
        [
60
            'name' => 'field2',
61
            'label' => 'Field2',
62
        ],
63
    ];
64
65
    private $expectedTwoTextFieldsArray = [
0 ignored issues
show
introduced by
The private property $expectedTwoTextFieldsArray is not used, and could be removed.
Loading history...
66
        'field1' => [
67
            'name' => 'field1',
68
            'label' => 'Field1',
69
            'type' => 'text',
70
            'entity' => false,
71
        ],
72
        'field2' => [
73
            'name' => 'field2',
74
            'label' => 'Field2',
75
            'type' => 'text',
76
            'entity' => false,
77
        ],
78
    ];
79
80
    private $threeTextFieldsArray = [
81
        [
82
            'name' => 'field1',
83
            'label' => 'Field1',
84
            'type' => 'text',
85
        ],
86
        [
87
            'name' => 'field2',
88
            'label' => 'Field2',
89
        ],
90
        [
91
            'name' => 'field3',
92
        ],
93
    ];
94
95
    private $expectedThreeTextFieldsArray = [
96
        'field1' => [
97
            'name' => 'field1',
98
            'label' => 'Field1',
99
            'type' => 'text',
100
            'entity' => false,
101
        ],
102
        'field2' => [
103
            'name' => 'field2',
104
            'label' => 'Field2',
105
            'type' => 'text',
106
            'entity' => false,
107
        ],
108
        'field3' => [
109
            'name' => 'field3',
110
            'label' => 'Field3',
111
            'type' => 'text',
112
            'entity' => false,
113
        ],
114
    ];
115
116
    private $multipleFieldTypesArray = [
117
        [
118
            'name' => 'field1',
119
            'label' => 'Field1',
120
        ],
121
        [
122
            'name' => 'field2',
123
            'type' => 'address',
124
        ],
125
        [
126
            'name' => 'field3',
127
            'type' => 'address',
128
        ],
129
        [
130
            'name' => 'field4',
131
            'type' => 'checkbox',
132
        ],
133
        [
134
            'name' => 'field5',
135
            'type' => 'date',
136
        ],
137
        [
138
            'name' => 'field6',
139
            'type' => 'email',
140
        ],
141
        [
142
            'name' => 'field7',
143
            'type' => 'hidden',
144
        ],
145
        [
146
            'name' => 'field8',
147
            'type' => 'password',
148
        ],
149
        [
150
            'name' => 'field9',
151
            'type' => 'select2',
152
        ],
153
        [
154
            'name' => 'field10',
155
            'type' => 'select2_multiple',
156
        ],
157
        [
158
            'name' => 'field11',
159
            'type' => 'table',
160
        ],
161
        [
162
            'name' => 'field12',
163
            'type' => 'url',
164
        ],
165
    ];
166
167
    private $expectedMultipleFieldTypesArray = [
168
        'field1' => [
169
            'name' => 'field1',
170
            'label' => 'Field1',
171
            'type' => 'text',
172
            'entity' => false,
173
        ],
174
        'field2' => [
175
            'name' => 'field2',
176
            'type' => 'address',
177
            'label' => 'Field2',
178
            'entity' => false,
179
        ],
180
        'field3' => [
181
            'name' => 'field3',
182
            'type' => 'address',
183
            'label' => 'Field3',
184
            'entity' => false,
185
        ],
186
        'field4' => [
187
            'name' => 'field4',
188
            'type' => 'checkbox',
189
            'label' => 'Field4',
190
            'entity' => false,
191
        ],
192
        'field5' => [
193
            'name' => 'field5',
194
            'type' => 'date',
195
            'label' => 'Field5',
196
            'entity' => false,
197
        ],
198
        'field6' => [
199
            'name' => 'field6',
200
            'type' => 'email',
201
            'label' => 'Field6',
202
            'entity' => false,
203
        ],
204
        'field7' => [
205
            'name' => 'field7',
206
            'type' => 'hidden',
207
            'label' => 'Field7',
208
            'entity' => false,
209
        ],
210
        'field8' => [
211
            'name' => 'field8',
212
            'type' => 'password',
213
            'label' => 'Field8',
214
            'entity' => false,
215
        ],
216
        'field9' => [
217
            'name' => 'field9',
218
            'type' => 'select2',
219
            'label' => 'Field9',
220
            'entity' => false,
221
        ],
222
        'field10' => [
223
            'name' => 'field10',
224
            'type' => 'select2_multiple',
225
            'label' => 'Field10',
226
            'entity' => false,
227
        ],
228
        'field11' => [
229
            'name' => 'field11',
230
            'type' => 'table',
231
            'label' => 'Field11',
232
            'entity' => false,
233
        ],
234
        'field12' => [
235
            'name' => 'field12',
236
            'type' => 'url',
237
            'label' => 'Field12',
238
            'entity' => false,
239
        ],
240
    ];
241
242
    /**
243
     * Setup the test environment.
244
     *
245
     * @return void
246
     */
247
    protected function setUp(): void
248
    {
249
        parent::setUp();
250
251
        $this->crudPanel->setOperation('create');
252
    }
253
254
    public function testAddFieldByName()
255
    {
256
        $this->crudPanel->addField('field1');
257
258
        $this->assertEquals(1, count($this->crudPanel->fields()));
259
        $this->assertEquals($this->expectedOneTextFieldArray, $this->crudPanel->fields());
260
    }
261
262
    public function testAddFieldsByName()
263
    {
264
        $this->crudPanel->addFields(['field1', 'field2', 'field3']);
265
266
        $this->assertEquals(3, count($this->crudPanel->fields()));
267
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
268
    }
269
270
    public function testAddFieldsAsArray()
271
    {
272
        $this->crudPanel->addFields($this->threeTextFieldsArray);
273
274
        $this->assertEquals(3, count($this->crudPanel->fields()));
275
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
276
    }
277
278
    public function testAddFieldsDifferentTypes()
279
    {
280
        $this->crudPanel->addFields($this->multipleFieldTypesArray);
281
282
        $this->assertEquals(12, count($this->crudPanel->fields()));
283
        $this->assertEquals($this->expectedMultipleFieldTypesArray, $this->crudPanel->fields());
284
    }
285
286
    public function testAddFieldsInvalidArray()
287
    {
288
        $this->expectException(\Exception::class);
289
290
        $this->crudPanel->addFields($this->invalidTwoFieldsArray);
291
    }
292
293
    public function testAddFieldWithInvalidType()
294
    {
295
        $this->markTestIncomplete('Not correctly implemented');
296
297
        // TODO: should we validate field types and throw an error if they're not in the pre-defined list of fields or
298
        //       in the list of custom field?
299
        $this->crudPanel->addFields($this->unknownFieldTypeArray);
300
    }
301
302
    public function testAddFieldsForCreateForm()
303
    {
304
        $this->crudPanel->addFields($this->threeTextFieldsArray, 'create');
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...\CrudPanel::addFields() has too many arguments starting with 'create'. ( Ignorable by Annotation )

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

304
        $this->crudPanel->/** @scrutinizer ignore-call */ 
305
                          addFields($this->threeTextFieldsArray, 'create');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
305
306
        $this->assertEquals(3, count($this->crudPanel->fields()));
307
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->getCreateFields());
308
    }
309
310
    public function testAddFieldsForUpdateForm()
311
    {
312
        $this->crudPanel->addFields($this->threeTextFieldsArray, 'update');
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...\CrudPanel::addFields() has too many arguments starting with 'update'. ( Ignorable by Annotation )

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

312
        $this->crudPanel->/** @scrutinizer ignore-call */ 
313
                          addFields($this->threeTextFieldsArray, 'update');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
313
314
        $this->assertEquals(3, count($this->crudPanel->fields()));
315
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
316
    }
317
318
    public function testBeforeField()
319
    {
320
        $this->crudPanel->addFields($this->threeTextFieldsArray);
321
        $this->crudPanel->beforeField('field2');
322
323
        $createKeys = array_keys($this->crudPanel->fields());
324
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[1]]);
325
        $this->assertEquals(['field1', 'field3', 'field2'], $createKeys);
326
    }
327
328
    public function testBeforeFieldFirstField()
329
    {
330
        $this->crudPanel->addFields($this->threeTextFieldsArray);
331
        $this->crudPanel->beforeField('field1');
332
333
        $createKeys = array_keys($this->crudPanel->fields());
334
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[0]]);
335
        $this->assertEquals(['field3', 'field1', 'field2'], $createKeys);
336
337
        $updateKeys = array_keys($this->crudPanel->fields());
338
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$updateKeys[0]]);
339
        $this->assertEquals(['field3', 'field1', 'field2'], $updateKeys);
340
    }
341
342
    public function testBeforeFieldLastField()
343
    {
344
        $this->crudPanel->addFields($this->threeTextFieldsArray);
345
        $this->crudPanel->beforeField('field3');
346
347
        $createKeys = array_keys($this->crudPanel->fields());
348
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[2]]);
349
        $this->assertEquals(['field1', 'field2', 'field3'], $createKeys);
350
    }
351
352
    public function testBeforeFieldCreateForm()
353
    {
354
        $this->crudPanel->addFields($this->threeTextFieldsArray);
355
        $this->crudPanel->beforeField('field1');
356
357
        $createKeys = array_keys($this->crudPanel->fields());
358
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[0]]);
359
        $this->assertEquals(['field3', 'field1', 'field2'], $createKeys);
360
    }
361
362
    public function testBeforeUnknownField()
363
    {
364
        $this->crudPanel->addFields($this->threeTextFieldsArray);
365
366
        $this->crudPanel->beforeField('field4');
367
368
        $this->assertEquals(3, count($this->crudPanel->fields()));
369
        $this->assertEquals(array_keys($this->expectedThreeTextFieldsArray), array_keys($this->crudPanel->fields()));
370
    }
371
372
    public function testAfterField()
373
    {
374
        $this->crudPanel->addFields($this->threeTextFieldsArray);
375
376
        $this->crudPanel->afterField('field1');
377
378
        $createKeys = array_keys($this->crudPanel->fields());
379
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[1]]);
380
        $this->assertEquals(['field1', 'field3', 'field2'], $createKeys);
381
382
        $updateKeys = array_keys($this->crudPanel->fields());
383
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$updateKeys[1]]);
384
        $this->assertEquals(['field1', 'field3', 'field2'], $updateKeys);
385
    }
386
387
    public function testAfterFieldLastField()
388
    {
389
        $this->crudPanel->addFields($this->threeTextFieldsArray);
390
391
        $this->crudPanel->afterField('field3');
392
393
        $createKeys = array_keys($this->crudPanel->fields());
394
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$createKeys[2]]);
395
        $this->assertEquals(['field1', 'field2', 'field3'], $createKeys);
396
397
        $updateKeys = array_keys($this->crudPanel->fields());
398
        $this->assertEquals($this->expectedThreeTextFieldsArray['field3'], $this->crudPanel->fields()[$updateKeys[2]]);
399
        $this->assertEquals(['field1', 'field2', 'field3'], $updateKeys);
400
    }
401
402
    public function testAfterFieldOnCertainField()
403
    {
404
        $this->crudPanel->addFields($this->threeTextFieldsArray);
405
        $this->crudPanel->addField('custom')->afterField('field1');
406
407
        $createKeys = array_keys($this->crudPanel->fields());
408
        $this->assertEquals(['field1', 'custom', 'field2', 'field3'], $createKeys);
409
    }
410
411
    public function testAfterUnknownField()
412
    {
413
        $this->crudPanel->addFields($this->threeTextFieldsArray);
414
415
        $this->crudPanel->afterField('field4');
416
417
        $this->assertEquals(3, count($this->crudPanel->fields()));
418
        $this->assertEquals(array_keys($this->expectedThreeTextFieldsArray), array_keys($this->crudPanel->fields()));
419
    }
420
421
    public function testRemoveFieldsByName()
422
    {
423
        $this->crudPanel->addFields($this->threeTextFieldsArray);
424
425
        $this->crudPanel->removeFields(['field1']);
426
427
        $this->assertEquals(2, count($this->crudPanel->fields()));
428
        $this->assertEquals(['field2', 'field3'], array_keys($this->crudPanel->fields()));
429
    }
430
431
    public function testRemoveFieldsByNameInvalidArray()
432
    {
433
        $this->markTestIncomplete('Not correctly implemented');
434
435
        $this->crudPanel->addFields($this->threeTextFieldsArray);
436
437
        // TODO: this should not work because the method specifically asks for an array of field keys, but it does
438
        //       because the removeField method will actually work with arrays instead of a string
439
        $this->crudPanel->removeFields($this->twoTextFieldsArray);
440
441
        $this->assertEquals(3, count($this->crudPanel->fields()));
442
        $this->assertEquals(array_keys($this->expectedThreeTextFieldsArray), array_keys($this->crudPanel->fields()));
443
    }
444
445
    public function testRemoveFieldsFromCreateForm()
446
    {
447
        $this->crudPanel->addFields($this->threeTextFieldsArray);
448
        $this->crudPanel->removeFields(['field1']);
449
450
        $this->assertEquals(2, count($this->crudPanel->fields()));
451
        $this->assertEquals(['field2', 'field3'], array_keys($this->crudPanel->fields()));
452
    }
453
454
    public function testRemoveFieldsFromUpdateForm()
455
    {
456
        $this->crudPanel->addFields($this->threeTextFieldsArray);
457
        $this->crudPanel->removeFields(['field1']);
458
459
        $this->assertEquals(2, count($this->crudPanel->fields()));
460
        $this->assertEquals(['field2', 'field3'], array_keys($this->crudPanel->fields()));
461
    }
462
463
    public function testRemoveUnknownFields()
464
    {
465
        $this->crudPanel->addFields($this->threeTextFieldsArray);
466
467
        $this->crudPanel->removeFields(['field4']);
468
469
        $this->assertEquals(3, count($this->crudPanel->fields()));
470
        $this->assertEquals(3, count($this->crudPanel->fields()));
471
        $this->assertEquals(array_keys($this->expectedThreeTextFieldsArray), array_keys($this->crudPanel->fields()));
472
        $this->assertEquals(array_keys($this->expectedThreeTextFieldsArray), array_keys($this->crudPanel->fields()));
473
    }
474
475
    public function testOrderFields()
476
    {
477
        $this->crudPanel->addFields($this->threeTextFieldsArray);
478
479
        $this->crudPanel->orderFields(['field2', 'field1', 'field3']);
480
481
        $this->assertEquals(['field2', 'field1', 'field3'], array_keys($this->crudPanel->fields()));
482
    }
483
484
    public function testOrderFieldsCreateForm()
485
    {
486
        $this->crudPanel->addFields($this->threeTextFieldsArray);
487
488
        $this->crudPanel->orderFields(['field2', 'field1', 'field3'], 'create');
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...rudPanel::orderFields() has too many arguments starting with 'create'. ( Ignorable by Annotation )

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

488
        $this->crudPanel->/** @scrutinizer ignore-call */ 
489
                          orderFields(['field2', 'field1', 'field3'], 'create');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
489
490
        $this->assertEquals(['field2', 'field1', 'field3'], array_keys($this->crudPanel->fields()));
491
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
492
    }
493
494
    public function testOrderFieldsUpdateForm()
495
    {
496
        $this->crudPanel->addFields($this->threeTextFieldsArray);
497
498
        $this->crudPanel->orderFields(['field2', 'field1', 'field3'], 'update');
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...rudPanel::orderFields() has too many arguments starting with 'update'. ( Ignorable by Annotation )

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

498
        $this->crudPanel->/** @scrutinizer ignore-call */ 
499
                          orderFields(['field2', 'field1', 'field3'], 'update');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
499
500
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
501
        $this->assertEquals(['field2', 'field1', 'field3'], array_keys($this->crudPanel->fields()));
502
    }
503
504
    public function testOrderFieldsIncompleteList()
505
    {
506
        $this->crudPanel->addFields($this->threeTextFieldsArray);
507
508
        $this->crudPanel->orderFields(['field2', 'field3']);
509
510
        $this->assertEquals(['field2', 'field3', 'field1'], array_keys($this->crudPanel->fields()));
511
    }
512
513
    public function testOrderFieldsEmptyList()
514
    {
515
        $this->crudPanel->addFields($this->threeTextFieldsArray);
516
517
        $this->crudPanel->orderFields([]);
518
519
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
520
    }
521
522
    public function testOrderFieldsUnknownList()
523
    {
524
        $this->crudPanel->addFields($this->threeTextFieldsArray);
525
526
        $this->crudPanel->orderFields(['field4', 'field5', 'field6']);
527
528
        $this->assertEquals($this->expectedThreeTextFieldsArray, $this->crudPanel->fields());
529
    }
530
531
    public function testOrderColumnsMixedList()
532
    {
533
        $this->crudPanel->addFields($this->threeTextFieldsArray);
534
535
        $this->crudPanel->orderFields(['field2', 'field5', 'field6']);
536
537
        $this->assertEquals(['field2', 'field1', 'field3'], array_keys($this->crudPanel->fields()));
538
    }
539
540
    public function testCheckIfFieldIsFirstOfItsType()
541
    {
542
        $this->crudPanel->addFields($this->multipleFieldTypesArray);
543
544
        $isFirstAddressFieldFirst = $this->crudPanel->checkIfFieldIsFirstOfItsType($this->multipleFieldTypesArray[1]);
545
        $isSecondAddressFieldFirst = $this->crudPanel->checkIfFieldIsFirstOfItsType($this->multipleFieldTypesArray[2]);
546
547
        $this->assertTrue($isFirstAddressFieldFirst);
548
        $this->assertFalse($isSecondAddressFieldFirst);
549
    }
550
551
    public function testCheckIfUnknownFieldIsFirstOfItsType()
552
    {
553
        $isUnknownFieldFirst = $this->crudPanel->checkIfFieldIsFirstOfItsType($this->unknownFieldTypeArray, $this->expectedMultipleFieldTypesArray);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...FieldIsFirstOfItsType() has too many arguments starting with $this->expectedMultipleFieldTypesArray. ( Ignorable by Annotation )

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

553
        /** @scrutinizer ignore-call */ 
554
        $isUnknownFieldFirst = $this->crudPanel->checkIfFieldIsFirstOfItsType($this->unknownFieldTypeArray, $this->expectedMultipleFieldTypesArray);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
554
555
        $this->assertFalse($isUnknownFieldFirst);
556
    }
557
558
    public function testCheckIfInvalidFieldIsFirstOfItsType()
559
    {
560
        $this->expectException(\ErrorException::class);
561
562
        $this->crudPanel->checkIfFieldIsFirstOfItsType($this->invalidTwoFieldsArray[0], $this->expectedMultipleFieldTypesArray);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...FieldIsFirstOfItsType() has too many arguments starting with $this->expectedMultipleFieldTypesArray. ( Ignorable by Annotation )

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

562
        $this->crudPanel->/** @scrutinizer ignore-call */ 
563
                          checkIfFieldIsFirstOfItsType($this->invalidTwoFieldsArray[0], $this->expectedMultipleFieldTypesArray);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
563
    }
564
565
    public function testDecodeJsonCastedAttributes()
566
    {
567
        $this->markTestIncomplete();
568
569
        // TODO: the decode JSON method should not be in fields trait and should not be exposed in the public API.
570
    }
571
572
    public function testFieldNameDotNotationIsRelationship()
573
    {
574
        $this->crudPanel->setModel(User::class);
575
        $this->crudPanel->addField('accountDetails.nickname');
576
        $fieldReadyForHtml = $this->crudPanel->fields()['accountDetails.nickname'];
577
        $fieldCleanState = $this->crudPanel->getCleanStateFields()['accountDetails.nickname'];
578
        $this->assertEquals(Arr::except($fieldReadyForHtml, ['name']), Arr::except($fieldCleanState, ['name']));
579
        $this->assertEquals($fieldCleanState['relation_type'], 'HasOne');
580
        $this->assertEquals($fieldReadyForHtml['name'], 'accountDetails[nickname]');
581
        $this->assertEquals($fieldCleanState['name'], 'accountDetails.nickname');
582
    }
583
584
    public function testFieldNameDotNotationIsRelationshipUsingFluentSynthax()
585
    {
586
        $this->crudPanel->setModel(User::class);
587
        $this->crudPanel->field('accountDetails.nickname')->label('custom label');
588
        $fieldReadyForHtml = $this->crudPanel->fields()['accountDetails.nickname'];
589
        $fieldCleanState = $this->crudPanel->getCleanStateFields()['accountDetails.nickname'];
590
        $this->assertEquals(Arr::except($fieldReadyForHtml, ['name']), Arr::except($fieldCleanState, ['name']));
591
        $this->assertEquals($fieldCleanState['relation_type'], 'HasOne');
592
        $this->assertEquals($fieldReadyForHtml['name'], 'accountDetails[nickname]');
593
        $this->assertEquals($fieldCleanState['name'], 'accountDetails.nickname');
594
    }
595
596
    public function testFieldNameIsRelationInCrudModel()
597
    {
598
        $this->crudPanel->setModel(User::class);
599
        $this->crudPanel->addField('roles');
600
        $field = $this->crudPanel->fields()['roles'];
601
        $this->assertEquals($field['relation_type'], 'BelongsToMany');
602
    }
603
604
    public function testFieldNameIsPartialRelationInCrudModel()
605
    {
606
        $this->crudPanel->setModel(User::class);
607
        $this->crudPanel->addField('articles_id');
608
        $field = $this->crudPanel->fields()['articles_id'];
609
        $this->assertEquals($field['relation_type'], 'HasMany');
610
    }
611
612
    public function testGetStrippedSaveRequestWithClosure()
613
    {
614
        $this->crudPanel->setOperationSetting(
615
            'strippedRequest',
616
            static function (Request $request) {
617
                return $request->toArray();
618
            },
619
            'update'
620
        );
621
        $this->crudPanel->setOperation('update');
622
        $this->crudPanel->setModel(User::class);
623
        $request = request()->create('/users/1/edit', 'POST', ['name' => 'john']);
624
        $result = $this->crudPanel->getStrippedSaveRequest($request);
625
        $this->assertIsArray($result);
626
        $this->assertSame(['name' => 'john'], $result);
627
    }
628
629
    public function testGetStrippedSaveRequestWithClass()
630
    {
631
        $this->crudPanel->setOperationSetting(
632
            'strippedRequest',
633
            Invokable::class,
634
            'update'
635
        );
636
        $this->crudPanel->setOperation('update');
637
        $this->crudPanel->setModel(User::class);
638
        $request = request()->create('/users/1/edit', 'POST', ['name' => 'john']);
639
        $result = $this->crudPanel->getStrippedSaveRequest($request);
640
        $this->assertIsArray($result);
641
        $this->assertSame(['invokable' => 'invokable'], $result);
642
    }
643
644
    public function testItDoesNotUseProtectedMethodsAsRelationshipMethods()
645
    {
646
        $this->crudPanel->setModel(User::class);
647
        $this->crudPanel->addField('isNotRelation');
648
        $this->crudPanel->addField('isNotRelationPublic');
649
650
        $this->assertEquals(false, $this->crudPanel->fields()['isNotRelation']['entity']);
651
        $this->assertEquals(false, $this->crudPanel->fields()['isNotRelationPublic']['entity']);
652
    }
653
654
    public function testItAbortsOnUnexpectedEntity()
655
    {
656
        try {
657
            $this->crudPanel->getRelationInstance(['name' => 'doesNotExist', 'entity' => 'doesNotExist']);
658
        } catch (\Throwable $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
659
        }
660
        $this->assertEquals(
661
            new \Symfony\Component\HttpKernel\Exception\HttpException(500, 'Looks like field <code>doesNotExist</code> is not properly defined. The <code>doesNotExist()</code> relationship doesn\'t seem to exist on the <code>Backpack\CRUD\Tests\config\Models\TestModel</code> model.', null, ['developer-error-exception']),
662
            $e
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $e does not seem to be defined for all execution paths leading up to this point.
Loading history...
663
        );
664
    }
665
666
    public function testItCanRemoveAllFields()
667
    {
668
        $this->crudPanel->addFields([
669
            ['name' => 'test1'],
670
            ['name' => 'test2'],
671
        ]);
672
673
        $this->assertCount(2, $this->crudPanel->fieldS());
674
        $this->crudPanel->removeAllFields();
675
        $this->assertCount(0, $this->crudPanel->fieldS());
676
    }
677
678
    public function testItCanRemoveAnAttributeFromAField()
679
    {
680
        $this->crudPanel->addField(['name' => 'test', 'tab' => 'test']);
681
682
        $this->assertEquals('test', $this->crudPanel->fieldS()['test']['tab']);
683
        $this->crudPanel->removeFieldAttribute('test', 'tab');
684
        $this->assertNull($this->crudPanel->fieldS()['test']['tab'] ?? null);
685
    }
686
687
    public function testItCanSetALabelForAField()
688
    {
689
        $this->crudPanel->addField(['name' => 'test', 'tab' => 'test']);
690
        $this->crudPanel->setFieldLabel('test', 'my-test-label');
691
        $this->assertEquals('my-test-label', $this->crudPanel->fieldS()['test']['label']);
692
    }
693
694
    public function testItCanMakeAFieldFirst()
695
    {
696
        $firstField = $this->crudPanel->addField(['name' => 'test1']);
0 ignored issues
show
Unused Code introduced by
The assignment to $firstField is dead and can be removed.
Loading history...
697
        $secondField = $this->crudPanel->addField(['name' => 'test2']);
698
        $this->assertEquals(['test1', 'test2'], array_keys($this->crudPanel->fields()));
699
        $secondField->makeFirstField();
700
        $this->assertEquals(['test2', 'test1'], array_keys($this->crudPanel->fields()));
701
    }
702
703
    public function testItCanGetTheCurrentFields()
704
    {
705
        $this->crudPanel->addField(['name' => 'test1']);
706
        $this->crudPanel->addField(['name' => 'test2']);
707
708
        $this->assertCount(2, $this->crudPanel->getCurrentFields());
709
        $this->assertCount(2, $this->crudPanel->getFields());
710
    }
711
712
    public function testItCanGetUploadFields()
713
    {
714
        $this->crudPanel->addField(['name' => 'test1', 'upload' => true]);
715
        $this->crudPanel->addField(['name' => 'test2']);
716
717
        $this->assertCount(2, $this->crudPanel->getFields());
718
        $this->assertTrue($this->crudPanel->hasUploadFields());
719
    }
720
721
    public function testItCanGetTheFieldTypeWithViewNamespace()
722
    {
723
        $this->crudPanel->addField(['name' => 'test', 'view_namespace' => 'test_namespace']);
724
        $this->assertEquals('test_namespace.text', $this->crudPanel->getFieldTypeWithNamespace($this->crudPanel->fields()['test']));
725
        $this->assertEquals('test', $this->crudPanel->getFieldTypeWithNamespace('test'));
726
    }
727
728
    public function testItCanGetAllFieldNames()
729
    {
730
        $this->crudPanel->addField(['name' => 'test1']);
731
        $this->crudPanel->addField(['name' => 'test2']);
732
        $this->assertEquals(['test1', 'test2'], $this->crudPanel->getAllFieldNames());
733
    }
734
735
    public function testItCanAddAFluentField()
736
    {
737
        $this->crudPanel->setModel(User::class);
738
739
        $this->crudPanel->field('my_field')
740
                        ->type('my_custom_type')
741
                        ->label('my_label')
742
                        ->tab('custom_tab')
743
                        ->prefix('prefix')
744
                        ->suffix('suffix')
745
                        ->hint('hinter')
746
                        ->fake(false)
747
                        ->validationRules('required|min:2')
748
                        ->validationMessages(['required' => 'is_required', 'min' => 'min_2'])
749
                        ->store_in('some')
750
                        ->size(6)
751
                        ->on('created', function () {
752
                        })
753
                        ->subfields([['name' => 'sub_1']])
754
                        ->entity('bang');
755
756
        $this->assertCount(1, $this->crudPanel->fields());
757
758
        $this->assertEquals([
759
            'name' => 'my_field',
760
            'type' => 'my_custom_type',
761
            'entity' => 'bang',
762
            'relation_type' => 'BelongsTo',
763
            'attribute' => 'name',
764
            'model' => 'Backpack\CRUD\Tests\Config\Models\Bang',
765
            'multiple' => false,
766
            'pivot' => false,
767
            'label' => 'my_label',
768
            'tab' => 'custom_tab',
769
            'suffix' => 'suffix',
770
            'prefix' => 'prefix',
771
            'hint' => 'hinter',
772
            'fake' => false,
773
            'validationRules' => 'required|min:2',
774
            'validationMessages' => [
775
                'required' => 'is_required',
776
                'min' => 'min_2',
777
            ],
778
            'store_in' => 'some',
779
            'wrapper' => [
780
                'class' => 'form-group col-md-6 mb-3',
781
            ],
782
            'events' => [
783
                'created' => function () {
784
                },
785
            ],
786
            'subfields' => [
787
                [
788
                    'name' => 'sub_1',
789
                    'parentFieldName' => 'my_field',
790
                    'type' => 'text',
791
                    'entity' => false,
792
                    'label' => 'Sub 1',
793
                    'baseFieldName' => 'sub_1',
794
                ],
795
            ],
796
797
        ], $this->crudPanel->fields()['my_field']);
798
    }
799
800
    public function testAddFieldFluentClassUsingArrayDefinition()
801
    {
802
        $this->crudPanel->field($this->oneTextFieldArray);
803
804
        $this->assertEquals(1, count($this->crudPanel->fields()));
805
        $this->assertEquals($this->expectedOneTextFieldArray, $this->crudPanel->fields());
806
    }
807
808
    public function testItCanFluentlyAddUploadAttribute()
809
    {
810
        $this->crudPanel->field('avatar')->upload();
811
        $this->assertEquals(true, $this->crudPanel->fields()['avatar']['upload']);
812
    }
813
814
    public function testItCanMakeAFieldFirstFluently()
815
    {
816
        $this->crudPanel->field('test1');
817
        $this->crudPanel->field('test2')->makeFirst();
818
        $crudFields = $this->crudPanel->fields();
819
        $firstField = reset($crudFields);
820
        $this->assertEquals($firstField['name'], 'test2');
821
    }
822
823
    public function testItCanMakeAFieldLastFluently()
824
    {
825
        $this->crudPanel->field('test1');
826
        $this->crudPanel->field('test2');
827
        $this->crudPanel->field('test1')->makeLast();
828
        $crudFields = $this->crudPanel->fields();
829
        $firstField = reset($crudFields);
830
        $this->assertEquals($firstField['name'], 'test2');
831
    }
832
833
    public function testItCanPlaceFieldsFluently()
834
    {
835
        $this->crudPanel->field('test1');
836
        $this->crudPanel->field('test2');
837
        $this->crudPanel->field('test3')->after('test1');
838
839
        $crudFieldsNames = array_column($this->crudPanel->fields(), 'name');
840
        $this->assertEquals($crudFieldsNames, ['test1', 'test3', 'test2']);
841
842
        $this->crudPanel->field('test4')->before('test1');
843
        $crudFieldsNames = array_column($this->crudPanel->fields(), 'name');
844
        $this->assertEquals($crudFieldsNames, ['test4', 'test1', 'test3', 'test2']);
845
    }
846
847
    public function testItCanRemoveFieldAttributesFluently()
848
    {
849
        $this->crudPanel->field('test1')->type('test');
850
        $this->assertEquals($this->crudPanel->fields()['test1']['type'], 'test');
851
        $this->crudPanel->field('test1')->forget('type');
852
        $this->assertNull($this->crudPanel->fields()['test1']['type'] ?? null);
853
    }
854
855
    public function testItCanRemoveFieldFluently()
856
    {
857
        $this->crudPanel->field('test1')->type('test');
858
        $this->assertCount(1, $this->crudPanel->fields());
859
        $this->crudPanel->field('test1')->remove();
860
        $this->assertCount(0, $this->crudPanel->fields());
861
    }
862
863
    public function testItCanAddMorphFieldsFluently()
864
    {
865
        $this->crudPanel->setModel(Star::class);
866
        $this->crudPanel->field('starable')
867
                        ->addMorphOption('Backpack\CRUD\Tests\config\Models\User', 'User')
868
                        ->morphTypeField(['attributes' => ['custom-attribute' => true]])
869
                        ->morphIdField(['attributes' => ['custom-attribute' => true]]);
870
871
        [$morphTypeField, $morphIdField] = $this->crudPanel->fields()['starable']['subfields'];
872
873
        $this->assertTrue($morphTypeField['attributes']['custom-attribute']);
874
        $this->assertTrue($morphIdField['attributes']['custom-attribute']);
875
    }
876
877
    public function testAbortsConfiguringNonMorphTypeField()
878
    {
879
        $this->crudPanel->setModel(Star::class);
880
        $this->expectException(\Exception::class);
881
        $this->crudPanel->field('some_field')
882
                        ->morphTypeField(['attributes' => ['custom-attribute' => true]]);
883
    }
884
885
    public function testAbortsConfiguringNonMorphIdField()
886
    {
887
        $this->crudPanel->setModel(Star::class);
888
        $this->expectException(\Exception::class);
889
        $this->crudPanel->field('some_field')
890
                        ->morphIdField(['attributes' => ['custom-attribute' => true]]);
891
    }
892
893
    public function testItCanGetTheFieldAttributes()
894
    {
895
        $this->crudPanel->field('some_field');
896
897
        $this->assertEquals($this->crudPanel->fields()['some_field'], $this->crudPanel->field('some_field')->getAttributes());
898
    }
899
900
    public function testItAbortsWithEmptyNamesFluently()
901
    {
902
        try {
903
            CrudField::name('');
904
        } catch (\Throwable $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
905
        }
906
        $this->assertEquals(
907
            new \Symfony\Component\HttpKernel\Exception\HttpException(500, 'Field name can\'t be empty.', null, ['developer-error-exception']),
908
            $e
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $e does not seem to be defined for all execution paths leading up to this point.
Loading history...
909
        );
910
    }
911
912
    public function testCheckReturnTypesForWhenInferringRelation()
913
    {
914
        $this->crudPanel->setModel(\Backpack\CRUD\Tests\config\Models\UserWithReturnTypes::class);
915
        $this->crudPanel->addField('isAnAttribute');
916
        $this->crudPanel->addField('isARelation');
917
918
        $this->assertEquals(false, $this->crudPanel->fields()['isAnAttribute']['entity']);
919
        $this->assertEquals('isARelation', $this->crudPanel->fields()['isARelation']['entity']);
920
    }
921
922
    public function testItCanGetTheFirstFieldViewWithoutProvidingNamespace()
923
    {
924
        $this->assertEquals('backpack.theme-coreuiv2::fields.test', $this->crudPanel->getFirstFieldView('test'));
925
    }
926
927
    public function testItCanGetTheFirstFieldViewInProvidedNamespace()
928
    {
929
        $this->assertEquals('backpack.theme-coreuiv2::fields.custom_namespace.test', $this->crudPanel->getFirstFieldView('test', 'backpack.theme-coreuiv2::fields.custom_namespace'));
930
    }
931
932
    public function testItDoesntAttemptToMoveFieldsIfTheyDontExist()
933
    {
934
        $this->assertFalse($this->crudPanel->makeFirstField());
935
    }
936
937
    public function testItThrowExceptionWhenViewNotFound()
938
    {
939
        $this->expectException(\Exception::class);
940
        $this->crudPanel->getFirstFieldView('test2');
941
    }
942
943
    public function testItCanGetUploadFieldsFromSubfields()
944
    {
945
        $this->crudPanel->addField([
946
            'name' => 'test1',
947
            'subfields' => [
948
                ['name' => 'test1_1', 'upload' => true],
949
                ['name' => 'test1_2'],
950
            ],
951
        ]);
952
        $this->crudPanel->addField([
953
            'name' => 'test2',
954
            'subfields' => [
955
                ['name' => 'test2_1'],
956
                ['name' => 'test2_2'],
957
            ],
958
        ]);
959
960
        $this->assertCount(2, $this->crudPanel->getFields());
961
        $this->assertTrue($this->crudPanel->hasUploadFields());
962
    }
963
964
    public function testItCanMarkAFieldTypeAsLoaded()
965
    {
966
        $this->crudPanel->addField([
967
            'name' => 'test1',
968
            'type' => 'text',
969
        ]);
970
        $field = $this->crudPanel->fields()['test1'];
971
        $this->assertTrue($this->crudPanel->markFieldTypeAsLoaded($field));
972
        $this->assertFalse($this->crudPanel->markFieldTypeAsLoaded($field));
973
        $this->assertTrue($this->crudPanel->fieldTypeLoaded($field));
974
        $this->assertTrue($this->crudPanel->fieldTypeNotLoaded(['type' => 'test']));
0 ignored issues
show
Bug introduced by
array('type' => 'test') of type array<string,string> is incompatible with the type string expected by parameter $field of Backpack\CRUD\app\Librar...l::fieldTypeNotLoaded(). ( Ignorable by Annotation )

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

974
        $this->assertTrue($this->crudPanel->fieldTypeNotLoaded(/** @scrutinizer ignore-type */ ['type' => 'test']));
Loading history...
975
        $this->assertEquals(['text'], $this->crudPanel->getLoadedFieldTypes());
976
    }
977
978
    public function testItCanGetFieldNamesFromNamesWithCommas()
979
    {
980
        $this->crudPanel->addField('test1, test2');
981
        $this->assertEquals(['test1', 'test2'], $this->crudPanel->getAllFieldNames());
982
    }
983
984
    public function testItCanInferFieldAttributesFromADynamicRelation()
985
    {
986
        User::resolveRelationUsing('dynamicRelation', function ($user) {
987
            return $user->hasOne(\Backpack\CRUD\Tests\config\Models\AccountDetails::class);
988
        });
989
990
        $this->crudPanel->setModel(User::class);
991
        $this->crudPanel->addField('dynamicRelation.nickname');
992
993
        $this->assertEquals([
994
            'name' => 'dynamicRelation[nickname]',
995
            'type' => 'relationship',
996
            'entity' => 'dynamicRelation.nickname',
997
            'relation_type' => 'HasOne',
998
            'attribute' => 'nickname',
999
            'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
1000
            'multiple' => false,
1001
            'pivot' => false,
1002
            'label' => 'DynamicRelation.nickname',
1003
        ], $this->crudPanel->fields()['dynamicRelation.nickname']);
1004
    }
1005
}
1006
1007
class Invokable
1008
{
1009
    public function __invoke(): array
1010
    {
1011
        return ['invokable' => 'invokable'];
1012
    }
1013
}
1014