Completed
Push — dev2 ( 646d6a...7b2d13 )
by Gordon
02:57
created

QueryGeneratorTest::getQuerySuggester()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 11
rs 9.4286
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
use \SilverStripe\Elastica\ElasticSearcher;
3
use \SilverStripe\Elastica\QueryGenerator;
4
5
/**
6
 * Test query generation
7
 * @package elastica
8
 */
9
class QueryGeneratorTest extends ElasticsearchBaseTest {
10
	public static $fixture_file = 'elastica/tests/lotsOfPhotos.yml';
11
12
13
	public static $ignoreFixtureFileFor = array('testToQuoted*');
14
15
	public function testTextOnly() {
16
		$qg = new QueryGenerator();
17
		$qg->setQueryText('New Zealand');
18
		$qg->setFields(null);
19
		$qg->setSelectedFilters(null);
20
21
		//As the query is not empty it should not matter whether or not the show results for empty
22
		//query flag is set or not - test with true and false
23
24
		$qg->setShowResultsForEmptyQuery(false);
25
		$qs = array('query_string' => array('query' => 'New Zealand', 'lenient' => true));
26
		$expected = array(
27
			'query' => $qs,
28
			'size' => 10,
29
			'from' => 0,
30
			'suggest' => $this->getDefaultSuggest('New Zealand')
31
		);
32
33
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
34
35
		$qg->setShowResultsForEmptyQuery(true);
36
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
37
	}
38
39
40
	/**
41
	 * @param string $queryText
42
	 */
43
	private function getDefaultSuggest($queryText) {
44
		return array(
45
				'query-phrase-suggestions' => array(
46
					'phrase' => array(
47
						'field' => '_all',
48
						'size' => 4,
49
						'highlight' => array(
50
							'pre_tag' => '<strong class="hl">',
51
							'post_tag' => '</strong>'
52
						)
53
					),
54
					'text' => $queryText
55
				)
56
		);
57
	}
58
59
60
	public function testGetQuerySuggester() {
61
		$qg = new QueryGenerator();
62
		$qg->setQueryText('New Zealand');
63
		$expected = array('query-suggestions' => array(
64
			'text' => 'New Zealand',
65
			'term' => array('field' => '_all'))
66
		);
67
		$this->assertEquals(
68
			$expected,
69
			$this->getQuerySuggester($qg)
0 ignored issues
show
Unused Code introduced by
The call to QueryGeneratorTest::getQuerySuggester() has too many arguments starting with $qg.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
70
		);
71
	}
72
73
74
	public function testEmptyTextShowNone() {
75
		$qg = new QueryGenerator();
76
		$qg->setQueryText('');
77
		$qg->setFields(null);
78
		$qg->setSelectedFilters(null);
79
		$qg->setShowResultsForEmptyQuery(false);
80
81
		$qs = array('query_string' => array('query' => '', 'lenient' => true));
82
		$expected = array(
83
			'query' => $qs,
84
			'size' => 10,
85
			'from' => 0,
86
			'suggest' => $this->getDefaultSuggest('')
87
		);
88
89
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
90
	}
91
92
93
	public function testEmptyTextShowAll() {
94
		$qg = new QueryGenerator();
95
		$qg->setQueryText('');
96
		$qg->setFields(null);
97
		$qg->setSelectedFilters(null);
98
		$qg->setShowResultsForEmptyQuery(true);
99
100
		//In order to show all results an empty query works,
101
		//e.g. curl -XGET 'http://localhost:9200/elastica_ss_module_test_en_us/_search?pretty'
102
		$expected = array(
103
			'size' => 10,
104
			'from' => 0,
105
			'suggest' => $this->getDefaultSuggest('')
106
		);
107
108
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
109
	}
110
111
112 View Code Duplication
	public function testMultiMatchWithText() {
1 ignored issue
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...
113
		$qg = new QueryGenerator();
114
		$qg->setQueryText('New Zealand');
115
		$fields = array('Title' => 1, 'Description' => 1);
116
		$qg->setFields($fields);
117
		$qg->setSelectedFilters(null);
118
		$qg->setClasses('FlickrPhotoTO');
119
120
		//As the query is not empty it should not matter whether or not the show results for empty
121
		//query flag is set or not - test with true and false
122
123
		$qg->setShowResultsForEmptyQuery(false);
124
		$qs = array('multi_match' => array(
125
			'fields' => array('Title','Title.*','Description','Description.*'),
126
			'type' => 'most_fields',
127
			'query' => 'New Zealand',
128
			'lenient' => true
129
			)
130
		);
131
		$expected = array(
132
			'query' => $qs,
133
			'size' => 10,
134
			'from' => 0,
135
			'suggest' => $this->getDefaultSuggest('New Zealand')
136
		);
137
138
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
139
140
		$qg->setShowResultsForEmptyQuery(true);
141
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
142
	}
143
144
145
146 View Code Duplication
	public function testMultiMatchWithNoText() {
1 ignored issue
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...
147
		$qg = new QueryGenerator();
148
		$qg->setQueryText('');
149
		$fields = array('Title' => 1, 'Description' => 1);
150
		$qg->setFields($fields);
151
		$qg->setSelectedFilters(null);
152
		$qg->setClasses('FlickrPhotoTO');
153
154
		//As the query is not empty it should not matter whether or not the show results for empty
155
		//query flag is set or not - test with true and false
156
157
		//Case of empty query, do not show results
158
		$qg->setShowResultsForEmptyQuery(false);
159
		$qs = array(
160
			'multi_match' => array(
161
				'fields' => array('Title','Title.*','Description','Description.*'),
162
				'type' => 'most_fields',
163
				'query' => '',
164
				'lenient' => true
165
			)
166
		);
167
		$expected = array(
168
			'query' => $qs,
169
			'size' => 10,
170
			'from' => 0,
171
			'suggest' => $this->getDefaultSuggest('')
172
		);
173
174
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
175
176
177
		// Now the case of empty query and show results
178
		$qg->setShowResultsForEmptyQuery(true);
179
		unset($expected['query']);
180
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
181
	}
182
183
184
	// ---- tests with aggregations ----
185
186
187
	public function testEmptyTextShowNoResultsWithAggregations() {
188
		$this->assertFalse(false, 'This is not possible - an empty query returns 0 docs and 0 aggregations');
189
	}
190
191
192
	/*
193
	Test aggregations with and without text query
194
	 */
195
	public function testTextShowResultsWithAggregations() {
196
		$qg = new QueryGenerator();
197
		$qg->setQueryText('');
198
		$qg->setFields(null);
199
		$qg->setSelectedFilters(null);
200
		$qg->setShowResultsForEmptyQuery(true);
201
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
202
		$aggs = $this->baseAggs();
203
204
		//tests are complete
205
		$expected = array(
206
			'aggs' => $aggs,
207
			'size' => 10,
208
			'from' => 0,
209
			'sort' => array('TakenAt' => 'desc'),
210
			'suggest' => $this->getDefaultSuggest('')
211
		);
212
213
		print_r($qg->generateElasticaQuery());
214
215
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
216
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
217
218
		$qg->setQueryText('New Zealand');
219
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
220
		unset($expected['sort']);
221
		$expected['query'] = array('query_string' => array('query' => 'New Zealand', 'lenient' => true));
222
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
223
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
224
225
		$qg->setShowResultsForEmptyQuery(false);
226
		$qg->setQueryText('New Zealand');
227
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
228
		$expected['query'] = array('query_string' => array('query' => 'New Zealand', 'lenient' => true));
229
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
230
	}
231
232
233
	/*
234
	Should generate this working query:
235
	curl -XGET 'http://localhost:9200/elastica_ss_module_test_en_us/_search?pretty' -d '
236
	{
237
	  "query": {
238
	    "filtered": {
239
	      "filter": {
240
	        "term": {
241
	          "ISO": 400
242
	        }
243
	      }
244
	    }
245
	  },
246
	  "aggs": {
247
	    "Aperture": {
248
	      "terms": {
249
	        "field": "Aperture",
250
	        "size": 0,
251
	        "order": {
252
	          "_term": "asc"
253
	        }
254
	      }
255
	    },
256
	    "ShutterSpeed": {
257
	      "terms": {
258
	        "field": "ShutterSpeed",
259
	        "size": 0,
260
	        "order": {
261
	          "_term": "asc"
262
	        }
263
	      }
264
	    },
265
	    "FocalLength35mm": {
266
	      "terms": {
267
	        "field": "FocalLength35mm",
268
	        "size": 0,
269
	        "order": {
270
	          "_term": "asc"
271
	        }
272
	      }
273
	    },
274
	    "ISO": {
275
	      "terms": {
276
	        "field": "ISO",
277
	        "size": 0,
278
	        "order": {
279
	          "_term": "asc"
280
	        }
281
	      }
282
	    },
283
	    "Aspect": {
284
	      "range": {
285
	        "field": "AspectRatio",
286
	        "ranges": [{
287
	          "from": 1.0e-7,
288
	          "to": 0.3,
289
	          "key": "Panoramic"
290
	        }, {
291
	          "from": 0.3,
292
	          "to": 0.9,
293
	          "key": "Horizontal"
294
	        }, {
295
	          "from": 0.9,
296
	          "to": 1.2,
297
	          "key": "Square"
298
	        }, {
299
	          "from": 1.2,
300
	          "to": 1.79,
301
	          "key": "Vertical"
302
	        }, {
303
	          "from": 1.79,
304
	          "to": 10000000,
305
	          "key": "Tallest"
306
	        }]
307
	      }
308
	    }
309
	  },
310
	  "size": 10,
311
	  "from": 0
312
	}
313
	'
314
	 */
315
	public function testTextOneFilterAggregate() {
316
		$qg = new QueryGenerator();
317
		$qg->setQueryText('');
318
		$qg->setFields(null);
319
		$filters = array('ISO' => 400);
320
		$qg->setSelectedFilters($filters);
321
		$qg->setShowResultsForEmptyQuery(true);
322
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
323
		$aggs = $this->baseAggs();
324
325
		//FIXME - query needs removed in this case, leave as a reminder for now until
326
		//tests are complete
327
		$expected = array(
328
			'aggs' => $aggs,
329
			'size' => 10,
330
			'from' => 0,
331
			'query' => array(
332
				'filtered' => array(
333
					'filter' => array('term' => array('ISO' => 400))
334
				)
335
			),
336
			'sort' => array('TakenAt' => 'desc'),
337
			'suggest' => $this->getDefaultSuggest('')
338
		);
339
340
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
341
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
342
343
		$qg->setQueryText('New Zealand');
344
		unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch
345
		$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true);
346
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
347
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
348
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
349
	}
