xref: /plugin/bpmnio/_test/syntax_plugin_bpmnio_bpmnio.test.php (revision 738a44ff661500d783f23960888bd3ae2818f44c)
1<?php
2
3/**
4 * @group plugin_bpmnio
5 * @group plugins
6 */
7class syntax_plugin_bpmnio_test extends DokuWikiTest
8{
9    protected $pluginsEnabled = array('bpmnio');
10
11    public function setUp(): void
12    {
13        parent::setUp();
14        global $conf;
15        $conf['plugin']['bpmnio']['lint'] = 'inactive';
16    }
17
18    public function test_syntax_bpmn()
19    {
20        $info = array();
21        $expected = <<<OUT
22        <div class="plugin-bpmnio" id="__bpmn_js_1"><div class="bpmn_js_data">
23            WE1MLi4u
24        </div>
25        <div class="bpmn_js_links">
26            W10=
27        </div><div class="bpmn_js_canvas sectionedit1">
28            <div class="bpmn_js_container" data-lint="inactive"></div>
29        </div><!-- EDIT{&quot;target&quot;:&quot;plugin_bpmnio_bpmn&quot;,&quot;secid&quot;:1,&quot;range&quot;:&quot;21-29&quot;} --></div>
30        OUT;
31
32        $input = <<<IN
33        <bpmnio type="bpmn">
34        XML...
35        </bpmnio>
36        IN;
37
38        $instructions = p_get_instructions($input);
39        $xhtml = p_render('xhtml', $instructions, $info);
40
41        $this->assertEquals($expected, $xhtml);
42    }
43
44    public function test_syntax_dmn()
45    {
46        $info = array();
47        $expected = <<<OUT
48        <div class="plugin-bpmnio" id="__dmn_js_1"><div class="dmn_js_data">
49            WE1MLi4u
50        </div>
51        <div class="dmn_js_links">
52            W10=
53        </div><div class="dmn_js_canvas sectionedit1">
54            <div class="dmn_js_container"></div>
55        </div><!-- EDIT{&quot;target&quot;:&quot;plugin_bpmnio_dmn&quot;,&quot;secid&quot;:1,&quot;range&quot;:&quot;20-28&quot;} --></div>
56        OUT;
57
58        $input = <<<IN
59        <bpmnio type="dmn">
60        XML...
61        </bpmnio>
62        IN;
63
64        $instructions = p_get_instructions($input);
65        $xhtml = p_render('xhtml', $instructions, $info);
66
67        $this->assertEquals($expected, $xhtml);
68    }
69
70    /**
71     * Test that type defaults to bpmn when not specified
72     */
73    public function test_syntax_default_type()
74    {
75        $info = array();
76
77        $input = <<<IN
78        <bpmnio>
79        XML...
80        </bpmnio>
81        IN;
82
83        $instructions = p_get_instructions($input);
84        $xhtml = p_render('xhtml', $instructions, $info);
85
86        $this->assertStringContainsString('bpmn_js_data', $xhtml);
87        $this->assertStringContainsString('bpmn_js_canvas', $xhtml);
88        $this->assertStringContainsString('bpmn_js_container', $xhtml);
89    }
90
91    /**
92     * Test empty content between tags
93     */
94    public function test_syntax_empty_content()
95    {
96        $info = array();
97
98        $input = <<<IN
99        <bpmnio type="bpmn">
100        </bpmnio>
101        IN;
102
103        $instructions = p_get_instructions($input);
104        $xhtml = p_render('xhtml', $instructions, $info);
105
106        // Should still produce the structure, with base64 of whitespace/empty
107        $this->assertStringContainsString('plugin-bpmnio', $xhtml);
108        $this->assertStringContainsString('bpmn_js_data', $xhtml);
109    }
110
111    /**
112     * Test that multiline XML content is properly base64-encoded
113     */
114    public function test_syntax_multiline_content()
115    {
116        $info = array();
117
118        $input = <<<IN
119        <bpmnio type="bpmn">
120        <?xml version="1.0"?>
121        <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
122        </definitions>
123        </bpmnio>
124        IN;
125
126        $instructions = p_get_instructions($input);
127        $xhtml = p_render('xhtml', $instructions, $info);
128
129        $this->assertStringContainsString('bpmn_js_data', $xhtml);
130        // Verify the data section contains valid base64
131        preg_match('/<div class="bpmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $matches);
132        $this->assertNotEmpty($matches[1]);
133        $decoded = base64_decode(trim($matches[1]), true);
134        $this->assertNotFalse($decoded, 'Content should be valid base64');
135        $this->assertStringContainsString('definitions', $decoded);
136    }
137
138    /**
139     * Test that the plugin produces section edit markers for inline content
140     */
141    public function test_syntax_section_edit_bpmn()
142    {
143        $info = array();
144
145        $input = <<<IN
146        <bpmnio type="bpmn">
147        Content
148        </bpmnio>
149        IN;
150
151        $instructions = p_get_instructions($input);
152        $xhtml = p_render('xhtml', $instructions, $info);
153
154        $this->assertStringContainsString('sectionedit', $xhtml);
155        $this->assertStringContainsString('plugin_bpmnio_bpmn', $xhtml);
156    }
157
158    /**
159     * Test that the plugin produces section edit markers for DMN inline content
160     */
161    public function test_syntax_section_edit_dmn()
162    {
163        $info = array();
164
165        $input = <<<IN
166        <bpmnio type="dmn">
167        Content
168        </bpmnio>
169        IN;
170
171        $instructions = p_get_instructions($input);
172        $xhtml = p_render('xhtml', $instructions, $info);
173
174        $this->assertStringContainsString('sectionedit', $xhtml);
175        $this->assertStringContainsString('plugin_bpmnio_dmn', $xhtml);
176    }
177
178    /**
179     * Test that unrecognized text outside <bpmnio> is not affected
180     */
181    public function test_syntax_no_interference()
182    {
183        $info = array();
184
185        $input = <<<IN
186        Hello World
187        <bpmnio type="bpmn">
188        XML...
189        </bpmnio>
190        Goodbye World
191        IN;
192
193        $instructions = p_get_instructions($input);
194        $xhtml = p_render('xhtml', $instructions, $info);
195
196        $this->assertStringContainsString('Hello World', $xhtml);
197        $this->assertStringContainsString('Goodbye World', $xhtml);
198        $this->assertStringContainsString('plugin-bpmnio', $xhtml);
199    }
200
201    public function test_syntax_zoom_attribute()
202    {
203        $info = array();
204
205        $input = <<<IN
206        <bpmnio type="bpmn" zoom="0.5">
207        XML...
208        </bpmnio>
209        IN;
210
211        $instructions = p_get_instructions($input);
212        $xhtml = p_render('xhtml', $instructions, $info);
213
214        $this->assertStringContainsString('data-zoom="0.5"', $xhtml);
215    }
216
217    public function test_syntax_ignores_invalid_zoom_attribute()
218    {
219        $info = array();
220
221        $input = <<<IN
222        <bpmnio type="bpmn" zoom="0">
223        XML...
224        </bpmnio>
225        IN;
226
227        $instructions = p_get_instructions($input);
228        $xhtml = p_render('xhtml', $instructions, $info);
229
230        $this->assertStringNotContainsString('data-zoom=', $xhtml);
231    }
232
233    public function test_syntax_lint_attribute()
234    {
235        $info = array();
236
237        $input = <<<IN
238        <bpmnio type="bpmn" lint="on">
239        XML...
240        </bpmnio>
241        IN;
242
243        $instructions = p_get_instructions($input);
244        $xhtml = p_render('xhtml', $instructions, $info);
245
246        $this->assertStringContainsString('data-lint="on"', $xhtml);
247    }
248
249    public function test_syntax_lint_off_attribute()
250    {
251        $info = array();
252
253        $input = <<<IN
254        <bpmnio type="bpmn" lint="off">
255        XML...
256        </bpmnio>
257        IN;
258
259        $instructions = p_get_instructions($input);
260        $xhtml = p_render('xhtml', $instructions, $info);
261
262        $this->assertStringContainsString('data-lint="off"', $xhtml);
263    }
264
265    public function test_syntax_invalid_lint_attribute_falls_back_to_default()
266    {
267        global $conf;
268        $conf['plugin']['bpmnio']['lint'] = 'inactive';
269
270        $info = array();
271
272        $input = <<<IN
273        <bpmnio type="bpmn" lint="bogus">
274        XML...
275        </bpmnio>
276        IN;
277
278        $instructions = p_get_instructions($input);
279        $xhtml = p_render('xhtml', $instructions, $info);
280
281        // Invalid attribute -> fall back to the global plugin default.
282        $this->assertStringContainsString('data-lint="inactive"', $xhtml);
283    }
284
285    public function test_syntax_missing_lint_attribute_uses_plugin_default()
286    {
287        global $conf;
288        $conf['plugin']['bpmnio']['lint'] = 'inactive';
289
290        $info = array();
291
292        $input = <<<IN
293        <bpmnio type="bpmn">
294        XML...
295        </bpmnio>
296        IN;
297
298        $instructions = p_get_instructions($input);
299        $xhtml = p_render('xhtml', $instructions, $info);
300
301        $this->assertStringContainsString('data-lint="inactive"', $xhtml);
302    }
303
304    public function test_syntax_lint_attribute_is_ignored_for_dmn()
305    {
306        $info = array();
307
308        $input = <<<IN
309        <bpmnio type="dmn" lint="on">
310        XML...
311        </bpmnio>
312        IN;
313
314        $instructions = p_get_instructions($input);
315        $xhtml = p_render('xhtml', $instructions, $info);
316
317        $this->assertStringNotContainsString('data-lint=', $xhtml);
318    }
319
320    public function test_syntax_lint_and_zoom_coexist()
321    {
322        $info = array();
323
324        $input = <<<IN
325        <bpmnio type="bpmn" zoom="1.5" lint="inactive">
326        XML...
327        </bpmnio>
328        IN;
329
330        $instructions = p_get_instructions($input);
331        $xhtml = p_render('xhtml', $instructions, $info);
332
333        $this->assertStringContainsString('data-zoom="1.5"', $xhtml);
334        $this->assertStringContainsString('data-lint="inactive"', $xhtml);
335    }
336
337        public function test_syntax_builds_link_payload_for_named_elements()
338        {
339                $info = array();
340                io_mkdir_p(dirname(wikiFN('docs:start')));
341                io_saveFile(wikiFN('docs:start'), 'Read docs');
342
343                $input = <<<IN
344                <bpmnio type="bpmn">
345                <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
346                    <process id="Process_1">
347                        <task id="Task_1" name="[[:docs:start|Read docs]]" />
348                    </process>
349                </definitions>
350                </bpmnio>
351                IN;
352
353                $instructions = p_get_instructions($input);
354                $xhtml = p_render('xhtml', $instructions, $info);
355
356                preg_match('/<div class="bpmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $xmlMatch);
357                $this->assertNotEmpty($xmlMatch[1]);
358                $decodedXml = base64_decode(trim($xmlMatch[1]), true);
359                $this->assertNotFalse($decodedXml);
360                $this->assertStringContainsString('name="Read docs"', $decodedXml);
361                $this->assertStringNotContainsString('[[', $decodedXml);
362
363                preg_match('/<div class="bpmn_js_links">\s*(.*?)\s*<\/div>/s', $xhtml, $linkMatch);
364                $this->assertNotEmpty($linkMatch[1]);
365                $decodedLinks = base64_decode(trim($linkMatch[1]), true);
366                $this->assertNotFalse($decodedLinks);
367                $links = json_decode($decodedLinks, true);
368
369                $this->assertIsArray($links);
370                $this->assertArrayHasKey('Task_1', $links);
371                $this->assertEquals('/doku.php?id=docs%3Astart', $links['Task_1']['href']);
372                $this->assertEquals('docs:start', $links['Task_1']['target']);
373        }
374
375        public function test_syntax_keeps_unlinked_names_unchanged()
376        {
377                $info = array();
378
379                $input = <<<IN
380                <bpmnio type="dmn">
381                <?xml version="1.0" encoding="UTF-8"?>
382                <definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" id="Definitions_1">
383                    <decision id="Decision_1" name="Approve Order" />
384                </definitions>
385                </bpmnio>
386                IN;
387
388                $instructions = p_get_instructions($input);
389                $xhtml = p_render('xhtml', $instructions, $info);
390
391                preg_match('/<div class="dmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $xmlMatch);
392                $decodedXml = base64_decode(trim($xmlMatch[1]), true);
393                $this->assertNotFalse($decodedXml);
394                $this->assertStringContainsString('Approve Order', $decodedXml);
395
396                preg_match('/<div class="dmn_js_links">\s*(.*?)\s*<\/div>/s', $xhtml, $linkMatch);
397                $decodedLinks = base64_decode(trim($linkMatch[1]), true);
398                $this->assertSame('[]', $decodedLinks);
399        }
400
401    /**
402     * Test the handle method directly for ENTER state
403     */
404    public function test_handle_enter_state()
405    {
406        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
407        $this->assertNotNull($plugin, 'Plugin should be loadable');
408
409        $handler = new Doku_Handler();
410        $result = $plugin->handle('<bpmnio type="bpmn">', DOKU_LEXER_ENTER, 0, $handler);
411
412        $this->assertEquals(DOKU_LEXER_ENTER, $result[0]);
413        $this->assertEquals('bpmn', $result[1]);
414    }
415
416    /**
417     * Test the handle method directly for EXIT state
418     */
419    public function test_handle_exit_state()
420    {
421        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
422        $handler = new Doku_Handler();
423        $result = $plugin->handle('</bpmnio>', DOKU_LEXER_EXIT, 0, $handler);
424
425        $this->assertEquals(DOKU_LEXER_EXIT, $result[0]);
426    }
427
428    /**
429     * Test that the plugin is correctly registered
430     */
431    public function test_plugin_registration()
432    {
433        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
434        $this->assertNotNull($plugin, 'Plugin should be loadable');
435        $this->assertEquals('block', $plugin->getPType());
436        $this->assertEquals('protected', $plugin->getType());
437        $this->assertEquals(0, $plugin->getSort());
438    }
439}
440