Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
16
 
17
namespace mod_wiki;
18
 
19
use wiki_parser_proxy;
20
 
21
defined('MOODLE_INTERNAL') || die;
22
 
23
global $CFG;
24
require_once($CFG->dirroot . '/mod/wiki/parser/parser.php');
25
 
26
/**
27
 * Unit tests for the wiki parser
28
 *
29
 * @package   mod_wiki
30
 * @category  test
31
 * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu
32
 * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
33
 *
34
 * @author Jordi Piguillem
35
 * @author Marc Alier
36
 * @author David Jimenez
37
 * @author Josep Arus
38
 * @author Kenneth Riba
39
 *
40
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class wikiparser_test extends \advanced_testcase {
43
 
44
    /**
45
     * URL inside the clickable text of some link should not be turned into a new link via the url_tag_rule.
46
     *
47
     * @dataProvider urls_inside_link_text_provider
48
     * @param string $markup Markup of the Wiki page the text is part of.
49
     * @param string $input The input text.
50
     * @param string $output The expected output HTML as a result of the parsed input text.
51
     */
52
    public function test_urls_inside_link_text(string $markup, string $input, string $output) {
53
 
54
        $parsingresult = wiki_parser_proxy::parse($input, $markup, [
55
            'link_callback' => '/mod/wiki/locallib.php:wiki_parser_link',
56
            'link_callback_args' => ['swid' => 1],
57
        ]);
58
 
59
        $this->assertStringContainsString($output, $parsingresult['parsed_text']);
60
    }
61
 
62
    /**
63
     * Provides data sets for {@see self::test_urls_inside_link_text()}.
64
     *
65
     * @return array
66
     */
67
    public function urls_inside_link_text_provider() {
68
        return [
69
            'creole implicit link' => [
70
                'markup' => 'creole',
71
                'input' => 'Visit https://site.url for more information.',
72
                'output' => 'Visit <a href="https://site.url">https://site.url</a> for more information.',
73
            ],
74
            'creole explicit link' => [
75
                'markup' => 'creole',
76
                'input' => 'Visit [[https://site.url]] for more information.',
77
                'output' => 'Visit <a href="https://site.url">https://site.url</a> for more information.',
78
            ],
79
            'creole explicit link with text' => [
80
                'markup' => 'creole',
81
                'input' => 'Visit [[https://site.url|http://www.site.url]] for more information.',
82
                'output' => 'Visit <a href="https://site.url">http://www.site.url</a> for more information.',
83
            ],
84
            'nwiki implicit link' => [
85
                'markup' => 'nwiki',
86
                'input' => 'Visit https://site.url for more information.',
87
                'output' => 'Visit <a href="https://site.url">https://site.url</a> for more information.',
88
            ],
89
            'nwiki explicit link' => [
90
                'markup' => 'nwiki',
91
                'input' => 'Visit [https://site.url] for more information.',
92
                'output' => 'Visit <a href="https://site.url">https://site.url</a> for more information.',
93
            ],
94
            'nwiki explicit link with space separated text' => [
95
                'markup' => 'nwiki',
96
                'input' => 'Visit [https://site.url http://www.site.url] for more information.',
97
                'output' => 'Visit <a href="https://site.url">http://www.site.url</a> for more information.',
98
            ],
99
            'nwiki explicit link with pipe separated text' => [
100
                'markup' => 'nwiki',
101
                'input' => 'Visit [https://site.url|http://www.site.url] for more information.',
102
                'output' => 'Visit <a href="https://site.url">http://www.site.url</a> for more information.',
103
            ],
104
            'html implicit link' => [
105
                'markup' => 'html',
106
                'input' => 'Visit https://site.url for more information.',
107
                'output' => 'Visit <a href="https://site.url">https://site.url</a> for more information.',
108
            ],
109
            'html explicit link with text' => [
110
                'markup' => 'html',
111
                'input' => 'Visit <a href="https://site.url">http://www.site.url</a> for more information.',
112
                'output' => 'Visit <a href="https://site.url">http://www.site.url</a> for more information.',
113
            ],
114
            'html wiki link to non-existing page' => [
115
                'markup' => 'html',
116
                'input' => 'Visit [[Another page]] for more information.',
117
                'output' => 'Visit <a class="wiki_newentry" ' .
118
                    'href="https://www.example.com/moodle/mod/wiki/create.php?swid=1&amp;title=Another+page&amp;action=new">' .
119
                    'Another page</a> for more information.',
120
            ],
121
            'html wiki link inside an explicit link' => [
122
                // The explicit href URL takes precedence here, the [[...]] is not turned into a wiki link.
123
                'markup' => 'html',
124
                'input' => 'Visit <a href="https://site.url">[[Another page]]</a> for more information.',
125
                'output' => 'Visit <a href="https://site.url">[[Another page]]</a> for more information.',
126
            ],
127
        ];
128
    }