350
351
352
	public function testTextTwoFilterAggregate() {
353
		$qg = new QueryGenerator();
354
		$qg->setQueryText('');
355
		$qg->setFields(null);
356
		$filters = array('ISO' => 400, 'Aspect' => 'Square');
357
		$qg->setSelectedFilters($filters);
358
		$qg->setShowResultsForEmptyQuery(true);
359
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
360
		$aggs = $this->baseAggs();
361
362
		//FIXME - query needs removed in this case, leave as a reminder for now until
363
		//tests are complete
364
		$expected = array(
365
			'aggs' => $aggs,
366
			'size' => 10,
367
			'from' => 0,
368
			'query' => array(
369
				'filtered' => array(
370
					'filter' =>
371
					array('and' => array(
372
						0 => array( 'term' =>  array('ISO' => 400)),
373
						1 => array( 'range' => array(
374
							'AspectRatio' => array(
375
								'gte' => '0.9',
376
								'lt' => '1.2'
377
							)
378
						))
379
					)
380
				))
381
			),
382
			'sort' => array('TakenAt' => 'desc'),
383
			'suggest' => $this->getDefaultSuggest('')
384
		);
385
386
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
387
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
388
389
		$qg->setQueryText('New Zealand');
390
		unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch
391
		$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true);
