testResultListRemoveNotImplemented()   A
last analyzed

Complexity

Conditions 2
Paths 5

Size

Total Lines 10
Code Lines 8

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6
Metric Value
dl 10
loc 10
ccs 0
cts 10
cp 0
rs 9.4286
cc 2
eloc 8
nc 5
nop 0
crap 6
1
<?php
2
3
use SilverStripe\Elastica\ElasticSearcher;
4
5
/**
6
 * Test the functionality of the Searchable extension
7
 * @package elastica
8
 */
9
class SearchAndIndexingTest extends ElasticsearchBaseTest {
10
	public static $fixture_file = 'elastica/tests/lotsOfPhotos.yml';
11
12
13
	/*
14
	Notes:
15
	Searching string on number fields fails
16
	http://elasticsearch-users.115913.n3.nabble.com/Error-when-searching-multiple-fields-with-different-types-td3897459.html
17
	*/
18
	public function testNonTextFields() {
19
		$numericFields = array(
20
			'FlickrID' => 1,
21
			'TakenAt' => 1,
22
			'FirstViewed' => 1,
23
			'Aperture' => 1,
24
			'ShutterSpeed' => 1,
25
			'FocalLength35mm' => 1,
26
			'ISO' => 1
27
		);
28
29
		$this->search('New Zealand', 0, $numericFields);
30
31
		//There are 10 entries in the fixtures, 3 default indexed pages
32
		$this->search(400, 13, $numericFields);
33
34
	}
35
36
	public function testInvalidSearchFields() {
37
		// FIXME test to check unweighted fields
38
	}
39
40
	public function testSetStopwordsConfigurationCSV() {
41
		$stopwords = "a,the,then,this";
42
		$englishIndex = new EnglishIndexSettings();
43
		$englishIndex->setStopwords($stopwords);
44
		$expected = array('a', 'the', 'then', 'this');
45
		$this->assertEquals($expected, $englishIndex->getStopwords());
46
	}
47
48
49
	public function testSetStopwordsConfigurationArray() {
50
		$stopwords = array('a', 'the', 'then', 'this');
51
		$englishIndex = new EnglishIndexSettings();
52
		$englishIndex->setStopwords($stopwords);
53
		$expected = array('a', 'the', 'then', 'this');
54
		$this->assertEquals($expected, $englishIndex->getStopwords());
55
	}
56
57
58
	public function testConfigurationInvalidStopwords() {
59
		$stopwords = 45; // deliberately invalid
60
		$englishIndex = new EnglishIndexSettings();
61
		try {
62
			$englishIndex->setStopwords($stopwords);
63
			// should not get this far, should fail
64
			$this->assertTrue(false, "Invalid stopwords were not correctly prevented");
65
		} catch (Exception $e) {
66
			$this->assertTrue(true, "Invalid stopwords correctly prevented");
67
		}
68
	}
69
70
71
	/*
72
	Search for stop words and assert that they are not found
73
	 */
74
	public function testConfiguredStopWords() {
75
		$englishIndex = new EnglishIndexSettings();
76
		$stopwords = $englishIndex->getStopwords();
77
		$expected = array('that', 'into', 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'but', 'by', 'for', 'if',
78
			'in', 'into', 'is', 'it', 'of', 'on', 'or', 'such', 'that', 'the', 'their', 'then', 'there', 'these',
79
			'they', 'this', 'to', 'was', 'will', 'with');
80
		$this->assertEquals($expected, $stopwords);
81
	}
82
83
84
85
	public function testGetResults() {
86
		// several checks needed  here including aggregations
87
	}
88
89
90
	public function testResultListGetMap() {
91
		$resultList = $this->getResultsFor('New Zealand', 10);
92
		//default is ID -> Title, useful for dropdowns
93
		$mapping = $resultList->map();
94
		$ctr = 0;
95
		foreach($resultList->getIterator() as $item) {
96
			$mappedTitle = $mapping[$item->ID];
97
			$this->assertEquals($item->Title, $mappedTitle);
98
			$ctr++;
99
		}
100
	}
101
102
103
	public function testResultListColumn() {
104
		$resultList = $this->getResultsFor('New Zealand', 10);
105
		$ids = $resultList->column();
106
107
		$expected = array();
108
		foreach($resultList as $item) {
109
			array_push($expected, $item->ID);
110
		}
111
112
		$this->assertEquals($expected, $ids);
113
114
		$expected = array();
115
		foreach($resultList as $item) {
116
			array_push($expected, $item->Title);
117
		}
118
		$titles = $resultList->column('Title');
119
		$this->assertEquals($expected, $titles);
120
	}
121
122
123
	public function testEach() {
124
		$callback = function($fp) {
125
		    $this->assertTrue(true, 'Callback reached');
126
		};
127
		$resultList = $this->getResultsFor('New Zealand', 10);
128
		$resultList->each($callback);
129
	}
130
131
132
	/*
133
	The search term 'New Zealand' was used against Flickr to create the fixtures file, so this means
134
	that all of the fixtures should have 'New Zealand' in them.  Test page length from 1 to 100
135
	 */
136
	public function testResultListPageLength() {
137
		for($i = 1; $i <= 100; $i++) {
138
			$resultList = $this->getResultsFor('New Zealand', $i);
139
			$this->assertEquals($i, $resultList->count());
140
		}
141
	}
142
143
144
	public function testResultListIndex() {
145
		$resultList = $this->getResultsFor('New Zealand', 10);
146
		$index = $resultList->getService()->getIndex();
147
		$this->assertEquals('elastica_ss_module_test_en_us', $index->getName());
148
	}
149
150
151
	public function testResultListGetQuery() {
152
		$resultList = $this->getResultsFor('New Zealand', 10);
153
		$query = $resultList->getQuery()->toArray();
154
155
		$expected = array();
156
		$expected['query'] = array('multi_match' => array(
157
				'query' => 'New Zealand',
158
				'fields' => array('Title', 'Title.*', 'Description', 'Description.*'),
159
				'type' => 'most_fields',
160
				'lenient' => true
161
			)
162
		);
163
		$expected['size'] = 10;
164
		$expected['from'] = 0;
165
166
167
		$this->assertEquals($expected['size'], $query['size']);
168
		$this->assertEquals($expected['from'], $query['from']);
169
		$this->assertEquals($expected['query'], $query['query']);
170
	}
171
172
173
	/*
174
	Check that the time for the search was more than zero
175
	 */
176
	public function testResultListGetTotalTime() {
177
		$resultList = $this->getResultsFor('New Zealand', 10);
178
		$time = $resultList->getTotalTime();
179
		$this->assertGreaterThan(0, $time);
180
	}
181
182
183
	/*
184
	Test the result list iterator function
185
	 */
186
	public function testResultListGetIterator() {
187
		$resultList = $this->getResultsFor('New Zealand', 100);
188
		$ctr = 0;
189
		foreach($resultList->getIterator() as $result) {
190
			$ctr++;
191
		}
192
		$this->assertEquals(100, $ctr);
193
	}
194
195
196
	/*
197
	Check some basic properties of the array returned for a result
198
	 */
199
	public function testToArrayFunction() {
200
		$resultList = $this->getResultsFor('New Zealand', 1);
201
		$result = $resultList->toArray();
202
203
		$this->assertEquals(1, sizeof($result));
204
		$fp = $result[0];
205
		$this->assertEquals('FlickrPhotoTO', $fp->ClassName);
206
		$this->assertEquals(2147483647, $fp->FlickrID);
207
		$this->assertTrue(preg_match('/New Zealand/', $fp->Title) == 1);
208
	}
209
210
211
	/*
212
	Check some basic properties of the array returned for a result
213
	 */
214
	public function testToNestedArrayFunction() {
215
		$resultList = $this->getResultsFor('New Zealand', 4);
216
		$result = $resultList->toNestedArray();
217
218
		$this->assertEquals(4, sizeof($result));
219
		$fp = $result[0];
220
		$this->assertEquals('FlickrPhotoTO', $fp['ClassName']);
221
		$this->assertEquals(2147483647, $fp['FlickrID']);
222
		$this->assertTrue(preg_match('/New Zealand/', $fp['Title']) == 1);
223
	}
224
225
226 View Code Duplication
	public function testResultListOffsetExistsNotImplemented() {
227
		try {
228
			$resultList = $this->getResultsFor('New Zealand', 10);
229
			$resultList->offsetExists(10);
230
			$this->assertFalse(true, "This line should not have been reached");
231
		} catch (Exception $e) {
232
			$this->assertEquals('Not implemented', $e->getMessage());
233
		}
234
	}
235
236
237 View Code Duplication
	public function testResultListOffsetGetNotImplemented() {
238
		try {
239
			$resultList = $this->getResultsFor('New Zealand', 10);
240
			$resultList->offsetGet(10);
241
			$this->assertFalse(true, "This line should not have been reached");
242
		} catch (Exception $e) {
243
			$this->assertEquals('Not implemented', $e->getMessage());
244
		}
245
	}
246
247
248 View Code Duplication
	public function testResultListOffsetSetNotImplemented() {
249
		try {
250
			$resultList = $this->getResultsFor('New Zealand', 10);
251
			$resultList->offsetSet(10, null);
252
			$this->assertFalse(true, "This line should not have been reached");
253
		} catch (Exception $e) {
254
			$this->assertEquals('Not implemented', $e->getMessage());
255
		}
256
	}
257
258
259 View Code Duplication
	public function testResultListOffsetUnsetNotImplemented() {
260
		try {
261
			$resultList = $this->getResultsFor('New Zealand', 10);
262
			$resultList->offsetUnset(10);
263
			$this->assertFalse(true, "This line should not have been reached");
264
		} catch (Exception $e) {
265
			$this->assertEquals('Not implemented', $e->getMessage());
266
		}
267
	}
268
269
270 View Code Duplication
	public function testResultListAddNotImplemented() {
271
		try {
272
			$resultList = $this->getResultsFor('New Zealand', 10);
273
			$fp = new FlickrPhotoTO();
274
			$resultList->add($fp);
275
			$this->assertFalse(true, "This line should not have been reached");
276
		} catch (Exception $e) {
277
			$this->assertEquals('Not implemented', $e->getMessage());
278
		}
279
	}
280
281
282 View Code Duplication
	public function testResultListRemoveNotImplemented() {
283
		try {
284
			$resultList = $this->getResultsFor('New Zealand', 10);
285
			$fp = new FlickrPhotoTO();
286
			$resultList->remove($fp);
287
			$this->assertFalse(true, "This line should not have been reached");
288
		} catch (Exception $e) {
289
			$this->assertEquals('Not implemented', $e->getMessage());
290
		}
291
	}
292
293
294 View Code Duplication
	public function testResultListFindNotImplemented() {
295
		try {
296
			$resultList = $this->getResultsFor('New Zealand', 10);
297
			$fp = new FlickrPhotoTO();
298
			$resultList->find(4, $fp);
299
			$this->assertFalse(true, "This line should not have been reached");
300
		} catch (Exception $e) {
301
			$this->assertEquals('Not implemented', $e->getMessage());
302
		}
303
	}
304
305
306
307
308
	public function testResultListToArray() {
309
		$sfs = SearchableField::get()->filter(array('ClazzName' => 'FlickrPhotoTO', 'Type' => 'string'));
310
		foreach($sfs->getIterator() as $sf) {
311
			$sf->ShowHighlights = true;
312
			$sf->write();
313
		}
314
315
		$fields = array('Title' => 1, 'Description' => 1);
316
		$resultList = $this->getResultsFor('New Zealand', 10, $fields);
317
318
		$toarr = $resultList->toArray();
319
320
		foreach($toarr as $item) {
321
			$hl = $item->SearchHighlights;
322
			foreach ($hl as $shl) {
323
				$html = $shl->Snippet;
324
				$splits = explode('<strong class="hl">', $html);
325
				if (sizeof($splits) > 1) {
326
					$splits = explode('</strong>', $splits[1]);
327
					$term = $splits[0];
328
					$term = strtolower($term);
329
					$this->assertEquals('new', $term);
330
				}
331
			}
332
		}
333
334
335
	}
336
337 View Code Duplication
	public function testResultListFirstNotImplemented() {
338
		try {
339
			$resultList = $this->getResultsFor('New Zealand', 10);
340
			$resultList->first();
341
			$this->assertFalse(true, "This line should not have been reached");
342
		} catch (Exception $e) {
343
			$this->assertEquals('Not implemented', $e->getMessage());
344
		}
345
	}
346
347
348 View Code Duplication
	public function testResultListLastNotImplemented() {
349
		try {
350
			$resultList = $this->getResultsFor('New Zealand', 10);
351
			$resultList->last();
352
			$this->assertFalse(true, "This line should not have been reached");
353
		} catch (Exception $e) {
354
			$this->assertEquals('Not implemented', $e->getMessage());
355
		}
356
	}
357
358
359
	public function testFoldedIndexes() {
360
		$this->markTestIncomplete('Folded test to do');
361
	}
362
363
364
	public function testSynonymIndexes() {
365
		$this->markTestIncomplete('Synonym test to do');
366
	}
367
368
369
	public function testNonExistentField() {
370
		try {
371
			// this should fail as field Fwlubble does not exist
372
			$this->search('zealand', 0, array('Fwlubble' => 1));
373
			$this->assertTrue(false, "Field Fwlubble does not exist and an exception should have been thrown");
374
		} catch (Exception $e) {
375
			$this->assertTrue(true, "Field Fwlubble does not exist, exception thrown as expected");
376
		}
377
378
	}
379
380
381
	public function testPriming() {
382
		$searchableClasses = SearchableClass::get();
383
		$sortedNames = $searchableClasses->Map('Name')->toArray();
384
		sort($sortedNames);
385
386
		$expected = array(
387
		'0' => 'FlickrAuthorTO',
388
		'1' => 'FlickrPhotoTO',
389
		'2' => 'FlickrSetTO',
390
		'3' => 'FlickrTagTO',
391
		'4' => 'Page',
392
		'5' => 'SearchableTestPage',
393
		'6' => 'SiteTree'
394
		);
395
		$this->assertEquals($expected, $sortedNames);
396
397
		$searchableFields = SearchableField::get();
398
		$expected = array(
399
			'0' => 'Aperture',
400
			'1' => 'AspectRatio',
401
			'2' => 'Content',
402
			'3' => 'Country',
403
			'4' => 'Description',
404
			'5' => 'DisplayName',
405
			'6' => 'FirstViewed',
406
			'7' => 'FlickrID',
407
			'8' => 'FlickrPhotoTOs',
408
			'9' => 'FlickrSetTOs',
409
			'10' => 'FlickrTagTOs',
410
			'11' => 'FocalLength35mm',
411
			'12' => 'ISO',
412
			'13' => 'PageDate',
413
			'14' => 'PathAlias',
414
			'15' => 'Photographer',
415
			'16' => 'RawValue',
416
			'17' => 'ShutterSpeed',
417
			'18' => 'TakenAt',
418
			'19' => 'TakenAtDT',
419
			'20' => 'TestMethod',
420
			'21' => 'TestMethodHTML',
421
			'22' => 'Title'
422
		);
423
424
		$sortedNames = array_keys($searchableFields->Map('Name')->toArray());
425
		sort($sortedNames);
426
		$this->assertEquals($expected, $sortedNames);
427
	}
428
429
430
	/**
431
	 * Test searching
432
	 * http://stackoverflow.com/questions/28305250/elasticsearch-customize-score-for-synonyms-stemming
433
	 */
434 View Code Duplication
	private function search($query, $resultsExpected = 10, $fields = null) {
435
		$es = new ElasticSearcher();
436
		$es->setStart(0);
437
		$es->setPageLength(100);
438
		$es->setClasses('FlickrPhotoTO');
439
		$results = $es->search($query, $fields);
440
		$this->assertEquals($resultsExpected, $results->count());
441
		return $results->count();
442
	}
443
444
445 View Code Duplication
	private function getResultsFor($query, $pageLength = 10, $fields = array('Title' => 1, 'Description' => 1)) {
446
		$es = new ElasticSearcher();
447
		$es->setStart(0);
448
		$es->setPageLength($pageLength);
449
		$es->setClasses('FlickrPhotoTO');
450
		$resultList = $es->search($query, $fields)->getList();
451
		$this->assertEquals('SilverStripe\Elastica\ResultList', get_class($resultList));
452
		return $resultList;
453
	}
454
}
455