Passed
Push — master ( c5d65d...3bc83b )
by
unknown
02:05
created

testUrlToPathWithDomainBasedCaching()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 0
dl 0
loc 26
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\StaticPublishQueue\Test\Publisher;
4
5
use SilverStripe\Assets\Filesystem;
6
use SilverStripe\CMS\Model\RedirectorPage;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Control\HTTPApplication;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Dev\SapphireTest;
12
use SilverStripe\Dev\TestKernel;
13
use SilverStripe\StaticPublishQueue\Extension\Publishable\PublishableSiteTree;
14
use SilverStripe\StaticPublishQueue\Publisher\FilesystemPublisher;
15
use SilverStripe\StaticPublishQueue\Test\StaticPublisherTest\Model\StaticPublisherTestPage;
16
use SilverStripe\View\SSViewer;
17
use Symbiote\QueuedJobs\Services\QueuedJobService;
18
19
/**
20
 * Tests for the {@link FilesystemPublisher} class.
21
 *
22
 * @package staticpublishqueue
23
 */
24
class FilesystemPublisherTest extends SapphireTest
25
{
26
    protected $usesDatabase = true;
27
28
    /**
29
     * @var FilesystemPublisher
30
     */
31
    private $fsp = null;
32
33
    protected static $required_extensions = [
34
        SiteTree::class => [
35
            PublishableSiteTree::class,
36
        ],
37
    ];
38
39
    protected function setUp()
40
    {
41
        parent::setUp();
42
43
        Config::modify()->set(FilesystemPublisher::class, 'domain_based_caching', false);
44
        Config::modify()->set(QueuedJobService::class, 'use_shutdown_function', false);
45
        Config::modify()->set(Director::class, 'alternate_base_url', 'http://example.com/');
46
47
        $mockFSP = $this->getMockBuilder(FilesystemPublisher::class)->setMethods([
48
            'getHTTPApplication',
49
        ])->getMock();
50
51
        $mockFSP->method('getHTTPApplication')->willReturnCallback(function () {
52
            return new HTTPApplication(new TestKernel(BASE_PATH));
53
        });
54
55
        $this->fsp = $mockFSP->setDestFolder('cache/testing/');
56
    }
57
58
    protected function tearDown()
59
    {
60
        if ($this->fsp !== null && file_exists($this->fsp->getDestPath())) {
61
            Filesystem::removeFolder($this->fsp->getDestPath());
62
        }
63
        parent::tearDown();
64
    }
65
66
    public function testUrlToPathWithRelativeUrls()
67
    {
68
        $reflection = new \ReflectionClass(FilesystemPublisher::class);
69
        $urlToPath = $reflection->getMethod('URLtoPath');
70
        $urlToPath->setAccessible(true);
71
72
        $this->assertEquals(
73
            'index',
74
            $urlToPath->invokeArgs($this->fsp, ['/'])
75
        );
76
77
        $this->assertEquals(
78
            'about-us',
79
            $urlToPath->invokeArgs($this->fsp, ['about-us'])
80
        );
81
82
        $this->assertEquals(
83
            'parent/child',
84
            $urlToPath->invokeArgs($this->fsp, ['parent/child'])
85
        );
86
    }
87
88
    public function testUrlToPathWithAbsoluteUrls()
89
    {
90
        $reflection = new \ReflectionClass(FilesystemPublisher::class);
91
        $urlToPath = $reflection->getMethod('URLtoPath');
92
        $urlToPath->setAccessible(true);
93
94
        $url = Director::absoluteBaseUrl();
95
        $this->assertEquals(
96
            'index',
97
            $urlToPath->invokeArgs($this->fsp, [$url])
98
        );
99
100
        $url = Director::absoluteBaseUrl() . 'about-us';
101
        $this->assertEquals(
102
            'about-us',
103
            $urlToPath->invokeArgs($this->fsp, [$url])
104
        );
105
106
        $url = Director::absoluteBaseUrl() . 'parent/child';
107
        $this->assertEquals(
108
            'parent/child',
109
            $urlToPath->invokeArgs($this->fsp, [$url])
110
        );
111
    }
112
113
    public function testUrlToPathWithDomainBasedCaching()
114
    {
115
        Config::modify()->set(FilesystemPublisher::class, 'domain_based_caching', true);
116
117
        $reflection = new \ReflectionClass(FilesystemPublisher::class);
118
        $urlToPath = $reflection->getMethod('URLtoPath');
119
        $urlToPath->setAccessible(true);
120
121
        $this->fsp->setFileExtension('html');
122
123
        $url = 'http://domain1.com/';
124
        $this->assertEquals(
125
            'domain1.com/index',
126
            $urlToPath->invokeArgs($this->fsp, [$url])
127
        );
128
129
        $url = 'http://domain1.com/about-us';
130
        $this->assertEquals(
131
            'domain1.com/about-us',
132
            $urlToPath->invokeArgs($this->fsp, [$url])
133
        );
134
135
        $url = 'http://domain2.com/parent/child';
136
        $this->assertEquals(
137
            'domain2.com/parent/child',
138
            $urlToPath->invokeArgs($this->fsp, [$url])
139
        );
140
    }
141
142
    public function testMenu2LinkingMode()
143
    {
144
        SSViewer::set_themes(null);
145
146
        $reflection = new \ReflectionClass(FilesystemPublisher::class);
147
        $urlToPath = $reflection->getMethod('URLtoPath');
148
        $urlToPath->setAccessible(true);
149
150
        $level1 = new StaticPublisherTestPage();
151
        $level1->URLSegment = 'test-level-1';
152
        $level1->write();
153
        $level1->publishRecursive();
154
155
        $level2_1 = new StaticPublisherTestPage();
156
        $level2_1->URLSegment = 'test-level-2-1';
157
        $level2_1->ParentID = $level1->ID;
158
        $level2_1->write();
159
        $level2_1->publishRecursive();
160
161
        $this->fsp->publishURL($level1->Link(), true);
162
        $this->fsp->publishURL($level2_1->Link(), true);
163
        $static2_1FilePath = $this->fsp->getDestPath() . $urlToPath->invokeArgs($this->fsp, [$level2_1->Link()]);
164
165
        $this->assertFileExists($static2_1FilePath . '.html');
166
        $this->assertFileExists($static2_1FilePath . '.php');
167
        $this->assertContains(
168
            'current',
169
            file_get_contents($static2_1FilePath . '.html')
170
        );
171
172
        $level2_2 = new StaticPublisherTestPage();
173
        $level2_2->URLSegment = 'test-level-2-2';
174
        $level2_2->ParentID = $level1->ID;
175
        $level2_2->write();
176
        $level2_2->publishRecursive();
177
178
        $this->fsp->publishURL($level2_2->Link(), true);
179
        $static2_2FilePath = $this->fsp->getDestPath() . $urlToPath->invokeArgs($this->fsp, [$level2_2->Link()]);
180
181
        $this->assertFileExists($static2_2FilePath . '.html');
182
        $this->assertFileExists($static2_2FilePath . '.php');
183
        $this->assertContains(
184
            'linkcurrent',
185
            file_get_contents($static2_2FilePath . '.html')
186
        );
187
    }
188
189
    public function testOnlyHTML()
190
    {
191
        $this->fsp->setFileExtension('html');
192
193
        $level1 = new StaticPublisherTestPage();
194
        $level1->URLSegment = 'mimetype';
195
        $level1->write();
196
        $level1->publishRecursive();
197
198
        $this->fsp->publishURL($level1->Link(), true);
199
        $staticFilePath = $this->fsp->getDestPath() . 'mimetype';
200
201
        $this->assertFileExists($staticFilePath . '.html');
202
        $this->assertFileNotExists($staticFilePath . '.php');
203
        $this->assertEquals(
204
            "<div class=\"statically-published\" style=\"display: none\"></div>",
205
            trim(file_get_contents($staticFilePath . '.html'))
206
        );
207
    }
208
209
    public function testPurgeURL()
210
    {
211
        $level1 = new StaticPublisherTestPage();
212
        $level1->URLSegment = 'to-be-purged';
213
        $level1->write();
214
        $level1->publishRecursive();
215
216
        $this->fsp->publishURL('to-be-purged', true);
217
        $this->assertFileExists($this->fsp->getDestPath() . 'to-be-purged.html');
218
        $this->assertFileExists($this->fsp->getDestPath() . 'to-be-purged.php');
219
220
        $this->fsp->purgeURL('to-be-purged');
221
        $this->assertFileNotExists($this->fsp->getDestPath() . 'to-be-purged.html');
222
        $this->assertFileNotExists($this->fsp->getDestPath() . 'to-be-purged.php');
223
    }
224
225
    public function testPurgeURLAfterSwitchingExtensions()
226
    {
227
        $level1 = new StaticPublisherTestPage();
228
        $level1->URLSegment = 'purge-me';
229
        $level1->write();
230
        $level1->publishRecursive();
231
232
        $this->fsp->publishURL('purge-me', true);
233
        $this->assertFileExists($this->fsp->getDestPath() . 'purge-me.html');
234
        $this->assertFileExists($this->fsp->getDestPath() . 'purge-me.php');
235
236
        $this->fsp->setFileExtension('html');
237
238
        $this->fsp->purgeURL('purge-me');
239
        $this->assertFileNotExists($this->fsp->getDestPath() . 'purge-me.html');
240
        $this->assertFileNotExists($this->fsp->getDestPath() . 'purge-me.php');
241
    }
242
243
    public function testNoErrorPagesWhenHTMLOnly()
244
    {
245
        $this->fsp->setFileExtension('html');
246
247
        $this->fsp->publishURL('not_really_there', true);
248
        $this->assertFileNotExists($this->fsp->getDestPath() . 'not_really_there.html');
249
        $this->assertFileNotExists($this->fsp->getDestPath() . 'not_really_there.php');
250
    }
251
252
    public function testErrorPageWhenPHP()
253
    {
254
        $this->fsp->publishURL('not_really_there', true);
255
        $this->assertFileExists($this->fsp->getDestPath() . 'not_really_there.html');
256
        $this->assertFileExists($this->fsp->getDestPath() . 'not_really_there.php');
257
        $phpCacheConfig = require $this->fsp->getDestPath() . 'not_really_there.php';
258
        $this->assertEquals(404, $phpCacheConfig['responseCode']);
259
    }
260
261
    public function testRedirectorPageWhenPHP()
262
    {
263
        $redirectorPage = RedirectorPage::create();
264
        $redirectorPage->URLSegment = 'somewhere-else';
265
        $redirectorPage->RedirectionType = 'External';
266
        $redirectorPage->ExternalURL = 'silverstripe.org';
267
        $redirectorPage->write();
268
        $redirectorPage->publishRecursive();
269
270
        $this->fsp->publishURL('somewhere-else', true);
271
272
        $this->assertFileExists($this->fsp->getDestPath() . 'somewhere-else.html');
273
        $this->assertContains(
274
            'Click this link if your browser does not redirect you',
275
            file_get_contents($this->fsp->getDestPath() . 'somewhere-else.html')
276
        );
277
        $this->assertFileExists($this->fsp->getDestPath() . 'somewhere-else.php');
278
        $phpCacheConfig = require $this->fsp->getDestPath() . 'somewhere-else.php';
279
        $this->assertEquals(301, $phpCacheConfig['responseCode']);
280
        $this->assertContains('location: http://silverstripe.org', $phpCacheConfig['headers']);
281
    }
282
283
    public function testRedirectorPageWhenHTMLOnly()
284
    {
285
        $this->fsp->setFileExtension('html');
286
287
        $redirectorPage = RedirectorPage::create();
288
        $redirectorPage->URLSegment = 'somewhere-else';
289
        $redirectorPage->RedirectionType = 'External';
290
        $redirectorPage->ExternalURL = 'silverstripe.org';
291
        $redirectorPage->write();
292
        $redirectorPage->publishRecursive();
293
294
        $this->fsp->publishURL('somewhere-else', true);
295
296
        $this->assertFileExists($this->fsp->getDestPath() . 'somewhere-else.html');
297
        $this->assertContains(
298
            'Click this link if your browser does not redirect you',
299
            file_get_contents($this->fsp->getDestPath() . 'somewhere-else.html')
300
        );
301
        $this->assertFileNotExists($this->fsp->getDestPath() . 'somewhere-else.php');
302
    }
303
304
    /**
305
     * @dataProvider providePathsToURL
306
     */
307
    public function testPathToURL($expected, $path)
308
    {
309
        $reflection = new \ReflectionClass(FilesystemPublisher::class);
310
        $pathToURL = $reflection->getMethod('pathToURL');
311
        $pathToURL->setAccessible(true);
312
313
        $this->assertEquals(
314
            $expected,
315
            $pathToURL->invoke($this->fsp, $this->fsp->getDestPath() . $path)
316
        );
317
    }
318
319
    public function providePathsToURL()
320
    {
321
        return [
322
            ['http://example.com/', 'index.html'],
323
            ['http://example.com/about-us', 'about-us.html'],
324
            ['http://example.com/about-us', 'about-us.php'],
325
            ['http://example.com/parent/child', 'parent/child.html'],
326
        ];
327
    }
328
329
    public function testGetPublishedURLs()
330
    {
331
        $level1 = new StaticPublisherTestPage();
332
        $level1->URLSegment = 'find-me';
333
        $level1->write();
334
        $level1->publishRecursive();
335
336
        $this->fsp->publishURL('find-me', true);
337
        // We have to redeclare this config because the testkernel wipes it when we generate the page response
338
        Director::config()->set('alternate_base_url', 'http://example.com');
339
340
        $this->assertEquals(['http://example.com/find-me'], $this->fsp->getPublishedURLs());
341
342
        $level2_1 = new StaticPublisherTestPage();
343
        $level2_1->URLSegment = 'find-me-child';
344
        $level2_1->ParentID = $level1->ID;
345
        $level2_1->write();
346
        $level2_1->publishRecursive();
347
348
        $this->fsp->publishURL($level2_1->Link(), true);
349
        Director::config()->set('alternate_base_url', 'http://example.com');
350
351
        $urls = $this->fsp->getPublishedURLs();
352
        $this->assertContains('http://example.com/find-me', $urls);
353
        $this->assertContains('http://example.com/find-me/find-me-child', $urls);
354
        $this->assertCount(2, $urls);
355
356
        $this->fsp->purgeURL('find-me');
357
        $this->assertEquals(['http://example.com/find-me/find-me-child'], $this->fsp->getPublishedURLs());
358
    }
359
}
360