392
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
393
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
394
	}
395
396
397
	public function testTextThreeFilterAggregate() {
398
		$qg = new QueryGenerator();
399
		$qg->setQueryText('');
400
		$qg->setFields(null);
401
		$filters = array('ISO' => 400, 'Aspect' => 'Square', 'Aperture' => 5.6);
402
		$qg->setSelectedFilters($filters);
403
		$qg->setShowResultsForEmptyQuery(true);
404
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
405
		$aggs = $this->baseAggs();
406
407
		//FIXME - query needs removed in this case, leave as a reminder for now until
408
		//tests are complete
409
		$expected = array(
410
			'aggs' => $aggs,
411
			'size' => 10,
412
			'from' => 0,
413
			'query' => array(
414
				'filtered' => array('filter' =>
415
					array('and' => array(
416
						0 => array( 'term' =>  array('ISO' => 400)),
417
						1 => array( 'range' => array(
418
							'AspectRatio' => array(
419
								'gte' => '0.9',
420
								'lt' => '1.2'
421
							)
422
						)),
423
						2 => array( 'term' =>  array('Aperture' => 5.6)),
424
					)
425
				))
426
			),
427
			'sort' => array('TakenAt' => 'desc'),
428
			'suggest' => $this->getDefaultSuggest('')
429
		);
430
431
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
432
433
		$qg->setQueryText('New Zealand');
434
		unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch
435
		$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true);
