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