Issues (186)

tests/SolrIndexSubsitesTest.php (4 issues)

1
<?php
2
3
namespace SilverStripe\FullTextSearch\Tests;
4
5
use Apache_Solr_Document;
6
use Page;
0 ignored issues
show
The type Page was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use SilverStripe\Assets\File;
8
use SilverStripe\Assets\Image;
9
use SilverStripe\CMS\Model\SiteTree;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Core\Injector\Injector;
12
use SilverStripe\Dev\SapphireTest;
13
use SilverStripe\FullTextSearch\Search\FullTextSearch;
14
use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateImmediateProcessor;
15
use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateProcessor;
16
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
17
use SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites;
18
use SilverStripe\FullTextSearch\Solr\Services\Solr4Service;
19
use SilverStripe\FullTextSearch\Tests\SolrIndexSubsitesTest\SolrIndexSubsitesTest_Index;
20
use SilverStripe\FullTextSearch\Tests\SolrIndexVersionedTest\SolrDocumentMatcher;
0 ignored issues
show
The type SilverStripe\FullTextSea...est\SolrDocumentMatcher was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use SilverStripe\ORM\DataObject;
22
use SilverStripe\Subsites\Model\Subsite;
0 ignored issues
show
The type SilverStripe\Subsites\Model\Subsite was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use SilverStripe\Versioned\Versioned;
24
25
/**
26
 * Subsite specific solr testing
27
 */
