Completed
Pull Request — master (#6267)
by Jordi Sala
02:47
created

llbackException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\DataTransformer;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use PHPUnit\Framework\TestCase;
18
use Sonata\AdminBundle\Form\DataTransformer\ModelToIdPropertyTransformer;
19
use Sonata\AdminBundle\Model\ModelManagerInterface;
20
use Sonata\AdminBundle\Tests\Fixtures\Entity\Foo;
21
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooArrayAccess;
22
23
class ModelToIdPropertyTransformerTest extends TestCase
24
{
25
    private $modelManager;
26
27
    protected function setUp(): void
28
    {
29
        $this->modelManager = $this->getMockForAbstractClass(ModelManagerInterface::class);
30
    }
31
32
    public function testReverseTransform(): void
33
    {
34
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', false);
35
36
        $model = new Foo();
37
        $model->setBar('example');
38
39
        $this->modelManager
40
            ->method('find')
41
            ->willReturnCallback(static function (string $class, $id) use ($model) {
42
                if (Foo::class === $class && 123 === $id) {
43
                    return $model;
44
                }
45
            });
46
47
        $this->assertNull($transformer->reverseTransform(null));
48
        $this->assertNull($transformer->reverseTransform(false));
49
        $this->assertNull($transformer->reverseTransform(''));
50
        $this->assertNull($transformer->reverseTransform(12));
51
        $this->assertNull($transformer->reverseTransform([123]));
52
        $this->assertNull($transformer->reverseTransform([123, 456, 789]));
53
        $this->assertSame($model, $transformer->reverseTransform(123));
54
    }
55
56
    /**
57
     * @dataProvider getReverseTransformMultipleTests
58
     */
59
    public function testReverseTransformMultiple(array $expected, $params, Foo $entity1, Foo $entity2, Foo $entity3): void
60
    {
61
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', true);
62
63
        $this->modelManager
64
            ->method('find')
65
            ->willReturnCallback(static function (string $className, int $value) use ($entity1, $entity2, $entity3) {
66
                if (Foo::class !== $className) {
67
                    return;
68
                }
69
70
                if (123 === $value) {
71
                    return $entity1;
72
                }
73
74
                if (456 === $value) {
75
                    return $entity2;
76
                }
77
78
                if (789 === $value) {
79
                    return $entity3;
80
                }
81
            });
82
83
        $collection = new ArrayCollection();
84
        $this->modelManager
85
            ->method('getModelCollectionInstance')
86
            ->with($this->equalTo(Foo::class))
87
            ->willReturn($collection);
88
89
        $result = $transformer->reverseTransform($params);
90
        $this->assertInstanceOf(ArrayCollection::class, $result);
91
        $this->assertSame($expected, $result->getValues());
92
    }
93
94
    public function getReverseTransformMultipleTests()
95
    {
96
        $entity1 = new Foo();
97
        $entity1->setBaz(123);
98
        $entity1->setBar('example');
99
100
        $entity2 = new Foo();
101
        $entity2->setBaz(456);
102
        $entity2->setBar('example2');
103
104
        $entity3 = new Foo();
105
        $entity3->setBaz(789);
106
        $entity3->setBar('example3');
107
108
        return [
109
            [[], null, $entity1, $entity2, $entity3],
110
            [[], false, $entity1, $entity2, $entity3],
111
            [[$entity1], [123, '_labels' => ['example']], $entity1, $entity2, $entity3],
112
            [[$entity1, $entity2, $entity3], [123, 456, 789, '_labels' => ['example', 'example2', 'example3']], $entity1, $entity2, $entity3],
113
        ];
114
    }
115
116
    /**
117
     * @dataProvider getReverseTransformMultipleInvalidTypeTests
118
     */
119
    public function testReverseTransformMultipleInvalidTypeTests(array $expected, $params, string $type): void
120
    {
121
        $this->expectException(\UnexpectedValueException::class);
122
        $this->expectExceptionMessage(sprintf('Value should be array, %s given.', $type));
123
124
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', true);
125
126
        $collection = new ArrayCollection();
127
        $this->modelManager
128
            ->method('getModelCollectionInstance')
129
            ->with($this->equalTo(Foo::class))
130
            ->willReturn($collection);
131
132
        $result = $transformer->reverseTransform($params);
133
        $this->assertInstanceOf(ArrayCollection::class, $result);
134
        $this->assertSame($expected, $result->getValues());
135
    }
136
137
    public function getReverseTransformMultipleInvalidTypeTests(): array
138
    {
139
        return [
140
            [[], true, 'boolean'],
141
            [[], 12, 'integer'],
142
            [[], 12.9, 'double'],
143
            [[], '_labels', 'string'],
144
            [[], new \stdClass(), 'object'],
145
        ];
146
    }
147
148
    public function testTransform(): void
149
    {
150
        $model = new Foo();
151
        $model->setBar('example');
152
153
        $this->modelManager->expects($this->once())
154
            ->method('getIdentifierValues')
155
            ->willReturn([123]);
156
157
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', false);
158
159
        $this->assertSame([], $transformer->transform(null));
160
        $this->assertSame([], $transformer->transform(false));
161
        $this->assertSame([], $transformer->transform(''));
162
        $this->assertSame([], $transformer->transform(0));
163
        $this->assertSame([], $transformer->transform('0'));
164
165
        $this->assertSame([123, '_labels' => ['example']], $transformer->transform($model));
166
    }
167
168
    public function testTransformWorksWithArrayAccessEntity(): void
169
    {
170
        $model = new FooArrayAccess();
171
        $model->setBar('example');
172
173
        $this->modelManager->expects($this->once())
174
            ->method('getIdentifierValues')
175
            ->willReturn([123]);
176
177
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, FooArrayAccess::class, 'bar', false);
178
179
        $this->assertSame([123, '_labels' => ['example']], $transformer->transform($model));
180
    }
181
182
    public function testTransformToStringCallback(): void
183
    {
184
        $model = new Foo();
185
        $model->setBar('example');
186
        $model->setBaz('bazz');
187
188
        $this->modelManager->expects($this->once())
189
            ->method('getIdentifierValues')
190
            ->willReturn([123]);
191
192
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', false, static function ($model) {
193
            return $model->getBaz();
194
        });