436
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
437
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
438
	}
439
440
441
	public function testMultiMatchOneFilterAggregate() {
442
		$qg = new QueryGenerator();
443
		$qg->setQueryText('');
444
		$qg->setFields(array('Title' => 2, 'Content' => 1));
445
		$filters = array('ISO' => 400);
446
		$qg->setSelectedFilters($filters);
447
		$qg->setShowResultsForEmptyQuery(true);
448
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
449
		$aggs = $this->baseAggs();
450
451
		//FIXME - query needs removed in this case, leave as a reminder for now until
452
		//tests are complete
453
		$expected = array(
454
			'aggs' => $aggs,
455
			'size' => 10,
456
			'from' => 0,
457
			'query' => array(
458
				'filtered' => array(
459
					'filter' => array('term' => array('ISO' => 400))
460
				)
461
			),
462
			'sort' => array('TakenAt' => 'desc'),
463
			'suggest' => $this->getDefaultSuggest('')
464
		);
465
466
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
467
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
468
469
		$qg->setQueryText('New Zealand');
470
		unset($expected['sort']); // use relevance of search sorting
471
472
		$expected['query']['filtered']['query']['multi_match'] = array(
473
			'query' => 'New Zealand',
474
			'lenient' => true,
475
			'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'),
476
			'type' => 'most_fields'
477
		);
478
479
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
480
		print_r($qg->generateElasticaQuery()->toArray());
481
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
482
	}
