Completed
Pull Request — master (#1327)
by
unknown
05:17
created

testThatCanTransformObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
dl 10
loc 10
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 7
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\Transformer\ModelToElasticaAutoTransformer;
13
14
use FOS\ElasticaBundle\Event\TransformEvent;
15
use FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer;
16
use Symfony\Component\PropertyAccess\PropertyAccess;
17
18
class POPO
19
{
20
    public $id = 123;
21
    public $name = 'someName';
22
    public $float = 7.2;
23
    public $bool = true;
24
    public $falseBool = false;
25
    public $date;
26
    public $nullValue;
27
    public $file;
28
    public $fileContents;
29
    private $desc = 'desc';
30
31
    public function __construct()
32
    {
33
        $this->date = new \DateTime('1979-05-05');
34
        $this->file = new \SplFileInfo(__DIR__.'/../fixtures/attachment.odt');
35
        $this->fileContents = file_get_contents(__DIR__.'/../fixtures/attachment.odt');
36
    }
37
38
    public function getId()
39
    {
40
        return $this->id;
41
    }
42
43
    public function getName()
44
    {
45
        return $this->name;
46
    }
47
48
    public function getIterator()
49
    {
50
        $iterator = new \ArrayIterator();
51
        $iterator->append('value1');
52
53
        return $iterator;
54
    }
55
56
    public function getArray()
57
    {
58
        return [
59
            'key1' => 'value1',
60
            'key2' => 'value2',
61
        ];
62
    }
63
64
    public function getMultiArray()
65
    {
66
        return [
67
            'key1' => 'value1',
68
            'key2' => ['value2', false, 123, 8.9, new \DateTime('1978-09-07')],
69
        ];
70
    }
71
72
    public function getBool()
73
    {
74
        return $this->bool;
75
    }
76
77
    public function getFalseBool()
78
    {
79
        return $this->falseBool;
80
    }
81
82
    public function getFloat()
83
    {
84
        return $this->float;
85
    }
86
87
    public function getDate()
88
    {
89
        return $this->date;
90
    }
91
92
    public function getNullValue()
93
    {
94
        return $this->nullValue;
95
    }
96
97
    public function getFile()
98
    {
99
        return $this->file;
100
    }
101
102
    public function getFileContents()
103
    {
104
        return $this->fileContents;
105
    }
106
107
    public function getSub()
108
    {
109
        return [
110
            (object) ['foo' => 'foo', 'bar' => 'foo', 'id' => 1],
111
            (object) ['foo' => 'bar', 'bar' => 'bar', 'id' => 2],
112
        ];
113
    }
114
115
    public function getObj()
116
    {
117
        return ['foo' => 'foo', 'bar' => 'foo', 'id' => 1];
118
    }
119
120
    public function getNestedObject()
121
    {
122
        return ['key1' => (object) ['id' => 1, 'key1sub1' => 'value1sub1', 'key1sub2' => 'value1sub2']];
123
    }
124
125
    public function getUpper()
126
    {
127
        return (object) ['id' => 'parent', 'name' => 'a random name'];
128
    }
129
130
    public function getUpperAlias()
131
    {
132
        return $this->getUpper();
133
    }
134
135
    public function getObjWithoutIdentifier()
136
    {
137
        return (object) ['foo' => 'foo', 'bar' => 'foo'];
138
    }
139
140
    public function getSubWithoutIdentifier()
141
    {
142
        return [
143
            (object) ['foo' => 'foo', 'bar' => 'foo'],
144
            (object) ['foo' => 'bar', 'bar' => 'bar'],
145
        ];
146
    }
147
}
148
149
class CastableObject
150
{
151
    public $foo;
152
153
    public function __toString()
154
    {
155
        return $this->foo;
156
    }
157
}
158
159
class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
160
{
161
    public function testTransformerDispatches()
162
    {
163
        $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')
164
            ->getMock();
165
166
        $dispatcher->expects($this->exactly(2))
167
            ->method('dispatch')
168
            ->withConsecutive(
169
                [
170
                    TransformEvent::PRE_TRANSFORM,
171
                    $this->isInstanceOf('FOS\ElasticaBundle\Event\TransformEvent'),
172
                ],
173
                [
174
                    TransformEvent::POST_TRANSFORM,
175
                    $this->isInstanceOf('FOS\ElasticaBundle\Event\TransformEvent'),
176
                ]
177
            );
178
179
        $transformer = $this->getTransformer($dispatcher);
180
        $transformer->transform(new POPO(), []);
181
    }
182
183
    public function testPropertyPath()
184
    {
185
        $transformer = $this->getTransformer();
186
187
        $document = $transformer->transform(new POPO(), ['name' => ['property_path' => false]]);
188
        $this->assertInstanceOf('Elastica\Document', $document);
189
        $this->assertFalse($document->has('name'));
190
191
        $document = $transformer->transform(new POPO(), ['realName' => ['property_path' => 'name']]);
192
        $this->assertInstanceOf('Elastica\Document', $document);
193
        $this->assertTrue($document->has('realName'));
194
        $this->assertSame('someName', $document->get('realName'));
195
    }
196
197 View Code Duplication
    public function testThatCanTransformObject()
198
    {
199
        $transformer = $this->getTransformer();
200
        $document = $transformer->transform(new POPO(), ['name' => []]);
201
        $data = $document->getData();
202
203
        $this->assertInstanceOf('Elastica\Document', $document);
204
        $this->assertSame(123, $document->getId());
205
        $this->assertSame('someName', $data['name']);
206
    }
207
208
    public function testThatCanTransformObjectWithCorrectTypes()
209
    {
210
        $transformer = $this->getTransformer();
211
        $document = $transformer->transform(
212
            new POPO(), [
213
                             'name' => [],
214
                             'float' => [],
215
                             'bool' => [],
216
                             'date' => [],
217
                             'falseBool' => [],
218
                        ]
219
        );
220
        $data = $document->getData();
221
222
        $this->assertInstanceOf('Elastica\Document', $document);
223
        $this->assertSame(123, $document->getId());
224
        $this->assertSame('someName', $data['name']);
225
        $this->assertSame(7.2, $data['float']);
226
        $this->assertTrue($data['bool']);
227
        $this->assertFalse($data['falseBool']);
228
        $expectedDate = new \DateTime('1979-05-05');
229
        $this->assertSame($expectedDate->format('c'), $data['date']);
230
    }
231
232 View Code Duplication
    public function testThatCanTransformObjectWithIteratorValue()
233
    {
234
        $transformer = $this->getTransformer();
235
        $document = $transformer->transform(new POPO(), ['iterator' => []]);
236
        $data = $document->getData();
237
238
        $this->assertSame(['value1'], $data['iterator']);
239
    }
240
241 View Code Duplication
    public function testThatCanTransformObjectWithArrayValue()
242
    {
243
        $transformer = $this->getTransformer();
244
        $document = $transformer->transform(new POPO(), ['array' => []]);
245
        $data = $document->getData();
246
247
        $this->assertSame(
248
            [
249
                 'key1' => 'value1',
250
                 'key2' => 'value2',
251
            ], $data['array']
252
        );
253
    }
254
255
    public function testThatCanTransformObjectWithMultiDimensionalArrayValue()
256
    {
257
        $transformer = $this->getTransformer();
258
        $document = $transformer->transform(new POPO(), ['multiArray' => []]);
259
        $data = $document->getData();
260
261
        $expectedDate = new \DateTime('1978-09-07');
262
263
        $this->assertSame(
264
            [
265
                 'key1' => 'value1',
266
                 'key2' => ['value2', false, 123, 8.9, $expectedDate->format('c')],
267
            ], $data['multiArray']
268
        );
269
    }
270
271 View Code Duplication
    public function testThatNullValuesAreNotFilteredOut()
272
    {
273
        $transformer = $this->getTransformer();
274
        $document = $transformer->transform(new POPO(), ['nullValue' => []]);
275
        $data = $document->getData();
276
277
        $this->assertTrue(array_key_exists('nullValue', $data));
278
    }
279
280
    /**
281
     * @expectedException \Symfony\Component\PropertyAccess\Exception\RuntimeException
282
     */
283
    public function testThatCannotTransformObjectWhenGetterDoesNotExistForPrivateMethod()
284
    {
285
        $transformer = $this->getTransformer();
286
        $transformer->transform(new POPO(), ['desc' => []]);
287
    }
288
289 View Code Duplication
    public function testFileAddedForAttachmentMapping()
290
    {
291
        $transformer = $this->getTransformer();
292
        $document = $transformer->transform(new POPO(), ['file' => ['type' => 'attachment']]);
293
        $data = $document->getData();
294
295
        $this->assertSame(base64_encode(file_get_contents(__DIR__.'/../fixtures/attachment.odt')), $data['file']);
296
    }
297
298 View Code Duplication
    public function testFileContentsAddedForAttachmentMapping()
299
    {
300
        $transformer = $this->getTransformer();
301
        $document = $transformer->transform(new POPO(), ['fileContents' => ['type' => 'attachment']]);
302
        $data = $document->getData();
303
304
        $this->assertSame(
305
            base64_encode(file_get_contents(__DIR__.'/../fixtures/attachment.odt')), $data['fileContents']
306
        );
307
    }
308
309 View Code Duplication
    public function testNestedMapping()
310
    {
311
        $transformer = $this->getTransformer();
312
        $document = $transformer->transform(new POPO(), [
313
            'sub' => [
314
                'type' => 'nested',
315
                'properties' => ['foo' => []],
316
            ],
317
        ]);
318
        $data = $document->getData();
319
320
        $this->assertTrue(array_key_exists('sub', $data));
321
        $this->assertInternalType('array', $data['sub']);
322
        $this->assertSame([
323
             ['foo' => 'foo'],
324
             ['foo' => 'bar'],
325
           ], $data['sub']);
326
    }
327
328 View Code Duplication
    public function tesObjectMapping()
329
    {
330
        $transformer = $this->getTransformer();
331
        $document = $transformer->transform(new POPO(), [
332
                'sub' => [
333
                    'type' => 'object',
334
                    'properties' => ['bar'],
335
                    ],
336
                ]);
337
        $data = $document->getData();
338
339
        $this->assertTrue(array_key_exists('sub', $data));
340
        $this->assertInternalType('array', $data['sub']);
341
        $this->assertSame([
342
             ['bar' => 'foo'],
343
             ['bar' => 'bar'],
344
           ], $data['sub']);
345
    }
346
347
    public function testObjectDoesNotRequireProperties()
348
    {
349
        $transformer = $this->getTransformer();
350
        $document = $transformer->transform(new POPO(), [
351
                'obj' => [
352
                    'type' => 'object',
353
                    ],
354
                ]);
355
        $data = $document->getData();
356
357
        $this->assertTrue(array_key_exists('obj', $data));
358
        $this->assertInternalType('array', $data['obj']);
359
        $this->assertSame([
360
             'foo' => 'foo',
361
             'bar' => 'foo',
362
             'id' => 1,
363
       ], $data['obj']);
364
    }
365
366
    public function testObjectsMappingOfAtLeastOneAutoMappedObjectAndAtLeastOneManuallyMappedObject()
367
    {
368
        $transformer = $this->getTransformer();
369
        $document = $transformer->transform(
370
            new POPO(),
371
            [
372
                'obj' => ['type' => 'object', 'properties' => []],
373
                'nestedObject' => [
374
                    'type' => 'object',
375
                    'properties' => [
376
                        'key1sub1' => [
377
                            'type' => 'text',
378
                            'properties' => [],
379
                        ],
380
                        'key1sub2' => [
381
                            'type' => 'text',
382
                            'properties' => [],
383
                        ],
384
                    ],
385
                ],
386
            ]
387
        );
388
        $data = $document->getData();
389
390
        $this->assertTrue(array_key_exists('obj', $data));
391
        $this->assertTrue(array_key_exists('nestedObject', $data));
392
        $this->assertInternalType('array', $data['obj']);
393
        $this->assertInternalType('array', $data['nestedObject']);
394
        $this->assertSame(
395
            [
396
                'foo' => 'foo',
397
                'bar' => 'foo',
398
                'id' => 1,
399
            ],
400
            $data['obj']
401
        );
402
        $this->assertSame(
403
            [
404
                'key1sub1' => 'value1sub1',
405
                'key1sub2' => 'value1sub2',
406
            ],
407
            $data['nestedObject'][0]
408
        );
409
    }
410
411 View Code Duplication
    public function testParentMapping()
412
    {
413
        $transformer = $this->getTransformer();
414
        $document = $transformer->transform(new POPO(), [
415
            '_parent' => ['type' => 'upper', 'property' => 'upper', 'identifier' => 'id'],
416
        ]);
417
418
        $this->assertSame('parent', $document->getParent());
419
    }
420
421 View Code Duplication
    public function testParentMappingWithCustomIdentifier()
422
    {
423
        $transformer = $this->getTransformer();
424
        $document = $transformer->transform(new POPO(), [
425
            '_parent' => ['type' => 'upper', 'property' => 'upper', 'identifier' => 'name'],
426
        ]);
427
428
        $this->assertSame('a random name', $document->getParent());
429
    }
430
431 View Code Duplication
    public function testParentMappingWithNullProperty()
432
    {
433
        $transformer = $this->getTransformer();
434
        $document = $transformer->transform(new POPO(), [
435
            '_parent' => ['type' => 'upper', 'property' => null, 'identifier' => 'id'],
436
        ]);
437
438
        $this->assertSame('parent', $document->getParent());
439
    }
440
441 View Code Duplication
    public function testParentMappingWithCustomProperty()
442
    {
443
        $transformer = $this->getTransformer();
444
        $document = $transformer->transform(new POPO(), [
445
            '_parent' => ['type' => 'upper', 'property' => 'upperAlias', 'identifier' => 'id'],
446
        ]);
447
448
        $this->assertSame('parent', $document->getParent());
449
    }
450
451 View Code Duplication
    public function testThatMappedObjectsDontNeedAnIdentifierField()
452
    {
453
        $transformer = $this->getTransformer();
454
        $document = $transformer->transform(new POPO(), [
455
            'objWithoutIdentifier' => [
456
                'type' => 'object',
457
                'properties' => [
458
                    'foo' => [],
459
                    'bar' => [],
460
                ],
461
            ],
462
        ]);
463
        $data = $document->getData();
464
465
        $this->assertTrue(array_key_exists('objWithoutIdentifier', $data));
466
        $this->assertInternalType('array', $data['objWithoutIdentifier']);
467
        $this->assertSame([
468
            'foo' => 'foo',
469
            'bar' => 'foo',
470
        ], $data['objWithoutIdentifier']);
471
    }
472
473
    public function testThatNestedObjectsDontNeedAnIdentifierField()
474
    {
475
        $transformer = $this->getTransformer();
476
        $document = $transformer->transform(new POPO(), [
477
            'subWithoutIdentifier' => [
478
                'type' => 'nested',
479
                'properties' => [
480
                    'foo' => [],
481
                    'bar' => [],
482
                ],
483
            ],
484
        ]);
485
        $data = $document->getData();
486
487
        $this->assertTrue(array_key_exists('subWithoutIdentifier', $data));
488
        $this->assertInternalType('array', $data['subWithoutIdentifier']);
489
        $this->assertSame([
490
            ['foo' => 'foo', 'bar' => 'foo'],
491
            ['foo' => 'bar', 'bar' => 'bar'],
492
        ], $data['subWithoutIdentifier']);
493
    }
494
495 View Code Duplication
    public function testNestedTransformHandlesSingleObjects()
496
    {
497
        $transformer = $this->getTransformer();
498
        $document = $transformer->transform(new POPO(), [
499
            'upper' => [
500
                'type' => 'nested',
501
                'properties' => ['name' => null],
502
            ],
503
        ]);
504
505
        $data = $document->getData();
506
        $this->assertSame('a random name', $data['upper']['name']);
507
    }
508
509
    public function testNestedTransformReturnsAnEmptyArrayForNullValues()
510
    {
511
        $transformer = $this->getTransformer();
512
        $document = $transformer->transform(new POPO(), [
513
            'nullValue' => [
514
                'type' => 'nested',
515
                'properties' => [
516
                    'foo' => [],
517
                    'bar' => [],
518
                ],
519
            ],
520
        ]);
521
522
        $data = $document->getData();
523
        $this->assertInternalType('array', $data['nullValue']);
524
        $this->assertEmpty($data['nullValue']);
525
    }
526
527
    public function testUnmappedFieldValuesAreNormalisedToStrings()
528
    {
529
        $object = new \stdClass();
530
        $value = new CastableObject();
531
        $value->foo = 'bar';
532
533
        $object->id = 123;
534
        $object->unmappedValue = $value;
535
536
        $transformer = $this->getTransformer();
537
        $document = $transformer->transform($object, ['unmappedValue' => ['property' => 'unmappedValue']]);
538
539
        $data = $document->getData();
540
        $this->assertSame('bar', $data['unmappedValue']);
541
    }
542
543
    public function testIdentifierIsCastedToString()
544
    {
545
        $idObject = new CastableObject();;
546
        $idObject->foo = '00000000-0000-0000-0000-000000000000';
547
548
        $object = new \stdClass();
549
        $object->id = $idObject;
550
551
        $transformer = $this->getTransformer();
552
        $document = $transformer->transform($object, []);
553
554
        $this->assertSame('string', gettype($document->getId()));
555
    }
556
557
    /**
558
     * @param null|\Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
559
     *
560
     * @return ModelToElasticaAutoTransformer
561
     */
562
    private function getTransformer($dispatcher = null)
563
    {
564
        $transformer = new ModelToElasticaAutoTransformer([], $dispatcher);
565
        $transformer->setPropertyAccessor(PropertyAccess::createPropertyAccessor());
566
567
        return $transformer;
568
    }
569
}
570