Completed
Push — master ( 105f11...ea7cfc )
by
unknown
13:00 queued 11s
created

testGetNonExistingFieldDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
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\Persistence;
12
use eZ\Publish\Core\Search\Legacy\Content;
13
use eZ\Publish\API\Repository\Values\Content\Query;
14
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
15
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
16
use eZ\Publish\SPI\Persistence\Content\ContentInfo;
17
use eZ\Publish\Core\Search\Legacy\Content\Location\Gateway as LocationGateway;
18
use eZ\Publish\Core\Persistence\Legacy\Content\Location\Mapper as LocationMapper;
19
use eZ\Publish\Core\Persistence\Legacy\Content\Mapper as ContentMapper;
20
use eZ\Publish\Core\Persistence\Legacy\Content\FieldHandler;
21
use eZ\Publish\SPI\Persistence\Content\Type;
22
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
23
24
/**
25
 * Content Search test case for ContentSearchHandler.
26
 */
27
class HandlerContentTest extends AbstractTestCase
28
{
29
    /**
30
     * Returns the content search handler to test.
31
     *
32
     * This method returns a fully functional search handler to perform tests
33
     * on.
34
     *
35
     * @param array $fullTextSearchConfiguration
36
     *
37
     * @return \eZ\Publish\Core\Search\Legacy\Content\Handler
38
     */
39
    protected function getContentSearchHandler(array $fullTextSearchConfiguration = [])
40
    {
41
        $transformationProcessor = new Persistence\TransformationProcessor\DefinitionBased(
42
            new Persistence\TransformationProcessor\DefinitionBased\Parser(),
43
            new Persistence\TransformationProcessor\PcreCompiler(
44
                new Persistence\Utf8Converter()
45
            ),
46
            glob(__DIR__ . '/../../../../Persistence/Tests/TransformationProcessor/_fixtures/transformations/*.tr')
47
        );
48
        $commaSeparatedCollectionValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Collection(
49
            $this->getDatabaseHandler(),
50
            $transformationProcessor,
51
            ','
52
        );
53
        $hyphenSeparatedCollectionValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Collection(
54
            $this->getDatabaseHandler(),
55
            $transformationProcessor,
56
            '-'
57
        );
58
        $simpleValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Simple(
59
            $this->getDatabaseHandler(),
60
            $transformationProcessor
61
        );
62
        $compositeValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Composite(
63
            $this->getDatabaseHandler(),
64
            $transformationProcessor
65
        );
66
67
        return new Content\Handler(
68
            new Content\Gateway\DoctrineDatabase(
69
                $this->getDatabaseHandler(),
70
                new Content\Common\Gateway\CriteriaConverter(
71
                    [
72
                        new Content\Common\Gateway\CriterionHandler\ContentId(
73
                            $this->getDatabaseHandler()
74
                        ),
75
                        new Content\Common\Gateway\CriterionHandler\LogicalNot(
76
                            $this->getDatabaseHandler()
77
                        ),
78
                        new Content\Common\Gateway\CriterionHandler\LogicalAnd(
79
                            $this->getDatabaseHandler()
80
                        ),
81
                        new Content\Common\Gateway\CriterionHandler\LogicalOr(
82
                            $this->getDatabaseHandler()
83
                        ),
84
                        new Content\Gateway\CriterionHandler\Subtree(
85
                            $this->getDatabaseHandler()
86
                        ),
87
                        new Content\Common\Gateway\CriterionHandler\ContentTypeId(
88
                            $this->getDatabaseHandler()
89
                        ),
90
                        new Content\Common\Gateway\CriterionHandler\ContentTypeIdentifier(
91
                            $this->getDatabaseHandler(),
92
                            $this->getContentTypeHandler()
93
                        ),
94
                        new Content\Common\Gateway\CriterionHandler\ContentTypeGroupId(
95
                            $this->getDatabaseHandler()
96
                        ),
97
                        new Content\Common\Gateway\CriterionHandler\DateMetadata(
98
                            $this->getDatabaseHandler()
99
                        ),
100
                        new Content\Gateway\CriterionHandler\LocationId(
101
                            $this->getDatabaseHandler()
102
                        ),
103
                        new Content\Gateway\CriterionHandler\ParentLocationId(
104
                            $this->getDatabaseHandler()
105
                        ),
106
                        new Content\Common\Gateway\CriterionHandler\RemoteId(
107
                            $this->getDatabaseHandler()
108
                        ),
109
                        new Content\Gateway\CriterionHandler\LocationRemoteId(
110
                            $this->getDatabaseHandler()
111
                        ),
112
                        new Content\Common\Gateway\CriterionHandler\SectionId(
113
                            $this->getDatabaseHandler()
114
                        ),
115
                        new Content\Common\Gateway\CriterionHandler\FullText(
116
                            $this->getDatabaseHandler(),
117
                            $transformationProcessor,
118
                            $this->getLanguageMaskGenerator(),
119
                            $fullTextSearchConfiguration
120
                        ),
121
                        new Content\Common\Gateway\CriterionHandler\Field(
122
                            $this->getDatabaseHandler(),
123
                            $this->getContentTypeHandler(),
124
                            $this->getLanguageHandler(),
125
                            $this->getConverterRegistry(),
126
                            new Content\Common\Gateway\CriterionHandler\FieldValue\Converter(
127
                                new Content\Common\Gateway\CriterionHandler\FieldValue\HandlerRegistry(
128
                                    [
129
                                        'ezboolean' => $simpleValueHandler,
130
                                        'ezcountry' => $commaSeparatedCollectionValueHandler,
131
                                        'ezdate' => $simpleValueHandler,
132
                                        'ezdatetime' => $simpleValueHandler,
133
                                        'ezemail' => $simpleValueHandler,
134
                                        'ezinteger' => $simpleValueHandler,
135
                                        'ezobjectrelation' => $simpleValueHandler,
136
                                        'ezobjectrelationlist' => $commaSeparatedCollectionValueHandler,
137
                                        'ezselection' => $hyphenSeparatedCollectionValueHandler,
138
                                        'eztime' => $simpleValueHandler,
139
                                    ]
140
                                ),
141
                                $compositeValueHandler
142
                            ),
143
                            $transformationProcessor
144
                        ),
145
                        new Content\Common\Gateway\CriterionHandler\ObjectStateId(
146
                            $this->getDatabaseHandler()
147
                        ),
148
                        new Content\Common\Gateway\CriterionHandler\LanguageCode(
149
                            $this->getDatabaseHandler(),
150
                            $this->getLanguageMaskGenerator()
151
                        ),
152
                        new Content\Gateway\CriterionHandler\Visibility(
153
                            $this->getDatabaseHandler()
154
                        ),
155
                        new Content\Common\Gateway\CriterionHandler\MatchAll(
156
                            $this->getDatabaseHandler()
157
                        ),
158
                        new Content\Common\Gateway\CriterionHandler\UserMetadata(
159
                            $this->getDatabaseHandler()
160
                        ),
161
                        new Content\Common\Gateway\CriterionHandler\FieldRelation(
162
                            $this->getDatabaseHandler(),
163
                            $this->getContentTypeHandler(),
164
                            $this->getLanguageHandler()
165
                        ),
166
                    ]
167
                ),
168
                new Content\Common\Gateway\SortClauseConverter(
169
                    [
170
                        new Content\Common\Gateway\SortClauseHandler\ContentId($this->getDatabaseHandler()),
171
                    ]
172
                ),
173
                $this->getLanguageHandler()
174
            ),
175
            $this->createMock(LocationGateway::class),
176
            new Content\WordIndexer\Gateway\DoctrineDatabase(
177
                $this->getDatabaseHandler(),
178
                $this->getContentTypeHandler(),
179
                $this->getDefinitionBasedTransformationProcessor(),
180
                new Content\WordIndexer\Repository\SearchIndex($this->getDatabaseHandler()),
181
                $this->getLanguageMaskGenerator(),
182
                $this->getFullTextSearchConfiguration()
183
            ),
184
            $this->getContentMapperMock(),
185
            $this->createMock(LocationMapper::class),
186
            $this->getLanguageHandler(),
187
            $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...
188
        );
189
    }
190
191
    /**
192
     * Returns a content mapper mock.
193
     *
194
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\Mapper
195
     */
196
    protected function getContentMapperMock()
197
    {
198
        $mapperMock = $this->getMockBuilder(ContentMapper::class)
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/pull/3687

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...
199
            ->setConstructorArgs(
200
                [
201
                    $this->getConverterRegistry(),
202
                    $this->getLanguageHandler(),
203
                ]
204
            )
205
            ->setMethods(['extractContentInfoFromRows'])
206
            ->getMock();
207
        $mapperMock->expects($this->any())
208
            ->method('extractContentInfoFromRows')
209
            ->with($this->isType('array'))
210
            ->will(
211
                $this->returnCallback(
212
                    function ($rows) {
213
                        $contentInfoObjs = [];
214
                        foreach ($rows as $row) {
215
                            $contentId = (int)$row['id'];
216
                            if (!isset($contentInfoObjs[$contentId])) {
217
                                $contentInfoObjs[$contentId] = new ContentInfo();
218
                                $contentInfoObjs[$contentId]->id = $contentId;
219
                            }
220
                        }
221
222
                        return array_values($contentInfoObjs);
223
                    }
224
                )
225
            );
226
227
        return $mapperMock;
228
    }
229
230
    /**
231
     * Returns a content field handler mock.
232
     *
233
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\FieldHandler
234
     */
235
    protected function getContentFieldHandlerMock()
236
    {
237
        return $this->getMockBuilder(FieldHandler::class)
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/pull/3687

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...
238
            ->disableOriginalConstructor()
239
            ->setMethods(['loadExternalFieldData'])
240
            ->getMock();
241
    }
242
243
    /**
244
     * Bug #80.
245
     */
246
    public function testFindWithoutOffsetLimit()
247
    {
248
        $locator = $this->getContentSearchHandler();
249
250
        $result = $locator->findContent(
251
            new Query(
252
                [
253
                    'filter' => new Criterion\ContentId(10),
254
                ]
255
            )
256
        );
257
258
        $this->assertEquals(
259
            1,
260
            $result->totalCount
261
        );
262
    }
263
264
    /**
265
     * Bug #81, bug #82.
266
     */
267 View Code Duplication
    public function testFindWithZeroLimit()
268
    {
269
        $locator = $this->getContentSearchHandler();
270
271
        $result = $locator->findContent(
272
            new Query(
273
                [
274
                    'filter' => new Criterion\ContentId(10),
275
                    'offset' => 0,
276
                    'limit' => 0,
277
                ]
278
            )
279
        );
280
281
        $this->assertEquals(
282
            1,
283
            $result->totalCount
284
        );
285
        $this->assertEquals(
286
            [],
287
            $result->searchHits
288
        );
289
    }
290
291
    /**
292
     * Issue with PHP_MAX_INT limit overflow in databases.
293
     */
294
    public function testFindWithNullLimit()
295
    {
296
        $locator = $this->getContentSearchHandler();
297
298
        $result = $locator->findContent(
299
            new Query(
300
                [
301
                    'filter' => new Criterion\ContentId(10),
302
                    'offset' => 0,
303
                    'limit' => null,
304
                ]
305
            )
306
        );
307
308
        $this->assertEquals(
309
            1,
310
            $result->totalCount
311
        );
312
        $this->assertCount(
313
            1,
314
            $result->searchHits
315
        );
316
    }
317
318
    /**
319
     * Issue with offsetting to the nonexistent results produces \ezcQueryInvalidParameterException exception.
320
     */
321
    public function testFindWithOffsetToNonexistent()
322
    {
323
        $locator = $this->getContentSearchHandler();
324
325
        $result = $locator->findContent(
326
            new Query(
327
                [
328
                    'filter' => new Criterion\ContentId(10),
329
                    'offset' => 1000,
330
                    'limit' => null,
331
                ]
332
            )
333
        );
334
335
        $this->assertEquals(
336
            1,
337
            $result->totalCount
338
        );
339
        $this->assertCount(
340
            0,
341
            $result->searchHits
342
        );
343
    }
344
345
    public function testFindSingle()
346
    {
347
        $locator = $this->getContentSearchHandler();
348
349
        $contentInfo = $locator->findSingle(new Criterion\ContentId(10));
350
351
        $this->assertEquals(10, $contentInfo->id);
352
    }
353
354
    public function testFindSingleWithNonSearchableField()
355
    {
356
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
357
358
        $locator = $this->getContentSearchHandler();
359
        $locator->findSingle(
360
            new Criterion\Field(
361
                'tag_cloud_url',
362
                Criterion\Operator::EQ,
363
                'http://nimbus.com'
364
            )
365
        );
366
    }
367
368
    public function testFindContentWithNonSearchableField()
369
    {
370
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
371
372
        $locator = $this->getContentSearchHandler();
373
        $locator->findContent(
374
            new Query(
375
                [
376
                    'filter' => new Criterion\Field(
377
                        'tag_cloud_url',
378
                        Criterion\Operator::EQ,
379
                        'http://nimbus.com'
380
                    ),
381
                    'sortClauses' => [new SortClause\ContentId()],
382
                ]
383
            )
384
        );
385
    }
386
387
    public function testFindSingleTooMany()
388
    {
389
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
390
391
        $locator = $this->getContentSearchHandler();
392
        $locator->findSingle(new Criterion\ContentId([4, 10, 12, 23]));
393
    }
394
395
    public function testFindSingleZero()
396
    {
397
        $this->expectException(NotFoundException::class);
398
399
        $locator = $this->getContentSearchHandler();
400
        $locator->findSingle(new Criterion\ContentId(0));
401
    }
402
403
    public function testContentIdFilter()
404
    {
405
        $this->assertSearchResults(
406
            [4, 10],
407
            $this->getContentSearchHandler()->findContent(
408
                new Query(
409
                    [
410
                        'filter' => new Criterion\ContentId(
411
                            [1, 4, 10]
412
                        ),
413
                        'limit' => 10,
414
                    ]
415
                )
416
            )
417
        );
418
    }
419
420
    public function testContentIdFilterCount()
421
    {
422
        $locator = $this->getContentSearchHandler();
423
424
        $result = $locator->findContent(
425
            new Query(
426
                [
427
                    'filter' => new Criterion\ContentId(
428
                        [1, 4, 10]
429
                    ),
430
                    'limit' => 10,
431
                ]
432
            )
433
        );
434
435
        $this->assertSame(2, $result->totalCount);
436
    }
437
438
    public function testContentAndCombinatorFilter()
439
    {
440
        $this->assertSearchResults(
441
            [4],
442
            $this->getContentSearchHandler()->findContent(
443
                new Query(
444
                    [
445
                        'filter' => new Criterion\LogicalAnd(
446
                            [
447
                                new Criterion\ContentId(
448
                                    [1, 4, 10]
449
                                ),
450
                                new Criterion\ContentId(
451
                                    [4, 12]
452
                                ),
453
                            ]
454
                        ),
455
                        'limit' => 10,
456
                    ]
457
                )
458
            )
459
        );
460
    }
461
462
    public function testContentOrCombinatorFilter()
463
    {
464
        $locator = $this->getContentSearchHandler();
465
466
        $result = $locator->findContent(
467
            new Query(
468
                [
469
                    'filter' => new Criterion\LogicalOr(
470
                        [
471
                            new Criterion\ContentId(
472
                                [1, 4, 10]
473
                            ),
474
                            new Criterion\ContentId(
475
                                [4, 12]
476
                            ),
477
                        ]
478
                    ),
479
                    'limit' => 10,
480
                ]
481
            )
482
        );
483
484
        $expectedContentIds = [4, 10, 12];
485
486
        $this->assertEquals(
487
            count($expectedContentIds),
488
            count($result->searchHits)
489
        );
490
        foreach ($result->searchHits as $hit) {
491
            $this->assertContains(
492
                $hit->valueObject->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
493
                $expectedContentIds
494
            );
495
        }
496
    }
497
498
    public function testContentNotCombinatorFilter()
499
    {
500
        $this->assertSearchResults(
501
            [4],
502
            $this->getContentSearchHandler()->findContent(
503
                new Query(
504
                    [
505
                        'filter' => new Criterion\LogicalAnd(
506
                            [
507
                                new Criterion\ContentId(
508
                                    [1, 4, 10]
509
                                ),
510
                                new Criterion\LogicalNot(
511
                                    new Criterion\ContentId(
512
                                        [10, 12]
513
                                    )
514
                                ),
515
                            ]
516
                        ),
517
                        'limit' => 10,
518
                    ]
519
                )
520
            )
521
        );
522
    }
523
524 View Code Duplication
    public function testContentSubtreeFilterIn()
525
    {
526
        $this->assertSearchResults(
527
            [67, 68, 69, 70, 71, 72, 73, 74],
528
            $this->getContentSearchHandler()->findContent(
529
                new Query(
530
                    [
531
                        'filter' => new Criterion\Subtree(
532
                            ['/1/2/69/']
533
                        ),
534
                        'limit' => 10,
535
                    ]
536
                )
537
            )
538
        );
539
    }
540
541 View Code Duplication
    public function testContentSubtreeFilterEq()
542
    {
543
        $this->assertSearchResults(
544
            [67, 68, 69, 70, 71, 72, 73, 74],
545
            $this->getContentSearchHandler()->findContent(
546
                new Query(
547
                    [
548
                        'filter' => new Criterion\Subtree('/1/2/69/'),
549
                        'limit' => 10,
550
                    ]
551
                )
552
            )
553
        );
554
    }
555
556 View Code Duplication
    public function testContentTypeIdFilter()
557
    {
558
        $this->assertSearchResults(
559
            [10, 14, 226],
560
            $this->getContentSearchHandler()->findContent(
561
                new Query(
562
                    [
563
                        'filter' => new Criterion\ContentTypeId(4),
564
                        'limit' => 10,
565
                    ]
566
                )
567
            )
568
        );
569
    }
570
571
    public function testContentTypeIdentifierFilter()
572
    {
573
        $this->assertSearchResults(
574
            [41, 45, 49, 50, 51],
575
            $this->getContentSearchHandler()->findContent(
576
                new Query(
577
                    [
578
                        'filter' => new Criterion\ContentTypeIdentifier('folder'),
579
                        'limit' => 5,
580
                        'sortClauses' => [new SortClause\ContentId()],
581
                    ]
582
                )
583
            )
584
        );
585
    }
586
587 View Code Duplication
    public function testContentTypeGroupFilter()
588
    {
589
        $this->assertSearchResults(
590
            [4, 10, 11, 12, 13, 14, 42, 225, 226],
591
            $this->getContentSearchHandler()->findContent(
592
                new Query(
593
                    [
594
                        'filter' => new Criterion\ContentTypeGroupId(2),
595
                        'limit' => 10,
596
                    ]
597
                )
598
            )
599
        );
600
    }
601
602
    public function testDateMetadataFilterModifiedGreater()
603
    {
604
        $this->assertSearchResults(
605
            [11, 225, 226],
606
            $this->getContentSearchHandler()->findContent(
607
                new Query(
608
                    [
609
                        'filter' => new Criterion\DateMetadata(
610
                            Criterion\DateMetadata::MODIFIED,
611
                            Criterion\Operator::GT,
612
                            1311154214
613
                        ),
614
                        'limit' => 10,
615
                    ]
616
                )
617
            )
618
        );
619
    }
620
621
    public function testDateMetadataFilterModifiedGreaterOrEqual()
622
    {
623
        $this->assertSearchResults(
624
            [11, 14, 225, 226],
625
            $this->getContentSearchHandler()->findContent(
626
                new Query(
627
                    [
628
                        'filter' => new Criterion\DateMetadata(
629
                            Criterion\DateMetadata::MODIFIED,
630
                            Criterion\Operator::GTE,
631
                            1311154214
632
                        ),
633
                        'limit' => 10,
634
                    ]
635
                )
636
            )
637
        );
638
    }
639
640
    public function testDateMetadataFilterModifiedIn()
641
    {
642
        $this->assertSearchResults(
643
            [11, 14, 225, 226],
644
            $this->getContentSearchHandler()->findContent(
645
                new Query(
646
                    [
647
                        'filter' => new Criterion\DateMetadata(
648
                            Criterion\DateMetadata::MODIFIED,
649
                            Criterion\Operator::IN,
650
                            [1311154214, 1311154215]
651
                        ),
652
                        'limit' => 10,
653
                    ]
654
                )
655
            )
656
        );
657
    }
658
659
    public function testDateMetadataFilterModifiedBetween()
660
    {
661
        $this->assertSearchResults(
662
            [11, 14, 225, 226],
663
            $this->getContentSearchHandler()->findContent(
664
                new Query(
665
                    [
666
                        'filter' => new Criterion\DateMetadata(
667
                            Criterion\DateMetadata::MODIFIED,
668
                            Criterion\Operator::BETWEEN,
669
                            [1311154213, 1311154215]
670
                        ),
671
                        'limit' => 10,
672
                    ]
673
                )
674
            )
675
        );
676
    }
677
678
    public function testDateMetadataFilterCreatedBetween()
679
    {
680
        $this->assertSearchResults(
681
            [66, 131, 225],
682
            $this->getContentSearchHandler()->findContent(
683
                new Query(
684
                    [
685
                        'filter' => new Criterion\DateMetadata(
686
                            Criterion\DateMetadata::CREATED,
687
                            Criterion\Operator::BETWEEN,
688
                            [1299780749, 1311154215]
689
                        ),
690
                        'limit' => 10,
691
                    ]
692
                )
693
            )
694
        );
695
    }
696
697
    public function testLocationIdFilter()
698
    {
699
        $this->assertSearchResults(
700
            [4, 65],
701
            $this->getContentSearchHandler()->findContent(
702
                new Query(
703
                    [
704
                        'filter' => new Criterion\LocationId([1, 2, 5]),
705
                        'limit' => 10,
706
                    ]
707
                )
708
            )
709
        );
710
    }
711
712
    public function testParentLocationIdFilter()
713
    {
714
        $this->assertSearchResults(
715
            [4, 41, 45, 56, 65],
716
            $this->getContentSearchHandler()->findContent(
717
                new Query(
718
                    [
719
                        'filter' => new Criterion\ParentLocationId([1]),
720
                        'limit' => 10,
721
                    ]
722
                )
723
            )
724
        );
725
    }
726
727
    public function testRemoteIdFilter()
728
    {
729
        $this->assertSearchResults(
730
            [4, 10],
731
            $this->getContentSearchHandler()->findContent(
732
                new Query(
733
                    [
734
                        'filter' => new Criterion\RemoteId(
735
                            ['f5c88a2209584891056f987fd965b0ba', 'faaeb9be3bd98ed09f606fc16d144eca']
736
                        ),
737
                        'limit' => 10,
738
                    ]
739
                )
740
            )
741
        );
742
    }
743
744
    public function testLocationRemoteIdFilter()
745
    {
746
        $this->assertSearchResults(
747
            [4, 65],
748
            $this->getContentSearchHandler()->findContent(
749
                new Query(
750
                    [
751
                        'filter' => new Criterion\LocationRemoteId(
752
                            ['3f6d92f8044aed134f32153517850f5a', 'f3e90596361e31d496d4026eb624c983']
753
                        ),
754
                        'limit' => 10,
755
                    ]
756
                )
757
            )
758
        );
759
    }
760
761 View Code Duplication
    public function testSectionFilter()
762
    {
763
        $this->assertSearchResults(
764
            [4, 10, 11, 12, 13, 14, 42, 226],
765
            $this->getContentSearchHandler()->findContent(
766
                new Query(
767
                    [
768
                        'filter' => new Criterion\SectionId([2]),
769
                        'limit' => 10,
770
                    ]
771
                )
772
            )
773
        );
774
    }
775
776
    public function testStatusFilter()
777
    {
778
        $this->assertSearchResults(
779
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
780
            $searchResult = $this->getContentSearchHandler()->findContent(
781
                new Query(
782
                    [
783
                        // Status criterion is gone, but this will also match all published
784
                        'filter' => new Criterion\LogicalNot(
785
                            new Criterion\ContentId(
786
                                [0]
787
                            )
788
                        ),
789
                        'limit' => 10,
790
                        'sortClauses' => [new SortClause\ContentId()],
791
                    ]
792
                )
793
            )
794
        );
795
796
        $this->assertEquals(
797
            185,
798
            $searchResult->totalCount
799
        );
800
    }
801
802
    public function testFieldFilter()
803
    {
804
        $this->assertSearchResults(
805
            [11],
806
            $this->getContentSearchHandler()->findContent(
807
                new Query(
808
                    [
809
                        'filter' => new Criterion\Field(
810
                            'name',
811
                            Criterion\Operator::EQ,
812
                            'members'
813
                        ),
814
                        'limit' => 10,
815
                    ]
816
                )
817
            )
818
        );
819
    }
820
821 View Code Duplication
    public function testFieldFilterIn()
822
    {
823
        $this->assertSearchResults(
824
            [11, 42],
825
            $this->getContentSearchHandler()->findContent(
826
                new Query(
827
                    [
828
                        'filter' => new Criterion\Field(
829
                            'name',
830
                            Criterion\Operator::IN,
831
                            ['members', 'anonymous users']
832
                        ),
833
                        'limit' => 10,
834
                    ]
835
                )
836
            )
837
        );
838
    }
839
840
    public function testFieldFilterContainsPartial()
841
    {
842
        $this->assertSearchResults(
843
            [42],
844
            $this->getContentSearchHandler()->findContent(
845
                new Query(
846
                    [
847
                        'filter' => new Criterion\Field(
848
                            'name',
849
                            Criterion\Operator::CONTAINS,
850
                            'nonymous use'
851
                        ),
852
                        'limit' => 10,
853
                    ]
854
                )
855
            )
856
        );
857
    }
858
859
    public function testFieldFilterContainsSimple()
860
    {
861
        $this->assertSearchResults(
862
            [77],
863
            $this->getContentSearchHandler()->findContent(
864
                new Query(
865
                    [
866
                        'filter' => new Criterion\Field(
867
                            'publish_date',
868
                            Criterion\Operator::CONTAINS,
869
                            1174643880
870
                        ),
871
                        'limit' => 10,
872
                    ]
873
                )
874
            )
875
        );
876
    }
877
878
    public function testFieldFilterContainsSimpleNoMatch()
879
    {
880
        $this->assertSearchResults(
881
            [],
882
            $this->getContentSearchHandler()->findContent(
883
                new Query(
884
                    [
885
                        'filter' => new Criterion\Field(
886
                            'publish_date',
887
                            Criterion\Operator::CONTAINS,
888
                            1174643
889
                        ),
890
                        'limit' => 10,
891
                    ]
892
                )
893
            )
894
        );
895
    }
896
897 View Code Duplication
    public function testFieldFilterBetween()
898
    {
899
        $this->assertSearchResults(
900
            [186, 187],
901
            $this->getContentSearchHandler()->findContent(
902
                new Query(
903
                    [
904
                        'filter' => new Criterion\Field(
905
                            'publication_date',
906
                            Criterion\Operator::BETWEEN,
907
                            [1190000000, 1200000000]
908
                        ),
909
                        'limit' => 10,
910
                    ]
911
                )
912
            )
913
        );
914
    }
915
916 View Code Duplication
    public function testFieldFilterOr()
917
    {
918
        $this->assertSearchResults(
919
            [11, 186, 187],
920
            $this->getContentSearchHandler()->findContent(
921
                new Query(
922
                    [
923
                        'filter' => new Criterion\LogicalOr(
924
                            [
925
                                new Criterion\Field(
926
                                    'name',
927
                                    Criterion\Operator::EQ,
928
                                    'members'
929
                                ),
930
                                new Criterion\Field(
931
                                    'publication_date',
932
                                    Criterion\Operator::BETWEEN,
933
                                    [1190000000, 1200000000]
934
                                ),
935
                            ]
936
                        ),
937
                        'limit' => 10,
938
                    ]
939
                )
940
            )
941
        );
942
    }
943
944 View Code Duplication
    public function testFullTextFilter()
945
    {
946
        $this->assertSearchResults(
947
            [191],
948
            $this->getContentSearchHandler()->findContent(
949
                new Query(
950
                    [
951
                        'filter' => new Criterion\FullText('applied webpage'),
952
                        'limit' => 10,
953
                    ]
954
                )
955
            )
956
        );
957
    }
958
959 View Code Duplication
    public function testFullTextWildcardFilter()
960
    {
961
        $this->assertSearchResults(
962
            [191],
963
            $this->getContentSearchHandler()->findContent(
964
                new Query(
965
                    [
966
                        'filter' => new Criterion\FullText('applie*'),
967
                        'limit' => 10,
968
                    ]
969
                )
970
            )
971
        );
972
    }
973
974 View Code Duplication
    public function testFullTextDisabledWildcardFilter()
975
    {
976
        $this->assertSearchResults(
977
            [],
978
            $this->getContentSearchHandler(
979
                ['enableWildcards' => false]
980
            )->findContent(
981
                new Query(
982
                    [
983
                        'filter' => new Criterion\FullText('applie*'),
984
                        'limit' => 10,
985
                    ]
986
                )
987
            )
988
        );
989
    }
990
991 View Code Duplication
    public function testFullTextFilterStopwordRemoval()
992
    {
993
        $handler = $this->getContentSearchHandler(
994
            [
995
                'stopWordThresholdFactor' => 0.1,
996
            ]
997
        );
998
999
        $this->assertSearchResults(
1000
            [],
1001
            $handler->findContent(
1002
                new Query(
1003
                    [
1004
                        'filter' => new Criterion\FullText('the'),
1005
                        'limit' => 10,
1006
                    ]
1007
                )
1008
            )
1009
        );
1010
    }
1011
1012
    public function testFullTextFilterNoStopwordRemoval()
1013
    {
1014
        $handler = $this->getContentSearchHandler(
1015
            [
1016
                'stopWordThresholdFactor' => 1,
1017
            ]
1018
        );
1019
1020
        $result = $handler->findContent(
1021
            new Query(
1022
                [
1023
                    'filter' => new Criterion\FullText(
1024
                        'the'
1025
                    ),
1026
                    'limit' => 10,
1027
                ]
1028
            )
1029
        );
1030
1031
        $this->assertCount(
1032
            10,
1033
1034
                array_map(
1035
                    function ($hit) {
1036
                        return $hit->valueObject->id;
1037
                    },
1038
                    $result->searchHits
1039
                )
1040
        );
1041
    }
1042
1043
    public function testFullTextFilterInvalidStopwordThreshold()
1044
    {
1045
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1046
1047
        $this->getContentSearchHandler(
1048
            [
1049
                'stopWordThresholdFactor' => 2,
1050
            ]
1051
        );
1052
    }
1053
1054
    public function testObjectStateIdFilter()
1055
    {
1056
        $this->assertSearchResults(
1057
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1058
            $this->getContentSearchHandler()->findContent(
1059
                new Query(
1060
                    [
1061
                        'filter' => new Criterion\ObjectStateId(1),
1062
                        'limit' => 10,
1063
                        'sortClauses' => [new SortClause\ContentId()],
1064
                    ]
1065
                )
1066
            )
1067
        );
1068
    }
1069
1070
    public function testObjectStateIdFilterIn()
1071
    {
1072
        $this->assertSearchResults(
1073
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1074
            $this->getContentSearchHandler()->findContent(
1075
                new Query(
1076
                    [
1077
                        'filter' => new Criterion\ObjectStateId([1, 2]),
1078
                        'limit' => 10,
1079
                        'sortClauses' => [new SortClause\ContentId()],
1080
                    ]
1081
                )
1082
            )
1083
        );
1084
    }
1085
1086
    public function testLanguageCodeFilter()
1087
    {
1088
        $this->assertSearchResults(
1089
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1090
            $this->getContentSearchHandler()->findContent(
1091
                new Query(
1092
                    [
1093
                        'filter' => new Criterion\LanguageCode('eng-US'),
1094
                        'limit' => 10,
1095
                        'sortClauses' => [new SortClause\ContentId()],
1096
                    ]
1097
                )
1098
            )
1099
        );
1100
    }
1101
1102
    public function testLanguageCodeFilterIn()
1103
    {
1104
        $this->assertSearchResults(
1105
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1106
            $this->getContentSearchHandler()->findContent(
1107
                new Query(
1108
                    [
1109
                        'filter' => new Criterion\LanguageCode(['eng-US', 'eng-GB']),
1110
                        'limit' => 10,
1111
                        'sortClauses' => [new SortClause\ContentId()],
1112
                    ]
1113
                )
1114
            )
1115
        );
1116
    }
1117
1118 View Code Duplication
    public function testLanguageCodeFilterWithAlwaysAvailable()
1119
    {
1120
        $this->assertSearchResults(
1121
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49, 50, 51, 56, 57, 65, 68, 70, 74, 76, 80],
1122
            $this->getContentSearchHandler()->findContent(
1123
                new Query(
1124
                    [
1125
                        'filter' => new Criterion\LanguageCode('eng-GB', true),
1126
                        'limit' => 20,
1127
                        'sortClauses' => [new SortClause\ContentId()],
1128
                    ]
1129
                )
1130
            )
1131
        );
1132
    }