195
196
        $this->assertSame([123, '_labels' => ['bazz']], $transformer->transform($model));
197
    }
198
199
    public function testTransformMultiple(): void
200
    {
201
        $entity1 = new Foo();
202
        $entity1->setBar('foo');
203
204
        $entity2 = new Foo();
205
        $entity2->setBar('bar');
206
207
        $entity3 = new Foo();
208
        $entity3->setBar('baz');
209
210
        $collection = new ArrayCollection();
211
        $collection[] = $entity1;
212
        $collection[] = $entity2;
213
        $collection[] = $entity3;
214
215
        $this->modelManager->expects($this->exactly(3))
216
            ->method('getIdentifierValues')
217
            ->willReturnCallback(static function (Foo $value) use ($entity1, $entity2, $entity3): array {
218
                if ($value === $entity1) {
219
                    return [123];
220
                }
221
222
                if ($value === $entity2) {
223
                    return [456];
224
                }
225
226
                if ($value === $entity3) {
227
                    return [789];
228
                }
229
230
                return [999];
231
            });
232
233
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', true);
234
235
        $this->assertSame([], $transformer->transform(null));
236
        $this->assertSame([], $transformer->transform(false));
237
        $this->assertSame([], $transformer->transform(''));
238
        $this->assertSame([], $transformer->transform(0));
239
        $this->assertSame([], $transformer->transform('0'));
240
241
        $this->assertSame([
242
            123,
243
            '_labels' => ['foo', 'bar', 'baz'],
244
            456,
245
            789,
246
        ], $transformer->transform($collection));
247
    }
248
249
    public function testTransformCollectionException(): void
250
    {
251
        $this->expectException(\InvalidArgumentException::class);
252
        $this->expectExceptionMessage('A multiple selection must be passed a collection not a single value. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
253
254
        $model = new Foo();
255
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', true);
256
        $transformer->transform($model);
257
    }
258
259
    public function testTransformArrayAccessException(): void
260
    {
261
        $this->expectException(\InvalidArgumentException::class);
262
        $this->expectExceptionMessage('A multiple selection must be passed a collection not a single value. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
263
264
        $model = new FooArrayAccess();
265
        $model->setBar('example');
266
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, FooArrayAccess::class, 'bar', true);
267
        $transformer->transform($model);
268
    }
269
270
    public function testTransformEntityException(): void
271
    {
272
        $this->expectException(\InvalidArgumentException::class);
273
        $this->expectExceptionMessage('A single selection must be passed a single value not a collection. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
274
275
        $entity1 = new Foo();
276
        $entity1->setBar('foo');
277
278
        $entity2 = new Foo();
279
        $entity2->setBar('bar');
280
281
        $entity3 = new Foo();
282
        $entity3->setBar('baz');
283
284
        $collection = new ArrayCollection();
285
        $collection[] = $entity1;
286
        $collection[] = $entity2;
287
        $collection[] = $entity3;
288
289
        $transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', false);
290
291
        $transformer->transform($collection);
292
    }
293
}
294