xref: /plugin/bpmnio/_test/syntax_plugin_bpmnio_bpmnio.test.php (revision 36b712d809a9afeda77eb7dba8abf621818208c9)
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 test_syntax_bpmn()
12    {
13        $info = array();
14        $expected = <<<OUT
15        <div class="plugin-bpmnio" id="__bpmn_js_1"><div class="bpmn_js_data">
16            ClhNTC4uLgo=
17        </div>
18        <div class="bpmn_js_links">
19            W10=
20        </div><div class="bpmn_js_canvas sectionedit1">
21            <div class="bpmn_js_container"></div>
22        </div><!-- EDIT{&quot;target&quot;:&quot;plugin_bpmnio_bpmn&quot;,&quot;secid&quot;:1,&quot;range&quot;:&quot;21-29&quot;} --></div>
23        OUT;
24
25        $input = <<<IN
26        <bpmnio type="bpmn">
27        XML...
28        </bpmnio>
29        IN;
30
31        $instructions = p_get_instructions($input);
32        $xhtml = p_render('xhtml', $instructions, $info);
33
34        $this->assertEquals($expected, $xhtml);
35    }
36
37    public function test_syntax_dmn()
38    {
39        $info = array();
40        $expected = <<<OUT
41        <div class="plugin-bpmnio" id="__dmn_js_1"><div class="dmn_js_data">
42            ClhNTC4uLgo=
43        </div>
44        <div class="dmn_js_links">
45            W10=
46        </div><div class="dmn_js_canvas sectionedit1">
47            <div class="dmn_js_container"></div>
48        </div><!-- EDIT{&quot;target&quot;:&quot;plugin_bpmnio_dmn&quot;,&quot;secid&quot;:1,&quot;range&quot;:&quot;20-28&quot;} --></div>
49        OUT;
50
51        $input = <<<IN
52        <bpmnio type="dmn">
53        XML...
54        </bpmnio>
55        IN;
56
57        $instructions = p_get_instructions($input);
58        $xhtml = p_render('xhtml', $instructions, $info);
59
60        $this->assertEquals($expected, $xhtml);
61    }
62
63    /**
64     * Test that type defaults to bpmn when not specified
65     */
66    public function test_syntax_default_type()
67    {
68        $info = array();
69
70        $input = <<<IN
71        <bpmnio>
72        XML...
73        </bpmnio>
74        IN;
75
76        $instructions = p_get_instructions($input);
77        $xhtml = p_render('xhtml', $instructions, $info);
78
79        $this->assertStringContainsString('bpmn_js_data', $xhtml);
80        $this->assertStringContainsString('bpmn_js_canvas', $xhtml);
81        $this->assertStringContainsString('bpmn_js_container', $xhtml);
82    }
83
84    /**
85     * Test empty content between tags
86     */
87    public function test_syntax_empty_content()
88    {
89        $info = array();
90
91        $input = <<<IN
92        <bpmnio type="bpmn">
93        </bpmnio>
94        IN;
95
96        $instructions = p_get_instructions($input);
97        $xhtml = p_render('xhtml', $instructions, $info);
98
99        // Should still produce the structure, with base64 of whitespace/empty
100        $this->assertStringContainsString('plugin-bpmnio', $xhtml);
101        $this->assertStringContainsString('bpmn_js_data', $xhtml);
102    }
103
104    /**
105     * Test that multiline XML content is properly base64-encoded
106     */
107    public function test_syntax_multiline_content()
108    {
109        $info = array();
110
111        $input = <<<IN
112        <bpmnio type="bpmn">
113        <?xml version="1.0"?>
114        <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
115        </definitions>
116        </bpmnio>
117        IN;
118
119        $instructions = p_get_instructions($input);
120        $xhtml = p_render('xhtml', $instructions, $info);
121
122        $this->assertStringContainsString('bpmn_js_data', $xhtml);
123        // Verify the data section contains valid base64
124        preg_match('/<div class="bpmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $matches);
125        $this->assertNotEmpty($matches[1]);
126        $decoded = base64_decode(trim($matches[1]), true);
127        $this->assertNotFalse($decoded, 'Content should be valid base64');
128        $this->assertStringContainsString('definitions', $decoded);
129    }
130
131    /**
132     * Test that the plugin produces section edit markers for inline content
133     */
134    public function test_syntax_section_edit_bpmn()
135    {
136        $info = array();
137
138        $input = <<<IN
139        <bpmnio type="bpmn">
140        Content
141        </bpmnio>
142        IN;
143
144        $instructions = p_get_instructions($input);
145        $xhtml = p_render('xhtml', $instructions, $info);
146
147        $this->assertStringContainsString('sectionedit', $xhtml);
148        $this->assertStringContainsString('plugin_bpmnio_bpmn', $xhtml);
149    }
150
151    /**
152     * Test that the plugin produces section edit markers for DMN inline content
153     */
154    public function test_syntax_section_edit_dmn()
155    {
156        $info = array();
157
158        $input = <<<IN
159        <bpmnio type="dmn">
160        Content
161        </bpmnio>
162        IN;
163
164        $instructions = p_get_instructions($input);
165        $xhtml = p_render('xhtml', $instructions, $info);
166
167        $this->assertStringContainsString('sectionedit', $xhtml);
168        $this->assertStringContainsString('plugin_bpmnio_dmn', $xhtml);
169    }
170
171    /**
172     * Test that unrecognized text outside <bpmnio> is not affected
173     */
174    public function test_syntax_no_interference()
175    {
176        $info = array();
177
178        $input = <<<IN
179        Hello World
180        <bpmnio type="bpmn">
181        XML...
182        </bpmnio>
183        Goodbye World
184        IN;
185
186        $instructions = p_get_instructions($input);
187        $xhtml = p_render('xhtml', $instructions, $info);
188
189        $this->assertStringContainsString('Hello World', $xhtml);
190        $this->assertStringContainsString('Goodbye World', $xhtml);
191        $this->assertStringContainsString('plugin-bpmnio', $xhtml);
192    }
193
194    public function test_syntax_zoom_attribute()
195    {
196        $info = array();
197
198        $input = <<<IN
199        <bpmnio type="bpmn" zoom="0.5">
200        XML...
201        </bpmnio>
202        IN;
203
204        $instructions = p_get_instructions($input);
205        $xhtml = p_render('xhtml', $instructions, $info);
206
207        $this->assertStringContainsString('data-zoom="0.5"', $xhtml);
208    }
209
210    public function test_syntax_ignores_invalid_zoom_attribute()
211    {
212        $info = array();
213
214        $input = <<<IN
215        <bpmnio type="bpmn" zoom="0">
216        XML...
217        </bpmnio>
218        IN;
219
220        $instructions = p_get_instructions($input);
221        $xhtml = p_render('xhtml', $instructions, $info);
222
223        $this->assertStringNotContainsString('data-zoom=', $xhtml);
224    }
225
226        public function test_syntax_builds_link_payload_for_named_elements()
227        {
228                $info = array();
229                io_mkdir_p(dirname(wikiFN('docs:start')));
230                io_saveFile(wikiFN('docs:start'), 'Read docs');
231
232                $input = <<<IN
233                <bpmnio type="bpmn">
234                <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
235                    <process id="Process_1">
236                        <task id="Task_1" name="[[:docs:start|Read docs]]" />
237                    </process>
238                </definitions>
239                </bpmnio>
240                IN;
241
242                $instructions = p_get_instructions($input);
243                $xhtml = p_render('xhtml', $instructions, $info);
244
245                preg_match('/<div class="bpmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $xmlMatch);
246                $this->assertNotEmpty($xmlMatch[1]);
247                $decodedXml = base64_decode(trim($xmlMatch[1]), true);
248                $this->assertNotFalse($decodedXml);
249                $this->assertStringContainsString('name="Read docs"', $decodedXml);
250                $this->assertStringNotContainsString('[[', $decodedXml);
251
252                preg_match('/<div class="bpmn_js_links">\s*(.*?)\s*<\/div>/s', $xhtml, $linkMatch);
253                $this->assertNotEmpty($linkMatch[1]);
254                $decodedLinks = base64_decode(trim($linkMatch[1]), true);
255                $this->assertNotFalse($decodedLinks);
256                $links = json_decode($decodedLinks, true);
257
258                $this->assertIsArray($links);
259                $this->assertArrayHasKey('Task_1', $links);
260                $this->assertEquals('/doku.php?id=docs%3Astart', $links['Task_1']['href']);
261                $this->assertEquals('docs:start', $links['Task_1']['target']);
262        }
263
264        public function test_syntax_keeps_unlinked_names_unchanged()
265        {
266                $info = array();
267
268                $input = <<<IN
269                <bpmnio type="dmn">
270                <?xml version="1.0" encoding="UTF-8"?>
271                <definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" id="Definitions_1">
272                    <decision id="Decision_1" name="Approve Order" />
273                </definitions>
274                </bpmnio>
275                IN;
276
277                $instructions = p_get_instructions($input);
278                $xhtml = p_render('xhtml', $instructions, $info);
279
280                preg_match('/<div class="dmn_js_data">\s*(.*?)\s*<\/div>/s', $xhtml, $xmlMatch);
281                $decodedXml = base64_decode(trim($xmlMatch[1]), true);
282                $this->assertNotFalse($decodedXml);
283                $this->assertStringContainsString('Approve Order', $decodedXml);
284
285                preg_match('/<div class="dmn_js_links">\s*(.*?)\s*<\/div>/s', $xhtml, $linkMatch);
286                $decodedLinks = base64_decode(trim($linkMatch[1]), true);
287                $this->assertSame('[]', $decodedLinks);
288        }
289
290    /**
291     * Test the handle method directly for ENTER state
292     */
293    public function test_handle_enter_state()
294    {
295        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
296        $this->assertNotNull($plugin, 'Plugin should be loadable');
297
298        $handler = new Doku_Handler();
299        $result = $plugin->handle('<bpmnio type="bpmn">', DOKU_LEXER_ENTER, 0, $handler);
300
301        $this->assertEquals(DOKU_LEXER_ENTER, $result[0]);
302        $this->assertEquals('bpmn', $result[1]);
303    }
304
305    /**
306     * Test the handle method directly for EXIT state
307     */
308    public function test_handle_exit_state()
309    {
310        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
311        $handler = new Doku_Handler();
312        $result = $plugin->handle('</bpmnio>', DOKU_LEXER_EXIT, 0, $handler);
313
314        $this->assertEquals(DOKU_LEXER_EXIT, $result[0]);
315    }
316
317    /**
318     * Test that the plugin is correctly registered
319     */
320    public function test_plugin_registration()
321    {
322        $plugin = plugin_load('syntax', 'bpmnio_bpmnio');
323        $this->assertNotNull($plugin, 'Plugin should be loadable');
324        $this->assertEquals('block', $plugin->getPType());
325        $this->assertEquals('protected', $plugin->getType());
326        $this->assertEquals(0, $plugin->getSort());
327    }
328}
329