Completed
Pull Request — master (#1950)
by François-Xavier
03:01
created

QueryTest   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 591
Duplicated Lines 18.95 %

Coupling/Cohesion

Components 2
Dependencies 16

Importance

Changes 0
Metric Value
wmc 30
lcom 2
cbo 16
dl 112
loc 591
rs 10
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A testRawQuery() 11 11 1
A testSuggestShouldNotRemoveOtherParameters() 0 16 1
A testArrayQuery() 0 17 1
A testSetSort() 0 43 1
A testAddSort() 0 8 1
A testSetTrackScores() 0 8 1
A testSetRawQuery() 0 9 1
A testSetStoredFields() 0 13 1
A testGetQuery() 0 17 2
A testSetQueryToArrayCast() 14 14 1
A testNotCloneInnerObjects() 0 13 1
A testSetQueryToArrayChangeQuery() 0 14 1
A testSetScriptFieldsToArrayCast() 0 15 1
A testAddScriptFieldsToArrayCast() 14 14 1
A testAddScriptFieldToExistingScriptFields() 0 21 1
A testAddAggregationToArrayCast() 15 15 1
A testSetSuggestToArrayCast() 15 15 1
A testSetRescoreToArrayCast() 15 15 1
A testSetPostFilterToArrayCast() 13 13 1
A testNoSource() 0 35 1
A testSetCollapseToArrayCast() 15 15 1
A testCollapseArrayStructure() 0 32 1
A testCollapseSecondLevelArrayStructure() 0 39 1
A testSetTrackTotalHitsIsInParams() 0 7 1
A provideSetTrackTotalHitsInvalidValue() 0 7 1
A testSetTrackTotalHitsInvalidValue() 0 6 1
A testSetTrackTotalHits() 0 35 2
A testRawPostFilter() 0 10 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
            ->setStoredFields(['firstname', 'lastname'])
172
        ;
173
174
        $data = $query->toArray();
175
176
        $this->assertArrayHasKey('stored_fields', $data);
177
        $this->assertContains('firstname', $data['stored_fields']);
178
        $this->assertContains('lastname', $data['stored_fields']);
179
        $this->assertCount(2, $data['stored_fields']);
180
    }
181
182
    /**
183
     * @group unit
184
     */
185
    public function testGetQuery(): void
186
    {
187
        $query = new Query();
188
189
        try {
190
            $query->getQuery();
191
            $this->fail('should throw exception because query does not exist');
192
        } catch (InvalidException $e) {
193
            $this->assertTrue(true);
194
        }
195
196
        $termQuery = new Term();
197
        $termQuery->setTerm('text', 'value');
198
        $query->setQuery($termQuery);
199
200
        $this->assertSame($termQuery, $query->getQuery());
201
    }
202
203
    /**
204
     * @group unit
205
     */
206 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...
207
    {
208
        $query = new Query();
209
        $termQuery = new Term();
210
        $termQuery->setTerm('text', 'value');
211
        $query->setQuery($termQuery);
212
213
        $termQuery->setTerm('text', 'another value');
214
215
        $anotherQuery = new Query();
216
        $anotherQuery->setQuery($termQuery);
217
218
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
219
    }
220
221
    /**
222
     * @group unit
223
     */
224
    public function testNotCloneInnerObjects(): void
225
    {
226
        $query = new Query();
227
        $termQuery = new Term();
228
        $termQuery->setTerm('text', 'value');
229
        $query->setQuery($termQuery);
230
231
        $anotherQuery = clone $query;
232
233
        $termQuery->setTerm('text', 'another value');
234
235
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
236
    }
237
238
    /**
239
     * @group unit
240
     */
241
    public function testSetQueryToArrayChangeQuery(): void
242
    {
243
        $query = new Query();
244
        $termQuery = new Term();
245
        $termQuery->setTerm('text', 'value');
246
        $query->setQuery($termQuery);
247
248
        $queryArray = $query->toArray();
249
250
        $termQuery = $query->getQuery();
251
        $termQuery->setTerm('text', 'another value');
252
253
        $this->assertNotEquals($queryArray, $query->toArray());
254
    }
255
256
    /**
257
     * @group unit
258
     */
259
    public function testSetScriptFieldsToArrayCast(): void
260
    {
261
        $query = new Query();
262
        $scriptFields = new ScriptFields();
263
        $scriptFields->addScript('script', new Script('script'));
264
265
        $query->setScriptFields($scriptFields);
266
267
        $scriptFields->addScript('another script', new Script('another script'));
268
269
        $anotherQuery = new Query();
270
        $anotherQuery->setScriptFields($scriptFields);
271
272
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
273
    }
274
275
    /**
276
     * @group unit
277
     */