1133
1134
    public function testVisibilityFilter()
1135
    {
1136
        $this->assertSearchResults(
1137
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1138
            $this->getContentSearchHandler()->findContent(
1139
                new Query(
1140
                    [
1141
                        'filter' => new Criterion\Visibility(
1142
                            Criterion\Visibility::VISIBLE
1143
                        ),
1144
                        'limit' => 10,
1145
                        'sortClauses' => [new SortClause\ContentId()],
1146
                    ]
1147
                )
1148
            )
1149
        );
1150
    }
1151
1152 View Code Duplication
    public function testUserMetadataFilterOwnerWrongUserId()
1153
    {
1154
        $this->assertSearchResults(
1155
            [],
1156
            $this->getContentSearchHandler()->findContent(
1157
                new Query(
1158
                    [
1159
                        'filter' => new Criterion\UserMetadata(
1160
                            Criterion\UserMetadata::OWNER,
1161
                            Criterion\Operator::EQ,
1162
                            2
1163
                        ),
1164
                    ]
1165
                )
1166
            )
1167
        );
1168
    }
1169
1170 View Code Duplication
    public function testUserMetadataFilterOwnerAdministrator()
1171
    {
1172
        $this->assertSearchResults(
1173
            [4, 10, 11, 12, 13, 14, 41, 42, 45, 49],
1174
            $this->getContentSearchHandler()->findContent(
1175
                new Query(
1176
                    [
1177
                        'filter' => new Criterion\UserMetadata(
1178
                            Criterion\UserMetadata::OWNER,
1179
                            Criterion\Operator::EQ,
1180
                            14
1181
                        ),
1182
                        'limit' => 10,
1183
                        'sortClauses' => [new SortClause\ContentId()],
1184
                    ]
1185
                )
1186
            )
1187
        );
1188
    }
