Passed
Push — sheepy/introspection ( 69e16c...c6c7ca )
by Marco
05:28
created

BaseIndexTest::testFacetFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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