Completed
Push — master ( 5c73c5...651a01 )
by Javier
17s queued 11s
created

getRenderViewElementWithNoValueTests()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 55
rs 8.9818
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Tests\Twig\Extension;
15
16
use PHPUnit\Framework\TestCase;
17
use Prophecy\Argument;
18
use Psr\Log\LoggerInterface;
19
use Sonata\AdminBundle\Admin\AbstractAdmin;
20
use Sonata\AdminBundle\Admin\AdminInterface;
21
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
22
use Sonata\AdminBundle\Admin\Pool;
23
use Sonata\AdminBundle\Exception\NoValueException;
24
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
25
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
26
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension;
27
use Sonata\AdminBundle\Twig\Extension\StringExtension;
28
use Symfony\Bridge\Twig\AppVariable;
29
use Symfony\Bridge\Twig\Extension\RoutingExtension;
30
use Symfony\Bridge\Twig\Extension\TranslationExtension;
31
use Symfony\Component\Config\FileLocator;
32
use Symfony\Component\DependencyInjection\ContainerInterface;
33
use Symfony\Component\HttpFoundation\Request;
34
use Symfony\Component\Routing\Generator\UrlGenerator;
35
use Symfony\Component\Routing\Loader\XmlFileLoader;
36
use Symfony\Component\Routing\RequestContext;
37
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
38
use Symfony\Component\Translation\Loader\XliffFileLoader;
39
use Symfony\Component\Translation\Translator;
40
use Symfony\Contracts\Translation\TranslatorInterface;
41
use Twig\Environment;
42
use Twig\Loader\FilesystemLoader;
43
44
/**
45
 * Test for SonataAdminExtension.
46
 *
47
 * @author Andrej Hudec <[email protected]>
48
 */
49
class SonataAdminExtensionTest extends TestCase
50
{
51
    /**
52
     * @var SonataAdminExtension
53
     */
54
    private $twigExtension;
55
56
    /**
57
     * @var Environment
58
     */
59
    private $environment;
60
61
    /**
62
     * @var AdminInterface
63
     */
64
    private $admin;
65
66
    /**
67
     * @var AdminInterface
68
     */
69
    private $adminBar;
70
71
    /**
72
     * @var FieldDescriptionInterface
73
     */
74
    private $fieldDescription;
75
76
    /**
77
     * @var \stdClass
78
     */
79
    private $object;
80
81
    /**
82
     * @var Pool
83
     */
84
    private $pool;
85
86
    /**
87
     * @var LoggerInterface
88
     */
89
    private $logger;
90
91
    /**
92
     * @var string[]
93
     */
94
    private $xEditableTypeMapping;
95
96
    /**
97
     * @var TranslatorInterface
98
     */
99
    private $translator;
100
101
    /**
102
     * @var ContainerInterface
103
     */
104
    private $container;
105
106
    /**
107
     * @var TemplateRegistryInterface
108
     */
109
    private $templateRegistry;
110
111
    /**
112
     * @var AuthorizationCheckerInterface
113
     */
114
    private $securityChecker;
115
116
    protected function setUp(): void
117
    {
118
        date_default_timezone_set('Europe/London');
119
120
        $container = $this->createMock(ContainerInterface::class);
121
122
        $this->pool = new Pool($container, '', '');
123
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service']);
124
        $this->pool->setAdminClasses(['fooClass' => ['sonata_admin_foo_service']]);
125
126
        $this->logger = $this->getMockForAbstractClass(LoggerInterface::class);
127
        $this->xEditableTypeMapping = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array('choice' => 'selec...umber', 'url' => 'url') of type array<string,string,{"ch...tring","url":"string"}> is incompatible with the declared type array<integer,string> of property $xEditableTypeMapping.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
128
            'choice' => 'select',
129
            'boolean' => 'select',
130
            'text' => 'text',
131
            'textarea' => 'textarea',
132
            'html' => 'textarea',
133
            'email' => 'email',
134
            'string' => 'text',
135
            'smallint' => 'text',
136
            'bigint' => 'text',
137
            'integer' => 'number',
138
            'decimal' => 'number',
139
            'currency' => 'number',
140
            'percent' => 'number',
141
            'url' => 'url',
142
        ];
143
144
        // translation extension
145
        $translator = new Translator('en');
146
        $translator->addLoader('xlf', new XliffFileLoader());
147
        $translator->addResource(
148
            'xlf',
149
            __DIR__.'/../../../src/Resources/translations/SonataAdminBundle.en.xliff',
150
            'en',
151
            'SonataAdminBundle'
152
        );
153
154
        $this->translator = $translator;
155
156
        $this->templateRegistry = $this->prophesize(TemplateRegistryInterface::class);
157
        $this->container = $this->prophesize(ContainerInterface::class);
158
        $this->container->get('sonata_admin_foo_service.template_registry')->willReturn($this->templateRegistry->reveal());
159
160
        $this->securityChecker = $this->prophesize(AuthorizationCheckerInterface::class);
161
        $this->securityChecker->isGranted(['foo', 'bar'], null)->willReturn(false);
162
        $this->securityChecker->isGranted(Argument::type('string'), null)->willReturn(true);
163
164
        $this->twigExtension = new SonataAdminExtension(
165
            $this->pool,
166
            $this->logger,
167
            $this->translator,
168
            $this->container->reveal(),
169
            $this->securityChecker->reveal()
170
        );
171
        $this->twigExtension->setXEditableTypeMapping($this->xEditableTypeMapping);
172
173
        $request = $this->createMock(Request::class);
174
        $request->method('get')->with('_sonata_admin')->willReturn('sonata_admin_foo_service');
175
176
        $loader = new FilesystemLoader([
177
            __DIR__.'/../../../src/Resources/views/CRUD',
178
        ]);
179
        $loader->addPath(__DIR__.'/../../../src/Resources/views/', 'SonataAdmin');
180
181
        $this->environment = new Environment($loader, [
182
            'strict_variables' => true,
183
            'cache' => false,
184
            'autoescape' => 'html',
185
            'optimizations' => 0,
186
        ]);
187
        $this->environment->addExtension($this->twigExtension);
188
        $this->environment->addExtension(new TranslationExtension($translator));
189
        $this->environment->addExtension(new FakeTemplateRegistryExtension());
190
191
        // routing extension
192
        $xmlFileLoader = new XmlFileLoader(new FileLocator([__DIR__.'/../../../src/Resources/config/routing']));
193
        $routeCollection = $xmlFileLoader->load('sonata_admin.xml');
194
195
        $xmlFileLoader = new XmlFileLoader(new FileLocator([__DIR__.'/../../Fixtures/Resources/config/routing']));
196
        $testRouteCollection = $xmlFileLoader->load('routing.xml');
197
198
        $routeCollection->addCollection($testRouteCollection);
0 ignored issues
show
Documentation introduced by
$testRouteCollection is of type object<Symfony\Component\Routing\RouteCollection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
199
        $requestContext = new RequestContext();
200
        $urlGenerator = new UrlGenerator($routeCollection, $requestContext);
201
        $this->environment->addExtension(new RoutingExtension($urlGenerator));
202
        $this->environment->addExtension(new StringExtension());
203
204
        // initialize object
205
        $this->object = new \stdClass();
206
207
        // initialize admin
208
        $this->admin = $this->createMock(AbstractAdmin::class);
209
210
        $this->admin
211
            ->method('getCode')
212
            ->willReturn('sonata_admin_foo_service');
213
214
        $this->admin
215
            ->method('id')
216
            ->with($this->equalTo($this->object))
217
            ->willReturn(12345);
218
219
        $this->admin
220
            ->method('getNormalizedIdentifier')
221
            ->with($this->equalTo($this->object))
222
            ->willReturn(12345);
223
224
        $this->admin
225
            ->method('trans')
226
            ->willReturnCallback(static function ($id, $parameters = [], $domain = null) use ($translator) {
227
                return $translator->trans($id, $parameters, $domain);
228
            });
229
230
        $this->adminBar = $this->createMock(AbstractAdmin::class);
231
        $this->adminBar
232
            ->method('hasAccess')
233
            ->willReturn(true);
234
        $this->adminBar
235
            ->method('getNormalizedIdentifier')
236
            ->with($this->equalTo($this->object))
237
            ->willReturn(12345);
238
239
        $container
240
            ->method('get')
241
            ->willReturnCallback(function (string $id) {
242
                if ('sonata_admin_foo_service' === $id) {
243
                    return $this->admin;
244
                }
245
246
                if ('sonata_admin_bar_service' === $id) {
247
                    return $this->adminBar;
248
                }
249
            });
250
251
        // initialize field description
252
        $this->fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
253
254
        $this->fieldDescription
255
            ->method('getName')
256
            ->willReturn('fd_name');
257
258
        $this->fieldDescription
259
            ->method('getAdmin')
260
            ->willReturn($this->admin);
261
262
        $this->fieldDescription
263
            ->method('getLabel')
264
            ->willReturn('Data');
265
    }
266
267
    public function getRenderListElementTests()
