]> BookStack Code Mirror - bookstack/blob - tests/Settings/CustomHeadContentTest.php
CommentDisplayTest correct namespace
[bookstack] / tests / Settings / CustomHeadContentTest.php
1 <?php
2
3 namespace Tests\Settings;
4
5 use BookStack\Util\CspService;
6 use Tests\TestCase;
7
8 class CustomHeadContentTest extends TestCase
9 {
10     public function test_configured_content_shows_on_pages()
11     {
12         $this->setSettings(['app-custom-head' => '<script>console.log("cat");</script>']);
13         $resp = $this->get('/login');
14         $resp->assertSee('console.log("cat")', false);
15     }
16
17     public function test_content_wrapped_in_specific_html_comments()
18     {
19         // These comments are used to identify head content for editor injection
20         $this->setSettings(['app-custom-head' => '<script>console.log("cat");</script>']);
21         $resp = $this->get('/login');
22         $resp->assertSee('<!-- Start: custom user content -->', false);
23         $resp->assertSee('<!-- End: custom user content -->', false);
24     }
25
26     public function test_configured_content_does_not_show_on_settings_page()
27     {
28         $this->setSettings(['app-custom-head' => '<script>console.log("cat");</script>']);
29         $resp = $this->asAdmin()->get('/settings/features');
30         $resp->assertDontSee('console.log("cat")', false);
31     }
32
33     public function test_divs_in_js_preserved_in_configured_content()
34     {
35         $this->setSettings(['app-custom-head' => '<script><div id="hello">cat</div></script>']);
36         $resp = $this->get('/login');
37         $resp->assertSee('<div id="hello">cat</div>', false);
38     }
39
40     public function test_nonce_application_handles_edge_cases()
41     {
42         $mockCSP = $this->mock(CspService::class);
43         $mockCSP->shouldReceive('getNonce')->andReturn('abc123');
44
45         $content = trim('
46 <script>console.log("cat");</script>
47 <script type="text/html"><\script>const a = `<div></div>`<\/\script></script>
48 <script >const a = `<div></div>`;</script>
49 <script type="<script text>test">const c = `<div></div>`;</script>
50 <script
51     type="text/html"
52 >
53 const a = `<\script><\/script>`;
54 const b = `<script`;
55 </script>
56 <SCRIPT>const b = `↗️£`;</SCRIPT>
57         ');
58
59         $expectedOutput = trim('
60 <script nonce="abc123">console.log("cat");</script>
61 <script type="text/html" nonce="abc123"><\script>const a = `<div></div>`<\/\script></script>
62 <script nonce="abc123">const a = `<div></div>`;</script>
63 <script type="&lt;script text&gt;test" nonce="abc123">const c = `<div></div>`;</script>
64 <script type="text/html" nonce="abc123">
65 const a = `<\script><\/script>`;
66 const b = `<script`;
67 </script>
68 <script nonce="abc123">const b = `↗️£`;</script>
69         ');
70
71         $this->setSettings(['app-custom-head' => $content]);
72         $resp = $this->get('/login');
73         $resp->assertSee($expectedOutput, false);
74     }
75 }