Passed
Pull Request — master (#70)
by Daniel
02:31
created

FilesystemPublisherTest::testPathToURL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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