129
 
130
    function testCreoleMarkup() {
131
        $this->assertTestFiles('creole');
132
    }
133
 
134
    function testNwikiMarkup() {
135
        $this->assertTestFiles('nwiki');
136
    }
137
 
138
    function testHtmlMarkup() {
139
        $this->assertTestFiles('html');
140
    }
141
 
142
    private function assertTestFile($num, $markup) {
143
        if(!file_exists(__DIR__."/fixtures/input/$markup/$num") || !file_exists(__DIR__."/fixtures/output/$markup/$num")) {
144
            return false;
145
        }
146
        $input = file_get_contents(__DIR__."/fixtures/input/$markup/$num");
147
        $output = file_get_contents(__DIR__."/fixtures/output/$markup/$num");
148
 
149
        $result = wiki_parser_proxy::parse($input, $markup, array('pretty_print' => true));
150
 
151
        //removes line breaks to avoid line break encoding causing tests to fail.
152
        $result['parsed_text'] = preg_replace('~[\r\n]~', '', $result['parsed_text']);
153
        $output                = preg_replace('~[\r\n]~', '', $output);
154
 
155
        $this->assertEquals($output, $result['parsed_text'], 'Failed asserting that two strings are equal. Markup = '.$markup.", num = $num");
156
        return true;
157
    }
158
 
159
    private function assertTestFiles($markup) {
160
        $i = 1;
161
        while($this->assertTestFile($i, $markup)) {
162
            $i++;
163
        }
164
    }
165
 
166
    /**
167
     * Check that headings with special characters work as expected with HTML.
168
     *
169
     * - The heading itself is well displayed,
170
     * - The TOC heading is well display,
171
     * - The edit link points to the right page,
172
     * - The links properly works with get_section.
173
     */
