Passed
Push — hans/logtests ( 76c086...71695d )
by Simon
06:24 queued 02:27
created

BaseIndexTest::testFacetFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
eloc 33
c 5
b 1
f 0
dl 0
loc 37
rs 9.392
cc 1
nc 1
nop 0
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Tests;
5
6
use CircleCITestIndex;
7
use Firesphere\SolrSearch\Compat\SubsitesExtension;
8
use Firesphere\SolrSearch\Extensions\DataObjectExtension;
9
use Firesphere\SolrSearch\Helpers\Synonyms;
10
use Firesphere\SolrSearch\Indexes\BaseIndex;
11
use Firesphere\SolrSearch\Queries\BaseQuery;
12
use Firesphere\SolrSearch\Results\SearchResult;
13
use Firesphere\SolrSearch\Stores\FileConfigStore;
14
use Firesphere\SolrSearch\Tasks\SolrConfigureTask;
15
use Firesphere\SolrSearch\Tasks\SolrIndexTask;
16
use Page;
17
use Psr\Log\NullLogger;
18
use SilverStripe\CMS\Model\SiteTree;
19
use SilverStripe\Control\Director;
20
use SilverStripe\Control\HTTPRequest;
21
use SilverStripe\Control\NullHTTPRequest;
22
use SilverStripe\Core\Injector\Injector;
23
use SilverStripe\Dev\Debug;
24
use SilverStripe\Dev\SapphireTest;
25
use SilverStripe\ORM\ArrayList;
26
use SilverStripe\ORM\DataObject;
27
use SilverStripe\ORM\PaginatedList;
28
use SilverStripe\Security\DefaultAdminService;
29
use SilverStripe\View\ArrayData;
30
use Solarium\Component\Result\Highlighting\Highlighting;
31
use Solarium\Core\Client\Client;
32
33
class BaseIndexTest extends SapphireTest
34
{
35
    protected static $fixture_file = '../fixtures/DataResolver.yml';
36
    /**
37
     * @var array
38
     */
39
    protected static $extra_dataobjects = [
40
        TestObject::class,
41
        TestPage::class,
42
        TestRelationObject::class,
43
    ];
44
45
    /**
46
     * @var array
47
     */
48
    protected static $required_extensions = [
49
        DataObject::class => [DataObjectExtension::class],
50
        BaseIndex::class  => [SubsitesExtension::class],
51
    ];
52
53
    /**
54
     * @var BaseIndex
55
     */
56
    protected $index;
57
58
    public function testConstruct()
59
    {
60
        $this->assertInstanceOf(Client::class, $this->index->getClient());
61
        $this->assertCount(1, $this->index->getClasses());
62
        $this->assertCount(2, $this->index->getFulltextFields());
63
        $this->assertContains(SiteTree::class, $this->index->getClasses());
64
    }
65
66
    public function testInit()
67
    {
68
        $this->assertNull($this->index->init());
69
        $this->assertNotEmpty($this->index->getFulltextFields());
70
        $this->assertNotEmpty($this->index->getFieldsForIndexing());
71
        $expected = [
72
            'Title',
73
            'Content',
74
            'ParentID',
75
            'SubsiteID',
76
            'Created',
77
        ];
78
79
        $this->assertEquals($expected, array_values($this->index->getFieldsForIndexing()));
80
81
        $index = new TestIndexTwo();
82
83
        $this->assertCount(3, $index->getFulltextFields());
84
        $this->assertCount(1, $index->getFacetFields());
85
    }
86
87
    public function testFacetFields()
88
    {
89
        /** @var Page $parent */
90
        $parent = $this->objFromFixture(Page::class, 'homepage');
91
        $id = $parent->write();
92
        $parent->publishRecursive();
93
        $page1 = Page::create(['Title' => 'Test 1', 'ParentID' => $id, 'ShowInSearch' => true]);
94
        $page1->write();
95
        $page1->publishRecursive();
96
        $page2 = Page::create(['Title' => 'Test 2', 'ParentID' => $id, 'ShowInSearch' => true]);
97
        $page2->write();
98
        $page2->publishRecursive();
99
        $task = new SolrIndexTask();
100
        $index = new TestIndex();
101
        $request = new HTTPRequest('GET', 'dev/tasks/SolrIndexTask', ['index' => TestIndex::class]);
102
        $task->run($request);
103
        $facets = $index->getFacetFields();
104
        $this->assertEquals([
105
            'Title' => 'Parent',
106
            'Field' => 'ParentID'
107
        ], $facets[SiteTree::class]);
108
        $query = new BaseQuery();
109
        $query->addTerm('Test');
110
        $clientQuery = $index->buildSolrQuery($query);
111
        $this->arrayHasKey('facet-Parent', $clientQuery->getFacetSet()->getFacets());
112
        $result = $index->doSearch($query);
113
        $this->assertInstanceOf(ArrayData::class, $result->getFacets());
114
        $facets = $result->getFacets();
115
        /** @var ArrayList $parents */
116
        $parents = $facets->Parent;
117
        $this->assertEquals('Home', $parents->first()->Title);
118
        $this->assertEquals(2, $parents->first()->FacetCount);
119
        $this->assertCount(1, $parents);
120
        $query->addFacetFilter('Parent', $id);
121
        $result = $index->buildSolrQuery($query);
122
        $filterQuery = $result->getFilterQuery('facet-Parent');
123
        $this->assertEquals('SiteTree_ParentID:' . $id, $filterQuery->getQuery());
124
        $query->setHighlight(['Test']);
125
        $result = $index->doSearch($query);
126
        $this->assertInstanceOf(Highlighting::class, $result->getHighlight());
127
    }
128
129
    public function testStoredFields()
130
    {
131
        $ftsFields = $this->index->getFulltextFields();
132
        $this->index->addStoredField('Test');
133
        $fields = $this->index->getStoredFields();
134
135
        $this->assertContains('Test', $fields);
136
137
        $this->index->setStoredFields(['Test', 'Test1']);
138
139
        $this->assertEquals(['Test', 'Test1'], $this->index->getStoredFields());
140
141
        $this->index->setFulltextFields($ftsFields);
142
    }
143
144
    public function testGetSynonyms()
145
    {
146
        $this->assertEquals(Synonyms::getSynonymsAsString(), $this->index->getSynonyms());
147
148
        $this->assertEmpty(trim($this->index->getSynonyms(false)));
149
    }
150
151
    public function testIndexName()
152
    {
153
        $this->assertEquals('TestIndex', $this->index->getIndexName());
154
    }
155
156
    public function testUploadConfig()
157
    {
158
        $config = [
159
            'mode' => 'file',
160
            'path' => '.solr'
161
        ];
162
163
        /** @var FileConfigStore $configStore */
164
        $configStore = Injector::inst()->create(FileConfigStore::class, $config);
165
166
        $this->index->uploadConfig($configStore);
167
168
        $this->assertFileExists(Director::baseFolder() . '/.solr/TestIndex/conf/schema.xml');
169
        $this->assertFileExists(Director::baseFolder() . '/.solr/TestIndex/conf/synonyms.txt');
170
        $this->assertFileExists(Director::baseFolder() . '/.solr/TestIndex/conf/stopwords.txt');
171
172
        $xml = file_get_contents(Director::baseFolder() . '/.solr/TestIndex/conf/schema.xml');
173
        $this->assertContains(
174
            '<field name=\'SiteTree_Title\' type=\'string\' indexed=\'true\' stored=\'true\' multiValued=\'false\'/>',
175
            $xml
176
        );
177
178
        $original = $configStore->getConfig();
179
        $configStore->setConfig([]);
180
        $this->assertEquals([], $configStore->getConfig());
181
        // Unhappy path, the config is not updated
182
        $this->assertNotEquals($original, $configStore->getConfig());
183
    }
184
185
    public function testGetFieldsForIndexing()
186
    {
187
        $expected = [
188
            'Title',
189
            'Content',
190
            'ParentID',
191
            'SubsiteID',
192
            'Created',
193
        ];
194
        $this->assertEquals($expected, array_values($this->index->getFieldsForIndexing()));
195
    }
196
197
    public function testGetSetClient()
198
    {
199
        $client = $this->index->getClient();
200
        // set client to something stupid
201
        $this->index->setClient('test');
202
        $this->assertEquals('test', $this->index->getClient());
203
        $this->index->setClient($client);
204
        $this->assertInstanceOf(Client::class, $this->index->getClient());
205
    }
206
207
    public function testDoSearch()
208
    {
209
        $index = new CircleCITestIndex();
210
211
        $query = new BaseQuery();
212
        $query->addTerm('Home');
213
214
        $result = $index->doSearch($query);
215
        $this->assertInstanceOf(SearchResult::class, $result);
216
        $this->assertEquals(1, $result->getTotalItems());
217
218
        $admin = singleton(DefaultAdminService::class)->findOrCreateDefaultAdmin();
219
        $this->loginAs($admin);
220
        // Result should be the same for now
221
        $result2 = $index->doSearch($query);
222
        $this->assertEquals($result, $result2);
223
224
        $query->addClass(SiteTree::class);
225
226
        $result3 = $index->doSearch($query);
227
        $request = new NullHTTPRequest();
228
        $this->assertInstanceOf(PaginatedList::class, $result3->getPaginatedMatches($request));
229
        $this->assertEquals($result3->getTotalItems(), $result3->getPaginatedMatches($request)->getTotalItems());
230
        $this->assertInstanceOf(ArrayData::class, $result3->getFacets());
231
        $this->assertInstanceOf(ArrayList::class, $result3->getSpellcheck());
232
        $this->assertInstanceOf(Highlighting::class, $result3->getHighlight());
233
234
        $result3->setCustomisedMatches([]);
235
        $this->assertInstanceOf(ArrayList::class, $result3->getMatches());
236
        $this->assertCount(0, $result3->getMatches());
237
238
        $index = new CircleCITestIndex();
239
        $query = new BaseQuery();
240
        $query->addTerm('Home', ['SiteTree_Title'], 5);
241
        $result4 = $index->doSearch($query);
242
243
        $this->assertContains('SiteTree_Title:Home^5.0', $index->getQueryFactory()->getBoostTerms());
244
        $this->assertContains('Home', $index->getQueryTerms());
245
        $this->assertEquals(1, $result4->getTotalItems());
246
247
        $index = new CircleCITestIndex();
248
        $query = new BaseQuery();
249
        $query->addTerm('Home', ['SiteTree.Title'], 3);
250
        $result4 = $index->doSearch($query);
251
252
        $this->assertContains('SiteTree_Title:Home^3.0', $index->getQueryFactory()->getBoostTerms());
253
        $this->assertContains('Home', $index->getQueryTerms());
254
        $this->assertEquals(1, $result4->getTotalItems());
255
256
        $index = new CircleCITestIndex();
257
        $query = new BaseQuery();
258
        $query->addTerm('Home', [], 0, true);
259
        $index->doSearch($query);
260
261
        $this->assertContains('Home~', $index->getQueryTerms());
262
263
        $index = new CircleCITestIndex();
264
        $query = new BaseQuery();
265
        $query->addTerm('Home', [], 0, 2);
266
        $index->doSearch($query);
267
268
        $this->assertContains('Home~2', $index->getQueryTerms());
269
    }
270
271
    public function testGetFieldsForSubsites()
272
    {
273
        $this->assertContains('SubsiteID', $this->index->getFilterFields());
274
    }
275
276
    public function testSetFacets()
277
    {
278
        $this->index->addFacetField(Page::class, ['Title' => 'Title', 'Field' => 'Content']);
279
280
        $expected = [
281
            SiteTree::class => [
282
                'Title' => 'Parent',
283
                'Field' => 'ParentID'
284
            ],
285
            Page::class     => [
286
                'Title' => 'Title',
287
                'Field' => 'Content'
288
            ]
289
        ];
290
        $this->assertEquals($expected, $this->index->getFacetFields());
291
    }
292
293
    public function testAddCopyField()
294
    {
295
        $this->index->addCopyField('mycopyfield', ['Content']);
296
        $expected = [
297
            '_text'       => ['*'],
298
            'mycopyfield' => ['Content']
299
        ];
300
        $this->assertEquals($expected, $this->index->getCopyFields());
301
    }
302
303
    protected function setUp()
304
    {
305
        $task = new SolrConfigureTask();
306
        $task->setLogger(new NullLogger());
307
        $task->run(new NullHTTPRequest());
308
309
        $this->index = Injector::inst()->get(TestIndex::class, false);
310
311
        parent::setUp();
312
    }
313
}
314