Completed
Push — master ( 3fd2dd...aba624 )
by Grégoire
04:19
created

tests/Form/FormMapperTest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Form;
15
16
use PHPUnit\Framework\TestCase;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Admin\BaseFieldDescription;
19
use Sonata\AdminBundle\Builder\FormContractorInterface;
20
use Sonata\AdminBundle\Form\FormMapper;
21
use Sonata\AdminBundle\Model\ModelManagerInterface;
22
use Sonata\AdminBundle\Tests\Fixtures\Admin\CleanAdmin;
23
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
24
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
25
use Symfony\Component\Form\Extension\Core\Type\FormType;
26
use Symfony\Component\Form\FormBuilder;
27
use Symfony\Component\Form\FormFactoryInterface;
28
use Symfony\Component\Form\ResolvedFormTypeInterface;
29
30
class FormMapperTest extends TestCase
31
{
32
    /**
33
     * @var FormContractorInterface
34
     */
35
    protected $contractor;
36
37
    /**
38
     * @var AdminInterface
39
     */
40
    protected $admin;
41
42
    /**
43
     * @var ModelManagerInterface
44
     */
45
    protected $modelManager;
46
47
    /**
48
     * @var FormMapper
49
     */
50
    protected $formMapper;
51
52
    public function setUp(): void
53
    {
54
        $this->contractor = $this->getMockForAbstractClass(FormContractorInterface::class);
55
56
        $formFactory = $this->getMockForAbstractClass(FormFactoryInterface::class);
57
        $eventDispatcher = $this->getMockForAbstractClass(EventDispatcherInterface::class);
58
59
        $formBuilder = new FormBuilder('test', 'stdClass', $eventDispatcher, $formFactory);
60
61
        $this->admin = new CleanAdmin('code', 'class', 'controller');
62
63
        $this->modelManager = $this->getMockForAbstractClass(ModelManagerInterface::class);
64
65
        $this->modelManager->expects($this->any())
66
            ->method('getNewFieldDescriptionInstance')
67
            ->will($this->returnCallback(function ($class, $name, array $options = []) {
68
                $fieldDescription = $this->getFieldDescriptionMock();
69
                $fieldDescription->setName($name);
70
                $fieldDescription->setOptions($options);
71
72
                return $fieldDescription;
73
            }));
74
75
        $this->admin->setModelManager($this->modelManager);
76
77
        $labelTranslatorStrategy = $this->getMockForAbstractClass(LabelTranslatorStrategyInterface::class);
78
        $this->admin->setLabelTranslatorStrategy($labelTranslatorStrategy);
79
80
        $this->formMapper = new FormMapper(
81
            $this->contractor,
82
            $formBuilder,
83
            $this->admin
84
        );
85
    }
86
87
    public function testWithNoOptions(): void
88
    {
89
        $this->formMapper->with('foobar');
90
91
        $this->assertSame(['default' => [
92
            'collapsed' => false,
93
            'class' => false,
94
            'description' => false,
95
            'label' => 'default',
96
            'translation_domain' => null,
97
            'name' => 'default',
98
            'box_class' => 'box box-primary',
99
            'auto_created' => true,
100
            'groups' => ['foobar'],
101
            'tab' => true,
102
        ]], $this->admin->getFormTabs());
103
104
        $this->assertSame(['foobar' => [
105
            'collapsed' => false,
106
            'class' => false,
107
            'description' => false,
108
            'label' => 'foobar',
109
            'translation_domain' => null,
110
            'name' => 'foobar',
111
            'box_class' => 'box box-primary',
112
            'fields' => [],
113
        ]], $this->admin->getFormGroups());
114
    }
115
116
    public function testWithOptions(): void
117
    {
118
        $this->formMapper->with('foobar', [
119
            'translation_domain' => 'Foobar',
120
        ]);
121
122
        $this->assertSame(['foobar' => [
123
            'collapsed' => false,
124
            'class' => false,
125
            'description' => false,
126
            'label' => 'foobar',
127
            'translation_domain' => 'Foobar',
128
            'name' => 'foobar',
129
            'box_class' => 'box box-primary',
130
            'fields' => [],
131
        ]], $this->admin->getFormGroups());
132
133
        $this->assertSame(['default' => [
134
            'collapsed' => false,
135
            'class' => false,
136
            'description' => false,
137
            'label' => 'default',
138
            'translation_domain' => 'Foobar',
139
            'name' => 'default',
140
            'box_class' => 'box box-primary',
141
            'auto_created' => true,
142
            'groups' => ['foobar'],
143
            'tab' => true,
144
        ]], $this->admin->getFormTabs());
145
    }
146
147
    public function testWithFieldsCascadeTranslationDomain(): void
148
    {
149
        $this->contractor->expects($this->once())
150
            ->method('getDefaultOptions')
151
            ->will($this->returnValue([]));
152
153
        $this->formMapper->with('foobar', [
154
                'translation_domain' => 'Foobar',
155
            ])
156
            ->add('foo', 'bar')
157
        ->end();
158
159
        $fieldDescription = $this->admin->getFormFieldDescription('foo');
160
        $this->assertSame('foo', $fieldDescription->getName());
161
        $this->assertSame('bar', $fieldDescription->getType());
162
        $this->assertSame('Foobar', $fieldDescription->getTranslationDomain());
163
164
        $this->assertTrue($this->formMapper->has('foo'));
165
166
        $this->assertSame(['default' => [
167
            'collapsed' => false,
168
            'class' => false,
169
            'description' => false,
170
            'label' => 'default',
171
            'translation_domain' => 'Foobar',
172
            'name' => 'default',
173
            'box_class' => 'box box-primary',
174
            'auto_created' => true,
175
            'groups' => ['foobar'],
176
            'tab' => true,
177
        ]], $this->admin->getFormTabs());
178
179
        $this->assertSame(['foobar' => [
180
            'collapsed' => false,
181
            'class' => false,
182
            'description' => false,
183
            'label' => 'foobar',
184
            'translation_domain' => 'Foobar',
185
            'name' => 'foobar',
186
            'box_class' => 'box box-primary',
187
            'fields' => [
188
                'foo' => 'foo',
189
            ],
190
        ]], $this->admin->getFormGroups());
191
    }
192
193
    /**
194
     * @doesNotPerformAssertions
195
     */
196
    public function testRemoveCascadeRemoveFieldFromFormGroup(): void
197
    {
198
        $this->formMapper->with('foo');
199
        $this->formMapper->remove('foo');
200
    }
201
202
    public function testIfTrueApply(): void
203
    {
204
        $this->contractor->expects($this->once())
205
            ->method('getDefaultOptions')
206
            ->will($this->returnValue([]));
207
208
        $this->formMapper
209
            ->ifTrue(true)
210
            ->add('foo', 'bar')
211
            ->ifEnd()
212
        ;
213
214
        $this->assertTrue($this->formMapper->has('foo'));
215
    }
216
217
    public function testIfTrueNotApply(): void
218
    {
219
        $this->formMapper
220
            ->ifTrue(false)
221
            ->add('foo', 'bar')
222
            ->ifEnd()
223
        ;
224
225
        $this->assertFalse($this->formMapper->has('foo'));
226
    }
227
228
    public function testIfTrueCombination(): void
229
    {
230
        $this->contractor->expects($this->once())
231
            ->method('getDefaultOptions')
232
            ->will($this->returnValue([]));
233
234
        $this->formMapper
235
            ->ifTrue(false)
236
            ->add('foo', 'bar')
237
            ->ifEnd()
238
            ->add('baz', 'foobaz')
239
        ;
240
241
        $this->assertFalse($this->formMapper->has('foo'));
242
        $this->assertTrue($this->formMapper->has('baz'));
243
    }
244
245
    public function testIfFalseApply(): void
246
    {
247
        $this->contractor->expects($this->once())
248
            ->method('getDefaultOptions')
249
            ->will($this->returnValue([]));
250
251
        $this->formMapper
252
            ->ifFalse(false)
253
            ->add('foo', 'bar')
254
            ->ifEnd()
255
        ;
256
257
        $this->assertTrue($this->formMapper->has('foo'));
258
    }
259
260
    public function testIfFalseNotApply(): void
261
    {
262
        $this->formMapper
263
            ->ifFalse(true)
264
            ->add('foo', 'bar')
265
            ->ifEnd()
266
        ;
267
268
        $this->assertFalse($this->formMapper->has('foo'));
269
    }
270
271
    public function testIfFalseCombination(): void
272
    {
273
        $this->contractor->expects($this->once())
274
            ->method('getDefaultOptions')
275
            ->will($this->returnValue([]));
276
277
        $this->formMapper
278
            ->ifFalse(true)
279
            ->add('foo', 'bar')
280
            ->ifEnd()
281
            ->add('baz', 'foobaz')
282
        ;
283
284
        $this->assertFalse($this->formMapper->has('foo'));
285
        $this->assertTrue($this->formMapper->has('baz'));
286
    }
287
288
    public function testIfTrueNested(): void
289
    {
290
        $this->expectException(\RuntimeException::class);
291
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
292
293
        $this->formMapper->ifTrue(true);
294
        $this->formMapper->ifTrue(true);
295
    }
296
297
    public function testIfFalseNested(): void
298
    {
299
        $this->expectException(\RuntimeException::class);
300
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
301
302
        $this->formMapper->ifFalse(false);
303
        $this->formMapper->ifFalse(false);
304
    }
305
306
    public function testIfCombinationNested(): void
307
    {
308
        $this->expectException(\RuntimeException::class);
309
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
310
311
        $this->formMapper->ifTrue(true);
312
        $this->formMapper->ifFalse(false);
313
    }
314
315
    public function testIfFalseCombinationNested2(): void
316
    {
317
        $this->expectException(\RuntimeException::class);
318
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
319
320
        $this->formMapper->ifFalse(false);
321
        $this->formMapper->ifTrue(true);
322
    }
323
324
    public function testIfFalseCombinationNested3(): void
325
    {
326
        $this->expectException(\RuntimeException::class);
327
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
328
329
        $this->formMapper->ifFalse(true);
330
        $this->formMapper->ifTrue(false);
331
    }
332
333
    public function testIfFalseCombinationNested4(): void
334
    {
335
        $this->expectException(\RuntimeException::class);
336
        $this->expectExceptionMessage('Cannot nest ifTrue or ifFalse call');
337
338
        $this->formMapper->ifTrue(false);
339
        $this->formMapper->ifFalse(true);
340
    }
341
342
    public function testAddAcceptFormBuilder(): void
343
    {
344
        $formBuilder = $this
345
            ->getMockBuilder(FormBuilder::class)
346
            ->disableOriginalConstructor()
347
            ->getMock();
348
349
        $formBuilder->expects($this->any())
350
            ->method('getName')
351
            ->will($this->returnValue('foo'));
352
353
        $formType = $this
354
            ->getMockBuilder(ResolvedFormTypeInterface::class)
355
            ->getMock();
356
357
        $innerType = $this
358
            ->getMockBuilder(FormType::class)
359
            ->getMock();
360
361
        $formType->expects($this->once())
362
            ->method('getInnerType')
363
            ->will($this->returnValue($innerType));
364
365
        $formBuilder->expects($this->once())
366
            ->method('getType')
367
            ->will($this->returnValue($formType));
368
369
        $this->formMapper->add($formBuilder);
370
        $this->assertSame($this->formMapper->get('foo'), $formBuilder);
371
    }
372
373
    public function testAddFormBuilderWithType(): void
374
    {
375
        $formBuilder = $this
376
            ->getMockBuilder(FormBuilder::class)
377
            ->disableOriginalConstructor()
378
            ->getMock();
379
380
        $formBuilder->expects($this->any())
381
            ->method('getName')
382
            ->will($this->returnValue('foo'));
383
384
        $formBuilder->expects($this->never())
385
            ->method('getType');
386
387
        $this->formMapper->add($formBuilder, FormType::class);
388
        $this->assertSame($this->formMapper->get('foo'), $formBuilder);
389
    }
390
391
    public function testGroupRemovingWithoutTab(): void
392
    {
393
        $this->formMapper->with('foobar');
394
395
        $this->formMapper->removeGroup('foobar');
396
397
        $this->assertSame([], $this->admin->getFormGroups());
398
    }
399
400
    public function testGroupRemovingWithTab(): void
401
    {
402
        $this->formMapper->tab('mytab')->with('foobar');
403
404
        $this->formMapper->removeGroup('foobar', 'mytab');
405
406
        $this->assertSame([], $this->admin->getFormGroups());
407
    }
408
409
    public function testGroupRemovingWithoutTabAndWithTabRemoving(): void
410
    {
411
        $this->formMapper->with('foobar');
412
413
        $this->formMapper->removeGroup('foobar', 'default', true);
414
415
        $this->assertSame([], $this->admin->getFormGroups());
416
        $this->assertSame([], $this->admin->getFormTabs());
417
    }
418
419
    public function testGroupRemovingWithTabAndWithTabRemoving(): void
420
    {
421
        $this->formMapper->tab('mytab')->with('foobar');
422
423
        $this->formMapper->removeGroup('foobar', 'mytab', true);
424
425
        $this->assertSame([], $this->admin->getFormGroups());
426
        $this->assertSame([], $this->admin->getFormTabs());
427
    }
428
429
    public function testKeys(): void
430
    {
431
        $this->contractor->expects($this->any())
432
            ->method('getDefaultOptions')
433
            ->will($this->returnValue([]));
434
435
        $this->formMapper
436
            ->add('foo', 'bar')
437
            ->add('baz', 'foobaz')
438
        ;
439
440
        $this->assertSame(['foo', 'baz'], $this->formMapper->keys());
441
    }
442
443
    public function testFieldNameIsSanitized(): void
444
    {
445
        $this->contractor->expects($this->any())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundl...ormContractorInterface>.

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...
446
            ->method('getDefaultOptions')
447
            ->will($this->returnValue([]));
448
449
        $this->formMapper
450
            ->add('fo.o', 'bar')
451
            ->add('ba__z', 'foobaz')
452
        ;
453
454
        $this->assertSame(['fo__o', 'ba____z'], $this->formMapper->keys());
455
    }
456
457
    private function getFieldDescriptionMock(
458
        ?string $name = null,
459
        ?string $label = null,
460
        ?string $translationDomain = null
461
    ): BaseFieldDescription {
462
        $fieldDescription = $this->getMockForAbstractClass(BaseFieldDescription::class);
463
464
        if (null !== $name) {
465
            $fieldDescription->setName($name);
466
        }
467
468
        if (null !== $label) {
469
            $fieldDescription->setOption('label', $label);
470
        }
471
472
        if (null !== $translationDomain) {
473
            $fieldDescription->setOption('translation_domain', $translationDomain);
474
        }
475
476
        return $fieldDescription;
477
    }
478
}
479