268
    {
269
        return [
270
            [
271
                '<td class="sonata-ba-list-field sonata-ba-list-field-string" objectId="12345"> Example </td>',
272
                'string',
273
                'Example',
274
                [],
275
            ],
276
            [
277
                '<td class="sonata-ba-list-field sonata-ba-list-field-string" objectId="12345"> </td>',
278
                'string',
279
                null,
280
                [],
281
            ],
282
            [
283
                '<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345"> Example </td>',
284
                'text',
285
                'Example',
286
                [],
287
            ],
288
            [
289
                '<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345"> </td>',
290
                'text',
291
                null,
292
                [],
293
            ],
294
            [
295
                '<td class="sonata-ba-list-field sonata-ba-list-field-textarea" objectId="12345"> Example </td>',
296
                'textarea',
297
                'Example',
298
                [],
299
            ],
300
            [
301
                '<td class="sonata-ba-list-field sonata-ba-list-field-textarea" objectId="12345"> </td>',
302
                'textarea',
303
                null,
304
                [],
305
            ],
306
            'datetime field' => [
307
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
308
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
309
                        December 24, 2013 10:11
310
                    </time>
311
                </td>',
312
                'datetime',
313
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
314
                [],
315
            ],
316
            [
317
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
318
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
319
                        December 24, 2013 18:11
320
                    </time>
321
                </td>',
322
                'datetime',
323
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
324
                ['timezone' => 'Asia/Hong_Kong'],
325
            ],
326
            [
327
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
328
                'datetime',
329
                null,
330
                [],
331
            ],
332
            [
333
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
334
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
335
                        24.12.2013 10:11:12
336
                    </time>
337
                </td>',
338
                'datetime',
339
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
340
                ['format' => 'd.m.Y H:i:s'],
341
            ],
342
            [
343
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
344
                'datetime',
345
                null,
346
                ['format' => 'd.m.Y H:i:s'],
347
            ],
348
            [
349
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
350
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
351
                        24.12.2013 18:11:12
352
                    </time>
353
                </td>',
354
                'datetime',
355
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
356
                ['format' => 'd.m.Y H:i:s', 'timezone' => 'Asia/Hong_Kong'],
357
            ],
358
            [
359
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
360
                'datetime',
361
                null,
362
                ['format' => 'd.m.Y H:i:s', 'timezone' => 'Asia/Hong_Kong'],
363
            ],
364
            [
365
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345">
366
                    <time datetime="2013-12-24" title="2013-12-24">
367
                        December 24, 2013
368
                    </time>
369
                </td>',
370
                'date',
371
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
372
                [],
373
            ],
374
            [
375
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345"> &nbsp; </td>',
376
                'date',
377
                null,
378
                [],
379
            ],
380
            [
381
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345">
382
                    <time datetime="2013-12-24" title="2013-12-24">
383
                        24.12.2013
384
                    </time>
385
                </td>',
386
                'date',
387
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
388
                ['format' => 'd.m.Y'],
389
            ],
390
            [
391
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345"> &nbsp; </td>',
392
                'date',
393
                null,
394
                ['format' => 'd.m.Y'],
395
            ],
396
            [
397
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345">
398
                    <time datetime="10:11:12+00:00" title="10:11:12+00:00">
399
                        10:11:12
400
                    </time>
401
                </td>',
402
                'time',
403
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
404
                [],
405
            ],
406
            [
407
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345">
408
                    <time datetime="10:11:12+00:00" title="10:11:12+00:00">
409
                        18:11:12
410
                    </time>
411
                </td>',
412
                'time',
413
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
414
                ['timezone' => 'Asia/Hong_Kong'],
415
            ],
416
            [
417
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345"> &nbsp; </td>',
418
                'time',
419
                null,
420
                [],
421
            ],
422
            [
423
                '<td class="sonata-ba-list-field sonata-ba-list-field-number" objectId="12345"> 10.746135 </td>',
424
                'number', 10.746135,
425
                [],
426
            ],
427
            [
428
                '<td class="sonata-ba-list-field sonata-ba-list-field-number" objectId="12345"> </td>',
429
                'number',
430
                null,
431
                [],
432
            ],
433
            [
434
                '<td class="sonata-ba-list-field sonata-ba-list-field-integer" objectId="12345"> 5678 </td>',
435
                'integer',
436
                5678,
437
                [],
438
            ],
439
            [
440
                '<td class="sonata-ba-list-field sonata-ba-list-field-integer" objectId="12345"> </td>',
441
                'integer',
442
                null,
443
                [],
444
            ],
445
            [
446
                '<td class="sonata-ba-list-field sonata-ba-list-field-percent" objectId="12345"> 1074.6135 % </td>',
447
                'percent',
448
                10.746135,
449
                [],
450
            ],
451
            [
452
                '<td class="sonata-ba-list-field sonata-ba-list-field-percent" objectId="12345"> 0 % </td>',
453
                'percent',
454
                null,
455
                [],
456
            ],
457
            [
458
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> EUR 10.746135 </td>',
459
                'currency',
460
                10.746135,
461
                ['currency' => 'EUR'],
462
            ],
463
            [
464
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> </td>',
465
                'currency',
466
                null,
467
                ['currency' => 'EUR'],
468
            ],
469
            [
470
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> GBP 51.23456 </td>',
471
                'currency',
472
                51.23456,
473
                ['currency' => 'GBP'],
474
            ],
475
            [
476
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> </td>',
477
                'currency',
478
                null,
479
                ['currency' => 'GBP'],
480
            ],
481
            [
482
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> &nbsp; </td>',
483
                'email',
484
                null,
485
                [],
486
            ],
487
            [
488
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> <a href="mailto:[email protected]">[email protected]</a> </td>',
489
                'email',
490
                '[email protected]',
491
                [],
492
            ],
493
            [
494
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
495
                    <a href="mailto:[email protected]">[email protected]</a> </td>',
496
                'email',
497
                '[email protected]',
498
                ['as_string' => false],
499
            ],
500
            [
501
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
502
                'email',
503
                '[email protected]',
504
                ['as_string' => true],
505
            ],
506
            [
507
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
508
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme', 'body' => 'Message Body']).'">[email protected]</a>  </td>',
509
                'email',
510
                '[email protected]',
511
                ['subject' => 'Main Theme', 'body' => 'Message Body'],
512
            ],
513
            [
514
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
515
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme']).'">[email protected]</a>  </td>',
516
                'email',
517
                '[email protected]',
518
                ['subject' => 'Main Theme'],
519
            ],
520
            [
521
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
522
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['body' => 'Message Body']).'">[email protected]</a>  </td>',
523
                'email',
524
                '[email protected]',
525
                ['body' => 'Message Body'],
526
            ],
527
            [
528
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
529
                'email',
530
                '[email protected]',
531
                ['as_string' => true, 'subject' => 'Main Theme', 'body' => 'Message Body'],
532
            ],
533
            [
534
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
535
                'email',
536
                '[email protected]',
537
                ['as_string' => true, 'body' => 'Message Body'],
538
            ],
539
            [
540
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
541
                'email',
542
                '[email protected]',
543
                ['as_string' => true, 'subject' => 'Main Theme'],
544
            ],
545
            [
546
                '<td class="sonata-ba-list-field sonata-ba-list-field-array" objectId="12345">
547
                    [1&nbsp;=>&nbsp;First, 2&nbsp;=>&nbsp;Second]
548
                </td>',
549
                'array',
550
                [1 => 'First', 2 => 'Second'],
551
                [],
552
            ],
553
            [
554
                '<td class="sonata-ba-list-field sonata-ba-list-field-array" objectId="12345"> [] </td>',
555
                'array',
556
                null,
557
                [],
558
            ],
559
            [
560
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
561
                    <span class="label label-success">yes</span>
562
                </td>',
563
                'boolean',
564
                true,
565
                ['editable' => false],
566
            ],
567
            [
568
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
569
                    <span class="label label-danger">no</span>
570
                </td>',
571
                'boolean',
572
                false,
573
                ['editable' => false],
574
            ],
575
            [
576
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
577
                    <span class="label label-danger">no</span>
578
                </td>',
579
                'boolean',
580
                null,
581
                ['editable' => false],
582
            ],
583
            [
584
                <<<'EOT'
585
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
586
    <span
587
        class="x-editable"
588
        data-type="select"
589
        data-value="1"
590
        data-title="Data"
591
        data-pk="12345"
592
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
593
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]"
594
    >
595
        <span class="label label-success">yes</span>
596
    </span>
597
</td>
598
EOT
599
            ,
600
                'boolean',
601
                true,
602
                ['editable' => true],
603
            ],
604
            [
605
                <<<'EOT'
606
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
607
    <span
608
        class="x-editable"
609
        data-type="select"
610
        data-value="0"
611
        data-title="Data"
612
        data-pk="12345"
613
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
614
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]"
615
    >
616
    <span class="label label-danger">no</span> </span>
617
</td>
618
EOT
619
                ,
620
                'boolean',
621
                false,
622
                ['editable' => true],
623
            ],
624
            [
625
                <<<'EOT'
626
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
627
    <span
628
        class="x-editable"
629
        data-type="select"
630
        data-value="0"
631
        data-title="Data"
632
        data-pk="12345"
633
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
634
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]" >
635
        <span class="label label-danger">no</span> </span>
636
</td>
637
EOT
638
                ,
639
                'boolean',
640
                null,
641
                ['editable' => true],
642
            ],
643
            [
644
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> Delete </td>',
645
                'trans',
646
                'action_delete',
647
                ['catalogue' => 'SonataAdminBundle'],
648
            ],
649
            [
650
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> </td>',
651
                'trans',
652
                null,
653
                ['catalogue' => 'SonataAdminBundle'],
654
            ],
655
            [
656
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> Delete </td>',
657
                'trans',
658
                'action_delete',
659
                ['format' => '%s', 'catalogue' => 'SonataAdminBundle'],
660
            ],
661
            [
662
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345">
663
                action.action_delete
664
                </td>',
665
                'trans',
666
                'action_delete',
667
                ['format' => 'action.%s'],
668
            ],
669
            [
670
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345">
671
                action.action_delete
672
                </td>',
673
                'trans',
674
                'action_delete',
675
                ['format' => 'action.%s', 'catalogue' => 'SonataAdminBundle'],
676
            ],
677
            [
678
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Status1 </td>',
679
                'choice',
680
                'Status1',
681
                [],
682
            ],
683
            [
684
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Status1 </td>',
685
                'choice',
686
                ['Status1'],
687
                ['choices' => [], 'multiple' => true],
688
            ],
689
            [
690
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1 </td>',
691
                'choice',
692
                'Status1',
693
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
694
            ],