1189
1190 View Code Duplication
    public function testUserMetadataFilterOwnerEqAMember()
1191
    {
1192
        $this->assertSearchResults(
1193
            [223],
1194
            $this->getContentSearchHandler()->findContent(
1195
                new Query(
1196
                    [
1197
                        'filter' => new Criterion\UserMetadata(
1198
                            Criterion\UserMetadata::OWNER,
1199
                            Criterion\Operator::EQ,
1200
                            226
1201
                        ),
1202
                    ]
1203
                )
1204
            )
1205
        );
1206
    }
1207
1208 View Code Duplication
    public function testUserMetadataFilterOwnerInAMember()
1209
    {
1210
        $this->assertSearchResults(
1211
            [223],
1212
            $this->getContentSearchHandler()->findContent(
1213
                new Query(
1214
                    [
1215
                        'filter' => new Criterion\UserMetadata(
1216
                            Criterion\UserMetadata::OWNER,
1217
                            Criterion\Operator::IN,
1218
                            [226]
1219
                        ),
1220
                    ]
1221
                )
1222
            )
1223
        );
1224
    }
1225
1226 View Code Duplication
    public function testUserMetadataFilterCreatorEqAMember()
1227
    {
1228
        $this->assertSearchResults(
1229
            [223],
1230
            $this->getContentSearchHandler()->findContent(
1231
                new Query(
1232
                    [
1233
                        'filter' => new Criterion\UserMetadata(
1234
                            Criterion\UserMetadata::MODIFIER,
1235
                            Criterion\Operator::EQ,
1236
                            226
1237
                        ),
1238
                    ]
1239
                )
1240
            )
1241
        );
1242
    }
