Completed
Push — 3.x ( 1c4316...c54077 )
by Jordi Sala
05:23
created

testRetrieveAutocompleteItemsActionNotGranted()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\AdminBundle\Tests\Controller;
13
14
use Doctrine\Common\Persistence\ManagerRegistry;
15
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
16
use Doctrine\Common\Persistence\ObjectManager;
17
use PHPUnit\Framework\TestCase;
18
use Prophecy\Argument;
19
use Sonata\AdminBundle\Admin\AbstractAdmin;
20
use Sonata\AdminBundle\Admin\AdminHelper;
21
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
22
use Sonata\AdminBundle\Admin\Pool;
23
use Sonata\AdminBundle\Controller\HelperController;
24
use Sonata\AdminBundle\Datagrid\DatagridInterface;
25
use Sonata\AdminBundle\Datagrid\Pager;
26
use Sonata\AdminBundle\Model\ModelManagerInterface;
27
use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Foo;
28
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension;
29
use Sonata\CoreBundle\Model\Metadata;
30
use Symfony\Bridge\Twig\AppVariable;
31
use Symfony\Bridge\Twig\Command\DebugCommand;
32
use Symfony\Bridge\Twig\Extension\FormExtension;
33
use Symfony\Bridge\Twig\Form\TwigRenderer;
34
use Symfony\Component\DependencyInjection\ContainerInterface;
35
use Symfony\Component\Form\Form;
36
use Symfony\Component\Form\FormBuilder;
37
use Symfony\Component\Form\FormConfigInterface;
38
use Symfony\Component\Form\FormRenderer;
39
use Symfony\Component\Form\FormView;
40
use Symfony\Component\HttpFoundation\Request;
41
use Symfony\Component\HttpFoundation\Response;
42
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
43
use Symfony\Component\PropertyAccess\PropertyAccessor;
44
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
45
use Symfony\Component\Translation\TranslatorInterface;
46
use Symfony\Component\Validator\ConstraintViolation;
47
use Symfony\Component\Validator\ConstraintViolationList;
48
use Symfony\Component\Validator\Validator\ValidatorInterface;
49
use Twig\Environment;
50
use Twig\Template;
51
52
class AdminControllerHelper_Foo
0 ignored issues
show
Coding Style introduced by
This class is not in CamelCase format.

Classes in PHP are usually named in CamelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.

Thus the name database provider becomes DatabaseProvider.

Loading history...
53
{
54
    private $bar;
55
56
    public function getAdminTitle()
57
    {
58
        return 'foo';
59
    }
60
61
    public function setEnabled($value)
0 ignored issues
show
Unused Code introduced by
The parameter $value 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...
62
    {
63
    }
64
65
    public function setBar(AdminControllerHelper_Bar $bar)
66
    {
67
        $this->bar = $bar;
68
    }
69
70
    public function getBar()
71
    {
72
        return $this->bar;
73
    }
74
}
75
76
class AdminControllerHelper_Bar
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style introduced by
This class is not in CamelCase format.

Classes in PHP are usually named in CamelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.

Thus the name database provider becomes DatabaseProvider.

