1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* @package comments |
6
|
|
|
*/ |
7
|
|
|
class ElasticSearchPageControllerTest extends ElasticsearchFunctionalTestBase { |
8
|
|
|
|
9
|
|
|
public static $fixture_file = 'elastica/tests/lotsOfPhotos.yml'; |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
public function setUp() { |
13
|
|
|
parent::setUp(); |
14
|
|
|
$esp = new ElasticSearchPage(); |
15
|
|
|
$esp->Title = 'Search with aggregation'; |
16
|
|
|
$esp->Content = 'Example search page with aggregation'; |
17
|
|
|
$esp->Identifier = 'testwithagg'; |
18
|
|
|
$esp->IndexingOff = true; |
19
|
|
|
$esp->URLSegment = 'search'; |
20
|
|
|
$esp->SiteTreeOnly = false; |
21
|
|
|
$esp->ClassesToSearch = 'FlickrPhotoTO'; |
22
|
|
|
$esp->SearchHelper = 'FlickrPhotoTOElasticaSearchHelper'; |
23
|
|
|
$esp->write(); |
24
|
|
|
|
25
|
|
|
$esp2 = new ElasticSearchPage(); |
26
|
|
|
$esp2->Title = 'Search without aggregation'; |
27
|
|
|
$esp2->Content = 'Example search page'; |
28
|
|
|
$esp2->Identifier = 'testwithoutagg'; |
29
|
|
|
$esp2->IndexingOff = true; |
30
|
|
|
$esp2->URLSegment = 'search'; |
31
|
|
|
$esp2->SiteTreeOnly = false; |
32
|
|
|
$esp2->ClassesToSearch = 'FlickrPhotoTO'; |
33
|
|
|
$esp2->ContentForEmptySearch = 'Content for empty search'; |
34
|
|
|
$esp2->write(); |
35
|
|
|
|
36
|
|
|
#NOTE: how to edit extra extra fields programatically |
37
|
|
|
$extraFields = array('Searchable' => 1, 'SimilarSearchable' => 1, 'Active' => 1, |
38
|
|
|
'Weight' => 1); |
39
|
|
|
$esfs2 = $esp2->ElasticaSearchableFields(); |
40
|
|
|
foreach($esfs2 as $sf) { |
41
|
|
|
if($sf->Name == 'Title' || $sf->Name == 'Description') { |
42
|
|
|
$esfs2->remove($sf); |
43
|
|
|
$esfs2->add($sf, $extraFields); |
44
|
|
|
} |
45
|
|
|
} |
46
|
|
|
$esp2->write(); |
47
|
|
|
|
48
|
|
|
$esfs = $esp->ElasticaSearchableFields(); |
49
|
|
|
|
50
|
|
|
foreach($esfs as $sf) { |
51
|
|
|
if($sf->Name == 'Title' || $sf->Name == 'Description') { |
52
|
|
|
$esfs->remove($sf); |
53
|
|
|
$esfs->add($sf, $extraFields); |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
$esp->write(); |
57
|
|
|
$esp->publish('Stage', 'Live'); |
58
|
|
|
$esp2->publish('Stage', 'Live'); |
59
|
|
|
$this->ElasticSearchPage = $esp; |
60
|
|
|
$this->ElasticSearchPage2 = $esp2; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
public function testAggregationNoneSelected() { |
65
|
|
|
//SearchHelper |
66
|
|
|
|
67
|
|
|
$this->autoFollowRedirection = false; |
68
|
|
|
|
69
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
70
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
71
|
|
|
|
72
|
|
|
$url = $searchPageObj->Link(); |
73
|
|
|
$searchPage = $this->get($searchPageObj->URLSegment); |
74
|
|
|
$this->assertEquals(200, $searchPage->getStatusCode()); |
75
|
|
|
$url = rtrim($url, '/'); |
76
|
|
|
|
77
|
|
|
$response = $this->get($url); |
78
|
|
|
|
79
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
80
|
|
|
|
81
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 0, '(5)'); |
82
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 1, '(11)'); |
83
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 2, '(12)'); |
84
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 3, '(13)'); |
85
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 4, '(16)'); |
86
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 5, '(13)'); |
87
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 6, '(11)'); |
88
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.iso span.count', 7, '(19)'); |
89
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 0, '(12)'); |
90
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 1, '(11)'); |
91
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 2, '(11)'); |
92
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 3, '(20)'); |
93
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 4, '(12)'); |
94
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 5, '(17)'); |
95
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 6, '(17)'); |
96
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 0, '(17)'); |
97
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 1, '(15)'); |
98
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 2, '(17)'); |
99
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 3, '(10)'); |
100
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 4, '(18)'); |
101
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 5, '(1)'); |
102
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 6, '(10)'); |
103
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 7, '(12)'); |
104
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 0, '(21)'); |
105
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 1, '(23)'); |
106
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 2, '(17)'); |
107
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 3, '(16)'); |
108
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 4, '(23)'); |
109
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 0, '(9)'); |
110
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 1, '(31)'); |
111
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 2, '(16)'); |
112
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 3, '(39)'); |
113
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 4, '(5)'); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
|
117
|
|
|
public function testAggregationOneSelected() { |
118
|
|
|
//SearchHelper |
119
|
|
|
|
120
|
|
|
$this->autoFollowRedirection = false; |
121
|
|
|
|
122
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
123
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
124
|
|
|
|
125
|
|
|
$url = $searchPageObj->Link(); |
126
|
|
|
$searchPage = $this->get($searchPageObj->URLSegment); |
127
|
|
|
$this->assertEquals(200, $searchPage->getStatusCode()); |
128
|
|
|
$url = rtrim($url, '/'); |
129
|
|
|
$url .= '?ISO=400'; |
130
|
|
|
|
131
|
|
|
$response = $this->get($url); |
132
|
|
|
|
133
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
134
|
|
|
|
135
|
|
|
// These are less than in the no facets selected case, as expected |
136
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 0, '(2)'); |
137
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 1, '(1)'); |
138
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 2, '(2)'); |
139
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 3, '(1)'); |
140
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 4, '(3)'); |
141
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 5, '(1)'); |
142
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 6, '(3)'); |
143
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 0, '(3)'); |
144
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 1, '(2)'); |
145
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 2, '(2)'); |
146
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 3, '(1)'); |
147
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 4, '(2)'); |
148
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.shutter_speed span.count', 5, '(3)'); |
149
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 0, '(3)'); |
150
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 1, '(4)'); |
151
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 2, '(3)'); |
152
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 3, '(1)'); |
153
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 4, '(2)'); |
154
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 0, '(0)'); |
155
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 1, '(4)'); |
156
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 2, '(1)'); |
157
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 3, '(7)'); |
158
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 4, '(1)'); |
159
|
|
|
|
160
|
|
|
|
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
|
164
|
|
|
|
165
|
|
|
public function testAggregationTwoSelected() { |
166
|
|
|
//SearchHelper |
167
|
|
|
|
168
|
|
|
$this->autoFollowRedirection = false; |
169
|
|
|
|
170
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
171
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
172
|
|
|
|
173
|
|
|
$url = $searchPageObj->Link(); |
174
|
|
|
$searchPage = $this->get($searchPageObj->URLSegment); |
175
|
|
|
$this->assertEquals(200, $searchPage->getStatusCode()); |
176
|
|
|
$url = rtrim($url, '/'); |
177
|
|
|
$url .= '?ISO=400&ShutterSpeed=2%2F250'; |
178
|
|
|
|
179
|
|
|
$response = $this->get($url); |
180
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
181
|
|
|
|
182
|
|
|
// These are less than in the one facet selected case, as expected |
183
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 0, '(1)'); |
184
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.focal_length span.count', 1, '(2)'); |
185
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 0, '(1)'); |
186
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 1, '(1)'); |
187
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aperture span.count', 2, '(1)'); |
188
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 0, '(0)'); |
189
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 1, '(1)'); |
190
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 2, '(0)'); |
191
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 3, '(2)'); |
192
|
|
|
$this->assertSelectorStartsWithOrEquals('ul.aspect span.count', 4, '(0)'); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
|
196
|
|
|
public function testAggregationThreeSelected() { |
197
|
|
|
//SearchHelper |
198
|
|
|
|
199
|
|
|
$this->autoFollowRedirection = false; |
200
|
|
|
|
201
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
202
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
203
|
|
|
|
204
|
|
|
$url = $searchPageObj->Link(); |
205
|
|
|
$searchPage = $this->get($searchPageObj->URLSegment); |
206
|
|
|
$this->assertEquals(200, $searchPage->getStatusCode()); |
207
|
|
|
$url = rtrim($url, '/'); |
208
|
|
|
$url .= '?ISO=400&ShutterSpeed=2%2F250&Aspect=Vertical'; |
209
|
|
|
|
210
|
|
|
$response = $this->get($url); |
211
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
212
|
|
|
|
213
|
|
|
// These are less than in the one facet selected case, as expected |
214
|
|
|
$this->assertSelectorStartsWithOrEquals('span.count', 0, '(2)'); |
215
|
|
|
$this->assertSelectorStartsWithOrEquals('span.count', 1, '(1)'); |
216
|
|
|
$this->assertSelectorStartsWithOrEquals('span.count', 2, '(1)'); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
|
220
|
|
|
public function testQueryIsEmpty() { |
221
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
222
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
223
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
224
|
|
|
$response = $this->get($url); |
225
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
226
|
|
|
$this->assertSelectorStartsWithOrEquals('div.contentForEmptySearch', 0, |
227
|
|
|
$searchPageObj->ContentForEmptySearch); |
228
|
|
|
|
229
|
|
|
|
230
|
|
|
$url .= '?q='; |
231
|
|
|
$response = $this->get($url); |
232
|
|
|
$this->assertEquals(200, |
233
|
|
|
$response->getStatusCode()); |
234
|
|
|
$this->assertSelectorStartsWithOrEquals('div.contentForEmptySearch', 0, |
235
|
|
|
$searchPageObj->ContentForEmptySearch); |
236
|
|
|
|
237
|
|
|
$url .= 'farming'; |
238
|
|
|
$response = $this->get($url); |
239
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
240
|
|
|
$this->assertExactHTMLMatchBySelector('div.contentForEmptySearch', array()); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
View Code Duplication |
public function testQueryInSearchBoxForOneFormOnly() { |
|
|
|
|
244
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
245
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
246
|
|
|
$url .= "?q=Auckland&sfid=".$searchPageObj->Identifier; |
247
|
|
|
$response = $this->get($url); |
248
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
249
|
|
|
$this->assertAttributeHasExactValue('#ElasticSearchForm_SearchForm_q', 'q', |
250
|
|
|
'Auckland'); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
|
254
|
|
|
/* |
255
|
|
|
Check the search form attributes for autocomplete info |
256
|
|
|
*/ |
257
|
|
|
public function testSearchFormAutocompleteEnabled() { |
258
|
|
|
// prepeare autocomplete field |
259
|
|
|
$this->autoFollowRedirection = false; |
260
|
|
|
|
261
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
262
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
263
|
|
|
$searchPageObj->ClassesToSearch = 'FlickrPhotoTO'; |
264
|
|
|
$filter = array('ClazzName' => 'FlickrPhotoTO', 'Name' => 'Title'); |
265
|
|
|
$sfid = SearchableField::get()->filter($filter)->first()->ID; |
266
|
|
|
$searchPageObj->AutoCompleteFieldID = $sfid; |
267
|
|
|
$pageLength = 10; // the default |
268
|
|
|
$searchPageObj->ResultsPerPage = $pageLength; |
269
|
|
|
$searchPageObj->write(); |
270
|
|
|
$searchPageObj->publish('Stage', 'Live'); |
271
|
|
|
|
272
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
273
|
|
|
$response = $this->get($url); |
274
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
275
|
|
|
|
276
|
|
|
// note, need to test with strings |
277
|
|
|
$expected = array( |
278
|
|
|
'data-autocomplete' => 'true', |
279
|
|
|
'data-autocomplete-field' => 'Title', |
280
|
|
|
'data-autocomplete-field' => 'Title', |
281
|
|
|
'data-autocomplete-classes' => 'FlickrPhotoTO', |
282
|
|
|
'data-autocomplete-sitetree' => '0', |
283
|
|
|
'data-autocomplete-source' => '/search-2/' |
284
|
|
|
); |
285
|
|
|
$this->assertAttributesHaveExactValues('#ElasticSearchForm_SearchForm_q', $expected); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
|
289
|
|
|
public function testTemplateOverrideExtension() { |
290
|
|
|
|
291
|
|
|
if(!class_exists('PageControllerTemplateOverrideExtension')) { |
292
|
|
|
$this->markTestSkipped('PageControllerTemplateOverrideExtension not installed'); |
|
|
|
|
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
Page_Controller::remove_extension('PageControllerTemplateOverrideExtension'); |
296
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
297
|
|
|
|
298
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
299
|
|
|
$response = $this->get($url); |
|
|
|
|
300
|
|
|
$this->assertEquals(0, PageControllerTemplateOverrideExtension::getTemplateOverrideCounter()); |
301
|
|
|
Page_Controller::add_extension('PageControllerTemplateOverrideExtension'); |
302
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
303
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
304
|
|
|
$response = $this->get($url); |
|
|
|
|
305
|
|
|
$this->assertEquals(1, PageControllerTemplateOverrideExtension::getTemplateOverrideCounter()); |
306
|
|
|
|
307
|
|
|
$url .= "/similar/FlickrPhotoTO/77"; |
308
|
|
|
$response = $this->get($url); |
|
|
|
|
309
|
|
|
|
310
|
|
|
//check the template override method was called |
311
|
|
|
$this->assertEquals(2, PageControllerTemplateOverrideExtension::getTemplateOverrideCounter()); |
312
|
|
|
|
313
|
|
|
Page_Controller::remove_extension('PageControllerTemplateOverrideExtension'); |
314
|
|
|
|
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
|
318
|
|
View Code Duplication |
public function testSimilarNotSearchable() { |
|
|
|
|
319
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
320
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
321
|
|
|
$url .= "/similar/Member/1"; |
322
|
|
|
$response = $this->get($url); |
323
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
324
|
|
|
|
325
|
|
|
$this->assertSelectorStartsWithOrEquals('div.error', 0, |
326
|
|
|
'Class Member is either not found or not searchable'); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
|
330
|
|
View Code Duplication |
public function testSimilarNull() { |
|
|
|
|
331
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
332
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
333
|
|
|
$url .= "/similar/Member/0"; |
334
|
|
|
$response = $this->get($url); |
335
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
336
|
|
|
|
337
|
|
|
$this->assertSelectorStartsWithOrEquals('div.error', 0, |
338
|
|
|
'Class Member is either not found or not searchable'); |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
|
342
|
|
View Code Duplication |
public function testSimilarClassDoesNotExist() { |
|
|
|
|
343
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
344
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
345
|
|
|
$url .= "/similar/asdfsadfsfd/4"; |
346
|
|
|
$response = $this->get($url); |
347
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
348
|
|
|
$this->assertSelectorStartsWithOrEquals('div.error', 0, |
349
|
|
|
'Class asdfsadfsfd is either not found or not searchable'); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
|
353
|
|
View Code Duplication |
public function testSimilarSearchServerDown() { |
|
|
|
|
354
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
355
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
356
|
|
|
$url .= "/similar/FlickrPhotoTO/77?ServerDown=1"; |
357
|
|
|
$response = $this->get($url); |
|
|
|
|
358
|
|
|
$this->assertSelectorStartsWithOrEquals('div.error', 0, |
359
|
|
|
'Unable to connect to search server'); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
|
363
|
|
View Code Duplication |
public function testNormalSearchServerDown() { |
|
|
|
|
364
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
365
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
366
|
|
|
$url .= "?q=Zealand&ServerDown=1"; |
367
|
|
|
$response = $this->get($url); |
|
|
|
|
368
|
|
|
$this->assertSelectorStartsWithOrEquals('div.error', 0, |
369
|
|
|
'Unable to connect to search server'); |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
|
373
|
|
|
public function testSimilarValid() { |
374
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
375
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
376
|
|
|
$url .= "/similar/FlickrPhotoTO/77"; |
377
|
|
|
$response = $this->get($url); |
|
|
|
|
378
|
|
|
$ctr = 0; |
379
|
|
|
|
380
|
|
|
// results vary slightly due to sharding, hence check for a string instead of absolute results |
381
|
|
View Code Duplication |
while ($ctr < 18) { |
|
|
|
|
382
|
|
|
$this->assertSelectorContains('div.searchResult a', $ctr, 'New Orleans, Southern Pacific'); |
383
|
|
|
$ctr++; |
384
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult a', $ctr, 'Similar'); |
385
|
|
|
$ctr++; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
|
391
|
|
|
/* |
392
|
|
|
Search for New Zealind and get search results for New Zealand. Show option to click on |
393
|
|
|
actual search of New Zealind |
394
|
|
|
*/ |
395
|
|
|
public function testSuggestion() { |
396
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
397
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
398
|
|
|
$url .= "?q=New%20Zealind&TestMode=true"; |
399
|
|
|
$response = $this->get($url); |
400
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
401
|
|
|
$ctr = 0; |
402
|
|
|
$this->assertSelectorStartsWithOrEquals('p.showingResultsForMsg', 0, 'Showing results for '); |
403
|
|
|
$this->assertSelectorStartsWithOrEquals('p.showingResultsForMsg a', 0, 'New '); |
404
|
|
|
$this->assertSelectorStartsWithOrEquals('p.showingResultsForMsg strong.hl', 0, 'Zealand'); |
405
|
|
|
|
406
|
|
|
$this->assertSelectorStartsWithOrEquals('p.searchOriginalQueryMsg', 0, 'Search instead for '); |
407
|
|
|
$this->assertSelectorStartsWithOrEquals('p.searchOriginalQueryMsg a', 0, 'New Zealind'); |
408
|
|
|
|
409
|
|
|
// simulate following the link to search for 'New Zealind' |
410
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
411
|
|
|
$url .= '?q=New Zealind&is=1'; |
412
|
|
|
$response = $this->get($url); |
413
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
414
|
|
|
|
415
|
|
|
// results vary slightly due to sharding, hence check for a string instead of absolute results |
416
|
|
View Code Duplication |
while ($ctr < 18) { |
|
|
|
|
417
|
|
|
$this->assertSelectorContains('div.searchResult a', $ctr, 'New', true); |
418
|
|
|
$ctr++; |
419
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult a', $ctr, 'Similar'); |
420
|
|
|
$ctr++; |
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
|
424
|
|
|
|
425
|
|
|
//no suggestions shown, the is flag prevents this |
426
|
|
|
$this->assertExactHTMLMatchBySelector('p.showingResultsForMsg', array()); |
427
|
|
|
$this->assertExactHTMLMatchBySelector('p.searchOriginalQueryMsg', array()); |
428
|
|
|
|
429
|
|
|
// reconfirm lack of suggestions when searching for 'New Zealand' with the is flag set |
430
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
431
|
|
|
$url .= '?q=New Zealand&is=1'; |
432
|
|
|
$response = $this->get($url); |
433
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
434
|
|
|
$this->assertExactHTMLMatchBySelector('p.showingResultsForMsg', array()); |
435
|
|
|
$this->assertExactHTMLMatchBySelector('p.searchOriginalQueryMsg', array()); |
436
|
|
|
} |
437
|
|
|
/* |
438
|
|
|
<p class="showingResultsForMsg">Showing results for <a href="./?q=New Zealand">New <strong class="hl">Zealand</strong></a></p> |
439
|
|
|
<p class="searchOriginalQueryMsg">Search instead for <a href="/search-2?q=New Zealind&is=1">New Zealind</a></p> |
440
|
|
|
|
441
|
|
|
|
442
|
|
|
*/ |
443
|
|
|
|
444
|
|
|
|
445
|
|
View Code Duplication |
public function testSearchOnePageNoAggregation() { |
|
|
|
|
446
|
|
|
$this->enableHighlights(); |
447
|
|
|
$this->autoFollowRedirection = false; |
448
|
|
|
$searchTerm = 'mineralogy'; |
449
|
|
|
|
450
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
451
|
|
|
$searchPageObj = $this->ElasticSearchPage2; |
452
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
453
|
|
|
$url = $url.'?q='.$searchTerm; |
454
|
|
|
$response = $this->get($url); |
455
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
456
|
|
|
|
457
|
|
|
//There are 3 results for mineralogy |
458
|
|
|
$this->assertSelectorStartsWithOrEquals('div.resultsFound', 0, |
459
|
|
|
"Page 1 of 1 (3 results found"); |
460
|
|
|
|
461
|
|
|
|
462
|
|
|
//Check all the result highlights for mineralogy matches |
463
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 1, 'mineralogy'); |
464
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 2, 'Mineralogy'); |
465
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 3, 'mineralogy'); |
466
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 4, 'Mineralogy'); |
467
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 5, 'mineralogy'); |
468
|
|
|
|
469
|
|
|
|
470
|
|
|
// Check the start text of the 3 results |
471
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 0, |
472
|
|
|
"Image taken from page 273 of"); |
473
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 1, |
474
|
|
|
'Image taken from page 69 of'); |
475
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 2, |
476
|
|
|
'Image taken from page 142 of'); |
477
|
|
|
|
478
|
|
|
// No span.count means no aggregations |
479
|
|
|
$this->assertExactHTMLMatchBySelector('span.count', array()); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
|
483
|
|
|
/* When a search is posted, should redirect to the same URL with the search term attached. This |
484
|
|
|
means that searches can be bookmarked if so required */ |
485
|
|
|
public function testRedirection() { |
486
|
|
|
$this->autoFollowRedirection = false; |
487
|
|
|
|
488
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
489
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
490
|
|
|
$url = $searchPageObj->Link(); |
491
|
|
|
$searchPage = $this->get($searchPageObj->URLSegment); |
492
|
|
|
$this->assertEquals(200, $searchPage->getStatusCode()); |
493
|
|
|
|
494
|
|
|
$response = $this->submitForm("ElasticSearchForm_SearchForm", null, array( |
495
|
|
|
'q' => 'New Zealand' |
496
|
|
|
)); |
497
|
|
|
|
498
|
|
|
$url = rtrim($url, '/'); |
499
|
|
|
$this->assertEquals(302, $response->getStatusCode()); |
500
|
|
|
$this->assertEquals($url . '?q=New Zealand&sfid=testwithagg', $response->getHeader('Location')); |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
|
504
|
|
|
/* |
505
|
|
|
Add test for redirection of /search/?q=XXX to /search?q=XXX |
506
|
|
|
*/ |
507
|
|
|
|
508
|
|
|
|
509
|
|
|
/* |
510
|
|
|
Test a search for an uncommon term, no pagination here |
511
|
|
|
*/ |
512
|
|
View Code Duplication |
public function testSearchOnePage() { |
|
|
|
|
513
|
|
|
$this->enableHighlights(); |
514
|
|
|
$this->autoFollowRedirection = false; |
515
|
|
|
$searchTerm = 'mineralogy'; |
516
|
|
|
|
517
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
518
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
519
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
520
|
|
|
$url = $url.'?q='.$searchTerm; |
521
|
|
|
$response = $this->get($url); |
522
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
523
|
|
|
|
524
|
|
|
//There are 3 results for mineralogy |
525
|
|
|
$this->assertSelectorStartsWithOrEquals('div.resultsFound', 0, |
526
|
|
|
"Page 1 of 1 (3 results found"); |
527
|
|
|
|
528
|
|
|
|
529
|
|
|
//Check all the result highlights for mineralogy matches |
530
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 1, 'mineralogy'); |
531
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 2, 'Mineralogy'); |
532
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 3, 'mineralogy'); |
533
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 4, 'Mineralogy'); |
534
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 5, 'mineralogy'); |
535
|
|
|
|
536
|
|
|
|
537
|
|
|
// Check the start text of the 3 results |
538
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 0, |
539
|
|
|
"Image taken from page 273 of"); |
540
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 1, |
541
|
|
|
'Image taken from page 69 of'); |
542
|
|
|
$this->assertSelectorStartsWithOrEquals('div.searchResult h4 a', 2, |
543
|
|
|
'Image taken from page 142 of'); |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
|
547
|
|
|
|
548
|
|
|
/* |
549
|
|
|
Test a search for a common term, in order to induce pagination |
550
|
|
|
*/ |
551
|
|
|
public function testSiteTreeSearch() { |
552
|
|
|
$this->enableHighlights(); |
553
|
|
|
$this->autoFollowRedirection = false; |
554
|
|
|
|
555
|
|
|
//One of the default pages |
556
|
|
|
$searchTerm = 'Contact Us'; |
557
|
|
|
|
558
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
559
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
560
|
|
|
$searchPageObj->SiteTreeOnly = true; |
561
|
|
|
$searchPageObj->write(); |
562
|
|
|
$searchPageObj->publish('Stage', 'Live'); |
563
|
|
|
|
564
|
|
|
|
565
|
|
|
$pageLength = 10; // the default |
566
|
|
|
$searchPageObj->ResultsPerPage = $pageLength; |
567
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
568
|
|
|
$url = $url . '?q=' . $searchTerm; |
569
|
|
|
$firstPageURL = $url; |
|
|
|
|
570
|
|
|
$response = $this->get($url); |
571
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
572
|
|
|
|
573
|
|
|
//There are 2 results for 'Contact Us', as 'About Us' has an Us in the title. |
574
|
|
|
$this->assertSelectorStartsWithOrEquals('div.resultsFound', 0, |
575
|
|
|
"Page 1 of 1 (2 results found in"); |
576
|
|
|
|
577
|
|
|
//The classname 'searchResults' appears to be matching the contained 'searchResult', hence |
578
|
|
|
//the apparently erroneous addition of 1 to the required 2 |
579
|
|
|
$this->assertNumberOfNodes('div.searchResult', 3); |
580
|
|
|
|
581
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 0, 'Contact'); // CONTACT US |
582
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 1, 'Us'); // Contact US |
583
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 2, 'Us'); // About US |
584
|
|
|
|
585
|
|
|
} |
586
|
|
|
|
587
|
|
|
|
588
|
|
|
|
589
|
|
|
/* |
590
|
|
|
Test a search for a common term, in order to induce pagination |
591
|
|
|
*/ |
592
|
|
|
public function testSearchSeveralPagesPage() { |
593
|
|
|
$this->enableHighlights(); |
594
|
|
|
$this->autoFollowRedirection = false; |
595
|
|
|
$searchTerm = 'railroad'; |
596
|
|
|
|
597
|
|
|
//Note pages need to be published, by default fixtures only reside in Stage |
598
|
|
|
$searchPageObj = $this->ElasticSearchPage; |
599
|
|
|
$pageLength = 10; // the default |
600
|
|
|
$searchPageObj->ResultsPerPage = $pageLength; |
601
|
|
|
$url = rtrim($searchPageObj->Link(), '/'); |
602
|
|
|
$url = $url . '?q=' . $searchTerm; |
603
|
|
|
$firstPageURL = $url; |
604
|
|
|
$response = $this->get($url); |
605
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
606
|
|
|
|
607
|
|
|
//There are 3 results for mineralogy |
608
|
|
|
$this->assertSelectorStartsWithOrEquals('div.resultsFound', 0, |
609
|
|
|
"Page 1 of 2 (11 results found in"); |
610
|
|
|
|
611
|
|
|
//The classname 'searchResults' appears to be matching the contained 'searchResult', hence |
612
|
|
|
//the apparently erroneous addition of 1 to the required 10 |
613
|
|
|
$this->assertNumberOfNodes('div.searchResult', 11); |
614
|
|
|
|
615
|
|
|
//Check for a couple of highlighed 'Railroad' terms |
616
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 0, 'Railroad'); |
617
|
|
|
$this->assertSelectorStartsWithOrEquals('strong.hl', 1, 'Railroad'); |
618
|
|
|
|
619
|
|
|
$this->assertSelectorStartsWithOrEquals('div.pagination a', 0, '2'); |
620
|
|
|
$this->assertSelectorStartsWithOrEquals('div.pagination a.next', 0, '→'); |
621
|
|
|
|
622
|
|
|
$resultsP1 = $this->collateSearchResults(); |
623
|
|
|
|
624
|
|
|
$page2url = $url . '&start=' . $pageLength; |
625
|
|
|
|
626
|
|
|
//Check pagination on page 2 |
627
|
|
|
$response2 = $this->get($page2url); |
628
|
|
|
$this->assertEquals(200, $response2->getStatusCode()); |
629
|
|
|
|
630
|
|
|
//FIXME pluralisation probably needs fixed here, change test later acoordingly |
631
|
|
|
$this->assertSelectorStartsWithOrEquals('div.resultsFound', 0, |
632
|
|
|
"Page 2 of 2 (11 results found in"); |
633
|
|
|
|
634
|
|
|
//The classname 'searchResults' appears to be matching the contained 'searchResult', hence |
635
|
|
|
//the apparently erroneous addition of 1 to the required 1 |
636
|
|
|
$this->assertNumberOfNodes('div.searchResult', 2); |
637
|
|
|
|
638
|
|
|
$this->assertSelectorStartsWithOrEquals('div.pagination a', 1, '1'); |
639
|
|
|
$this->assertSelectorStartsWithOrEquals('div.pagination a.prev', 0, '←'); |
640
|
|
|
|
641
|
|
|
$resultsP2 = $this->collateSearchResults(); |
642
|
|
|
|
643
|
|
|
$resultsFrom2Pages = array_merge($resultsP1, $resultsP2); |
644
|
|
|
|
645
|
|
|
//there are 11 results in total |
646
|
|
|
$this->assertEquals(11, sizeof($resultsFrom2Pages)); |
647
|
|
|
|
648
|
|
|
//increase the number of results and assert that they are the same as per pages 1,2 joined |
649
|
|
|
$searchPageObj->ResultsPerPage = 20; |
650
|
|
|
$searchPageObj->write(); |
651
|
|
|
$searchPageObj->publish('Stage','Live'); |
652
|
|
|
$response3 = $this->get($firstPageURL); |
|
|
|
|
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
|
656
|
|
|
private function enableHighlights() { |
657
|
|
|
foreach (SearchableField::get()->filter('Name', 'Title') as $sf) { |
658
|
|
|
$sf->ShowHighlights = true; |
659
|
|
|
$sf->write(); |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
foreach (SearchableField::get()->filter('Name', 'Content') as $sf) { |
663
|
|
|
$sf->ShowHighlights = true; |
664
|
|
|
$sf->write(); |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
//FIXME - do this with ORM |
668
|
|
|
//$sql = "UPDATE ElasticSearchPage_ElasticaSearchableFields SET " |
669
|
|
|
} |
670
|
|
|
} |
671
|
|
|
|
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.