##// END OF EJS Templates
Adds tests for class attribute parsing on pre/code tags....
Jean-Philippe Lang -
r4423:a7595ec19154
parent child
Show More
@@ -1,655 +1,658
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class ApplicationHelperTest < ActionView::TestCase
20 class ApplicationHelperTest < ActionView::TestCase
21
21
22 fixtures :projects, :roles, :enabled_modules, :users,
22 fixtures :projects, :roles, :enabled_modules, :users,
23 :repositories, :changesets,
23 :repositories, :changesets,
24 :trackers, :issue_statuses, :issues, :versions, :documents,
24 :trackers, :issue_statuses, :issues, :versions, :documents,
25 :wikis, :wiki_pages, :wiki_contents,
25 :wikis, :wiki_pages, :wiki_contents,
26 :boards, :messages,
26 :boards, :messages,
27 :attachments,
27 :attachments,
28 :enumerations
28 :enumerations
29
29
30 def setup
30 def setup
31 super
31 super
32 end
32 end
33
33
34 context "#link_to_if_authorized" do
34 context "#link_to_if_authorized" do
35 context "authorized user" do
35 context "authorized user" do
36 should "be tested"
36 should "be tested"
37 end
37 end
38
38
39 context "unauthorized user" do
39 context "unauthorized user" do
40 should "be tested"
40 should "be tested"
41 end
41 end
42
42
43 should "allow using the :controller and :action for the target link" do
43 should "allow using the :controller and :action for the target link" do
44 User.current = User.find_by_login('admin')
44 User.current = User.find_by_login('admin')
45
45
46 @project = Issue.first.project # Used by helper
46 @project = Issue.first.project # Used by helper
47 response = link_to_if_authorized("By controller/action",
47 response = link_to_if_authorized("By controller/action",
48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
49 assert_match /href/, response
49 assert_match /href/, response
50 end
50 end
51
51
52 end
52 end
53
53
54 def test_auto_links
54 def test_auto_links
55 to_test = {
55 to_test = {
56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
57 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
57 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
58 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
58 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
59 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
59 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
60 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
60 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
61 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
61 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
62 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
62 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
63 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
63 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
64 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
64 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
65 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
65 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
66 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
66 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
67 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
67 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
68 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
68 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
69 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
69 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
70 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
70 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
71 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
71 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
72 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
72 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
73 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
73 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
74 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
74 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
75 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
75 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
76 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
76 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
77 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
77 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
78 # two exclamation marks
78 # two exclamation marks
79 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
79 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
80 # escaping
80 # escaping
81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
82 # wrap in angle brackets
82 # wrap in angle brackets
83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
84 }
84 }
85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
86 end
86 end
87
87
88 def test_auto_mailto
88 def test_auto_mailto
89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
90 textilizable('test@foo.bar')
90 textilizable('test@foo.bar')
91 end
91 end
92
92
93 def test_inline_images
93 def test_inline_images
94 to_test = {
94 to_test = {
95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
96 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
96 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
97 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
97 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
98 # inline styles should be stripped
98 # inline styles should be stripped
99 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
99 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
100 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
100 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
101 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
101 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
102 }
102 }
103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
104 end
104 end
105
105
106 def test_inline_images_inside_tags
106 def test_inline_images_inside_tags
107 raw = <<-RAW
107 raw = <<-RAW
108 h1. !foo.png! Heading
108 h1. !foo.png! Heading
109
109
110 Centered image:
110 Centered image:
111
111
112 p=. !bar.gif!
112 p=. !bar.gif!
113 RAW
113 RAW
114
114
115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
117 end
117 end
118
118
119 def test_attached_images
119 def test_attached_images
120 to_test = {
120 to_test = {
121 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
121 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
123 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
123 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
124 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
124 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
125 # link image
125 # link image
126 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
126 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
127 }
127 }
128 attachments = Attachment.find(:all)
128 attachments = Attachment.find(:all)
129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
130 end
130 end
131
131
132 def test_textile_external_links
132 def test_textile_external_links
133 to_test = {
133 to_test = {
134 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
134 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
135 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
135 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
136 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
136 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
137 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
137 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
138 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
138 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
139 # no multiline link text
139 # no multiline link text
140 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
140 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
141 # mailto link
141 # mailto link
142 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
142 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
143 # two exclamation marks
143 # two exclamation marks
144 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
144 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
145 # escaping
145 # escaping
146 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
146 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
147 }
147 }
148 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
148 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
149 end
149 end
150
150
151 def test_redmine_links
151 def test_redmine_links
152 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
152 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
153 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
153 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
154
154
155 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
155 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
156 :class => 'changeset', :title => 'My very first commit')
156 :class => 'changeset', :title => 'My very first commit')
157 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
157 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
158 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
158 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
159
159
160 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
160 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
161 :class => 'document')
161 :class => 'document')
162
162
163 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
163 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
164 :class => 'version')
164 :class => 'version')
165
165
166 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
166 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
167
167
168 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
168 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
169
169
170 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
170 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
171 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
171 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
172
172
173 to_test = {
173 to_test = {
174 # tickets
174 # tickets
175 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
175 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
176 # changesets
176 # changesets
177 'r1' => changeset_link,
177 'r1' => changeset_link,
178 'r1.' => "#{changeset_link}.",
178 'r1.' => "#{changeset_link}.",
179 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
179 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
180 'r1,r2' => "#{changeset_link},#{changeset_link2}",
180 'r1,r2' => "#{changeset_link},#{changeset_link2}",
181 # documents
181 # documents
182 'document#1' => document_link,
182 'document#1' => document_link,
183 'document:"Test document"' => document_link,
183 'document:"Test document"' => document_link,
184 # versions
184 # versions
185 'version#2' => version_link,
185 'version#2' => version_link,
186 'version:1.0' => version_link,
186 'version:1.0' => version_link,
187 'version:"1.0"' => version_link,
187 'version:"1.0"' => version_link,
188 # source
188 # source
189 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
189 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
190 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
190 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
191 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
191 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
192 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
192 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
193 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
193 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
194 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
194 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
195 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
195 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
196 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
196 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
197 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
197 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
198 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
198 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
199 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
199 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
200 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
200 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
201 # message
201 # message
202 'message#4' => link_to('Post 2', message_url, :class => 'message'),
202 'message#4' => link_to('Post 2', message_url, :class => 'message'),
203 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
203 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
204 # project
204 # project
205 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
205 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
206 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
206 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
207 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
207 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
208 # escaping
208 # escaping
209 '!#3.' => '#3.',
209 '!#3.' => '#3.',
210 '!r1' => 'r1',
210 '!r1' => 'r1',
211 '!document#1' => 'document#1',
211 '!document#1' => 'document#1',
212 '!document:"Test document"' => 'document:"Test document"',
212 '!document:"Test document"' => 'document:"Test document"',
213 '!version#2' => 'version#2',
213 '!version#2' => 'version#2',
214 '!version:1.0' => 'version:1.0',
214 '!version:1.0' => 'version:1.0',
215 '!version:"1.0"' => 'version:"1.0"',
215 '!version:"1.0"' => 'version:"1.0"',
216 '!source:/some/file' => 'source:/some/file',
216 '!source:/some/file' => 'source:/some/file',
217 # not found
217 # not found
218 '#0123456789' => '#0123456789',
218 '#0123456789' => '#0123456789',
219 # invalid expressions
219 # invalid expressions
220 'source:' => 'source:',
220 'source:' => 'source:',
221 # url hash
221 # url hash
222 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
222 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
223 }
223 }
224 @project = Project.find(1)
224 @project = Project.find(1)
225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
226 end
226 end
227
227
228 def test_attachment_links
228 def test_attachment_links
229 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
229 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
230 to_test = {
230 to_test = {
231 'attachment:error281.txt' => attachment_link
231 'attachment:error281.txt' => attachment_link
232 }
232 }
233 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
233 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
234 end
234 end
235
235
236 def test_wiki_links
236 def test_wiki_links
237 to_test = {
237 to_test = {
238 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
238 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
239 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
239 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
240 # link with anchor
240 # link with anchor
241 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
241 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
242 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
242 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
243 # page that doesn't exist
243 # page that doesn't exist
244 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
244 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
245 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
245 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
246 # link to another project wiki
246 # link to another project wiki
247 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
247 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
248 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
248 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
249 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
249 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
250 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
250 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
251 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
251 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
252 # striked through link
252 # striked through link
253 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
253 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
254 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
254 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
255 # escaping
255 # escaping
256 '![[Another page|Page]]' => '[[Another page|Page]]',
256 '![[Another page|Page]]' => '[[Another page|Page]]',
257 # project does not exist
257 # project does not exist
258 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
258 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
259 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
259 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
260 }
260 }
261 @project = Project.find(1)
261 @project = Project.find(1)
262 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
262 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
263 end
263 end
264
264
265 def test_html_tags
265 def test_html_tags
266 to_test = {
266 to_test = {
267 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
267 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
268 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
268 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
269 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
269 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
270 # do not escape pre/code tags
270 # do not escape pre/code tags
271 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
271 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
272 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
272 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
273 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
273 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
274 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
274 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
275 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
275 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
276 # remove attributes except class
276 # remove attributes except class
277 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
277 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
278 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
278 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
279 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
279 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
280 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
280 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
281 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
281 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
282 # xss
283 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
284 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
282 }
285 }
283 to_test.each { |text, result| assert_equal result, textilizable(text) }
286 to_test.each { |text, result| assert_equal result, textilizable(text) }
284 end
287 end
285
288
286 def test_allowed_html_tags
289 def test_allowed_html_tags
287 to_test = {
290 to_test = {
288 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
291 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
289 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
292 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
290 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
293 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
291 }
294 }
292 to_test.each { |text, result| assert_equal result, textilizable(text) }
295 to_test.each { |text, result| assert_equal result, textilizable(text) }
293 end
296 end
294
297
295 def test_pre_tags
298 def test_pre_tags
296 raw = <<-RAW
299 raw = <<-RAW
297 Before
300 Before
298
301
299 <pre>
302 <pre>
300 <prepared-statement-cache-size>32</prepared-statement-cache-size>
303 <prepared-statement-cache-size>32</prepared-statement-cache-size>
301 </pre>
304 </pre>
302
305
303 After
306 After
304 RAW
307 RAW
305
308
306 expected = <<-EXPECTED
309 expected = <<-EXPECTED
307 <p>Before</p>
310 <p>Before</p>
308 <pre>
311 <pre>
309 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
312 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
310 </pre>
313 </pre>
311 <p>After</p>
314 <p>After</p>
312 EXPECTED
315 EXPECTED
313
316
314 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
317 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
315 end
318 end
316
319
317 def test_pre_content_should_not_parse_wiki_and_redmine_links
320 def test_pre_content_should_not_parse_wiki_and_redmine_links
318 raw = <<-RAW
321 raw = <<-RAW
319 [[CookBook documentation]]
322 [[CookBook documentation]]
320
323
321 #1
324 #1
322
325
323 <pre>
326 <pre>
324 [[CookBook documentation]]
327 [[CookBook documentation]]
325
328
326 #1
329 #1
327 </pre>
330 </pre>
328 RAW
331 RAW
329
332
330 expected = <<-EXPECTED
333 expected = <<-EXPECTED
331 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
334 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
332 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
335 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
333 <pre>
336 <pre>
334 [[CookBook documentation]]
337 [[CookBook documentation]]
335
338
336 #1
339 #1
337 </pre>
340 </pre>
338 EXPECTED
341 EXPECTED
339
342
340 @project = Project.find(1)
343 @project = Project.find(1)
341 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
344 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
342 end
345 end
343
346
344 def test_non_closing_pre_blocks_should_be_closed
347 def test_non_closing_pre_blocks_should_be_closed
345 raw = <<-RAW
348 raw = <<-RAW
346 <pre><code>
349 <pre><code>
347 RAW
350 RAW
348
351
349 expected = <<-EXPECTED
352 expected = <<-EXPECTED
350 <pre><code>
353 <pre><code>
351 </code></pre>
354 </code></pre>
352 EXPECTED
355 EXPECTED
353
356
354 @project = Project.find(1)
357 @project = Project.find(1)
355 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
358 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
356 end
359 end
357
360
358 def test_syntax_highlight
361 def test_syntax_highlight
359 raw = <<-RAW
362 raw = <<-RAW
360 <pre><code class="ruby">
363 <pre><code class="ruby">
361 # Some ruby code here
364 # Some ruby code here
362 </code></pre>
365 </code></pre>
363 RAW
366 RAW
364
367
365 expected = <<-EXPECTED
368 expected = <<-EXPECTED
366 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
369 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
367 </code></pre>
370 </code></pre>
368 EXPECTED
371 EXPECTED
369
372
370 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
373 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
371 end
374 end
372
375
373 def test_wiki_links_in_tables
376 def test_wiki_links_in_tables
374 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
377 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
375 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
378 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
376 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
379 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
377 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
380 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
378 }
381 }
379 @project = Project.find(1)
382 @project = Project.find(1)
380 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
383 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
381 end
384 end
382
385
383 def test_text_formatting
386 def test_text_formatting
384 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
387 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
385 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
388 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
386 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
389 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
387 'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
390 'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
388 'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
391 'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
389 }
392 }
390 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
393 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
391 end
394 end
392
395
393 def test_wiki_horizontal_rule
396 def test_wiki_horizontal_rule
394 assert_equal '<hr />', textilizable('---')
397 assert_equal '<hr />', textilizable('---')
395 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
398 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
396 end
399 end
397
400
398 def test_footnotes
401 def test_footnotes
399 raw = <<-RAW
402 raw = <<-RAW
400 This is some text[1].
403 This is some text[1].
401
404
402 fn1. This is the foot note
405 fn1. This is the foot note
403 RAW
406 RAW
404
407
405 expected = <<-EXPECTED
408 expected = <<-EXPECTED
406 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
409 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
407 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
410 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
408 EXPECTED
411 EXPECTED
409
412
410 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
413 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
411 end
414 end
412
415
413 def test_table_of_content
416 def test_table_of_content
414 raw = <<-RAW
417 raw = <<-RAW
415 {{toc}}
418 {{toc}}
416
419
417 h1. Title
420 h1. Title
418
421
419 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
422 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
420
423
421 h2. Subtitle with a [[Wiki]] link
424 h2. Subtitle with a [[Wiki]] link
422
425
423 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
426 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
424
427
425 h2. Subtitle with [[Wiki|another Wiki]] link
428 h2. Subtitle with [[Wiki|another Wiki]] link
426
429
427 h2. Subtitle with %{color:red}red text%
430 h2. Subtitle with %{color:red}red text%
428
431
429 h3. Subtitle with *some* _modifiers_
432 h3. Subtitle with *some* _modifiers_
430
433
431 h1. Another title
434 h1. Another title
432
435
433 h3. An "Internet link":http://www.redmine.org/ inside subtitle
436 h3. An "Internet link":http://www.redmine.org/ inside subtitle
434
437
435 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
438 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
436
439
437 RAW
440 RAW
438
441
439 expected = '<ul class="toc">' +
442 expected = '<ul class="toc">' +
440 '<li><a href="#Title">Title</a>' +
443 '<li><a href="#Title">Title</a>' +
441 '<ul>' +
444 '<ul>' +
442 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
445 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
443 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
446 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
444 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
447 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
445 '<ul>' +
448 '<ul>' +
446 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
449 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
447 '</ul>' +
450 '</ul>' +
448 '</li>' +
451 '</li>' +
449 '</ul>' +
452 '</ul>' +
450 '</li>' +
453 '</li>' +
451 '<li><a href="#Another-title">Another title</a>' +
454 '<li><a href="#Another-title">Another title</a>' +
452 '<ul>' +
455 '<ul>' +
453 '<li>' +
456 '<li>' +
454 '<ul>' +
457 '<ul>' +
455 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
458 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
456 '</ul>' +
459 '</ul>' +
457 '</li>' +
460 '</li>' +
458 '<li><a href="#Project-Name">Project Name</a></li>' +
461 '<li><a href="#Project-Name">Project Name</a></li>' +
459 '</ul>' +
462 '</ul>' +
460 '</li>' +
463 '</li>' +
461 '</ul>'
464 '</ul>'
462
465
463 @project = Project.find(1)
466 @project = Project.find(1)
464 assert textilizable(raw).gsub("\n", "").include?(expected)
467 assert textilizable(raw).gsub("\n", "").include?(expected)
465 end
468 end
466
469
467 def test_table_of_content_should_contain_included_page_headings
470 def test_table_of_content_should_contain_included_page_headings
468 raw = <<-RAW
471 raw = <<-RAW
469 {{toc}}
472 {{toc}}
470
473
471 h1. Included
474 h1. Included
472
475
473 {{include(Child_1)}}
476 {{include(Child_1)}}
474 RAW
477 RAW
475
478
476 expected = '<ul class="toc">' +
479 expected = '<ul class="toc">' +
477 '<li><a href="#Included">Included</a></li>' +
480 '<li><a href="#Included">Included</a></li>' +
478 '<li><a href="#Child-page-1">Child page 1</a></li>' +
481 '<li><a href="#Child-page-1">Child page 1</a></li>' +
479 '</ul>'
482 '</ul>'
480
483
481 @project = Project.find(1)
484 @project = Project.find(1)
482 assert textilizable(raw).gsub("\n", "").include?(expected)
485 assert textilizable(raw).gsub("\n", "").include?(expected)
483 end
486 end
484
487
485 def test_blockquote
488 def test_blockquote
486 # orig raw text
489 # orig raw text
487 raw = <<-RAW
490 raw = <<-RAW
488 John said:
491 John said:
489 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
492 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
490 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
493 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
491 > * Donec odio lorem,
494 > * Donec odio lorem,
492 > * sagittis ac,
495 > * sagittis ac,
493 > * malesuada in,
496 > * malesuada in,
494 > * adipiscing eu, dolor.
497 > * adipiscing eu, dolor.
495 >
498 >
496 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
499 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
497 > Proin a tellus. Nam vel neque.
500 > Proin a tellus. Nam vel neque.
498
501
499 He's right.
502 He's right.
500 RAW
503 RAW
501
504
502 # expected html
505 # expected html
503 expected = <<-EXPECTED
506 expected = <<-EXPECTED
504 <p>John said:</p>
507 <p>John said:</p>
505 <blockquote>
508 <blockquote>
506 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
509 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
507 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
510 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
508 <ul>
511 <ul>
509 <li>Donec odio lorem,</li>
512 <li>Donec odio lorem,</li>
510 <li>sagittis ac,</li>
513 <li>sagittis ac,</li>
511 <li>malesuada in,</li>
514 <li>malesuada in,</li>
512 <li>adipiscing eu, dolor.</li>
515 <li>adipiscing eu, dolor.</li>
513 </ul>
516 </ul>
514 <blockquote>
517 <blockquote>
515 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
518 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
516 </blockquote>
519 </blockquote>
517 <p>Proin a tellus. Nam vel neque.</p>
520 <p>Proin a tellus. Nam vel neque.</p>
518 </blockquote>
521 </blockquote>
519 <p>He's right.</p>
522 <p>He's right.</p>
520 EXPECTED
523 EXPECTED
521
524
522 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
525 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
523 end
526 end
524
527
525 def test_table
528 def test_table
526 raw = <<-RAW
529 raw = <<-RAW
527 This is a table with empty cells:
530 This is a table with empty cells:
528
531
529 |cell11|cell12||
532 |cell11|cell12||
530 |cell21||cell23|
533 |cell21||cell23|
531 |cell31|cell32|cell33|
534 |cell31|cell32|cell33|
532 RAW
535 RAW
533
536
534 expected = <<-EXPECTED
537 expected = <<-EXPECTED
535 <p>This is a table with empty cells:</p>
538 <p>This is a table with empty cells:</p>
536
539
537 <table>
540 <table>
538 <tr><td>cell11</td><td>cell12</td><td></td></tr>
541 <tr><td>cell11</td><td>cell12</td><td></td></tr>
539 <tr><td>cell21</td><td></td><td>cell23</td></tr>
542 <tr><td>cell21</td><td></td><td>cell23</td></tr>
540 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
543 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
541 </table>
544 </table>
542 EXPECTED
545 EXPECTED
543
546
544 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
547 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
545 end
548 end
546
549
547 def test_table_with_line_breaks
550 def test_table_with_line_breaks
548 raw = <<-RAW
551 raw = <<-RAW
549 This is a table with line breaks:
552 This is a table with line breaks:
550
553
551 |cell11
554 |cell11
552 continued|cell12||
555 continued|cell12||
553 |-cell21-||cell23
556 |-cell21-||cell23
554 cell23 line2
557 cell23 line2
555 cell23 *line3*|
558 cell23 *line3*|
556 |cell31|cell32
559 |cell31|cell32
557 cell32 line2|cell33|
560 cell32 line2|cell33|
558
561
559 RAW
562 RAW
560
563
561 expected = <<-EXPECTED
564 expected = <<-EXPECTED
562 <p>This is a table with line breaks:</p>
565 <p>This is a table with line breaks:</p>
563
566
564 <table>
567 <table>
565 <tr>
568 <tr>
566 <td>cell11<br />continued</td>
569 <td>cell11<br />continued</td>
567 <td>cell12</td>
570 <td>cell12</td>
568 <td></td>
571 <td></td>
569 </tr>
572 </tr>
570 <tr>
573 <tr>
571 <td><del>cell21</del></td>
574 <td><del>cell21</del></td>
572 <td></td>
575 <td></td>
573 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
576 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
574 </tr>
577 </tr>
575 <tr>
578 <tr>
576 <td>cell31</td>
579 <td>cell31</td>
577 <td>cell32<br/>cell32 line2</td>
580 <td>cell32<br/>cell32 line2</td>
578 <td>cell33</td>
581 <td>cell33</td>
579 </tr>
582 </tr>
580 </table>
583 </table>
581 EXPECTED
584 EXPECTED
582
585
583 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
586 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
584 end
587 end
585
588
586 def test_textile_should_not_mangle_brackets
589 def test_textile_should_not_mangle_brackets
587 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
590 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
588 end
591 end
589
592
590 def test_default_formatter
593 def test_default_formatter
591 Setting.text_formatting = 'unknown'
594 Setting.text_formatting = 'unknown'
592 text = 'a *link*: http://www.example.net/'
595 text = 'a *link*: http://www.example.net/'
593 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
596 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
594 Setting.text_formatting = 'textile'
597 Setting.text_formatting = 'textile'
595 end
598 end
596
599
597 def test_due_date_distance_in_words
600 def test_due_date_distance_in_words
598 to_test = { Date.today => 'Due in 0 days',
601 to_test = { Date.today => 'Due in 0 days',
599 Date.today + 1 => 'Due in 1 day',
602 Date.today + 1 => 'Due in 1 day',
600 Date.today + 100 => 'Due in about 3 months',
603 Date.today + 100 => 'Due in about 3 months',
601 Date.today + 20000 => 'Due in over 54 years',
604 Date.today + 20000 => 'Due in over 54 years',
602 Date.today - 1 => '1 day late',
605 Date.today - 1 => '1 day late',
603 Date.today - 100 => 'about 3 months late',
606 Date.today - 100 => 'about 3 months late',
604 Date.today - 20000 => 'over 54 years late',
607 Date.today - 20000 => 'over 54 years late',
605 }
608 }
606 to_test.each do |date, expected|
609 to_test.each do |date, expected|
607 assert_equal expected, due_date_distance_in_words(date)
610 assert_equal expected, due_date_distance_in_words(date)
608 end
611 end
609 end
612 end
610
613
611 def test_avatar
614 def test_avatar
612 # turn on avatars
615 # turn on avatars
613 Setting.gravatar_enabled = '1'
616 Setting.gravatar_enabled = '1'
614 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
617 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
615 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
618 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
616 assert_nil avatar('jsmith')
619 assert_nil avatar('jsmith')
617 assert_nil avatar(nil)
620 assert_nil avatar(nil)
618
621
619 # turn off avatars
622 # turn off avatars
620 Setting.gravatar_enabled = '0'
623 Setting.gravatar_enabled = '0'
621 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
624 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
622 end
625 end
623
626
624 def test_link_to_user
627 def test_link_to_user
625 user = User.find(2)
628 user = User.find(2)
626 t = link_to_user(user)
629 t = link_to_user(user)
627 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
630 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
628 end
631 end
629
632
630 def test_link_to_user_should_not_link_to_locked_user
633 def test_link_to_user_should_not_link_to_locked_user
631 user = User.find(5)
634 user = User.find(5)
632 assert user.locked?
635 assert user.locked?
633 t = link_to_user(user)
636 t = link_to_user(user)
634 assert_equal user.name, t
637 assert_equal user.name, t
635 end
638 end
636
639
637 def test_link_to_user_should_not_link_to_anonymous
640 def test_link_to_user_should_not_link_to_anonymous
638 user = User.anonymous
641 user = User.anonymous
639 assert user.anonymous?
642 assert user.anonymous?
640 t = link_to_user(user)
643 t = link_to_user(user)
641 assert_equal ::I18n.t(:label_user_anonymous), t
644 assert_equal ::I18n.t(:label_user_anonymous), t
642 end
645 end
643
646
644 def test_link_to_project
647 def test_link_to_project
645 project = Project.find(1)
648 project = Project.find(1)
646 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
649 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
647 link_to_project(project)
650 link_to_project(project)
648 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
651 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
649 link_to_project(project, :action => 'settings')
652 link_to_project(project, :action => 'settings')
650 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
653 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
651 link_to_project(project, {:only_path => false, :jump => 'blah'})
654 link_to_project(project, {:only_path => false, :jump => 'blah'})
652 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
655 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
653 link_to_project(project, {:action => 'settings'}, :class => "project")
656 link_to_project(project, {:action => 'settings'}, :class => "project")
654 end
657 end
655 end
658 end
General Comments 0
You need to be logged in to leave comments. Login now