]> BookStack Code Mirror - bookstack/blob - tests/Unit/PageIncludeParserTest.php
ee7a64344de7b468643079772224aec7bf07b4bf
[bookstack] / tests / Unit / PageIncludeParserTest.php
1 <?php
2
3 namespace Tests\Unit;
4
5 use BookStack\Entities\Tools\PageIncludeParser;
6 use Tests\TestCase;
7
8 class PageIncludeParserTest extends TestCase
9 {
10     public function test_simple_inline_text()
11     {
12         $this->runParserTest(
13             '<p>{{@45#content}}</p>',
14             ['45' => '<p id="content">Testing</p>'],
15             '<p>Testing</p>',
16         );
17     }
18
19     public function test_simple_inline_text_with_existing_siblings()
20     {
21         $this->runParserTest(
22             '<p>{{@45#content}} <strong>Hi</strong>there!</p>',
23             ['45' => '<p id="content">Testing</p>'],
24             '<p>Testing <strong>Hi</strong>there!</p>',
25         );
26     }
27
28     public function test_simple_inline_text_within_other_text()
29     {
30         $this->runParserTest(
31             '<p>Hello {{@45#content}}there!</p>',
32             ['45' => '<p id="content">Testing</p>'],
33             '<p>Hello Testingthere!</p>',
34         );
35     }
36
37     public function test_complex_inline_text_within_other_text()
38     {
39         $this->runParserTest(
40             '<p>Hello {{@45#content}}there!</p>',
41             ['45' => '<p id="content"><strong>Testing</strong> with<em>some</em><i>extra</i>tags</p>'],
42             '<p>Hello <strong>Testing</strong> with<em>some</em><i>extra</i>tagsthere!</p>',
43         );
44     }
45
46     public function test_block_content_types()
47     {
48         $inputs = [
49             '<table id="content"><td>Text</td></table>',
50             '<ul id="content"><li>Item A</li></ul>',
51             '<ol id="content"><li>Item A</li></ol>',
52             '<pre id="content">Code</pre>',
53         ];
54
55         foreach ($inputs as $input) {
56             $this->runParserTest(
57                 '<p>A{{@45#content}}B</p>',
58                 ['45' => $input],
59                 '<p>A</p>' . $input . '<p>B</p>',
60             );
61         }
62     }
63
64     public function test_block_content_nested_origin_gets_placed_before()
65     {
66         $this->runParserTest(
67             '<p><strong>A {{@45#content}} there!</strong></p>',
68             ['45' => '<pre id="content">Testing</pre>'],
69             '<pre id="content">Testing</pre><p><strong>A  there!</strong></p>',
70         );
71     }
72
73     public function test_block_content_nested_origin_gets_placed_after()
74     {
75         $this->runParserTest(
76             '<p><strong>Some really good {{@45#content}} there!</strong></p>',
77             ['45' => '<pre id="content">Testing</pre>'],
78             '<p><strong>Some really good  there!</strong></p><pre id="content">Testing</pre>',
79         );
80     }
81
82     public function test_block_content_in_shallow_origin_gets_split()
83     {
84         $this->runParserTest(
85             '<p>Some really good {{@45#content}} there!</p>',
86             ['45' => '<pre id="content">doggos</pre>'],
87             '<p>Some really good </p><pre id="content">doggos</pre><p> there!</p>',
88         );
89     }
90
91     public function test_block_content_in_shallow_origin_split_does_not_duplicate_id()
92     {
93         $this->runParserTest(
94             '<p id="test" title="Hi">Some really good {{@45#content}} there!</p>',
95             ['45' => '<pre id="content">doggos</pre>'],
96             '<p title="Hi">Some really good </p><pre id="content">doggos</pre><p id="test" title="Hi"> there!</p>',
97         );
98     }
99
100     public function test_block_content_in_shallow_origin_does_not_leave_empty_nodes()
101     {
102         $this->runParserTest(
103             '<p>{{@45#content}}</p>',
104             ['45' => '<pre id="content">doggos</pre>'],
105             '<pre id="content">doggos</pre>',
106         );
107     }
108
109     public function test_block_content_in_allowable_parent_element()
110     {
111         $this->runParserTest(
112             '<div>{{@45#content}}</div>',
113             ['45' => '<pre id="content">doggos</pre>'],
114             '<div><pre id="content">doggos</pre></div>',
115         );
116     }
117
118     public function test_block_content_in_paragraph_origin_with_allowable_grandparent()
119     {
120         $this->runParserTest(
121             '<div><p>{{@45#content}}</p></div>',
122             ['45' => '<pre id="content">doggos</pre>'],
123             '<div><pre id="content">doggos</pre></div>',
124         );
125     }
126
127     public function test_block_content_in_paragraph_origin_with_allowable_grandparent_with_adjacent_content()
128     {
129         $this->runParserTest(
130             '<div><p>Cute {{@45#content}} over there!</p></div>',
131             ['45' => '<pre id="content">doggos</pre>'],
132             '<div><p>Cute </p><pre id="content">doggos</pre><p> over there!</p></div>',
133         );
134     }
135
136     public function test_block_content_in_child_within_paragraph_origin_with_allowable_grandparent_with_adjacent_content()
137     {
138         $this->runParserTest(
139             '<div><p><strong>Cute {{@45#content}} over there!</strong></p></div>',
140             ['45' => '<pre id="content">doggos</pre>'],
141             '<div><pre id="content">doggos</pre><p><strong>Cute  over there!</strong></p></div>',
142         );
143     }
144
145     public function test_block_content_in_paragraph_origin_within_details()
146     {
147         $this->runParserTest(
148             '<details><p>{{@45#content}}</p></details>',
149             ['45' => '<pre id="content">doggos</pre>'],
150             '<details><pre id="content">doggos</pre></details>',
151         );
152     }
153
154     public function test_simple_whole_document()
155     {
156         $this->runParserTest(
157             '<p>{{@45}}</p>',
158             ['45' => '<p id="content">Testing</p>'],
159             '<p id="content">Testing</p>',
160         );
161     }
162
163     public function test_multi_source_elem_whole_document()
164     {
165         $this->runParserTest(
166             '<p>{{@45}}</p>',
167             ['45' => '<p>Testing</p><blockquote>This</blockquote>'],
168             '<p>Testing</p><blockquote>This</blockquote>',
169         );
170     }
171
172     public function test_multi_source_elem_whole_document_with_shared_content_origin()
173     {
174         $this->runParserTest(
175             '<p>This is {{@45}} some text</p>',
176             ['45' => '<p>Testing</p><blockquote>This</blockquote>'],
177             '<p>This is </p><p>Testing</p><blockquote>This</blockquote><p> some text</p>',
178         );
179     }
180
181     public function test_multiple_tags_in_same_origin_with_inline_content()
182     {
183         $this->runParserTest(
184             '<p>This {{@45#content}}{{@45#content}} content is {{@45#content}}</p>',
185             ['45' => '<p id="content">inline</p>'],
186             '<p>This inlineinline content is inline</p>',
187         );
188     }
189
190     public function test_multiple_tags_in_same_origin_with_block_content()
191     {
192         $this->runParserTest(
193             '<p>This {{@45#content}}{{@45#content}} content is {{@45#content}}</p>',
194             ['45' => '<pre id="content">block</pre>'],
195             '<p>This </p><pre id="content">block</pre><pre id="content">block</pre><p> content is </p><pre id="content">block</pre>',
196         );
197     }
198
199     public function test_multiple_tags_in_differing_origin_levels_with_block_content()
200     {
201         $this->runParserTest(
202             '<div><p>This <strong>{{@45#content}}</strong> content is {{@45#content}}</p>{{@45#content}}</div>',
203             ['45' => '<pre id="content">block</pre>'],
204             '<div><pre id="content">block</pre><p>This <strong></strong> content is </p><pre id="content">block</pre><pre id="content">block</pre></div>',
205         );
206     }
207
208     public function test_multiple_tags_in_shallow_origin_with_multi_block_content()
209     {
210         $this->runParserTest(
211             '<p>{{@45}}C{{@45}}</p><div>{{@45}}{{@45}}</div>',
212             ['45' => '<p>A</p><p>B</p>'],
213             '<p>A</p><p>B</p><p>C</p><p>A</p><p>B</p><div><p>A</p><p>B</p><p>A</p><p>B</p></div>',
214         );
215     }
216
217     protected function runParserTest(string $html, array $contentById, string $expected)
218     {
219         $parser = new PageIncludeParser($html, function (int $id) use ($contentById) {
220             return $contentById[strval($id)] ?? '';
221         });
222
223         $result = $parser->parse();
224         $this->assertEquals($expected, $result);
225     }
226 }