Completed
Pull Request — master (#1269)
by Wesley
02:45
created

AbstractProviderTest::testPopulateNotStopOnError()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 19
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\Tests\Doctrine;
13
14
use Elastica\Bulk\ResponseSet;
15
use Elastica\Response;
16
17
class AbstractProviderTest extends \PHPUnit_Framework_TestCase
18
{
19
    private $objectClass;
20
    private $objectManager;
21
    private $objectPersister;
22
    private $options;
23
    private $managerRegistry;
24
    private $indexable;
25
    private $sliceFetcher;
26
27
    public function setUp()
28
    {
29
        $this->objectClass = 'objectClass';
30
        $this->options = ['debug_logging' => true, 'indexName' => 'index', 'typeName' => 'type'];
31
32
        $this->objectPersister = $this->getMockObjectPersister();
33
        $this->managerRegistry = $this->getMockManagerRegistry();
34
        $this->objectManager = $this->getMockObjectManager();
35
        $this->indexable = $this->getMockIndexable();
36
37
        $this->managerRegistry->expects($this->any())
38
            ->method('getManagerForClass')
39
            ->with($this->objectClass)
40
            ->will($this->returnValue($this->objectManager));
41
42
        $this->sliceFetcher = $this->getMockSliceFetcher();
43
    }
44
45
    /**
46
     * @dataProvider providePopulateIterations
47
     */
48
    public function testPopulateIterations($nbObjects, $objectsByIteration, $batchSize, $limit)
49
    {
50
        $this->options['batch_size'] = $batchSize;
51
        $this->options['limit'] = $limit;
52
53
        $provider = $this->getMockAbstractProvider();
54
55
        $queryBuilder = new \stdClass();
56
57
        $provider->expects($this->once())
58
            ->method('createQueryBuilder')
59
            ->will($this->returnValue($queryBuilder));
60
61
        $provider->expects($this->once())
62
            ->method('countObjects')
63
            ->with($queryBuilder)
64
            ->will($this->returnValue($nbObjects));
65
66
        $this->indexable->expects($this->any())
67
            ->method('isObjectIndexable')
68
            ->with('index', 'type', $this->anything())
69
            ->will($this->returnValue(true));
70
71
        $previousSlice = [];
72
73 View Code Duplication
        foreach ($objectsByIteration as $i => $objects) {
74
            $offset = $objects[0] - 1;
75
76
            $this->sliceFetcher->expects($this->at($i))
77
                ->method('fetch')
78
                ->with($queryBuilder, $batchSize, $offset, $previousSlice, ['id'])
79
                ->will($this->returnValue($objects));
80
81
            $this->objectManager->expects($this->at($i))
82
                ->method('clear');
83
84
            $previousSlice = $objects;
85
        }
86
87
        $this->objectPersister->expects($this->exactly(count($objectsByIteration)))
88
            ->method('insertMany');
89
90
        $provider->populate();
91
    }
92
93
    /**
94
     * @dataProvider providePopulateIterations
95
     */
96
    public function testPopulateIterationsWithoutSliceFetcher($nbObjects, $objectsByIteration, $batchSize, $limit)
97
    {
98
        $this->options['batch_size'] = $batchSize;
99
        $this->options['limit'] = $limit;
100
101
        $provider = $this->getMockAbstractProvider(false);
102
103
        $queryBuilder = new \stdClass();
104
105
        $provider->expects($this->once())
106
            ->method('createQueryBuilder')
107
            ->will($this->returnValue($queryBuilder));
108
109
        $provider->expects($this->once())
110
            ->method('countObjects')
111
            ->with($queryBuilder)
112
            ->will($this->returnValue($nbObjects));
113
114
        $this->indexable->expects($this->any())
115
            ->method('isObjectIndexable')
116
            ->with('index', 'type', $this->anything())
117
            ->will($this->returnValue(true));
118
119
        $providerInvocationOffset = 2;
120
121 View Code Duplication
        foreach ($objectsByIteration as $i => $objects) {
122
            $offset = $objects[0] - 1;
123
124
            $provider->expects($this->at($providerInvocationOffset + $i))
125
                ->method('fetchSlice')
126
                ->with($queryBuilder, $batchSize, $offset)
127
                ->will($this->returnValue($objects));
128
129
            $this->objectManager->expects($this->at($i))
130
                ->method('clear');
131
        }
132
133
        $this->objectPersister->expects($this->exactly(count($objectsByIteration)))
134
            ->method('insertMany');
135
136
        $provider->populate();
137
    }
138
139
    public function providePopulateIterations()
140
    {
141
        return [
142
            [
143
                100,
144
                [range(1, 100)],
145
                100,
146
                null
147
            ],
148
            [
149
                105,
150
                [range(1, 50), range(51, 100), range(101, 105)],
151
                50,
152
                null
153
            ],
154
            [
155
                105,
156
                [range(1, 50), range(51, 100)],
157
                50,
158
                100
159
            ],
160
            [
161
                95,
162
                [range(1, 50), range(51, 95)],
163
                50,
164
                100
165
            ],
166
        ];
167
    }
168
169 View Code Duplication
    public function testPopulateShouldNotClearObjectManager()
170
    {
171
        $nbObjects = 1;
172
        $objects = [1];
173
        $this->options['clear_object_manager'] = false;
174
175
        $provider = $this->getMockAbstractProvider();
176
177
        $provider->expects($this->any())
178
            ->method('countObjects')
179
            ->will($this->returnValue($nbObjects));
180
181
        $this->sliceFetcher->expects($this->any())
182
            ->method('fetch')
183
            ->will($this->returnValue($objects));
184
185
        $this->indexable->expects($this->any())
186
            ->method('isObjectIndexable')
187
            ->with('index', 'type', $this->anything())
188
            ->will($this->returnValue(true));
189
190
        $this->objectManager->expects($this->never())
191
            ->method('clear');
192
193
        $provider->populate();
194
    }
195
196 View Code Duplication
    public function testPopulateShouldClearObjectManagerForFilteredBatch()
197
    {
198
        $nbObjects = 1;
199
        $objects = [1];
200
201
        $provider = $this->getMockAbstractProvider(true);
202
203
        $provider->expects($this->any())
204
            ->method('countObjects')
205
            ->will($this->returnValue($nbObjects));
206
207
        $this->sliceFetcher->expects($this->any())
208
            ->method('fetch')
209
            ->will($this->returnValue($objects));
210
211
        $this->indexable->expects($this->any())
212
            ->method('isObjectIndexable')
213
            ->with('index', 'type', $this->anything())
214
            ->will($this->returnValue(false));
215
216
        $this->objectManager->expects($this->once())
217
            ->method('clear');
218
219
        $provider->populate();
220
    }
221
222
    public function testPopulateInvokesLoggerClosure()
223
    {
224
        $nbObjects = 1;
225
        $objects = [1];
226
227
        $provider = $this->getMockAbstractProvider();
228
229
        $provider->expects($this->any())
230
            ->method('countObjects')
231
            ->will($this->returnValue($nbObjects));
232
233
        $this->sliceFetcher->expects($this->any())
234
            ->method('fetch')
235
            ->will($this->returnValue($objects));
236
237
        $this->indexable->expects($this->any())
238
            ->method('isObjectIndexable')
239
            ->with('index', 'type', $this->anything())
240
            ->will($this->returnValue(true));
241
242
        $loggerClosureInvoked = false;
243
        $loggerClosure = function () use (&$loggerClosureInvoked) {
244
            $loggerClosureInvoked = true;
245
        };
246
247
        $provider->populate();
248
        $this->assertFalse($loggerClosureInvoked);
249
250
        $provider->populate($loggerClosure);
251
        $this->assertTrue($loggerClosureInvoked);
252
    }
253
254
    public function testPopulateNotStopOnError()
255
    {
256
        $nbObjects = 1;
257
        $objects = [1];
258
259
        $provider = $this->getMockAbstractProvider();
260
261
        $provider->expects($this->any())
262
            ->method('countObjects')
263
            ->will($this->returnValue($nbObjects));
264
265
        $this->sliceFetcher->expects($this->any())
266
            ->method('fetch')
267
            ->will($this->returnValue($objects));
268
269
        $this->indexable->expects($this->any())
270
            ->method('isObjectIndexable')
271
            ->with('index', 'type', $this->anything())
272
            ->will($this->returnValue(true));
273
274
        $this->objectPersister->expects($this->any())
275
            ->method('insertMany')
276
            ->will($this->throwException($this->getMockBulkResponseException()));
277
278
        $this->setExpectedException('Elastica\Exception\Bulk\ResponseException');
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0; use expectException() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
279
280
        $provider->populate(null, ['ignore_errors' => false]);
281
    }
282
283
    public function testPopulateRunsIndexCallable()
284
    {
285
        $nbObjects = 2;
286
        $objects = [1, 2];
287
288
        $provider = $this->getMockAbstractProvider();
289
        $provider->expects($this->any())
290
            ->method('countObjects')
291
            ->will($this->returnValue($nbObjects));
292
293
        $this->sliceFetcher->expects($this->any())
294
            ->method('fetch')
295
            ->will($this->returnValue($objects));
296
297
        $this->indexable->expects($this->at(0))
298
            ->method('isObjectIndexable')
299
            ->with('index', 'type', 1)
300
            ->will($this->returnValue(false));
301
        $this->indexable->expects($this->at(1))
302
            ->method('isObjectIndexable')
303
            ->with('index', 'type', 2)
304
            ->will($this->returnValue(true));
305
306
        $this->objectPersister->expects($this->once())
307
            ->method('insertMany')
308
            ->with([2]);
309
310
        $provider->populate();
311
    }
312
313
    /**
314
     * @param bool $setSliceFetcher Whether or not to set the slice fetcher
315
     *
316
     * @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject
317
     */
318
    private function getMockAbstractProvider($setSliceFetcher = true)
319
    {
320
        return $this->getMockForAbstractClass('FOS\ElasticaBundle\Doctrine\AbstractProvider', [
321
            $this->objectPersister,
322
            $this->indexable,
323
            $this->objectClass,
324
            $this->options,
325
            $this->managerRegistry,
326
            $setSliceFetcher ? $this->sliceFetcher : null,
327
        ]);
328
    }
329
330
    /**
331
     * @return \Elastica\Exception\Bulk\ResponseException
332
     */
333
    private function getMockBulkResponseException()
334
    {
335
        return $this->getMockBuilder('Elastica\Exception\Bulk\ResponseException')
336
            ->setConstructorArgs([
337
                new ResponseSet(new Response([]), []), ]
338
            )
339
            ->getMock();
340
    }
341
342
    /**
343
     * @return \Doctrine\Common\Persistence\ManagerRegistry|\PHPUnit_Framework_MockObject_MockObject
344
     */
345
    private function getMockManagerRegistry()
346
    {
347
        return $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')->getMock();
348
    }
349
350
    /**
351
     * @return ObjectManager|\PHPUnit_Framework_MockObject_MockObject
352
     */
353
    private function getMockObjectManager()
354
    {
355
        $mock = $this->getMockBuilder(__NAMESPACE__.'\ObjectManager')->getMock();
356
357
        $mock->expects($this->any())
358
            ->method('getClassMetadata')
359
            ->will($this->returnSelf());
360
361
        $mock->expects($this->any())
362
            ->method('getIdentifierFieldNames')
363
            ->will($this->returnValue(['id']));
364
365
        return $mock;
366
    }
367
368
    /**
369
     * @return \FOS\ElasticaBundle\Persister\ObjectPersisterInterface|\PHPUnit_Framework_MockObject_MockObject
370
     */
371
    private function getMockObjectPersister()
372
    {
373
        return $this->getMockBuilder('FOS\ElasticaBundle\Persister\ObjectPersisterInterface')->getMock();
374
    }
375
376
    /**
377
     * @return \FOS\ElasticaBundle\Provider\IndexableInterface|\PHPUnit_Framework_MockObject_MockObject
378
     */
379
    private function getMockIndexable()
380
    {
381
        return $this->getMockBuilder('FOS\ElasticaBundle\Provider\IndexableInterface')->getMock();
382
    }
383
384
    /**
385
     * @return \FOS\ElasticaBundle\Doctrine\SliceFetcherInterface|\PHPUnit_Framework_MockObject_MockObject
386
     */
387
    private function getMockSliceFetcher()
388
    {
389
        return $this->getMockBuilder('FOS\ElasticaBundle\Doctrine\SliceFetcherInterface')->getMock();
390
    }
391
}
392
393
/**
394
 * Doctrine\Common\Persistence\ObjectManager does not include a clear() method
395
 * in its interface, so create a new interface for mocking.
396
 */
397
interface ObjectManager
398
{
399
    public function clear();
400
    public function getClassMetadata();
401
    public function getIdentifierFieldNames();
402
}
403