695
            [
696
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> </td>',
697
                'choice',
698
                null,
699
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
700
            ],
701
            [
702
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
703
                NoValidKeyInChoices
704
                </td>',
705
                'choice',
706
                'NoValidKeyInChoices',
707
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
708
            ],
709
            [
710
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Delete </td>',
711
                'choice',
712
                'Foo',
713
                ['catalogue' => 'SonataAdminBundle', 'choices' => [
714
                    'Foo' => 'action_delete',
715
                    'Status2' => 'Alias2',
716
                    'Status3' => 'Alias3',
717
                ]],
718
            ],
719
            [
720
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1, Alias3 </td>',
721
                'choice',
722
                ['Status1', 'Status3'],
723
                ['choices' => [
724
                    'Status1' => 'Alias1',
725
                    'Status2' => 'Alias2',
726
                    'Status3' => 'Alias3',
727
                ], 'multiple' => true], ],
728
            [
729
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1 | Alias3 </td>',
730
                'choice',
731
                ['Status1', 'Status3'],
732
                ['choices' => [
733
                    'Status1' => 'Alias1',
734
                    'Status2' => 'Alias2',
735
                    'Status3' => 'Alias3',
736
                ], 'multiple' => true, 'delimiter' => ' | '], ],
737
            [
738
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> </td>',
739
                'choice',
740
                null,
741
                ['choices' => [
742
                    'Status1' => 'Alias1',
743
                    'Status2' => 'Alias2',
744
                    'Status3' => 'Alias3',
745
                ], 'multiple' => true],
746
            ],
747
            [
748
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
749
                NoValidKeyInChoices
750
                </td>',
751
                'choice',
752
                ['NoValidKeyInChoices'],
753
                ['choices' => [
754
                    'Status1' => 'Alias1',
755
                    'Status2' => 'Alias2',
756
                    'Status3' => 'Alias3',
757
                ], 'multiple' => true],
758
            ],
759
            [
760
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
761
                NoValidKeyInChoices, Alias2
762
                </td>',
763
                'choice',
764
                ['NoValidKeyInChoices', 'Status2'],
765
                ['choices' => [
766
                    'Status1' => 'Alias1',
767
                    'Status2' => 'Alias2',
768
                    'Status3' => 'Alias3',
769
                ], 'multiple' => true],
770
            ],
771
            [
772
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Delete, Alias3 </td>',
773
                'choice',
774
                ['Foo', 'Status3'],
775
                ['catalogue' => 'SonataAdminBundle', 'choices' => [
776
                    'Foo' => 'action_delete',
777
                    'Status2' => 'Alias2',
778
                    'Status3' => 'Alias3',
779
                ], 'multiple' => true],
780
            ],
781
            [
782
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
783
                &lt;b&gt;Alias1&lt;/b&gt;, &lt;b&gt;Alias3&lt;/b&gt;
784
            </td>',
785
                'choice',
786
                ['Status1', 'Status3'],
787
                ['choices' => [
788
                    'Status1' => '<b>Alias1</b>',
789
                    'Status2' => '<b>Alias2</b>',
790
                    'Status3' => '<b>Alias3</b>',
791
                ], 'multiple' => true], ],
792
            [
793
                <<<'EOT'
794
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
795
    <span
796
        class="x-editable"
797
        data-type="select"
798
        data-value="Status1"
799
        data-title="Data"
800
        data-pk="12345"
801
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
802
        data-source="[]"
803
    >
804
        Status1
805
    </span>
806
</td>
807
EOT
808
                ,
809
                'choice',
810
                'Status1',
811
                ['editable' => true],
812
            ],
813
            [
814
                <<<'EOT'
815
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
816
    <span
817
        class="x-editable"
818
        data-type="select"
819
        data-value="Status1"
820
        data-title="Data"
821
        data-pk="12345"
822
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
823
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
824
        Alias1 </span>
825
</td>
826
EOT
827
                ,
828
                'choice',
829
                'Status1',
830
                [
831
                    'editable' => true,
832
                    'choices' => [
833
                        'Status1' => 'Alias1',
834
                        'Status2' => 'Alias2',
835
                        'Status3' => 'Alias3',
836
                    ],
837
                ],
838
            ],
839
            [
840
                <<<'EOT'
841
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
842
    <span
843
        class="x-editable"
844
        data-type="select"
845
        data-value=""
846
        data-title="Data"
847
        data-pk="12345"
848
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
849
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
850
851
    </span>
852
</td>
853
EOT
854
                ,
855
                'choice',
856
                null,
857
                [
858
                    'editable' => true,
859
                    'choices' => [
860
                        'Status1' => 'Alias1',
861
                        'Status2' => 'Alias2',
862
                        'Status3' => 'Alias3',
863
                    ],
864
                ],
865
            ],
866
            [
867
                <<<'EOT'
868
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
869
    <span
870
        class="x-editable"
871
        data-type="select"
872
        data-value="NoValidKeyInChoices"
873
        data-title="Data" data-pk="12345"
874
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
875
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
876
        NoValidKeyInChoices
877
    </span>
878
</td>
879
EOT
880
                ,
881
                'choice',
882
                'NoValidKeyInChoices',
883
                [
884
                    'editable' => true,
885
                    'choices' => [
886
                        'Status1' => 'Alias1',
887
                        'Status2' => 'Alias2',
888
                        'Status3' => 'Alias3',
889
                    ],
890
                ],
891
            ],
892
            [
893
                <<<'EOT'
894
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
895
    <span
896
        class="x-editable"
897
        data-type="select"
898
        data-value="Foo"
899
        data-title="Data"
900
        data-pk="12345"
901
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
902
        data-source="[{&quot;value&quot;:&quot;Foo&quot;,&quot;text&quot;:&quot;Delete&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
903
         Delete
904
    </span>
905
</td>
906
EOT
907
                ,
908
                'choice',
909
                'Foo',
910
                [
911
                    'editable' => true,
912
                    'catalogue' => 'SonataAdminBundle',
913
                    'choices' => [
914
                        'Foo' => 'action_delete',
915
                        'Status2' => 'Alias2',
916
                        'Status3' => 'Alias3',
917
                    ],
918
                ],
919
            ],
920
            [
921
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
922
                'url',
923
                null,
924
                [],
925
            ],
926
            [
927
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
928
                'url',
929
                null,
930
                ['url' => 'http://example.com'],
931
            ],
932
            [
933
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
934
                'url',
935
                null,
936
                ['route' => ['name' => 'sonata_admin_foo']],
937
            ],
938
            [
939
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
940
                <a href="http://example.com">http://example.com</a>
941
                </td>',
942
                'url',
943
                'http://example.com',
944
                [],
945
            ],
946
            [
947
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
948
                <a href="https://example.com">https://example.com</a>
949
                </td>',
950
                'url',
951
                'https://example.com',
952
                [],
953
            ],
954
            [
955
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
956
                <a href="https://example.com" target="_blank">https://example.com</a>
957
                </td>',
958
                'url',
959
                'https://example.com',
960
                ['attributes' => ['target' => '_blank']],
961
            ],
962
            [
963
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
964
                <a href="https://example.com" target="_blank" class="fooLink">https://example.com</a>
965
                </td>',
966
                'url',
967
                'https://example.com',
968
                ['attributes' => ['target' => '_blank', 'class' => 'fooLink']],
969
            ],
970
            [
971
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
972
                <a href="http://example.com">example.com</a>
973
                </td>',
974
                'url',
975
                'http://example.com',
976
                ['hide_protocol' => true],
977
            ],
978
            [
979
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
980
                <a href="https://example.com">example.com</a>
981
                </td>',
982
                'url',
983
                'https://example.com',
984
                ['hide_protocol' => true],
985
            ],
986
            [
987
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
988
                <a href="http://example.com">http://example.com</a>
989
                </td>',
990
                'url',
991
                'http://example.com',
992
                ['hide_protocol' => false],
993
            ],
994
            [
995
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
996
                <a href="https://example.com">https://example.com</a>
997
                </td>',
998
                'url',
999
                'https://example.com',
1000
                ['hide_protocol' => false],
1001
            ],
1002
            [
1003
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1004
                <a href="http://example.com">Foo</a>
1005
                </td>',
1006
                'url',
1007
                'Foo',
1008
                ['url' => 'http://example.com'],
1009
            ],
1010
            [
1011
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1012
                <a href="http://example.com">&lt;b&gt;Foo&lt;/b&gt;</a>
1013
                </td>',
1014
                'url',
1015
                '<b>Foo</b>',
1016
                ['url' => 'http://example.com'],
1017
            ],
1018
            [
1019
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1020
                <a href="/foo">Foo</a>
1021
                </td>',
1022
                'url',
1023
                'Foo',
1024
                ['route' => ['name' => 'sonata_admin_foo']],
1025
            ],
1026
            [
1027
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1028
                <a href="http://localhost/foo">Foo</a>
1029
                </td>',
1030
                'url',
1031
                'Foo',
1032
                ['route' => ['name' => 'sonata_admin_foo', 'absolute' => true]],
1033
            ],
1034
            [
1035
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1036
                <a href="/foo">foo/bar?a=b&amp;c=123456789</a>
1037
                </td>',
1038
                'url',
1039
                'http://foo/bar?a=b&c=123456789',
1040
                ['route' => ['name' => 'sonata_admin_foo'],
1041
                'hide_protocol' => true, ],
1042
            ],
1043
            [
1044
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1045
                <a href="http://localhost/foo">foo/bar?a=b&amp;c=123456789</a>
1046
                </td>',
1047
                'url',
1048
                'http://foo/bar?a=b&c=123456789',
1049
                [
1050
                    'route' => ['name' => 'sonata_admin_foo', 'absolute' => true],
1051
                    'hide_protocol' => true,
1052
                ],
1053
            ],
