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