SearchableTest::testGetElasticaDocument()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 27
ccs 0
cts 23
cp 0
rs 8.8571
cc 1
eloc 23
nc 1
nop 0
crap 2
1
<?php
2
3
use SilverStripe\Elastica\ElasticSearcher;
4
5
6
/**
7
 * Test the functionality of the Searchable extension
8
 * @package elastica
9
 */
10
class SearchableTest extends ElasticsearchBaseTest {
11
	public static $fixture_file = 'elastica/tests/ElasticaTest.yml';
12
13
	public function setUp() {
14
		// this needs to be called in order to create the list of searchable
15
		// classes and fields that are available.  Simulates part of a build
16
		$classes = array('SearchableTestPage', 'SiteTree', 'Page', 'FlickrPhotoTO', 'FlickrSetTO',
17
			'FlickrTagTO', 'FlickrAuthorTO', 'FlickrSetTO');
18
		$this->requireDefaultRecordsFrom = $classes;
19
20
		// load fixtures
21
		parent::setUp();
22
	}
23
24
25
	/*
26
	FIXME - this method may be problematic, look at when fresh.  Different types
27
	returned between mysql and sqlite3
28
	 */
29
	public function testgetFieldValuesAsArrayFromFixtures() {
30
		$manyTypes = $this->objFromFixture('ManyTypesPage', 'manytypes0001');
31
		$result = $manyTypes->getFieldValuesAsArray();
32
		$this->generateAssertionsFromArray($result);
33
		$expected = array(
34
			'BooleanField' => '1',
35
			'CurrencyField' => '100.25',
36
			'DateField' => '2014-04-15',
37
			'DecimalField' => '0.00',
38
			'HTMLTextField' => '',
39
			'HTMLVarcharField' => 'This is some *HTML*varchar field',
40
			'IntField' => '677',
41
			'PercentageField' => '8.2000',
42
			'SS_DatetimeField' => '2014-10-18 08:24:00',
43
			'TextField' => 'This is a text field',
44
			'TimeField' => '17:48:18',
45
			'Title' => 'Many Types Page',
46
			'Content' => 'Many types of fields'
47
		);
48
49
		$this->assertEquals($expected, $result);
50
51
	}
52
53
54
55
	public function testBadFormatFields() {
56
		$manyTypes = $this->objFromFixture('ManyTypesPage', 'manytypes0001');
57
		$fields = $manyTypes->getElasticaFields();
58
59
		$expected = array('type' => 'boolean');
60
		$this->assertEquals($expected, $fields['BooleanField']);
61
62
		$expected = array('type' => 'double');
63
		$this->assertEquals($expected, $fields['CurrencyField']);
64
65
		$expected = array('type' => 'date', 'format' => 'y-M-d');
66
		$this->assertEquals($expected, $fields['DateField']);
67
68
		$expected = array('type' => 'double');
69
		$this->assertEquals($expected, $fields['DecimalField']);
70
71
		$stringFormat = array(
72
			'type' => 'string',
73
			'analyzer' => 'stemmed',
74
			'term_vector' => 'yes',
75
			'fields' => array(
76
				'standard' => array(
77
					'type' => 'string',
78
					'analyzer' => 'unstemmed',
79
					'term_vector' => 'yes'
80
				),
81
				'shingles' => array(
82
					'type' => 'string',
83
					'analyzer' => 'shingles',
84
					'term_vector' => 'yes'
85
				)
86
			)
87
		);
88
89
		$expected = $stringFormat;
90
		$this->assertEquals($expected, $fields['HTMLTextField']);
91
92
		$expected = $stringFormat;
93
		$this->assertEquals($expected, $fields['HTMLVarcharField']);
94
95
		$expected = array('type' => 'integer');
96
		$this->assertEquals($expected, $fields['IntField']);
97
98
		$expected = array('type' => 'double');
99
		$this->assertEquals($expected, $fields['PercentageField']);
100
101
		$expected = array('type' => 'date', 'format' => 'y-M-d H:m:s');
102
		$this->assertEquals($expected, $fields['SS_DatetimeField']);
103
104
		$expected = $stringFormat;
105
		$this->assertEquals($expected, $fields['TextField']);
106
107
		$expected = array('type' => 'date', 'format' => 'H:m:s');
108
		$this->assertEquals($expected, $fields['TimeField']);
109
	}
110
111
112
	public function testGetDateFields() {
113
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
114
		$fields = $flickrPhoto->getElasticaFields();
115
116
		$expected = array('type' => 'date', 'format' => 'y-M-d H:m:s');
117
		$this->assertEquals($expected, $fields['TakenAt']);
118
119
		$expected = array('type' => 'date', 'format' => 'y-M-d H:m:s');
120
		$this->assertEquals($expected, $fields['TakenAtDT']);
121
122
		$expected = array('type' => 'date', 'format' => 'y-M-d');
123
		$this->assertEquals($expected, $fields['FirstViewed']);
124
	}
125
126
127
	/**
128
	 * Test a valid identifier
129
	 */
130
	public function testMapping() {
131
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
132
		$mapping = $flickrPhoto->getElasticaMapping();
133
134
		//array of mapping properties
135
		$properties = $mapping->getProperties();
136
137
		//test FlickrPhotoTO relationships mapping
138
		$expectedRelStringArray = array(
139
			'type' => 'string',
140
			'fields' => array(
141
				'standard' => array(
142
					'type' => 'string',
143
					'analyzer' => 'unstemmed',
144
					'term_vector' => 'yes'
145
				),
146
				'shingles' => array(
147
					'type' => 'string',
148
					'analyzer' => 'shingles',
149
					'term_vector' => 'yes'
150
				)
151
			),
152
			'analyzer' => 'stemmed',
153
			'term_vector' => 'yes'
154
		);
155
156
		$this->assertEquals($expectedRelStringArray,
157
			$properties['FlickrAuthorTO']['properties']['DisplayName']
158
		);
159
		$this->assertEquals($expectedRelStringArray,
160
			$properties['FlickrAuthorTO']['properties']['PathAlias']
161
		);
162
		$this->assertEquals($expectedRelStringArray,
163
			$properties['FlickrTagTO']['properties']['RawValue']
164
		);
165
		$this->assertEquals($expectedRelStringArray,
166
			$properties['FlickrSetTO']['properties']['Title']
167
		);
168
		$this->assertEquals($expectedRelStringArray,
169
			$properties['FlickrSetTO']['properties']['Description']
170
		);
171
172
		// check constructed field, location
173
		$locationProperties = $properties['location'];
174
		$this->assertEquals('geo_point', $locationProperties['type']);
175
		$this->assertEquals('compressed', $locationProperties['fielddata']['format']);
176
		$this->assertEquals('1cm', $locationProperties['fielddata']['precision']);
177
178
179
		//test the FlickrPhotoTO core model
180
181
182
183
		// check strings
184
		$shouldBeString = array('Title', 'Description');
185
		$shouldBeInt = array('ISO', 'FlickrID', 'FocalLength35mm');
186
		$shouldBeBoolean = array('IsInSiteTree');
187
		$shouldBeDouble = array('Aperture');
188
		$shouldBeDateTime = array('TakenAt');
189
		$shouldBeDate = array('FirstViewed');
190
191
		// tokens are strings that have analyzer 'not_analyzed', namely the string is indexed as is
192
		$shouldBeTokens = array('ShutterSpeed', 'Link');
193
194
195
		// check strings
196
		$expectedStandardArray = array('type' => 'string', 'analyzer' => 'unstemmed', 'term_vector' => 'yes');
197
		foreach($shouldBeString as $fieldName) {
198
			$fieldProperties = $properties[$fieldName];
199
200
			$type = $fieldProperties['type'];
201
			$analyzer = $fieldProperties['analyzer'];
202
			$this->assertEquals('string', $type);
203
204
			// check for stemmed analysis
205
			$this->assertEquals('stemmed', $analyzer);
206
207
			// check for unstemmed analaysis
208
209
			$this->assertEquals($expectedStandardArray, $fieldProperties['fields']['standard']);
210
211
			// check for only 3 entries
212
			$this->assertEquals(4, sizeof(array_keys($fieldProperties)));
213
		}
214
215
		// check ints
216
		foreach($shouldBeInt as $fieldName) {
217
			$fieldProperties = $properties[$fieldName];
218
			$type = $fieldProperties['type'];
219
			$this->assertEquals(1, sizeof(array_keys($fieldProperties)));
220
			$this->assertEquals('integer', $type);
221
		}
222
223
224
		// check doubles
225
		foreach($shouldBeDouble as $fieldName) {
226
			$fieldProperties = $properties[$fieldName];
227
			$type = $fieldProperties['type'];
228
			$this->assertEquals(1, sizeof(array_keys($fieldProperties)));
229
			$this->assertEquals('double', $type);
230
		}
231
232
		// check boolean
233
		foreach($shouldBeBoolean as $fieldName) {
234
			$fieldProperties = $properties[$fieldName];
235
			$type = $fieldProperties['type'];
236
			$this->assertEquals(1, sizeof(array_keys($fieldProperties)));
237
			$this->assertEquals('boolean', $type);
238
		}
239
240
241
		foreach($shouldBeDate as $fieldName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
242
			$fieldProperties = $properties[$fieldName];
243
			$type = $fieldProperties['type'];
244
			$this->assertEquals(2, sizeof(array_keys($fieldProperties)));
245
			$this->assertEquals('date', $type);
246
			$this->assertEquals('y-M-d', $fieldProperties['format']);
247
		}
248
249
250
251
		// check date time, stored in Elasticsearch as a date with a different format than above
252
		foreach($shouldBeDateTime as $fieldName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
253
			$fieldProperties = $properties[$fieldName];
254
			$type = $fieldProperties['type'];
255
			$this->assertEquals(2, sizeof(array_keys($fieldProperties)));
256
			$this->assertEquals('date', $type);
257
			$this->assertEquals('y-M-d H:m:s', $fieldProperties['format']);
258
		}
259
260
		//check shutter speed is tokenized, ie not analyzed - for aggregation purposes
261
		//
262
		foreach($shouldBeTokens as $fieldName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
263
			$fieldProperties = $properties[$fieldName];
264
			$type = $fieldProperties['type'];
265
			$this->assertEquals('string', $type);
266
267
			// check for no analysis
268
			$analyzer = $fieldProperties['index'];
269
			$this->assertEquals('not_analyzed', $analyzer);
270
271
			// check for only 2 entries
272
			$this->assertEquals(2, sizeof(array_keys($fieldProperties)));
273
		}
274
	}
275
276
277
	public function testGetType() {
278
		//A type in Elasticsearch is used to represent each SilverStripe content type,
279
		//the name used being the Silverstripe $fieldName
280
281
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
282
		$type = $flickrPhoto->getElasticaType();
283
		$this->assertEquals('FlickrPhotoTO', $type);
284
	}
285
286
287
	/*
288
	Get a record as an Elastic document and check values
289
	 */
290
	public function testGetElasticaDocument() {
291
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
292
		$doc = $flickrPhoto->getElasticaDocument()->getData();
293
294
		$expected = array();
295
		$expected['Title'] = 'Bangkok';
296
		$expected['FlickrID'] = '1234567';
297
		$expected['Description'] = 'Test photograph';
298
		$expected['TakenAt'] = '2011-07-04 20:36:00';
299
		$expected['TakenAtDT'] = null;
300
		$expected['FirstViewed'] = '2012-04-28';
301
		$expected['Aperture'] = 8.0;
302
303
		//Shutter speed is altered for aggregations
304
		$expected['ShutterSpeed'] = '0.01|1/100';
305
		$expected['FocalLength35mm'] = 140;
306
		$expected['ISO'] = 400;
307
		$expected['AspectRatio'] = 1.013;
308
		$expected['Photographer'] = array();
309
		$expected['FlickrTagTOs'] = array();
310
		$expected['FlickrSetTOs'] = array();
311
		$expected['IsInSiteTree'] = false;
312
		$expected['location'] = array('lat' => 13.42, 'lon' => 100);
313
		$expected['TestMethod'] = 'this is a test method';
314
		$expected['TestMethodHTML'] = 'this is a test method that returns *HTML*';
315
		$this->assertEquals($expected, $doc);
316
	}
317
318
319
	public function testElasticaResult() {
320
		$resultList = $this->getResultsFor('Bangkok');
321
322
		// there is only one result.  Note lack of a 'first' method
323
		foreach($resultList->getIterator() as $fp) {
324
			//This is an Elastica\Result object
325
			$elasticaResult = $fp->getElasticaResult();
326
327
			$fields = $elasticaResult->getSource();
328
329
			$this->assertEquals($fp->Title, $fields['Title']);
330
			$this->assertEquals($fp->FlickrID, $fields['FlickrID']);
331
			$this->assertEquals($fp->Description, $fields['Description']);
332
			$this->assertEquals($fp->TakenAt, $fields['TakenAt']);
333
			$this->assertEquals($fp->FirstViewed, $fields['FirstViewed']);
334
			$this->assertEquals($fp->Aperture, $fields['Aperture']);
335
336
			//ShutterSpeed is a special case, mangled field
337
			$this->assertEquals('0.01|1/100', $fields['ShutterSpeed']);
338
			$this->assertEquals($fp->FocalLength35mm, $fields['FocalLength35mm']);
339
			$this->assertEquals($fp->ISO, $fields['ISO']);
340
			$this->assertEquals($fp->AspectRatio, $fields['AspectRatio']);
341
342
			//Empty arrays for null values
343
			$this->assertEquals(array(), $fields['Photographer']);
344
			$this->assertEquals(array(), $fields['FlickrTagTOs']);
345
			$this->assertEquals(array(), $fields['FlickrSetTOs']);
346
			$this->assertEquals(false, $fields['IsInSiteTree']);
347
		}
348
	}
349
350
351
	public function testDeleteNonExistentDoc() {
352
		$fp = new FlickrPhotoTO();
353
		$fp->Title = 'Test Deletion';
354
		$fp->IndexingOff = true; // do no index this
355
		$fp->write();
356
		$fp->IndexingOff = false;
357
358
		try {
359
			$fp->delete();
360
			$this->fail('Exception should have been thrown when deleting non existent item');
361
		} catch (Exception $e) {
362
			//This error comes out of Elastica itself
363
			$this->assertEquals('Deleted document FlickrPhotoTO (2) not found in search index.',
364
				$e->getMessage());
365
		}
366
	}
367
368
369
370
371
	public function testUnpublishPublish() {
372
		$nDocsAtStart = $this->getNumberOfIndexedDocuments();
373
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
374
375
		$page = $this->objFromFixture('SiteTree', 'sitetree001');
376
		$page->doUnpublish();
377
378
		$this->checkNumberOfIndexedDocuments($nDocsAtStart - 1);
379
380
		$page->doPublish();
381
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
382
	}
383
384
385
	/**
386
	 * For a page that is already published, set the ShowInSearch flag to false,
387
	 * write to stage, and then rePublish
388
	 */
389
	public function testUnpublishAlreadyPublisedhHideFromSearch() {
390
		$page = $this->objFromFixture('SiteTree', 'sitetree001');
391
392
		// By default the page is not indexed (for speed reasons)
393
		// Change the title, turn on indexing and save it
394
		// This will invoke a database write
395
		$page->Title = "I will be indexed";
396
		$page->IndexingOff = true;
397
		$page->write();
398
399
		$nDocsAtStart = $this->getNumberOfIndexedDocuments();
400
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
401
402
		// assert keys of term vectors, this will indicate page
403
		// is stored in the index or not
404
		$termVectors = $page->getTermVectors();
405
		$expected = array(
406
		'0' => 'Content',
407
		'1' => 'Content.shingles',
408
		'2' => 'Content.standard',
409
		'3' => 'Link',
410
				'4' => 'Title',
411
		'5' => 'Title.autocomplete',
412
		'6' => 'Title.shingles',
413
		'7' => 'Title.standard',
414
		);
415
416
		$keys = array_keys($termVectors);
417
		sort($keys);
418
419
		$this->assertEquals($expected, $keys);
420
421
422
//CURRENT
423
		$page->ShowInSearch = false;
424
		$page->write();
425
426
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
427
428
		$page->doPublish();
429
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
430
	}
431
432
433
434
	/**
435
	 * For a page that is not published, set the ShowInSearch flag to false,
436
	 * write to stage, and then rePublish.  Same as previous test except
437
	 * no need to delete from the index as it already does not exist
438
	 */
439
	public function testUnpublishPublishHideFromSearch() {
440
		$page = $this->objFromFixture('SiteTree', 'sitetree001');
441
		$page->doUnpublish();
442
443
		// By default the page is not indexed (for speed reasons)
444
		// Change the title, turn on indexing and save it
445
		// This will invoke a database write
446
		$page->Title = "I will be indexed";
447
		$page->IndexingOff = true;
448
		$page->write();
449
450
		$nDocsAtStart = $this->getNumberOfIndexedDocuments();
451
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
452
		$page->ShowInSearch = false;
453
		$page->write();
454
455
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
456
457
		$page->doPublish();
458
		$this->checkNumberOfIndexedDocuments($nDocsAtStart);
459
	}
460
461
462
463
464
	public function testGetCMSFields() {
465
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
466
		$fields = $flickrPhoto->getCMSFields();
467
468
		$this->checkTabExists($fields, 'ElasticaTermsset');
469
	}
470
471
472
	public function testNoSearchableFieldsConfigured() {
473
		$config = Config::inst();
474
		$sf = $config->get('FlickrPhotoTO', 'searchable_fields');
475
		$config->remove('FlickrPhotoTO', 'searchable_fields');
476
		$fp = Injector::inst()->create('FlickrPhotoTO');
477
		try {
478
			$fp->getAllSearchableFields();
479
			$this->fail("getAllSearchableFields should have failed as static var searchable_fields not configured");
480
		} catch (Exception $e) {
481
			$this->assertEquals('The field $searchable_fields must be set for the class FlickrPhotoTO', $e->getMessage());
482
		}
483
484
		$config->update('FlickrPhotoTO', 'searchable_fields', $sf);
485
	}
486
487
488
	public function testNoSearchableFieldsConfiguredForHasManyRelation() {
489
		$config = Config::inst();
490
		$sf = $config->get('FlickrTagTO', 'searchable_fields');
491
		$config->remove('FlickrTagTO', 'searchable_fields');
492
		$fp = Injector::inst()->create('FlickrPhotoTO');
493
		try {
494
			$fp->getAllSearchableFields();
495
			$this->fail("getAllSearchableFields should have failed as static var searchable_fields not configured");
496
		} catch (Exception $e) {
497
			$this->assertEquals('The field $searchable_fields must be set for the class FlickrTagTO', $e->getMessage());
498
		}
499
500
		$config->update('FlickrTagTO', 'searchable_fields', $sf);
501
502
	}
503
504
505
	public function testNoSearchableFieldsConfiguredForHasOneRelation() {
506
		$config = Config::inst();
507
		$sf = $config->get('FlickrAuthorTO', 'searchable_fields');
508
		$config->remove('FlickrAuthorTO', 'searchable_fields');
509
		$fp = Injector::inst()->create('FlickrPhotoTO');
510
		try {
511
			$fp->getAllSearchableFields();
512
			$this->fail("getAllSearchableFields should have failed as static var searchable_fields not configured");
513
		} catch (Exception $e) {
514
			$this->assertEquals('The field $searchable_fields must be set for the class FlickrAuthorTO', $e->getMessage());
515
		}
516
517
		$config->update('FlickrAuthorTO', 'searchable_fields', $sf);
518
519
	}
520
521
522
	public function testSearchableMethodNotExist() {
523
		$config = Config::inst();
524
		$sr = $config->get('FlickrPhotoTO', 'searchable_relationships');
525
		$config->remove('FlickrPhotoTO', 'searchable_relationships');
526
		$config->update('FlickrPhotoTO', 'searchable_relationships', array('thisMethodDoesNotExist'));
527
		$fp = Injector::inst()->create('FlickrPhotoTO');
528
		try {
529
			$fp->getAllSearchableFields();
530
			$this->fail("getAllSearchableFields should have failed searchable relationship does not exist");
531
		} catch (Exception $e) {
532
			$this->assertEquals('The method thisMethodDoesNotExist not found in class FlickrPhotoTO, please check configuration',
533
				 $e->getMessage());
534
		}
535
536
		// MUST REMOVE FIRST.  Otherwise append and the erroroneus value above still exists
537
		$config->remove('FlickrPhotoTO', 'searchable_relationships');
538
		$config->update('FlickrPhotoTO', 'searchable_relationships', $sr);
539
	}
540
541
542
	public function testFieldsToElasticaConfig() {
543
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
544
		$fields = $flickrPhoto->getAllSearchableFields();
545
546
		$expected = array(
547
			'Title' => array(
548
				'title' => 'Title',
549
				'filter' => 'PartialMatchFilter'
550
			),
551
			'FlickrID' => array(
552
				'title' => 'Flickr ID',
553
				'filter' => 'PartialMatchFilter'
554
			),
555
			'Description' => array(
556
				'title' => 'Description',
557
				'filter' => 'PartialMatchFilter'
558
			),
559
			'TakenAt' => array(
560
				'title' => 'Taken At',
561
				'filter' => 'PartialMatchFilter'
562
			),
563
			'TakenAtDT' => array(
564
				'title' => 'Taken At DT',
565
				'filter' => 'PartialMatchFilter'
566
			),
567
			'FirstViewed' => array(
568
				'title' => 'First Viewed',
569
				'filter' => 'PartialMatchFilter'
570
			),
571
			'Aperture' => array(
572
				'title' => 'Aperture',
573
				'filter' => 'PartialMatchFilter'
574
			),
575
			'ShutterSpeed' => array(
576
				'title' => 'Shutter Speed',
577
				'filter' => 'PartialMatchFilter'
578
			),
579
			'FocalLength35mm' => array(
580
				'title' => 'Focal Length35mm',
581
				'filter' => 'PartialMatchFilter'
582
			),
583
			'ISO' => array(
584
				'title' => 'ISO',
585
				'filter' => 'PartialMatchFilter'
586
			),
587
			'AspectRatio' => array(
588
				'title' => 'Aspect Ratio',
589
				'filter' => 'PartialMatchFilter'
590
			),
591
			'TestMethod' => array(
592
				'title' => 'Test Method',
593
				'filter' => 'PartialMatchFilter'
594
			),
595
			'TestMethodHTML' => array(
596
				'title' => 'Test Method HTML',
597
				'filter' => 'PartialMatchFilter'
598
			),
599
			'Photographer()' => array(
600
				'PathAlias' => array(
601
					'title' => 'Path Alias',
602
					'filter' => 'PartialMatchFilter'
603
				),
604
				'DisplayName' => array(
605
					'title' => 'Display Name',
606
					'filter' => 'PartialMatchFilter'
607
				)
608
			),
609
			'FlickrTagTOs()' => array(
610
				'RawValue' => array(
611
					'title' => 'Raw Value',
612
					'filter' => 'PartialMatchFilter'
613
				)
614
			),
615
			'FlickrSetTOs()' => array(
616
				'Title' => array(
617
					'title' => 'Title',
618
					'filter' => 'PartialMatchFilter'
619
				),
620
				'FlickrID' => array(
621
					'title' => 'Flickr ID',
622
					'filter' => 'PartialMatchFilter'
623
				),
624
				'Description' => array(
625
					'title' => 'Description',
626
					'filter' => 'PartialMatchFilter'
627
				)
628
			)
629
		);
630
631
		$this->assertEquals($expected, $fields);
632
	}
633
634
635
	public function testHasOneExistsSearchableToArray() {
636
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
637
		$flickrPhoto->IndexingOff = false;
638
		$flickrPhoto->Title = 'Test title edited';
639
		$photographer = new FlickrAuthorTO();
640
		$photographer->DisplayName = 'Fred Bloggs';
641
		$photographer->PathAlias = '/fredbloggs';
642
643
		$photographer->write();
644
645
		$flickrPhoto->PhotographerID = $photographer->ID; ;
646
		$flickrPhoto->write();
647
		$fieldValuesArray = $flickrPhoto->getFieldValuesAsArray();
648
649
		$actual = $fieldValuesArray['Photographer'];
650
		$this->generateAssertionsFromArray($actual);
651
		$expected = array(
652
			'PathAlias' => '/fredbloggs',
653
			'DisplayName' => 'Fred Bloggs',
654
			'FlickrPhotoTO' => '',
655
		);
656
657
		$this->assertEquals($expected, $actual);
658
	}
659
660
661
662
	public function testHasManyExistsSearchableToArray() {
663
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
664
		$flickrPhoto->IndexingOff = false;
665
		$flickrPhoto->Title = 'Test title edited';
666
		$tag1 = new FlickrTagTO();
667
		$tag1->FlickrID = '1000001';
668
		$tag1->Value = 'auckland';
669
		$tag1->RawValue = 'Auckland';
670
		$tag1->write();
671
672
673
		$tag2 = new FlickrTagTO();
674
		$tag2->FlickrID = '1000002';
675
		$tag2->Value = 'wellington';
676
		$tag2->RawValue = 'Wellington';
677
		$tag2->write();
678
679
		$flickrPhoto->FlickrTagTOs()->add($tag1);
680
		$flickrPhoto->FlickrTagTOs()->add($tag2);
681
		$flickrPhoto->write();
682
		$fieldValuesArray = $flickrPhoto->getFieldValuesAsArray();
683
		$actual = $fieldValuesArray['Photographer'];
684
		$this->assertEquals(array(), $actual);
685
686
		$actual = $fieldValuesArray['FlickrTagTOs'];
687
		$this->generateAssertionsFromArrayRecurse($actual);
688
689
		$expected = array(
690
			'0' => array(
691
				'RawValue' => 'Auckland'
692
			),
693
			'1' => array(
694
				'RawValue' => 'Wellington'
695
			)
696
		);
697
698
699
		$this->assertEquals($expected, $actual);
700
	}
701
702
703
	public function testUpdateCMSFieldsDatabject() {
704
		$flickrPhoto = $this->objFromFixture('FlickrPhotoTO', 'photo0001');
705
		$flickrPhoto->IndexingOff = false;
706
		$flickrPhoto->Title = 'Test title edited';
707
		$flickrPhoto->write();
708
		$fields = $flickrPhoto->getCMSFields();
709
710
		$tabset = $fields->findOrMakeTab('Root.ElasticaTerms');
711
		$tabNames = array();
712 View Code Duplication
		foreach($tabset->Tabs() as $tab) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
713
			$tabFields = array();
714
			foreach($tab->FieldList() as $field) {
715
				array_push($tabFields, $field->getName());
716
			}
717
			$expectedName = 'TermsFor' . $tab->getName();
0 ignored issues
show
Unused Code introduced by
$expectedName 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...
718
			//$expected = array($expectedName);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
719
			//$this->assertEquals($expected, $tabFields);
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
720
			array_push($tabNames, $tab->getName());
721
		}
722
		$expected = array('Description_stemmed', 'Description_shingles', 'Description_unstemmed',
723
			'ShutterSpeed_stemmed', 'TestMethod_stemmed', 'TestMethod_shingles', 'TestMethod_unstemmed',
724
			'TestMethodHTML_stemmed', 'TestMethodHTML_shingles', 'TestMethodHTML_unstemmed',
725
			'Title_stemmed', 'Title_autocomplete', 'Title_shingles', 'Title_unstemmed');
726
727
		$this->assertEquals($expected, $tabNames);
728
	}