483
484
485
486
	public function testMultiMatchTwoFilterAggregate() {
487
		$qg = new QueryGenerator();
488
		$qg->setQueryText('');
489
		$qg->setFields(array('Title' => 2, 'Content' => 1));
490
		$filters = array('ISO' => 400, 'Aspect' => 'Square');
491
		$qg->setSelectedFilters($filters);
492
		$qg->setShowResultsForEmptyQuery(true);
493
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
494
		$aggs = $this->baseAggs();
495
496
		//FIXME - query needs removed in this case, leave as a reminder for now until
497
		//tests are complete
498
		$expected = array(
499
			'aggs' => $aggs,
500
			'size' => 10,
501
			'from' => 0,
502
			'query' => array(
503
				'filtered' => array(
504
					'filter' =>
505
					array('and' => array(
506
						0 => array( 'term' =>  array('ISO' => 400)),
507
						1 => array( 'range' => array(
508
							'AspectRatio' => array(
509
								'gte' => '0.9',
510
								'lt' => '1.2'
511
							)
512
						))
513
					)
514
				))
515
			),
516
			'sort' => array('TakenAt' => 'desc'),
517
			'suggest' => $this->getDefaultSuggest('')
518
		);
519
520
		echo(json_encode($qg->generateElasticaQuery()->toArray()));
521
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
522
523
		$qg->setQueryText('New Zealand');
524
		unset($expected['sort']); // use relevance of search sorting
525
		$expected['query']['filtered']['query']['multi_match'] = array(
526
			'query' => 'New Zealand',
527
			'lenient' => true,
528
			'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'),
529
			'type' => 'most_fields'
530
		);
531
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
532
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
533
	}
534
535
536
537
	public function testMultiMatchThreeFilterAggregate() {
538
		$qg = new QueryGenerator();
539
		$qg->setQueryText('');
540
		$qg->setFields(array('Title' => 2, 'Content' => 1));
541
		$filters = array('ISO' => 400, 'Aspect' => 'Square', 'Aperture' => 5.6);
542
		$qg->setSelectedFilters($filters);
543
		$qg->setShowResultsForEmptyQuery(true);
544
		$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper');
545
		$aggs = $this->baseAggs();
546
547
		//FIXME - query needs removed in this case, leave as a reminder for now until
548
		//tests are complete
549
		$expected = array(
550
			'aggs' => $aggs,
551
			'size' => 10,
552
			'from' => 0,
553
			'query' => array(
554
				'filtered' => array('filter' =>
555
					array('and' => array(
556
						0 => array( 'term' =>  array('ISO' => 400)),
557
						1 => array( 'range' => array(
558
							'AspectRatio' => array(
559
								'gte' => '0.9',
560
								'lt' => '1.2'
561
							)
562
						)),
563
						2 => array( 'term' =>  array('Aperture' => 5.6)),
564
					)
565
				))
566
			),
567
			'sort' => array('TakenAt' => 'desc'),
568
			'suggest' => $this->getDefaultSuggest('')
569
		);
570
571
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
572
573
		$qg->setQueryText('New Zealand');
574
		unset($expected['sort']);
575
		$expected['query']['filtered']['query']['multi_match'] = array(
576
			'query' => 'New Zealand',
577
			'lenient' => true,
578
			'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'),
579
			'type' => 'most_fields'
580
		);
581
		$expected['suggest'] = $this->getDefaultSuggest('New Zealand');
582
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
583
	}
584
585
586
587
588
	// ---- tests for field array to elasticsearch syntax
589 View Code Duplication
	public function testConvertWeightedFieldsForElasticaUnaryStrings() {
1 ignored issue
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...
590
		$qg = new QueryGenerator();
591
		$qg->setClasses('FlickrPhotoTO');
592
		$fields = array('Title' => 1, 'Description' => 1);
593
		$expected = array('Title', 'Title.*','Description', 'Description.*');
594
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
595
	}
596
597
598 View Code Duplication
	public function testConvertWeightedFieldsForElasticaMultipleStrings() {
1 ignored issue
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...
599
		$qg = new QueryGenerator();
600
		$qg->setClasses('FlickrPhotoTO');
601
		$fields = array('Title' => 2, 'Description' => 1);
602
		$expected = array('Title^2', 'Title.*^2','Description', 'Description.*');
603
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
604
	}
605
606
607
	public function testConvertWeightedFieldsForElasticaTestNonString() {
608
		$qg = new QueryGenerator();
609
		$qg->setClasses('FlickrPhotoTO');
610
		$fields = array('Aperture' => 2, 'FocalLength35mm' => 1);
611
		$expected = array('Aperture^2', 'FocalLength35mm');
612
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
613
	}
