Completed
Push — master ( 727c99...0dc4f6 )
by André
21:06
created

HandlerLocationSortTest::getLocationMapperMock()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 28

Duplication

Lines 28
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
nc 1
nop 0
dl 28
loc 28
rs 9.472
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
namespace eZ\Publish\Core\Search\Legacy\Tests\Content;
10
11
use eZ\Publish\Core\Search\Legacy\Content;
12
use eZ\Publish\SPI\Persistence\Content\Location as SPILocation;
13
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
14
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
15
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
16
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter;
17
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler as CommonCriterionHandler;
18
use eZ\Publish\Core\Search\Legacy\Content\Location\Gateway\CriterionHandler as LocationCriterionHandler;
19
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\SortClauseConverter;
20
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\SortClauseHandler as CommonSortClauseHandler;
21
use eZ\Publish\Core\Search\Legacy\Content\Location\Gateway\SortClauseHandler as LocationSortClauseHandler;
22
use eZ\Publish\Core\Search\Legacy\Content\Gateway as ContentGateway;
23
use eZ\Publish\Core\Persistence\Legacy\Content\Mapper as ContentMapper;
24
use eZ\Publish\Core\Persistence\Legacy\Content\Location\Mapper as LocationMapper;
25
26
/**
27
 * Location Search test case for ContentSearchHandler.
28
 */