1054
            [
1055
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1056
                <a href="/foo/abcd/efgh?param3=ijkl">Foo</a>
1057
                </td>',
1058
                'url',
1059
                'Foo',
1060
                [
1061
                    'route' => ['name' => 'sonata_admin_foo_param',
1062
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'], ],
1063
                ],
1064
            ],
1065
            [
1066
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1067
                <a href="http://localhost/foo/abcd/efgh?param3=ijkl">Foo</a>
1068
                </td>',
1069
                'url',
1070
                'Foo',
1071
                [
1072
                    'route' => ['name' => 'sonata_admin_foo_param',
1073
                    'absolute' => true,
1074
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'], ],
1075
                ],
1076
            ],
1077
            [
1078
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1079
                <a href="/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a>
1080
                </td>',
1081
                'url',
1082
                'Foo',
1083
                [
1084
                    'route' => ['name' => 'sonata_admin_foo_object',
1085
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1086
                    'identifier_parameter_name' => 'barId', ],
1087
                ],
1088
            ],
1089
            [
1090
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1091
                <a href="http://localhost/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a>
1092
                </td>',
1093
                'url',
1094
                'Foo',
1095
                [
1096
                    'route' => ['name' => 'sonata_admin_foo_object',
1097
                    'absolute' => true,
1098
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1099
                    'identifier_parameter_name' => 'barId', ],
1100
                ],
1101
            ],
1102
            [
1103
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1104
                <p><strong>Creating a Template for the Field</strong> and form</p>
1105
                </td>',
1106
                'html',
1107
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1108
                [],
1109
            ],
1110
            [
1111
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1112
                Creating a Template for the Field and form
1113
                </td>',
1114
                'html',
1115
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1116
                ['strip' => true],
1117
            ],
1118
            [
1119
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1120
                Creating a Template for the...
1121
                </td>',
1122
                'html',
1123
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1124
                ['truncate' => true],
1125
            ],
1126
            [
1127
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345"> Creatin... </td>',
1128
                'html',
1129
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1130
                ['truncate' => ['length' => 10]],
1131
            ],
1132
            [
1133
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1134
                Creating a Template for the Field...
1135
                </td>',
1136
                'html',
1137
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1138
                ['truncate' => ['cut' => false]],
1139
            ],
1140
            [
1141
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1142
                Creating a Template for t etc.
1143
                </td>',
1144
                'html',
1145
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1146
                ['truncate' => ['ellipsis' => ' etc.']],
1147
            ],
1148
            [
1149
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1150
                Creating a Template[...]
1151
                </td>',
1152
                'html',
1153
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1154
                [
1155
                    'truncate' => [
1156
                        'length' => 20,
1157
                        'cut' => false,
1158
                        'ellipsis' => '[...]',
1159
                    ],
1160
                ],
1161
            ],
1162
1163
            [
1164
                <<<'EOT'
1165
<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345">
1166
<div
1167
    class="sonata-readmore"
1168
    data-readmore-height="40"
1169
    data-readmore-more="Read more"
1170
    data-readmore-less="Close">A very long string</div>
1171
</td>
1172
EOT
1173
                ,
1174
                'text',
1175
                'A very long string',
1176
                [
1177
                    'collapse' => true,
1178
                ],
1179
            ],
1180
            [
1181
                <<<'EOT'
1182
<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345">
1183
<div
1184
    class="sonata-readmore"
1185
    data-readmore-height="10"
1186
    data-readmore-more="More"
1187
    data-readmore-less="Less">A very long string</div>
1188
</td>
1189
EOT
1190
                ,
1191
                'text',
1192
                'A very long string',
1193
                [
1194
                    'collapse' => [
1195
                        'height' => 10,
1196
                        'more' => 'More',
1197
                        'less' => 'Less',
1198
                    ],
1199
                ],
1200
            ],
1201
            [
1202
                <<<'EOT'
1203
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
1204
    <span
1205
        class="x-editable"
1206
        data-type="checklist"
1207
        data-value="[&quot;Status1&quot;,&quot;Status2&quot;]"
1208
        data-title="Data"
1209
        data-pk="12345"
1210
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
1211
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Delete&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
1212
         Delete, Alias2
1213
    </span>
1214
</td>
1215
EOT
1216
                ,
1217
                'choice',
1218
                [
1219
                    'Status1',
1220
                    'Status2',
1221
                ],
1222
                [
1223
                    'editable' => true,
1224
                    'multiple' => true,
1225
                    'catalogue' => 'SonataAdminBundle',
1226
                    'choices' => [
1227
                        'Status1' => 'action_delete',
1228
                        'Status2' => 'Alias2',
1229
                        'Status3' => 'Alias3',
1230
                    ],
1231
                ],
1232
            ],
1233
        ];
1234
    }
1235
1236
    /**
1237
     * @dataProvider getRenderViewElementTests
1238
     */
1239
    public function testRenderViewElement(string $expected, string $type, $value, array $options): void
1240
    {
1241
        $this->fieldDescription
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1242
            ->method('getValue')
1243
            ->willReturn($value);
1244
1245
        $this->fieldDescription
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1246
            ->method('getType')
1247
            ->willReturn($type);
1248
1249
        $this->fieldDescription
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1250
            ->method('getOptions')
1251
            ->willReturn($options);
1252
1253
        $this->fieldDescription
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1254
            ->method('getTemplate')
1255
            ->willReturnCallback(static function () use ($type): ?string {
1256
                switch ($type) {
1257
                    case 'boolean':
1258
                        return '@SonataAdmin/CRUD/show_boolean.html.twig';
1259
                    case 'datetime':
1260
                        return '@SonataAdmin/CRUD/show_datetime.html.twig';
1261
                    case 'date':
1262
                        return '@SonataAdmin/CRUD/show_date.html.twig';
1263
                    case 'time':
1264
                        return '@SonataAdmin/CRUD/show_time.html.twig';
1265
                    case 'currency':
1266
                        return '@SonataAdmin/CRUD/show_currency.html.twig';
1267
                    case 'percent':
1268
                        return '@SonataAdmin/CRUD/show_percent.html.twig';
1269
                    case 'email':
1270
                        return '@SonataAdmin/CRUD/show_email.html.twig';
1271
                    case 'choice':
1272
                        return '@SonataAdmin/CRUD/show_choice.html.twig';
1273
                    case 'array':
1274
                        return '@SonataAdmin/CRUD/show_array.html.twig';
1275
                    case 'trans':
1276
                        return '@SonataAdmin/CRUD/show_trans.html.twig';
1277
                    case 'url':
1278
                        return '@SonataAdmin/CRUD/show_url.html.twig';
1279
                    case 'html':
1280
                        return '@SonataAdmin/CRUD/show_html.html.twig';
1281
                    default:
1282
                        return null;
1283
                }
1284
            });
1285
1286
        $this->assertSame(
1287
            $this->removeExtraWhitespace($expected),
1288
            $this->removeExtraWhitespace(
1289
                $this->twigExtension->renderViewElement(
1290
                    $this->environment,
1291
                    $this->fieldDescription,
1292
                    $this->object
1293
                )
1294
            )
1295
        );
1296
    }
1297
1298
    public function getRenderViewElementTests()
1299
    {
1300
        return [
1301
            ['<th>Data</th> <td>Example</td>', 'string', 'Example', ['safe' => false]],
1302
            ['<th>Data</th> <td>Example</td>', 'text', 'Example', ['safe' => false]],
1303
            ['<th>Data</th> <td>Example</td>', 'textarea', 'Example', ['safe' => false]],
1304
            [
1305
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> December 24, 2013 10:11 </time></td>',
1306
                'datetime',
1307
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')), [],
1308
            ],
1309
            [
1310
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> 24.12.2013 10:11:12 </time></td>',
1311
                'datetime',
1312
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1313
                ['format' => 'd.m.Y H:i:s'],
1314
            ],
1315
            [
1316
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> December 24, 2013 18:11 </time></td>',
1317
                'datetime',
1318
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
1319
                ['timezone' => 'Asia/Hong_Kong'],
1320
            ],
1321
            [
1322
                '<th>Data</th> <td><time datetime="2013-12-24" title="2013-12-24"> December 24, 2013 </time></td>',
1323
                'date',
1324
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1325
                [],
1326
            ],
1327
            [
1328
                '<th>Data</th> <td><time datetime="2013-12-24" title="2013-12-24"> 24.12.2013 </time></td>',
1329
                'date',
1330
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1331
                ['format' => 'd.m.Y'],
1332
            ],
1333
            [
1334
                '<th>Data</th> <td><time datetime="10:11:12+00:00" title="10:11:12+00:00"> 10:11:12 </time></td>',
1335
                'time',
1336
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1337
                [],
1338
            ],
1339
            [
1340
                '<th>Data</th> <td><time datetime="10:11:12+00:00" title="10:11:12+00:00"> 18:11:12 </time></td>',
1341
                'time',
1342
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
1343
                ['timezone' => 'Asia/Hong_Kong'],
1344
            ],
1345
            ['<th>Data</th> <td>10.746135</td>', 'number', 10.746135, ['safe' => false]],
1346
            ['<th>Data</th> <td>5678</td>', 'integer', 5678, ['safe' => false]],
1347
            ['<th>Data</th> <td> 1074.6135 % </td>', 'percent', 10.746135, []],
1348
            ['<th>Data</th> <td> EUR 10.746135 </td>', 'currency', 10.746135, ['currency' => 'EUR']],
1349
            ['<th>Data</th> <td> GBP 51.23456 </td>', 'currency', 51.23456, ['currency' => 'GBP']],
1350
            [
1351
                '<th>Data</th> <td> <ul><li>1&nbsp;=>&nbsp;First</li><li>2&nbsp;=>&nbsp;Second</li></ul> </td>',
1352
                'array',
1353
                [1 => 'First', 2 => 'Second'],
1354
                ['safe' => false],
1355
            ],
1356
            [
1357
                '<th>Data</th> <td> [1&nbsp;=>&nbsp;First, 2&nbsp;=>&nbsp;Second] </td>',
1358
                'array',
1359
                [1 => 'First', 2 => 'Second'],
1360
                ['safe' => false, 'inline' => true],
1361
            ],
1362
            [
1363
                '<th>Data</th> <td><span class="label label-success">yes</span></td>',
1364
                'boolean',
1365
                true,
1366
                [],
1367
            ],
1368
            [
1369
                '<th>Data</th> <td><span class="label label-danger">yes</span></td>',
1370
                'boolean',
1371
                true,
1372
                ['inverse' => true],
1373
            ],
1374
            ['<th>Data</th> <td><span class="label label-danger">no</span></td>', 'boolean', false, []],
1375
            [
1376
                '<th>Data</th> <td><span class="label label-success">no</span></td>',
1377
                'boolean',
1378
                false,
1379
                ['inverse' => true],
1380
            ],
1381
            [
1382
                '<th>Data</th> <td> Delete </td>',
1383
                'trans',
1384
                'action_delete',
1385
                ['safe' => false, 'catalogue' => 'SonataAdminBundle'],
1386
            ],
1387
            [
1388
                '<th>Data</th> <td> Delete </td>',
1389
                'trans',
1390
                'delete',
1391
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'format' => 'action_%s'],
1392
            ],
1393
            ['<th>Data</th> <td>Status1</td>', 'choice', 'Status1', ['safe' => false]],
1394
            [
1395
                '<th>Data</th> <td>Alias1</td>',
1396
                'choice',
1397
                'Status1',
1398
                ['safe' => false, 'choices' => [
1399
                    'Status1' => 'Alias1',
1400
                    'Status2' => 'Alias2',
1401
                    'Status3' => 'Alias3',
1402
                ]],
1403
            ],
1404
            [
1405
                '<th>Data</th> <td>NoValidKeyInChoices</td>',
1406
                'choice',
1407
                'NoValidKeyInChoices',
1408
                ['safe' => false, 'choices' => [
1409
                    'Status1' => 'Alias1',
1410
                    'Status2' => 'Alias2',
1411
                    'Status3' => 'Alias3',
1412
                ]],
1413
            ],
1414
            [
1415
                '<th>Data</th> <td>Delete</td>',
1416
                'choice',
1417
                'Foo',
1418
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'choices' => [
1419
                    'Foo' => 'action_delete',
1420
                    'Status2' => 'Alias2',
1421
                    'Status3' => 'Alias3',
1422
                ]],
1423
            ],