174
    public function test_special_headings() {
175
 
176
        // First testing HTML markup.
177
 
178
        // Test section name using HTML entities.
179
        $input = '<h1>Code &amp; Test</h1>';
180
        $output = '<h3><a name="toc-1"></a>Code &amp; Test <a href="edit.php?pageid=&amp;section=Code+%26amp%3B+Test" '.
181
            'class="wiki_edit_section">[edit]</a></h3>' . "\n";
182
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
183
            'wiki-toc-section">1. <a href="#toc-1">Code &amp; Test <a href="edit.php?pageid=&amp;section=Code+%26amp%3B+'.
184
            'Test" class="wiki_edit_section">[edit]</a></a></p></div>';
185
        $section = wiki_parser_proxy::get_section($input, 'html', 'Code &amp; Test');
186
        $actual = wiki_parser_proxy::parse($input, 'html');
187
        $this->assertEquals($output, $actual['parsed_text']);
188
        $this->assertEquals($toc, $actual['toc']);
189
        $this->assertNotEquals(false, $section);
190
 
191
        // Test section name using non-ASCII characters.
192
        $input = '<h1>Another áéíóúç€ test</h1>';
193
        $output = '<h3><a name="toc-1"></a>Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
194
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
195
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
196
            'wiki-toc-section">1. <a href="#toc-1">Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
197
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></a></p></div>';
198
        $section = wiki_parser_proxy::get_section($input, 'html', 'Another áéíóúç€ test');
199
        $actual = wiki_parser_proxy::parse($input, 'html');
200
        $this->assertEquals($output, $actual['parsed_text']);
201
        $this->assertEquals($toc, $actual['toc']);
202
        $this->assertNotEquals(false, $section);
203
 
204
        // Test section name with a URL.
205
        $input = '<h1>Another http://moodle.org test</h1>';
206
        $output = '<h3><a name="toc-1"></a>Another <a href="http://moodle.org">http://moodle.org</a> test <a href="edit.php'.
207
            '?pageid=&amp;section=Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
208
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
209
            'wiki-toc-section">1. <a href="#toc-1">Another http://moodle.org test <a href="edit.php?pageid=&amp;section='.
210
            'Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></a></p></div>';
211
        $section = wiki_parser_proxy::get_section($input, 'html', 'Another http://moodle.org test');
212
        $actual = wiki_parser_proxy::parse($input, 'html', array(
213
            'link_callback' => '/mod/wiki/locallib.php:wiki_parser_link'
214
        ));
215
        $this->assertEquals($output, $actual['parsed_text']);
216
        $this->assertEquals($toc, $actual['toc']);
217
        $this->assertNotEquals(false, $section);
218
 
219
        // Test toc section names being wikilinks.
220
        $input = '<h1>[[Heading 1]]</h1><h2>[[Heading A]]</h2><h2>Heading D</h2>';
221
        $regexpoutput = '!<h3><a name="toc-1"></a>' .
222
            '<a class="wiki_newentry" href.*mod/wiki/create\.php\?.*title=Heading\+1.*action=new.*>Heading 1<.*' .
223
            '<h4><a name="toc-2"></a>' .
224
            '<a class="wiki_newentry" href.*mod/wiki/create\.php\?.*title=Heading\+A.*action=new.*>Heading A<.*' .
225
            '<h4><a name="toc-3"></a>' .
226
            'Heading D!ms';
227
        $regexptoc = '!<a href="#toc-1">Heading 1.*<a href="#toc-2">Heading A</a>.*<a href="#toc-3">Heading D</a>!ms';
228
        $section = wiki_parser_proxy::get_section($input, 'html', 'Another [[wikilinked]] test');
229
        $actual = wiki_parser_proxy::parse($input, 'html', array(
230
            'link_callback' => '/mod/wiki/locallib.php:wiki_parser_link',
231
            'link_callback_args' => array('swid' => 1)
232
        ));
233
        $this->assertMatchesRegularExpression($regexpoutput, $actual['parsed_text']);
234
        $this->assertMatchesRegularExpression($regexptoc, $actual['toc']);
235
 
236
        // Now going to test Creole markup.
237
        // Note that Creole uses links to the escaped version of the section.
238
 
239
        // Test section name using HTML entities.
240
        $input = '= Code & Test =';
241
        $output = '<h3><a name="toc-1"></a>Code &amp; Test <a href="edit.php?pageid=&amp;section=Code+%26amp%3B+Test" '.
242
            'class="wiki_edit_section">[edit]</a></h3>' . "\n";
243
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
244
            'wiki-toc-section">1. <a href="#toc-1">Code &amp; Test <a href="edit.php?pageid=&amp;section=Code+%26amp%3B+'.
245
            'Test" class="wiki_edit_section">[edit]</a></a></p></div>';
246
        $section = wiki_parser_proxy::get_section($input, 'creole', 'Code &amp; Test');
247
        $actual = wiki_parser_proxy::parse($input, 'creole');
248
        $this->assertEquals($output, $actual['parsed_text']);
249
        $this->assertEquals($toc, $actual['toc']);
250
        $this->assertNotEquals(false, $section);
251
 
252
        // Test section name using non-ASCII characters.
253
        $input = '= Another áéíóúç€ test =';
254
        $output = '<h3><a name="toc-1"></a>Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
255
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
256
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
257
            'wiki-toc-section">1. <a href="#toc-1">Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
258
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></a></p></div>';
259
        $section = wiki_parser_proxy::get_section($input, 'creole', 'Another áéíóúç€ test');
260
        $actual = wiki_parser_proxy::parse($input, 'creole');
261
        $this->assertEquals($output, $actual['parsed_text']);
262
        $this->assertEquals($toc, $actual['toc']);
263
        $this->assertNotEquals(false, $section);
264
 
265
        // Test section name with a URL, creole does not support linking links in a heading.
266
        $input = '= Another http://moodle.org test =';
267
        $output = '<h3><a name="toc-1"></a>Another http://moodle.org test <a href="edit.php'.
268
            '?pageid=&amp;section=Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
269
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
270
            'wiki-toc-section">1. <a href="#toc-1">Another http://moodle.org test <a href="edit.php?pageid=&amp;section='.
271
            'Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></a></p></div>';
272
        $section = wiki_parser_proxy::get_section($input, 'creole', 'Another http://moodle.org test');
273
        $actual = wiki_parser_proxy::parse($input, 'creole');
274
        $this->assertEquals($output, $actual['parsed_text']);
275
        $this->assertEquals($toc, $actual['toc']);
276
        $this->assertNotEquals(false, $section);
277
 
278
        // Now going to test NWiki markup.
279
        // Note that Creole uses links to the escaped version of the section.
280
 
281
        // Test section name using HTML entities.
282
        $input = '= Code & Test =';
283
        $output = '<h3><a name="toc-1"></a>Code & Test <a href="edit.php?pageid=&amp;section=Code+%26+Test" '.
284
            'class="wiki_edit_section">[edit]</a></h3>' . "\n";
285
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
286
            'wiki-toc-section">1. <a href="#toc-1">Code & Test <a href="edit.php?pageid=&amp;section=Code+%26+'.
287
            'Test" class="wiki_edit_section">[edit]</a></a></p></div>';
288
        $section = wiki_parser_proxy::get_section($input, 'nwiki', 'Code & Test');
289
        $actual = wiki_parser_proxy::parse($input, 'nwiki');
290
        $this->assertEquals($output, $actual['parsed_text']);
291
        $this->assertEquals($toc, $actual['toc']);
292
        $this->assertNotEquals(false, $section);
293
 
294
        // Test section name using non-ASCII characters.
295
        $input = '= Another áéíóúç€ test =';
296
        $output = '<h3><a name="toc-1"></a>Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
297
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
298
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
299
            'wiki-toc-section">1. <a href="#toc-1">Another áéíóúç€ test <a href="edit.php?pageid=&amp;section=Another+%C'.
300
            '3%A1%C3%A9%C3%AD%C3%B3%C3%BA%C3%A7%E2%82%AC+test" class="wiki_edit_section">[edit]</a></a></p></div>';
301
        $section = wiki_parser_proxy::get_section($input, 'nwiki', 'Another áéíóúç€ test');
302
        $actual = wiki_parser_proxy::parse($input, 'nwiki');
303
        $this->assertEquals($output, $actual['parsed_text']);
304
        $this->assertEquals($toc, $actual['toc']);
305
        $this->assertNotEquals(false, $section);
306
 
307
        // Test section name with a URL, nwiki does not support linking links in a heading.
308
        $input = '= Another http://moodle.org test =';
309
        $output = '<h3><a name="toc-1"></a>Another http://moodle.org test <a href="edit.php'.
310
            '?pageid=&amp;section=Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></h3>' . "\n";
311
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
312
            'wiki-toc-section">1. <a href="#toc-1">Another http://moodle.org test <a href="edit.php?pageid=&amp;section='.
313
            'Another+http%3A%2F%2Fmoodle.org+test" class="wiki_edit_section">[edit]</a></a></p></div>';
314
        $section = wiki_parser_proxy::get_section($input, 'nwiki', 'Another http://moodle.org test');
315
        $actual = wiki_parser_proxy::parse($input, 'nwiki');
316
        $this->assertEquals($output, $actual['parsed_text']);
317
        $this->assertEquals($toc, $actual['toc']);
318
        $this->assertNotEquals(false, $section);
319
 
320
        // Test section names when headings start with level 3.
321
        $input = '<h3>Heading test</h3><h4>Subsection</h4>';
322
        $output = '<h3><a name="toc-1"></a>Heading test <a href="edit.php?pageid=&amp;section=Heading+test" '.
323
            'class="wiki_edit_section">[edit]</a></h3>'. "\n" . '<h4><a name="toc-2"></a>Subsection</h4>' . "\n";
324
        $toc = '<div class="wiki-toc"><p class="wiki-toc-title">Table of contents</p><p class="wiki-toc-section-1 '.
325
            'wiki-toc-section">1. <a href="#toc-1">Heading test <a href="edit.php?pageid=&amp;section=Heading+'.
326
            'test" class="wiki_edit_section">[edit]</a></a></p><p class="wiki-toc-section-2 wiki-toc-section">'.
327
            '1.1. <a href="#toc-2">Subsection</a></p></div>';
328
        $section = wiki_parser_proxy::get_section($input, 'html', 'Heading test');
329
        $actual = wiki_parser_proxy::parse($input, 'html');
330
        $this->assertEquals($output, $actual['parsed_text']);
331
        $this->assertEquals($toc, $actual['toc']);
332
        $this->assertNotEquals(false, $section);
333
    }