729
730
731
	public function testUpdateCMSFieldsSiteTreeLive() {
732
		$page = $this->objFromFixture('SearchableTestPage', 'first');
733
		$page->IndexingOff = false;
734
		$page->Title = 'Test title edited';
735
		$page->write();
736
		$page->doPublish();
737
		$fields = $page->getCMSFields();
738
739
		$tabset = $fields->findOrMakeTab('Root.ElasticaTerms');
740
		$tabNames = array();
741 View Code Duplication
		foreach($tabset->Tabs() as $tab) {
742
			$tabFields = array();
743
			foreach($tab->FieldList() as $field) {
744
				array_push($tabFields, $field->getName());
745
			}
746
			array_push($tabNames, $tab->getName());
747
		}
748
		$expected = array(
749
			'Content_stemmed', 'Content_unstemmed', 'Link_stemmed',
750
			'Title_stemmed', 'Title_autocomplete', 'Title_shingles',
751
			'Title_unstemmed');
752
		$this->generateAssertionsFromArray1D($tabNames);
753
		$this->assertEquals($expected, $tabNames);
754
755
	}
756
757
758 View Code Duplication
	private function getResultsFor($query, $pageLength = 10) {
759
		$es = new ElasticSearcher();
760
		$es->setStart(0);
761
		$es->setPageLength($pageLength);
762
		$es->setClasses('FlickrPhotoTO');
763
		$fields = array('Title' => 1, 'Description' => 1);
764
		$resultList = $es->search($query, $fields)->getList();
765
		$this->assertEquals('SilverStripe\Elastica\ResultList', get_class($resultList));
766
		return $resultList;
767
	}
768
769
}
770