1243
1244 View Code Duplication
    public function testUserMetadataFilterCreatorInAMember()
1245
    {
1246
        $this->assertSearchResults(
1247
            [223],
1248
            $this->getContentSearchHandler()->findContent(
1249
                new Query(
1250
                    [
1251
                        'filter' => new Criterion\UserMetadata(
1252
                            Criterion\UserMetadata::MODIFIER,
1253
                            Criterion\Operator::IN,
1254
                            [226]
1255
                        ),
1256
                    ]
1257
                )
1258
            )
1259
        );
1260
    }
1261
1262 View Code Duplication
    public function testUserMetadataFilterEqGroupMember()
1263
    {
1264
        $this->assertSearchResults(
1265
            [223],
1266
            $this->getContentSearchHandler()->findContent(
1267
                new Query(
1268
                    [
1269
                        'filter' => new Criterion\UserMetadata(
1270
                            Criterion\UserMetadata::GROUP,
1271
                            Criterion\Operator::EQ,
1272
                            11
1273
                        ),
1274
                    ]
1275
                )
1276
            )
1277
        );
1278
    }
1279
1280 View Code Duplication
    public function testUserMetadataFilterInGroupMember()
1281
    {
1282
        $this->assertSearchResults(
1283
            [223],
1284
            $this->getContentSearchHandler()->findContent(
1285
                new Query(
1286
                    [
1287
                        'filter' => new Criterion\UserMetadata(
1288
                            Criterion\UserMetadata::GROUP,
1289
                            Criterion\Operator::IN,
1290
                            [11]
1291
                        ),
1292
                    ]
1293
                )
1294
            )
1295
        );
1296
    }
