Completed
Push — master ( 696369...f27ecd )
by Karel
34:05 queued 29:37
created

ListenerTest::getMockClassMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace FOS\ElasticaBundle\Tests\Doctrine;
4
5
/**
6
 * See concrete MongoDB/ORM instances of this abstract test.
7
 *
8
 * @author Richard Miller <[email protected]>
9
 */
10
abstract class ListenerTest extends \PHPUnit_Framework_TestCase
11
{
12 View Code Duplication
    public function testObjectInsertedOnPersist()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
13
    {
14
        $entity = new Listener\Entity(1);
15
        $persister = $this->getMockPersister($entity, 'index', 'type');
16
        $eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
17
        $indexable = $this->getMockIndexable('index', 'type', $entity, true);
18
19
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type'));
20
        $listener->postPersist($eventArgs);
21
22
        $this->assertEquals($entity, current($listener->scheduledForInsertion));
23
24
        $persister->expects($this->once())
25
            ->method('insertMany')
26
            ->with($listener->scheduledForInsertion);
27
28
        $listener->postFlush($eventArgs);
29
    }
30
31 View Code Duplication
    public function testPersistDeferred()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
32
    {
33
        $entity = new Listener\Entity(1);
34
        $persister = $this->getMockPersister($entity, 'index', 'type');
35
        $eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
36
        $indexable = $this->getMockIndexable('index', 'type', $entity, true);
37
38
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type', 'defer' => true));
39
        $listener->postPersist($eventArgs);
40
41
        $this->assertEquals($entity, current($listener->scheduledForInsertion));
42
43
        $persister->expects($this->never())->method('insertMany');
44
45
        $listener->postFlush($eventArgs);
46
    }
47
48 View Code Duplication
    public function testNonIndexableObjectNotInsertedOnPersist()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
    {
50
        $entity = new Listener\Entity(1);
51
        $persister = $this->getMockPersister($entity, 'index', 'type');
52
        $eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
53
        $indexable = $this->getMockIndexable('index', 'type', $entity, false);
54
55
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type'));
56
        $listener->postPersist($eventArgs);
57
58
        $this->assertEmpty($listener->scheduledForInsertion);
59
60
        $persister->expects($this->never())
61
            ->method('insertOne');
62
        $persister->expects($this->never())
63
            ->method('insertMany');
64
65
        $listener->postFlush($eventArgs);
66
    }
67
68 View Code Duplication
    public function testObjectReplacedOnUpdate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
    {
70
        $entity = new Listener\Entity(1);
71
        $persister = $this->getMockPersister($entity, 'index', 'type');
72
        $eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
73
        $indexable = $this->getMockIndexable('index', 'type', $entity, true);
74
75
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type'));
76
        $listener->postUpdate($eventArgs);
77
78
        $this->assertEquals($entity, current($listener->scheduledForUpdate));
79
80
        $persister->expects($this->once())
81
            ->method('replaceMany')
82
            ->with(array($entity));
83
        $persister->expects($this->never())
84
            ->method('deleteById');
85
86
        $listener->postFlush($eventArgs);
87
    }
88
89
    public function testNonIndexableObjectRemovedOnUpdate()
90
    {
91
        $classMetadata = $this->getMockClassMetadata();
92
        $objectManager = $this->getMockObjectManager();
93
94
        $entity = new Listener\Entity(1);
95
        $persister = $this->getMockPersister($entity, 'index', 'type');
96
        $eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
97
        $indexable = $this->getMockIndexable('index', 'type', $entity, false);
98
99
        $objectManager->expects($this->any())
100
            ->method('getClassMetadata')
101
            ->with(get_class($entity))
102
            ->will($this->returnValue($classMetadata));
103
104
        $classMetadata->expects($this->any())
105
            ->method('getFieldValue')
106
            ->with($entity, 'id')
107
            ->will($this->returnValue($entity->getId()));
108
109
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type'));
110
        $listener->postUpdate($eventArgs);
111
112
        $this->assertEmpty($listener->scheduledForUpdate);
113
        $this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
114
115
        $persister->expects($this->never())
116
            ->method('replaceOne');
117
        $persister->expects($this->once())
118
            ->method('deleteManyByIdentifiers')
119
            ->with(array($entity->getId()));
120
121
        $listener->postFlush($eventArgs);
122
    }
123
124
    public function testObjectDeletedOnRemove()
125
    {
126
        $classMetadata = $this->getMockClassMetadata();
127
        $objectManager = $this->getMockObjectManager();
128
129
        $entity = new Listener\Entity(1);
130
        $persister = $this->getMockPersister($entity, 'index', 'type');
131
        $eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
132
        $indexable = $this->getMockIndexable('index', 'type', $entity);
133
134
        $objectManager->expects($this->any())
135
            ->method('getClassMetadata')
136
            ->with(get_class($entity))
137
            ->will($this->returnValue($classMetadata));
138
139
        $classMetadata->expects($this->any())
140
            ->method('getFieldValue')
141
            ->with($entity, 'id')
142
            ->will($this->returnValue($entity->getId()));
143
144
        $listener = $this->createListener($persister, $indexable, array('indexName' => 'index', 'typeName' => 'type'));
145
        $listener->preRemove($eventArgs);
146
147
        $this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
148
149
        $persister->expects($this->once())
150
            ->method('deleteManyByIdentifiers')
151
            ->with(array($entity->getId()));
152
153
        $listener->postFlush($eventArgs);
154
    }
155
156
    public function testObjectWithNonStandardIdentifierDeletedOnRemove()
157
    {
158
        $classMetadata = $this->getMockClassMetadata();
159
        $objectManager = $this->getMockObjectManager();
160
161
        $entity = new Listener\Entity(1);
162
        $entity->identifier = 'foo';
163
        $persister = $this->getMockPersister($entity, 'index', 'type');
164
        $eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
165
        $indexable = $this->getMockIndexable('index', 'type', $entity);
166
167
        $objectManager->expects($this->any())
168
            ->method('getClassMetadata')
169
            ->with(get_class($entity))
170
            ->will($this->returnValue($classMetadata));
171
172
        $classMetadata->expects($this->any())
173
            ->method('getFieldValue')
174
            ->with($entity, 'identifier')
175
            ->will($this->returnValue($entity->getId()));
176
177
        $listener = $this->createListener($persister, $indexable, array('identifier' => 'identifier', 'indexName' => 'index', 'typeName' => 'type'));
178
        $listener->preRemove($eventArgs);
179
180
        $this->assertEquals($entity->identifier, current($listener->scheduledForDeletion));
181
182
        $persister->expects($this->once())
183
            ->method('deleteManyByIdentifiers')
184
            ->with(array($entity->identifier));
185
186
        $listener->postFlush($eventArgs);
187
    }
188
189
    public function testShouldPersistOnKernelTerminateIfDeferIsTrue()
190
    {
191
        $entity = new Listener\Entity(1);
192
        $persister = $this->getMockPersister($entity, 'index', 'type');
193
        $indexable = $this->getMockIndexable(null, null, null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<FOS\ElasticaBundl...ctrine\Listener\Entity>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
194
        $listener = $this->createListener(
195
            $persister,
196
            $indexable,
197
            array('identifier' => 'identifier', 'indexName' => 'index', 'typeName' => 'type', 'defer' => true)
198
        );
199
        $scheduledForInsertion = array('data');
200
        $refListener = new \ReflectionObject($listener);
201
        $refScheduledForInsertion = $refListener->getProperty('scheduledForInsertion');
202
        $refScheduledForInsertion->setAccessible(true);
203
        $refScheduledForInsertion->setValue($listener, $scheduledForInsertion);
204
        $persister->expects($this->once())->method('insertMany')->with($scheduledForInsertion);
205
206
        $listener->onKernelTerminate();
207
    }
208
209
    abstract protected function getLifecycleEventArgsClass();
210
211
    abstract protected function getListenerClass();
212
213
    /**
214
     * @return string
215
     */
216
    abstract protected function getObjectManagerClass();
217
218
    /**
219
     * @return string
220
     */
221
    abstract protected function getClassMetadataClass();
222
223
    private function createLifecycleEventArgs()
224
    {
225
        $refl = new \ReflectionClass($this->getLifecycleEventArgsClass());
226
227
        return $refl->newInstanceArgs(func_get_args());
228
    }
229
230
    private function createListener()
231
    {
232
        $refl = new \ReflectionClass($this->getListenerClass());
233
234
        return $refl->newInstanceArgs(func_get_args());
235
    }
236
237
    private function getMockClassMetadata()
238
    {
239
        return $this->getMockBuilder($this->getClassMetadataClass())
240
            ->disableOriginalConstructor()
241
            ->getMock();
242
    }
243
244
    private function getMockObjectManager()
245
    {
246
        return $this->getMockBuilder($this->getObjectManagerClass())
247
            ->disableOriginalConstructor()
248
            ->getMock();
249
    }
250
251
    /**
252
     * @param Listener\Entity $object
253
     * @param string          $indexName
254
     * @param string          $typeName
255
     */
256
    private function getMockPersister($object, $indexName, $typeName)
257
    {
258
        $mock = $this->getMockBuilder('FOS\ElasticaBundle\Persister\ObjectPersister')
259
            ->disableOriginalConstructor()
260
            ->getMock();
261
262
        $mock->expects($this->any())
263
            ->method('handlesObject')
264
            ->with($object)
265
            ->will($this->returnValue(true));
266
267
        $index = $this->getMockBuilder('Elastica\Index')->disableOriginalConstructor()->getMock();
268
        $index->expects($this->any())
269
            ->method('getName')
270
            ->will($this->returnValue($indexName));
271
        $type = $this->getMockBuilder('Elastica\Type')->disableOriginalConstructor()->getMock();
272
        $type->expects($this->any())
273
            ->method('getName')
274
            ->will($this->returnValue($typeName));
275
        $type->expects($this->any())
276
            ->method('getIndex')
277
            ->will($this->returnValue($index));
278
279
        $index->expects($this->any())
280
            ->method('getType')
281
            ->will($this->returnValue($type));
282
283
        return $mock;
284
    }
285
286
    /**
287
     * @param string          $indexName
288
     * @param string          $typeName
289
     * @param Listener\Entity $object
290
     * @param boolean         $return
291
     */
292
    private function getMockIndexable($indexName, $typeName, $object, $return = null)
293
    {
294
        $mock = $this->getMockBuilder('FOS\ElasticaBundle\Provider\IndexableInterface')->getMock();
295
296
        if (null !== $return) {
297
            $mock->expects($this->once())
298
                ->method('isObjectIndexable')
299
                ->with($indexName, $typeName, $object)
300
                ->will($this->returnValue($return));
301
        }
302
303
        return $mock;
304
    }
305
}
306
307
namespace FOS\ElasticaBundle\Tests\Doctrine\Listener;
308
309
class Entity
310
{
311
    private $id;
312
    public $identifier;
313
314
    /**
315
     * @param integer $id
316
     */
317
    public function __construct($id)
318
    {
319
        $this->id = $id;
320
    }
321
322
    public function getId()
323
    {
324
        return $this->id;
325
    }
326
}
327