614
615
616
	public function testConvertWeightedFieldsForElasticaNonExistent() {
617
		$qg = new QueryGenerator();
618
		$qg->setClasses('FlickrPhotoTO');
619
		$fields = array('Aperture' => 2, 'FocalLength35mm' => 1, 'Wibble' => 2);
620
		try {
621
			$this->assertEquals('This test should fail', $qg->convertWeightedFieldsForElastica($fields));
622
			$this->fail('An exception should have been thrown as the field Wibble does not exist');
623
		} catch (Exception $e) {
624
			$this->assertEquals('Field Wibble does not exist', $e->getMessage());
625
		}
626
627
	}
628
629
630 View Code Duplication
	public function testSearchFieldsMappingForClasses() {
1 ignored issue
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...
631
		$qg = new QueryGenerator();
632
		$qg->setClasses('FlickrPhotoTO,Page');
633
		$fields = array('Title' => 2, 'Description' => 1);
634
		$expected = array('Title^2', 'Title.*^2','Description', 'Description.*');
635
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
636
637
		$qg->setClasses(array('FlickrPhotoTO','Page'));
0 ignored issues
show
Documentation introduced by
array('FlickrPhotoTO', 'Page') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
638
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
639
640
	}
641
642
643
	public function testSearchFieldsMappingForClassesCaching() {
644
		QueryGenerator::resetCacheHitCounter();
645
		$cache = SS_Cache::factory('elasticsearch');
646
		// Previous tests may have altered this so start from a known position
647
		$cache->remove('SEARCHABLE_FIELDS_FlickrPhotoTO_Page');
648
		$qg = new QueryGenerator();
649
		$qg->setClasses('FlickrPhotoTO,Page');
650
		$fields = array('Title' => 2, 'Description' => 1);
651
		$expected = array('Title^2', 'Title.*^2','Description', 'Description.*');
652
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
653
654
		//Execute a 2nd time
655
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
656
		//Check for cache hit
657
		$this->assertEquals(1, QueryGenerator::getCacheHitCounter());
658
659
		//Execute a 3rd time
660
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
661
		//Check for cache hit
662
		$this->assertEquals(2, QueryGenerator::getCacheHitCounter());
663
	}
664
665
666 View Code Duplication
	public function testSearchFieldsMappingForSiteTree() {
1 ignored issue
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...
667
		$qg = new QueryGenerator();
668
		$qg->setClasses(null); // select all of site tree classes
669
		$fields = array('Title' => 2, 'Content' => 1);
670
		$expected = array('Title^2', 'Title.*^2','Content', 'Content.*');
671
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
672
673
		echo "--------------------\n";
674
		$qg->setClasses(array('FlickrPhotoTO','Page'));
0 ignored issues
show
Documentation introduced by
array('FlickrPhotoTO', 'Page') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
675
		$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields));
676
677
	}
678
679
680
	public function testPagination() {
681
		$qg = new QueryGenerator();
682
		$qg->setQueryText('New Zealand');
683
		$qg->setFields(null);
684
		$qg->setSelectedFilters(null);
685
		$qg->setPageLength(12);
686
		$qg->setStart(24);
687
688
		//As the query is not empty it should not matter whether or not the show results for empty
689
		//query flag is set or not - test with true and false
690
691
		$qg->setShowResultsForEmptyQuery(false);
692
		$this->assertEquals(false, $qg->getShowResultsForEmptyQuery());
693
		$qs = array('query_string' => array('query' => 'New Zealand', 'lenient' => true));
694
		$expected = array(
695
			'query' => $qs,
696
			'size' => 12,
697
			'from' => 24,
698
			'suggest' => $this->getDefaultSuggest('New Zealand')
699
		);
700
701
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
702
703
		$qg->setShowResultsForEmptyQuery(true);
704
		$this->assertEquals(true, $qg->getShowResultsForEmptyQuery());
705
		$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray());
706
	}
