SchemaValidatorTest   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 76
c 2
b 0
f 0
dl 0
loc 190
rs 10
wmc 12

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 4 1
A modelSetProvider() 0 9 1
A testCmsModelSet() 0 7 1
A testInvalidTripleAssociationAsKeyMapping() 0 14 1
A testInvalidOrderByCollectionValuedAssociation() 0 10 1
A testInvalidReferencedJoinTableColumnIsNotPrimary() 0 10 1
A testInvalidOrderByInvalidField() 0 10 1
A testInvalidManyToManyJoinColumnSchema() 0 16 1
A testInvalidBiDirectionalRelationMappingMissingInversedByAttribute() 0 11 1
A testValidOneToOneAsIdentifierSchema() 0 8 1
A testInvalidOrderByAssociationInverseSide() 0 10 1
A testInvalidToOneJoinColumnSchema() 0 16 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Tools;
6
7
use Doctrine\ORM\Annotation as ORM;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\Tools\SchemaValidator;
10
use Doctrine\Tests\OrmTestCase;
11
use function sprintf;
12
13
class SchemaValidatorTest extends OrmTestCase
14
{
15
    /** @var EntityManagerInterface */
16
    private $em;
17
18
    /** @var SchemaValidator */
19
    private $validator;
20
21
    public function setUp() : void
22
    {
23
        $this->em        = $this->getTestEntityManager();
24
        $this->validator = new SchemaValidator($this->em);
25
    }
26
27
    /**
28
     * @dataProvider modelSetProvider
29
     */
30
    public function testCmsModelSet(string $path) : void
31
    {
32
        $this->em->getConfiguration()
33
                 ->getMetadataDriverImpl()
34
                 ->addPaths([$path]);
0 ignored issues
show
Bug introduced by
The method addPaths() does not exist on Doctrine\ORM\Mapping\Driver\MappingDriver. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Driver\MappingDriver such as Doctrine\ORM\Mapping\Driver\AnnotationDriver. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

34
                 ->/** @scrutinizer ignore-call */ addPaths([$path]);
Loading history...
35
36
        self::assertEmpty($this->validator->validateMapping());
37
    }
38
39
    public function modelSetProvider() : array
40
    {
41
        return [
42
            'cms'        => [__DIR__ . '/../../Models/CMS'],
43
            'company'    => [__DIR__ . '/../../Models/Company'],
44
            'ecommerce'  => [__DIR__ . '/../../Models/ECommerce'],
45
            'forum'      => [__DIR__ . '/../../Models/Forum'],
46
            'navigation' => [__DIR__ . '/../../Models/Navigation'],
47
            'routing'    => [__DIR__ . '/../../Models/Routing'],
48
        ];
49
    }
50
51
    /**
52
     * @group DDC-1439
53
     */
54
    public function testInvalidManyToManyJoinColumnSchema() : void
55
    {
56
        $class1 = $this->em->getClassMetadata(InvalidEntity1::class);
57
        $class2 = $this->em->getClassMetadata(InvalidEntity2::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $class2 is dead and can be removed.
Loading history...
58
59
        $errors = $this->validator->validateClass($class1);
60
61
        $message1 = "The inverse join columns of the many-to-many table '%s' have to contain to ALL identifier columns of the target entity '%s', however '%s' are missing.";
62
        $message2 = "The join columns of the many-to-many table '%s' have to contain to ALL identifier columns of the source entity '%s', however '%s' are missing.";
63
64
        self::assertEquals(
65
            [
66
                sprintf($message1, 'Entity1Entity2', InvalidEntity2::class, 'key4'),
67
                sprintf($message2, 'Entity1Entity2', InvalidEntity1::class, 'key2'),
68
            ],
69
            $errors
70
        );
71
    }
72
73
    /**
74
     * @group DDC-1439
75
     */
76
    public function testInvalidToOneJoinColumnSchema() : void
77
    {
78
        $class1 = $this->em->getClassMetadata(InvalidEntity1::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $class1 is dead and can be removed.
Loading history...
79
        $class2 = $this->em->getClassMetadata(InvalidEntity2::class);
80
81
        $errors = $this->validator->validateClass($class2);
82
83
        $message1 = "The referenced column name '%s' has to be a primary key column on the target entity class '%s'.";
84
        $message2 = "The join columns of the association '%s' have to match to ALL identifier columns of the target entity '%s', however '%s' are missing.";
85
86
        self::assertEquals(
87
            [
88
                sprintf($message1, 'id', InvalidEntity1::class),
89
                sprintf($message2, 'assoc', InvalidEntity1::class, "key1', 'key2"),
90
            ],
91
            $errors
92
        );
93
    }
94
95
    /**
96
     * @group DDC-1587
97
     */
98
    public function testValidOneToOneAsIdentifierSchema() : void
99
    {
100
        $class1 = $this->em->getClassMetadata(DDC1587ValidEntity2::class);
101
        $class2 = $this->em->getClassMetadata(DDC1587ValidEntity1::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $class2 is dead and can be removed.
Loading history...
102
103
        $errors = $this->validator->validateClass($class1);
104
105
        self::assertEquals([], $errors);
106
    }
107
108
    /**
109
     * @group DDC-1649
110
     */
111
    public function testInvalidTripleAssociationAsKeyMapping() : void
112
    {
113
        $classThree = $this->em->getClassMetadata(DDC1649Three::class);
114
        $errors     = $this->validator->validateClass($classThree);
115
116
        $message1 = "Cannot map association %s#%s as identifier, because the target entity '%s' also maps an association as identifier.";
117
        $message2 = "The referenced column name '%s' has to be a primary key column on the target entity class '%s'.";
118
119
        self::assertEquals(
120
            [
121
                sprintf($message1, DDC1649Three::class, 'two', DDC1649Two::class),
122
                sprintf($message2, 'id', DDC1649Two::class),
123
            ],
124
            $errors
125
        );
126
    }
127
128
    /**
129
     * @group DDC-3274
130
     */
131
    public function testInvalidBiDirectionalRelationMappingMissingInversedByAttribute() : void
132
    {
133
        $class  = $this->em->getClassMetadata(DDC3274One::class);
134
        $errors = $this->validator->validateClass($class);
135
136
        $message = 'The property %s#%s is on the inverse side of a bi-directional relationship, but the '
137
            . "specified mappedBy association on the target-entity %s#%s does not contain the required 'inversedBy=\"%s\"' attribute.";
138
139
        self::assertEquals(
140
            [sprintf($message, DDC3274One::class, 'two', DDC3274Two::class, 'one', 'two')],
141
            $errors
142
        );
143
    }
144
145
    /**
146
     * @group DDC-3322
147
     */
148
    public function testInvalidOrderByInvalidField() : void
149
    {
150
        $class  = $this->em->getClassMetadata(DDC3322One::class);
151
        $errors = $this->validator->validateClass($class);
152
153
        $message = "The association %s#%s is ordered by a property '%s' that is non-existing field on the target entity '%s'.";
154
155
        self::assertEquals(
156
            [sprintf($message, DDC3322One::class, 'invalidAssoc', 'invalidField', DDC3322ValidEntity1::class)],
157
            $errors
158
        );
159
    }
160
161
    /**
162
     * @group DDC-3322
163
     */
164
    public function testInvalidOrderByCollectionValuedAssociation() : void
165
    {
166
        $class  = $this->em->getClassMetadata(DDC3322Two::class);
167
        $errors = $this->validator->validateClass($class);
168
169
        $message = "The association %s#%s is ordered by a property '%s' on '%s' that is a collection-valued association.";
170
171
        self::assertEquals(
172
            [sprintf($message, DDC3322Two::class, 'invalidAssoc', 'oneToMany', DDC3322ValidEntity1::class)],
173
            $errors
174
        );
175
    }
176
177
    /**
178
     * @group DDC-3322
179
     */
180
    public function testInvalidOrderByAssociationInverseSide() : void
181
    {
182
        $class  = $this->em->getClassMetadata(DDC3322Three::class);
183
        $errors = $this->validator->validateClass($class);
184
185
        $message = "The association %s#%s is ordered by a property '%s' on '%s' that is the inverse side of an association.";
186
187
        self::assertEquals(
188
            [sprintf($message, DDC3322Three::class, 'invalidAssoc', 'oneToOneInverse', DDC3322ValidEntity1::class)],
189
            $errors
190
        );
191
    }
192
193
    public function testInvalidReferencedJoinTableColumnIsNotPrimary() : void
194
    {
195
        $class  = $this->em->getClassMetadata(InvalidEntity3::class);
196
        $errors = $this->validator->validateClass($class);
197
198
        $message = "The referenced column name '%s' has to be a primary key column on the target entity class '%s'.";
199
200
        self::assertEquals(
201
            [sprintf($message, 'nonId4', InvalidEntity4::class)],
202
            $errors
203
        );
204
    }
205
}
206
207
/**
208
 * @ORM\Entity
209
 */
210
class InvalidEntity1
211
{
212
    /** @ORM\Id @ORM\Column */
213
    protected $key1;
214
    /** @ORM\Id @ORM\Column */
215
    protected $key2;
216
    /**
217
     * @ORM\ManyToMany (targetEntity=InvalidEntity2::class)
218
     * @ORM\JoinTable (name="Entity1Entity2",
219
     *      joinColumns={@ORM\JoinColumn(name="key1", referencedColumnName="key1")},
220
     *      inverseJoinColumns={@ORM\JoinColumn(name="key3", referencedColumnName="key3")}
221
     *      )
222
     */
223
    protected $entity2;
224
}
225
226
/**
227
 * @ORM\Entity
228
 */
229
class InvalidEntity2
230
{
231
    /** @ORM\Id @ORM\Column */
232
    protected $key3;
233
234
    /** @ORM\Id @ORM\Column */
235
    protected $key4;
236
237
    /** @ORM\ManyToOne(targetEntity=InvalidEntity1::class) */
238
    protected $assoc;
239
}
240
241
/**
242
 * @ORM\Entity
243
 */
244
class InvalidEntity3
245
{
246
    /** @ORM\Id @ORM\Column */
247
    protected $id3;
248
249
    /**
250
     * @ORM\ManyToMany(targetEntity=InvalidEntity4::class)
251
     * @ORM\JoinTable(name="invalid_entity_3_4")
252
     * @ORM\JoinTable (name="Entity1Entity2",
253
     *      joinColumns={@ORM\JoinColumn(name="id3_fk", referencedColumnName="id3")},
254
     *      inverseJoinColumns={@ORM\JoinColumn(name="id4_fk", referencedColumnName="nonId4")}
255
     * )
256
     */
257
    protected $invalid4;
258
}
259
260
/**
261
 * @ORM\Entity
262
 */
263
class InvalidEntity4
264
{
265
    /** @ORM\Id @ORM\Column */
266
    protected $id4;
267
    /** @ORM\Column */
268
    protected $nonId4;
269
}
270
271
/**
272
 * @ORM\Entity(repositoryClass="Entity\Repository\Agent")
273
 * @ORM\Table(name="agent")
274
 */
275
class DDC1587ValidEntity1
276
{
277
    /**
278
     * @ORM\Id @ORM\GeneratedValue
279
     * @ORM\Column(name="pk", type="integer")
280
     *
281
     * @var int
282
     */
283
    private $pk;
0 ignored issues
show
introduced by
The private property $pk is not used, and could be removed.
Loading history...
284
285
    /**
286
     * @ORM\Column(name="name", type="string", length=32)
287
     *
288
     * @var string
289
     */
290
    private $name;
0 ignored issues
show
introduced by
The private property $name is not used, and could be removed.
Loading history...
291
292
    /**
293
     * @ORM\OneToOne(targetEntity=DDC1587ValidEntity2::class, cascade={"all"}, mappedBy="agent")
294
     * @ORM\JoinColumn(name="pk", referencedColumnName="pk_agent")
295
     *
296
     * @var Identifier
0 ignored issues
show
Bug introduced by
The type Doctrine\Tests\ORM\Tools\Identifier was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
297
     */
298
    private $identifier;
0 ignored issues
show
introduced by
The private property $identifier is not used, and could be removed.
Loading history...
299
}
300
301
/**
302
 * @ORM\Entity
303
 * @ORM\Table
304
 */
305
class DDC1587ValidEntity2
306
{
307
    /**
308
     * @ORM\Id
309
     * @ORM\OneToOne(targetEntity=DDC1587ValidEntity1::class, inversedBy="identifier")
310
     * @ORM\JoinColumn(name="pk_agent", referencedColumnName="pk", nullable=false)
311
     *
312
     * @var DDC1587ValidEntity1
313
     */
314
    private $agent;
0 ignored issues
show
introduced by
The private property $agent is not used, and could be removed.
Loading history...
315
316
    /**
317
     * @ORM\Column(name="num", type="string", length=16, nullable=true)
318
     *
319
     * @var string
320
     */
321
    private $num;
0 ignored issues
show
introduced by
The private property $num is not used, and could be removed.
Loading history...
322
}
323
324
/**
325
 * @ORM\Entity
326
 */
327
class DDC1649One
328
{
329
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
330
    public $id;
331
}
332
333
/**
334
 * @ORM\Entity
335
 */
336
class DDC1649Two
337
{
338
    /** @ORM\Id @ORM\ManyToOne(targetEntity=DDC1649One::class)@ORM\JoinColumn(name="id", referencedColumnName="id")  */
339
    public $one;
340
}
341
342
/**
343
 * @ORM\Entity
344
 */
345
class DDC1649Three
346
{
347
    /** @ORM\Id @ORM\ManyToOne(targetEntity=DDC1649Two::class) @ORM\JoinColumn(name="id",  referencedColumnName="id") */
348
    private $two;
0 ignored issues
show
introduced by
The private property $two is not used, and could be removed.
Loading history...
349
}
350
351
/**
352
 * @ORM\Entity
353
 */
354
class DDC3274One
355
{
356
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
357
    private $id;
0 ignored issues
show
introduced by
The private property $id is not used, and could be removed.
Loading history...
358
359
    /** @ORM\OneToMany(targetEntity=DDC3274Two::class, mappedBy="one") */
360
    private $two;
361
}
362
363
/**
364
 * @ORM\Entity
365
 */
366
class DDC3274Two
367
{
368
    /**
369
     * @ORM\Id
370
     * @ORM\ManyToOne(targetEntity=DDC3274One::class)
371
     */
372
    private $one;
0 ignored issues
show
introduced by
The private property $one is not used, and could be removed.
Loading history...
373
}
374
375
/**
376
 * @ORM\Entity
377
 */
378
class DDC3322ValidEntity1
379
{
380
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
381
    private $id;
382
383
    /** @ORM\ManyToOne(targetEntity=DDC3322One::class, inversedBy="validAssoc") */
384
    private $oneValid;
0 ignored issues
show
introduced by
The private property $oneValid is not used, and could be removed.
Loading history...
385
386
    /** @ORM\ManyToOne(targetEntity=DDC3322One::class, inversedBy="invalidAssoc") */
387
    private $oneInvalid;
0 ignored issues
show
introduced by
The private property $oneInvalid is not used, and could be removed.
Loading history...
388
389
    /** @ORM\ManyToOne(targetEntity=DDC3322Two::class, inversedBy="validAssoc") */
390
    private $twoValid;
0 ignored issues
show
introduced by
The private property $twoValid is not used, and could be removed.
Loading history...
391
392
    /** @ORM\ManyToOne(targetEntity=DDC3322Two::class, inversedBy="invalidAssoc") */
393
    private $twoInvalid;
0 ignored issues
show
introduced by
The private property $twoInvalid is not used, and could be removed.
Loading history...
394
395
    /** @ORM\ManyToOne(targetEntity=DDC3322Three::class, inversedBy="validAssoc") */
396
    private $threeValid;
0 ignored issues
show
introduced by
The private property $threeValid is not used, and could be removed.
Loading history...
397
398
    /** @ORM\ManyToOne(targetEntity=DDC3322Three::class, inversedBy="invalidAssoc") */
399
    private $threeInvalid;
0 ignored issues
show
introduced by
The private property $threeInvalid is not used, and could be removed.
Loading history...
400
401
    /** @ORM\OneToMany(targetEntity=DDC3322ValidEntity2::class, mappedBy="manyToOne") */
402
    private $oneToMany;
0 ignored issues
show
introduced by
The private property $oneToMany is not used, and could be removed.
Loading history...
403
404
    /** @ORM\ManyToOne(targetEntity=DDC3322ValidEntity2::class, inversedBy="oneToMany") */
405
    private $manyToOne;
0 ignored issues
show
introduced by
The private property $manyToOne is not used, and could be removed.
Loading history...
406
407
    /** @ORM\OneToOne(targetEntity=DDC3322ValidEntity2::class, mappedBy="oneToOneOwning") */
408
    private $oneToOneInverse;
0 ignored issues
show
introduced by
The private property $oneToOneInverse is not used, and could be removed.
Loading history...
409
410
    /** @ORM\OneToOne(targetEntity=DDC3322ValidEntity2::class, inversedBy="oneToOneInverse") */
411
    private $oneToOneOwning;
0 ignored issues
show
introduced by
The private property $oneToOneOwning is not used, and could be removed.
Loading history...
412
}
413
414
/**
415
 * @ORM\Entity
416
 */
417
class DDC3322ValidEntity2
418
{
419
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
420
    private $id;
421
422
    /** @ORM\ManyToOne(targetEntity=DDC3322ValidEntity1::class, inversedBy="oneToMany") */
423
    private $manyToOne;
424
425
    /** @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="manyToOne") */
426
    private $oneToMany;
427
428
    /** @ORM\OneToOne(targetEntity=DDC3322ValidEntity1::class, inversedBy="oneToOneInverse") */
429
    private $oneToOneOwning;
430
431
    /** @ORM\OneToOne(targetEntity=DDC3322ValidEntity1::class, mappedBy="oneToOneOwning") */
432
    private $oneToOneInverse;
433
}
434
435
/**
436
 * @ORM\Entity
437
 */
438
class DDC3322One
439
{
440
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
441
    private $id;
442
443
    /**
444
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="oneValid")
445
     * @ORM\OrderBy({"id" = "ASC"})
446
     */
447
    private $validAssoc;
0 ignored issues
show
introduced by
The private property $validAssoc is not used, and could be removed.
Loading history...
448
449
    /**
450
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="oneInvalid")
451
     * @ORM\OrderBy({"invalidField" = "ASC"})
452
     */
453
    private $invalidAssoc;
0 ignored issues
show
introduced by
The private property $invalidAssoc is not used, and could be removed.
Loading history...
454
}
455
456
/**
457
 * @ORM\Entity
458
 */
459
class DDC3322Two
460
{
461
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
462
    private $id;
463
464
    /**
465
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="twoValid")
466
     * @ORM\OrderBy({"manyToOne" = "ASC"})
467
     */
468
    private $validAssoc;
469
470
    /**
471
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="twoInvalid")
472
     * @ORM\OrderBy({"oneToMany" = "ASC"})
473
     */
474
    private $invalidAssoc;
475
}
476
477
/**
478
 * @ORM\Entity
479
 */
480
class DDC3322Three
481
{
482
    /** @ORM\Id @ORM\Column @ORM\GeneratedValue */
483
    private $id;
484
485
    /**
486
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="threeValid")
487
     * @ORM\OrderBy({"oneToOneOwning" = "ASC"})
488
     */
489
    private $validAssoc;
490
491
    /**
492
     * @ORM\OneToMany(targetEntity=DDC3322ValidEntity1::class, mappedBy="threeInvalid")
493
     * @ORM\OrderBy({"oneToOneInverse" = "ASC"})
494
     */
495
    private $invalidAssoc;
496
}
497