1424
            [
1425
                '<th>Data</th> <td>NoValidKeyInChoices</td>',
1426
                'choice',
1427
                ['NoValidKeyInChoices'],
1428
                ['safe' => false, 'choices' => [
1429
                    'Status1' => 'Alias1',
1430
                    'Status2' => 'Alias2',
1431
                    'Status3' => 'Alias3',
1432
                ], 'multiple' => true],
1433
            ],
1434
            [
1435
                '<th>Data</th> <td>NoValidKeyInChoices, Alias2</td>',
1436
                'choice',
1437
                ['NoValidKeyInChoices', 'Status2'],
1438
                ['safe' => false, 'choices' => [
1439
                    'Status1' => 'Alias1',
1440
                    'Status2' => 'Alias2',
1441
                    'Status3' => 'Alias3',
1442
                ], 'multiple' => true],
1443
            ],
1444
            [
1445
                '<th>Data</th> <td>Alias1, Alias3</td>',
1446
                'choice',
1447
                ['Status1', 'Status3'],
1448
                ['safe' => false, 'choices' => [
1449
                    'Status1' => 'Alias1',
1450
                    'Status2' => 'Alias2',
1451
                    'Status3' => 'Alias3',
1452
                ], 'multiple' => true],
1453
            ],
1454
            [
1455
                '<th>Data</th> <td>Alias1 | Alias3</td>',
1456
                'choice',
1457
                ['Status1', 'Status3'], ['safe' => false, 'choices' => [
1458
                    'Status1' => 'Alias1',
1459
                    'Status2' => 'Alias2',
1460
                    'Status3' => 'Alias3',
1461
                ], 'multiple' => true, 'delimiter' => ' | '],
1462
            ],
1463
            [
1464
                '<th>Data</th> <td>Delete, Alias3</td>',
1465
                'choice',
1466
                ['Foo', 'Status3'],
1467
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'choices' => [
1468
                    'Foo' => 'action_delete',
1469
                    'Status2' => 'Alias2',
1470
                    'Status3' => 'Alias3',
1471
                ], 'multiple' => true],
1472
            ],
1473
            [
1474
                '<th>Data</th> <td><b>Alias1</b>, <b>Alias3</b></td>',
1475
                'choice',
1476
                ['Status1', 'Status3'],
1477
                ['safe' => true, 'choices' => [
1478
                    'Status1' => '<b>Alias1</b>',
1479
                    'Status2' => '<b>Alias2</b>',
1480
                    'Status3' => '<b>Alias3</b>',
1481
                ], 'multiple' => true],
1482
            ],
1483
            [
1484
                '<th>Data</th> <td>&lt;b&gt;Alias1&lt;/b&gt;, &lt;b&gt;Alias3&lt;/b&gt;</td>',
1485
                'choice',
1486
                ['Status1', 'Status3'],
1487
                ['safe' => false, 'choices' => [
1488
                    'Status1' => '<b>Alias1</b>',
1489
                    'Status2' => '<b>Alias2</b>',
1490
                    'Status3' => '<b>Alias3</b>',
1491
                ], 'multiple' => true],
1492
            ],
1493
            [
1494
                '<th>Data</th> <td><a href="http://example.com">http://example.com</a></td>',
1495
                'url',
1496
                'http://example.com',
1497
                ['safe' => false],
1498
            ],
1499
            [
1500
                '<th>Data</th> <td><a href="http://example.com" target="_blank">http://example.com</a></td>',
1501
                'url',
1502
                'http://example.com',
1503
                ['safe' => false, 'attributes' => ['target' => '_blank']],
1504
            ],
1505
            [
1506
                '<th>Data</th> <td><a href="http://example.com" target="_blank" class="fooLink">http://example.com</a></td>',
1507
                'url',
1508
                'http://example.com',
1509
                ['safe' => false, 'attributes' => ['target' => '_blank', 'class' => 'fooLink']],
1510
            ],
1511
            [
1512
                '<th>Data</th> <td><a href="https://example.com">https://example.com</a></td>',
1513
                'url',
1514
                'https://example.com',
1515
                ['safe' => false],
1516
            ],
1517
            [
1518
                '<th>Data</th> <td><a href="http://example.com">example.com</a></td>',
1519
                'url',
1520
                'http://example.com',
1521
                ['safe' => false, 'hide_protocol' => true],
1522
            ],
1523
            [
1524
                '<th>Data</th> <td><a href="https://example.com">example.com</a></td>',
1525
                'url',
1526
                'https://example.com',
1527
                ['safe' => false, 'hide_protocol' => true],
1528
            ],
1529
            [
1530
                '<th>Data</th> <td><a href="http://example.com">http://example.com</a></td>',
1531
                'url',
1532
                'http://example.com',
1533
                ['safe' => false, 'hide_protocol' => false],
1534
            ],
1535
            [
1536
                '<th>Data</th> <td><a href="https://example.com">https://example.com</a></td>',
1537
                'url',
1538
                'https://example.com',
1539
                ['safe' => false,
1540
                'hide_protocol' => false, ],
1541
            ],
1542
            [
1543
                '<th>Data</th> <td><a href="http://example.com">Foo</a></td>',
1544
                'url',
1545
                'Foo',
1546
                ['safe' => false, 'url' => 'http://example.com'],
1547
            ],
1548
            [
1549
                '<th>Data</th> <td><a href="http://example.com">&lt;b&gt;Foo&lt;/b&gt;</a></td>',
1550
                'url',
1551
                '<b>Foo</b>',
1552
                ['safe' => false, 'url' => 'http://example.com'],
1553
            ],
1554
            [
1555
                '<th>Data</th> <td><a href="http://example.com"><b>Foo</b></a></td>',
1556
                'url',
1557
                '<b>Foo</b>',
1558
                ['safe' => true, 'url' => 'http://example.com'],
1559
            ],
1560
            [
1561
                '<th>Data</th> <td><a href="/foo">Foo</a></td>',
1562
                'url',
1563
                'Foo',
1564
                ['safe' => false, 'route' => ['name' => 'sonata_admin_foo']],
1565
            ],
1566
            [
1567
                '<th>Data</th> <td><a href="http://localhost/foo">Foo</a></td>',
1568
                'url',
1569
                'Foo',
1570
                ['safe' => false, 'route' => [
1571
                    'name' => 'sonata_admin_foo',
1572
                    'absolute' => true,
1573
                ]],
1574
            ],
1575
            [
1576
                '<th>Data</th> <td><a href="/foo">foo/bar?a=b&amp;c=123456789</a></td>',
1577
                'url',
1578
                'http://foo/bar?a=b&c=123456789',
1579
                [
1580
                    'safe' => false,
1581
                    'route' => ['name' => 'sonata_admin_foo'],
1582
                    'hide_protocol' => true,
1583
                ],
1584
            ],
1585
            [
1586
                '<th>Data</th> <td><a href="http://localhost/foo">foo/bar?a=b&amp;c=123456789</a></td>',
1587
                'url',
1588
                'http://foo/bar?a=b&c=123456789',
1589
                ['safe' => false, 'route' => [
1590
                    'name' => 'sonata_admin_foo',
1591
                    'absolute' => true,
1592
                ], 'hide_protocol' => true],
1593
            ],
1594
            [
1595
                '<th>Data</th> <td><a href="/foo/abcd/efgh?param3=ijkl">Foo</a></td>',
1596
                'url',
1597
                'Foo',
1598
                ['safe' => false, 'route' => [
1599
                    'name' => 'sonata_admin_foo_param',
1600
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1601
                ]],
1602
            ],
