Completed
Push — master ( e0017c...6b1304 )
by Tom
14s queued 11s
created

DoctrineModuleTest/Validator/UniqueObjectTest.php (14 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace DoctrineModuleTest\Validator\Adapter;
6
7
use DateTime;
8
use Doctrine\Persistence\ObjectManager;
9
use DoctrineModule\Validator\UniqueObject;
10
use InvalidArgumentException;
11
use Laminas\Validator\Exception\RuntimeException;
12
use PHPUnit\Framework\TestCase as BaseTestCase;
13
use stdClass;
14
use function sprintf;
15
use function str_replace;
16
17
/**
18
 * Tests for the UniqueObject validator
19
 *
20
 * @link    http://www.doctrine-project.org/
21
 */
22
class UniqueObjectTest extends BaseTestCase
23
{
24
    public function testCanValidateWithNotAvailableObjectInRepository() : void
25
    {
26
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
27
        $repository
28
            ->expects($this->once())
29
            ->method('findOneBy')
30
            ->with(['matchKey' => 'matchValue'])
31
            ->will($this->returnValue(null));
32
33
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
34
35
        $validator = new UniqueObject([
36
            'object_repository' => $repository,
37
            'object_manager'    => $objectManager,
38
            'fields'            => 'matchKey',
39
        ]);
40
        $this->assertTrue($validator->isValid('matchValue'));
41
    }
42
43
    public function testCanValidateIfThereIsTheSameObjectInTheRepository() : void
44
    {
45
        $match = new stdClass();
46
47
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
48
        $classMetadata
49
            ->expects($this->once())
50
            ->method('getIdentifierFieldNames')
51
            ->will($this->returnValue(['id']));
52
        $classMetadata
53
            ->expects($this->once())
54
            ->method('getIdentifierValues')
55
            ->with($match)
56
            ->will($this->returnValue(['id' => 'identifier']));
57
58
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
59
        $objectManager->expects($this->any())
60
                      ->method('getClassMetadata')
61
                      ->with('stdClass')
62
                      ->will($this->returnValue($classMetadata));
63
64
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
65
        $repository
66
            ->expects($this->any())
67
            ->method('getClassName')
68
            ->will($this->returnValue('stdClass'));
0 ignored issues
show
The method returnValue() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
69
        $repository
70
            ->expects($this->once())
71
            ->method('findOneBy')
72
            ->with(['matchKey' => 'matchValue'])
73
            ->will($this->returnValue($match));
74
75
        $validator = new UniqueObject([
76
            'object_repository' => $repository,
77
            'object_manager'    => $objectManager,
78
            'fields'            => 'matchKey',
79
        ]);
80
        $this->assertTrue($validator->isValid(['matchKey' => 'matchValue', 'id' => 'identifier']));
81
    }
82
83
    public function testCannotValidateIfThereIsAnotherObjectWithTheSameValueInTheRepository() : void
84
    {
85
        $match = new stdClass();
86
87
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
88
        $classMetadata
0 ignored issues
show
The method expects cannot be called on $classMetadata (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...
89
            ->expects($this->once())
90
            ->method('getIdentifierFieldNames')
91
            ->will($this->returnValue(['id']));
92
        $classMetadata
93
            ->expects($this->once())
94
            ->method('getIdentifierValues')
95
            ->with($match)
96
            ->will($this->returnValue(['id' => 'identifier']));
97
98
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
99
        $objectManager->expects($this->any())
0 ignored issues
show
The method any() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
100
                      ->method('getClassMetadata')
101
                      ->with('stdClass')
102
                      ->will($this->returnValue($classMetadata));
0 ignored issues
show
The method returnValue() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
103
104
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
105
        $repository
106
            ->expects($this->any())
0 ignored issues
show
The method any() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
107
            ->method('getClassName')
108
            ->will($this->returnValue('stdClass'));
109
        $repository
110
            ->expects($this->once())
0 ignored issues
show
The method once() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
111
            ->method('findOneBy')
112
            ->with(['matchKey' => 'matchValue'])
113
            ->will($this->returnValue($match));
114
115
        $validator = new UniqueObject([
116
            'object_repository' => $repository,
117
            'object_manager'    => $objectManager,
118
            'fields'            => 'matchKey',
119
        ]);
120
        $this->assertFalse($validator->isValid(['matchKey' => 'matchValue', 'id' => 'another identifier']));
121
    }
122
123
    public function testCanFetchIdentifierFromContext() : void
124
    {
125
        $match = new stdClass();
126
127
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
128
        $classMetadata
129
            ->expects($this->once())
130
            ->method('getIdentifierFieldNames')
131
            ->will($this->returnValue(['id']));
132
        $classMetadata
133
            ->expects($this->once())
134
            ->method('getIdentifierValues')
135
            ->with($match)
136
            ->will($this->returnValue(['id' => 'identifier']));
137
138
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
139
        $objectManager->expects($this->any())
140
                      ->method('getClassMetadata')
141
                      ->with('stdClass')
142
                      ->will($this->returnValue($classMetadata));
143
144
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
145
        $repository
146
            ->expects($this->any())
147
            ->method('getClassName')
148
            ->will($this->returnValue('stdClass'));
149
        $repository
150
            ->expects($this->once())
151
            ->method('findOneBy')
152
            ->with(['matchKey' => 'matchValue'])
153
            ->will($this->returnValue($match));
154
155
        $validator = new UniqueObject([
156
            'object_repository' => $repository,
157
            'object_manager'    => $objectManager,
158
            'fields'            => 'matchKey',
159
            'use_context'       => true,
160
        ]);
161
        $this->assertTrue($validator->isValid('matchValue', ['id' => 'identifier']));
162
    }
163
164
    public function testThrowsAnExceptionOnUsedButMissingContext() : void
165
    {
166
        $this->expectException(RuntimeException::class);
167
        $this->expectExceptionMessage('Expected context to be an array but is null');
168
169
        $match = new stdClass();
170
171
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
172
        $repository
173
            ->expects($this->once())
174
            ->method('findOneBy')
175
            ->with(['matchKey' => 'matchValue'])
176
            ->will($this->returnValue($match));
177
178
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
179
180
        $validator = new UniqueObject([
181
            'object_repository' => $repository,
182
            'object_manager'    => $objectManager,
183
            'fields'            => 'matchKey',
184
            'use_context'       => true,
185
        ]);
186
        $validator->isValid('matchValue');
187
    }
188
189
    public function testThrowsAnExceptionOnMissingIdentifier() : void
190
    {
191
        $this->expectException(RuntimeException::class);
192
        $this->expectExceptionMessage('Expected context to contain id');
193
194
        $match = new stdClass();
195
196
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
197
        $classMetadata
0 ignored issues
show
The method expects cannot be called on $classMetadata (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...
198
            ->expects($this->once())
199
            ->method('getIdentifierFieldNames')
200
            ->will($this->returnValue(['id']));
201
202
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
203
        $objectManager->expects($this->any())
204
                      ->method('getClassMetadata')
205
                      ->with('stdClass')
206
                      ->will($this->returnValue($classMetadata));
207
208
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
209
        $repository
210
            ->expects($this->any())
211
            ->method('getClassName')
212
            ->will($this->returnValue('stdClass'));
213
        $repository
214
            ->expects($this->once())
215
            ->method('findOneBy')
216
            ->with(['matchKey' => 'matchValue'])
217
            ->will($this->returnValue($match));
218
219
        $validator = new UniqueObject([
220
            'object_repository' => $repository,
221
            'object_manager'    => $objectManager,
222
            'fields'            => 'matchKey',
223
        ]);
224
        $validator->isValid('matchValue');
225
    }
226
227
    public function testThrowsAnExceptionOnMissingIdentifierInContext() : void
228
    {
229
        $this->expectException(RuntimeException::class);
230
        $this->expectExceptionMessage('Expected context to contain id');
231
232
        $match = new stdClass();
233
234
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
235
        $classMetadata
236
            ->expects($this->once())
237
            ->method('getIdentifierFieldNames')
238
            ->will($this->returnValue(['id']));
239
240
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
241
        $objectManager->expects($this->any())
242
                      ->method('getClassMetadata')
243
                      ->with('stdClass')
244
                      ->will($this->returnValue($classMetadata));
245
246
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
247
        $repository
248
            ->expects($this->any())
249
            ->method('getClassName')
250
            ->will($this->returnValue('stdClass'));
251
        $repository
0 ignored issues
show
The method expects cannot be called on $repository (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...
252
            ->expects($this->once())
253
            ->method('findOneBy')
254
            ->with(['matchKey' => 'matchValue'])
255
            ->will($this->returnValue($match));
256
257
        $validator = new UniqueObject([
258
            'object_repository' => $repository,
259
            'object_manager'    => $objectManager,
260
            'fields'            => 'matchKey',
261
            'use_context'       => true,
262
        ]);
263
        $validator->isValid('matchValue', []);
264
    }
265
266
    public function testThrowsAnExceptionOnMissingObjectManager() : void
267
    {
268
        $this->expectException(InvalidArgumentException::class);
269
        $this->expectExceptionMessage(sprintf(
270
            'Option "object_manager" is required and must be an instance of %s, nothing given',
271
            ObjectManager::class
272
        ));
273
274
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
275
276
        new UniqueObject([
277
            'object_repository' => $repository,
278
            'fields'            => 'matchKey',
279
        ]);
280
    }
281
282
    public function testThrowsAnExceptionOnWrongObjectManager() : void
283
    {
284
        $this->expectException(InvalidArgumentException::class);
285
        $this->expectExceptionMessage(sprintf(
286
            'Option "object_manager" is required and must be an instance of %s, stdClass given',
287
            ObjectManager::class
288
        ));
289
290
        $objectManager = new stdClass();
291
292
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
293
294
        new UniqueObject([
295
            'object_repository' => $repository,
296
            'object_manager'    => $objectManager,
297
            'fields'            => 'matchKey',
298
        ]);
299
    }
300
301
    public function testCanValidateWithNotAvailableObjectInRepositoryByDateTimeObject() : void
302
    {
303
        $date       = new DateTime('17 March 2014');
304
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
305
        $repository
306
            ->expects($this->once())
307
            ->method('findOneBy')
308
            ->with(['date' => $date])
309
            ->will($this->returnValue(null));
310
311
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
312
313
        $validator = new UniqueObject([
314
            'object_repository' => $repository,
315
            'object_manager'    => $objectManager,
316
            'fields'            => 'date',
317
        ]);
318
319
        $this->assertTrue($validator->isValid($date));
320
    }
321
322
    public function testCanFetchIdentifierFromObjectContext() : void
323
    {
324
        $context     = new stdClass();
325
        $context->id = 'identifier';
326
327
        $match = new stdClass();
328
329
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
330
        $classMetadata
0 ignored issues
show
The method expects cannot be called on $classMetadata (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...
331
            ->expects($this->at(0))
0 ignored issues
show
The method at() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
332
            ->method('getIdentifierValues')
333
            ->with($context)
334
            ->will($this->returnValue(['id' => 'identifier']));
335
        $classMetadata
0 ignored issues
show
The method expects cannot be called on $classMetadata (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...
336
            ->expects($this->at(1))
0 ignored issues
show
The method at() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
337
            ->method('getIdentifierValues')
338
            ->with($match)
339
            ->will($this->returnValue(['id' => 'identifier']));
340
341
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
342
        $objectManager->expects($this->any())
343
            ->method('getClassMetadata')
344
            ->with('stdClass')
345
            ->will($this->returnValue($classMetadata));
346
347
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
348
        $repository
0 ignored issues
show
The method expects cannot be called on $repository (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...
349
            ->expects($this->any())
350
            ->method('getClassName')
351
            ->will($this->returnValue('stdClass'));
352
        $repository
353
            ->expects($this->once())
354
            ->method('findOneBy')
355
            ->with(['matchKey' => 'matchValue'])
356
            ->will($this->returnValue($match));
0 ignored issues
show
The method returnValue() does not seem to exist on object<DoctrineModuleTes...apter\UniqueObjectTest>.

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...
357
358
        $validator = new UniqueObject([
359
            'object_repository' => $repository,
360
            'object_manager'    => $objectManager,
361
            'fields'            => 'matchKey',
362
            'use_context'       => true,
363
        ]);
364
365
        $this->assertTrue($validator->isValid('matchValue', $context));
366
    }
367
368
    public function testErrorMessageIsStringInsteadArray() : void
369
    {
370
        $match = new stdClass();
371
372
        $classMetadata = $this->createMock('Doctrine\Persistence\Mapping\ClassMetadata');
373
        $classMetadata
374
            ->expects($this->once())
375
            ->method('getIdentifierFieldNames')
376
            ->will($this->returnValue(['id']));
377
        $classMetadata
378
            ->expects($this->once())
379
            ->method('getIdentifierValues')
380
            ->with($match)
381
            ->will($this->returnValue(['id' => 'identifier']));
382
383
        $objectManager = $this->createMock('Doctrine\Persistence\ObjectManager');
384
        $objectManager->expects($this->any())
385
                      ->method('getClassMetadata')
386
                      ->with('stdClass')
387
                      ->will($this->returnValue($classMetadata));
388
389
        $repository = $this->createMock('Doctrine\Persistence\ObjectRepository');
390
        $repository
391
            ->expects($this->any())
392
            ->method('getClassName')
393
            ->will($this->returnValue('stdClass'));
394
        $repository
395
            ->expects($this->once())
396
            ->method('findOneBy')
397
            ->with(['matchKey' => 'matchValue'])
398
            ->will($this->returnValue($match));
399
400
        $validator = new UniqueObject([
401
            'object_repository' => $repository,
402
            'object_manager'    => $objectManager,
403
            'fields'            => 'matchKey',
404
            'use_context'       => true,
405
        ]);
406
        $this->assertFalse(
407
            $validator->isValid(
408
                'matchValue',
409
                ['matchKey' => 'matchValue', 'id' => 'another identifier']
410
            )
411
        );
412
        $messageTemplates = $validator->getMessageTemplates();
413
414
        $expectedMessage = str_replace(
415
            '%value%',
416
            'matchValue',
417
            $messageTemplates[UniqueObject::ERROR_OBJECT_NOT_UNIQUE]
418
        );
419
        $messages        = $validator->getMessages();
420
        $receivedMessage = $messages[UniqueObject::ERROR_OBJECT_NOT_UNIQUE];
421
        $this->assertSame($expectedMessage, $receivedMessage);
422
    }
423
}
424