Completed
Branch feature/currentUserRefactoring (c13c1d)
by Schlaefer
09:08
created

BbcodeParserTest.php$0 ➔ setSingle()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace BbcodeParser\Test\Lib;
14
15
use App\View\Helper\ParserHelper;
16
use Cake\Cache\Cache;
17
use Cake\Core\Configure;
18
use Cake\View\View;
19
use Plugin\BbcodeParser\Lib;
0 ignored issues
show
Bug introduced by
The type Plugin\BbcodeParser\Lib 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...
20
use Plugin\BbcodeParser\src\Lib\Parser;
21
use Saito\Markup\MarkupSettings;
22
use Saito\Test\SaitoTestCase;
23
use Saito\User\Userlist;
24
use Saito\User\Userlist\UserlistModel;
25
26
class BbcodeParserTest extends SaitoTestCase
27
{
28
29
    /**
30
     * @var Parser
31
     */
32
    protected $_Parser = null;
33
34
    /** @var MarkupSettings */
35
    protected $MarkupSettings;
36
37
    public function testBold()
38
    {
39
        $input = '[b]bold[/b]';
40
        $expected = ['strong' => [], 'bold', '/strong'];
41
        $result = $this->_Parser->parse($input);
42
        $this->assertHtml($expected, $result);
43
    }
44
45
    public function testEmphasis()
46
    {
47
        $input = '[i]italic[/i]';
48
        $expected = ['em' => [], 'italic', '/em'];
49
        $result = $this->_Parser->parse($input);
50
        $this->assertHtml($expected, $result);
51
    }
52
53
    public function testQuoteblock()
54
    {
55
        $input = '[quote]foo bar[/quote]';
56
        $expected = ['blockquote' => [], 'foo bar', '/blockquote'];
57
        $result = $this->_Parser->parse($input);
58
        $this->assertHtml($expected, $result);
59
    }
60
61
    public function testStrike()
62
    {
63
        $expected = ['del' => [], 'text', '/del'];
64
65
        // [strike]
66
        $input = '[strike]text[/strike]';
67
        $result = $this->_Parser->parse($input);
68
        $this->assertHtml($expected, $result);
69
70
        // [s]
71
        $input = '[s]text[/s]';
72
        $result = $this->_Parser->parse($input);
73
        $this->assertHtml($expected, $result);
74
    }
75
76
    public function testSpoiler()
77
    {
78
        $input = 'pre [spoiler] te "\' xt[/spoiler]';
79
        $expected = [
80
            'pre',
81
            [
82
                'div' => [
83
                    'class' => 'richtext-spoiler',
84
                    'style' => 'display: inline;'
85
                ]
86
            ],
87
            ['script' => true],
88
            'preg:/(.*?)"string":" te &quot;&#039; xt"(.*?)(?=<)/',
89
            '/script',
90
            [
91
                'a' => [
92
                    'href' => '#',
93
                    'class' => 'richtext-spoiler-link',
94
                    'onclick'
95
                ]
96
            ],
97
            'preg:/.*▇ Spoiler ▇.*?(?=<)/',
98
            '/a',
99
            '/div'
100
        ];
101
        $result = $this->_Parser->parse($input);
102
        $this->assertHtml($expected, $result);
103
    }
104
105
    public function testList()
106
    {
107
        $input = "[list]\n[*]fooo\n[*]bar\n[/list]";
108
        $expected = [
109
            ['ul' => []],
110
            ['li' => []],
111
            'fooo',
112
            ['br' => []],
113
            '/li',
114
            ['li' => []],
115
            'bar',
116
            ['br' => []],
117
            '/li',
118
            '/ul'
119
        ];
120
        $result = $this->_Parser->parse($input);
121
        $this->assertHtml($expected, $result);
122
    }
123
124
    public function testMaskLinkWithoutProtocol()
125
    {
126
        $input = '[url=thetempe.st/station]purge[/url]';
127
        $expected = [
128
            'a' => [
129
                'href' => 'http://thetempe.st/station',
130
                'rel' => 'external',
131
                'target' => '_blank'
132
            ],
133
            'purge',
134
            '/a'
135
        ];
136
        $result = $this->_Parser->parse($input);
137
        $this->assertHtml($expected, $result);
138
    }
139
140
    public function testParserEngineCaching()
141
    {
142
        $input = '[img=]foo.png[/img]';
143
        $result = $this->_Parser->parse($input, ['multimedia' => true]);
144
        $this->assertContains('<img src', $result);
145
        $result = $this->_Parser->parse($input, ['multimedia' => false]);
146
        $this->assertNotContains('<img src', $result);
147
    }
148
149
    public function testLink()
150
    {
151
        $input = '[url=http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=250678480561&ssPageName=ADME:X:RTQ:DE:1123]test[/url]';
152
        $expected = "<a href='http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&amp;item=250678480561&amp;ssPageName=ADME:X:RTQ:DE:1123' rel='external' target='_blank'>test</a> <span class='richtext-linkInfo'>[ebay.de]</span>";
153
        $result = $this->_Parser->parse($input);
154
        $this->assertEquals($expected, $result);
155
156
        /*
157
         * external server
158
         */
159
        $input = '[url]http://heise.de/foobar[/url]';
160
        $expected = [
161
            'a' => [
162
                'href' => 'http://heise.de/foobar',
163
                'rel' => 'external',
164
                'target' => '_blank'
165
            ],
166
            'http://heise.de/foobar',
167
            '/a'
168
        ];
169
        $result = $this->_Parser->parse($input);
170
        $this->assertHtml($expected, $result);
171
172
        $input = '[link]http://heise.de/foobar[/link]';
173
        $expected = [
174
            'a' => [
175
                'href' => 'http://heise.de/foobar',
176
                'rel' => 'external',
177
                'target' => '_blank'
178
            ],
179
            'http://heise.de/foobar',
180
            '/a'
181
        ];
182
        $result = $this->_Parser->parse($input);
183
        $this->assertHtml($expected, $result);
184
185
        // masked link
186
        $input = '[url=http://heise.de/foobar]foobar[/url]';
187
        $expected = [
188
            'a' => [
189
                'href' => 'http://heise.de/foobar',
190
                'rel' => 'external',
191
                'target' => '_blank'
192
            ],
193
            'foobar',
194
            '/a',
195
            'span' => ['class' => 'richtext-linkInfo'],
196
            '[heise.de]',
197
            '/span'
198
        ];
199
        $result = $this->_Parser->parse($input);
200
        $this->assertHtml($expected, $result);
201
202
        // masked link with no label
203
        $input = '[url=http://heise.de/foobar  label=none ]foobar[/url]';
204
        $expected = [
205
            'a' => [
206
                'href' => 'http://heise.de/foobar',
207
                'rel' => 'external',
208
                'target' => '_blank',
209
            ],
210
            'foobar',
211
            '/a',
212
        ];
213
        $result = $this->_Parser->parse($input);
214
        $this->assertHtml($expected, $result);
215
216
        /*
217
         * local server
218
         */
219
        $input = '[url=http://macnemo.de/foobar]foobar[/url]';
220
        $expected = "<a href='http://macnemo.de/foobar'>foobar</a>";
221
        $result = $this->_Parser->parse($input);
222
        $this->assertEquals($expected, $result);
223
224
        $input = '[url]/foobar[/url]';
225
        $expected = [
226
            'a' => [
227
                'href' => '/foobar',
228
            ],
229
            'preg:/\/foobar/',
230
            '/a',
231
        ];
232
        $result = $this->_Parser->parse($input);
233
        $this->assertHtml($expected, $result);
234
235
        // test lokaler server with absolute url
236
        $input = '[url=/foobar]foobar[/url]';
237
        $expected = "<a href='/foobar'>foobar</a>";
238
        $result = $this->_Parser->parse($input);
239
        $this->assertEquals($expected, $result);
240
241
        // test 'http://' only
242
        $input = '[url=http://]foobar[/url]';
243
        $expected = "<a href='http://'>foobar</a>";
244
        $result = $this->_Parser->parse($input);
245
        $this->assertEquals($expected, $result);
246
247
        // test for co.uk
248
        $input = '[url=http://heise.co.uk/foobar]foobar[/url]';
249
        $expected = [
250
            'a' => [
251
                'href' => 'http://heise.co.uk/foobar',
252
                'rel' => 'external',
253
                'target' => '_blank'
254
            ],
255
            'foobar',
256
            '/a',
257
            'span' => ['class' => 'richtext-linkInfo'],
258
            '[heise.co.uk]',
259
            '/span'
260
        ];
261
        $result = $this->_Parser->parse($input);
262
        $this->assertHtml($expected, $result);
263
    }
264
265
    public function testHashLinkSuccess()
266
    {
267
        // inline content ([i])
268
        $input = "[i]#2234[/i]";
269
        $expected = [
270
            'em' => [],
271
            'a' => [
272
                'href' => '/hash/2234'
273
            ],
274
            '#2234',
275
            '/a',
276
            '/em'
277
        ];
278
        $result = $this->_Parser->parse($input);
279
        $this->assertHtml($expected, $result);
280
281
        // lists
282
        $input = "[list][*]#2234[/list]";
283
        $expected = [
284
            'ul' => true,
285
            'li' => true,
286
            'a' => [
287
                'href' => '/hash/2234'
288
            ],
289
            '#2234',
290
            '/a',
291
            '/li',
292
            '/ul'
293
        ];
294
        $result = $this->_Parser->parse($input);
295
        $this->assertHtml($expected, $result);
296
297
        /// in paranthesis
298
        $input = "foo (#2234) bar";
299
        $expected = [
300
            'foo (',
301
            'a' => [
302
                'href' => '/hash/2234'
303
            ],
304
            '#2234',
305
            '/a',
306
            ') bar'
307
        ];
308
        $result = $this->_Parser->parse($input);
309
        $this->assertHtml($expected, $result);
310
    }
311
312
    public function testHashLinkFailure()
313
    {
314
        // don't hash code
315
        $input = '[code]#2234[/code]';
316
        $result = $this->_Parser->parse($input);
317
        $this->assertNotContains('>#2234</a>', $result);
318
319
        // not a valid hash
320
        $input = '#2234t';
321
        $result = $this->_Parser->parse($input);
322
        $this->assertEquals('#2234t', $result);
323
    }
324
325
    public function testAtLinkKnownUsers()
326
    {
327
        $input = '@Alice @Bob @Bobby Junior @Bobby Tables @Dr. No';
328
        $expected =
329
            "<a href='/at/Alice'>@Alice</a>" .
330
            " @Bob " .
331
            "<a href='/at/Bobby+Junior'>@Bobby Junior</a>" .
332
            " @Bobby Tables " .
333
            "<a href='/at/Dr.+No'>@Dr. No</a>";
334
335
        $result = $this->_Parser->parse($input);
336
        $this->assertEquals(
337
            $expected,
338
            $result,
339
            '@User string is not replaced with link to user profile.'
340
        );
341
342
        $input = '[code]@Alice[/code]';
343
        $result = $this->_Parser->parse($input);
344
        $this->assertNotContains('>@Alice</a>', $result);
345
    }
346
347
    public function testAtLinkKnownUsersLinebreak()
348
    {
349
        $input = "@Alice\nfoo";
350
        $result = $this->_Parser->parse($input);
351
        $expected = [
352
            'a' => ['href' => '/at/Alice'],
353
            '@Alice',
354
            '/a',
355
            'br' => true
356
        ];
357
        $this->assertHtml($expected, $result);
358
    }
359
360
    public function testLinkEmptyUrl()
361
    {
362
        $input = '[url=][/url]';
363
        $expected = "<a href=''></a>";
364
        $result = $this->_Parser->parse($input);
365
        $this->assertEquals($expected, $result);
366
    }
367
368
    public function testEditMarker()
369
    {
370
        $input = 'pre [e] post';
371
        $expected = [
372
            'pre ',
373
            'span' => [
374
                'class' => 'richtext-editMark'
375
            ],
376
            '/span',
377
            ' post'
378
        ];
379
        $result = $this->_Parser->parse($input);
380
        $this->assertHtml($expected, $result);
381
    }
382
383
    /*
384
     * without obfuscator
385
     *
386
    public function testEmail() {
387
        /*
388
            // mailto:
389
            $input = '[email]mailto:[email protected][/email]';
390
            $expected = "<a href='mailto:[email protected]'>mailto:[email protected]</a>";
391
            $result = $this->Bbcode->parse($input);
392
            $this->assertEquals($expected, $result);
393
394
            // mailto: mask
395
            $input = '[email=mailto:[email protected]]Mail[/email]';
396
            $expected = "<a href='mailto:[email protected]'>Mail</a>";
397
            $result = $this->Bbcode->parse($input);
398
            $this->assertEquals($expected, $result);
399
400
            // no mailto:
401
            $input = '[email][email protected][/email]';
402
            $expected = "<a href='mailto:[email protected]'>[email protected]</a>";
403
            $result = $this->Bbcode->parse($input);
404
            $this->assertEquals($expected, $result);
405
406
            // no mailto: mask
407
            $input = '[[email protected]]Mail[/email]';
408
            $expected = "<a href='mailto:[email protected]'>Mail</a>";
409
            $result = $this->Bbcode->parse($input);
410
            $this->assertEquals($expected, $result);
411
    }
412
            */
413
414
    public function testEmailMailto()
415
    {
416
        $MO = $this->getMockBuilder('MailObfuscator')
417
            ->setMethods(['link'])
418
            ->getMock();
419
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\TestCase::once() has too many arguments starting with 4. ( Ignorable by Annotation )

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

419
        $MO->expects($this->/** @scrutinizer ignore-call */ once(4))

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...
420
            ->method('link')
421
            ->with('[email protected]', null);
422
        $this->_Helper->MailObfuscator = $MO;
423
424
        $input = '[email]mailto:[email protected][/email]';
425
        $this->_Parser->parse($input);
426
    }
427
428
    public function testEmailMailtoMask()
429
    {
430
        $MO = $this->getMockBuilder('MailObfuscator')
431
            ->setMethods(['link'])
432
            ->getMock();
433
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\TestCase::once() has too many arguments starting with 4. ( Ignorable by Annotation )

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

433
        $MO->expects($this->/** @scrutinizer ignore-call */ once(4))

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...
434
            ->method('link')
435
            ->with('[email protected]', 'Mail');
436
        $this->_Helper->MailObfuscator = $MO;
437
438
        $input = '[email=mailto:[email protected]]Mail[/email]';
439
        $this->_Parser->parse($input);
440
    }
441
442
    public function testEmailNoMailto()
443
    {
444
        $MO = $this->getMockBuilder('MailObfuscator')
445
            ->setMethods(['link'])
446
            ->getMock();
447
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\TestCase::once() has too many arguments starting with 4. ( Ignorable by Annotation )

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

447
        $MO->expects($this->/** @scrutinizer ignore-call */ once(4))

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...
448
            ->method('link')
449
            ->with('[email protected]', null);
450
        $this->_Helper->MailObfuscator = $MO;
451
452
        $input = '[email][email protected][/email]';
453
        $this->_Parser->parse($input);
454
    }
455
456
    public function testEmailNoMailtoMask()
457
    {
458
        $MO = $this->getMockBuilder('MailObfuscator')
459
            ->setMethods(['link'])
460
            ->getMock();
461
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\TestCase::once() has too many arguments starting with 4. ( Ignorable by Annotation )

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

461
        $MO->expects($this->/** @scrutinizer ignore-call */ once(4))

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...
462
            ->method('link')
463
            ->with('[email protected]', 'Mail');
464
        $this->_Helper->MailObfuscator = $MO;
465
466
        $input = '[[email protected]]Mail[/email]';
467
        $this->_Parser->parse($input);
468
    }
469
470
    public function testFlash()
471
    {
472
        $bbcode = '[flash_video]//www.youtube.com/v/MrBRPYlrGF8?version=3&amp;hl=en_US|560|315[/flash_video]';
473
        $expected = <<<EOF
474
			<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="315">
475
									<param name="movie" value="//www.youtube.com/v/MrBRPYlrGF8?version=3&amp;amp;hl=en_US"></param>
476
									<embed src="//www.youtube.com/v/MrBRPYlrGF8?version=3&amp;amp;hl=en_US" width="560" height="315" type="application/x-shockwave-flash" wmode="opaque" style="width:560px; height:315px;" id="VideoPlayback" flashvars=""> </embed> </object>
477
EOF;
478
        $actual = $this->_Parser->parse(
479
            $bbcode,
480
            ['video_domains_allowed' => 'youtube']
481
        );
482
        $this->assertEquals(trim($expected), trim($actual));
483
    }
484
485
    public function testFloat()
486
    {
487
        $expected = [
488
            ['div' => ['class' => 'clearfix']],
489
            '/div',
490
            ['div' => ['class' => 'richtext-float']],
491
            'text',
492
            '/div',
493
            'more'
494
        ];
495
496
        $input = '[float]text[/float]more';
497
        $result = $this->_Parser->parse($input);
498
        $this->assertHtml($expected, $result);
499
    }
500
501
    public function testLinkAuto()
502
    {
503
        $input = 'http://heise.de/foobar';
504
        $expected = "<a href='http://heise.de/foobar' rel='external' target='_blank'>http://heise.de/foobar</a>";
505
        $result = $this->_Parser->parse($input);
506
        $this->assertEquals($expected, $result);
507
508
        // autolink surrounded by text
509
        $input = 'some http://heise.de/foobar text';
510
        $expected = "some <a href='http://heise.de/foobar' rel='external' target='_blank'>http://heise.de/foobar</a> text";
511
        $result = $this->_Parser->parse($input);
512
        $this->assertEquals($expected, $result);
513
514
        // no autolink in [code]
515
        $input = '[code]http://heise.de/foobar[/code]';
516
        $needle = 'heise.de/foobar</a>';
517
        $result = $this->_Parser->parse($input);
518
        $this->assertNotContains($result, $needle);
519
520
        // no autolink in [url]
521
        $input = '[url=http://a.com/]http://b.de/[/url]';
522
        $result = $this->_Parser->parse($input);
523
        $this->assertRegExp(
524
            '#href=["\']http://a.com/["\'][^>]*?>http://b.de/#',
525
            $result
526
        );
527
528
        // email autolink
529
        $input = 'text [email protected] test';
530
        // $expected = "text <a href='mailto:[email protected]'>[email protected]</a> test";
531
        $result = $this->_Parser->parse($input);
532
        // $this->assertEquals($expected, $result);
533
        // @bogus weak test
534
        $this->assertRegExp('/^text .*href=".* test$/sm', $result);
535
536
        //# in list
537
        $input = <<<EOF
538
[list]
539
[*] http://heise.de
540
[/list]
541
EOF;
542
        $result = $this->_Parser->parse($input);
543
        $expected = "<a href='http://heise.de";
544
        $this->assertTextContains($expected, $result);
545
    }
546
547
    public function testLinkAutoWithoutHttpPrefix()
548
    {
549
        $input = 'some www.example.com/foobar text';
550
        $expected = [
551
            'some ',
552
            'a' => [
553
                'href' => 'http://www.example.com/foobar',
554
                'rel' => 'external',
555
                'target' => '_blank',
556
            ],
557
            'http://www.example.com/foobar',
558
            '/a',
559
            ' text'
560
        ];
561
        $result = $this->_Parser->parse($input);
562
        $this->assertHtml($expected, $result);
563
    }
564
565
    public function testLinkAutoUrlWithinParentheses()
566
    {
567
        $input = 'some (www.example.com/foobar) text';
568
        $expected = [
569
            'some (',
570
            'a' => [
571
                'href' => 'http://www.example.com/foobar',
572
                'rel' => 'external',
573
                'target' => '_blank',
574
            ],
575
            'http://www.example.com/foobar',
576
            '/a',
577
            ') text'
578
        ];
579
        $result = $this->_Parser->parse($input);
580
        $this->assertHtml($expected, $result);
581
    }
582
583
    public function testLinkAutoSurroundingChars()
584
    {
585
        $input = 'text http://example.com/?foo,,, text';
586
        $result = $this->_Parser->parse($input);
587
        $expected = [
588
            'text ',
589
            'a' => [
590
                'href' => 'http://example.com/?foo,,',
591
                'rel' => 'external',
592
                'target' => '_blank',
593
            ],
594
            'http://example.com/?foo,,',
595
            '/a',
596
            ', text'
597
        ];
598
        $this->assertHtml($expected, $result);
599
600
        // Question mark
601
        $input = 'question http://example.com/? Text';
602
        $result = $this->_Parser->parse($input);
603
        $expected = [
604
            'question ',
605
            'a' => [
606
                'href' => 'http://example.com/',
607
                'rel' => 'external',
608
                'target' => '_blank',
609
            ],
610
            'http://example.com/',
611
            '/a',
612
            '? Text'
613
        ];
614
        $this->assertHtml($expected, $result);
615
616
        // No Question mark but url
617
        $input = 'no question http://example.com/?foo=bar text';
618
        $result = $this->_Parser->parse($input);
619
        $expected = [
620
            'no question ',
621
            'a' => [
622
                'href' => 'http://example.com/?foo=bar',
623
                'rel' => 'external',
624
                'target' => '_blank',
625
            ],
626
            'http://example.com/?foo=bar',
627
            '/a',
628
            ' text'
629
        ];
630
        $this->assertHtml($expected, $result);
631
    }
632
633
    public function testLinkAutoIgnoreLocalFiles()
634
    {
635
        $input = 'a file:///foo.bar b file://foo c file:// d file:///';
636
        $result = $this->_Parser->parse($input);
637
        $this->assertEquals($input, $result);
638
    }
639
640
    public function testReturnText()
641
    {
642
        $in = 'test [b]test[b] test';
643
        $expected = 'test test test';
644
        $actual = $this->_Parser->parse($in, ['return' => 'text']);
645
        $this->assertEquals($expected, $actual);
646
    }
647
648
    public function testShortenLink()
649
    {
650
        $maxLength = 15;
651
        $this->MarkupSettings->setSingle('text_word_maxlength', $maxLength);
0 ignored issues
show
introduced by
The method setSingle() does not exist on Saito\Markup\MarkupSettings. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

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

651
        $this->MarkupSettings->/** @scrutinizer ignore-call */ 
652
                               setSingle('text_word_maxlength', $maxLength);
Loading history...
652
653
        $input = '[url]http://this/url/is/32/chars/long[/url]';
654
        $expected = "<a href='http://this/url/is/32/chars/long' rel='external' target='_blank'>http:// … /long</a>";
655
656
        $result = $this->_Parser->parse($input);
657
        $this->assertEquals($expected, $result);
658
659
        $input = 'http://this/url/is/32/chars/long';
660
        $expected = "<a href='http://this/url/is/32/chars/long' rel='external' target='_blank'>http:// … /long</a>";
661
        $result = $this->_Parser->parse($input);
662
        $this->assertEquals($expected, $result);
663
    }
664
665
    public function testIframe()
666
    {
667
        //* test allowed domain
668
        $input = '[iframe height=349 width=560 ' .
669
            'src=http://www.youtube.com/embed/HdoW3t_WorU ' .
670
            'frameborder=0][/iframe]';
671
        $expected = [
672
            [
673
                'div' => [
674
                    'class' => 'embed-responsive embed-responsive-16by9',
675
                ],
676
                'iframe' => [
677
                    'class' => 'embed-responsive-item',
678
                    'src' => 'http://www.youtube.com/embed/HdoW3t_WorU?&amp;wmode=Opaque',
679
                    'height' => '349',
680
                    'width' => '560',
681
                    'frameborder' => '0'
682
                ]
683
            ],
684
            '/iframe',
685
        ];
686
        $result = $this->_Parser->parse(
687
            $input,
688
            ['video_domains_allowed' => 'youtube | vimeo']
689
        );
690
        $this->assertHtml($expected, $result);
691
692
        //* test forbidden domains
693
        $input = '[iframe height=349 width=560 ' .
694
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
695
            'frameborder=0][/iframe]';
696
        $pattern = '/src/i';
697
        $result = $this->_Parser->parse(
698
            $input,
699
            ['video_domains_allowed' => 'youtube | vimeo']
700
        );
701
        $this->assertNotRegExp($pattern, $result);
702
    }
703
704
    public function testIframeAllDomainsAllowed()
705
    {
706
        $input = '[iframe height=349 width=560 ' .
707
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
708
            '][/iframe]';
709
        $expected = 'src="http://www.youtubescam.com/embed/HdoW3t_WorU';
710
        $this->MarkupSettings->setSingle('video_domains_allowed', '*');
711
        $result = $this->_Parser->parse($input);
712
        $this->assertContains($expected, $result);
713
    }
714
715
    public function testIframeNoDomainAllowed()
716
    {
717
        $input = '[iframe height=349 width=560 ' .
718
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
719
            '][/iframe]';
720
        $expected = '/src/i';
721
        $result = $this->_Parser->parse(
722
            $input,
723
            ['video_domains_allowed' => '']
724
        );
725
        $this->assertNotRegExp($expected, $result);
726
    }
727
728
    public function testExternalImageAbsoluteAutoLinked()
729
    {
730
        // test for standard URIs
731
        $input = '[img]http://foo.bar/img/macnemo.png[/img]';
732
        $expected = [
733
            'a' => [
734
                'href' => 'http://foo.bar/img/macnemo.png',
735
                // 'rel' => 'external',
736
                'target' => '_blank',
737
            ],
738
            'img' => [
739
                'src' => 'http://foo.bar/img/macnemo.png',
740
                'alt' => ''
741
            ]
742
        ];
743
        $result = $this->_Parser->parse($input);
744
        $this->assertHtml($expected, $result);
745
    }
746
747
    public function testExternalImageRelativeAutoLinked()
748
    {
749
        // test for standard URIs
750
        $input = '[img]/somewhere/macnemo.png[/img]';
751
        $expected = [
752
            'a' => [
753
                'href' => '/somewhere/macnemo.png',
754
                'target' => '_blank',
755
            ],
756
            'img' => [
757
                'src' => '/somewhere/macnemo.png',
758
                'alt' => ''
759
            ]
760
        ];
761
        $result = $this->_Parser->parse($input);
762
        $this->assertHtml($expected, $result);
763
    }
764
765
    /**
766
     * test scaling with 1 parameter
767
     */
768
    public function testExternalImageAbsoluteAutoLinkedScaledByOne()
769
    {
770
        // test for standard URIs
771
        $input = '[img=50]http://foo.bar/img/macnemo.png[/img]';
772
        $expected = [
773
            'a' => [
774
                'href' => 'http://foo.bar/img/macnemo.png',
775
                'target' => '_blank',
776
            ],
777
            'img' => [
778
                'src' => 'http://foo.bar/img/macnemo.png',
779
                'alt' => '',
780
                'width' => '50',
781
            ]
782
        ];
783
        $result = $this->_Parser->parse($input);
784
        $this->assertHtml($expected, $result);
785
    }
786
787
    /**
788
     * test scaling with 2 parameter
789
     */
790
    public function testExternalImageAbsoluteAutoLinkedScaledByTwo()
791
    {
792
        // test for standard URIs
793
        $input = '[img=50x100]http://foo.bar/img/macnemo.png[/img]';
794
        $expected = [
795
            'a' => [
796
                'href' => 'http://foo.bar/img/macnemo.png',
797
                'target' => '_blank',
798
            ],
799
            'img' => [
800
                'src' => 'http://foo.bar/img/macnemo.png',
801
                'alt' => '',
802
                'height' => '100',
803
                'width' => '50',
804
            ]
805
        ];
806
        $result = $this->_Parser->parse($input);
807
        $this->assertHtml($expected, $result);
808
    }
809
810
    public function testExternalImageWithHttpsEnforced()
811
    {
812
        $_SERVER['HTTPS'] = true;
813
        $input = '[img=]http://foo.bar/img/macnemo.png[/img]';
814
        $expected = [
815
            'a' => [
816
                'href' => 'https://foo.bar/img/macnemo.png',
817
                'target' => '_blank',
818
            ],
819
            'img' => [
820
                'src' => 'https://foo.bar/img/macnemo.png',
821
                'alt' => '',
822
            ]
823
        ];
824
        $result = $this->_Parser->parse($input);
825
        $this->assertHtml($expected, $result);
826
        unset($_SERVER['HTTPS']);
827
    }
828
829
    public function testImageNestedInExternalLink()
830
    {
831
        $input = '[url=http://heise.de][img]http://heise.de/img.png[/img][/url]';
832
833
        /*
834
        $expected = "<a href='http://heise.de' rel='external' target='_blank'><img src=\"http://heise.de/img.png\" class=\"external_image\" style=\"\" width=\"auto\" height=\"auto\" alt=\"\" /></a>";
835
        */
836
        $expected = [
837
            [
838
                'a' => [
839
                    'href' => 'http://heise.de',
840
                    'rel' => 'external',
841
                    'target' => '_blank',
842
                ]
843
            ],
844
            [
845
                'img' => [
846
                    'src' => 'http://heise.de/img.png',
847
                    'alt' => '',
848
                ]
849
            ],
850
            '/a'
851
        ];
852
        $result = $this->_Parser->parse($input);
853
        $this->assertHtml($expected, $result);
854
    }
855
856
    /**
857
     * [uploads]<image>[/uploads]
858
     */
859
    public function testInternalImageAutoLinked()
860
    {
861
        //// internal image
862
        $input = '[upload]test.png[/upload]';
863
        $expected = [
864
            [
865
                'a' => [
866
                    'href' => '/useruploads/test.png',
867
                    'target' => '_blank',
868
                ],
869
                'img' => [
870
                    'alt' => '',
871
                    'src' => '/useruploads/test.png',
872
                ],
873
            ],
874
        ];
875
        $result = $this->_Parser->parse($input);
876
        $this->assertHtml($expected, $result);
877
878
        //// internal image with attributes
879
        $input = '[upload width=50 height=60]test.png[/upload]';
880
        $expected = [
881
            [
882
                'a' => [
883
                    'href' => '/useruploads/test.png',
884
                    'target' => '_blank',
885
                ],
886
                'img' =>
887
                    [
888
                        'alt' => '',
889
                        'src' => '/useruploads/test.png',
890
                        'width' => '50',
891
                        'height' => '60',
892
                    ]
893
            ]
894
        ];
895
        $result = $this->_Parser->parse($input);
896
        $this->assertHtml($expected, $result);
897
898
        // nested image does not have [domain.info]
899
        $input = '[url=http://heise.de][upload]test.png[/upload][/url]';
900
        $expected = "/richtext-linkInfo/";
901
        $result = $this->_Parser->parse($input);
902
        $this->assertNotRegExp($expected, $result);
903
    }
904
905
    public function testInternalImageExternallyLinked()
906
    {
907
        //// internal image
908
        $input = '[url=http://foo.de][upload]test.png[/upload][/url]';
909
        $expected = [
910
            [
911
                'a' => [
912
                    'href' => 'http://foo.de',
913
                    'rel' => 'external',
914
                    'target' => '_blank',
915
                ],
916
                'img' => [
917
                    'src' => '/useruploads/test.png',
918
                    'alt' => '',
919
                ]
920
            ],
921
        ];
922
        $result = $this->_Parser->parse($input);
923
        $this->assertHtml($expected, $result);
924
    }
925
926
    public function testUploadTypeImage()
927
    {
928
        //// internal image
929
        $input = '[img src=upload]test.png[/img]';
930
        $expected = [
931
            [
932
                'a' => [
933
                    'href' => '/useruploads/test.png',
934
                    'target' => '_blank',
935
                ],
936
                'img' => [
937
                    'src' => '/useruploads/test.png',
938
                    'alt' => '',
939
                ]
940
            ],
941
        ];
942
        $result = $this->_Parser->parse($input);
943
        $this->assertHtml($expected, $result);
944
    }
945
946
    public function testUploadTypeAudio()
947
    {
948
        //// internal image
949
        $input = '[audio src=upload]test.mp3[/audio]';
950
        $expected = [
951
            'audio' => [
952
                'controls' => 'controls',
953
                'preload' => 'auto',
954
                'src' => '/useruploads/test.mp3',
955
                'x-webkit-airplay' => 'allow',
956
            ]
957
        ];
958
        $result = $this->_Parser->parse($input);
959
        $this->assertHtml($expected, $result);
960
    }
961
962
    public function testUploadTypeVideo()
963
    {
964
        $input = '[video src=upload]test.mp4[/video]';
965
        $expected = [
966
            'video' => [
967
                'controls' => 'controls',
968
                'preload' => 'auto',
969
                'src' => '/useruploads/test.mp4',
970
                'x-webkit-airplay' => 'allow',
971
            ]
972
        ];
973
        $result = $this->_Parser->parse($input);
974
        $this->assertHtml($expected, $result);
975
    }
976
977
    public function testUploadTypeFile()
978
    {
979
        $input = '[file src=upload]test.txt[/file]';
980
        $expected = [
981
            'a' => [
982
                'href' => '/useruploads/test.txt',
983
                'target' => '_blank',
984
            ],
985
            'test.txt',
986
            '/a'
987
        ];
988
        $result = $this->_Parser->parse($input);
989
        $this->assertHtml($expected, $result);
990
    }
991
992
    public function testUploadTypeFileSrcNotValid()
993
    {
994
        $input = '[file src=foo]test.txt[/file]';
995
        $expected = [
996
            'div' => [
997
                'class' => 'richtext-imessage',
998
            ],
999
        ];
1000
        $result = $this->_Parser->parse($input);
1001
        $this->assertHtml($expected, $result);
1002
    }
1003
1004
    public function testUploadTypeFileNoSource()
1005
    {
1006
        $input = '[file]test.txt[/file]';
1007
        $result = $this->_Parser->parse($input);
1008
        $this->assertHtml($input, $result);
0 ignored issues
show
Bug introduced by
$input of type string is incompatible with the type array expected by parameter $expected of Cake\TestSuite\TestCase::assertHtml(). ( Ignorable by Annotation )

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

1008
        $this->assertHtml(/** @scrutinizer ignore-type */ $input, $result);
Loading history...
1009
    }
1010
1011
    public function testSmiliesNoSmiliesInCodeTag()
1012
    {
1013
        $input = '[code text]:)[/code]';
1014
        $needle = '<img';
1015
        $result = $this->_Parser->parse($input, ['cache' => false]);
1016
        $this->assertNotContains($needle, $result);
1017
    }
1018
1019
    public function testCodeNestedTags()
1020
    {
1021
        $input = '[code][b]text[b][/code]';
1022
        $expected = [
1023
            [
1024
                'div' => ['class' => 'geshi-wrapper']
1025
            ],
1026
            'preg:/.*?\[b\]text\[b\].*/',
1027
        ];
1028
        $result = $this->_Parser->parse($input);
1029
        $this->assertHtml($expected, $result);
1030
    }
1031
1032
    public function testCodeWhitespace()
1033
    {
1034
        $input = "[code]\ntest\n[/code]";
1035
        $expected = "/>test</";
1036
        $result = $this->_Parser->parse($input);
1037
        $this->assertRegExp($expected, $result);
1038
    }
1039
1040
    public function testCodeSimple()
1041
    {
1042
        $input = '[code]text[/code]';
1043
        $result = $this->_Parser->parse($input);
1044
        $expected = 'lang="text"';
1045
        $this->assertContains($expected, $result);
1046
    }
1047
1048
    public function testCodeLangAttribute()
1049
    {
1050
        $input = '[code=php]text[/code]';
1051
        $result = $this->_Parser->parse($input);
1052
        $expected = 'lang="php"';
1053
        $this->assertContains($expected, $result);
1054
    }
1055
1056
    /**
1057
     * tests that citation marks are not replaced in code-blocks
1058
     */
1059
    public function testCodeNoCitationMark()
1060
    {
1061
        // [code]<citation mark>[/code] should not be cited
1062
        $input = h(
1063
            "[code]\n" . $this->_Helper->getConfig('quote_symbol') . "\n[/code]"
1064
        );
1065
        $expected = '`span class=.*?richtext-citation`';
1066
        $result = $this->_Parser->parse($input);
1067
        $this->assertNotRegExp($expected, $result);
1068
    }
1069
1070
    public function testCodeDetaginize()
1071
    {
1072
        $input = '[code bash]pre http://example.com post[/code]';
1073
        $result = $this->_Parser->parse($input);
1074
        $this->assertNotContains('autoLink', $result);
1075
    }
1076
1077
    public function testQuote()
1078
    {
1079
        $_qs = $this->MarkupSettings->get('quote_symbol');
1080
        $input = $_qs . ' fo [b]test[/b] ba';
1081
        $result = $this->_Parser->parse($input);
1082
        $expected = [
1083
            'span' => ['class' => 'richtext-citation'],
1084
            $_qs . ' fo ',
1085
            'strong' => [],
1086
            'test',
1087
            '/strong',
1088
            ' ba',
1089
            '/span'
1090
        ];
1091
        $this->assertHtml($expected, $result);
1092
    }
1093
1094
    public function testHtml5Video()
1095
    {
1096
        //* setup
1097
        $bbcodeImg = Configure::read('Saito.Settings.bbcode_img');
1098
        Configure::write('Saito.Settings.bbcode_img', true);
1099
1100
        //* @td write video tests
1101
        $url = 'http://example.com/audio.mp4';
1102
        $input = "[video]{$url}[/video]";
1103
        $result = $this->_Parser->parse($input);
1104
        $expected = [
1105
            'video' => [
1106
                'src' => $url,
1107
                'preload' => 'auto',
1108
                'controls' => 'controls',
1109
                'x-webkit-airplay' => 'allow'
1110
            ],
1111
        ];
1112
        $this->assertHtml($expected, $result);
1113
1114
        //* teardown
1115
        Configure::write('Saito.Settings.bbcode_img', $bbcodeImg);
1116
    }
1117
1118
    public function testHr()
1119
    {
1120
        $input = '[hr][hr]';
1121
        $expected = '<hr><hr>';
1122
        $result = $this->_Parser->parse($input);
1123
        $this->assertEquals($result, $expected);
1124
    }
1125
1126
    public function testHrShort()
1127
    {
1128
        $input = '[---][---]';
1129
        $expected = '<hr><hr>';
1130
        $result = $this->_Parser->parse($input);
1131
        $this->assertEquals($result, $expected);
1132
    }
1133
1134
    public function testEmbedNoReplacement()
1135
    {
1136
        $input = '[embed]http://no.provider/unreplaced[/embed]';
1137
1138
        $result = $this->_Parser->parse($input);
1139
1140
        $expected = [
1141
            'div' => [
1142
                'class' => 'js-embed',
1143
                'data-embed' => '{&quot;url&quot;:&quot;http:\/\/no.provider\/unreplaced&quot;}',
1144
                'id' => 'embed-10478631dd9f8f00da95953f63f6e5f3',
1145
            ],
1146
            '/div',
1147
        ];
1148
1149
        $this->assertHtml($expected, $result);
1150
    }
1151
1152
    public function testEmbedDisabledWithoutAutolinking()
1153
    {
1154
        $this->MarkupSettings->setSingle('autolink', false);
1155
        $this->MarkupSettings->setSingle('content_embed_active', false);
1156
1157
        $url = 'http://foo.bar/baz';
1158
        $input = "[embed]{$url}[/embed]";
1159
1160
        $result = $this->_Parser->parse($input);
1161
1162
        $this->assertHtml($url, $result);
0 ignored issues
show
Bug introduced by
$url of type string is incompatible with the type array expected by parameter $expected of Cake\TestSuite\TestCase::assertHtml(). ( Ignorable by Annotation )

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

1162
        $this->assertHtml(/** @scrutinizer ignore-type */ $url, $result);
Loading history...
1163
    }
1164
1165
    public function testEmbedDisabledWithAutolinking()
1166
    {
1167
        $this->MarkupSettings->setSingle('autolink', true);
1168
        $this->MarkupSettings->setSingle('content_embed_active', false);
1169
1170
        $url = 'http://foo.bar/baz';
1171
        $input = "[embed]{$url}[/embed]";
1172
1173
        $result = $this->_Parser->parse($input);
1174
1175
        $expected = [
1176
            'a' => [
1177
                'href' => $url,
1178
                'target' => '_blank',
1179
            ],
1180
            $url,
1181
            '/a',
1182
        ];
1183
1184
        $this->assertHtml($expected, $result);
1185
    }
1186
1187
    public function testHtml5Audio()
1188
    {
1189
        //* setup
1190
        $bbcodeImg = Configure::read('Saito.Settings.bbcode_img');
1191
        Configure::write('Saito.Settings.bbcode_img', true);
1192
1193
        //* simple test
1194
        $url = 'http://example.com/audio3.m4a';
1195
        $input = "[audio]{$url}[/audio]";
1196
        $result = $this->_Parser->parse($input);
1197
        $expected = [
1198
            'audio' => [
1199
                'src' => $url,
1200
                'controls' => 'controls',
1201
                'preload' => 'auto',
1202
                'x-webkit-airplay' => 'allow',
1203
            ],
1204
            '/audio',
1205
        ];
1206
        $this->assertHtml($expected, $result);
1207
1208
        //* teardown
1209
        Configure::write('Saito.Settings.bbcode_img', $bbcodeImg);
1210
    }
1211
1212
    /* ******************** Setup ********************** */
1213
1214
    public function setUp()
1215
    {
1216
        Cache::clear();
1217
1218
        if (Cache::getConfig('bbcodeParserEmbed') === null) {
1219
            Cache::setConfig(
1220
                'bbcodeParserEmbed',
1221
                [
1222
                    'className' => 'File',
1223
                    'prefix' => 'saito_embed-',
1224
                    'path' => CACHE,
1225
                    'groups' => ['embed'],
1226
                    'duration' => '+1 year'
1227
1228
                ]
1229
            );
1230
        }
1231
1232
        if (isset($_SERVER['SERVER_NAME'])) {
1233
            $this->server_name = $_SERVER['SERVER_NAME'];
1234
        } else {
1235
            $this->server_name = false;
1236
        }
1237
1238
        if (isset($_SERVER['SERVER_PORT'])) {
1239
            $this->server_port = $_SERVER['SERVER_PORT'];
1240
        } else {
1241
            $this->server_port = false;
1242
        }
1243
1244
        $this->autolink = Configure::read('Saito.Settings.autolink');
1245
        Configure::write('Saito.Settings.autolink', true);
1246
1247
        $_SERVER['SERVER_NAME'] = 'macnemo.de';
1248
        $_SERVER['SERVER_PORT'] = '80';
1249
1250
        parent::setUp();
1251
1252
        $View = new View();
1253
1254
        //= smiley fixture
1255
        $smiliesFixture = [
1256
            [
1257
                'order' => 1,
1258
                'icon' => 'wink.png',
1259
                'image' => 'wink.png',
1260
                'title' => 'Wink',
1261
                'code' => ';)',
1262
                'type' => 'image'
1263
            ],
1264
            [
1265
                'order' => 2,
1266
                'icon' => 'smile_icon.svg',
1267
                'image' => 'smile_image.svg',
1268
                'title' => 'Smile',
1269
                'code' => ':-)',
1270
                'type' => 'image'
1271
            ],
1272
            [
1273
                'order' => 3,
1274
                'icon' => 'coffee',
1275
                'image' => 'coffee',
1276
                'title' => 'Coffee',
1277
                'code' => '[_]P',
1278
                'type' => 'font'
1279
            ],
1280
        ];
1281
        Cache::write('Saito.Smilies.data', $smiliesFixture);
1282
        $SmileyLoader = new \Saito\Smiley\SmileyLoader();
1283
1284
        //= userlist fixture
1285
        $Userlist = $this->getMockBuilder(UserlistModel::class)
1286
            ->disableOriginalConstructor()
1287
            ->setMethods(['get'])
1288
            ->getMock();
1289
        $Userlist->method('get')->willReturn(['Alice', 'Bobby Junior', 'Dr. No']);
1290
1291
        //= ParserHelper
1292
        $markupSettingsMock = new class extends MarkupSettings {
1293
            public function setSingle(string $key, $value)
1294
            {
1295
                $this->_settings[$key] = $value;
1296
            }
1297
        };
1298
        $this->MarkupSettings = new $markupSettingsMock([
1299
            'UserList' => $Userlist,
1300
            'atBaseUrl' => '/at/',
1301
            'autolink' => true,
1302
            'bbcode_img' => true,
1303
            'content_embed_active' => true,
1304
            'content_embed_media' => true,
1305
            'content_embed_text' => true,
1306
            'hashBaseUrl' => '/hash/',
1307
            'quote_symbol' => '»',
1308
            'smilies' => true,
1309
            'smiliesData' => $SmileyLoader,
1310
            'text_word_maxlength' => 100000,
1311
            'video_domains_allowed' => 'youtube',
1312
            'webroot' => ''
1313
        ]);
1314
        $this->_Helper = $ParserHelper = new ParserHelper($View);
0 ignored issues
show
Bug Best Practice introduced by
The property _Helper does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1315
        $ParserHelper->beforeRender(null);
1316
1317
        //= Smiley Renderer
1318
        $this->_Helper->getView()->set('smiliesData', $SmileyLoader);
1319
1320
        //= Parser
1321
        $this->_Parser = new Parser($ParserHelper, $this->MarkupSettings);
1322
    }
1323
1324
    public function tearDown()
1325
    {
1326
        parent::tearDown();
1327
        if ($this->server_name) {
0 ignored issues
show
Bug Best Practice introduced by
The property server_name does not exist on BbcodeParser\Test\Lib\BbcodeParserTest. Did you maybe forget to declare it?
Loading history...
1328
            $_SERVER['SERVER_NAME'] = $this->server_name;
1329
        }
1330
1331
        if ($this->server_name) {
1332
            $_SERVER['SERVER_PORT'] = $this->server_port;
0 ignored issues
show
Bug Best Practice introduced by
The property server_port does not exist on BbcodeParser\Test\Lib\BbcodeParserTest. Did you maybe forget to declare it?
Loading history...
1333
        }
1334
1335
        Configure::write('Saito.Settings.autolink', $this->autolink);
0 ignored issues
show
Bug Best Practice introduced by
The property autolink does not exist on BbcodeParser\Test\Lib\BbcodeParserTest. Did you maybe forget to declare it?
Loading history...
1336
1337
        Cache::clear();
1338
        unset($this->_Parser);
1339
    }
1340
}
1341