278 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...
279
    {
280
        $query = new Query();
281
        $scriptField = new Script('script');
282
283
        $query->addScriptField('script', $scriptField);
284
285
        $scriptField->setScript('another script');
286
287
        $anotherQuery = new Query();
288
        $anotherQuery->addScriptField('script', $scriptField);
289
290
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
291
    }
292
293
    /**
294
     * @group unit
295
     */
296
    public function testAddScriptFieldToExistingScriptFields(): void
297
    {
298
        $script1 = new Script('s1');
299
        $script2 = new Script('s2');
300
301
        // add script1, then add script2
302
        $query = new Query();
303
        $scriptFields1 = new ScriptFields();
304
        $scriptFields1->addScript('script1', $script1);
305
        $query->setScriptFields($scriptFields1);
306
        $query->addScriptField('script2', $script2);
307
308
        // add script1 and script2 at once
309
        $anotherQuery = new Query();
310
        $scriptFields2 = new ScriptFields();
311
        $scriptFields2->addScript('script1', $script1);
312
        $scriptFields2->addScript('script2', $script2);
313
        $anotherQuery->setScriptFields($scriptFields2);
314
315
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
316
    }
317
318
    /**
319
     * @group unit
320
     */
321 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...
322
    {
323
        $query = new Query();
324
        $aggregation = new TermsAggregation('text');
325
        $aggregation->setField('field');
326
327
        $query->addAggregation($aggregation);
328
329
        $aggregation->setName('another text');
330
331
        $anotherQuery = new Query();
332
        $anotherQuery->addAggregation($aggregation);
333
334
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
335
    }
336
337
    /**
338
     * @group unit
339
     */
340 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...
341
    {
342
        $query = new Query();
343
        $suggest = new Suggest();
344
        $suggest->setGlobalText('text');
345
346
        $query->setSuggest($suggest);
347
348
        $suggest->setGlobalText('another text');
349
350
        $anotherQuery = new Query();
351
        $anotherQuery->setSuggest($suggest);
352
353
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
354
    }
355
356
    /**
357
     * @group unit
358
     */
359 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...
360
    {
361
        $query = new Query();
362
        $rescore = new RescoreQuery();
363
        $rescore->setQueryWeight(1);
364
365
        $query->setRescore($rescore);
366
367
        $rescore->setQueryWeight(2);
368
369
        $anotherQuery = new Query();
370
        $anotherQuery->setRescore($rescore);
371
372
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
373
    }
374
375
    /**
376
     * @group unit
377
     */
378 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...
379
    {
380
        $query = new Query();
381
        $postFilter = new Terms('key', ['term']);
382
        $query->setPostFilter($postFilter);
383
384
        $postFilter->addTerm('another term');
385
386
        $anotherQuery = new Query();
387
        $anotherQuery->setPostFilter($postFilter);
388
389
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
390
    }
391
392
    /**
393
     * @group unit
394
     */
395
    public function testRawPostFilter(): void
396
    {
397
        $query = (new Query())
398
            ->setParam('post_filter', [
399
                'term' => ['field' => 'value'],
400
            ])
401
        ;
402
403
        $this->assertSame([], $query->toArray());
404
    }
405
406
    /**
407
     * @group functional
408
     */
409
    public function testNoSource(): void
410
    {
411
        $index = $this->_createIndex();
412
413
        // Adds 1 document to the index
414
        $doc1 = new Document(
415
            1,
416
            ['username' => 'ruflin', 'test' => ['2', '3', '5']]
417
        );
418
        $index->addDocument($doc1);
419
420
        // To update index
421
        $index->refresh();
422
423
        $query = Query::create('ruflin');
424
        $resultSet = $index->search($query);
425
426
        // Disable source
427
        $query->setSource(false);
428
429
        $resultSetNoSource = $index->search($query);
430
431
        $this->assertEquals(1, $resultSet->count());
432
        $this->assertEquals(1, $resultSetNoSource->count());
433
434
        // Tests if no source is in response except id
435
        $result = $resultSetNoSource->current();
436
        $this->assertEquals(1, $result->getId());
437
        $this->assertEmpty($result->getData());
438
439
        // Tests if source is in response except id
440
        $result = $resultSet->current();
441
        $this->assertEquals(1, $result->getId());
442
        $this->assertNotEmpty($result->getData());
443
    }
444
445
    /**
446
     * @group unit
447
     */
448 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...
449
    {
450
        $query = new Query();
451
        $collapse = new Collapse();
452
        $collapse->setFieldname('some_field');
453
454
        $query->setCollapse($collapse);
455
456
        $collapse->setFieldname('another_field');
457
458
        $anotherQuery = new Query();
459
        $anotherQuery->setCollapse($collapse);
460
461
        $this->assertEquals($query->toArray(), $anotherQuery->toArray());
462
    }