1297
1298 View Code Duplication
    public function testUserMetadataFilterEqGroupMemberNoMatch()
1299
    {
1300
        $this->assertSearchResults(
1301
            [],
1302
            $this->getContentSearchHandler()->findContent(
1303
                new Query(
1304
                    [
1305
                        'filter' => new Criterion\UserMetadata(
1306
                            Criterion\UserMetadata::GROUP,
1307
                            Criterion\Operator::EQ,
1308
                            13
1309
                        ),
1310
                    ]
1311
                )
1312
            )
1313
        );
1314
    }
1315
1316 View Code Duplication
    public function testUserMetadataFilterInGroupMemberNoMatch()
1317
    {
1318
        $this->assertSearchResults(
1319
            [],
1320
            $this->getContentSearchHandler()->findContent(
1321
                new Query(
1322
                    [
1323
                        'filter' => new Criterion\UserMetadata(
1324
                            Criterion\UserMetadata::GROUP,
1325
                            Criterion\Operator::IN,
1326
                            [13]
1327
                        ),
1328
                    ]
1329
                )
1330
            )
1331
        );
1332
    }
1333
1334
    public function testFieldRelationFilterContainsSingle()
1335
    {
1336
        $this->assertSearchResults(
1337
            [67],
1338
            $this->getContentSearchHandler()->findContent(
1339
                new Query(
1340
                    [
1341
                        'filter' => new Criterion\FieldRelation(
1342
                            'billboard',
1343
                            Criterion\Operator::CONTAINS,
1344
                            [60]
1345
                        ),
1346
                    ]
1347
                )
1348
            )
1349
        );
1350
    }
