Completed
Push — master ( 91356a...f55f08 )
by
unknown
02:51
created

QueryTest::testSetSuggestMustReturnQueryInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Elastica\Test;
4
5
use Elastica\Aggregation\Terms as TermsAggregation;
6
use Elastica\Collapse;
7
use Elastica\Collapse\InnerHits;
8
use Elastica\Document;
9
use Elastica\Exception\InvalidException;
10
use Elastica\Mapping;
11
use Elastica\Query;
12
use Elastica\Query\Term;
13
use Elastica\Query\Terms;
14
use Elastica\Rescore\Query as RescoreQuery;
15
use Elastica\Script\Script;
16
use Elastica\Script\ScriptFields;
17
use Elastica\Suggest;
18
use Elastica\Test\Base as BaseTest;
19
20
/**
21
 * @internal
22
 */
23
class QueryTest extends BaseTest
24
{
25
    /**
26
     * @group unit
27
     */
28 View Code Duplication
    public function testRawQuery(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
29
    {
30
        $textQuery = new Term(['title' => 'test']);
31
32
        $query1 = Query::create($textQuery);
33
34
        $query2 = new Query();
35
        $query2->setRawQuery(['query' => ['term' => ['title' => 'test']]]);
36
37
        $this->assertEquals($query1->toArray(), $query2->toArray());
38
    }
39
40
    /**
41
     * @group unit
42
     */
43
    public function testSuggestShouldNotRemoveOtherParameters(): void
44
    {
45
        $query1 = new Query();
46
        $query2 = new Query();
47
48
        $suggest = new Suggest();
49
        $suggest->setGlobalText('test');
50
51
        $query1->setSize(40);
52
        $query1->setSuggest($suggest);
53
54
        $query2->setSuggest($suggest);
55
        $query2->setSize(40);
56
57
        $this->assertEquals($query1->toArray(), $query2->toArray());
58
    }
59
60
    /**
61
     * @group unit
62
     */
63
    public function testArrayQuery(): void
64
    {
65
        $query = [
66
            'query' => [
67
                'text' => [
68
                    'title' => 'test',
69
                ],
70
            ],
71
        ];
72
73
        $query1 = Query::create($query);
74
75
        $query2 = new Query();
76
        $query2->setRawQuery(['query' => ['text' => ['title' => 'test']]]);
77
78
        $this->assertEquals($query1->toArray(), $query2->toArray());
79
    }
80
81
    /**
82
     * @group functional
83
     */
84
    public function testSetSort(): void
85
    {
86
        $index = $this->_createIndex();
87
        $index->setMapping(new Mapping([
88
            'firstname' => ['type' => 'text', 'fielddata' => true],
89
            'lastname' => ['type' => 'text', 'fielddata' => true],
90
        ]));
91
92
        $index->addDocuments([
93
            new Document(1, ['name' => 'hello world']),
94
            new Document(2, ['firstname' => 'guschti', 'lastname' => 'ruflin']),
95
            new Document(3, ['firstname' => 'nicolas', 'lastname' => 'ruflin']),
96
        ]);
97
        $index->refresh();
98
99
        $queryTerm = new Term();
100
        $queryTerm->setTerm('lastname', 'ruflin');
101
        $query = Query::create($queryTerm);
102
103
        // ASC order
104
        $query->setSort([['firstname' => ['order' => 'asc']]]);
105
        $resultSet = $index->search($query);
106
        $this->assertEquals(2, $resultSet->count());
107
108
        $first = $resultSet->current()->getData();
109
        $resultSet->next();
110
        $second = $resultSet->current()->getData();
111
112
        $this->assertEquals('guschti', $first['firstname']);
113
        $this->assertEquals('nicolas', $second['firstname']);
114
115
        // DESC order
116
        $query->setSort(['firstname' => ['order' => 'desc']]);
117
        $resultSet = $index->search($query);
118
        $this->assertEquals(2, $resultSet->count());
119
120
        $first = $resultSet->current()->getData();
121
        $resultSet->next();
122
        $second = $resultSet->current()->getData();
123
124
        $this->assertEquals('nicolas', $first['firstname']);
125
        $this->assertEquals('guschti', $second['firstname']);
126
    }
127
128
    /**
129
     * @group unit
130
     */
131
    public function testAddSort(): void
132
    {
133
        $query = new Query();
134
        $sortParam = ['firstname' => ['order' => 'asc']];
135
        $query->addSort($sortParam);
136
137
        $this->assertEquals($query->getParam('sort'), [$sortParam]);
138
    }
139
140
    /**
141
     * @group unit
142
     */
143
    public function testSetTrackScores(): void
144
    {
145
        $query = new Query();
146
        $param = false;
147
        $query->setTrackScores($param);
148
149
        $this->assertEquals($param, $query->getParam('track_scores'));
150
    }
151
152
    /**
153
     * @group unit
154
     */
155
    public function testSetRawQuery(): void
156
    {
157
        $query = new Query();
158
159
        $params = ['query' => 'test'];
160
        $query->setRawQuery($params);
161
162
        $this->assertEquals($params, $query->toArray());
163
    }
164
165
    /**
166
     * @group unit
167
     */
168
    public function testSetStoredFields(): void
169
    {
170
        $query = new Query();
171
172
        $params = ['query' => 'test'];
0 ignored issues
show
Unused Code introduced by
$params is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
173
174
        $query->setStoredFields(['firstname', 'lastname']);
175
176
        $data = $query->toArray();
177
178
        $this->assertContains('firstname', $data['stored_fields']);
179
        $this->assertContains('lastname', $data['stored_fields']);
180
        $this->assertCount(2, $data['stored_fields']);
181
    }
182
183
    /**
184
     * @group unit
185
     */
186
    public function testGetQuery(): void
187
    {
188
        $query = new Query();
189
190
        try {
191
            $query->getQuery();
192
            $this->fail('should throw exception because query does not exist');
193
        } catch (InvalidException $e) {
194
            $this->assertTrue(true);
195
        }
196
197
        $termQuery = new Term();
198
        $termQuery->setTerm('text', 'value');
199
        $query->setQuery($termQuery);
200
201
        $this->assertSame($termQuery, $query->getQuery());
202
    }
203
204
    /**
205
     * @group unit
206
     */
207 View Code Duplication
    public function testSetQueryToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
    {
209
        $query = new Query();
210
        $termQuery = new Term();
211
        $termQuery->setTerm('text', 'value');
212
        $query->setQuery($termQuery);
213
214
        $termQuery->setTerm('text', 'another value');
215
216
        $anotherQuery = new Query();
217
        $anotherQuery->setQuery($termQuery);
218
219
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
220
    }
221
222
    /**
223
     * @group unit
224
     */
225
    public function testNotCloneInnerObjects(): void
226
    {
227
        $query = new Query();
228
        $termQuery = new Term();
229
        $termQuery->setTerm('text', 'value');
230
        $query->setQuery($termQuery);
231
232
        $anotherQuery = clone $query;
233
234
        $termQuery->setTerm('text', 'another value');
235
236
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
237
    }
238
239
    /**
240
     * @group unit
241
     */
242
    public function testSetQueryToArrayChangeQuery(): void
243
    {
244
        $query = new Query();
245
        $termQuery = new Term();
246
        $termQuery->setTerm('text', 'value');
247
        $query->setQuery($termQuery);
248
249
        $queryArray = $query->toArray();
250
251
        $termQuery = $query->getQuery();
252
        $termQuery->setTerm('text', 'another value');
253
254
        $this->assertNotEquals($queryArray, $query->toArray());
255
    }
256
257
    /**
258
     * @group unit
259
     */
260
    public function testSetScriptFieldsToArrayCast(): void
261
    {
262
        $query = new Query();
263
        $scriptFields = new ScriptFields();
264
        $scriptFields->addScript('script', new Script('script'));
265
266
        $query->setScriptFields($scriptFields);
267
268
        $scriptFields->addScript('another script', new Script('another script'));
269
270
        $anotherQuery = new Query();
271
        $anotherQuery->setScriptFields($scriptFields);
272
273
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
274
    }
275
276
    /**
277
     * @group unit
278
     */
279 View Code Duplication
    public function testAddScriptFieldsToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
    {
281
        $query = new Query();
282
        $scriptField = new Script('script');
283
284
        $query->addScriptField('script', $scriptField);
285
286
        $scriptField->setScript('another script');
287
288
        $anotherQuery = new Query();
289
        $anotherQuery->addScriptField('script', $scriptField);
290
291
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
292
    }
293
294
    /**
295
     * @group unit
296
     */
297
    public function testAddScriptFieldToExistingScriptFields(): void
298
    {
299
        $script1 = new Script('s1');
300
        $script2 = new Script('s2');
301
302
        // add script1, then add script2
303
        $query = new Query();
304
        $scriptFields1 = new ScriptFields();
305
        $scriptFields1->addScript('script1', $script1);
306
        $query->setScriptFields($scriptFields1);
307
        $query->addScriptField('script2', $script2);
308
309
        // add script1 and script2 at once
310
        $anotherQuery = new Query();
311
        $scriptFields2 = new ScriptFields();
312
        $scriptFields2->addScript('script1', $script1);
313
        $scriptFields2->addScript('script2', $script2);
314
        $anotherQuery->setScriptFields($scriptFields2);
315
316
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
317
    }
318
319
    /**
320
     * @group unit
321
     */
322 View Code Duplication
    public function testAddAggregationToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
323
    {
324
        $query = new Query();
325
        $aggregation = new TermsAggregation('text');
326
        $aggregation->setField('field');
327
328
        $query->addAggregation($aggregation);
329
330
        $aggregation->setName('another text');
331
332
        $anotherQuery = new Query();
333
        $anotherQuery->addAggregation($aggregation);
334
335
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
336
    }
337
338
    /**
339
     * @group unit
340
     */
341 View Code Duplication
    public function testSetSuggestToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
342
    {
343
        $query = new Query();
344
        $suggest = new Suggest();
345
        $suggest->setGlobalText('text');
346
347
        $query->setSuggest($suggest);
348
349
        $suggest->setGlobalText('another text');
350
351
        $anotherQuery = new Query();
352
        $anotherQuery->setSuggest($suggest);
353
354
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
355
    }
356
357
    /**
358
     * @group unit
359
     */
360 View Code Duplication
    public function testSetRescoreToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
    {
362
        $query = new Query();
363
        $rescore = new RescoreQuery();
364
        $rescore->setQueryWeight(1);
365
366
        $query->setRescore($rescore);
367
368
        $rescore->setQueryWeight(2);
369
370
        $anotherQuery = new Query();
371
        $anotherQuery->setRescore($rescore);
372
373
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
374
    }
375
376
    /**
377
     * @group unit
378
     */
379 View Code Duplication
    public function testSetPostFilterToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
    {
381
        $query = new Query();
382
        $postFilter = new Terms('key', ['term']);
383
        $query->setPostFilter($postFilter);
384
385
        $postFilter->addTerm('another term');
386
387
        $anotherQuery = new Query();
388
        $anotherQuery->setPostFilter($postFilter);
389
390
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
391
    }
392
393
    /**
394
     * @group functional
395
     */
396
    public function testNoSource(): void
397
    {
398
        $index = $this->_createIndex();
399
400
        // Adds 1 document to the index
401
        $doc1 = new Document(
402
            1,
403
            ['username' => 'ruflin', 'test' => ['2', '3', '5']]
404
        );
405
        $index->addDocument($doc1);
406
407
        // To update index
408
        $index->refresh();
409
410
        $query = Query::create('ruflin');
411
        $resultSet = $index->search($query);
412
413
        // Disable source
414
        $query->setSource(false);
415
416
        $resultSetNoSource = $index->search($query);
417
418
        $this->assertEquals(1, $resultSet->count());
419
        $this->assertEquals(1, $resultSetNoSource->count());
420
421
        // Tests if no source is in response except id
422
        $result = $resultSetNoSource->current();
423
        $this->assertEquals(1, $result->getId());
424
        $this->assertEmpty($result->getData());
425
426
        // Tests if source is in response except id
427
        $result = $resultSet->current();
428
        $this->assertEquals(1, $result->getId());
429
        $this->assertNotEmpty($result->getData());
430
    }
431
432
    /**
433
     * @group unit
434
     */
435 View Code Duplication
    public function testSetCollapseToArrayCast(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
    {
437
        $query = new Query();
438
        $collapse = new Collapse();
439
        $collapse->setFieldname('some_field');
440
441
        $query->setCollapse($collapse);
442
443
        $collapse->setFieldname('another_field');
444
445
        $anotherQuery = new Query();
446
        $anotherQuery->setCollapse($collapse);
447
448
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
449
    }
450
451
    /**
452
     * @group unit
453
     */
454
    public function testCollapseArrayStructure(): void
455
    {
456
        $query = new Query();
457
        $collapse = new Collapse();
458
        $collapse
459
            ->setFieldname('user')
460
            ->setInnerHits(
461
                (new InnerHits())
462
                    ->setName('last_tweets')
463
                    ->setSize(5)
464
                    ->setSort(['date' => 'asc'])
465
            )
466
            ->setMaxConcurrentGroupSearches(4)
467
        ;
468
469
        $query->setCollapse($collapse);
470
471
        $expected = [
472
            'field' => 'user',
473
            'inner_hits' => [
474
                'name' => 'last_tweets',
475
                'size' => 5,
476
                'sort' => ['date' => 'asc'],
477
            ],
478
            'max_concurrent_group_searches' => 4,
479
        ];
480
481
        $actual = $query->toArray();
482
483
        $this->assertArrayHasKey('collapse', $actual);
484
        $this->assertEquals($expected, $actual['collapse']);
485
    }
486
487
    /**
488
     * @group unit
489
     */
490
    public function testCollapseSecondLevelArrayStructure(): void
491
    {
492
        $query = new Query();
493
        $collapse = new Collapse();
494
        $collapse
495
            ->setFieldname('user')
496
            ->setInnerHits(
497
                (new InnerHits())
498
                    ->setName('last_tweets')
499
                    ->setSize(5)
500
                    ->setSort(['date' => 'asc'])
501
                    ->setCollapse(
502
                        (new Collapse())
503
                            ->setFieldname('date')
504
                    )
505
            )
506
            ->setMaxConcurrentGroupSearches(4)
507
        ;
508
509
        $query->setCollapse($collapse);
510
511
        $expected = [
512
            'field' => 'user',
513
            'inner_hits' => [
514
                'name' => 'last_tweets',
515
                'size' => 5,
516
                'sort' => ['date' => 'asc'],
517
                'collapse' => [
518
                    'field' => 'date',
519
                ],
520
            ],
521
            'max_concurrent_group_searches' => 4,
522
        ];
523
524
        $actual = $query->toArray();
525
526
        $this->assertArrayHasKey('collapse', $actual);
527
        $this->assertEquals($expected, $actual['collapse']);
528
    }
529
530
    /**
531
     * @group functional
532
     */
533
    public function testSetTrackTotalHitsIsInParams(): void
534
    {
535
        $query = new Query();
536
        $query->setTrackTotalHits(false);
537
538
        $this->assertFalse($query->getParam('track_total_hits'));
539
    }
540
541
    public function provideSetTrackTotalHitsInvalidValue(): iterable
542
    {
543
        yield 'string' => ['string string'];
544
        yield 'null' => [null];
545
        yield 'object' => [new \stdClass()];
546
        yield 'array' => [[]];
547
    }
548
549
    /**
550
     * @group functional
551
     * @dataProvider provideSetTrackTotalHitsInvalidValue
552
     *
553
     * @param mixed $value
554
     */
555
    public function testSetTrackTotalHitsInvalidValue($value): void
556
    {
557
        $this->expectException(InvalidException::class);
558
559
        (new Query())->setTrackTotalHits($value);
560
    }
561
562
    /**
563
     * @group functional
564
     */
565
    public function testSetTrackTotalHits(): void
566
    {
567
        $index = $this->_createIndex();
568
        $index->setMapping(new Mapping([
569
            'firstname' => ['type' => 'text', 'fielddata' => true],
570
        ]));
571
572
        $documents = [];
573
        for ($i = 0; $i < 50; ++$i) {
574
            $documents[] = new Document($i, ['firstname' => 'antoine '.$i]);
575
        }
576
577
        $index->addDocuments($documents);
578
579
        $queryTerm = new Term();
580
        $queryTerm->setTerm('firstname', 'antoine');
581
582
        $index->refresh();
583
584
        $query = Query::create($queryTerm);
585
586
        $resultSet = $index->search($query);
587
        $this->assertEquals(50, $resultSet->getTotalHits());
588
        $this->assertEquals('eq', $resultSet->getTotalHitsRelation());
589
590
        $query->setTrackTotalHits(false);
591
        $resultSet = $index->search($query);
592
        $this->assertEquals(0, $resultSet->getTotalHits());
593
        $this->assertEquals('eq', $resultSet->getTotalHitsRelation());
594
595
        $query->setTrackTotalHits(25);
596
        $resultSet = $index->search($query);
597
        $this->assertEquals(25, $resultSet->getTotalHits());
598
        $this->assertEquals('gte', $resultSet->getTotalHitsRelation());
599
    }
600
}
601