334
 
335
    /**
336
     * Test that format that are not supported are raising an exception
337
     *
338
     * @param string $format
339
     * @param string $expected
340
     * @covers \wiki_parser_proxy::parse
341
     * @dataProvider format_parser_provider
342
     */
343
    public function test_format_parser(string $format, string $expected) {
344
        $this->resetAfterTest();
345
        $this->setAdminUser();
346
        $generator = $this->getDataGenerator();
347
        $course = $generator->create_course();
348
        $wiki = $generator->create_module('wiki', array_merge(['course' => $course->id, 'defaultformat' => $format]));
349
        $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
350
        if ($expected === 'exception') {
351
            $this->expectException(\moodle_exception::class);
352
        }
353
        $page = $wikigenerator->create_page($wiki);
354
        $version = wiki_get_current_version($page->id);
355
        $this->assertEquals($expected, $version->contentformat);
356
    }
357
 
358
    /**
359
     * Data provider for test_format_parser
360
     *
361
     * @return array[]
362
     */
363
    public static function format_parser_provider(): array {
364
        return [
365
            'creole' => [
366
                'data' => 'creole',
367
                'expected' => 'creole',
368
            ],
369
            'html' => [
370
                'data' => 'html',
371
                'expected' => 'html',
372
            ],
373
            'wikimarkup' => [
374
                'data' => 'nwiki',
375
                'expected' => 'nwiki',
376
            ],
377
            'wrong format' => [
378
                'data' => '../wrongformat123',
379
                'expected' => 'exception',
380
            ],
381
        ];
382
    }
383
}