1351
1352 View Code Duplication
    public function testFieldRelationFilterContainsSingleNoMatch()
1353
    {
1354
        $this->assertSearchResults(
1355
            [],
1356
            $this->getContentSearchHandler()->findContent(
1357
                new Query(
1358
                    [
1359
                        'filter' => new Criterion\FieldRelation(
1360
                            'billboard',
1361
                            Criterion\Operator::CONTAINS,
1362
                            [4]
1363
                        ),
1364
                    ]
1365
                )
1366
            )
1367
        );
1368
    }
1369
1370
    public function testFieldRelationFilterContainsArray()
1371
    {
1372
        $this->assertSearchResults(
1373
            [67],
1374
            $this->getContentSearchHandler()->findContent(
1375
                new Query(
1376
                    [
1377
                        'filter' => new Criterion\FieldRelation(
1378
                            'billboard',
1379
                            Criterion\Operator::CONTAINS,
1380
                            [60, 75]
1381
                        ),
1382
                    ]
1383
                )
1384
            )
1385
        );
1386
    }
1387
1388
    public function testFieldRelationFilterContainsArrayNotMatch()
1389
    {
1390
        $this->assertSearchResults(
1391
            [],
1392
            $this->getContentSearchHandler()->findContent(
1393
                new Query(
1394
                    [
1395
                        'filter' => new Criterion\FieldRelation(
1396
                            'billboard',
1397
                            Criterion\Operator::CONTAINS,
1398
                            [60, 64]
1399
                        ),
1400
                    ]
1401
                )
1402
            )
1403
        );
1404
    }