29
class HandlerLocationSortTest extends AbstractTestCase
30
{
31
    protected function getIds($searchResult)
32
    {
33
        $ids = array_map(
34
            function ($hit) {
35
                return $hit->valueObject->id;
36
            },
37
            $searchResult->searchHits
38
        );
39
40
        return $ids;
41
    }
42
43
    /**
44
     * Returns the location search handler to test.
45
     *
46
     * This method returns a fully functional search handler to perform tests on.
47
     *
48
     * @return \eZ\Publish\Core\Search\Legacy\Content\Handler
49
     */
50
    protected function getContentSearchHandler()
51
    {
52
        return new Content\Handler(
53
            $this->createMock(ContentGateway::class),
54
            new Content\Location\Gateway\DoctrineDatabase(
55
                $this->getDatabaseHandler(),
56
                new CriteriaConverter(
57
                    array(
58
                        new LocationCriterionHandler\LocationId($this->getDatabaseHandler()),
59
                        new LocationCriterionHandler\ParentLocationId($this->getDatabaseHandler()),
60
                        new CommonCriterionHandler\LogicalAnd($this->getDatabaseHandler()),
61
                        new CommonCriterionHandler\MatchAll($this->getDatabaseHandler()),
62
                        new CommonCriterionHandler\SectionId($this->getDatabaseHandler()),
63
                        new CommonCriterionHandler\ContentTypeIdentifier(
64
                            $this->getDatabaseHandler(),
65
                            $this->getContentTypeHandler()
66
                        ),
67
                    )
68
                ),
69
                new SortClauseConverter(
70
                    array(
71
                        new LocationSortClauseHandler\Location\Id($this->getDatabaseHandler()),
72
                        new LocationSortClauseHandler\Location\Depth($this->getDatabaseHandler()),
73
                        new LocationSortClauseHandler\Location\Path($this->getDatabaseHandler()),
74
                        new LocationSortClauseHandler\Location\Priority($this->getDatabaseHandler()),
75
                        new LocationSortClauseHandler\Location\Visibility($this->getDatabaseHandler()),
76
                        new LocationSortClauseHandler\Location\IsMainLocation($this->getDatabaseHandler()),
77
                        new CommonSortClauseHandler\ContentId($this->getDatabaseHandler()),
78
                        new CommonSortClauseHandler\ContentName($this->getDatabaseHandler()),
79
                        new CommonSortClauseHandler\DateModified($this->getDatabaseHandler()),
80
                        new CommonSortClauseHandler\DatePublished($this->getDatabaseHandler()),
81
                        new CommonSortClauseHandler\SectionIdentifier($this->getDatabaseHandler()),
82
                        new CommonSortClauseHandler\SectionName($this->getDatabaseHandler()),
83
                        new CommonSortClauseHandler\Field(
84
                            $this->getDatabaseHandler(),
85
                            $this->getLanguageHandler(),
86
                            $this->getContentTypeHandler()
87
                        ),
88
                    )
89
                ),
90
                $this->getLanguageHandler()
91
            ),
92
            new Content\WordIndexer\Gateway\DoctrineDatabase(
93
                $this->getDatabaseHandler(),
94
                $this->getContentTypeHandler(),
95
                $this->getDefinitionBasedTransformationProcessor(),
96
                new Content\WordIndexer\Repository\SearchIndex($this->getDatabaseHandler()),
97
                $this->getFullTextSearchConfiguration()
98
            ),
99
            $this->createMock(ContentMapper::class),
100
            $this->getLocationMapperMock(),
101
            $this->getLanguageHandler(),
102
            $this->getFullTextMapper($this->getContentTypeHandler())
0 ignored issues
show
Compatibility introduced by
$this->getContentTypeHandler() of type object<eZ\Publish\SPI\Pe...e\Content\Type\Handler> is not a sub-type of object<eZ\Publish\Core\P...y\Content\Type\Handler>. It seems like you assume a concrete implementation of the interface eZ\Publish\SPI\Persistence\Content\Type\Handler to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
103
        );
104
    }
105
106
    /**
107
     * Returns a location mapper mock.
108
     *
109
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\Location\Mapper
110
     */
111 View Code Duplication
    protected function getLocationMapperMock()
112
    {
113
        $mapperMock = $this->getMockBuilder(LocationMapper::class)
114
            ->setMethods(array('createLocationsFromRows'))
115
            ->getMock();
116
        $mapperMock
117
            ->expects($this->any())
118
            ->method('createLocationsFromRows')
119
            ->with($this->isType('array'))
120
            ->will(
121
                $this->returnCallback(
122
                    function ($rows) {
123
                        $locations = array();
124
                        foreach ($rows as $row) {
125
                            $locationId = (int)$row['node_id'];
126
                            if (!isset($locations[$locationId])) {
127
                                $locations[$locationId] = new SPILocation();
128
                                $locations[$locationId]->id = $locationId;
129
                            }
130
                        }
131
132
                        return array_values($locations);
133
                    }
134
                )
135
            );
136
137
        return $mapperMock;
138
    }
139
140
    public function testNoSorting()
141
    {
142
        $handler = $this->getContentSearchHandler();
143
144
        $locations = $handler->findLocations(
145
            new LocationQuery(
146
                array(
147
                    'filter' => new Criterion\ParentLocationId(array(178)),
148
                    'offset' => 0,
149
                    'limit' => 5,
150
                    'sortClauses' => array(),
151
                )
152
            )
153
        );
154
155
        $ids = $this->getIds($locations);
156
        sort($ids);
157
        $this->assertEquals(
158
            array(179, 180, 181, 182, 183),
159
            $ids
160
        );
161
    }
162
163
    public function testSortLocationPath()
164
    {
165
        $handler = $this->getContentSearchHandler();
166
167
        $locations = $handler->findLocations(
168
            new LocationQuery(
169
                array(
170
                    'filter' => new Criterion\ParentLocationId(array(178)),
171
                    'offset' => 0,
172
                    'limit' => 10,
173
                    'sortClauses' => array(new SortClause\Location\Path(LocationQuery::SORT_DESC)),
174
                )
175
            )
176
        );
177
178
        $this->assertSearchResults(
179
            array(186, 185, 184, 183, 182, 181, 180, 179),
180
            $locations
181
        );
182
    }
183
184 View Code Duplication
    public function testSortLocationDepth()
185
    {
186
        $handler = $this->getContentSearchHandler();
187
188
        $locations = $handler->findLocations(
189
            new LocationQuery(
190
                array(
191
                    'filter' => new Criterion\LocationId(array(148, 167, 169, 172)),
192
                    'offset' => 0,
193
                    'limit' => 10,
194
                    'sortClauses' => array(new SortClause\Location\Depth(LocationQuery::SORT_ASC)),
195
                )
196
            )
197
        );
198
199
        $this->assertSearchResults(
200
            array(167, 172, 169, 148),
201
            $locations
202
        );
203
    }
204
205
    public function testSortLocationDepthAndPath()
206
    {
207
        $handler = $this->getContentSearchHandler();
208
209
        $locations = $handler->findLocations(
210
            new LocationQuery(
211
                array(
212
                    'filter' => new Criterion\LocationId(array(141, 142, 143, 144, 146, 147)),
213
                    'offset' => 0,
214
                    'limit' => 10,
215
                    'sortClauses' => array(
216
                        new SortClause\Location\Depth(LocationQuery::SORT_ASC),
217
                        new SortClause\Location\Path(LocationQuery::SORT_DESC),
218
                    ),
219
                )
220
            )
221
        );
222
223
        $this->assertSearchResults(
224
            array(147, 146, 141, 144, 143, 142),
225
            $locations
226
        );
227
    }
228
229 View Code Duplication
    public function testSortLocationPriority()
230
    {
231
        $handler = $this->getContentSearchHandler();
232
233
        $locations = $handler->findLocations(
234
            new LocationQuery(
235
                array(
236
                    'filter' => new Criterion\LocationId(array(149, 156, 167)),
237
                    'offset' => 0,
238
                    'limit' => 10,
239
                    'sortClauses' => array(
240
                        new SortClause\Location\Priority(LocationQuery::SORT_DESC),
241
                    ),
242
                )
243
            )
244
        );
245
246
        $this->assertSearchResults(
247
            array(167, 156, 149),
248
            $locations
249
        );
250
    }
251
252
    public function testSortDateModified()
253
    {
254
        $handler = $this->getContentSearchHandler();
255
256
        $locations = $handler->findLocations(
257
            new LocationQuery(
258
                array(
259
                    'filter' => new Criterion\LocationId(array(148, 167, 169, 172)),
260
                    'offset' => 0,
261
                    'limit' => 10,
262
                    'sortClauses' => array(
263
                        new SortClause\DateModified(),
264
                    ),
265
                )
266
            )
267
        );
268
269
        $this->assertSearchResults(
270
            array(169, 172, 167, 148),
271
            $locations
272
        );
273
    }
274
275 View Code Duplication
    public function testSortDatePublished()
276
    {
277
        $handler = $this->getContentSearchHandler();
278
279
        $locations = $handler->findLocations(
280
            new LocationQuery(
281
                array(
282
                    'filter' => new Criterion\LocationId(array(148, 167, 169, 172)),
283
                    'offset' => 0,
284
                    'limit' => 10,
285
                    'sortClauses' => array(
286
                        new SortClause\DatePublished(LocationQuery::SORT_DESC),
287
                    ),
288
                )
289
            )
290
        );
291
292
        $this->assertSearchResults(
293
            array(148, 172, 169, 167),
294
            $locations
295
        );
296
    }
297
298
    public function testSortSectionIdentifier()
299
    {
300
        $handler = $this->getContentSearchHandler();
301
302
        $locations = $handler->findLocations(
303
            new LocationQuery(
304
                array(
305
                    'filter' => new Criterion\LocationId(
306
                        array(5, 43, 45, 48, 51, 54, 156, 157)
307
                    ),
308
                    'offset' => 0,
309
                    'limit' => null,
310
                    'sortClauses' => array(
311
                        new SortClause\SectionIdentifier(),
312
                    ),
313
                )
314
            )
315
        );
316
317
        // First, results of section 2 should appear, then the ones of 3, 4 and 6
318
        // From inside a specific section, no particular order should be defined
319
        // the logic is then to have a set of sorted id's to compare with
320
        // the comparison being done slice by slice.
321
        $idMapSet = array(
322
            2 => array(5, 45),
323
            3 => array(43, 51),
324
            4 => array(48, 54),
325
            6 => array(156, 157),
326
        );
327
        $locationIds = $this->getIds($locations);
328
        $index = 0;
329
330
        foreach ($idMapSet as $idSet) {
331
            $locationIdsSubset = array_slice($locationIds, $index, $count = count($idSet));
332
            $index += $count;
333
            sort($locationIdsSubset);
334
            $this->assertEquals(
335
                $idSet,
336
                $locationIdsSubset
337
            );
338
        }
339
    }
340
341
    public function testSortContentName()
342
    {
343
        $handler = $this->getContentSearchHandler();
344
345
        $locations = $handler->findLocations(
346
            new LocationQuery(
347
                array(
348
                    'filter' => new Criterion\LocationId(array(13, 15, 44, 45, 228)),
349
                    'offset' => 0,
350
                    'limit' => null,
351
                    'sortClauses' => array(
352
                        new SortClause\ContentName(),
353
                    ),
354
                )
355
            )
356
        );
357
358
        $this->assertSearchResults(
359
            array(228, 15, 13, 45, 44),
360
            $locations
361
        );
362
    }
363
364
    public function testSortContentId()
365
    {
366
        $handler = $this->getContentSearchHandler();
367
368
        $locations = $handler->findLocations(
369
            new LocationQuery(
370
                array(
371
                    'filter' => new Criterion\LocationId(array(13, 15, 44, 45, 228)),
372
                    'offset' => 0,
373
                    'limit' => null,
374
                    'sortClauses' => array(
375
                        new SortClause\ContentId(),
376
                    ),
377
                )
378
            )
379
        );
380
381
        $this->assertSearchResults(
382
            array(45, 13, 15, 44, 228),
383
            $locations
384
        );
385
    }
386
387
    public function testSortLocationId()
388
    {
389
        $handler = $this->getContentSearchHandler();
390
391
        $locations = $handler->findLocations(
392
            new LocationQuery(
393
                array(
394
                    'filter' => new Criterion\LocationId(array(13, 15, 44, 45, 228)),
395
                    'offset' => 0,
396
                    'limit' => null,
397
                    'sortClauses' => array(
398
                        new SortClause\Location\Id(LocationQuery::SORT_DESC),
399
                    ),
400
                )
401
            )
402
        );
403
404
        $this->assertSearchResults(
405
            array(228, 45, 44, 15, 13),
406
            $locations
407
        );
408
    }
409
410 View Code Duplication
    public function testSortLocationVisibilityAscending()
411
    {
412
        $handler = $this->getContentSearchHandler();
413
414
        $locations = $handler->findLocations(
415
            new LocationQuery(
416
                array(
417
                    'filter' => new Criterion\LocationId(array(45, 228)),
418
                    'offset' => 0,
419
                    'limit' => null,
420
                    'sortClauses' => array(
421
                        new SortClause\Location\Visibility(LocationQuery::SORT_ASC),
422
                    ),
423
                )
424
            )
425
        );
426
427
        $this->assertSearchResults(
428
            array(45, 228),
429
            $locations
430
        );
431
    }
432
433 View Code Duplication
    public function testSortLocationVisibilityDescending()
434
    {
435
        $handler = $this->getContentSearchHandler();
436
437
        $locations = $handler->findLocations(
438
            new LocationQuery(
439
                array(
440
                    'filter' => new Criterion\LocationId(array(45, 228)),
441
                    'offset' => 0,
442
                    'limit' => null,
443
                    'sortClauses' => array(
444
                        new SortClause\Location\Visibility(LocationQuery::SORT_DESC),
445
                    ),
446
                )
447
            )
448
        );
449
450
        $this->assertSearchResults(
451
            array(228, 45),
452
            $locations
453
        );
454
    }
455
456 View Code Duplication
    public function testSortSectionName()
457
    {
458
        $handler = $this->getContentSearchHandler();
459
460
        $result = $handler->findLocations(
461
            new LocationQuery(
462
                array(
463
                    'filter' => new Criterion\SectionId(array(4, 2, 6, 3)),
464
                    'offset' => 0,
465
                    'limit' => null,
466
                    'sortClauses' => array(
467
                        new SortClause\SectionName(),
468
                    ),
469
                )
470
            )
471
        );
472
473
        // First, results of section "Media" should appear, then the ones of "Protected",
474
        // "Setup" and "Users"
475
        // From inside a specific section, no particular order should be defined
476
        // the logic is then to have a set of sorted id's to compare with
477
        // the comparison being done slice by slice.
478
        $idMapSet = array(
479
            'media' => array(43, 51, 52, 53, 59, 60, 61, 62, 63, 64, 65, 66, 68, 202, 203),
480
            'protected' => array(156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166),
481
            'setup' => array(48, 54),
482
            'users' => array(5, 12, 13, 14, 15, 44, 45, 228),
483
        );
484
        $locationIds = array_map(
485
            function ($hit) {
486
                return $hit->valueObject->id;
487
            },
488
            $result->searchHits
489
        );
490
491
        $expectedCount = 0;
492
        foreach ($idMapSet as $set) {
493
            $expectedCount += count($set);
494
        }
495
496
        $this->assertEquals($expectedCount, $result->totalCount);
497
498
        $index = 0;
499
        foreach ($idMapSet as $idSet) {
500
            $locationIdsSubset = array_slice($locationIds, $index, $count = count($idSet));
501
            $index += $count;
502
            sort($locationIdsSubset);
503
            $this->assertEquals(
504
                $idSet,
505
                $locationIdsSubset
506
            );
507
        }
508
    }
509
510 View Code Duplication
    public function testSortFieldText()
511
    {
512
        $handler = $this->getContentSearchHandler();
513
514
        $result = $handler->findLocations(
515
            new LocationQuery(
516
                array(
517
                    'filter' => new Criterion\LogicalAnd(
518
                        array(
519
                            new Criterion\SectionId(array(1)),
520
                            new Criterion\ContentTypeIdentifier(array('article')),
521
                        )
522
                    ),
523
                    'offset' => 0,
524
                    'limit' => null,
525
                    'sortClauses' => array(
526
                        new SortClause\Field('article', 'title', LocationQuery::SORT_ASC, 'eng-US'),
527
                    ),
528
                )
529
            )
530
        );
531
532
        // There are several identical titles, need to take care about this
533
        $idMapSet = array(
534
            'aenean malesuada ligula' => array(85),
535
            'aliquam pulvinar suscipit tellus' => array(104),
536
            'asynchronous publishing' => array(150, 217),
537
            'canonical links' => array(149, 218),
538
            'class aptent taciti' => array(90),
539
            'class aptent taciti sociosqu' => array(84),
540
            'duis auctor vehicula erat' => array(91),
541
            'etiam posuere sodales arcu' => array(80),
542
            'etiam sodales mauris' => array(89),
543
            'ez publish enterprise' => array(153),
544
            'fastcgi' => array(146, 220),
545
            'fusce sagittis sagittis' => array(79),
546
            'fusce sagittis sagittis urna' => array(83),
547
            'get involved' => array(109),
548
            'how to develop with ez publish' => array(129, 213),
549
            'how to manage ez publish' => array(120, 204),
550
            'how to use ez publish' => array(110, 195),
551
            'improved block editing' => array(138),
552
            'improved front-end editing' => array(141),
553
            'improved user registration workflow' => array(134),
554
            'in hac habitasse platea' => array(81),
555
            'lots of websites, one ez publish installation' => array(132),
556
            'rest api interface' => array(152, 216),
557
            'separate content & design in ez publish' => array(193),
558
            'support for red hat enterprise' => array(147, 219),
559
            'tutorials for' => array(108),
560
        );
561
        $locationIds = array_map(
562
            function ($hit) {
563
                return $hit->valueObject->id;
564
            },
565
            $result->searchHits
566
        );
567
        $index = 0;
568
569
        foreach ($idMapSet as $idSet) {
570
            $locationIdsSubset = array_slice($locationIds, $index, $count = count($idSet));
571
            $index += $count;
572
            sort($locationIdsSubset);
573
            $this->assertEquals(
574
                $idSet,
575
                $locationIdsSubset
576
            );
577
        }
578
    }
579
580 View Code Duplication
    public function testSortFieldNumeric()
581
    {
582
        $handler = $this->getContentSearchHandler();
583
584
        $result = $handler->findLocations(
585
            new LocationQuery(
586
                array(
587
                    'filter' => new Criterion\LogicalAnd(
588
                        array(
589
                            new Criterion\SectionId(array(1)),
590
                            new Criterion\ContentTypeIdentifier('product'),
591
                        )
592
                    ),
593
                    'offset' => 0,
594
                    'limit' => null,
595
                    'sortClauses' => array(
596
                        new SortClause\Field('product', 'price', LocationQuery::SORT_ASC, 'eng-US'),
597
                    ),
598
                )
599
            )
600
        );
601
602
        $this->assertEquals(
603
            array(75, 73, 74, 71),
604
            array_map(
605
                function ($hit) {
606
                    return $hit->valueObject->id;
607
                },
608
                $result->searchHits
609
            )
610
        );
611
    }
612
613 View Code Duplication
    public function testSortIsMainLocationAscending()
614
    {
615
        $handler = $this->getContentSearchHandler();
616
617
        $locations = $handler->findLocations(
618
            new LocationQuery(
619
                array(
620
                    'filter' => new Criterion\ParentLocationId(224),
621
                    'offset' => 0,
622
                    'limit' => null,
623
                    'sortClauses' => array(
624
                        new SortClause\Location\IsMainLocation(LocationQuery::SORT_ASC),
625
                    ),
626
                )
627
            )
628
        );
629
630
        $this->assertSearchResults(
631
            array(510, 225),
632
            $locations
633
        );
634
    }
635
636 View Code Duplication
    public function testSortIsMainLocationDescending()
637
    {
638
        $handler = $this->getContentSearchHandler();
639
640
        $locations = $handler->findLocations(
641
            new LocationQuery(
642
                array(
643
                    'filter' => new Criterion\ParentLocationId(224),
644
                    'offset' => 0,
645
                    'limit' => null,
646
                    'sortClauses' => array(
647
                        new SortClause\Location\IsMainLocation(LocationQuery::SORT_DESC),
648
                    ),
649
                )
650
            )
651
        );
652
653
        $this->assertSearchResults(
654
            array(225, 510),
655
            $locations
656
        );
657
    }
658
}
659