463
464
    /**
465
     * @group unit
466
     */
467
    public function testCollapseArrayStructure(): void
468
    {
469
        $query = new Query();
470
        $collapse = new Collapse();
471
        $collapse
472
            ->setFieldname('user')
473
            ->setInnerHits(
474
                (new InnerHits())
475
                    ->setName('last_tweets')
476
                    ->setSize(5)
477
                    ->setSort(['date' => 'asc'])
478
            )
479
            ->setMaxConcurrentGroupSearches(4)
480
        ;
481
482
        $query->setCollapse($collapse);
483
484
        $expected = [
485
            'field' => 'user',
486
            'inner_hits' => [
487
                'name' => 'last_tweets',
488
                'size' => 5,
489
                'sort' => ['date' => 'asc'],
490
            ],
491
            'max_concurrent_group_searches' => 4,
492
        ];
493
494
        $actual = $query->toArray();
495
496
        $this->assertArrayHasKey('collapse', $actual);
497
        $this->assertEquals($expected, $actual['collapse']);
498
    }
499
500
    /**
501
     * @group unit
502
     */
503
    public function testCollapseSecondLevelArrayStructure(): void
504
    {
505
        $query = new Query();
506
        $collapse = new Collapse();
507
        $collapse
508
            ->setFieldname('user')
509
            ->setInnerHits(
510
                (new InnerHits())
511
                    ->setName('last_tweets')
512
                    ->setSize(5)
513
                    ->setSort(['date' => 'asc'])
514
                    ->setCollapse(
515
                        (new Collapse())
516
                            ->setFieldname('date')
517
                    )
518
            )
519
            ->setMaxConcurrentGroupSearches(4)
520
        ;
521
522
        $query->setCollapse($collapse);
523
524
        $expected = [
525
            'field' => 'user',
526
            'inner_hits' => [
527
                'name' => 'last_tweets',
528
                'size' => 5,
529
                'sort' => ['date' => 'asc'],
530
                'collapse' => [
531
                    'field' => 'date',
532
                ],
533
            ],
534
            'max_concurrent_group_searches' => 4,
535
        ];
536
537
        $actual = $query->toArray();
538
539
        $this->assertArrayHasKey('collapse', $actual);
540
        $this->assertEquals($expected, $actual['collapse']);
541
    }
542
543
    /**
544
     * @group functional
545
     */
546
    public function testSetTrackTotalHitsIsInParams(): void
547
    {
548
        $query = new Query();
549
        $query->setTrackTotalHits(false);
550
551
        $this->assertFalse($query->getParam('track_total_hits'));
552
    }
553
554
    public function provideSetTrackTotalHitsInvalidValue(): iterable
555
    {
556
        yield 'string' => ['string string'];
557
        yield 'null' => [null];
558
        yield 'object' => [new \stdClass()];
559
        yield 'array' => [[]];
560
    }
561
562
    /**
563
     * @group functional
564
     * @dataProvider provideSetTrackTotalHitsInvalidValue
565
     *
566
     * @param mixed $value
567
     */
568
    public function testSetTrackTotalHitsInvalidValue($value): void
569
    {
570
        $this->expectException(InvalidException::class);
571
572
        (new Query())->setTrackTotalHits($value);
573
    }
574
575
    /**
576
     * @group functional
577
     */
578
    public function testSetTrackTotalHits(): void
579
    {
580
        $index = $this->_createIndex();
581
        $index->setMapping(new Mapping([
582
            'firstname' => ['type' => 'text', 'fielddata' => true],
583
        ]));
584
585
        $documents = [];
586
        for ($i = 0; $i < 50; ++$i) {
587
            $documents[] = new Document($i, ['firstname' => 'antoine '.$i]);
588
        }
589
590
        $index->addDocuments($documents);
591
592
        $queryTerm = new Term();
593
        $queryTerm->setTerm('firstname', 'antoine');
594
595
        $index->refresh();
596
597
        $query = Query::create($queryTerm);
598
599
        $resultSet = $index->search($query);
600
        $this->assertEquals(50, $resultSet->getTotalHits());
601
        $this->assertEquals('eq', $resultSet->getTotalHitsRelation());
602
603
        $query->setTrackTotalHits(false);
604
        $resultSet = $index->search($query);
605
        $this->assertEquals(0, $resultSet->getTotalHits());
606
        $this->assertEquals('eq', $resultSet->getTotalHitsRelation());
607
608
        $query->setTrackTotalHits(25);
609
        $resultSet = $index->search($query);
610
        $this->assertEquals(25, $resultSet->getTotalHits());
611
        $this->assertEquals('gte', $resultSet->getTotalHitsRelation());
612
    }
613
}
614