##// END OF EJS Templates
Rails4: replace hard-coded html with class at Redmine::WikiFormatting::MacrosTest...
Toshi MARUYAMA -
r12601:2fc8ede0933b
parent child
Show More
@@ -1,362 +1,374
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 20 class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
21 21 include ApplicationHelper
22 22 include ActionView::Helpers::TextHelper
23 23 include ActionView::Helpers::SanitizeHelper
24 24 include ERB::Util
25 25 extend ActionView::Helpers::SanitizeHelper::ClassMethods
26 26
27 27 fixtures :projects, :roles, :enabled_modules, :users,
28 28 :repositories, :changesets,
29 29 :trackers, :issue_statuses, :issues,
30 30 :versions, :documents,
31 31 :wikis, :wiki_pages, :wiki_contents,
32 32 :boards, :messages,
33 33 :attachments
34 34
35 35 def setup
36 36 super
37 37 @project = nil
38 38 end
39 39
40 40 def teardown
41 41 end
42 42
43 43 def test_macro_registration
44 44 Redmine::WikiFormatting::Macros.register do
45 45 macro :foo do |obj, args|
46 46 "Foo: #{args.size} (#{args.join(',')}) (#{args.class.name})"
47 47 end
48 48 end
49 49
50 50 assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo}}")
51 51 assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo()}}")
52 52 assert_equal '<p>Foo: 1 (arg1) (Array)</p>', textilizable("{{foo(arg1)}}")
53 53 assert_equal '<p>Foo: 2 (arg1,arg2) (Array)</p>', textilizable("{{foo(arg1, arg2)}}")
54 54 end
55 55
56 56 def test_macro_registration_parse_args_set_to_false_should_disable_arguments_parsing
57 57 Redmine::WikiFormatting::Macros.register do
58 58 macro :bar, :parse_args => false do |obj, args|
59 59 "Bar: (#{args}) (#{args.class.name})"
60 60 end
61 61 end
62 62
63 63 assert_equal '<p>Bar: (args, more args) (String)</p>', textilizable("{{bar(args, more args)}}")
64 64 assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar}}")
65 65 assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar()}}")
66 66 end
67 67
68 68 def test_macro_registration_with_3_args_should_receive_text_argument
69 69 Redmine::WikiFormatting::Macros.register do
70 70 macro :baz do |obj, args, text|
71 71 "Baz: (#{args.join(',')}) (#{text.class.name}) (#{text})"
72 72 end
73 73 end
74 74
75 75 assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz}}")
76 76 assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz()}}")
77 77 assert_equal "<p>Baz: () (String) (line1\nline2)</p>", textilizable("{{baz()\nline1\nline2\n}}")
78 78 assert_equal "<p>Baz: (arg1,arg2) (String) (line1\nline2)</p>", textilizable("{{baz(arg1, arg2)\nline1\nline2\n}}")
79 79 end
80 80
81 81 def test_macro_name_with_upper_case
82 82 Redmine::WikiFormatting::Macros.macro(:UpperCase) {|obj, args| "Upper"}
83 83
84 84 assert_equal "<p>Upper</p>", textilizable("{{UpperCase}}")
85 85 end
86 86
87 87 def test_multiple_macros_on_the_same_line
88 88 Redmine::WikiFormatting::Macros.macro :foo do |obj, args|
89 89 args.any? ? "args: #{args.join(',')}" : "no args"
90 90 end
91 91
92 92 assert_equal '<p>no args no args</p>', textilizable("{{foo}} {{foo}}")
93 93 assert_equal '<p>args: a,b no args</p>', textilizable("{{foo(a,b)}} {{foo}}")
94 94 assert_equal '<p>args: a,b args: c,d</p>', textilizable("{{foo(a,b)}} {{foo(c,d)}}")
95 95 assert_equal '<p>no args args: c,d</p>', textilizable("{{foo}} {{foo(c,d)}}")
96 96 end
97 97
98 98 def test_macro_should_receive_the_object_as_argument_when_with_object_and_attribute
99 99 issue = Issue.find(1)
100 100 issue.description = "{{hello_world}}"
101 101 assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(issue, :description)
102 102 end
103 103
104 104 def test_macro_should_receive_the_object_as_argument_when_called_with_object_option
105 105 text = "{{hello_world}}"
106 106 assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
107 107 end
108 108
109 109 def test_extract_macro_options_should_with_args
110 110 options = extract_macro_options(["arg1", "arg2"], :foo, :size)
111 111 assert_equal([["arg1", "arg2"], {}], options)
112 112 end
113 113
114 114 def test_extract_macro_options_should_with_options
115 115 options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
116 116 assert_equal([[], {:foo => "bar", :size => "2"}], options)
117 117 end
118 118
119 119 def test_extract_macro_options_should_with_args_and_options
120 120 options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
121 121 assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
122 122 end
123 123
124 124 def test_extract_macro_options_should_parse_options_lazily
125 125 options = extract_macro_options(["params=x=1&y=2"], :params)
126 126 assert_equal([[], {:params => "x=1&y=2"}], options)
127 127 end
128 128
129 129 def test_macro_exception_should_be_displayed
130 130 Redmine::WikiFormatting::Macros.macro :exception do |obj, args|
131 131 raise "My message"
132 132 end
133 133
134 134 text = "{{exception}}"
135 135 assert_include '<div class="flash error">Error executing the <strong>exception</strong> macro (My message)</div>', textilizable(text)
136 136 end
137 137
138 138 def test_macro_arguments_should_not_be_parsed_by_formatters
139 139 text = '{{hello_world(http://www.redmine.org, #1)}}'
140 140 assert_include 'Arguments: http://www.redmine.org, #1', textilizable(text)
141 141 end
142 142
143 143 def test_exclamation_mark_should_not_run_macros
144 144 text = "!{{hello_world}}"
145 145 assert_equal '<p>{{hello_world}}</p>', textilizable(text)
146 146 end
147 147
148 148 def test_exclamation_mark_should_escape_macros
149 149 text = "!{{hello_world(<tag>)}}"
150 150 assert_equal '<p>{{hello_world(&lt;tag&gt;)}}</p>', textilizable(text)
151 151 end
152 152
153 153 def test_unknown_macros_should_not_be_replaced
154 154 text = "{{unknown}}"
155 155 assert_equal '<p>{{unknown}}</p>', textilizable(text)
156 156 end
157 157
158 158 def test_unknown_macros_should_parsed_as_text
159 159 text = "{{unknown(*test*)}}"
160 160 assert_equal '<p>{{unknown(<strong>test</strong>)}}</p>', textilizable(text)
161 161 end
162 162
163 163 def test_unknown_macros_should_be_escaped
164 164 text = "{{unknown(<tag>)}}"
165 165 assert_equal '<p>{{unknown(&lt;tag&gt;)}}</p>', textilizable(text)
166 166 end
167 167
168 168 def test_html_safe_macro_output_should_not_be_escaped
169 169 Redmine::WikiFormatting::Macros.macro :safe_macro do |obj, args|
170 170 "<tag>".html_safe
171 171 end
172 172 assert_equal '<p><tag></p>', textilizable("{{safe_macro}}")
173 173 end
174 174
175 175 def test_macro_hello_world
176 176 text = "{{hello_world}}"
177 177 assert textilizable(text).match(/Hello world!/)
178 178 end
179 179
180 180 def test_macro_hello_world_should_escape_arguments
181 181 text = "{{hello_world(<tag>)}}"
182 182 assert_include 'Arguments: &lt;tag&gt;', textilizable(text)
183 183 end
184 184
185 185 def test_macro_macro_list
186 186 text = "{{macro_list}}"
187 187 assert_match %r{<code>hello_world</code>}, textilizable(text)
188 188 end
189 189
190 190 def test_macro_include
191 191 @project = Project.find(1)
192 192 # include a page of the current project wiki
193 193 text = "{{include(Another page)}}"
194 194 assert_include 'This is a link to a ticket', textilizable(text)
195 195
196 196 @project = nil
197 197 # include a page of a specific project wiki
198 198 text = "{{include(ecookbook:Another page)}}"
199 199 assert_include 'This is a link to a ticket', textilizable(text)
200 200
201 201 text = "{{include(ecookbook:)}}"
202 202 assert_include 'CookBook documentation', textilizable(text)
203 203
204 204 text = "{{include(unknowidentifier:somepage)}}"
205 205 assert_include 'Page not found', textilizable(text)
206 206 end
207 207
208 208 def test_macro_collapse
209 209 text = "{{collapse\n*Collapsed* block of text\n}}"
210 210 result = textilizable(text)
211 211
212 212 assert_select_in result, 'div.collapsed-text'
213 213 assert_select_in result, 'strong', :text => 'Collapsed'
214 214 assert_select_in result, 'a.collapsible.collapsed', :text => 'Show'
215 215 assert_select_in result, 'a.collapsible', :text => 'Hide'
216 216 end
217 217
218 218 def test_macro_collapse_with_one_arg
219 219 text = "{{collapse(Example)\n*Collapsed* block of text\n}}"
220 220 result = textilizable(text)
221 221
222 222 assert_select_in result, 'div.collapsed-text'
223 223 assert_select_in result, 'strong', :text => 'Collapsed'
224 224 assert_select_in result, 'a.collapsible.collapsed', :text => 'Example'
225 225 assert_select_in result, 'a.collapsible', :text => 'Example'
226 226 end
227 227
228 228 def test_macro_collapse_with_two_args
229 229 text = "{{collapse(Show example, Hide example)\n*Collapsed* block of text\n}}"
230 230 result = textilizable(text)
231 231
232 232 assert_select_in result, 'div.collapsed-text'
233 233 assert_select_in result, 'strong', :text => 'Collapsed'
234 234 assert_select_in result, 'a.collapsible.collapsed', :text => 'Show example'
235 235 assert_select_in result, 'a.collapsible', :text => 'Hide example'
236 236 end
237 237
238 238 def test_macro_child_pages
239 239 expected = "<p><ul class=\"pages-hierarchy\">\n" +
240 240 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
241 241 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
242 242 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
243 243 "</ul>\n</p>"
244 244
245 245 @project = Project.find(1)
246 246 # child pages of the current wiki page
247 247 assert_equal expected, textilizable("{{child_pages}}", :object => WikiPage.find(2).content)
248 248 # child pages of another page
249 249 assert_equal expected, textilizable("{{child_pages(Another_page)}}", :object => WikiPage.find(1).content)
250 250
251 251 @project = Project.find(2)
252 252 assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
253 253 end
254 254
255 255 def test_macro_child_pages_with_parent_option
256 256 expected = "<p><ul class=\"pages-hierarchy\">\n" +
257 257 "<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
258 258 "<ul class=\"pages-hierarchy\">\n" +
259 259 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
260 260 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
261 261 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
262 262 "</ul>\n</li>\n</ul>\n</p>"
263 263
264 264 @project = Project.find(1)
265 265 # child pages of the current wiki page
266 266 assert_equal expected, textilizable("{{child_pages(parent=1)}}", :object => WikiPage.find(2).content)
267 267 # child pages of another page
268 268 assert_equal expected, textilizable("{{child_pages(Another_page, parent=1)}}", :object => WikiPage.find(1).content)
269 269
270 270 @project = Project.find(2)
271 271 assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
272 272 end
273 273
274 274 def test_macro_child_pages_with_depth_option
275 275 expected = "<p><ul class=\"pages-hierarchy\">\n" +
276 276 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
277 277 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
278 278 "</ul>\n</p>"
279 279
280 280 @project = Project.find(1)
281 281 assert_equal expected, textilizable("{{child_pages(depth=1)}}", :object => WikiPage.find(2).content)
282 282 end
283 283
284 284 def test_macro_child_pages_without_wiki_page_should_fail
285 285 assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}")
286 286 end
287 287
288 288 def test_macro_thumbnail
289 assert_equal '<p><a href="/attachments/17" class="thumbnail" title="testfile.PNG"><img alt="testfile.PNG" src="/attachments/thumbnail/17" /></a></p>',
289 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
290 "/attachments/17",
291 :class => "thumbnail",
292 :title => "testfile.PNG")
293 assert_equal "<p>#{link}</p>",
290 294 textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14))
291 295 end
292 296
293 297 def test_macro_thumbnail_with_size
294 assert_equal '<p><a href="/attachments/17" class="thumbnail" title="testfile.PNG"><img alt="testfile.PNG" src="/attachments/thumbnail/17/200" /></a></p>',
298 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
299 "/attachments/17",
300 :class => "thumbnail",
301 :title => "testfile.PNG")
302 assert_equal "<p>#{link}</p>",
295 303 textilizable("{{thumbnail(testfile.png, size=200)}}", :object => Issue.find(14))
296 304 end
297 305
298 306 def test_macro_thumbnail_with_title
299 assert_equal '<p><a href="/attachments/17" class="thumbnail" title="Cool image"><img alt="testfile.PNG" src="/attachments/thumbnail/17" /></a></p>',
307 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
308 "/attachments/17",
309 :class => "thumbnail",
310 :title => "Cool image")
311 assert_equal "<p>#{link}</p>",
300 312 textilizable("{{thumbnail(testfile.png, title=Cool image)}}", :object => Issue.find(14))
301 313 end
302 314
303 315 def test_macro_thumbnail_with_invalid_filename_should_fail
304 316 assert_include 'test.png not found',
305 317 textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
306 318 end
307 319
308 320 def test_macros_should_not_be_executed_in_pre_tags
309 321 text = <<-RAW
310 322 {{hello_world(foo)}}
311 323
312 324 <pre>
313 325 {{hello_world(pre)}}
314 326 !{{hello_world(pre)}}
315 327 </pre>
316 328
317 329 {{hello_world(bar)}}
318 330 RAW
319 331
320 332 expected = <<-EXPECTED
321 333 <p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
322 334
323 335 <pre>
324 336 {{hello_world(pre)}}
325 337 !{{hello_world(pre)}}
326 338 </pre>
327 339
328 340 <p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
329 341 EXPECTED
330 342
331 343 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
332 344 end
333 345
334 346 def test_macros_should_be_escaped_in_pre_tags
335 347 text = "<pre>{{hello_world(<tag>)}}</pre>"
336 348 assert_equal "<pre>{{hello_world(&lt;tag&gt;)}}</pre>", textilizable(text)
337 349 end
338 350
339 351 def test_macros_should_not_mangle_next_macros_outputs
340 352 text = '{{macro(2)}} !{{macro(2)}} {{hello_world(foo)}}'
341 353 assert_equal '<p>{{macro(2)}} {{macro(2)}} Hello world! Object: NilClass, Arguments: foo and no block of text.</p>', textilizable(text)
342 354 end
343 355
344 356 def test_macros_with_text_should_not_mangle_following_macros
345 357 text = <<-RAW
346 358 {{hello_world
347 359 Line of text
348 360 }}
349 361
350 362 {{hello_world
351 363 Another line of text
352 364 }}
353 365 RAW
354 366
355 367 expected = <<-EXPECTED
356 368 <p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
357 369 <p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
358 370 EXPECTED
359 371
360 372 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
361 373 end
362 374 end
General Comments 0
You need to be logged in to leave comments. Login now