28
class SolrIndexSubsitesTest extends SapphireTest
29
{
30
    protected static $fixture_file = 'SolrIndexSubsitesTest/SolrIndexSubsitesTest.yml';
31
32
    /**
33
     * @var SolrIndexSubsitesTest_Index
34
     */
35
    private static $index = null;
36
37
    protected $server = null;
38
39
    protected function setUp()
40
    {
41
        // Prevent parent::setUp() crashing on db build
42
        if (!class_exists(Subsite::class)) {
43
            static::$fixture_file = null;
44
        }
45
46
        parent::setUp();
47
48
        if (!class_exists(Subsite::class)) {
49
            $this->markTestSkipped("These tests need the Subsite module installed to run");
50
        }
51
52
        $this->server = $_SERVER;
53
54
        if (self::$index === null) {
55
            self::$index = singleton(SolrIndexSubsitesTest_Index::class);
56
        }
57
58
        Config::modify()->set(Injector::class, SearchUpdateProcessor::class, [
59
            'class' => SearchUpdateImmediateProcessor::class,
60
        ]);
61
62
        FullTextSearch::force_index_list(self::$index);
63
        SearchUpdater::clear_dirty_indexes();
64
    }
65
66
    protected function tearDown()
67
    {
68
        if ($this->server) {
69
            $_SERVER = $this->server;
70
            $this->server = null;
71
        }
72
        parent::tearDown();
73
    }
74
75
    protected function getServiceMock()
76
    {
77
        return $this->getMockBuilder(Solr4Service::class)
78
            ->setMethods(['addDocument', 'commit'])
79
            ->getMock();
80
    }
81
82
    /**
83
     * @param DataObject $object Item being added
84
     * @param int $subsiteID
85
     * @param string $stage
86
     * @return string
87
     */
88
    protected function getExpectedDocumentId($object, $subsiteID, $stage = null)
89
    {
90
        $id = $object->ID;
91
        $class = DataObject::getSchema()->baseDataClass($object);
92
        $variants = array();
93
94
        // Check subsite
95
        if (class_exists(Subsite::class)
96
            && DataObject::getSchema()->hasOneComponent($object->getClassName(), 'Subsite')
97
        ) {
98
            $variants[] = '"SearchVariantSubsites":"' . $subsiteID . '"';
99
        }
100
101
        // Check versioned
102
        if ($stage) {
103
            $variants[] = '"SearchVariantVersioned":"' . $stage . '"';
104
        }
105
        return $id . '-' . $class . '-{' . implode(',', $variants) . '}';
106
    }
107
108
    public function testPublishing()
109
    {
110
        // Setup mocks
111
        $serviceMock = $this->getServiceMock();
112
        self::$index->setService($serviceMock);
113
114
        $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
115
116
        // Add records to first subsite
117
        Versioned::set_stage(Versioned::DRAFT);
118
        $_SERVER['HTTP_HOST'] = 'www.subsite1.com';
119
120
        $file = new File();
121
        $file->Title = 'My File';
122
        $file->SubsiteID = $subsite1->ID;
123
        $file->write();
124
125
        $page = new Page();
126
        $page->Title = 'My Page';
127
        $page->SubsiteID = $subsite1->ID;
128
        $page->write();
129
130
        $doc1 = new Apache_Solr_Document([
0 ignored issues
show
The call to Apache_Solr_Document::__construct() has too many arguments starting with array('_documentid' => $...site' => $subsite1->ID). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
        $doc1 = /** @scrutinizer ignore-call */ new Apache_Solr_Document([

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
131
            '_documentid' => $this->getExpectedDocumentId($page, $subsite1->ID, 'Stage'),
132
            'ClassName' => 'Page',
133
            'SiteTree_Title' => 'My Page',
134
            '_versionedstage' => 'Stage',
135
            '_subsite' => $subsite1->ID,
136
        ]);
137
138
        $doc2 = new Apache_Solr_Document([
139
            '_documentid' => $this->getExpectedDocumentId($file, $subsite1->ID),
140
            'ClassName' => File::class,
141
            'File_Title' => 'My File',
142
            '_subsite' => $subsite1->ID,
143
        ]);
144
145
        $serviceMock
146
            ->expects($this->exactly(2))
147
            ->method('addDocument')
148
            ->withConsecutive($doc1, $doc2);
149
150
        SearchUpdater::flush_dirty_indexes();
151
    }
152
153
    public function testCorrectSubsiteIDOnPageWrite()
154
    {
155
        $mockWrites = [
156
            '3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}' => [
157
                'base' => 'SilverStripe\\CMS\\Model\\SiteTree',
158
                'class' => 'Page',
159
                'id' => 3367,
160
                'statefulids' => [
161
                    [
162
                        'id' => 3367,
163
                        'state' => [
164
                            'SearchVariantVersioned' => 'Live',
165
                        ],
166
                    ],
167
                ],
168
                'fields' => [
169
                    'SilverStripe\\CMS\\Model\\SiteTree:ClassName' => 'Page',
170
                    'SilverStripe\\CMS\\Model\\SiteTree:LastEdited' => '2016-12-08 23:55:30',
171
                    'SilverStripe\\CMS\\Model\\SiteTree:Created' => '2016-11-30 05:23:58',
172
                    'SilverStripe\\CMS\\Model\\SiteTree:URLSegment' => 'test',
173
                    'SilverStripe\\CMS\\Model\\SiteTree:Title' => 'Test Title',
174
                    'SilverStripe\\CMS\\Model\\SiteTree:Content' => '<p>test content</p>',
175
                    'SilverStripe\\CMS\\Model\\SiteTree:MetaDescription' => 'a solr test',
176
                    'SilverStripe\\CMS\\Model\\SiteTree:ShowInMenus' => 1,
177
                    'SilverStripe\\CMS\\Model\\SiteTree:ShowInSearch' => 1,
178
                    'SilverStripe\\CMS\\Model\\SiteTree:Sort' => 77,
179
                    'SilverStripe\\CMS\\Model\\SiteTree:HasBrokenFile' => 0,
180
                    'SilverStripe\\CMS\\Model\\SiteTree:HasBrokenLink' => 0,
181
                    'SilverStripe\\CMS\\Model\\SiteTree:CanViewType' => 'Inherit',
182
                    'SilverStripe\\CMS\\Model\\SiteTree:CanEditType' => 'Inherit',
183
                    'SilverStripe\\CMS\\Model\\SiteTree:Locale' => 'en_NZ',
184
                    'SilverStripe\\CMS\\Model\\SiteTree:SubsiteID' => 0,
185
                    'Page:ID' => 3367,
186
                    'Page:MetaKeywords' => null,
187
                ],
188
            ],
189
        ];
190
        $variant = new SearchVariantSubsites();
191
        $tmpMockWrites = $mockWrites;
192
        $variant->extractManipulationWriteState($tmpMockWrites);
193
194
        foreach ($tmpMockWrites as $mockWrite) {
195
            $this->assertCount(1, $mockWrite['statefulids']);
196
            $statefulIDs = array_shift($mockWrite['statefulids']);
197
198
            $this->assertArrayHasKey(SearchVariantSubsites::class, $statefulIDs['state']);
199
            $this->assertEquals(0, $statefulIDs['state'][SearchVariantSubsites::class]);
200
        }
201
202
        $subsite = $this->objFromFixture(Subsite::class, 'subsite1');
203
        $tmpMockWrites = $mockWrites;
204
        $tmpMockWrites['3367:SiteTree:a:1:{s:22:"SearchVariantVersioned";s:4:"Live";}']['fields'][SiteTree::class . ':SubsiteID'] = $subsite->ID;
205
206
        $variant->extractManipulationWriteState($tmpMockWrites);
207
        foreach ($tmpMockWrites as $mockWrite) {
208
            $this->assertCount(1, $mockWrite['statefulids']);
209
            $statefulIDs = array_shift($mockWrite['statefulids']);
210
211
            $this->assertArrayHasKey(SearchVariantSubsites::class, $statefulIDs['state']);
212
            $this->assertEquals($subsite->ID, $statefulIDs['state'][SearchVariantSubsites::class]);
213
        }
214
    }
215
216
    public function testCorrectSubsiteIDOnFileWrite()
217
    {
218
        $subsiteIDs = ['0'] + $this->allFixtureIDs(Subsite::class);
219
        $mockWrites = [
220
            '35910:File:a:0:{}' => [
221
                'base' => File::class,
222
                'class' => File::class,
223
                'id' => 35910,
224
                'statefulids' => [
225
                    [
226
                        'id' => 35910,
227
                        'state' => [],
228
                    ],
229
                ],
230
                'fields' => [
231
                    File::class . ':ClassName' => Image::class,
232
                    File::class . ':ShowInSearch' => 1,
233
                    File::class . ':ParentID' => 26470,
234
                    File::class . ':Filename' => 'assets/Uploads/pic.jpg',
235
                    File::class . ':Name' => 'pic.jpg',
236
                    File::class . ':Title' => 'pic',
237
                    File::class . ':SubsiteID' => 0,
238
                    File::class . ':OwnerID' => 661,
239
                    File::class . ':CurrentVersionID' => 22038,
240
                    File::class . ':LastEdited' => '2016-12-09 00:35:13',
241
                ],
242
            ],
243
        ];
244
        $variant = new SearchVariantSubsites();
245
        $tmpMockWrites = $mockWrites;
246
        $variant->extractManipulationWriteState($tmpMockWrites);
247
        foreach ($tmpMockWrites as $mockWrite) {
248
            $this->assertCount(count($subsiteIDs), $mockWrite['statefulids']);
249
            foreach ($mockWrite['statefulids'] as $statefulIDs) {
250
                $this->assertContains(
251
                    $statefulIDs['state'][SearchVariantSubsites::class],
252
                    $subsiteIDs,
253
                    sprintf(
254
                        'Failed to assert that %s is in list of valid subsites: %s',
255
                        $statefulIDs['state'][SearchVariantSubsites::class],
256
                        implode(', ', $subsiteIDs)
257
                    )
258
                );
259
            }
260
        }
261
262
        $subsite = $this->objFromFixture(Subsite::class, 'subsite1');
263
        $tmpMockWrites = $mockWrites;
264
        $tmpMockWrites['35910:File:a:0:{}']['fields'][File::class . ':SubsiteID'] = $subsite->ID;
265
266
        $variant->extractManipulationWriteState($tmpMockWrites);
267
        foreach ($tmpMockWrites as $mockWrite) {
268
            $this->assertCount(1, $mockWrite['statefulids']);
269
            $statefulIDs = array_shift($mockWrite['statefulids']);
270
            $this->assertEquals($subsite->ID, $statefulIDs['state'][SearchVariantSubsites::class]);
271
        }
272
    }
273
}
274