1603
            [
1604
                '<th>Data</th> <td><a href="http://localhost/foo/abcd/efgh?param3=ijkl">Foo</a></td>',
1605
                'url',
1606
                'Foo',
1607
                ['safe' => false, 'route' => [
1608
                    'name' => 'sonata_admin_foo_param',
1609
                    'absolute' => true,
1610
                    'parameters' => [
1611
                        'param1' => 'abcd',
1612
                        'param2' => 'efgh',
1613
                        'param3' => 'ijkl',
1614
                    ],
1615
                ]],
1616
            ],
1617
            [
1618
                '<th>Data</th> <td><a href="/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a></td>',
1619
                'url',
1620
                'Foo',
1621
                ['safe' => false, 'route' => [
1622
                    'name' => 'sonata_admin_foo_object',
1623
                    'parameters' => [
1624
                        'param1' => 'abcd',
1625
                        'param2' => 'efgh',
1626
                        'param3' => 'ijkl',
1627
                    ],
1628
                    'identifier_parameter_name' => 'barId',
1629
                ]],
1630
            ],
1631
            [
1632
                '<th>Data</th> <td><a href="http://localhost/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a></td>',
1633
                'url',
1634
                'Foo',
1635
                ['safe' => false, 'route' => [
1636
                    'name' => 'sonata_admin_foo_object',
1637
                    'absolute' => true,
1638
                    'parameters' => [
1639
                        'param1' => 'abcd',
1640
                        'param2' => 'efgh',
1641
                        'param3' => 'ijkl',
1642
                    ],
1643
                    'identifier_parameter_name' => 'barId',
1644
                ]],
1645
            ],
1646
            [
1647
                '<th>Data</th> <td> &nbsp;</td>',
1648
                'email',
1649
                null,
1650
                [],
1651
            ],
1652
            [
1653
                '<th>Data</th> <td> <a href="mailto:[email protected]">[email protected]</a></td>',
1654
                'email',
1655
                '[email protected]',
1656
                [],
1657
            ],
1658
            [
1659
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme', 'body' => 'Message Body']).'">[email protected]</a></td>',
1660
                'email',
1661
                '[email protected]',
1662
                ['subject' => 'Main Theme', 'body' => 'Message Body'],
1663
            ],
1664
            [
1665
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme']).'">[email protected]</a></td>',
1666
                'email',
1667
                '[email protected]',
1668
                ['subject' => 'Main Theme'],
1669
            ],
1670
            [
1671
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['body' => 'Message Body']).'">[email protected]</a></td>',
1672
                'email',
1673
                '[email protected]',
1674
                ['body' => 'Message Body'],
1675
            ],
1676
            [
1677
                '<th>Data</th> <td> [email protected]</td>',
1678
                'email',
1679
                '[email protected]',
1680
                ['as_string' => true, 'subject' => 'Main Theme', 'body' => 'Message Body'],
1681
            ],
1682
            [
1683
                '<th>Data</th> <td> [email protected]</td>',
1684
                'email',
1685
                '[email protected]',
1686
                ['as_string' => true, 'subject' => 'Main Theme'],
1687
            ],
1688
            [
1689
                '<th>Data</th> <td> [email protected]</td>',
1690
                'email',
1691
                '[email protected]',
1692
                ['as_string' => true, 'body' => 'Message Body'],
1693
            ],
1694
            [
1695
                '<th>Data</th> <td> <a href="mailto:[email protected]">[email protected]</a></td>',
1696
                'email',
1697
                '[email protected]',
1698
                ['as_string' => false],
1699
            ],
1700
            [
1701
                '<th>Data</th> <td> [email protected]</td>',
1702
                'email',
1703
                '[email protected]',
1704
                ['as_string' => true],
1705
            ],
1706
            [
1707
                '<th>Data</th> <td><p><strong>Creating a Template for the Field</strong> and form</p> </td>',
1708
                'html',
1709
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1710
                [],
1711
            ],
1712
            [
1713
                '<th>Data</th> <td>Creating a Template for the Field and form </td>',
1714
                'html',
1715
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1716
                ['strip' => true],
1717
            ],
1718
            [
1719
                '<th>Data</th> <td> Creating a Template for the... </td>',
1720
                'html',
1721
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1722
                ['truncate' => true],
1723
            ],
1724
            [
1725
                '<th>Data</th> <td> Creatin... </td>',
1726
                'html',
1727
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1728
                ['truncate' => ['length' => 10]],
1729
            ],
1730
            [
1731
                '<th>Data</th> <td> Creating a Template for the Field... </td>',
1732
                'html',
1733
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1734
                ['truncate' => ['cut' => false]],
1735
            ],
1736
            [
1737
                '<th>Data</th> <td> Creating a Template for t etc. </td>',
1738
                'html',
1739
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1740
                ['truncate' => ['ellipsis' => ' etc.']],
1741
            ],
1742
            [
1743
                '<th>Data</th> <td> Creating a Template[...] </td>',
1744
                'html',
1745
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1746
                [
1747
                    'truncate' => [
1748
                        'length' => 20,
1749
                        'cut' => false,
1750
                        'ellipsis' => '[...]',
1751
                    ],
1752
                ],
1753
            ],
1754
            [
1755
                <<<'EOT'
1756
<th>Data</th> <td><div
1757
        class="sonata-readmore"
1758
        data-readmore-height="40"
1759
        data-readmore-more="Read more"
1760
        data-readmore-less="Close">
1761
            A very long string
1762
</div></td>
1763
EOT
1764
                ,
1765
                'text',
1766
                ' A very long string ',
1767
                [
1768
                    'collapse' => true,
1769
                    'safe' => false,
1770
                ],
1771
            ],
1772
            [
1773
                <<<'EOT'
1774
<th>Data</th> <td><div
1775
        class="sonata-readmore"
1776
        data-readmore-height="10"
1777
        data-readmore-more="More"
1778
        data-readmore-less="Less">
1779
            A very long string
1780
</div></td>
1781
EOT
1782
                ,
1783
                'text',
1784
                ' A very long string ',
1785
                [
1786
                    'collapse' => [
1787
                        'height' => 10,
1788
                        'more' => 'More',
1789
                        'less' => 'Less',
1790
                    ],
1791
                    'safe' => false,
1792
                ],
1793
            ],
1794
        ];
1795
    }
1796
1797
    public function getRenderViewElementWithNoValueTests(): iterable
1798
    {
1799
        return [
1800
            // NoValueException
1801
            ['<th>Data</th> <td></td>', 'string', ['safe' => false]],
1802
            ['<th>Data</th> <td></td>', 'text', ['safe' => false]],
1803
            ['<th>Data</th> <td></td>', 'textarea', ['safe' => false]],
1804
            ['<th>Data</th> <td>&nbsp;</td>', 'datetime', []],
1805
            [
1806
                '<th>Data</th> <td>&nbsp;</td>',
1807
                'datetime',
1808
                ['format' => 'd.m.Y H:i:s'],
1809
            ],
1810
            ['<th>Data</th> <td>&nbsp;</td>', 'date', []],
1811
            ['<th>Data</th> <td>&nbsp;</td>', 'date', ['format' => 'd.m.Y']],
1812
            ['<th>Data</th> <td>&nbsp;</td>', 'time', []],
1813
            ['<th>Data</th> <td></td>', 'number', ['safe' => false]],
1814
            ['<th>Data</th> <td></td>', 'integer', ['safe' => false]],
1815
            ['<th>Data</th> <td> 0 % </td>', 'percent', []],
1816
            ['<th>Data</th> <td> </td>', 'currency', ['currency' => 'EUR']],
1817
            ['<th>Data</th> <td> </td>', 'currency', ['currency' => 'GBP']],
1818
            ['<th>Data</th> <td> <ul></ul> </td>', 'array', ['safe' => false]],
1819
            [
1820
                '<th>Data</th> <td><span class="label label-danger">no</span></td>',
1821
                'boolean',
1822
                [],
1823
            ],
1824
            [
1825
                '<th>Data</th> <td> </td>',
1826
                'trans',
1827
                ['safe' => false, 'catalogue' => 'SonataAdminBundle'],
1828
            ],
1829
            [
1830
                '<th>Data</th> <td></td>',
1831
                'choice',
1832
                ['safe' => false, 'choices' => []],
1833
            ],
1834
            [
1835
                '<th>Data</th> <td></td>',
1836
                'choice',
1837
                ['safe' => false, 'choices' => [], 'multiple' => true],
1838
            ],
1839
            ['<th>Data</th> <td>&nbsp;</td>', 'url', []],
1840
            [
1841
                '<th>Data</th> <td>&nbsp;</td>',
1842
                'url',
1843
                ['url' => 'http://example.com'],
1844
            ],
1845
            [
1846
                '<th>Data</th> <td>&nbsp;</td>',
1847
                'url',
1848
                ['route' => ['name' => 'sonata_admin_foo']],
1849
            ],
1850
        ];
1851
    }
1852
1853
    public function testGetValueFromFieldDescription(): void
1854
    {
1855
        $object = new \stdClass();
1856
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
1857
1858
        $fieldDescription
1859
            ->method('getValue')
1860
            ->willReturn('test123');
1861
1862
        $this->assertSame(
1863
            'test123',
1864
            $this->getMethodAsPublic('getValueFromFieldDescription')->invoke(
1865
                $this->twigExtension,
1866
                $object,
1867
                $fieldDescription
1868
            )
1869
        );
1870
    }
1871
1872
    public function testGetValueFromFieldDescriptionWithRemoveLoopException(): void