Loading history...
77
{
78
    public function getAdminTitle()
79
    {
80
        return 'bar';
81
    }
82
83
    public function setEnabled($value)
0 ignored issues
show
Unused Code introduced by
The parameter $value 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...
84
    {
85
    }
86
87
    public function getEnabled()
88
    {
89
    }
90
}
91
92
class HelperControllerTest extends TestCase
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
93
{
94
    /**
95
     * {@inheritdoc}
96
     */
97
    protected function setUp()
98
    {
99
        $this->pool = $this->prophesize(Pool::class);
100
        $this->twig = $this->prophesize(Environment::class);
101
        $this->helper = $this->prophesize(AdminHelper::class);
102
        $this->validator = $this->prophesize(ValidatorInterface::class);
103
        $this->admin = $this->prophesize(AbstractAdmin::class);
104
105
        $this->pool->getInstance(Argument::any())->willReturn($this->admin->reveal());
106
        $this->admin->setRequest(Argument::type(Request::class))->shouldBeCalled();
107
108
        $this->controller = new HelperController(
109
            $this->twig->reveal(),
110
            $this->pool->reveal(),
111
            $this->helper->reveal(),
112
            $this->validator->reveal()
113
        );
114
    }
115
116
    public function testGetShortObjectDescriptionActionInvalidAdmin()
117
    {
118
        $this->expectException(NotFoundHttpException::class);
119
120
        $request = new Request([
121
            'code' => 'sonata.post.admin',
122
            'objectId' => 42,
123
            'uniqid' => 'asdasd123',
124
        ]);
125
126
        $this->pool->getInstance('sonata.post.admin')->willReturn(null);
127
        $this->admin->setRequest(Argument::type(Request::class))->shouldNotBeCalled();
128
129
        $this->controller->getShortObjectDescriptionAction($request);
130
    }
131
132
    public function testGetShortObjectDescriptionActionObjectDoesNotExist()
133
    {
134
        $this->expectException(\RuntimeException::class);
135
        $this->expectExceptionMessage('Invalid format');
136
137
        $request = new Request([
138
            'code' => 'sonata.post.admin',
139
            'objectId' => 42,
140
            'uniqid' => 'asdasd123',
141
        ]);
142
143
        $this->admin->setUniqid('asdasd123')->shouldBeCalled();
144
        $this->admin->getObject(42)->willReturn(false);
145
146
        $this->controller->getShortObjectDescriptionAction($request);
147
    }
148
149
    public function testGetShortObjectDescriptionActionEmptyObjectId()
150
    {
151
        $request = new Request([
152
            'code' => 'sonata.post.admin',
153
            'objectId' => '',
154
            'uniqid' => 'asdasd123',
155
            '_format' => 'html',
156
        ]);
157
158
        $this->admin->setUniqid('asdasd123')->shouldBeCalled();
159
        $this->admin->getObject(null)->willReturn(false);
160
161
        $response = $this->controller->getShortObjectDescriptionAction($request);
162
163
        $this->assertInstanceOf(Response::class, $response);
164
    }
165
166
    public function testGetShortObjectDescriptionActionObject()
167
    {
168
        $request = new Request([
169
            'code' => 'sonata.post.admin',
170
            'objectId' => 42,
171
            'uniqid' => 'asdasd123',
172
            '_format' => 'html',
173
        ]);
174
        $object = new AdminControllerHelper_Foo();
175
176
        $this->admin->setUniqid('asdasd123')->shouldBeCalled();
177
        $this->admin->getObject(42)->willReturn($object);
178
        $this->admin->getTemplate('short_object_description')->willReturn('template');
179
        $this->admin->toString($object)->willReturn('bar');
180
        $this->twig->render('template', [
181
            'admin' => $this->admin->reveal(),
182
            'description' => 'bar',
183
            'object' => $object,
184
            'link_parameters' => [],
185
        ])->willReturn('renderedTemplate');
186
187
        $response = $this->controller->getShortObjectDescriptionAction($request);
188
189
        $this->assertSame('renderedTemplate', $response->getContent());
190
    }
191
192
    public function testSetObjectFieldValueAction()
193
    {
194
        $object = new AdminControllerHelper_Foo();
195
        $request = new Request([
196
            'code' => 'sonata.post.admin',
197
            'objectId' => 42,
198
            'field' => 'enabled',
199
            'value' => 1,
200
            'context' => 'list',
201
        ], [], [], [], [], ['REQUEST_METHOD' => 'POST', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
202
203
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
204
        $pool = $this->prophesize(Pool::class);
205
        $template = $this->prophesize(Template::class);
206
        $translator = $this->prophesize(TranslatorInterface::class);
207
        $propertyAccessor = new PropertyAccessor();
208
209
        $this->admin->getObject(42)->willReturn($object);
210
        $this->admin->hasAccess('edit', $object)->willReturn(true);
211
        $this->admin->getListFieldDescription('enabled')->willReturn($fieldDescription->reveal());
212
        $this->admin->update($object)->shouldBeCalled();
213
        $this->admin->getTemplate('base_list_field')->willReturn('admin_template');
214
        $this->pool->getPropertyAccessor()->willReturn($propertyAccessor);
215
        $this->twig->getExtension(SonataAdminExtension::class)->willReturn(
216
            new SonataAdminExtension($pool->reveal(), null, $translator->reveal())
217
        );
218
        $this->twig->loadTemplate('admin_template')->willReturn($template->reveal());
219
        $this->twig->isDebug()->willReturn(false);
220
        $fieldDescription->getOption('editable')->willReturn(true);
221
        $fieldDescription->getAdmin()->willReturn($this->admin->reveal());
222
        $fieldDescription->getType()->willReturn('boolean');
223
        $fieldDescription->getTemplate()->willReturn(false);
224
        $fieldDescription->getValue(Argument::cetera())->willReturn('some value');
225
        $this->validator->validate($object)->willReturn(new ConstraintViolationList([]));
226
227
        $response = $this->controller->setObjectFieldValueAction($request);
228
229
        $this->assertEquals(200, $response->getStatusCode());
230
    }
231
232
    public function testSetObjectFieldValueActionOnARelationField()
233
    {
234
        $object = new AdminControllerHelper_Foo();
235
        $associationObject = new AdminControllerHelper_Bar();
236
        $request = new Request([
237
            'code' => 'sonata.post.admin',
238
            'objectId' => 42,
239
            'field' => 'bar',
240
            'value' => 1,
241
            'context' => 'list',
242
        ], [], [], [], [], ['REQUEST_METHOD' => 'POST', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
243
244
        $container = $this->prophesize(ContainerInterface::class);
245
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
246
        $managerRegistry = $this->prophesize(ManagerRegistry::class);
247
        $objectManager = $this->prophesize(ObjectManager::class);
248
        $classMetadata = $this->prophesize(ClassMetadata::class);
249
        $pool = $this->prophesize(Pool::class);
250
        $template = $this->prophesize(Template::class);
251
        $translator = $this->prophesize(TranslatorInterface::class);
252
        $propertyAccessor = new PropertyAccessor();
253
254
        $this->admin->getObject(42)->willReturn($object);
255
        $this->admin->hasAccess('edit', $object)->willReturn(true);
256
        $this->admin->getListFieldDescription('bar')->willReturn($fieldDescription->reveal());
257
        $this->admin->getManagerType()->willReturn('doctrine_orm');
258
        $this->admin->getClass()->willReturn(get_class($object));
259
        $this->admin->update($object)->shouldBeCalled();
260
        $this->admin->getTemplate('base_list_field')->willReturn('admin_template');
261
        $this->validator->validate($object)->willReturn(new ConstraintViolationList([]));
262
        $this->twig->getExtension(SonataAdminExtension::class)->willReturn(
263
            new SonataAdminExtension($pool->reveal(), null, $translator->reveal())
264
        );
265
        $this->twig->loadTemplate('field_template')->willReturn($template->reveal());
266
        $this->twig->isDebug()->willReturn(false);
267
        $this->pool->getContainer()->willReturn($container->reveal());
268
        $this->pool->getPropertyAccessor()->willReturn($propertyAccessor);
269
        $fieldDescription->getType()->willReturn('choice');
270
        $fieldDescription->getOption('editable')->willReturn(true);
271
        $fieldDescription->getOption('class')->willReturn(AdminControllerHelper_Bar::class);
272
        $fieldDescription->getAdmin()->willReturn($this->admin->reveal());
273
        $fieldDescription->getTemplate()->willReturn('field_template');
274
        $fieldDescription->getValue(Argument::cetera())->willReturn('some value');
275
        $container->get('doctrine_orm')->willReturn($managerRegistry->reveal());
276
        $managerRegistry->getManager()->willReturn($objectManager->reveal());
277
        $objectManager->getClassMetadata(get_class($object))->willReturn($classMetadata->reveal());
278
        $objectManager->find(get_class($associationObject), 1)->willReturn($associationObject);
279
        $classMetadata->hasAssociation('bar')->willReturn(true);
280
281
        $response = $this->controller->setObjectFieldValueAction($request);
282
283
        $this->assertEquals(200, $response->getStatusCode());
284
    }
285
286
    public function testAppendFormFieldElementAction()
287
    {
288
        $object = new AdminControllerHelper_Foo();
289
        $request = new Request([
290
            'code' => 'sonata.post.admin',
291
            'objectId' => 42,
292
            'field' => 'enabled',
293
            'value' => 1,
294
            'context' => 'list',
295
        ], [], [], [], [], ['REQUEST_METHOD' => 'POST']);
296
297
        $modelManager = $this->prophesize(ModelManagerInterface::class);
298
        $formView = new FormView();
299
        $form = $this->prophesize(Form::class);
300
301
        $renderer = $this->configureFormRenderer();
302
303
        $this->admin->getModelManager()->willReturn($modelManager->reveal());
304
        $this->admin->getClass()->willReturn(get_class($object));
305
        $this->admin->setSubject($object)->shouldBeCalled();
306
        $this->admin->getFormTheme()->willReturn($formView);
307
        $this->helper->appendFormFieldElement($this->admin->reveal(), $object, null)->willReturn([
308
            $this->prophesize(FieldDescriptionInterface::class),
309
            $form->reveal(),
310
        ]);
311
        $this->helper->getChildFormView($formView, null)
312
            ->willReturn($formView);
313
        $modelManager->find(get_class($object), 42)->willReturn($object);
314
        $form->createView()->willReturn($formView);
315
        $renderer->setTheme($formView, $formView)->shouldBeCalled();
316
        $renderer->searchAndRenderBlock($formView, 'widget')->willReturn('block');
317
318
        $response = $this->controller->appendFormFieldElementAction($request);
319
320
        $this->isInstanceOf(Response::class, $response);
321
        $this->assertSame($response->getContent(), 'block');
322
    }
323
324
    public function testRetrieveFormFieldElementAction()
325
    {
326
        $object = new AdminControllerHelper_Foo();
327
        $request = new Request([
328
            'code' => 'sonata.post.admin',
329
            'objectId' => 42,
330
            'field' => 'enabled',
331
            'value' => 1,
332
            'context' => 'list',
333
        ], [], [], [], [], ['REQUEST_METHOD' => 'POST']);
334
335
        $modelManager = $this->prophesize(ModelManagerInterface::class);
336
        $formView = new FormView();
337
        $form = $this->prophesize(Form::class);
338
        $formBuilder = $this->prophesize(FormBuilder::class);
339
340
        $renderer = $this->configureFormRenderer();
341
342
        $this->admin->getModelManager()->willReturn($modelManager->reveal());
343
        $this->admin->getClass()->willReturn(get_class($object));
344
        $this->admin->setSubject($object)->shouldBeCalled();
345
        $this->admin->getFormTheme()->willReturn($formView);
346
        $this->admin->getFormBuilder()->willReturn($formBuilder->reveal());
347
        $this->helper->getChildFormView($formView, null)
348
            ->willReturn($formView);
349
        $modelManager->find(get_class($object), 42)->willReturn($object);
350
        $form->setData($object)->shouldBeCalled();
351
        $form->handleRequest($request)->shouldBeCalled();
352
        $form->createView()->willReturn($formView);
353
        $formBuilder->getForm()->willReturn($form->reveal());
354
        $renderer->setTheme($formView, $formView)->shouldBeCalled();
355
        $renderer->searchAndRenderBlock($formView, 'widget')->willReturn('block');
356
357
        $response = $this->controller->retrieveFormFieldElementAction($request);
358
359
        $this->isInstanceOf(Response::class, $response);
360
        $this->assertSame($response->getContent(), 'block');
361
    }
362
363
    public function testSetObjectFieldValueActionWithViolations()
364
    {
365
        $bar = new AdminControllerHelper_Bar();
366
        $object = new AdminControllerHelper_Foo();
367
        $object->setBar($bar);
368
        $request = new Request([
369
            'code' => 'sonata.post.admin',
370
            'objectId' => 42,
371
            'field' => 'bar.enabled',
372
            'value' => 1,
373
            'context' => 'list',
374
        ], [], [], [], [], ['REQUEST_METHOD' => 'POST', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
375
376
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
377
        $propertyAccessor = new PropertyAccessor();
378
379
        $this->pool->getPropertyAccessor()->willReturn($propertyAccessor);
380
        $this->admin->getObject(42)->willReturn($object);
381
        $this->admin->hasAccess('edit', $object)->willReturn(true);
382
        $this->admin->getListFieldDescription('bar.enabled')->willReturn($fieldDescription->reveal());
383
        $this->validator->validate($bar)->willReturn(new ConstraintViolationList([
384
            new ConstraintViolation('error1', null, [], null, 'enabled', null),
385
            new ConstraintViolation('error2', null, [], null, 'enabled', null),
386
        ]));
387
        $fieldDescription->getOption('editable')->willReturn(true);
388
        $fieldDescription->getType()->willReturn('boolean');
389
390
        $response = $this->controller->setObjectFieldValueAction($request);
391
392
        $this->assertEquals(400, $response->getStatusCode());
393
        $this->assertSame(json_encode("error1\nerror2"), $response->getContent());
394
    }
395
396
    public function testRetrieveAutocompleteItemsActionNotGranted()
397
    {
398
        $this->expectException(AccessDeniedException::class);
399
400
        $request = new Request([
401
            'admin_code' => 'foo.admin',
402
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
403
404
        $this->admin->hasAccess('create')->willReturn(false);
405
        $this->admin->hasAccess('edit')->willReturn(false);
406
407
        $this->controller->retrieveAutocompleteItemsAction($request);
408
    }
409
410
    public function testRetrieveAutocompleteItemsActionDisabledFormelememt()
411
    {
412
        $this->expectException(AccessDeniedException::class);
413
        $this->expectExceptionMessage('Autocomplete list can`t be retrieved because the form element is disabled or read_only.');
414
415
        $object = new AdminControllerHelper_Foo();
416
        $request = new Request([
417
            'admin_code' => 'foo.admin',
418
            'field' => 'barField',
419
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
420
421
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
422
423
        $this->configureFormConfig('barField', true);
424
425
        $this->admin->getNewInstance()->willReturn($object);
426
        $this->admin->setSubject($object)->shouldBeCalled();
427
        $this->admin->hasAccess('create')->willReturn(true);
428
        $this->admin->getFormFieldDescriptions()->willReturn(null);
429
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
430
431
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
432
        $fieldDescription->getName()->willReturn('barField');
433
434
        $this->controller->retrieveAutocompleteItemsAction($request);
435
    }
436
437
    public function testRetrieveAutocompleteItemsTooShortSearchString()
438
    {
439
        $object = new AdminControllerHelper_Foo();
440
        $request = new Request([
441
            'admin_code' => 'foo.admin',
442
            'field' => 'barField',
443
            'q' => 'so',
444
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
445
446
        $targetAdmin = $this->prophesize(AbstractAdmin::class);
447
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
448
449
        $this->configureFormConfig('barField');
450
451
        $this->admin->getNewInstance()->willReturn($object);
452
        $this->admin->setSubject($object)->shouldBeCalled();
453
        $this->admin->hasAccess('create')->willReturn(true);
454
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
455
        $this->admin->getFormFieldDescriptions()->willReturn(null);
456
        $targetAdmin->checkAccess('list')->willReturn(null);
457
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
458
        $fieldDescription->getName()->willReturn('barField');
459
        $fieldDescription->getAssociationAdmin()->willReturn($targetAdmin->reveal());
460
461
        $response = $this->controller->retrieveAutocompleteItemsAction($request);
462
463
        $this->isInstanceOf(Response::class, $response);
464
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
465
        $this->assertSame('{"status":"KO","message":"Too short search string."}', $response->getContent());
466
    }
467
468
    public function testRetrieveAutocompleteItems()
469
    {
470
        $entity = new Foo();
471
        $request = new Request([
472
            'admin_code' => 'foo.admin',
473
            'field' => 'barField',
474
            'q' => 'sonata',
475
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
476
477
        $targetAdmin = $this->prophesize(AbstractAdmin::class);
478
        $datagrid = $this->prophesize(DatagridInterface::class);
479
        $metadata = $this->prophesize(Metadata::class);
480
        $pager = $this->prophesize(Pager::class);
481
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
482
483
        $this->configureFormConfig('barField');
484
485
        $this->admin->getNewInstance()->willReturn($entity);
486
        $this->admin->setSubject($entity)->shouldBeCalled();
487
        $this->admin->hasAccess('create')->willReturn(true);
488
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
489
        $this->admin->getFormFieldDescriptions()->willReturn(null);
490
        $this->admin->id($entity)->willReturn(123);
491
        $targetAdmin->checkAccess('list')->willReturn(null);
492
        $targetAdmin->setPersistFilters(false)->willReturn(null);
493
        $targetAdmin->getDatagrid()->willReturn($datagrid->reveal());
494
        $targetAdmin->getObjectMetadata($entity)->willReturn($metadata->reveal());
495
        $metadata->getTitle()->willReturn('FOO');
496
        $datagrid->hasFilter('foo')->willReturn(true);
497
        $datagrid->setValue('foo', null, 'sonata')->shouldBeCalled();
498
        $datagrid->setValue('_per_page', null, 10)->shouldBeCalled();
499
        $datagrid->setValue('_page', null, 1)->shouldBeCalled();
500
        $datagrid->buildPager()->willReturn(null);
501
        $datagrid->getPager()->willReturn($pager->reveal());
502
        $pager->getResults()->willReturn([$entity]);
503
        $pager->isLastPage()->willReturn(true);
504
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
505
        $fieldDescription->getName()->willReturn('barField');
506
        $fieldDescription->getAssociationAdmin()->willReturn($targetAdmin->reveal());
507
508
        $response = $this->controller->retrieveAutocompleteItemsAction($request);
509
510
        $this->isInstanceOf(Response::class, $response);
511
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
512
        $this->assertSame('{"status":"OK","more":false,"items":[{"id":123,"label":"FOO"}]}', $response->getContent());
513
    }
514
515
    private function configureFormConfig($field, $disabled = false)
516
    {
517
        $form = $this->prophesize(Form::class);
518
        $formType = $this->prophesize(Form::class);
519
        $formConfig = $this->prophesize(FormConfigInterface::class);
520
521
        $this->admin->getForm()->willReturn($form->reveal());
522
        $form->get($field)->willReturn($formType->reveal());
523
        $formType->getConfig()->willReturn($formConfig->reveal());
524
        $formConfig->getAttribute('disabled')->willReturn($disabled);
525
        $formConfig->getAttribute('property')->willReturn('foo');
526
        $formConfig->getAttribute('callback')->willReturn(null);
527
        $formConfig->getAttribute('minimum_input_length')->willReturn(3);
528
        $formConfig->getAttribute('items_per_page')->willReturn(10);
529
        $formConfig->getAttribute('req_param_name_page_number')->willReturn('_page');
530
        $formConfig->getAttribute('to_string_callback')->willReturn(null);
531
        $formConfig->getAttribute('target_admin_access_action')->willReturn('list');
532
    }
533
534
    private function configureFormRenderer()
535
    {
536
        $runtime = $this->prophesize(FormRenderer::class);
537
538
        // Remove the condition when dropping sf < 3.2
539
        if (!method_exists(AppVariable::class, 'getToken')) {
540
            $extension = $this->prophesize(FormExtension::class);
541
542
            $this->twig->getExtension(FormExtension::class)->willReturn($extension->reveal());
543
            $extension->initRuntime($this->twig->reveal())->shouldBeCalled();
544
            $extension->renderer = $runtime->reveal();
545
546
            return $runtime;
547
        }
548
549
        // Remove the condition when dropping sf < 3.4
550
        if (!method_exists(DebugCommand::class, 'getLoaderPaths')) {
551
            $twigRuntime = $this->prophesize(TwigRenderer::class);
552
553
            $this->twig->getRuntime(TwigRenderer::class)->willReturn($twigRuntime->reveal());
554
            $twigRuntime->setEnvironment($this->twig->reveal())->shouldBeCalled();
555
556
            return $twigRuntime;
557
        }
558
559
        $this->twig->getRuntime(FormRenderer::class)->willReturn($runtime->reveal());
560
561
        return $runtime;
562
    }
563
}
564