Completed
Push — signal_search_issues ( 5556b2...f328ba )
by André
63:06 queued 07:22
created

HandlerContentSortTest::getFieldRegistry()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\Core\Search\Legacy\Tests\Content;
12
13
use eZ\Publish\Core\Persistence\Legacy\Tests\Content\LanguageAwareTestCase;
14
use eZ\Publish\Core\Search\Legacy\Content;
15
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
16
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
17
use eZ\Publish\SPI\Persistence\Content\ContentInfo;
18
use eZ\Publish\API\Repository\Values\Content\Query;
19
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter;
20
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry;
21
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Gateway\DoctrineDatabase as ContentTypeGateway;
22
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Handler as ContentTypeHandler;
23
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Mapper as ContentTypeMapper;
24
25
/**
26
 * Content Search test case for ContentSearchHandler.
27
 */
28
class HandlerContentSortTest extends LanguageAwareTestCase
29
{
30
    protected static $setUp = false;
31
32
    /**
33
     * Field registry mock.
34
     *
35
     * @var \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry
36
     */
37
    protected $fieldRegistry;
38
39
    /**
40
     * Only set up once for these read only tests on a large fixture.
41
     *
42
     * Skipping the reset-up, since setting up for these tests takes quite some
43
     * time, which is not required to spent, since we are only reading from the
44
     * database anyways.
45
     */
46 View Code Duplication
    public function setUp()
47
    {
48
        if (!self::$setUp) {
49
            parent::setUp();
50
            $this->insertDatabaseFixture(__DIR__ . '/../_fixtures/full_dump.php');
51
            self::$setUp = $this->handler;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->handler of type object<eZ\Publish\Core\P...tabase\DatabaseHandler> is incompatible with the declared type boolean of property $setUp.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
52
        } else {
53
            $this->handler = self::$setUp;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$setUp of type boolean is incompatible with the declared type object<eZ\Publish\Core\P...tabase\DatabaseHandler> of property $handler.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
        }
55
    }
56
57
    /**
58
     * Returns the content search handler to test.
59
     *
60
     * This method returns a fully functional search handler to perform tests
61
     * on.
62
     *
63
     * @param array $fullTextSearchConfiguration
64
     *
65
     * @return \eZ\Publish\Core\Search\Legacy\Content\Handler
66
     */
67
    protected function getContentSearchHandler(array $fullTextSearchConfiguration = array())
0 ignored issues
show
Unused Code introduced by
The parameter $fullTextSearchConfiguration is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
    {
69
        $db = $this->getDatabaseHandler();
70
71
        return new Content\Handler(
72
            new Content\Gateway\DoctrineDatabase(
73
                $this->getDatabaseHandler(),
74
                new Content\Common\Gateway\CriteriaConverter(
75
                    array(
76
                        new Content\Common\Gateway\CriterionHandler\MatchAll($db),
77
                        new Content\Common\Gateway\CriterionHandler\LogicalAnd($db),
78
                        new Content\Common\Gateway\CriterionHandler\SectionId($db),
79
                        new Content\Common\Gateway\CriterionHandler\ContentTypeIdentifier(
80
                            $db,
81
                            $this->getContentTypeHandler()
82
                        ),
83
                    )
84
                ),
85
                new Content\Common\Gateway\SortClauseConverter(
86
                    array(
87
                        new Content\Common\Gateway\SortClauseHandler\DateModified($db),
88
                        new Content\Common\Gateway\SortClauseHandler\DatePublished($db),
89
                        new Content\Common\Gateway\SortClauseHandler\SectionIdentifier($db),
90
                        new Content\Common\Gateway\SortClauseHandler\SectionName($db),
91
                        new Content\Common\Gateway\SortClauseHandler\ContentName($db),
92
                        new Content\Common\Gateway\SortClauseHandler\Field(
93
                            $db,
94
                            $this->getLanguageHandler(),
95
                            $this->getContentTypeHandler()
96
                        ),
97
                    )
98
                ),
99
                $this->getLanguageHandler()
100
            ),
101
            $this->getMock('eZ\\Publish\\Core\\Search\\Legacy\\Content\\Location\\Gateway'),
102
            $this->getContentMapperMock(),
103
            $this->getMock('eZ\\Publish\\Core\\Persistence\\Legacy\\Content\\Location\\Mapper'),
104
            $this->getLanguageHandler()
105
        );
106
    }
107
108
    protected $contentTypeHandler;
109
110
    protected function getContentTypeHandler()
111
    {
112
        if (!isset($this->contentTypeHandler)) {
113
            $this->contentTypeHandler = new ContentTypeHandler(
114
                new ContentTypeGateway(
115
                    $this->getDatabaseHandler(),
116
                    $this->getLanguageMaskGenerator()
117
                ),
118
                new ContentTypeMapper(
119
                    new ConverterRegistry(
120
                        array(
121
                            'ezdatetime' => new Converter\DateAndTimeConverter(),
122
                            'ezinteger' => new Converter\IntegerConverter(),
123
                            'ezstring' => new Converter\TextLineConverter(),
124
                            'ezprice' => new Converter\IntegerConverter(),
125
                            'ezurl' => new Converter\UrlConverter(),
126
                            'ezrichtext' => new Converter\RichTextConverter(),
127
                            'ezboolean' => new Converter\CheckboxConverter(),
128
                            'ezkeyword' => new Converter\KeywordConverter(),
129
                            'ezauthor' => new Converter\AuthorConverter(),
130
                            'ezimage' => new Converter\NullConverter(),
131
                            'ezsrrating' => new Converter\NullConverter(),
132
                            'ezmultioption' => new Converter\NullConverter(),
133
                        )
134
                    )
135
                ),
136
                $this->getMock('eZ\\Publish\\Core\\Persistence\\Legacy\\Content\\Type\\Update\\Handler')
137
            );
138
        }
139
140
        return $this->contentTypeHandler;
141
    }
142
143
    /**
144
     * Returns a content mapper mock.
145
     *
146
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\Mapper
147
     */
148 View Code Duplication
    protected function getContentMapperMock()
149
    {
150
        $mapperMock = $this->getMock(
151
            'eZ\\Publish\\Core\\Persistence\\Legacy\\Content\\Mapper',
152
            array('extractContentInfoFromRows'),
153
            array(
154
                $this->getFieldRegistry(),
155
                $this->getLanguageHandler(),
156
            )
157
        );
158
        $mapperMock->expects($this->any())
159
            ->method('extractContentInfoFromRows')
160
            ->with($this->isType('array'))
161
            ->will(
162
                $this->returnCallback(
163
                    function ($rows) {
164
                        $contentInfoObjs = array();
165
                        foreach ($rows as $row) {
166
                            $contentId = (int)$row['id'];
167
                            if (!isset($contentInfoObjs[$contentId])) {
168
                                $contentInfoObjs[$contentId] = new ContentInfo();
169
                                $contentInfoObjs[$contentId]->id = $contentId;
170
                            }
171
                        }
172
173
                        return array_values($contentInfoObjs);
174
                    }
175
                )
176
            );
177
178
        return $mapperMock;
179
    }
180
181
    /**
182
     * Returns a field registry mock object.
183
     *
184
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry
185
     */
186
    protected function getFieldRegistry()
187
    {
188
        if (!isset($this->fieldRegistry)) {
189
            $this->fieldRegistry = $this->getMock(
190
                '\\eZ\\Publish\\Core\\Persistence\\Legacy\\Content\\FieldValue\\ConverterRegistry',
191
                array(),
192
                array(array())
193
            );
194
        }
195
196
        return $this->fieldRegistry;
197
    }
198
199
    /**
200
     * Returns a content field handler mock.
201
     *
202
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\FieldHandler
203
     */
204
    protected function getContentFieldHandlerMock()
205
    {
206
        return $this->getMock(
207
            'eZ\\Publish\\Core\\Persistence\\Legacy\\Content\\FieldHandler',
208
            array('loadExternalFieldData'),
209
            array(),
210
            '',
211
            false
212
        );
213
    }
214
215
    public function testNoSorting()
216
    {
217
        $locator = $this->getContentSearchHandler();
218
219
        $result = $locator->findContent(
220
            new Query(
221
                array(
222
                    'filter' => new Criterion\SectionId(array(2)),
223
                    'offset' => 0,
224
                    'limit' => 10,
225
                    'sortClauses' => array(),
226
                )
227
            )
228
        );
229
230
        $ids = array_map(
231
            function ($hit) {
232
                return $hit->valueObject->id;
233
            },
234
            $result->searchHits
235
        );
236
        sort($ids);
237
        $this->assertEquals(
238
            array(4, 10, 11, 12, 13, 14, 42, 226),
239
            $ids
240
        );
241
    }
242
243 View Code Duplication
    public function testSortDateModified()
244
    {
245
        $locator = $this->getContentSearchHandler();
246
247
        $result = $locator->findContent(
248
            new Query(
249
                array(
250
                    'filter' => new Criterion\SectionId(array(2)),
251
                    'offset' => 0,
252
                    'limit' => 10,
253
                    'sortClauses' => array(
254
                        new SortClause\DateModified(),
255
                    ),
256
                )
257
            )
258
        );
259
260
        $this->assertEquals(
261
            array(4, 12, 13, 42, 10, 14, 11, 226),
262
            array_map(
263
                function ($hit) {
264
                    return $hit->valueObject->id;
265
                },
266
                $result->searchHits
267
            )
268
        );
269
    }
270
271 View Code Duplication
    public function testSortDatePublished()
272
    {
273
        $locator = $this->getContentSearchHandler();
274
275
        $result = $locator->findContent(
276
            new Query(
277
                array(
278
                    'filter' => new Criterion\SectionId(array(2)),
279
                    'offset' => 0,
280
                    'limit' => 10,
281
                    'sortClauses' => array(
282
                        new SortClause\DatePublished(),
283
                    ),
284
                )
285
            )
286
        );
287
288
        $this->assertEquals(
289
            array(4, 10, 11, 12, 13, 14, 226, 42),
290
            array_map(
291
                function ($hit) {
292
                    return $hit->valueObject->id;
293
                },
294
                $result->searchHits
295
            )
296
        );
297
    }
298
299
    public function testSortSectionIdentifier()
300
    {
301
        $locator = $this->getContentSearchHandler();
302
303
        $result = $locator->findContent(
304
            new Query(
305
                array(
306
                    'filter' => new Criterion\SectionId(array(4, 2, 6, 3)),
307
                    'offset' => 0,
308
                    'limit' => null,
309
                    'sortClauses' => array(
310
                        new SortClause\SectionIdentifier(),
311
                    ),
312
                )
313
            )
314
        );
315
316
        // First, results of section 2 should appear, then the ones of 3, 4 and 6
317
        // From inside a specific section, no particular order should be defined
318
        // the logic is then to have a set of sorted id's to compare with
319
        // the comparison being done slice by slice.
320
        $idMapSet = array(
321
            2 => array(4, 10, 11, 12, 13, 14, 42, 226),
322
            3 => array(41, 49, 50, 51, 57, 58, 59, 60, 61, 62, 63, 64, 66, 200, 201),
323
            4 => array(45, 52),
324
            6 => array(154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164),
325
        );
326
        $contentIds = array_map(
327
            function ($hit) {
328
                return $hit->valueObject->id;
329
            },
330
            $result->searchHits
331
        );
332
        $index = 0;
333
334
        foreach ($idMapSet as $idSet) {
335
            $contentIdsSubset = array_slice($contentIds, $index, $count = count($idSet));
336
            $index += $count;
337
            sort($contentIdsSubset);
338
            $this->assertEquals(
339
                $idSet,
340
                $contentIdsSubset
341
            );
342
        }
343
    }
344
345 View Code Duplication
    public function testSortSectionName()
346
    {
347
        $locator = $this->getContentSearchHandler();
348
349
        $result = $locator->findContent(
350
            new Query(
351
                array(
352
                    'filter' => new Criterion\SectionId(array(4, 2, 6, 3)),
353
                    'offset' => 0,
354
                    'limit' => null,
355
                    'sortClauses' => array(
356
                        new SortClause\SectionName(),
357
                    ),
358
                )
359
            )
360
        );
361
362
        // First, results of section "Media" should appear, then the ones of "Protected",
363
        // "Setup" and "Users"
364
        // From inside a specific section, no particular order should be defined
365
        // the logic is then to have a set of sorted id's to compare with
366
        // the comparison being done slice by slice.
367
        $idMapSet = array(
368
            'media' => array(41, 49, 50, 51, 57, 58, 59, 60, 61, 62, 63, 64, 66, 200, 201),
369
            'protected' => array(154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164),
370
            'setup' => array(45, 52),
371
            'users' => array(4, 10, 11, 12, 13, 14, 42, 226),
372
        );
373
        $contentIds = array_map(
374
            function ($hit) {
375
                return $hit->valueObject->id;
376
            },
377
            $result->searchHits
378
        );
379
380
        $expectedCount = 0;
381
        foreach ($idMapSet as $set) {
382
            $expectedCount += count($set);
383
        }
384
385
        $this->assertEquals($expectedCount, $result->totalCount);
386
387
        $index = 0;
388
        foreach ($idMapSet as $idSet) {
389
            $contentIdsSubset = array_slice($contentIds, $index, $count = count($idSet));
390
            $index += $count;
391
            sort($contentIdsSubset);
392
            $this->assertEquals(
393
                $idSet,
394
                $contentIdsSubset
395
            );
396
        }
397
    }
398
399
    public function testSortContentName()
400
    {
401
        $locator = $this->getContentSearchHandler();
402
403
        $result = $locator->findContent(
404
            new Query(
405
                array(
406
                    'filter' => new Criterion\SectionId(array(2, 3)),
407
                    'offset' => 0,
408
                    'limit' => null,
409
                    'sortClauses' => array(
410
                        new SortClause\ContentName(),
411
                    ),
412
                )
413
            )
414
        );
415
416
        $this->assertEquals(
417
            array(226, 14, 12, 10, 42, 57, 13, 50, 49, 41, 11, 51, 62, 4, 58, 59, 61, 60, 64, 63, 200, 66, 201),
418
            array_map(
419
                function ($hit) {
420
                    return $hit->valueObject->id;
421
                },
422
                $result->searchHits
423
            )
424
        );
425
    }
426
427 View Code Duplication
    public function testSortFieldText()
428
    {
429
        $locator = $this->getContentSearchHandler();
430
431
        $result = $locator->findContent(
432
            new Query(
433
                array(
434
                    'filter' => new Criterion\LogicalAnd(
435
                        array(
436
                            new Criterion\SectionId(array(1)),
437
                            new Criterion\ContentTypeIdentifier(array('article')),
438
                        )
439
                    ),
440
                    'offset' => 0,
441
                    'limit' => null,
442
                    'sortClauses' => array(
443
                        new SortClause\Field('article', 'title', Query::SORT_ASC, 'eng-US'),
444
                    ),
445
                )
446
            )
447
        );
448
449
        // There are several identical titles, need to take care about this
450
        $idMapSet = array(
451
            'aenean malesuada ligula' => array(83),
452
            'aliquam pulvinar suscipit tellus' => array(102),
453
            'asynchronous publishing' => array(148, 215),
454
            'canonical links' => array(147, 216),
455
            'class aptent taciti' => array(88),
456
            'class aptent taciti sociosqu' => array(82),
457
            'duis auctor vehicula erat' => array(89),
458
            'etiam posuere sodales arcu' => array(78),
459
            'etiam sodales mauris' => array(87),
460
            'ez publish enterprise' => array(151),
461
            'fastcgi' => array(144, 218),
462
            'fusce sagittis sagittis' => array(77),
463
            'fusce sagittis sagittis urna' => array(81),
464
            'get involved' => array(107),
465
            'how to develop with ez publish' => array(127, 211),
466
            'how to manage ez publish' => array(118, 202),
467
            'how to use ez publish' => array(108, 193),
468
            'improved block editing' => array(136),
469
            'improved front-end editing' => array(139),
470
            'improved user registration workflow' => array(132),
471
            'in hac habitasse platea' => array(79),
472
            'lots of websites, one ez publish installation' => array(130),
473
            'rest api interface' => array(150, 214),
474
            'separate content & design in ez publish' => array(191),
475
            'support for red hat enterprise' => array(145, 217),
476
            'tutorials for' => array(106),
477
        );
478
        $contentIds = array_map(
479
            function ($hit) {
480
                return $hit->valueObject->id;
481
            },
482
            $result->searchHits
483
        );
484
        $index = 0;
485
486
        foreach ($idMapSet as $idSet) {
487
            $contentIdsSubset = array_slice($contentIds, $index, $count = count($idSet));
488
            $index += $count;
489
            sort($contentIdsSubset);
490
            $this->assertEquals(
491
                $idSet,
492
                $contentIdsSubset
493
            );
494
        }
495
    }
496
497 View Code Duplication
    public function testSortFieldNumeric()
498
    {
499
        $locator = $this->getContentSearchHandler();
500
501
        $result = $locator->findContent(
502
            new Query(
503
                array(
504
                    'filter' => new Criterion\LogicalAnd(
505
                        array(
506
                            new Criterion\SectionId(array(1)),
507
                            new Criterion\ContentTypeIdentifier('product'),
508
                        )
509
                    ),
510
                    'offset' => 0,
511
                    'limit' => null,
512
                    'sortClauses' => array(
513
                        new SortClause\Field('product', 'price', Query::SORT_ASC, 'eng-US'),
514
                    ),
515
                )
516
            )
517
        );
518
519
        $this->assertEquals(
520
            array(73, 71, 72, 69),
521
            array_map(
522
                function ($hit) {
523
                    return $hit->valueObject->id;
524
                },
525
                $result->searchHits
526
            )
527
        );
528
    }
529
}
530