1873
    {
1874
        $object = $this->createMock(\ArrayAccess::class);
1875
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
1876
1877
        $this->expectException(\RuntimeException::class);
1878
        $this->expectExceptionMessage('remove the loop requirement');
1879
1880
        $this->assertSame(
1881
            'anything',
1882
            $this->getMethodAsPublic('getValueFromFieldDescription')->invoke(
1883
                $this->twigExtension,
1884
                $object,
1885
                $fieldDescription,
1886
                ['loop' => true]
1887
            )
1888
        );
1889
    }
1890
1891
    public function testGetValueFromFieldDescriptionWithNoValueException(): void
1892
    {
1893
        $object = new \stdClass();
1894
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
1895
1896
        $fieldDescription
1897
            ->method('getValue')
1898
            ->willReturnCallback(static function (): void {
1899
                throw new NoValueException();
1900
            });
1901
1902
        $fieldDescription
1903
            ->method('getAssociationAdmin')
1904
            ->willReturn(null);
1905
1906
        $this->assertNull(
1907
            $this->getMethodAsPublic('getValueFromFieldDescription')->invoke(
1908
                $this->twigExtension,
1909
                $object,
1910
                $fieldDescription
1911
            )
1912
        );
1913
    }
1914
1915
    public function testGetValueFromFieldDescriptionWithNoValueExceptionNewAdminInstance(): void
1916
    {
1917
        $object = new \stdClass();
1918
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
1919
1920
        $fieldDescription
1921
            ->method('getValue')
1922
            ->willReturnCallback(static function (): void {
1923
                throw new NoValueException();
1924
            });
1925
1926
        $fieldDescription
1927
            ->method('getAssociationAdmin')
1928
            ->willReturn($this->admin);
1929
1930
        $this->admin->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
1931
            ->method('getNewInstance')
1932
            ->willReturn('foo');
1933
1934
        $this->assertSame(
1935
            'foo',
1936
            $this->getMethodAsPublic('getValueFromFieldDescription')->invoke(
1937
                $this->twigExtension,
1938
                $object,
1939
                $fieldDescription
1940
            )
1941
        );
1942
    }
1943
1944
    public function testRenderRelationElementNoObject(): void
1945
    {
1946
        $this->assertSame('foo', $this->twigExtension->renderRelationElement('foo', $this->fieldDescription));
1947
    }
1948
1949
    public function testRenderRelationElementToString(): void
