##// END OF EJS Templates
scm: fix indents in "commit:xxx" unit test....
Toshi MARUYAMA -
r4572:fb51f27b8a15
parent child
Show More
@@ -1,710 +1,712
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_redmine_links_git_commit
228 def test_redmine_links_git_commit
229 changeset_link = link_to('abcd',
229 changeset_link = link_to('abcd',
230 {
230 {
231 :controller => 'repositories',
231 :controller => 'repositories',
232 :action => 'revision', :id => 'subproject1',
232 :action => 'revision',
233 :rev => 'abcd'
233 :id => 'subproject1',
234 },
234 :rev => 'abcd',
235 },
235 :class => 'changeset', :title => 'test commit')
236 :class => 'changeset', :title => 'test commit')
236 to_test = {
237 to_test = {
237 'commit:abcd' => changeset_link,
238 'commit:abcd' => changeset_link,
238 }
239 }
239 @project = Project.find(3)
240 @project = Project.find(3)
240 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
241 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
241 assert r
242 assert r
242 c = Changeset.new(:repository => r,
243 c = Changeset.new(:repository => r,
243 :committed_on => Time.now,
244 :committed_on => Time.now,
244 :revision => 'abcd',
245 :revision => 'abcd',
245 :scmid => 'abcd',
246 :scmid => 'abcd',
246 :comments => 'test commit')
247 :comments => 'test commit')
247 assert( c.save )
248 assert( c.save )
248 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
249 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
249 end
250 end
250
251
251 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
252 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
252 def test_redmine_links_darcs_commit
253 def test_redmine_links_darcs_commit
253 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
254 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
254 {
255 {
255 :controller => 'repositories',
256 :controller => 'repositories',
256 :action => 'revision', :id => 'subproject1',
257 :action => 'revision',
257 :rev => '123'
258 :id => 'subproject1',
258 },
259 :rev => '123',
260 },
259 :class => 'changeset', :title => 'test commit')
261 :class => 'changeset', :title => 'test commit')
260 to_test = {
262 to_test = {
261 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
263 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
262 }
264 }
263 @project = Project.find(3)
265 @project = Project.find(3)
264 r = Repository::Darcs.create!(:project => @project, :url => '/tmp/test/darcs')
266 r = Repository::Darcs.create!(:project => @project, :url => '/tmp/test/darcs')
265 assert r
267 assert r
266 c = Changeset.new(:repository => r,
268 c = Changeset.new(:repository => r,
267 :committed_on => Time.now,
269 :committed_on => Time.now,
268 :revision => '123',
270 :revision => '123',
269 :scmid => '20080308225258-98289-abcd456efg.gz',
271 :scmid => '20080308225258-98289-abcd456efg.gz',
270 :comments => 'test commit')
272 :comments => 'test commit')
271 assert( c.save )
273 assert( c.save )
272 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
274 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
273 end
275 end
274
276
275 def test_attachment_links
277 def test_attachment_links
276 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
278 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
277 to_test = {
279 to_test = {
278 'attachment:error281.txt' => attachment_link
280 'attachment:error281.txt' => attachment_link
279 }
281 }
280 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
282 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
281 end
283 end
282
284
283 def test_wiki_links
285 def test_wiki_links
284 to_test = {
286 to_test = {
285 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
287 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
286 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
288 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
287 # link with anchor
289 # link with anchor
288 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
290 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
289 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
291 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
290 # page that doesn't exist
292 # page that doesn't exist
291 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
293 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
292 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
294 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
293 # link to another project wiki
295 # link to another project wiki
294 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
296 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
295 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
297 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
296 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
298 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
297 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
299 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
298 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
300 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
299 # striked through link
301 # striked through link
300 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
302 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
301 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
303 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
302 # escaping
304 # escaping
303 '![[Another page|Page]]' => '[[Another page|Page]]',
305 '![[Another page|Page]]' => '[[Another page|Page]]',
304 # project does not exist
306 # project does not exist
305 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
307 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
306 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
308 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
307 }
309 }
308 @project = Project.find(1)
310 @project = Project.find(1)
309 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
311 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
310 end
312 end
311
313
312 def test_html_tags
314 def test_html_tags
313 to_test = {
315 to_test = {
314 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
316 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
315 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
317 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
316 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
318 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
317 # do not escape pre/code tags
319 # do not escape pre/code tags
318 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
320 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
319 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
321 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
320 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
322 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
321 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
323 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
322 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
324 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
323 # remove attributes except class
325 # remove attributes except class
324 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
326 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
325 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
327 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
326 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
328 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
327 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
329 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
328 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
330 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
329 # xss
331 # xss
330 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
332 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
331 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
333 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
332 }
334 }
333 to_test.each { |text, result| assert_equal result, textilizable(text) }
335 to_test.each { |text, result| assert_equal result, textilizable(text) }
334 end
336 end
335
337
336 def test_allowed_html_tags
338 def test_allowed_html_tags
337 to_test = {
339 to_test = {
338 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
340 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
339 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
341 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
340 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
342 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
341 }
343 }
342 to_test.each { |text, result| assert_equal result, textilizable(text) }
344 to_test.each { |text, result| assert_equal result, textilizable(text) }
343 end
345 end
344
346
345 def test_pre_tags
347 def test_pre_tags
346 raw = <<-RAW
348 raw = <<-RAW
347 Before
349 Before
348
350
349 <pre>
351 <pre>
350 <prepared-statement-cache-size>32</prepared-statement-cache-size>
352 <prepared-statement-cache-size>32</prepared-statement-cache-size>
351 </pre>
353 </pre>
352
354
353 After
355 After
354 RAW
356 RAW
355
357
356 expected = <<-EXPECTED
358 expected = <<-EXPECTED
357 <p>Before</p>
359 <p>Before</p>
358 <pre>
360 <pre>
359 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
361 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
360 </pre>
362 </pre>
361 <p>After</p>
363 <p>After</p>
362 EXPECTED
364 EXPECTED
363
365
364 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
366 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
365 end
367 end
366
368
367 def test_pre_content_should_not_parse_wiki_and_redmine_links
369 def test_pre_content_should_not_parse_wiki_and_redmine_links
368 raw = <<-RAW
370 raw = <<-RAW
369 [[CookBook documentation]]
371 [[CookBook documentation]]
370
372
371 #1
373 #1
372
374
373 <pre>
375 <pre>
374 [[CookBook documentation]]
376 [[CookBook documentation]]
375
377
376 #1
378 #1
377 </pre>
379 </pre>
378 RAW
380 RAW
379
381
380 expected = <<-EXPECTED
382 expected = <<-EXPECTED
381 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
383 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
382 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
384 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
383 <pre>
385 <pre>
384 [[CookBook documentation]]
386 [[CookBook documentation]]
385
387
386 #1
388 #1
387 </pre>
389 </pre>
388 EXPECTED
390 EXPECTED
389
391
390 @project = Project.find(1)
392 @project = Project.find(1)
391 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
393 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
392 end
394 end
393
395
394 def test_non_closing_pre_blocks_should_be_closed
396 def test_non_closing_pre_blocks_should_be_closed
395 raw = <<-RAW
397 raw = <<-RAW
396 <pre><code>
398 <pre><code>
397 RAW
399 RAW
398
400
399 expected = <<-EXPECTED
401 expected = <<-EXPECTED
400 <pre><code>
402 <pre><code>
401 </code></pre>
403 </code></pre>
402 EXPECTED
404 EXPECTED
403
405
404 @project = Project.find(1)
406 @project = Project.find(1)
405 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
407 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
406 end
408 end
407
409
408 def test_syntax_highlight
410 def test_syntax_highlight
409 raw = <<-RAW
411 raw = <<-RAW
410 <pre><code class="ruby">
412 <pre><code class="ruby">
411 # Some ruby code here
413 # Some ruby code here
412 </code></pre>
414 </code></pre>
413 RAW
415 RAW
414
416
415 expected = <<-EXPECTED
417 expected = <<-EXPECTED
416 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
418 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
417 </code></pre>
419 </code></pre>
418 EXPECTED
420 EXPECTED
419
421
420 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
422 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
421 end
423 end
422
424
423 def test_wiki_links_in_tables
425 def test_wiki_links_in_tables
424 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
426 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
425 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
427 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
426 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
428 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
427 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
429 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
428 }
430 }
429 @project = Project.find(1)
431 @project = Project.find(1)
430 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
432 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
431 end
433 end
432
434
433 def test_text_formatting
435 def test_text_formatting
434 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
436 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
435 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
437 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
436 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
438 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
437 '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>',
439 '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>',
438 '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',
440 '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',
439 }
441 }
440 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
442 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
441 end
443 end
442
444
443 def test_wiki_horizontal_rule
445 def test_wiki_horizontal_rule
444 assert_equal '<hr />', textilizable('---')
446 assert_equal '<hr />', textilizable('---')
445 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
447 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
446 end
448 end
447
449
448 def test_footnotes
450 def test_footnotes
449 raw = <<-RAW
451 raw = <<-RAW
450 This is some text[1].
452 This is some text[1].
451
453
452 fn1. This is the foot note
454 fn1. This is the foot note
453 RAW
455 RAW
454
456
455 expected = <<-EXPECTED
457 expected = <<-EXPECTED
456 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
458 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
457 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
459 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
458 EXPECTED
460 EXPECTED
459
461
460 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
462 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
461 end
463 end
462
464
463 def test_table_of_content
465 def test_table_of_content
464 raw = <<-RAW
466 raw = <<-RAW
465 {{toc}}
467 {{toc}}
466
468
467 h1. Title
469 h1. Title
468
470
469 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
471 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
470
472
471 h2. Subtitle with a [[Wiki]] link
473 h2. Subtitle with a [[Wiki]] link
472
474
473 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
475 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
474
476
475 h2. Subtitle with [[Wiki|another Wiki]] link
477 h2. Subtitle with [[Wiki|another Wiki]] link
476
478
477 h2. Subtitle with %{color:red}red text%
479 h2. Subtitle with %{color:red}red text%
478
480
479 <pre>
481 <pre>
480 some code
482 some code
481 </pre>
483 </pre>
482
484
483 h3. Subtitle with *some* _modifiers_
485 h3. Subtitle with *some* _modifiers_
484
486
485 h1. Another title
487 h1. Another title
486
488
487 h3. An "Internet link":http://www.redmine.org/ inside subtitle
489 h3. An "Internet link":http://www.redmine.org/ inside subtitle
488
490
489 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
491 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
490
492
491 RAW
493 RAW
492
494
493 expected = '<ul class="toc">' +
495 expected = '<ul class="toc">' +
494 '<li><a href="#Title">Title</a>' +
496 '<li><a href="#Title">Title</a>' +
495 '<ul>' +
497 '<ul>' +
496 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
498 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
497 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
499 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
498 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
500 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
499 '<ul>' +
501 '<ul>' +
500 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
502 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
501 '</ul>' +
503 '</ul>' +
502 '</li>' +
504 '</li>' +
503 '</ul>' +
505 '</ul>' +
504 '</li>' +
506 '</li>' +
505 '<li><a href="#Another-title">Another title</a>' +
507 '<li><a href="#Another-title">Another title</a>' +
506 '<ul>' +
508 '<ul>' +
507 '<li>' +
509 '<li>' +
508 '<ul>' +
510 '<ul>' +
509 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
511 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
510 '</ul>' +
512 '</ul>' +
511 '</li>' +
513 '</li>' +
512 '<li><a href="#Project-Name">Project Name</a></li>' +
514 '<li><a href="#Project-Name">Project Name</a></li>' +
513 '</ul>' +
515 '</ul>' +
514 '</li>' +
516 '</li>' +
515 '</ul>'
517 '</ul>'
516
518
517 @project = Project.find(1)
519 @project = Project.find(1)
518 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
520 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
519 end
521 end
520
522
521 def test_table_of_content_should_contain_included_page_headings
523 def test_table_of_content_should_contain_included_page_headings
522 raw = <<-RAW
524 raw = <<-RAW
523 {{toc}}
525 {{toc}}
524
526
525 h1. Included
527 h1. Included
526
528
527 {{include(Child_1)}}
529 {{include(Child_1)}}
528 RAW
530 RAW
529
531
530 expected = '<ul class="toc">' +
532 expected = '<ul class="toc">' +
531 '<li><a href="#Included">Included</a></li>' +
533 '<li><a href="#Included">Included</a></li>' +
532 '<li><a href="#Child-page-1">Child page 1</a></li>' +
534 '<li><a href="#Child-page-1">Child page 1</a></li>' +
533 '</ul>'
535 '</ul>'
534
536
535 @project = Project.find(1)
537 @project = Project.find(1)
536 assert textilizable(raw).gsub("\n", "").include?(expected)
538 assert textilizable(raw).gsub("\n", "").include?(expected)
537 end
539 end
538
540
539 def test_blockquote
541 def test_blockquote
540 # orig raw text
542 # orig raw text
541 raw = <<-RAW
543 raw = <<-RAW
542 John said:
544 John said:
543 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
545 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
544 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
546 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
545 > * Donec odio lorem,
547 > * Donec odio lorem,
546 > * sagittis ac,
548 > * sagittis ac,
547 > * malesuada in,
549 > * malesuada in,
548 > * adipiscing eu, dolor.
550 > * adipiscing eu, dolor.
549 >
551 >
550 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
552 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
551 > Proin a tellus. Nam vel neque.
553 > Proin a tellus. Nam vel neque.
552
554
553 He's right.
555 He's right.
554 RAW
556 RAW
555
557
556 # expected html
558 # expected html
557 expected = <<-EXPECTED
559 expected = <<-EXPECTED
558 <p>John said:</p>
560 <p>John said:</p>
559 <blockquote>
561 <blockquote>
560 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
562 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
561 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
563 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
562 <ul>
564 <ul>
563 <li>Donec odio lorem,</li>
565 <li>Donec odio lorem,</li>
564 <li>sagittis ac,</li>
566 <li>sagittis ac,</li>
565 <li>malesuada in,</li>
567 <li>malesuada in,</li>
566 <li>adipiscing eu, dolor.</li>
568 <li>adipiscing eu, dolor.</li>
567 </ul>
569 </ul>
568 <blockquote>
570 <blockquote>
569 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
571 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
570 </blockquote>
572 </blockquote>
571 <p>Proin a tellus. Nam vel neque.</p>
573 <p>Proin a tellus. Nam vel neque.</p>
572 </blockquote>
574 </blockquote>
573 <p>He's right.</p>
575 <p>He's right.</p>
574 EXPECTED
576 EXPECTED
575
577
576 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
578 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
577 end
579 end
578
580
579 def test_table
581 def test_table
580 raw = <<-RAW
582 raw = <<-RAW
581 This is a table with empty cells:
583 This is a table with empty cells:
582
584
583 |cell11|cell12||
585 |cell11|cell12||
584 |cell21||cell23|
586 |cell21||cell23|
585 |cell31|cell32|cell33|
587 |cell31|cell32|cell33|
586 RAW
588 RAW
587
589
588 expected = <<-EXPECTED
590 expected = <<-EXPECTED
589 <p>This is a table with empty cells:</p>
591 <p>This is a table with empty cells:</p>
590
592
591 <table>
593 <table>
592 <tr><td>cell11</td><td>cell12</td><td></td></tr>
594 <tr><td>cell11</td><td>cell12</td><td></td></tr>
593 <tr><td>cell21</td><td></td><td>cell23</td></tr>
595 <tr><td>cell21</td><td></td><td>cell23</td></tr>
594 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
596 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
595 </table>
597 </table>
596 EXPECTED
598 EXPECTED
597
599
598 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
600 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
599 end
601 end
600
602
601 def test_table_with_line_breaks
603 def test_table_with_line_breaks
602 raw = <<-RAW
604 raw = <<-RAW
603 This is a table with line breaks:
605 This is a table with line breaks:
604
606
605 |cell11
607 |cell11
606 continued|cell12||
608 continued|cell12||
607 |-cell21-||cell23
609 |-cell21-||cell23
608 cell23 line2
610 cell23 line2
609 cell23 *line3*|
611 cell23 *line3*|
610 |cell31|cell32
612 |cell31|cell32
611 cell32 line2|cell33|
613 cell32 line2|cell33|
612
614
613 RAW
615 RAW
614
616
615 expected = <<-EXPECTED
617 expected = <<-EXPECTED
616 <p>This is a table with line breaks:</p>
618 <p>This is a table with line breaks:</p>
617
619
618 <table>
620 <table>
619 <tr>
621 <tr>
620 <td>cell11<br />continued</td>
622 <td>cell11<br />continued</td>
621 <td>cell12</td>
623 <td>cell12</td>
622 <td></td>
624 <td></td>
623 </tr>
625 </tr>
624 <tr>
626 <tr>
625 <td><del>cell21</del></td>
627 <td><del>cell21</del></td>
626 <td></td>
628 <td></td>
627 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
629 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
628 </tr>
630 </tr>
629 <tr>
631 <tr>
630 <td>cell31</td>
632 <td>cell31</td>
631 <td>cell32<br/>cell32 line2</td>
633 <td>cell32<br/>cell32 line2</td>
632 <td>cell33</td>
634 <td>cell33</td>
633 </tr>
635 </tr>
634 </table>
636 </table>
635 EXPECTED
637 EXPECTED
636
638
637 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
639 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
638 end
640 end
639
641
640 def test_textile_should_not_mangle_brackets
642 def test_textile_should_not_mangle_brackets
641 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
643 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
642 end
644 end
643
645
644 def test_default_formatter
646 def test_default_formatter
645 Setting.text_formatting = 'unknown'
647 Setting.text_formatting = 'unknown'
646 text = 'a *link*: http://www.example.net/'
648 text = 'a *link*: http://www.example.net/'
647 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
649 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
648 Setting.text_formatting = 'textile'
650 Setting.text_formatting = 'textile'
649 end
651 end
650
652
651 def test_due_date_distance_in_words
653 def test_due_date_distance_in_words
652 to_test = { Date.today => 'Due in 0 days',
654 to_test = { Date.today => 'Due in 0 days',
653 Date.today + 1 => 'Due in 1 day',
655 Date.today + 1 => 'Due in 1 day',
654 Date.today + 100 => 'Due in about 3 months',
656 Date.today + 100 => 'Due in about 3 months',
655 Date.today + 20000 => 'Due in over 54 years',
657 Date.today + 20000 => 'Due in over 54 years',
656 Date.today - 1 => '1 day late',
658 Date.today - 1 => '1 day late',
657 Date.today - 100 => 'about 3 months late',
659 Date.today - 100 => 'about 3 months late',
658 Date.today - 20000 => 'over 54 years late',
660 Date.today - 20000 => 'over 54 years late',
659 }
661 }
660 ::I18n.locale = :en
662 ::I18n.locale = :en
661 to_test.each do |date, expected|
663 to_test.each do |date, expected|
662 assert_equal expected, due_date_distance_in_words(date)
664 assert_equal expected, due_date_distance_in_words(date)
663 end
665 end
664 end
666 end
665
667
666 def test_avatar
668 def test_avatar
667 # turn on avatars
669 # turn on avatars
668 Setting.gravatar_enabled = '1'
670 Setting.gravatar_enabled = '1'
669 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
671 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
670 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
672 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
671 assert_nil avatar('jsmith')
673 assert_nil avatar('jsmith')
672 assert_nil avatar(nil)
674 assert_nil avatar(nil)
673
675
674 # turn off avatars
676 # turn off avatars
675 Setting.gravatar_enabled = '0'
677 Setting.gravatar_enabled = '0'
676 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
678 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
677 end
679 end
678
680
679 def test_link_to_user
681 def test_link_to_user
680 user = User.find(2)
682 user = User.find(2)
681 t = link_to_user(user)
683 t = link_to_user(user)
682 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
684 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
683 end
685 end
684
686
685 def test_link_to_user_should_not_link_to_locked_user
687 def test_link_to_user_should_not_link_to_locked_user
686 user = User.find(5)
688 user = User.find(5)
687 assert user.locked?
689 assert user.locked?
688 t = link_to_user(user)
690 t = link_to_user(user)
689 assert_equal user.name, t
691 assert_equal user.name, t
690 end
692 end
691
693
692 def test_link_to_user_should_not_link_to_anonymous
694 def test_link_to_user_should_not_link_to_anonymous
693 user = User.anonymous
695 user = User.anonymous
694 assert user.anonymous?
696 assert user.anonymous?
695 t = link_to_user(user)
697 t = link_to_user(user)
696 assert_equal ::I18n.t(:label_user_anonymous), t
698 assert_equal ::I18n.t(:label_user_anonymous), t
697 end
699 end
698
700
699 def test_link_to_project
701 def test_link_to_project
700 project = Project.find(1)
702 project = Project.find(1)
701 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
703 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
702 link_to_project(project)
704 link_to_project(project)
703 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
705 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
704 link_to_project(project, :action => 'settings')
706 link_to_project(project, :action => 'settings')
705 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
707 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
706 link_to_project(project, {:only_path => false, :jump => 'blah'})
708 link_to_project(project, {:only_path => false, :jump => 'blah'})
707 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
709 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
708 link_to_project(project, {:action => 'settings'}, :class => "project")
710 link_to_project(project, {:action => 'settings'}, :class => "project")
709 end
711 end
710 end
712 end
General Comments 0
You need to be logged in to leave comments. Login now