Skip to content

Commit 945939a

Browse files
authored
Fix AttributeDriver not using Vich\UploaderBundle\Mapping\Annotation\UploadableField (#1564)
1 parent deb1d70 commit 945939a

File tree

2 files changed

+268
-3
lines changed

2 files changed

+268
-3
lines changed

src/Metadata/Driver/AttributeDriver.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Metadata\ClassMetadata as JMSClassMetadata;
66
use Metadata\Driver\AdvancedDriverInterface;
7+
use Vich\UploaderBundle\Mapping\Annotation\Uploadable as UploadableAnnotation;
8+
use Vich\UploaderBundle\Mapping\Annotation\UploadableField as UploadableFieldAnnotation;
79
use Vich\UploaderBundle\Mapping\Attribute\Uploadable;
810
use Vich\UploaderBundle\Mapping\Attribute\UploadableField;
911
use Vich\UploaderBundle\Metadata\ClassMetadata;
@@ -48,9 +50,9 @@ public function loadMetadataForClass(\ReflectionClass $class): ?JMSClassMetadata
4850
$uploadableField = $this->reader->getPropertyAttribute($property, UploadableField::class);
4951
if (null === $uploadableField) {
5052
// Fallback to deprecated Annotation namespace
51-
$uploadableField = $this->reader->getPropertyAttribute($property, 'Vich\UploaderBundle\Mapping\Annotation\UploadableField');
53+
$uploadableField = $this->reader->getPropertyAttribute($property, UploadableFieldAnnotation::class);
5254
}
53-
if (!$uploadableField instanceof UploadableField) {
55+
if (!$uploadableField instanceof UploadableField && !$uploadableField instanceof UploadableFieldAnnotation) {
5456
continue;
5557
}
5658
// TODO: try automatically determinate target fields if embeddable used
@@ -102,7 +104,7 @@ protected function isUploadable(\ReflectionClass $class): bool
102104
$uploadable = $this->reader->getClassAttribute($class, Uploadable::class);
103105
if (null === $uploadable) {
104106
// Fallback to deprecated Annotation namespace
105-
$uploadable = $this->reader->getClassAttribute($class, 'Vich\UploaderBundle\Mapping\Annotation\Uploadable');
107+
$uploadable = $this->reader->getClassAttribute($class, UploadableAnnotation::class);
106108
}
107109

108110
return null !== $uploadable;
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
<?php
2+
3+
namespace Metadata\Driver;
4+
5+
use Doctrine\DBAL\Connection;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
use Doctrine\Persistence\ManagerRegistry;
8+
use Metadata\ClassMetadata;
9+
use PHPUnit\Framework\MockObject\MockObject;
10+
use PHPUnit\Framework\TestCase;
11+
use Vich\TestBundle\Entity\Article;
12+
use Vich\UploaderBundle\Mapping\Annotation\Uploadable as UploadableAnnotation;
13+
use Vich\UploaderBundle\Mapping\Annotation\UploadableField as UploadableFieldAnnotation;
14+
use Vich\UploaderBundle\Mapping\Attribute\Uploadable;
15+
use Vich\UploaderBundle\Mapping\Attribute\UploadableField;
16+
use Vich\UploaderBundle\Metadata\Driver\AttributeDriver;
17+
use Vich\UploaderBundle\Metadata\Driver\AttributeReader;
18+
use Vich\UploaderBundle\Tests\DummyAttributeEntity;
19+
use Vich\UploaderBundle\Tests\DummyEntity;
20+
use Vich\UploaderBundle\Tests\DummyFile;
21+
22+
/**
23+
* @author Andy Palmer <andy@andypalmer.me>
24+
*/
25+
final class AttributeDriverTest extends TestCase
26+
{
27+
private Connection|MockObject $connection;
28+
29+
private EntityManagerInterface|MockObject $entityManager;
30+
31+
private ManagerRegistry|MockObject $managerRegistry;
32+
33+
protected function setUp(): void
34+
{
35+
// setup ManagerRegistry mock like Symfony\Bridge\Doctrine tests
36+
$this->connection = $this->createMock(Connection::class);
37+
38+
$this->entityManager = $this->createMock(EntityManagerInterface::class);
39+
$this->entityManager->method('getConnection')->willReturn($this->connection);
40+
41+
$this->managerRegistry = $this->createMock(ManagerRegistry::class);
42+
$this->managerRegistry->method('getManager')->willReturn($this->entityManager);
43+
}
44+
45+
public function testReadUploadableAttribute(): void
46+
{
47+
$entity = new DummyEntity();
48+
49+
// @phpstan-ignore-next-line method.unresolvableReturnType
50+
$reader = $this->createMock(AttributeReader::class);
51+
$reader
52+
->expects(self::once())
53+
->method('getClassAttribute')
54+
->willReturn(new Uploadable());
55+
$reader
56+
->expects(self::atLeastOnce())
57+
->method('getPropertyAttribute')
58+
->willReturnCallback(static fn (\ReflectionProperty $property): ?UploadableField => 'file' === $property->getName() ? new UploadableField('dummy_file', 'fileName') : null);
59+
60+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
61+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
62+
63+
self::assertInstanceOf(\Vich\UploaderBundle\Metadata\ClassMetadata::class, $metadata);
64+
self::assertObjectHasProperty('fields', $metadata);
65+
self::assertEquals([
66+
'file' => [
67+
'mapping' => 'dummy_file',
68+
'propertyName' => 'file',
69+
'fileNameProperty' => 'fileName',
70+
'size' => null,
71+
'mimeType' => null,
72+
'originalName' => null,
73+
'dimensions' => null,
74+
],
75+
], $metadata->fields);
76+
}
77+
78+
public function testReadUploadableAnnotation(): void
79+
{
80+
$entity = new DummyAttributeEntity();
81+
82+
// @phpstan-ignore-next-line method.unresolvableReturnType
83+
$reader = $this->createMock(AttributeReader::class);
84+
$reader
85+
->expects(self::once())
86+
->method('getClassAttribute')
87+
->willReturn(new UploadableAnnotation());
88+
$reader
89+
->expects(self::atLeastOnce())
90+
->method('getPropertyAttribute')
91+
->willReturnCallback(static fn (\ReflectionProperty $property): ?UploadableFieldAnnotation => 'file' === $property->getName() ? new UploadableFieldAnnotation('dummy_file', 'fileName') : null);
92+
93+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
94+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
95+
96+
self::assertInstanceOf(\Vich\UploaderBundle\Metadata\ClassMetadata::class, $metadata);
97+
self::assertObjectHasProperty('fields', $metadata);
98+
self::assertEquals([
99+
'file' => [
100+
'mapping' => 'dummy_file',
101+
'propertyName' => 'file',
102+
'fileNameProperty' => 'fileName',
103+
'size' => null,
104+
'mimeType' => null,
105+
'originalName' => null,
106+
'dimensions' => null,
107+
],
108+
], $metadata->fields);
109+
}
110+
111+
public function testReadUploadableAttributeReturnsNullWhenNonePresent(): void
112+
{
113+
$entity = new DummyEntity();
114+
115+
// @phpstan-ignore-next-line method.unresolvableReturnType
116+
$reader = $this->createMock(AttributeReader::class);
117+
$reader
118+
->expects(self::exactly(2))
119+
->method('getClassAttribute')
120+
->willReturn(null);
121+
$reader
122+
->expects(self::never())
123+
->method('getPropertyAttribute');
124+
125+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
126+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
127+
128+
self::assertNull($metadata);
129+
}
130+
131+
public function testReadTwoUploadableFields(): void
132+
{
133+
$entity = new Article();
134+
135+
// @phpstan-ignore-next-line method.unresolvableReturnType
136+
$reader = $this->createMock(AttributeReader::class);
137+
$reader
138+
->expects(self::once())
139+
->method('getClassAttribute')
140+
->willReturn(new Uploadable());
141+
142+
$reader
143+
->expects(self::atLeast(2))
144+
->method('getPropertyAttribute')
145+
->willReturnCallback(static function (\ReflectionProperty $property): ?UploadableField {
146+
if ('attachment' === $property->getName()) {
147+
return new UploadableField('dummy_file', 'attachmentName');
148+
}
149+
150+
if ('image' === $property->getName()) {
151+
return new UploadableField(
152+
'dummy_image',
153+
'imageName',
154+
'sizeField',
155+
'mimeTypeField',
156+
'originalNameField'
157+
);
158+
}
159+
160+
return null;
161+
});
162+
163+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
164+
/** @var \Vich\UploaderBundle\Metadata\ClassMetadata $metadata */
165+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
166+
167+
self::assertEquals([
168+
'attachment' => [
169+
'mapping' => 'dummy_file',
170+
'propertyName' => 'attachment',
171+
'fileNameProperty' => 'attachmentName',
172+
'size' => null,
173+
'mimeType' => null,
174+
'originalName' => null,
175+
'dimensions' => null,
176+
],
177+
'image' => [
178+
'mapping' => 'dummy_image',
179+
'propertyName' => 'image',
180+
'fileNameProperty' => 'imageName',
181+
'size' => 'sizeField',
182+
'mimeType' => 'mimeTypeField',
183+
'originalName' => 'originalNameField',
184+
'dimensions' => null,
185+
],
186+
], $metadata->fields);
187+
}
188+
189+
public function testReadNoUploadableFieldsWhenNoneExist(): void
190+
{
191+
$entity = new DummyEntity();
192+
193+
// @phpstan-ignore-next-line method.unresolvableReturnType
194+
$reader = $this->createMock(AttributeReader::class);
195+
$reader
196+
->expects(self::once())
197+
->method('getClassAttribute')
198+
->willReturn(new Uploadable());
199+
200+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
201+
/** @var \Vich\UploaderBundle\Metadata\ClassMetadata $metadata */
202+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
203+
204+
self::assertEmpty($metadata->fields);
205+
}
206+
207+
public function testReadUploadableAttributeInParentClass(): void
208+
{
209+
$entity = new DummyFile();
210+
211+
// @phpstan-ignore-next-line method.unresolvableReturnType
212+
$reader = $this->createMock(AttributeReader::class);
213+
$reader
214+
->expects(self::once())
215+
->method('getClassAttribute')
216+
->willReturn(new Uploadable());
217+
$reader
218+
->expects(self::atLeastOnce())
219+
->method('getPropertyAttribute')
220+
->willReturnCallback(static fn (\ReflectionProperty $property): ?UploadableField => 'file' === $property->getName() ? new UploadableField('dummyFile_file', 'fileName') : null);
221+
222+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
223+
/** @var \Vich\UploaderBundle\Metadata\ClassMetadata $metadata */
224+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
225+
226+
self::assertInstanceOf(ClassMetadata::class, $metadata);
227+
self::assertObjectHasProperty('fields', $metadata);
228+
self::assertEquals(
229+
[
230+
'file' => [
231+
'mapping' => 'dummyFile_file',
232+
'propertyName' => 'file',
233+
'fileNameProperty' => 'fileName',
234+
'size' => null,
235+
'mimeType' => null,
236+
'originalName' => null,
237+
'dimensions' => null,
238+
],
239+
],
240+
$metadata->fields
241+
);
242+
}
243+
244+
public function testReadUploadableAttributeReturnsNullWhenNonePresentInParentClass(): void
245+
{
246+
$entity = new DummyFile();
247+
248+
// @phpstan-ignore-next-line method.unresolvableReturnType
249+
$reader = $this->createMock(AttributeReader::class);
250+
$reader
251+
->expects(self::exactly(2))
252+
->method('getClassAttribute')
253+
->willReturn(null);
254+
$reader
255+
->expects($this->never())
256+
->method('getPropertyAttribute');
257+
258+
$driver = new AttributeDriver($reader, [$this->managerRegistry]);
259+
$metadata = $driver->loadMetadataForClass(new \ReflectionClass($entity));
260+
261+
self::assertNull($metadata);
262+
}
263+
}

0 commit comments

Comments
 (0)