1950
    {
1951
        $this->fieldDescription->expects($this->exactly(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1952
            ->method('getOption')
1953
            ->willReturnCallback(static function ($value, $default = null) {
1954
                if ('associated_property' === $value) {
1955
                    return $default;
1956
                }
1957
            });
1958
1959
        $element = new FooToString();
1960
        $this->assertSame('salut', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
1961
    }
1962
1963
    /**
1964
     * @group legacy
1965
     */
1966
    public function testDeprecatedRelationElementToString(): void
1967
    {
1968
        $this->fieldDescription->expects($this->exactly(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1969
            ->method('getOption')
1970
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1971
                if ('associated_tostring' === $value) {
1972
                    return '__toString';
1973
                }
1974
            });
1975
1976
        $element = new FooToString();
1977
        $this->assertSame(
1978
            'salut',
1979
            $this->twigExtension->renderRelationElement($element, $this->fieldDescription)
1980
        );
1981
    }
1982
1983
    /**
1984
     * @group legacy
1985
     */
1986
    public function testRenderRelationElementCustomToString(): void
1987
    {
1988
        $this->fieldDescription->expects($this->exactly(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1989
            ->method('getOption')
1990
            ->willReturnCallback(static function ($value, $default = null) {
1991
                if ('associated_property' === $value) {
1992
                    return $default;
1993
                }
1994
1995
                if ('associated_tostring' === $value) {
1996
                    return 'customToString';
1997
                }
1998
            });
1999
2000
        $element = $this->getMockBuilder(\stdClass::class)
2001
            ->setMethods(['customToString'])
2002
            ->getMock();
2003
        $element
2004
            ->method('customToString')
2005
            ->willReturn('fooBar');
2006
2007
        $this->assertSame('fooBar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
2008
    }
2009
2010
    /**
2011
     * @group legacy
2012
     */
2013
    public function testRenderRelationElementMethodNotExist(): void
2014
    {
2015
        $this->fieldDescription->expects($this->exactly(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2016
            ->method('getOption')
2017
2018
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2019
                if ('associated_tostring' === $value) {
2020
                    return 'nonExistedMethod';
2021
                }
2022
            });
2023
2024
        $element = new \stdClass();
2025
        $this->expectException(\RuntimeException::class);
2026
        $this->expectExceptionMessage('You must define an `associated_property` option or create a `stdClass::__toString');
2027
2028
        $this->twigExtension->renderRelationElement($element, $this->fieldDescription);
2029
    }
2030
2031
    public function testRenderRelationElementWithPropertyPath(): void
2032
    {
2033
        $this->fieldDescription->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2034
            ->method('getOption')
2035
2036
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2037
                if ('associated_property' === $value) {
2038
                    return 'foo';
2039
                }
2040
            });
2041
2042
        $element = new \stdClass();
2043
        $element->foo = 'bar';
2044
2045
        $this->assertSame('bar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
2046
    }
2047
2048
    public function testRenderRelationElementWithClosure(): void
2049
    {
2050
        $this->fieldDescription->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2051
            ->method('getOption')
2052
2053
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2054
                if ('associated_property' === $value) {
2055
                    return static function ($element): string {
2056
                        return 'closure '.$element->foo;
2057
                    };
2058
                }
2059
            });
2060
2061
        $element = new \stdClass();
2062
        $element->foo = 'bar';
2063
2064
        $this->assertSame(
2065
            'closure bar',
2066
            $this->twigExtension->renderRelationElement($element, $this->fieldDescription)
2067
        );
2068
    }
2069
2070
    public function testGetUrlsafeIdentifier(): void
2071
    {
2072
        $entity = new \stdClass();
2073
2074
        // set admin to pool
2075
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service']);
2076
        $this->pool->setAdminClasses([\stdClass::class => ['sonata_admin_foo_service']]);
2077
2078
        $this->admin->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2079
            ->method('getUrlSafeIdentifier')
2080
            ->with($this->equalTo($entity))
2081
            ->willReturn(1234567);
2082
2083
        $this->assertSame(1234567, $this->twigExtension->getUrlSafeIdentifier($entity));
2084
    }
2085
2086
    public function testGetUrlsafeIdentifier_GivenAdmin_Foo(): void
2087
    {
2088
        $entity = new \stdClass();
2089
2090
        // set admin to pool
2091
        $this->pool->setAdminServiceIds([
2092
            'sonata_admin_foo_service',
2093
            'sonata_admin_bar_service',
2094
        ]);
2095
        $this->pool->setAdminClasses([\stdClass::class => [
2096
            'sonata_admin_foo_service',
2097
            'sonata_admin_bar_service',
2098
        ]]);
2099
2100
        $this->admin->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2101
            ->method('getUrlSafeIdentifier')
2102
            ->with($this->equalTo($entity))
2103
            ->willReturn(1234567);
2104
2105
        $this->adminBar->expects($this->never())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2106
            ->method('getUrlSafeIdentifier');
2107
2108
        $this->assertSame(1234567, $this->twigExtension->getUrlSafeIdentifier($entity, $this->admin));
2109
    }
2110
2111
    public function testGetUrlsafeIdentifier_GivenAdmin_Bar(): void
2112
    {
2113
        $entity = new \stdClass();
2114
2115
        // set admin to pool
2116
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service', 'sonata_admin_bar_service']);
2117
        $this->pool->setAdminClasses([\stdClass::class => [
2118
            'sonata_admin_foo_service',
2119
            'sonata_admin_bar_service',
2120
        ]]);
2121
2122
        $this->admin->expects($this->never())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2123
            ->method('getUrlSafeIdentifier');
2124
2125
        $this->adminBar->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2126
            ->method('getUrlSafeIdentifier')
2127
            ->with($this->equalTo($entity))
2128
            ->willReturn(1234567);
2129
2130
        $this->assertSame(1234567, $this->twigExtension->getUrlSafeIdentifier($entity, $this->adminBar));
2131
    }
2132
2133
    public function xEditableChoicesProvider()
2134
    {
2135
        return [
2136
            'needs processing' => [
2137
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2']],
2138
                [
2139
                    ['value' => 'Status1', 'text' => 'Alias1'],
2140
                    ['value' => 'Status2', 'text' => 'Alias2'],
2141
                ],
2142
            ],
2143
            'already processed' => [
2144
                ['choices' => [
2145
                    ['value' => 'Status1', 'text' => 'Alias1'],
2146
                    ['value' => 'Status2', 'text' => 'Alias2'],
2147
                ]],
2148
                [
2149
                    ['value' => 'Status1', 'text' => 'Alias1'],
2150
                    ['value' => 'Status2', 'text' => 'Alias2'],
2151
                ],
2152
            ],
2153
            'not required' => [
2154
                [
2155
                    'required' => false,
2156
                    'choices' => ['' => '', 'Status1' => 'Alias1', 'Status2' => 'Alias2'],
2157
                ],
2158
                [
2159
                    ['value' => '', 'text' => ''],
2160
                    ['value' => 'Status1', 'text' => 'Alias1'],
2161
                    ['value' => 'Status2', 'text' => 'Alias2'],
2162
                ],
2163
            ],
2164
            'not required multiple' => [
2165
                [
2166
                    'required' => false,
2167
                    'multiple' => true,
2168
                    'choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2'],
2169
                ],
2170
                [
2171
                    ['value' => 'Status1', 'text' => 'Alias1'],
2172
                    ['value' => 'Status2', 'text' => 'Alias2'],
2173
                ],
2174
            ],
2175
        ];
2176
    }
2177
2178
    /**
2179
     * @dataProvider xEditablechoicesProvider
2180
     */
2181
    public function testGetXEditableChoicesIsIdempotent(array $options, array $expectedChoices): void
2182
    {
2183
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
2184
        $fieldDescription
2185
            ->method('getOption')
2186
            ->withConsecutive(
2187
                ['choices', []],
2188
                ['catalogue'],
2189
                ['required'],
2190
                ['multiple']
2191
            )
2192
            ->will($this->onConsecutiveCalls(
2193
                $options['choices'],
2194
                'MyCatalogue',
2195
                $options['multiple'] ?? null
2196
            ));
2197
2198
        $this->assertSame($expectedChoices, $this->twigExtension->getXEditableChoices($fieldDescription));
2199
    }
2200
2201
    public function select2LocalesProvider()
2202
    {
2203
        return [
2204
            ['ar', 'ar'],
2205
            ['az', 'az'],
2206
            ['bg', 'bg'],
2207
            ['ca', 'ca'],
2208
            ['cs', 'cs'],
2209
            ['da', 'da'],
2210
            ['de', 'de'],
2211
            ['el', 'el'],
2212
            [null, 'en'],
2213
            ['es', 'es'],
2214
            ['et', 'et'],
2215
            ['eu', 'eu'],
2216
            ['fa', 'fa'],
2217
            ['fi', 'fi'],
2218
            ['fr', 'fr'],
2219
            ['gl', 'gl'],
2220
            ['he', 'he'],
2221
            ['hr', 'hr'],
2222
            ['hu', 'hu'],
2223
            ['id', 'id'],
2224
            ['is', 'is'],
2225
            ['it', 'it'],
2226
            ['ja', 'ja'],
2227
            ['ka', 'ka'],
2228
            ['ko', 'ko'],
2229
            ['lt', 'lt'],
2230
            ['lv', 'lv'],
2231
            ['mk', 'mk'],
2232
            ['ms', 'ms'],
2233
            ['nb', 'nb'],
2234
            ['nl', 'nl'],
2235
            ['pl', 'pl'],
2236
            ['pt-PT', 'pt'],
2237
            ['pt-BR', 'pt-BR'],
2238
            ['pt-PT', 'pt-PT'],
2239
            ['ro', 'ro'],
2240
            ['rs', 'rs'],
2241
            ['ru', 'ru'],
2242
            ['sk', 'sk'],
2243
            ['sv', 'sv'],
2244
            ['th', 'th'],
2245
            ['tr', 'tr'],
2246
            ['ug-CN', 'ug'],
2247
            ['ug-CN', 'ug-CN'],
2248
            ['uk', 'uk'],
2249
            ['vi', 'vi'],
2250
            ['zh-CN', 'zh'],
2251
            ['zh-CN', 'zh-CN'],
2252
            ['zh-TW', 'zh-TW'],
2253
        ];
2254
    }
2255
2256
    /**
2257
     * @dataProvider select2LocalesProvider
2258
     */
2259
    public function testCanonicalizedLocaleForSelect2(?string $expected, string $original): void
2260
    {
2261
        $this->assertSame($expected, $this->twigExtension->getCanonicalizedLocaleForSelect2($this->mockExtensionContext($original)));
2262
    }
2263
2264
    public function momentLocalesProvider(): array
2265
    {
2266
        return [
2267
            ['af', 'af'],
2268
            ['ar-dz', 'ar-dz'],
2269
            ['ar', 'ar'],
2270
            ['ar-ly', 'ar-ly'],
2271
            ['ar-ma', 'ar-ma'],
2272
            ['ar-sa', 'ar-sa'],
2273
            ['ar-tn', 'ar-tn'],
2274
            ['az', 'az'],
2275
            ['be', 'be'],
2276
            ['bg', 'bg'],
2277
            ['bn', 'bn'],
2278
            ['bo', 'bo'],
2279
            ['br', 'br'],
2280
            ['bs', 'bs'],
2281
            ['ca', 'ca'],
2282
            ['cs', 'cs'],
2283
            ['cv', 'cv'],
2284
            ['cy', 'cy'],
2285
            ['da', 'da'],
2286
            ['de-at', 'de-at'],
2287
            ['de', 'de'],
2288
            ['de', 'de-de'],
2289
            ['dv', 'dv'],
2290
            ['el', 'el'],
2291
            [null, 'en'],
2292
            [null, 'en-us'],
2293
            ['en-au', 'en-au'],
2294
            ['en-ca', 'en-ca'],
2295
            ['en-gb', 'en-gb'],
2296
            ['en-ie', 'en-ie'],
2297
            ['en-nz', 'en-nz'],
2298
            ['eo', 'eo'],
2299
            ['es-do', 'es-do'],
2300
            ['es', 'es-ar'],
2301
            ['es', 'es-mx'],
2302
            ['es', 'es'],
2303
            ['et', 'et'],
2304
            ['eu', 'eu'],
2305
            ['fa', 'fa'],
2306
            ['fi', 'fi'],
2307
            ['fo', 'fo'],
2308
            ['fr-ca', 'fr-ca'],
2309
            ['fr-ch', 'fr-ch'],
2310
            ['fr', 'fr-fr'],
2311
            ['fr', 'fr'],
2312
            ['fy', 'fy'],
2313
            ['gd', 'gd'],
2314
            ['gl', 'gl'],
2315
            ['he', 'he'],
2316
            ['hi', 'hi'],
2317
            ['hr', 'hr'],
2318
            ['hu', 'hu'],
2319
            ['hy-am', 'hy-am'],
2320
            ['id', 'id'],
2321
            ['is', 'is'],
2322
            ['it', 'it'],
2323
            ['ja', 'ja'],
2324
            ['jv', 'jv'],
2325
            ['ka', 'ka'],
2326
            ['kk', 'kk'],
2327
            ['km', 'km'],
2328
            ['ko', 'ko'],
2329
            ['ky', 'ky'],
2330
            ['lb', 'lb'],
2331
            ['lo', 'lo'],
2332
            ['lt', 'lt'],
2333
            ['lv', 'lv'],
2334
            ['me', 'me'],
2335
            ['mi', 'mi'],
2336
            ['mk', 'mk'],
2337
            ['ml', 'ml'],
2338
            ['mr', 'mr'],
2339
            ['ms', 'ms'],
2340
            ['ms-my', 'ms-my'],
2341
            ['my', 'my'],
2342
            ['nb', 'nb'],
2343
            ['ne', 'ne'],
2344
            ['nl-be', 'nl-be'],
2345
            ['nl', 'nl'],
2346
            ['nl', 'nl-nl'],
2347
            ['nn', 'nn'],
2348
            ['pa-in', 'pa-in'],
2349
            ['pl', 'pl'],
2350
            ['pt-br', 'pt-br'],
2351
            ['pt', 'pt'],
2352
            ['ro', 'ro'],
2353
            ['ru', 'ru'],
2354
            ['se', 'se'],
2355
            ['si', 'si'],
2356
            ['sk', 'sk'],
2357
            ['sl', 'sl'],
2358
            ['sq', 'sq'],
2359
            ['sr-cyrl', 'sr-cyrl'],
2360
            ['sr', 'sr'],
2361
            ['ss', 'ss'],
2362
            ['sv', 'sv'],
2363
            ['sw', 'sw'],
2364
            ['ta', 'ta'],
2365
            ['te', 'te'],
2366
            ['tet', 'tet'],
2367
            ['th', 'th'],
2368
            ['tlh', 'tlh'],
2369
            ['tl-ph', 'tl-ph'],
2370
            ['tr', 'tr'],
2371
            ['tzl', 'tzl'],
2372
            ['tzm', 'tzm'],
2373
            ['tzm-latn', 'tzm-latn'],
2374
            ['uk', 'uk'],
2375
            ['uz', 'uz'],
2376
            ['vi', 'vi'],
2377
            ['x-pseudo', 'x-pseudo'],
2378
            ['yo', 'yo'],
2379
            ['zh-cn', 'zh-cn'],
2380
            ['zh-hk', 'zh-hk'],
2381
            ['zh-tw', 'zh-tw'],
2382
        ];
2383
    }
2384
2385
    /**
2386
     * @dataProvider momentLocalesProvider
2387
     */
2388
    public function testCanonicalizedLocaleForMoment(?string $expected, string $original): void
2389
    {
2390
        $this->assertSame($expected, $this->twigExtension->getCanonicalizedLocaleForMoment($this->mockExtensionContext($original)));
2391
    }
2392
2393
    public function testIsGrantedAffirmative(): void
2394
    {
2395
        $this->assertTrue(
2396
            $this->twigExtension->isGrantedAffirmative(['foo', 'bar'])
2397
        );
2398
        $this->assertTrue($this->twigExtension->isGrantedAffirmative('foo'));
2399
        $this->assertTrue($this->twigExtension->isGrantedAffirmative('bar'));
2400
    }
2401
2402
    /**
2403
     * This method generates url part for Twig layout.
2404
     */
2405
    private function buildTwigLikeUrl(array $url): string
2406
    {
2407
        return htmlspecialchars(http_build_query($url, '', '&', PHP_QUERY_RFC3986));
2408
    }
2409
2410
    private function getMethodAsPublic($privateMethod): \ReflectionMethod
2411
    {
2412
        $reflection = new \ReflectionMethod('Sonata\AdminBundle\Twig\Extension\SonataAdminExtension', $privateMethod);
2413
        $reflection->setAccessible(true);
2414
2415
        return $reflection;
2416
    }
2417
2418
    private function removeExtraWhitespace(string $string): string
2419
    {
2420
        return trim(preg_replace(
2421
            '/\s+/',
2422
            ' ',
2423
            $string
2424
        ));
2425
    }
2426
2427
    private function mockExtensionContext(string $locale): array
2428
    {
2429
        $request = $this->createMock(Request::class);
2430
        $request->method('getLocale')->willReturn($locale);
2431
        $appVariable = $this->createMock(AppVariable::class);
2432
        $appVariable->method('getRequest')->willReturn($request);
2433
2434
        return ['app' => $appVariable];
2435
    }
2436
}
2437