Completed
Push — dev2 ( bdf458...f6d9aa )
by Gordon
16:12
created

SearchableTest   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 764
Duplicated Lines 4.06 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 0%
Metric Value
wmc 40
lcom 2
cbo 11
dl 31
loc 764
ccs 0
cts 556
cp 0
rs 7.619

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 10 1
A testgetFieldValuesAsArrayFromFixtures() 0 23 1
A testBadFormatFields() 0 57 1
A testGetDateFields() 0 13 1
D testMapping() 0 145 8
A testGetType() 0 8 1
B testGetElasticaDocument() 0 27 1
B testElasticaResult() 0 30 2
A testDeleteNonExistentDoc() 0 16 2
A testUnpublishPublish() 0 12 1
B testUnpublishAlreadyPublisedhHideFromSearch() 0 42 1
A testUnpublishPublishHideFromSearch() 0 21 1
A testGetCMSFields() 0 6 1
A testNoSearchableFieldsConfigured() 0 14 2
A testNoSearchableFieldsConfiguredForHasManyRelation() 0 15 2
A testNoSearchableFieldsConfiguredForHasOneRelation() 0 15 2
A testSearchableMethodNotExist() 0 18 2
B testFieldsToElasticaConfig() 0 91 1
B testHasOneExistsSearchableToArray() 0 24 1
B testHasManyExistsSearchableToArray() 0 39 1
B testUpdateCMSFieldsDatabject() 10 26 3
B testUpdateCMSFieldsSiteTreeLive() 10 27 3
A getResultsFor() 10 10 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like SearchableTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SearchableTest, and based on these observations, apply Extract Interface, too.

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