blob: f9bb0ae7ce1717a79ea5276cb635676e913052b2 [file] [log] [blame]
Akronc8ffbac2026-07-22 17:58:54 +02001use Mojo::Base -strict;
2use Test::More;
3use Test::Mojo;
4use Mojolicious::Lite;
5
6my $link_cb_called = 0;
7
8plugin 'TagHelpers::ContentBlock';
9
10plugin 'Kalamar::Plugin::Markdown' => {
11 heading_offset => 2,
12 link_callback => sub {
13 my ($c, $url, $text) = @_;
14 $link_cb_called++;
15 if ($url =~ m{^/doc/}) {
16 return qq{<a href="$url" class="embedded-link">$text</a>};
17 }
18 if ($url =~ m{^https?://}) {
19 return qq{<a href="$url" target="_top">$text</a>};
20 }
21 return undef;
22 },
23};
24
25get '/md-inline' => sub {
26 shift->render(
27 handler => 'md',
28 inline => "# Heading\n\nSome **bold** text.\n"
29 );
30};
31
32get '/md-page' => sub {
33 shift->render(
34 template => 'test_page',
35 handler => 'md',
36 format => 'html',
37 name => 'World'
38 );
39};
40
41get '/md-helper' => sub {
42 shift->render(
43 template => 'test_helper',
44 handler => 'ep',
45 format => 'html'
46 );
47};
48
49get '/md-links' => sub {
50 shift->render(
51 handler => 'md',
52 inline => "[FAQ](/doc/faq)\n\n[GitHub](https://github.com)\n\n[relative](page)\n"
53 );
54};
55
56get '/md-html' => sub {
57 shift->render(
58 handler => 'md',
59 inline => qq{<pre class="query tutorial"><code>Baum</code></pre>\n\nSome text.\n}
60 );
61};
62
63get '/md-ep' => sub {
64 shift->render(
65 template => 'test_ep',
66 handler => 'md',
67 format => 'html',
68 title => 'Test Title'
69 );
70};
71
72get '/md-table' => sub {
73 shift->render(
74 handler => 'md',
75 inline => "| A | B |\n|---|---|\n| 1 | 2 |\n"
76 );
77};
78
79get '/md-comment' => sub {
80 shift->render(
81 handler => 'md',
82 inline => "<!-- maintenance note -->\n\nVisible text.\n\n"
83 . "Inline <!-- hidden --> text.\n\n"
84 . " <!-- in a code block -->\n"
85 );
86};
87
88get '/md-content-block' => sub {
89 my $c = shift;
90 $c->content_block('test_block' => { inline => '<span class="from-block">block content</span>' });
91 $c->render(
92 template => 'test_content_block',
93 handler => 'md',
94 format => 'html'
95 );
96};
97
98get '/md-details' => sub {
99 shift->render(
100 handler => 'md',
101 inline => "<details>\n<summary>More</summary>\n\n### Section\n\n- item\n\n</details>\n"
102 );
103};
104
105my $t = Test::Mojo->new;
106
107ok($t->app->renderer->handlers->{md}, 'md handler registered');
108
109ok($t->app->renderer->helpers->{markdown}, 'markdown helper registered');
110
111$t->get_ok('/md-inline')
112 ->status_is(200)
113 ->content_like(qr/<h3>Heading<\/h3>/)
114 ->content_like(qr/<strong>bold<\/strong>/)
115 ;
116
117$t->get_ok('/md-inline')
118 ->content_like(qr/<h3>/)
119 ->content_unlike(qr/<h1>/)
120 ;
121
122$t->get_ok('/md-page')
123 ->status_is(200)
124 ->content_like(qr/Hello, World/)
125 ->content_like(qr/<h3>/)
126 ;
127
128$t->get_ok('/md-helper')
129 ->status_is(200)
130 ->content_like(qr/<h3>Helper Section<\/h3>/)
131 ->content_like(qr/<strong>works<\/strong>/)
132 ;
133
134$link_cb_called = 0;
135$t->get_ok('/md-links')
136 ->status_is(200)
137 ->content_like(qr/class="embedded-link"/)
138 ->content_like(qr/target="_top"/)
139 ->content_like(qr/<a href="page">relative/)
140 ;
141ok($link_cb_called >= 3, 'link callback was called');
142
143$t->get_ok('/md-html')
144 ->status_is(200)
145 ->content_like(qr/<pre class="query tutorial">/)
146 ->content_like(qr/<code>Baum<\/code>/)
147 ;
148
149$t->get_ok('/md-ep')
150 ->status_is(200)
151 ->content_like(qr/Test Title/)
152 ;
153
154$t->get_ok('/md-table')
155 ->status_is(200)
156 ->content_like(qr/<table>/)
157 ->content_like(qr/<td>1<\/td>/)
158 ;
159
160$t->get_ok('/md-content-block')
161 ->status_is(200)
162 ->content_like(qr/class="from-block"/)
163 ->content_like(qr/block content/)
164 ;
165
166# HTML5 block elements (details/summary/...) survive conversion: the stray
167# <p> wrapper Text::MultiMarkdown adds is removed and the inner Markdown is
168# still converted.
169$t->get_ok('/md-details')
170 ->status_is(200)
171 ->content_like(qr/<details>/)
172 ->content_like(qr/<summary>More<\/summary>/)
173 ->content_like(qr/<\/details>/)
174 ->content_unlike(qr/<p>\s*<details>/)
175 ->content_unlike(qr/<p>\s*<summary>/)
176 ->content_unlike(qr/<p>\s*<\/details>/)
177 ->content_like(qr/<li>item<\/li>/)
178 ;
179
180# Unwrapping can be disabled
181my $wrapped = Mojolicious->new;
182$wrapped->plugin('Kalamar::Plugin::Markdown' => { unwrap_html5_blocks => 0 });
183like(
184 $wrapped->build_controller->markdown("<details>\n<summary>x</summary>\n</details>\n"),
185 qr/<p>\s*<details>/,
186 'block unwrapping skipped with unwrap_html5_blocks => 0'
187);
188
189$t->get_ok('/md-comment')
190 ->status_is(200)
191 ->content_unlike(qr/maintenance note/)
192 ->content_unlike(qr/hidden/)
193 ->content_like(qr/Visible text\./)
194 ->content_like(qr/Inline\s*text\./)
195 ->content_like(qr/&lt;!-- in a code block --&gt;/)
196 ;
197
198# Comments are kept when the option is disabled
199my $keep = Mojolicious->new;
200$keep->plugin('Kalamar::Plugin::Markdown' => { strip_comments => 0 });
201like(
202 $keep->build_controller->markdown("<!-- kept -->\n\nText.\n"),
203 qr/<!-- kept -->/,
204 'comment kept with strip_comments => 0'
205);
206
207done_testing;
208
209__DATA__
210
211@@ test_page.html.md
212# Welcome
213
214Hello, <%= $name %>!
215
216@@ test_helper.html.ep
217<div>
218%= markdown begin
219# Helper Section
220This **works** well.
221% end
222</div>
223
224@@ test_ep.html.md
225# Page: <%= $title %>
226
227This page is about **<%= $title %>**.
228
229@@ test_content_block.html.md
230# Content Block Test
231
232%= content_block 'test_block'
233
234Some **markdown** after the block.