Completed
Push — master ( 5b5792...2b84bd )
by Schlaefer
03:33 queued 11s
created

BbcodeParserTest::testImageNestedInExternalLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26

Duplication

Lines 26
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 26
loc 26
rs 9.504
c 0
b 0
f 0
1
<?php
2
3
namespace BbcodeParser\Test\Lib;
4
5
use App\View\Helper\ParserHelper;
6
use Cake\Cache\Cache;
7
use Cake\Core\Configure;
8
use Cake\View\View;
9
use Plugin\BbcodeParser\Lib;
10
use Plugin\BbcodeParser\src\Lib\Parser;
11
use Saito\Markup\MarkupSettings;
12
use Saito\Test\SaitoTestCase;
13
use Saito\User\Userlist;
14
use Saito\User\Userlist\UserlistModel;
15
16
class BbcodeParserTest extends SaitoTestCase
17
{
18
19
    /**
20
     * @var Parser
21
     */
22
    protected $_Parser = null;
23
24
    /** @var MarkupSettings */
25
    protected $MarkupSettings;
26
27 View Code Duplication
    public function testBold()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
28
    {
29
        $input = '[b]bold[/b]';
30
        $expected = ['strong' => [], 'bold', '/strong'];
31
        $result = $this->_Parser->parse($input);
32
        $this->assertHtml($expected, $result);
33
    }
34
35 View Code Duplication
    public function testEmphasis()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
36
    {
37
        $input = '[i]italic[/i]';
38
        $expected = ['em' => [], 'italic', '/em'];
39
        $result = $this->_Parser->parse($input);
40
        $this->assertHtml($expected, $result);
41
    }
42
43 View Code Duplication
    public function testQuoteblock()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
44
    {
45
        $input = '[quote]foo bar[/quote]';
46
        $expected = ['blockquote' => [], 'foo bar', '/blockquote'];
47
        $result = $this->_Parser->parse($input);
48
        $this->assertHtml($expected, $result);
49
    }
50
51
    public function testStrike()
52
    {
53
        $expected = ['del' => [], 'text', '/del'];
54
55
        // [strike]
56
        $input = '[strike]text[/strike]';
57
        $result = $this->_Parser->parse($input);
58
        $this->assertHtml($expected, $result);
59
60
        // [s]
61
        $input = '[s]text[/s]';
62
        $result = $this->_Parser->parse($input);
63
        $this->assertHtml($expected, $result);
64
    }
65
66
    public function testSpoiler()
67
    {
68
        $input = 'pre [spoiler] te "\' xt[/spoiler]';
69
        $expected = [
70
            'pre',
71
            [
72
                'div' => [
73
                    'class' => 'richtext-spoiler',
74
                    'style' => 'display: inline;'
75
                ]
76
            ],
77
            ['script' => true],
78
            'preg:/(.*?)"string":" te &quot;&#039; xt"(.*?)(?=<)/',
79
            '/script',
80
            [
81
                'a' => [
82
                    'href' => '#',
83
                    'class' => 'richtext-spoiler-link',
84
                    'onclick'
85
                ]
86
            ],
87
            'preg:/.*▇ Spoiler ▇.*?(?=<)/',
88
            '/a',
89
            '/div'
90
        ];
91
        $result = $this->_Parser->parse($input);
92
        $this->assertHtml($expected, $result);
93
    }
94
95
    public function testList()
96
    {
97
        $input = "[list]\n[*]fooo\n[*]bar\n[/list]";
98
        $expected = [
99
            ['ul' => []],
100
            ['li' => []],
101
            'fooo',
102
            ['br' => []],
103
            '/li',
104
            ['li' => []],
105
            'bar',
106
            ['br' => []],
107
            '/li',
108
            '/ul'
109
        ];
110
        $result = $this->_Parser->parse($input);
111
        $this->assertHtml($expected, $result);
112
    }
113
114 View Code Duplication
    public function testMaskLinkWithoutProtocol()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
    {
116
        $input = '[url=thetempe.st/station]purge[/url]';
117
        $expected = [
118
            'a' => [
119
                'href' => 'http://thetempe.st/station',
120
                'rel' => 'external',
121
                'target' => '_blank'
122
            ],
123
            'purge',
124
            '/a'
125
        ];
126
        $result = $this->_Parser->parse($input);
127
        $this->assertHtml($expected, $result);
128
    }
129
130
    public function testParserEngineCaching()
131
    {
132
        $input = '[img=]foo.png[/img]';
133
        $result = $this->_Parser->parse($input, ['multimedia' => true]);
134
        $this->assertContains('<img src', $result);
135
        $result = $this->_Parser->parse($input, ['multimedia' => false]);
136
        $this->assertNotContains('<img src', $result);
137
    }
138
139
    public function testLink()
140
    {
141
        $input = '[url=http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=250678480561&ssPageName=ADME:X:RTQ:DE:1123]test[/url]';
142
        $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>";
143
        $result = $this->_Parser->parse($input);
144
        $this->assertEquals($expected, $result);
145
146
        /*
147
         * external server
148
         */
149
        $input = '[url]http://heise.de/foobar[/url]';
150
        $expected = [
151
            'a' => [
152
                'href' => 'http://heise.de/foobar',
153
                'rel' => 'external',
154
                'target' => '_blank'
155
            ],
156
            'http://heise.de/foobar',
157
            '/a'
158
        ];
159
        $result = $this->_Parser->parse($input);
160
        $this->assertHtml($expected, $result);
161
162
        $input = '[link]http://heise.de/foobar[/link]';
163
        $expected = [
164
            'a' => [
165
                'href' => 'http://heise.de/foobar',
166
                'rel' => 'external',
167
                'target' => '_blank'
168
            ],
169
            'http://heise.de/foobar',
170
            '/a'
171
        ];
172
        $result = $this->_Parser->parse($input);
173
        $this->assertHtml($expected, $result);
174
175
        // masked link
176
        $input = '[url=http://heise.de/foobar]foobar[/url]';
177
        $expected = [
178
            'a' => [
179
                'href' => 'http://heise.de/foobar',
180
                'rel' => 'external',
181
                'target' => '_blank'
182
            ],
183
            'foobar',
184
            '/a',
185
            'span' => ['class' => 'richtext-linkInfo'],
186
            '[heise.de]',
187
            '/span'
188
        ];
189
        $result = $this->_Parser->parse($input);
190
        $this->assertHtml($expected, $result);
191
192
        // masked link with no label
193
        $input = '[url=http://heise.de/foobar  label=none ]foobar[/url]';
194
        $expected = [
195
            'a' => [
196
                'href' => 'http://heise.de/foobar',
197
                'rel' => 'external',
198
                'target' => '_blank',
199
            ],
200
            'foobar',
201
            '/a',
202
        ];
203
        $result = $this->_Parser->parse($input);
204
        $this->assertHtml($expected, $result);
205
206
        /*
207
         * local server
208
         */
209
        $input = '[url=http://macnemo.de/foobar]foobar[/url]';
210
        $expected = "<a href='http://macnemo.de/foobar'>foobar</a>";
211
        $result = $this->_Parser->parse($input);
212
        $this->assertEquals($expected, $result);
213
214
        $input = '[url]/foobar[/url]';
215
        $expected = [
216
            'a' => [
217
                'href' => '/foobar',
218
            ],
219
            'preg:/\/foobar/',
220
            '/a',
221
        ];
222
        $result = $this->_Parser->parse($input);
223
        $this->assertHtml($expected, $result);
224
225
        // test lokaler server with absolute url
226
        $input = '[url=/foobar]foobar[/url]';
227
        $expected = "<a href='/foobar'>foobar</a>";
228
        $result = $this->_Parser->parse($input);
229
        $this->assertEquals($expected, $result);
230
231
        // test 'http://' only
232
        $input = '[url=http://]foobar[/url]';
233
        $expected = "<a href='http://'>foobar</a>";
234
        $result = $this->_Parser->parse($input);
235
        $this->assertEquals($expected, $result);
236
237
        // test for co.uk
238
        $input = '[url=http://heise.co.uk/foobar]foobar[/url]';
239
        $expected = [
240
            'a' => [
241
                'href' => 'http://heise.co.uk/foobar',
242
                'rel' => 'external',
243
                'target' => '_blank'
244
            ],
245
            'foobar',
246
            '/a',
247
            'span' => ['class' => 'richtext-linkInfo'],
248
            '[heise.co.uk]',
249
            '/span'
250
        ];
251
        $result = $this->_Parser->parse($input);
252
        $this->assertHtml($expected, $result);
253
    }
254
255
    public function testHashLinkSuccess()
256
    {
257
        // inline content ([i])
258
        $input = "[i]#2234[/i]";
259
        $expected = [
260
            'em' => [],
261
            'a' => [
262
                'href' => '/hash/2234'
263
            ],
264
            '#2234',
265
            '/a',
266
            '/em'
267
        ];
268
        $result = $this->_Parser->parse($input);
269
        $this->assertHtml($expected, $result);
270
271
        // lists
272
        $input = "[list][*]#2234[/list]";
273
        $expected = [
274
            'ul' => true,
275
            'li' => true,
276
            'a' => [
277
                'href' => '/hash/2234'
278
            ],
279
            '#2234',
280
            '/a',
281
            '/li',
282
            '/ul'
283
        ];
284
        $result = $this->_Parser->parse($input);
285
        $this->assertHtml($expected, $result);
286
    }
287
288
    public function testHashLinkFailure()
289
    {
290
        // don't hash code
291
        $input = '[code]#2234[/code]';
292
        $result = $this->_Parser->parse($input);
293
        $this->assertNotContains('>#2234</a>', $result);
294
295
        // not a valid hash
296
        $input = '#2234t';
297
        $result = $this->_Parser->parse($input);
298
        $this->assertEquals('#2234t', $result);
299
    }
300
301
    public function testAtLinkKnownUsers()
302
    {
303
        $input = '@Alice @Bob @Bobby Junior @Bobby Tables @Dr. No';
304
        $expected =
305
            "<a href='/at/Alice'>@Alice</a>" .
306
            " @Bob " .
307
            "<a href='/at/Bobby+Junior'>@Bobby Junior</a>" .
308
            " @Bobby Tables " .
309
            "<a href='/at/Dr.+No'>@Dr. No</a>";
310
311
        $result = $this->_Parser->parse($input);
312
        $this->assertEquals(
313
            $expected,
314
            $result,
315
            '@User string is not replaced with link to user profile.'
316
        );
317
318
        $input = '[code]@Alice[/code]';
319
        $result = $this->_Parser->parse($input);
320
        $this->assertNotContains('>@Alice</a>', $result);
321
    }
322
323 View Code Duplication
    public function testAtLinkKnownUsersLinebreak()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
324
    {
325
        $input = "@Alice\nfoo";
326
        $result = $this->_Parser->parse($input);
327
        $expected = [
328
            'a' => ['href' => '/at/Alice'],
329
            '@Alice',
330
            '/a',
331
            'br' => true
332
        ];
333
        $this->assertHtml($expected, $result);
334
    }
335
336 View Code Duplication
    public function testLinkEmptyUrl()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
    {
338
        $input = '[url=][/url]';
339
        $expected = "<a href=''></a>";
340
        $result = $this->_Parser->parse($input);
341
        $this->assertEquals($expected, $result);
342
    }
343
344 View Code Duplication
    public function testEditMarker()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
    {
346
        $input = 'pre [e] post';
347
        $expected = [
348
            'pre ',
349
            'span' => [
350
                'class' => 'richtext-editMark'
351
            ],
352
            '/span',
353
            ' post'
354
        ];
355
        $result = $this->_Parser->parse($input);
356
        $this->assertHtml($expected, $result);
357
    }
358
359
    /*
360
     * without obfuscator
361
     *
362
    public function testEmail() {
363
        /*
364
            // mailto:
365
            $input = '[email]mailto:[email protected][/email]';
366
            $expected = "<a href='mailto:[email protected]'>mailto:[email protected]</a>";
367
            $result = $this->Bbcode->parse($input);
368
            $this->assertEquals($expected, $result);
369
370
            // mailto: mask
371
            $input = '[email=mailto:[email protected]]Mail[/email]';
372
            $expected = "<a href='mailto:[email protected]'>Mail</a>";
373
            $result = $this->Bbcode->parse($input);
374
            $this->assertEquals($expected, $result);
375
376
            // no mailto:
377
            $input = '[email][email protected][/email]';
378
            $expected = "<a href='mailto:[email protected]'>[email protected]</a>";
379
            $result = $this->Bbcode->parse($input);
380
            $this->assertEquals($expected, $result);
381
382
            // no mailto: mask
383
            $input = '[[email protected]]Mail[/email]';
384
            $expected = "<a href='mailto:[email protected]'>Mail</a>";
385
            $result = $this->Bbcode->parse($input);
386
            $this->assertEquals($expected, $result);
387
    }
388
            */
389
390 View Code Duplication
    public function testEmailMailto()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
391
    {
392
        $MO = $this->getMockBuilder('MailObfuscator')
393
            ->setMethods(['link'])
394
            ->getMock();
395
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to BbcodeParserTest::once() has too many arguments starting with 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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
396
            ->method('link')
397
            ->with('[email protected]', null);
398
        $this->_Helper->MailObfuscator = $MO;
0 ignored issues
show
Bug introduced by
The property _Helper does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
399
400
        $input = '[email]mailto:[email protected][/email]';
401
        $this->_Parser->parse($input);
402
    }
403
404 View Code Duplication
    public function testEmailMailtoMask()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
405
    {
406
        $MO = $this->getMockBuilder('MailObfuscator')
407
            ->setMethods(['link'])
408
            ->getMock();
409
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to BbcodeParserTest::once() has too many arguments starting with 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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
410
            ->method('link')
411
            ->with('[email protected]', 'Mail');
412
        $this->_Helper->MailObfuscator = $MO;
413
414
        $input = '[email=mailto:[email protected]]Mail[/email]';
415
        $this->_Parser->parse($input);
416
    }
417
418 View Code Duplication
    public function testEmailNoMailto()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
419
    {
420
        $MO = $this->getMockBuilder('MailObfuscator')
421
            ->setMethods(['link'])
422
            ->getMock();
423
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to BbcodeParserTest::once() has too many arguments starting with 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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
424
            ->method('link')
425
            ->with('[email protected]', null);
426
        $this->_Helper->MailObfuscator = $MO;
427
428
        $input = '[email][email protected][/email]';
429
        $this->_Parser->parse($input);
430
    }
431
432 View Code Duplication
    public function testEmailNoMailtoMask()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
433
    {
434
        $MO = $this->getMockBuilder('MailObfuscator')
435
            ->setMethods(['link'])
436
            ->getMock();
437
        $MO->expects($this->once(4))
0 ignored issues
show
Unused Code introduced by
The call to BbcodeParserTest::once() has too many arguments starting with 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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
438
            ->method('link')
439
            ->with('[email protected]', 'Mail');
440
        $this->_Helper->MailObfuscator = $MO;
441
442
        $input = '[[email protected]]Mail[/email]';
443
        $this->_Parser->parse($input);
444
    }
445
446
    public function testFlash()
447
    {
448
        $bbcode = '[flash_video]//www.youtube.com/v/MrBRPYlrGF8?version=3&amp;hl=en_US|560|315[/flash_video]';
449
        $expected = <<<EOF
450
			<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="315">
451
									<param name="movie" value="//www.youtube.com/v/MrBRPYlrGF8?version=3&amp;amp;hl=en_US"></param>
452
									<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>
453
EOF;
454
        $actual = $this->_Parser->parse(
455
            $bbcode,
456
            ['video_domains_allowed' => 'youtube']
457
        );
458
        $this->assertEquals(trim($expected), trim($actual));
459
    }
460
461 View Code Duplication
    public function testFloat()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
462
    {
463
        $expected = [
464
            ['div' => ['class' => 'clearfix']],
465
            '/div',
466
            ['div' => ['class' => 'richtext-float']],
467
            'text',
468
            '/div',
469
            'more'
470
        ];
471
472
        $input = '[float]text[/float]more';
473
        $result = $this->_Parser->parse($input);
474
        $this->assertHtml($expected, $result);
475
    }
476
477
    public function testLinkAuto()
478
    {
479
        $input = 'http://heise.de/foobar';
480
        $expected = "<a href='http://heise.de/foobar' rel='external' target='_blank'>http://heise.de/foobar</a>";
481
        $result = $this->_Parser->parse($input);
482
        $this->assertEquals($expected, $result);
483
484
        // autolink surrounded by text
485
        $input = 'some http://heise.de/foobar text';
486
        $expected = "some <a href='http://heise.de/foobar' rel='external' target='_blank'>http://heise.de/foobar</a> text";
487
        $result = $this->_Parser->parse($input);
488
        $this->assertEquals($expected, $result);
489
490
        // no autolink in [code]
491
        $input = '[code]http://heise.de/foobar[/code]';
492
        $needle = 'heise.de/foobar</a>';
493
        $result = $this->_Parser->parse($input);
494
        $this->assertNotContains($result, $needle);
495
496
        // no autolink in [url]
497
        $input = '[url=http://a.com/]http://b.de/[/url]';
498
        $result = $this->_Parser->parse($input);
499
        $this->assertRegExp(
500
            '#href=["\']http://a.com/["\'][^>]*?>http://b.de/#',
501
            $result
502
        );
503
504
        // email autolink
505
        $input = 'text [email protected] test';
506
        // $expected = "text <a href='mailto:[email protected]'>[email protected]</a> test";
507
        $result = $this->_Parser->parse($input);
508
        // $this->assertEquals($expected, $result);
509
        // @bogus weak test
510
        $this->assertRegExp('/^text .*href=".* test$/sm', $result);
511
512
        //# in list
513
        $input = <<<EOF
514
[list]
515
[*] http://heise.de
516
[/list]
517
EOF;
518
        $result = $this->_Parser->parse($input);
519
        $expected = "<a href='http://heise.de";
520
        $this->assertTextContains($expected, $result);
521
    }
522
523 View Code Duplication
    public function testLinkAutoWithoutHttpPrefix()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
524
    {
525
        $input = 'some www.example.com/foobar text';
526
        $expected = [
527
            'some ',
528
            'a' => [
529
                'href' => 'http://www.example.com/foobar',
530
                'rel' => 'external',
531
                'target' => '_blank',
532
            ],
533
            'http://www.example.com/foobar',
534
            '/a',
535
            ' text'
536
        ];
537
        $result = $this->_Parser->parse($input);
538
        $this->assertHtml($expected, $result);
539
    }
540
541 View Code Duplication
    public function testLinkAutoUrlWithinParentheses()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
542
    {
543
        $input = 'some (www.example.com/foobar) text';
544
        $expected = [
545
            'some (',
546
            'a' => [
547
                'href' => 'http://www.example.com/foobar',
548
                'rel' => 'external',
549
                'target' => '_blank',
550
            ],
551
            'http://www.example.com/foobar',
552
            '/a',
553
            ') text'
554
        ];
555
        $result = $this->_Parser->parse($input);
556
        $this->assertHtml($expected, $result);
557
    }
558
559
    public function testLinkAutoSurroundingChars()
560
    {
561
        $input = 'text http://example.com/?foo,,, text';
562
        $result = $this->_Parser->parse($input);
563
        $expected = [
564
            'text ',
565
            'a' => [
566
                'href' => 'http://example.com/?foo,,',
567
                'rel' => 'external',
568
                'target' => '_blank',
569
            ],
570
            'http://example.com/?foo,,',
571
            '/a',
572
            ', text'
573
        ];
574
        $this->assertHtml($expected, $result);
575
576
        // Question mark
577
        $input = 'question http://example.com/? Text';
578
        $result = $this->_Parser->parse($input);
579
        $expected = [
580
            'question ',
581
            'a' => [
582
                'href' => 'http://example.com/',
583
                'rel' => 'external',
584
                'target' => '_blank',
585
            ],
586
            'http://example.com/',
587
            '/a',
588
            '? Text'
589
        ];
590
        $this->assertHtml($expected, $result);
591
592
        // No Question mark but url
593
        $input = 'no question http://example.com/?foo=bar text';
594
        $result = $this->_Parser->parse($input);
595
        $expected = [
596
            'no question ',
597
            'a' => [
598
                'href' => 'http://example.com/?foo=bar',
599
                'rel' => 'external',
600
                'target' => '_blank',
601
            ],
602
            'http://example.com/?foo=bar',
603
            '/a',
604
            ' text'
605
        ];
606
        $this->assertHtml($expected, $result);
607
    }
608
609
    public function testReturnText()
610
    {
611
        $in = 'test [b]test[b] test';
612
        $expected = 'test test test';
613
        $actual = $this->_Parser->parse($in, ['return' => 'text']);
614
        $this->assertEquals($expected, $actual);
615
    }
616
617
    public function testShortenLink()
618
    {
619
        $maxLength = 15;
620
        $this->MarkupSettings->setSingle('text_word_maxlength', $maxLength);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
621
622
        $input = '[url]http://this/url/is/32/chars/long[/url]';
623
        $expected = "<a href='http://this/url/is/32/chars/long' rel='external' target='_blank'>http:// … /long</a>";
624
625
        $result = $this->_Parser->parse($input);
626
        $this->assertEquals($expected, $result);
627
628
        $input = 'http://this/url/is/32/chars/long';
629
        $expected = "<a href='http://this/url/is/32/chars/long' rel='external' target='_blank'>http:// … /long</a>";
630
        $result = $this->_Parser->parse($input);
631
        $this->assertEquals($expected, $result);
632
    }
633
634
    public function testIframe()
635
    {
636
        //* test allowed domain
637
        $input = '[iframe height=349 width=560 ' .
638
            'src=http://www.youtube.com/embed/HdoW3t_WorU ' .
639
            'frameborder=0][/iframe]';
640
        $expected = [
641
            [
642
                'div' => [
643
                    'class' => 'embed-responsive embed-responsive-16by9',
644
                ],
645
                'iframe' => [
646
                    'class' => 'embed-responsive-item',
647
                    'src' => 'http://www.youtube.com/embed/HdoW3t_WorU?&amp;wmode=Opaque',
648
                    'height' => '349',
649
                    'width' => '560',
650
                    'frameborder' => '0'
651
                ]
652
            ],
653
            '/iframe',
654
        ];
655
        $result = $this->_Parser->parse(
656
            $input,
657
            ['video_domains_allowed' => 'youtube | vimeo']
658
        );
659
        $this->assertHtml($expected, $result);
660
661
        //* test forbidden domains
662
        $input = '[iframe height=349 width=560 ' .
663
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
664
            'frameborder=0][/iframe]';
665
        $pattern = '/src/i';
666
        $result = $this->_Parser->parse(
667
            $input,
668
            ['video_domains_allowed' => 'youtube | vimeo']
669
        );
670
        $this->assertNotRegExp($pattern, $result);
671
    }
672
673
    public function testIframeAllDomainsAllowed()
674
    {
675
        $input = '[iframe height=349 width=560 ' .
676
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
677
            '][/iframe]';
678
        $expected = 'src="http://www.youtubescam.com/embed/HdoW3t_WorU';
679
        $this->MarkupSettings->setSingle('video_domains_allowed', '*');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
680
        $result = $this->_Parser->parse($input);
681
        $this->assertContains($expected, $result);
682
    }
683
684
    public function testIframeNoDomainAllowed()
685
    {
686
        $input = '[iframe height=349 width=560 ' .
687
            'src=http://www.youtubescam.com/embed/HdoW3t_WorU ' .
688
            '][/iframe]';
689
        $expected = '/src/i';
690
        $result = $this->_Parser->parse(
691
            $input,
692
            ['video_domains_allowed' => '']
693
        );
694
        $this->assertNotRegExp($expected, $result);
695
    }
696
697 View Code Duplication
    public function testExternalImageAbsoluteAutoLinked()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
698
    {
699
        // test for standard URIs
700
        $input = '[img]http://foo.bar/img/macnemo.png[/img]';
701
        $expected = [
702
            'a' => [
703
                'href' => 'http://foo.bar/img/macnemo.png',
704
                // 'rel' => 'external',
705
                'target' => '_blank',
706
            ],
707
            'img' => [
708
                'src' => 'http://foo.bar/img/macnemo.png',
709
                'alt' => ''
710
            ]
711
        ];
712
        $result = $this->_Parser->parse($input);
713
        $this->assertHtml($expected, $result);
714
    }
715
716 View Code Duplication
    public function testExternalImageRelativeAutoLinked()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
717
    {
718
        // test for standard URIs
719
        $input = '[img]/somewhere/macnemo.png[/img]';
720
        $expected = [
721
            'a' => [
722
                'href' => '/somewhere/macnemo.png',
723
                'target' => '_blank',
724
            ],
725
            'img' => [
726
                'src' => '/somewhere/macnemo.png',
727
                'alt' => ''
728
            ]
729
        ];
730
        $result = $this->_Parser->parse($input);
731
        $this->assertHtml($expected, $result);
732
    }
733
734
    /**
735
     * test scaling with 1 parameter
736
     */
737 View Code Duplication
    public function testExternalImageAbsoluteAutoLinkedScaledByOne()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
738
    {
739
        // test for standard URIs
740
        $input = '[img=50]http://foo.bar/img/macnemo.png[/img]';
741
        $expected = [
742
            'a' => [
743
                'href' => 'http://foo.bar/img/macnemo.png',
744
                'target' => '_blank',
745
            ],
746
            'img' => [
747
                'src' => 'http://foo.bar/img/macnemo.png',
748
                'alt' => '',
749
                'width' => '50',
750
            ]
751
        ];
752
        $result = $this->_Parser->parse($input);
753
        $this->assertHtml($expected, $result);
754
    }
755
756
    /**
757
     * test scaling with 2 parameter
758
     */
759 View Code Duplication
    public function testExternalImageAbsoluteAutoLinkedScaledByTwo()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
760
    {
761
        // test for standard URIs
762
        $input = '[img=50x100]http://foo.bar/img/macnemo.png[/img]';
763
        $expected = [
764
            'a' => [
765
                'href' => 'http://foo.bar/img/macnemo.png',
766
                'target' => '_blank',
767
            ],
768
            'img' => [
769
                'src' => 'http://foo.bar/img/macnemo.png',
770
                'alt' => '',
771
                'height' => '100',
772
                'width' => '50',
773
            ]
774
        ];
775
        $result = $this->_Parser->parse($input);
776
        $this->assertHtml($expected, $result);
777
    }
778
779
    public function testExternalImageWithHttpsEnforced()
780
    {
781
        $_SERVER['HTTPS'] = true;
782
        $input = '[img=]http://foo.bar/img/macnemo.png[/img]';
783
        $expected = [
784
            'a' => [
785
                'href' => 'https://foo.bar/img/macnemo.png',
786
                'target' => '_blank',
787
            ],
788
            'img' => [
789
                'src' => 'https://foo.bar/img/macnemo.png',
790
                'alt' => '',
791
            ]
792
        ];
793
        $result = $this->_Parser->parse($input);
794
        $this->assertHtml($expected, $result);
795
        unset($_SERVER['HTTPS']);
796
    }
797
798 View Code Duplication
    public function testImageNestedInExternalLink()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
799
    {
800
        $input = '[url=http://heise.de][img]http://heise.de/img.png[/img][/url]';
801
802
        /*
803
        $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>";
804
        */
805
        $expected = [
806
            [
807
                'a' => [
808
                    'href' => 'http://heise.de',
809
                    'rel' => 'external',
810
                    'target' => '_blank',
811
                ]
812
            ],
813
            [
814
                'img' => [
815
                    'src' => 'http://heise.de/img.png',
816
                    'alt' => '',
817
                ]
818
            ],
819
            '/a'
820
        ];
821
        $result = $this->_Parser->parse($input);
822
        $this->assertHtml($expected, $result);
823
    }
824
825
    /**
826
     * [uploads]<image>[/uploads]
827
     */
828
    public function testInternalImageAutoLinked()
829
    {
830
        //// internal image
831
        $input = '[upload]test.png[/upload]';
832
        $expected = [
833
            [
834
                'a' => [
835
                    'href' => '/useruploads/test.png',
836
                    'target' => '_blank',
837
                ],
838
                'img' => [
839
                    'alt' => '',
840
                    'src' => '/useruploads/test.png',
841
                ],
842
            ],
843
        ];
844
        $result = $this->_Parser->parse($input);
845
        $this->assertHtml($expected, $result);
846
847
        //// internal image with attributes
848
        $input = '[upload width=50 height=60]test.png[/upload]';
849
        $expected = [
850
            [
851
                'a' => [
852
                    'href' => '/useruploads/test.png',
853
                    'target' => '_blank',
854
                ],
855
                'img' =>
856
                    [
857
                        'alt' => '',
858
                        'src' => '/useruploads/test.png',
859
                        'width' => '50',
860
                        'height' => '60',
861
                    ]
862
            ]
863
        ];
864
        $result = $this->_Parser->parse($input);
865
        $this->assertHtml($expected, $result);
866
867
        // nested image does not have [domain.info]
868
        $input = '[url=http://heise.de][upload]test.png[/upload][/url]';
869
        $expected = "/richtext-linkInfo/";
870
        $result = $this->_Parser->parse($input);
871
        $this->assertNotRegExp($expected, $result);
872
    }
873
874 View Code Duplication
    public function testInternalImageExternallyLinked()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
875
    {
876
        //// internal image
877
        $input = '[url=http://foo.de][upload]test.png[/upload][/url]';
878
        $expected = [
879
            [
880
                'a' => [
881
                    'href' => 'http://foo.de',
882
                    'rel' => 'external',
883
                    'target' => '_blank',
884
                ],
885
                'img' => [
886
                    'src' => '/useruploads/test.png',
887
                    'alt' => '',
888
                ]
889
            ],
890
        ];
891
        $result = $this->_Parser->parse($input);
892
        $this->assertHtml($expected, $result);
893
    }
894
895
    public function testUploadTypeImage()
896
    {
897
        //// internal image
898
        $input = '[img src=upload]test.png[/img]';
899
        $expected = [
900
            [
901
                'a' => [
902
                    'href' => '/useruploads/test.png',
903
                    'target' => '_blank',
904
                ],
905
                'img' => [
906
                    'src' => '/useruploads/test.png',
907
                    'alt' => '',
908
                ]
909
            ],
910
        ];
911
        $result = $this->_Parser->parse($input);
912
        $this->assertHtml($expected, $result);
913
    }
914
915
    public function testUploadTypeAudio()
916
    {
917
        //// internal image
918
        $input = '[audio src=upload]test.mp3[/audio]';
919
        $expected = [
920
            'audio' => [
921
                'controls' => 'controls',
922
                'preload' => 'auto',
923
                'src' => '/useruploads/test.mp3',
924
                'x-webkit-airplay' => 'allow',
925
            ]
926
        ];
927
        $result = $this->_Parser->parse($input);
928
        $this->assertHtml($expected, $result);
929
    }
930
931
    public function testUploadTypeVideo()
932
    {
933
        $input = '[video src=upload]test.mp4[/video]';
934
        $expected = [
935
            'video' => [
936
                'controls' => 'controls',
937
                'preload' => 'auto',
938
                'src' => '/useruploads/test.mp4',
939
                'x-webkit-airplay' => 'allow',
940
            ]
941
        ];
942
        $result = $this->_Parser->parse($input);
943
        $this->assertHtml($expected, $result);
944
    }
945
946 View Code Duplication
    public function testUploadTypeFile()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
947
    {
948
        $input = '[file src=upload]test.txt[/file]';
949
        $expected = [
950
            'a' => [
951
                'href' => '/useruploads/test.txt',
952
                'target' => '_blank',
953
            ],
954
            'test.txt',
955
            '/a'
956
        ];
957
        $result = $this->_Parser->parse($input);
958
        $this->assertHtml($expected, $result);
959
    }
960
961 View Code Duplication
    public function testUploadTypeFileSrcNotValid()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
962
    {
963
        $input = '[file src=foo]test.txt[/file]';
964
        $expected = [
965
            'div' => [
966
                'class' => 'richtext-imessage',
967
            ],
968
        ];
969
        $result = $this->_Parser->parse($input);
970
        $this->assertHtml($expected, $result);
971
    }
972
973
    public function testUploadTypeFileNoSource()
974
    {
975
        $input = '[file]test.txt[/file]';
976
        $result = $this->_Parser->parse($input);
977
        $this->assertHtml($input, $result);
0 ignored issues
show
Documentation introduced by
$input is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
978
    }
979
980
    public function testSmiliesNoSmiliesInCodeTag()
981
    {
982
        $input = '[code text]:)[/code]';
983
        $needle = '<img';
984
        $result = $this->_Parser->parse($input, ['cache' => false]);
985
        $this->assertNotContains($needle, $result);
986
    }
987
988 View Code Duplication
    public function testCodeNestedTags()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
989
    {
990
        $input = '[code][b]text[b][/code]';
991
        $expected = [
992
            [
993
                'div' => ['class' => 'geshi-wrapper']
994
            ],
995
            'preg:/.*?\[b\]text\[b\].*/',
996
        ];
997
        $result = $this->_Parser->parse($input);
998
        $this->assertHtml($expected, $result);
999
    }
1000
1001 View Code Duplication
    public function testCodeWhitespace()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1002
    {
1003
        $input = "[code]\ntest\n[/code]";
1004
        $expected = "/>test</";
1005
        $result = $this->_Parser->parse($input);
1006
        $this->assertRegExp($expected, $result);
1007
    }
1008
1009 View Code Duplication
    public function testCodeSimple()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1010
    {
1011
        $input = '[code]text[/code]';
1012
        $result = $this->_Parser->parse($input);
1013
        $expected = 'lang="text"';
1014
        $this->assertContains($expected, $result);
1015
    }
1016
1017 View Code Duplication
    public function testCodeLangAttribute()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1018
    {
1019
        $input = '[code=php]text[/code]';
1020
        $result = $this->_Parser->parse($input);
1021
        $expected = 'lang="php"';
1022
        $this->assertContains($expected, $result);
1023
    }
1024
1025
    /**
1026
     * tests that citation marks are not replaced in code-blocks
1027
     */
1028
    public function testCodeNoCitationMark()
1029
    {
1030
        // [code]<citation mark>[/code] should not be cited
1031
        $input = h(
1032
            "[code]\n" . $this->_Helper->getConfig('quote_symbol') . "\n[/code]"
1033
        );
1034
        $expected = '`span class=.*?richtext-citation`';
1035
        $result = $this->_Parser->parse($input);
1036
        $this->assertNotRegExp($expected, $result);
1037
    }
1038
1039
    public function testCodeDetaginize()
1040
    {
1041
        $input = '[code bash]pre http://example.com post[/code]';
1042
        $result = $this->_Parser->parse($input);
1043
        $this->assertNotContains('autoLink', $result);
1044
    }
1045
1046
    public function testQuote()
1047
    {
1048
        $_qs = $this->MarkupSettings->get('quote_symbol');
1049
        $input = $_qs . ' fo [b]test[/b] ba';
1050
        $result = $this->_Parser->parse($input);
1051
        $expected = [
1052
            'span' => ['class' => 'richtext-citation'],
1053
            $_qs . ' fo ',
1054
            'strong' => [],
1055
            'test',
1056
            '/strong',
1057
            ' ba',
1058
            '/span'
1059
        ];
1060
        $this->assertHtml($expected, $result);
1061
    }
1062
1063 View Code Duplication
    public function testHtml5Video()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1064
    {
1065
        //* setup
1066
        $bbcodeImg = Configure::read('Saito.Settings.bbcode_img');
1067
        Configure::write('Saito.Settings.bbcode_img', true);
1068
1069
        //* @td write video tests
1070
        $url = 'http://example.com/audio.mp4';
1071
        $input = "[video]{$url}[/video]";
1072
        $result = $this->_Parser->parse($input);
1073
        $expected = [
1074
            'video' => [
1075
                'src' => $url,
1076
                'preload' => 'auto',
1077
                'controls' => 'controls',
1078
                'x-webkit-airplay' => 'allow'
1079
            ],
1080
        ];
1081
        $this->assertHtml($expected, $result);
1082
1083
        //* teardown
1084
        Configure::write('Saito.Settings.bbcode_img', $bbcodeImg);
1085
    }
1086
1087 View Code Duplication
    public function testHr()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1088
    {
1089
        $input = '[hr][hr]';
1090
        $expected = '<hr><hr>';
1091
        $result = $this->_Parser->parse($input);
1092
        $this->assertEquals($result, $expected);
1093
    }
1094
1095 View Code Duplication
    public function testHrShort()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1096
    {
1097
        $input = '[---][---]';
1098
        $expected = '<hr><hr>';
1099
        $result = $this->_Parser->parse($input);
1100
        $this->assertEquals($result, $expected);
1101
    }
1102
1103 View Code Duplication
    public function testEmbedNoReplacement()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1104
    {
1105
        $input = '[embed]http://no.provider/unreplaced[/embed]';
1106
1107
        $result = $this->_Parser->parse($input);
1108
1109
        $expected = [
1110
            'div' => [
1111
                'class' => 'js-embed',
1112
                'data-embed' => '{&quot;url&quot;:&quot;http:\/\/no.provider\/unreplaced&quot;}',
1113
                'id' => 'embed-10478631dd9f8f00da95953f63f6e5f3',
1114
            ],
1115
            '/div',
1116
        ];
1117
1118
        $this->assertHtml($expected, $result);
1119
    }
1120
1121
    public function testEmbedDisabledWithoutAutolinking()
1122
    {
1123
        $this->MarkupSettings->setSingle('autolink', false);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1124
        $this->MarkupSettings->setSingle('content_embed_active', false);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1125
1126
        $url = 'http://foo.bar/baz';
1127
        $input = "[embed]{$url}[/embed]";
1128
1129
        $result = $this->_Parser->parse($input);
1130
1131
        $this->assertHtml($url, $result);
0 ignored issues
show
Documentation introduced by
$url is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1132
    }
1133
1134
    public function testEmbedDisabledWithAutolinking()
1135
    {
1136
        $this->MarkupSettings->setSingle('autolink', true);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1137
        $this->MarkupSettings->setSingle('content_embed_active', false);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Saito\Markup\MarkupSettings as the method setSingle() does only exist in the following sub-classes of Saito\Markup\MarkupSettings: BbcodeParser\Test\Lib\an.../BbcodeParserTest.php$0. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1138
1139
        $url = 'http://foo.bar/baz';
1140
        $input = "[embed]{$url}[/embed]";
1141
1142
        $result = $this->_Parser->parse($input);
1143
1144
        $expected = [
1145
            'a' => [
1146
                'href' => $url,
1147
                'target' => '_blank',
1148
            ],
1149
            $url,
1150
            '/a',
1151
        ];
1152
1153
        $this->assertHtml($expected, $result);
1154
    }
1155
1156 View Code Duplication
    public function testHtml5Audio()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1157
    {
1158
        //* setup
1159
        $bbcodeImg = Configure::read('Saito.Settings.bbcode_img');
1160
        Configure::write('Saito.Settings.bbcode_img', true);
1161
1162
        //* simple test
1163
        $url = 'http://example.com/audio3.m4a';
1164
        $input = "[audio]{$url}[/audio]";
1165
        $result = $this->_Parser->parse($input);
1166
        $expected = [
1167
            'audio' => [
1168
                'src' => $url,
1169
                'controls' => 'controls',
1170
                'preload' => 'auto',
1171
                'x-webkit-airplay' => 'allow',
1172
            ],
1173
            '/audio',
1174
        ];
1175
        $this->assertHtml($expected, $result);
1176
1177
        //* teardown
1178
        Configure::write('Saito.Settings.bbcode_img', $bbcodeImg);
1179
    }
1180
1181
    /* ******************** Setup ********************** */
1182
1183
    public function setUp()
1184
    {
1185
        Cache::clear();
1186
1187 View Code Duplication
        if (Cache::getConfig('bbcodeParserEmbed') === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1188
            Cache::setConfig(
1189
                'bbcodeParserEmbed',
1190
                [
1191
                    'className' => 'File',
1192
                    'prefix' => 'saito_embed-',
1193
                    'path' => CACHE,
1194
                    'groups' => ['embed'],
1195
                    'duration' => '+1 year'
1196
1197
                ]
1198
            );
1199
        }
1200
1201
        if (isset($_SERVER['SERVER_NAME'])) {
1202
            $this->server_name = $_SERVER['SERVER_NAME'];
0 ignored issues
show
Bug introduced by
The property server_name does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1203
        } else {
1204
            $this->server_name = false;
1205
        }
1206
1207
        if (isset($_SERVER['SERVER_PORT'])) {
1208
            $this->server_port = $_SERVER['SERVER_PORT'];
0 ignored issues
show
Bug introduced by
The property server_port does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1209
        } else {
1210
            $this->server_port = false;
1211
        }
1212
1213
        $this->autolink = Configure::read('Saito.Settings.autolink');
0 ignored issues
show
Bug introduced by
The property autolink does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1214
        Configure::write('Saito.Settings.autolink', true);
1215
1216
        $_SERVER['SERVER_NAME'] = 'macnemo.de';
1217
        $_SERVER['SERVER_PORT'] = '80';
1218
1219
        parent::setUp();
1220
1221
        $View = new View();
1222
1223
        //= smiley fixture
1224
        $smiliesFixture = [
1225
            [
1226
                'order' => 1,
1227
                'icon' => 'wink.png',
1228
                'image' => 'wink.png',
1229
                'title' => 'Wink',
1230
                'code' => ';)',
1231
                'type' => 'image'
1232
            ],
1233
            [
1234
                'order' => 2,
1235
                'icon' => 'smile_icon.svg',
1236
                'image' => 'smile_image.svg',
1237
                'title' => 'Smile',
1238
                'code' => ':-)',
1239
                'type' => 'image'
1240
            ],
1241
            [
1242
                'order' => 3,
1243
                'icon' => 'coffee',
1244
                'image' => 'coffee',
1245
                'title' => 'Coffee',
1246
                'code' => '[_]P',
1247
                'type' => 'font'
1248
            ],
1249
        ];
1250
        Cache::write('Saito.Smilies.data', $smiliesFixture);
1251
        $SmileyLoader = new \Saito\Smiley\SmileyLoader();
1252
1253
        //= userlist fixture
1254
        $Userlist = $this->getMockBuilder(UserlistModel::class)
1255
            ->disableOriginalConstructor()
1256
            ->setMethods(['get'])
1257
            ->getMock();
1258
        $Userlist->method('get')->willReturn(['Alice', 'Bobby Junior', 'Dr. No']);
1259
1260
        //= ParserHelper
1261
        $markupSettingsMock = new class extends MarkupSettings {
1262
            public function setSingle(string $key, $value)
1263
            {
1264
                $this->_settings[$key] = $value;
1265
            }
1266
        };
1267
        $this->MarkupSettings = new $markupSettingsMock([
1268
            'UserList' => $Userlist,
1269
            'atBaseUrl' => '/at/',
1270
            'autolink' => true,
1271
            'bbcode_img' => true,
1272
            'content_embed_active' => true,
1273
            'content_embed_media' => true,
1274
            'content_embed_text' => true,
1275
            'hashBaseUrl' => '/hash/',
1276
            'quote_symbol' => '»',
1277
            'smilies' => true,
1278
            'smiliesData' => $SmileyLoader,
1279
            'text_word_maxlength' => 100000,
1280
            'video_domains_allowed' => 'youtube',
1281
            'webroot' => ''
1282
        ]);
1283
        $this->_Helper = $ParserHelper = new ParserHelper($View);
1284
        $ParserHelper->beforeRender(null);
1285
1286
        //= Smiley Renderer
1287
        $this->_Helper->getView()->set('smiliesData', $SmileyLoader);
1288
1289
        //= Parser
1290
        $this->_Parser = new Parser($ParserHelper, $this->MarkupSettings);
1291
    }
1292
1293
    public function tearDown()
1294
    {
1295
        parent::tearDown();
1296
        if ($this->server_name) {
1297
            $_SERVER['SERVER_NAME'] = $this->server_name;
1298
        }
1299
1300
        if ($this->server_name) {
1301
            $_SERVER['SERVER_PORT'] = $this->server_port;
1302
        }
1303
1304
        Configure::write('Saito.Settings.autolink', $this->autolink);
1305
1306
        Cache::clear();
1307
        unset($this->_Parser);
1308
    }
1309
}
1310