707
708
709
	/**
710
	 * 	Get an array to be used as a query for Elastica
711
	 * @return array Building bricks for a query suggester
712
	 */
713
	private function getQuerySuggester() {
714
		$suggester = array();
715
		$suggester['text'] = $this->queryText;
0 ignored issues
show
Bug introduced by
The property queryText does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
716
717
		//With _all field enable in the mapping, Searchable.php class, we can use _all field to
718
		//suggest against all fields.  It is not possible to pass an array here
719
		$suggester['term'] = array('field' => '_all');
720
		$querySuggester = array('query-suggestions' => $suggester);
721
722
		return $querySuggester;
723
	}
724
725
726
727
	/**
728
	 * Get the basic aggregates that should be returned for the augmenter being tested
729
	 * @return array array of aggregations.  Tweak these in tests and assert as required.
730
	 */
731
	private function baseAggs() {
732
		$result = array();
733
		$result['Aperture'] = array(
734
			'terms' => array(
735
				'field' => 'Aperture',
736
				'size' => 0,
737
				'order' => array('_term' => 'asc')
738
			)
739
		);
740
		$result['ShutterSpeed'] =  array(
741
			'terms' => array(
742
				'field' => 'ShutterSpeed',
743
				'size' => 0,
744
				'order' => array('_term' => 'asc')
745
			)
746
		);
747
		$result['FocalLength35mm'] =  array(
748
			'terms' => array(
749
				'field' => 'FocalLength35mm',
750
				'size' => 0,
751
				'order' => array('_term' => 'asc')
752
			)
753
		);
754
		$result['ISO'] =  array(
755
			'terms' => array(
756
				'field' => 'ISO',
757
				'size' => 0,
758
				'order' => array('_term' => 'asc')
759
			)
760
		);
761
762
		$ranges = array();
763
		$ranges[0] = array('from' => '1.0E-7', 'to' => '0.3', 'key' => 'Panoramic');
764
		$ranges[1] = array('from' => '0.3', 'to' => '0.9', 'key' => 'Horizontal');
765
		$ranges[2] = array('from' => '0.9', 'to' => '1.2', 'key' => 'Square');
766
		$ranges[3] = array('from' => '1.2', 'to' => '1.79', 'key' => 'Vertical');
767
		$ranges[4] = array('from' => '1.79', 'to' => '10000000', 'key' => 'Tallest');
768
769
		$result['Aspect'] =  array(
770
			'range' => array(
771
				'field' => 'AspectRatio',
772
				'ranges' => $ranges
773
			)
774
		);
775
		return $result;
776
	}
777
778
779
		// ---- tests for the toQuotedCSV function ----
780
	public function testToQuotedCSVFromString() {
781
		$expected = "'Bangkok','Nonthaburi','Saraburi','Chiang Mai'";
782
		$items = 'Bangkok,Nonthaburi,Saraburi,Chiang Mai';
783
		$quoted = QueryGenerator::convertToQuotedCSV($items);
784
		$this->assertEquals($expected, $quoted);
785
	}
786
787
	public function testToQuotedCSVFromArray() {
788
		$expected = "'Bangkok','Nonthaburi','Saraburi','Chiang Mai'";
789
		$items = array('Bangkok','Nonthaburi','Saraburi','Chiang Mai');
790
		$quoted = QueryGenerator::convertToQuotedCSV($items);
791
		$this->assertEquals($expected, $quoted);
792
	}
793
794
	public function testToQuotedCSVEmptyString() {
795
		$quoted = QueryGenerator::convertToQuotedCSV('');
796
		$this->assertEquals('', $quoted);
797
	}
798
799
	public function testToQuotedCSVEmptyArray() {
800
		$quoted = QueryGenerator::convertToQuotedCSV(array());
801
		$this->assertEquals('', $quoted);
802
	}
803
804
	public function testToQuotedCSVNull() {
805
		$quoted = QueryGenerator::convertToQuotedCSV(null);
806
		$this->assertEquals('', $quoted);
807
	}
808
}
809