Completed
Push — master ( 2eb0ca...af375c )
by Marko
14s
created

RetrieveAutocompleteItemsActionTest   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 287
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 287
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 10 1
A testRetrieveAutocompleteItemsActionNotGranted() 0 14 1
A testRetrieveAutocompleteItemsActionDisabledFormelememt() 0 27 1
A testRetrieveAutocompleteItemsTooShortSearchString() 0 31 1
A testRetrieveAutocompleteItems() 0 32 1
A testRetrieveAutocompleteItemsComplexPropertyArray() 0 32 1
A testRetrieveAutocompleteItemsComplexProperty() 0 25 1
A configureAutocompleteItemsDatagrid() 0 34 1
A configureFormConfig() 0 18 1
A configureFormConfigComplexProperty() 0 18 1
A configureFormConfigComplexPropertyArray() 0 18 1
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\Action;
15
16
use PHPUnit\Framework\TestCase;
17
use Prophecy\Argument;
18
use Sonata\AdminBundle\Action\GetShortObjectDescriptionAction;
19
use Sonata\AdminBundle\Action\RetrieveAutocompleteItemsAction;
20
use Sonata\AdminBundle\Admin\AbstractAdmin;
21
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
22
use Sonata\AdminBundle\Admin\Pool;
23
use Sonata\AdminBundle\Datagrid\Pager;
24
use Sonata\AdminBundle\Tests\Fixtures\Filter\FooFilter;
25
use Sonata\CoreBundle\Model\Metadata;
26
use Sonata\DatagridBundle\Datagrid\DatagridInterface;
27
use Symfony\Component\Form\Form;
28
use Symfony\Component\Form\FormConfigInterface;
29
use Symfony\Component\HttpFoundation\Request;
30
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
31
32
final class RetrieveAutocompleteItemsActionTest extends TestCase
33
{
34
    /**
35
     * @var Pool
36
     */
37
    private $pool;
38
39
    /**
40
     * @var GetShortObjectDescriptionAction
41
     */
42
    private $action;
43
44
    /**
45
     * @var AbstractAdmin
46
     */
47
    private $admin;
48
49
    protected function setUp(): void
50
    {
51
        $this->admin = $this->prophesize(AbstractAdmin::class);
52
        $this->admin->setRequest(Argument::type(Request::class))->shouldBeCalled();
53
        $this->pool = $this->prophesize(Pool::class);
54
        $this->pool->getInstance(Argument::any())->willReturn($this->admin->reveal());
55
        $this->action = new RetrieveAutocompleteItemsAction(
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Sonata\AdminBundle\...($this->pool->reveal()) of type object<Sonata\AdminBundl...utocompleteItemsAction> is incompatible with the declared type object<Sonata\AdminBundl...bjectDescriptionAction> of property $action.

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...
56
            $this->pool->reveal()
57
        );
58
    }
59
60
    public function testRetrieveAutocompleteItemsActionNotGranted(): void
61
    {
62
        $this->expectException(AccessDeniedException::class);
63
64
        $request = new Request([
65
            'admin_code' => 'foo.admin',
66
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
67
68
        $this->admin->hasAccess('create')->willReturn(false);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->hasAccess('create') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
69
        $this->admin->hasAccess('edit')->willReturn(false);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->hasAccess('edit') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
70
71
        $action = $this->action;
72
        $action($request);
73
    }
74
75
    public function testRetrieveAutocompleteItemsActionDisabledFormelememt(): void
76
    {
77
        $this->expectException(AccessDeniedException::class);
78
        $this->expectExceptionMessage('Autocomplete list can`t be retrieved because the form element is disabled or read_only.');
79
80
        $object = new \stdClass();
81
        $request = new Request([
82
            'admin_code' => 'foo.admin',
83
            'field' => 'barField',
84
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
85
86
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
87
88
        $this->configureFormConfig('barField', true);
89
90
        $this->admin->getNewInstance()->willReturn($object);
91
        $this->admin->setSubject($object)->shouldBeCalled();
0 ignored issues
show
Bug introduced by
The method shouldBeCalled cannot be called on $this->admin->setSubject($object) (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
92
        $this->admin->hasAccess('create')->willReturn(true);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->hasAccess('create') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
93
        $this->admin->getFormFieldDescriptions()->willReturn(null);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->getFormFieldDescriptions() (of type array<integer,object<Son...dDescriptionInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
94
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() 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...
95
96
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
97
        $fieldDescription->getName()->willReturn('barField');
98
99
        $action = $this->action;
100
        $action($request);
101
    }
102
103
    public function testRetrieveAutocompleteItemsTooShortSearchString(): void
104
    {
105
        $object = new \stdClass();
106
        $request = new Request([
107
            'admin_code' => 'foo.admin',
108
            'field' => 'barField',
109
            'q' => 'so',
110
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
111
112
        $targetAdmin = $this->prophesize(AbstractAdmin::class);
113
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
114
115
        $this->configureFormConfig('barField');
116
117
        $this->admin->getNewInstance()->willReturn($object);
118
        $this->admin->setSubject($object)->shouldBeCalled();
0 ignored issues
show
Bug introduced by
The method shouldBeCalled cannot be called on $this->admin->setSubject($object) (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
119
        $this->admin->hasAccess('create')->willReturn(true);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->hasAccess('create') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
120
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() 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...
121
        $this->admin->getFormFieldDescriptions()->willReturn(null);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->getFormFieldDescriptions() (of type array<integer,object<Son...dDescriptionInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
122
        $targetAdmin->checkAccess('list')->shouldBeCalled();
123
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
124
        $fieldDescription->getName()->willReturn('barField');
125
        $fieldDescription->getAssociationAdmin()->willReturn($targetAdmin->reveal());
126
127
        $action = $this->action;
128
        $response = $action($request);
129
130
        $this->isInstanceOf(Response::class, $response);
131
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
132
        $this->assertSame('{"status":"KO","message":"Too short search string."}', $response->getContent());
133
    }
134
135
    public function testRetrieveAutocompleteItems(): void
136
    {
137
        $entity = new \stdClass();
0 ignored issues
show
Unused Code introduced by
$entity is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
138
        $request = new Request([
139
            'admin_code' => 'foo.admin',
140
            'field' => 'barField',
141
            'q' => 'sonata',
142
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
143
144
        $targetAdmin = $this->prophesize(AbstractAdmin::class);
0 ignored issues
show
Unused Code introduced by
$targetAdmin is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
145
        $datagrid = $this->prophesize(DatagridInterface::class);
0 ignored issues
show
Unused Code introduced by
$datagrid is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
146
        $metadata = $this->prophesize(Metadata::class);
0 ignored issues
show
Unused Code introduced by
$metadata is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
147
        $pager = $this->prophesize(Pager::class);
0 ignored issues
show
Unused Code introduced by
$pager is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
148
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
0 ignored issues
show
Unused Code introduced by
$fieldDescription is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
149
150
        $this->configureFormConfig('barField');
151
152
        $datagrid = $this->configureAutocompleteItemsDatagrid();
153
        $filter = new FooFilter();
154
        $filter->initialize('foo');
155
156
        $datagrid->hasFilter('foo')->willReturn(true);
157
        $datagrid->getFilter('foo')->willReturn($filter);
158
        $datagrid->setValue('foo', null, 'sonata')->shouldBeCalled();
159
160
        $action = $this->action;
161
        $response = $action($request);
162
163
        $this->isInstanceOf(Response::class, $response);
164
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
165
        $this->assertSame('{"status":"OK","more":false,"items":[{"id":123,"label":"FOO"}]}', $response->getContent());
166
    }
167
168
    public function testRetrieveAutocompleteItemsComplexPropertyArray(): void
169
    {
170
        $request = new Request([
171
            'admin_code' => 'foo.admin',
172
            'field' => 'barField',
173
            'q' => 'sonata',
174
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
175
176
        $this->configureFormConfigComplexPropertyArray('barField');
177
        $datagrid = $this->configureAutocompleteItemsDatagrid();
178
179
        $filter = new FooFilter();
180
        $filter->initialize('entity.property');
181
182
        $datagrid->hasFilter('entity.property')->willReturn(true);
183
        $datagrid->getFilter('entity.property')->willReturn($filter);
184
        $filter2 = new FooFilter();
185
        $filter2->initialize('entity2.property2');
186
187
        $datagrid->hasFilter('entity2.property2')->willReturn(true);
188
        $datagrid->getFilter('entity2.property2')->willReturn($filter2);
189
190
        $datagrid->setValue('entity__property', null, 'sonata')->shouldBeCalled();
191
        $datagrid->setValue('entity2__property2', null, 'sonata')->shouldBeCalled();
192
193
        $action = $this->action;
194
        $response = $action($request);
195
196
        $this->isInstanceOf(Response::class, $response);
197
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
198
        $this->assertSame('{"status":"OK","more":false,"items":[{"id":123,"label":"FOO"}]}', $response->getContent());
199
    }
200
201
    public function testRetrieveAutocompleteItemsComplexProperty(): void
202
    {
203
        $request = new Request([
204
            'admin_code' => 'foo.admin',
205
            'field' => 'barField',
206
            'q' => 'sonata',
207
        ], [], [], [], [], ['REQUEST_METHOD' => 'GET', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
208
209
        $this->configureFormConfigComplexProperty('barField');
210
        $datagrid = $this->configureAutocompleteItemsDatagrid();
211
212
        $filter = new FooFilter();
213
        $filter->initialize('entity.property');
214
215
        $datagrid->hasFilter('entity.property')->willReturn(true);
216
        $datagrid->getFilter('entity.property')->willReturn($filter);
217
        $datagrid->setValue('entity__property', null, 'sonata')->shouldBeCalled();
218
219
        $action = $this->action;
220
        $response = $action($request);
221
222
        $this->isInstanceOf(Response::class, $response);
223
        $this->assertSame('application/json', $response->headers->get('Content-Type'));
224
        $this->assertSame('{"status":"OK","more":false,"items":[{"id":123,"label":"FOO"}]}', $response->getContent());
225
    }
226
227
    private function configureAutocompleteItemsDatagrid()
228
    {
229
        $entity = new \stdClass();
230
231
        $targetAdmin = $this->prophesize(AbstractAdmin::class);
232
        $datagrid = $this->prophesize(DatagridInterface::class);
233
        $metadata = $this->prophesize(Metadata::class);
234
        $pager = $this->prophesize(Pager::class);
235
        $fieldDescription = $this->prophesize(FieldDescriptionInterface::class);
236
237
        $this->admin->getNewInstance()->willReturn($entity);
238
        $this->admin->setSubject($entity)->shouldBeCalled();
0 ignored issues
show
Bug introduced by
The method shouldBeCalled cannot be called on $this->admin->setSubject($entity) (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
239
        $this->admin->hasAccess('create')->willReturn(true);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->hasAccess('create') (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
240
        $this->admin->getFormFieldDescription('barField')->willReturn($fieldDescription->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() 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...
241
        $this->admin->getFormFieldDescriptions()->willReturn(null);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->getFormFieldDescriptions() (of type array<integer,object<Son...dDescriptionInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
242
        $this->admin->id($entity)->willReturn(123);
0 ignored issues
show
Bug introduced by
The method willReturn cannot be called on $this->admin->id($entity) (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
243
        $targetAdmin->checkAccess('list')->shouldBeCalled();
244
        $targetAdmin->setFilterPersister(null)->shouldBeCalled();
245
        $targetAdmin->getDatagrid()->willReturn($datagrid->reveal());
246
        $targetAdmin->getObjectMetadata($entity)->willReturn($metadata->reveal());
247
        $metadata->getTitle()->willReturn('FOO');
248
249
        $datagrid->setValue('_per_page', null, 10)->shouldBeCalled();
250
        $datagrid->setValue('_page', null, 1)->shouldBeCalled();
251
        $datagrid->buildPager()->willReturn(null);
252
        $datagrid->getPager()->willReturn($pager->reveal());
253
        $pager->getResults()->willReturn([$entity]);
254
        $pager->isLastPage()->willReturn(true);
255
        $fieldDescription->getTargetEntity()->willReturn(Foo::class);
256
        $fieldDescription->getName()->willReturn('barField');
257
        $fieldDescription->getAssociationAdmin()->willReturn($targetAdmin->reveal());
258
259
        return $datagrid;
260
    }
261
262
    private function configureFormConfig($field, $disabled = false): void
263
    {
264
        $form = $this->prophesize(Form::class);
265
        $formType = $this->prophesize(Form::class);
266
        $formConfig = $this->prophesize(FormConfigInterface::class);
267
268
        $this->admin->getForm()->willReturn($form->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() does not seem to exist on object<Symfony\Component\Form\Form>.

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...
269
        $form->get($field)->willReturn($formType->reveal());
270
        $formType->getConfig()->willReturn($formConfig->reveal());
271
        $formConfig->getAttribute('disabled')->willReturn($disabled);
272
        $formConfig->getAttribute('property')->willReturn('foo');
273
        $formConfig->getAttribute('callback')->willReturn(null);
274
        $formConfig->getAttribute('minimum_input_length')->willReturn(3);
275
        $formConfig->getAttribute('items_per_page')->willReturn(10);
276
        $formConfig->getAttribute('req_param_name_page_number')->willReturn('_page');
277
        $formConfig->getAttribute('to_string_callback')->willReturn(null);
278
        $formConfig->getAttribute('target_admin_access_action')->willReturn('list');
279
    }
280
281
    private function configureFormConfigComplexProperty($field): void
282
    {
283
        $form = $this->prophesize(Form::class);
284
        $formType = $this->prophesize(Form::class);
285
        $formConfig = $this->prophesize(FormConfigInterface::class);
286
287
        $this->admin->getForm()->willReturn($form->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() does not seem to exist on object<Symfony\Component\Form\Form>.

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...
288
        $form->get($field)->willReturn($formType->reveal());
289
        $formType->getConfig()->willReturn($formConfig->reveal());
290
        $formConfig->getAttribute('disabled')->willReturn(false);
291
        $formConfig->getAttribute('property')->willReturn('entity.property');
292
        $formConfig->getAttribute('callback')->willReturn(null);
293
        $formConfig->getAttribute('minimum_input_length')->willReturn(3);
294
        $formConfig->getAttribute('items_per_page')->willReturn(10);
295
        $formConfig->getAttribute('req_param_name_page_number')->willReturn('_page');
296
        $formConfig->getAttribute('to_string_callback')->willReturn(null);
297
        $formConfig->getAttribute('target_admin_access_action')->willReturn('list');
298
    }
299
300
    private function configureFormConfigComplexPropertyArray($field): void
301
    {
302
        $form = $this->prophesize(Form::class);
303
        $formType = $this->prophesize(Form::class);
304
        $formConfig = $this->prophesize(FormConfigInterface::class);
305
306
        $this->admin->getForm()->willReturn($form->reveal());
0 ignored issues
show
Bug introduced by
The method willReturn() does not seem to exist on object<Symfony\Component\Form\Form>.

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...
307
        $form->get($field)->willReturn($formType->reveal());
308
        $formType->getConfig()->willReturn($formConfig->reveal());
309
        $formConfig->getAttribute('disabled')->willReturn(false);
310
        $formConfig->getAttribute('property')->willReturn(['entity.property', 'entity2.property2']);
311
        $formConfig->getAttribute('callback')->willReturn(null);
312
        $formConfig->getAttribute('minimum_input_length')->willReturn(3);
313
        $formConfig->getAttribute('items_per_page')->willReturn(10);
314
        $formConfig->getAttribute('req_param_name_page_number')->willReturn('_page');
315
        $formConfig->getAttribute('to_string_callback')->willReturn(null);
316
        $formConfig->getAttribute('target_admin_access_action')->willReturn('list');
317
    }
318
}
319