1405
1406
    public function testFieldRelationFilterInArray()
1407
    {
1408
        $this->assertSearchResults(
1409
            [67, 75],
1410
            $this->getContentSearchHandler()->findContent(
1411
                new Query(
1412
                    [
1413
                        'filter' => new Criterion\FieldRelation(
1414
                            'billboard',
1415
                            Criterion\Operator::IN,
1416
                            [60, 64]
1417
                        ),
1418
                    ]
1419
                )
1420
            )
1421
        );
1422
    }
1423
1424
    public function testFieldRelationFilterInArrayNotMatch()
1425
    {
1426
        $this->assertSearchResults(
1427
            [],
1428
            $this->getContentSearchHandler()->findContent(
1429
                new Query(
1430
                    [
1431
                        'filter' => new Criterion\FieldRelation(
1432
                            'billboard',
1433
                            Criterion\Operator::IN,
1434
                            [4, 10]
1435
                        ),
1436
                    ]
1437
                )
1438
            )
1439
        );
1440
    }
1441
1442
    public function testGetNonExistingFieldDefinition(): void
1443
    {
1444
        $this->expectException(NotFoundException::class);
1445
1446
        $this->getContentTypeHandler()->getFieldDefinition(0, Type::STATUS_DEFINED);
1447
    }
1448
}
1449