##// END OF EJS Templates
add unit application helper test to use latest image file (#3261)...
Toshi MARUYAMA -
r7787:627dfd80b637
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -1,184 +1,210
1 ---
1 ---
2 attachments_001:
2 attachments_001:
3 created_on: 2006-07-19 21:07:27 +02:00
3 created_on: 2006-07-19 21:07:27 +02:00
4 downloads: 0
4 downloads: 0
5 content_type: text/plain
5 content_type: text/plain
6 disk_filename: 060719210727_error281.txt
6 disk_filename: 060719210727_error281.txt
7 container_id: 3
7 container_id: 3
8 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
8 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
9 id: 1
9 id: 1
10 container_type: Issue
10 container_type: Issue
11 filesize: 28
11 filesize: 28
12 filename: error281.txt
12 filename: error281.txt
13 author_id: 2
13 author_id: 2
14 attachments_002:
14 attachments_002:
15 created_on: 2007-01-27 15:08:27 +01:00
15 created_on: 2007-01-27 15:08:27 +01:00
16 downloads: 0
16 downloads: 0
17 content_type: text/plain
17 content_type: text/plain
18 disk_filename: 060719210727_document.txt
18 disk_filename: 060719210727_document.txt
19 container_id: 1
19 container_id: 1
20 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
20 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
21 id: 2
21 id: 2
22 container_type: Document
22 container_type: Document
23 filesize: 28
23 filesize: 28
24 filename: document.txt
24 filename: document.txt
25 author_id: 2
25 author_id: 2
26 attachments_003:
26 attachments_003:
27 created_on: 2006-07-19 21:07:27 +02:00
27 created_on: 2006-07-19 21:07:27 +02:00
28 downloads: 0
28 downloads: 0
29 content_type: image/gif
29 content_type: image/gif
30 disk_filename: 060719210727_logo.gif
30 disk_filename: 060719210727_logo.gif
31 container_id: 4
31 container_id: 4
32 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
32 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
33 id: 3
33 id: 3
34 container_type: WikiPage
34 container_type: WikiPage
35 filesize: 280
35 filesize: 280
36 filename: logo.gif
36 filename: logo.gif
37 description: This is a logo
37 description: This is a logo
38 author_id: 2
38 author_id: 2
39 attachments_004:
39 attachments_004:
40 created_on: 2006-07-19 21:07:27 +02:00
40 created_on: 2006-07-19 21:07:27 +02:00
41 container_type: Issue
41 container_type: Issue
42 container_id: 3
42 container_id: 3
43 downloads: 0
43 downloads: 0
44 disk_filename: 060719210727_source.rb
44 disk_filename: 060719210727_source.rb
45 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
45 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
46 id: 4
46 id: 4
47 filesize: 153
47 filesize: 153
48 filename: source.rb
48 filename: source.rb
49 author_id: 2
49 author_id: 2
50 description: This is a Ruby source file
50 description: This is a Ruby source file
51 content_type: application/x-ruby
51 content_type: application/x-ruby
52 attachments_005:
52 attachments_005:
53 created_on: 2006-07-19 21:07:27 +02:00
53 created_on: 2006-07-19 21:07:27 +02:00
54 container_type: Issue
54 container_type: Issue
55 container_id: 3
55 container_id: 3
56 downloads: 0
56 downloads: 0
57 disk_filename: 060719210727_changeset_iso8859-1.diff
57 disk_filename: 060719210727_changeset_iso8859-1.diff
58 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
58 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
59 id: 5
59 id: 5
60 filesize: 687
60 filesize: 687
61 filename: changeset_iso8859-1.diff
61 filename: changeset_iso8859-1.diff
62 author_id: 2
62 author_id: 2
63 content_type: text/x-diff
63 content_type: text/x-diff
64 attachments_006:
64 attachments_006:
65 created_on: 2006-07-19 21:07:27 +02:00
65 created_on: 2006-07-19 21:07:27 +02:00
66 container_type: Issue
66 container_type: Issue
67 container_id: 3
67 container_id: 3
68 downloads: 0
68 downloads: 0
69 disk_filename: 060719210727_archive.zip
69 disk_filename: 060719210727_archive.zip
70 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
70 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
71 id: 6
71 id: 6
72 filesize: 157
72 filesize: 157
73 filename: archive.zip
73 filename: archive.zip
74 author_id: 2
74 author_id: 2
75 content_type: application/octet-stream
75 content_type: application/octet-stream
76 attachments_007:
76 attachments_007:
77 created_on: 2006-07-19 21:07:27 +02:00
77 created_on: 2006-07-19 21:07:27 +02:00
78 container_type: Issue
78 container_type: Issue
79 container_id: 4
79 container_id: 4
80 downloads: 0
80 downloads: 0
81 disk_filename: 060719210727_archive.zip
81 disk_filename: 060719210727_archive.zip
82 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
82 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
83 id: 7
83 id: 7
84 filesize: 157
84 filesize: 157
85 filename: archive.zip
85 filename: archive.zip
86 author_id: 1
86 author_id: 1
87 content_type: application/octet-stream
87 content_type: application/octet-stream
88 attachments_008:
88 attachments_008:
89 created_on: 2006-07-19 21:07:27 +02:00
89 created_on: 2006-07-19 21:07:27 +02:00
90 container_type: Project
90 container_type: Project
91 container_id: 1
91 container_id: 1
92 downloads: 0
92 downloads: 0
93 disk_filename: 060719210727_project_file.zip
93 disk_filename: 060719210727_project_file.zip
94 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
94 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
95 id: 8
95 id: 8
96 filesize: 320
96 filesize: 320
97 filename: project_file.zip
97 filename: project_file.zip
98 author_id: 2
98 author_id: 2
99 content_type: application/octet-stream
99 content_type: application/octet-stream
100 attachments_009:
100 attachments_009:
101 created_on: 2006-07-19 21:07:27 +02:00
101 created_on: 2006-07-19 21:07:27 +02:00
102 container_type: Version
102 container_type: Version
103 container_id: 1
103 container_id: 1
104 downloads: 0
104 downloads: 0
105 disk_filename: 060719210727_version_file.zip
105 disk_filename: 060719210727_version_file.zip
106 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
106 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
107 id: 9
107 id: 9
108 filesize: 452
108 filesize: 452
109 filename: version_file.zip
109 filename: version_file.zip
110 author_id: 2
110 author_id: 2
111 content_type: application/octet-stream
111 content_type: application/octet-stream
112 attachments_010:
112 attachments_010:
113 created_on: 2006-07-19 21:07:27 +02:00
113 created_on: 2006-07-19 21:07:27 +02:00
114 container_type: Issue
114 container_type: Issue
115 container_id: 2
115 container_id: 2
116 downloads: 0
116 downloads: 0
117 disk_filename: 060719210727_picture.jpg
117 disk_filename: 060719210727_picture.jpg
118 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
118 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
119 id: 10
119 id: 10
120 filesize: 452
120 filesize: 452
121 filename: picture.jpg
121 filename: picture.jpg
122 author_id: 2
122 author_id: 2
123 content_type: image/jpeg
123 content_type: image/jpeg
124 attachments_011:
124 attachments_011:
125 created_on: 2007-02-12 15:08:27 +01:00
125 created_on: 2007-02-12 15:08:27 +01:00
126 container_type: Document
126 container_type: Document
127 container_id: 1
127 container_id: 1
128 downloads: 0
128 downloads: 0
129 disk_filename: 060719210727_picture.jpg
129 disk_filename: 060719210727_picture.jpg
130 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
130 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
131 id: 11
131 id: 11
132 filesize: 452
132 filesize: 452
133 filename: picture.jpg
133 filename: picture.jpg
134 author_id: 2
134 author_id: 2
135 content_type: image/jpeg
135 content_type: image/jpeg
136 attachments_012:
136 attachments_012:
137 created_on: 2006-07-19 21:07:27 +02:00
137 created_on: 2006-07-19 21:07:27 +02:00
138 container_type: Version
138 container_type: Version
139 container_id: 1
139 container_id: 1
140 downloads: 0
140 downloads: 0
141 disk_filename: 060719210727_version_file.zip
141 disk_filename: 060719210727_version_file.zip
142 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
142 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
143 id: 12
143 id: 12
144 filesize: 452
144 filesize: 452
145 filename: version_file.zip
145 filename: version_file.zip
146 author_id: 2
146 author_id: 2
147 content_type: application/octet-stream
147 content_type: application/octet-stream
148 attachments_013:
148 attachments_013:
149 created_on: 2006-07-19 21:07:27 +02:00
149 created_on: 2006-07-19 21:07:27 +02:00
150 container_type: Message
150 container_type: Message
151 container_id: 1
151 container_id: 1
152 downloads: 0
152 downloads: 0
153 disk_filename: 060719210727_foo.zip
153 disk_filename: 060719210727_foo.zip
154 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
154 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
155 id: 13
155 id: 13
156 filesize: 452
156 filesize: 452
157 filename: foo.zip
157 filename: foo.zip
158 author_id: 2
158 author_id: 2
159 content_type: application/octet-stream
159 content_type: application/octet-stream
160 attachments_014:
160 attachments_014:
161 created_on: 2006-07-19 21:07:27 +02:00
161 created_on: 2006-07-19 21:07:27 +02:00
162 container_type: Issue
162 container_type: Issue
163 container_id: 3
163 container_id: 3
164 downloads: 0
164 downloads: 0
165 disk_filename: 060719210727_changeset_utf8.diff
165 disk_filename: 060719210727_changeset_utf8.diff
166 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
166 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
167 id: 14
167 id: 14
168 filesize: 687
168 filesize: 687
169 filename: changeset_utf8.diff
169 filename: changeset_utf8.diff
170 author_id: 2
170 author_id: 2
171 content_type: text/x-diff
171 content_type: text/x-diff
172 attachments_015:
172 attachments_015:
173 id: 15
173 id: 15
174 created_on: 2010-07-19 21:07:27 +02:00
174 created_on: 2010-07-19 21:07:27 +02:00
175 container_type: Issue
175 container_type: Issue
176 container_id: 14
176 container_id: 14
177 downloads: 0
177 downloads: 0
178 disk_filename: 060719210727_changeset_utf8.diff
178 disk_filename: 060719210727_changeset_utf8.diff
179 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
179 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
180 filesize: 687
180 filesize: 687
181 filename: private.diff
181 filename: private.diff
182 author_id: 2
182 author_id: 2
183 content_type: text/x-diff
183 content_type: text/x-diff
184 description: attachement of a private issue
184 description: attachement of a private issue
185 attachments_016:
186 content_type: image/png
187 downloads: 0
188 created_on: 2010-11-23 16:14:50 +09:00
189 disk_filename: 101123161450_testfile_1.png
190 container_id: 14
191 digest: 8e0294de2441577c529f170b6fb8f638
192 id: 16
193 container_type: Issue
194 description: ""
195 filename: testfile.png
196 filesize: 2654
197 author_id: 2
198 attachments_017:
199 content_type: image/png
200 downloads: 0
201 created_on: 2010-12-23 16:14:50 +09:00
202 disk_filename: 101223161450_testfile_2.png
203 container_id: 14
204 digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
205 id: 17
206 container_type: Issue
207 description: ""
208 filename: testfile.PNG
209 filesize: 3582
210 author_id: 2
@@ -1,854 +1,879
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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, :news,
26 :boards, :messages, :news,
27 :attachments,
27 :attachments,
28 :enumerations
28 :enumerations
29
29
30 def setup
30 def setup
31 super
31 super
32 set_tmp_attachments_directory
32 end
33 end
33
34
34 context "#link_to_if_authorized" do
35 context "#link_to_if_authorized" do
35 context "authorized user" do
36 context "authorized user" do
36 should "be tested"
37 should "be tested"
37 end
38 end
38
39
39 context "unauthorized user" do
40 context "unauthorized user" do
40 should "be tested"
41 should "be tested"
41 end
42 end
42
43
43 should "allow using the :controller and :action for the target link" do
44 should "allow using the :controller and :action for the target link" do
44 User.current = User.find_by_login('admin')
45 User.current = User.find_by_login('admin')
45
46
46 @project = Issue.first.project # Used by helper
47 @project = Issue.first.project # Used by helper
47 response = link_to_if_authorized("By controller/action",
48 response = link_to_if_authorized("By controller/action",
48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
49 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
49 assert_match /href/, response
50 assert_match /href/, response
50 end
51 end
51
52
52 end
53 end
53
54
54 def test_auto_links
55 def test_auto_links
55 to_test = {
56 to_test = {
56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
57 '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>',
58 '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>.',
59 '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>.',
60 '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>.',
61 '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>).',
62 '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>.',
63 '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>',
64 '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>)',
65 '(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>)',
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).' => '(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>)',
68 '(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>)',
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 '(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>',
71 '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>',
72 '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>',
73 '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>',
74 '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>',
75 '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>',
76 '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>',
77 '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>',
78 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
78 # two exclamation marks
79 # 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>',
80 '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
81 # escaping
81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
82 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
82 # wrap in angle brackets
83 # wrap in angle brackets
83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
84 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
84 }
85 }
85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
86 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
86 end
87 end
87
88
88 def test_auto_mailto
89 def test_auto_mailto
89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
90 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
90 textilizable('test@foo.bar')
91 textilizable('test@foo.bar')
91 end
92 end
92
93
93 def test_inline_images
94 def test_inline_images
94 to_test = {
95 to_test = {
95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
96 '!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>',
97 '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="" />',
98 '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
99 # 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="" />',
100 '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" />',
101 '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;" />',
102 '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 }
103 }
103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
104 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
104 end
105 end
105
106
106 def test_inline_images_inside_tags
107 def test_inline_images_inside_tags
107 raw = <<-RAW
108 raw = <<-RAW
108 h1. !foo.png! Heading
109 h1. !foo.png! Heading
109
110
110 Centered image:
111 Centered image:
111
112
112 p=. !bar.gif!
113 p=. !bar.gif!
113 RAW
114 RAW
114
115
115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
116 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
117 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
117 end
118 end
118
119
119 def test_attached_images
120 def test_attached_images
120 to_test = {
121 to_test = {
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 '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="" />',
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 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
125 # link image
126 # 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>',
127 '!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 }
128 }
128 attachments = Attachment.find(:all)
129 attachments = Attachment.find(:all)
129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
130 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
130 end
131 end
131
132
132 def test_attached_images_filename_extension
133 def test_attached_images_filename_extension
133 set_tmp_attachments_directory
134 set_tmp_attachments_directory
134 a1 = Attachment.new(
135 a1 = Attachment.new(
135 :container => Issue.find(1),
136 :container => Issue.find(1),
136 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
137 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
137 :author => User.find(1))
138 :author => User.find(1))
138 assert a1.save
139 assert a1.save
139 assert_equal "testtest.JPG", a1.filename
140 assert_equal "testtest.JPG", a1.filename
140 assert_equal "image/jpeg", a1.content_type
141 assert_equal "image/jpeg", a1.content_type
141 assert a1.image?
142 assert a1.image?
142
143
143 a2 = Attachment.new(
144 a2 = Attachment.new(
144 :container => Issue.find(1),
145 :container => Issue.find(1),
145 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
146 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
146 :author => User.find(1))
147 :author => User.find(1))
147 assert a2.save
148 assert a2.save
148 assert_equal "testtest.jpeg", a2.filename
149 assert_equal "testtest.jpeg", a2.filename
149 assert_equal "image/jpeg", a2.content_type
150 assert_equal "image/jpeg", a2.content_type
150 assert a2.image?
151 assert a2.image?
151
152
152 a3 = Attachment.new(
153 a3 = Attachment.new(
153 :container => Issue.find(1),
154 :container => Issue.find(1),
154 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
155 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
155 :author => User.find(1))
156 :author => User.find(1))
156 assert a3.save
157 assert a3.save
157 assert_equal "testtest.JPE", a3.filename
158 assert_equal "testtest.JPE", a3.filename
158 assert_equal "image/jpeg", a3.content_type
159 assert_equal "image/jpeg", a3.content_type
159 assert a3.image?
160 assert a3.image?
160
161
161 a4 = Attachment.new(
162 a4 = Attachment.new(
162 :container => Issue.find(1),
163 :container => Issue.find(1),
163 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
164 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
164 :author => User.find(1))
165 :author => User.find(1))
165 assert a4.save
166 assert a4.save
166 assert_equal "Testtest.BMP", a4.filename
167 assert_equal "Testtest.BMP", a4.filename
167 assert_equal "image/x-ms-bmp", a4.content_type
168 assert_equal "image/x-ms-bmp", a4.content_type
168 assert a4.image?
169 assert a4.image?
169
170
170 to_test = {
171 to_test = {
171 'Inline image: !testtest.jpg!' =>
172 'Inline image: !testtest.jpg!' =>
172 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '" alt="" />',
173 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '" alt="" />',
173 'Inline image: !testtest.jpeg!' =>
174 'Inline image: !testtest.jpeg!' =>
174 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
175 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
175 'Inline image: !testtest.jpe!' =>
176 'Inline image: !testtest.jpe!' =>
176 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '" alt="" />',
177 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '" alt="" />',
177 'Inline image: !testtest.bmp!' =>
178 'Inline image: !testtest.bmp!' =>
178 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '" alt="" />',
179 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '" alt="" />',
179 }
180 }
180
181
181 attachments = [a1, a2, a3, a4]
182 attachments = [a1, a2, a3, a4]
182 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
183 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
183 end
184 end
184
185
186 def test_attached_images_should_read_later
187 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
188 a1 = Attachment.find(16)
189 assert_equal "testfile.png", a1.filename
190 assert a1.readable?
191 assert (! a1.visible?(User.anonymous))
192 assert a1.visible?(User.find(2))
193 a2 = Attachment.find(17)
194 assert_equal "testfile.PNG", a2.filename
195 assert a2.readable?
196 assert (! a2.visible?(User.anonymous))
197 assert a2.visible?(User.find(2))
198 assert a1.created_on < a2.created_on
199
200 to_test = {
201 'Inline image: !testfile.png!' =>
202 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
203 'Inline image: !Testfile.PNG!' =>
204 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
205 }
206 attachments = [a1, a2]
207 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
208 end
209
185 def test_textile_external_links
210 def test_textile_external_links
186 to_test = {
211 to_test = {
187 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
212 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
188 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
213 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
189 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
214 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
190 '"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>',
215 '"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>',
191 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
216 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
192 # no multiline link text
217 # no multiline link text
193 "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",
218 "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",
194 # mailto link
219 # mailto link
195 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
220 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
196 # two exclamation marks
221 # two exclamation marks
197 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
222 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
198 # escaping
223 # escaping
199 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
224 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
200 }
225 }
201 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
226 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
202 end
227 end
203
228
204 def test_redmine_links
229 def test_redmine_links
205 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
230 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
206 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
231 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
207
232
208 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
233 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
209 :class => 'changeset', :title => 'My very first commit')
234 :class => 'changeset', :title => 'My very first commit')
210 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
235 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
211 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
236 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
212
237
213 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
238 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
214 :class => 'document')
239 :class => 'document')
215
240
216 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
241 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
217 :class => 'version')
242 :class => 'version')
218
243
219 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
244 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
220
245
221 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
246 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
222
247
223 news_url = {:controller => 'news', :action => 'show', :id => 1}
248 news_url = {:controller => 'news', :action => 'show', :id => 1}
224
249
225 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
250 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
226
251
227 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
252 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
228 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
253 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
229
254
230 to_test = {
255 to_test = {
231 # tickets
256 # tickets
232 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
257 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
233 # changesets
258 # changesets
234 'r1' => changeset_link,
259 'r1' => changeset_link,
235 'r1.' => "#{changeset_link}.",
260 'r1.' => "#{changeset_link}.",
236 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
261 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
237 'r1,r2' => "#{changeset_link},#{changeset_link2}",
262 'r1,r2' => "#{changeset_link},#{changeset_link2}",
238 # documents
263 # documents
239 'document#1' => document_link,
264 'document#1' => document_link,
240 'document:"Test document"' => document_link,
265 'document:"Test document"' => document_link,
241 # versions
266 # versions
242 'version#2' => version_link,
267 'version#2' => version_link,
243 'version:1.0' => version_link,
268 'version:1.0' => version_link,
244 'version:"1.0"' => version_link,
269 'version:"1.0"' => version_link,
245 # source
270 # source
246 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
271 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
247 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
272 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
248 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
273 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
249 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
274 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
250 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
275 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
251 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
276 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
252 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
277 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
253 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
278 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
254 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
279 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
255 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
280 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
256 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
281 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
257 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
282 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
258 # forum
283 # forum
259 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
284 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
260 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
285 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
261 # message
286 # message
262 'message#4' => link_to('Post 2', message_url, :class => 'message'),
287 'message#4' => link_to('Post 2', message_url, :class => 'message'),
263 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
288 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
264 # news
289 # news
265 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
290 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
266 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
291 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
267 # project
292 # project
268 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
293 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
269 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
294 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
270 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
295 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
271 # escaping
296 # escaping
272 '!#3.' => '#3.',
297 '!#3.' => '#3.',
273 '!r1' => 'r1',
298 '!r1' => 'r1',
274 '!document#1' => 'document#1',
299 '!document#1' => 'document#1',
275 '!document:"Test document"' => 'document:"Test document"',
300 '!document:"Test document"' => 'document:"Test document"',
276 '!version#2' => 'version#2',
301 '!version#2' => 'version#2',
277 '!version:1.0' => 'version:1.0',
302 '!version:1.0' => 'version:1.0',
278 '!version:"1.0"' => 'version:"1.0"',
303 '!version:"1.0"' => 'version:"1.0"',
279 '!source:/some/file' => 'source:/some/file',
304 '!source:/some/file' => 'source:/some/file',
280 # not found
305 # not found
281 '#0123456789' => '#0123456789',
306 '#0123456789' => '#0123456789',
282 # invalid expressions
307 # invalid expressions
283 'source:' => 'source:',
308 'source:' => 'source:',
284 # url hash
309 # url hash
285 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
310 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
286 }
311 }
287 @project = Project.find(1)
312 @project = Project.find(1)
288 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
313 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
289 end
314 end
290
315
291 def test_cross_project_redmine_links
316 def test_cross_project_redmine_links
292 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
317 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
293 :class => 'source')
318 :class => 'source')
294
319
295 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
320 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
296 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
321 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
297
322
298 to_test = {
323 to_test = {
299 # documents
324 # documents
300 'document:"Test document"' => 'document:"Test document"',
325 'document:"Test document"' => 'document:"Test document"',
301 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
326 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
302 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
327 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
303 # versions
328 # versions
304 'version:"1.0"' => 'version:"1.0"',
329 'version:"1.0"' => 'version:"1.0"',
305 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
330 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
306 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
331 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
307 # changeset
332 # changeset
308 'r2' => 'r2',
333 'r2' => 'r2',
309 'ecookbook:r2' => changeset_link,
334 'ecookbook:r2' => changeset_link,
310 'invalid:r2' => 'invalid:r2',
335 'invalid:r2' => 'invalid:r2',
311 # source
336 # source
312 'source:/some/file' => 'source:/some/file',
337 'source:/some/file' => 'source:/some/file',
313 'ecookbook:source:/some/file' => source_link,
338 'ecookbook:source:/some/file' => source_link,
314 'invalid:source:/some/file' => 'invalid:source:/some/file',
339 'invalid:source:/some/file' => 'invalid:source:/some/file',
315 }
340 }
316 @project = Project.find(3)
341 @project = Project.find(3)
317 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
342 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
318 end
343 end
319
344
320 def test_redmine_links_git_commit
345 def test_redmine_links_git_commit
321 changeset_link = link_to('abcd',
346 changeset_link = link_to('abcd',
322 {
347 {
323 :controller => 'repositories',
348 :controller => 'repositories',
324 :action => 'revision',
349 :action => 'revision',
325 :id => 'subproject1',
350 :id => 'subproject1',
326 :rev => 'abcd',
351 :rev => 'abcd',
327 },
352 },
328 :class => 'changeset', :title => 'test commit')
353 :class => 'changeset', :title => 'test commit')
329 to_test = {
354 to_test = {
330 'commit:abcd' => changeset_link,
355 'commit:abcd' => changeset_link,
331 }
356 }
332 @project = Project.find(3)
357 @project = Project.find(3)
333 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
358 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
334 assert r
359 assert r
335 c = Changeset.new(:repository => r,
360 c = Changeset.new(:repository => r,
336 :committed_on => Time.now,
361 :committed_on => Time.now,
337 :revision => 'abcd',
362 :revision => 'abcd',
338 :scmid => 'abcd',
363 :scmid => 'abcd',
339 :comments => 'test commit')
364 :comments => 'test commit')
340 assert( c.save )
365 assert( c.save )
341 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
366 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
342 end
367 end
343
368
344 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
369 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
345 def test_redmine_links_darcs_commit
370 def test_redmine_links_darcs_commit
346 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
371 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
347 {
372 {
348 :controller => 'repositories',
373 :controller => 'repositories',
349 :action => 'revision',
374 :action => 'revision',
350 :id => 'subproject1',
375 :id => 'subproject1',
351 :rev => '123',
376 :rev => '123',
352 },
377 },
353 :class => 'changeset', :title => 'test commit')
378 :class => 'changeset', :title => 'test commit')
354 to_test = {
379 to_test = {
355 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
380 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
356 }
381 }
357 @project = Project.find(3)
382 @project = Project.find(3)
358 r = Repository::Darcs.create!(
383 r = Repository::Darcs.create!(
359 :project => @project, :url => '/tmp/test/darcs',
384 :project => @project, :url => '/tmp/test/darcs',
360 :log_encoding => 'UTF-8')
385 :log_encoding => 'UTF-8')
361 assert r
386 assert r
362 c = Changeset.new(:repository => r,
387 c = Changeset.new(:repository => r,
363 :committed_on => Time.now,
388 :committed_on => Time.now,
364 :revision => '123',
389 :revision => '123',
365 :scmid => '20080308225258-98289-abcd456efg.gz',
390 :scmid => '20080308225258-98289-abcd456efg.gz',
366 :comments => 'test commit')
391 :comments => 'test commit')
367 assert( c.save )
392 assert( c.save )
368 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) }
369 end
394 end
370
395
371 def test_redmine_links_mercurial_commit
396 def test_redmine_links_mercurial_commit
372 changeset_link_rev = link_to('r123',
397 changeset_link_rev = link_to('r123',
373 {
398 {
374 :controller => 'repositories',
399 :controller => 'repositories',
375 :action => 'revision',
400 :action => 'revision',
376 :id => 'subproject1',
401 :id => 'subproject1',
377 :rev => '123' ,
402 :rev => '123' ,
378 },
403 },
379 :class => 'changeset', :title => 'test commit')
404 :class => 'changeset', :title => 'test commit')
380 changeset_link_commit = link_to('abcd',
405 changeset_link_commit = link_to('abcd',
381 {
406 {
382 :controller => 'repositories',
407 :controller => 'repositories',
383 :action => 'revision',
408 :action => 'revision',
384 :id => 'subproject1',
409 :id => 'subproject1',
385 :rev => 'abcd' ,
410 :rev => 'abcd' ,
386 },
411 },
387 :class => 'changeset', :title => 'test commit')
412 :class => 'changeset', :title => 'test commit')
388 to_test = {
413 to_test = {
389 'r123' => changeset_link_rev,
414 'r123' => changeset_link_rev,
390 'commit:abcd' => changeset_link_commit,
415 'commit:abcd' => changeset_link_commit,
391 }
416 }
392 @project = Project.find(3)
417 @project = Project.find(3)
393 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
418 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
394 assert r
419 assert r
395 c = Changeset.new(:repository => r,
420 c = Changeset.new(:repository => r,
396 :committed_on => Time.now,
421 :committed_on => Time.now,
397 :revision => '123',
422 :revision => '123',
398 :scmid => 'abcd',
423 :scmid => 'abcd',
399 :comments => 'test commit')
424 :comments => 'test commit')
400 assert( c.save )
425 assert( c.save )
401 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
426 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
402 end
427 end
403
428
404 def test_attachment_links
429 def test_attachment_links
405 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
430 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
406 to_test = {
431 to_test = {
407 'attachment:error281.txt' => attachment_link
432 'attachment:error281.txt' => attachment_link
408 }
433 }
409 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
434 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
410 end
435 end
411
436
412 def test_wiki_links
437 def test_wiki_links
413 to_test = {
438 to_test = {
414 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
439 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
415 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
440 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
416 # title content should be formatted
441 # title content should be formatted
417 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
442 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
418 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
443 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
419 # link with anchor
444 # link with anchor
420 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
445 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
421 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
446 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
422 # page that doesn't exist
447 # page that doesn't exist
423 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
448 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
424 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
449 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
425 # link to another project wiki
450 # link to another project wiki
426 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
451 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
427 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
452 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
428 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
453 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
429 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
454 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
430 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
455 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
431 # striked through link
456 # striked through link
432 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
457 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
433 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
458 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
434 # escaping
459 # escaping
435 '![[Another page|Page]]' => '[[Another page|Page]]',
460 '![[Another page|Page]]' => '[[Another page|Page]]',
436 # project does not exist
461 # project does not exist
437 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
462 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
438 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
463 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
439 }
464 }
440
465
441 @project = Project.find(1)
466 @project = Project.find(1)
442 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
467 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
443 end
468 end
444
469
445 def test_wiki_links_within_local_file_generation_context
470 def test_wiki_links_within_local_file_generation_context
446
471
447 to_test = {
472 to_test = {
448 # link to a page
473 # link to a page
449 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
474 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
450 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
475 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
451 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
476 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
452 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
477 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
453 # page that doesn't exist
478 # page that doesn't exist
454 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
479 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
455 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
480 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
456 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
481 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
457 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
482 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
458 }
483 }
459
484
460 @project = Project.find(1)
485 @project = Project.find(1)
461
486
462 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
487 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
463 end
488 end
464
489
465 def test_html_tags
490 def test_html_tags
466 to_test = {
491 to_test = {
467 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
492 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
468 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
493 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
469 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
494 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
470 # do not escape pre/code tags
495 # do not escape pre/code tags
471 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
496 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
472 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
497 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
473 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
498 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
474 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
499 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
475 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
500 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
476 # remove attributes except class
501 # remove attributes except class
477 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
502 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
478 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
503 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
479 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
504 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
480 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
505 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
481 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
506 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
482 # xss
507 # xss
483 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
508 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
484 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
509 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
485 }
510 }
486 to_test.each { |text, result| assert_equal result, textilizable(text) }
511 to_test.each { |text, result| assert_equal result, textilizable(text) }
487 end
512 end
488
513
489 def test_allowed_html_tags
514 def test_allowed_html_tags
490 to_test = {
515 to_test = {
491 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
516 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
492 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
517 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
493 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
518 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
494 }
519 }
495 to_test.each { |text, result| assert_equal result, textilizable(text) }
520 to_test.each { |text, result| assert_equal result, textilizable(text) }
496 end
521 end
497
522
498 def test_pre_tags
523 def test_pre_tags
499 raw = <<-RAW
524 raw = <<-RAW
500 Before
525 Before
501
526
502 <pre>
527 <pre>
503 <prepared-statement-cache-size>32</prepared-statement-cache-size>
528 <prepared-statement-cache-size>32</prepared-statement-cache-size>
504 </pre>
529 </pre>
505
530
506 After
531 After
507 RAW
532 RAW
508
533
509 expected = <<-EXPECTED
534 expected = <<-EXPECTED
510 <p>Before</p>
535 <p>Before</p>
511 <pre>
536 <pre>
512 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
537 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
513 </pre>
538 </pre>
514 <p>After</p>
539 <p>After</p>
515 EXPECTED
540 EXPECTED
516
541
517 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
542 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
518 end
543 end
519
544
520 def test_pre_content_should_not_parse_wiki_and_redmine_links
545 def test_pre_content_should_not_parse_wiki_and_redmine_links
521 raw = <<-RAW
546 raw = <<-RAW
522 [[CookBook documentation]]
547 [[CookBook documentation]]
523
548
524 #1
549 #1
525
550
526 <pre>
551 <pre>
527 [[CookBook documentation]]
552 [[CookBook documentation]]
528
553
529 #1
554 #1
530 </pre>
555 </pre>
531 RAW
556 RAW
532
557
533 expected = <<-EXPECTED
558 expected = <<-EXPECTED
534 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
559 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
535 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
560 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
536 <pre>
561 <pre>
537 [[CookBook documentation]]
562 [[CookBook documentation]]
538
563
539 #1
564 #1
540 </pre>
565 </pre>
541 EXPECTED
566 EXPECTED
542
567
543 @project = Project.find(1)
568 @project = Project.find(1)
544 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
569 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
545 end
570 end
546
571
547 def test_non_closing_pre_blocks_should_be_closed
572 def test_non_closing_pre_blocks_should_be_closed
548 raw = <<-RAW
573 raw = <<-RAW
549 <pre><code>
574 <pre><code>
550 RAW
575 RAW
551
576
552 expected = <<-EXPECTED
577 expected = <<-EXPECTED
553 <pre><code>
578 <pre><code>
554 </code></pre>
579 </code></pre>
555 EXPECTED
580 EXPECTED
556
581
557 @project = Project.find(1)
582 @project = Project.find(1)
558 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
583 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
559 end
584 end
560
585
561 def test_syntax_highlight
586 def test_syntax_highlight
562 raw = <<-RAW
587 raw = <<-RAW
563 <pre><code class="ruby">
588 <pre><code class="ruby">
564 # Some ruby code here
589 # Some ruby code here
565 </code></pre>
590 </code></pre>
566 RAW
591 RAW
567
592
568 expected = <<-EXPECTED
593 expected = <<-EXPECTED
569 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="line-numbers">1</span><span class="comment"># Some ruby code here</span></span>
594 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="line-numbers">1</span><span class="comment"># Some ruby code here</span></span>
570 </code></pre>
595 </code></pre>
571 EXPECTED
596 EXPECTED
572
597
573 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
598 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
574 end
599 end
575
600
576 def test_wiki_links_in_tables
601 def test_wiki_links_in_tables
577 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
602 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
578 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
603 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
579 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
604 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
580 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
605 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
581 }
606 }
582 @project = Project.find(1)
607 @project = Project.find(1)
583 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
608 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
584 end
609 end
585
610
586 def test_text_formatting
611 def test_text_formatting
587 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
612 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
588 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
613 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
589 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
614 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
590 '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>',
615 '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>',
591 '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',
616 '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',
592 }
617 }
593 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
618 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
594 end
619 end
595
620
596 def test_wiki_horizontal_rule
621 def test_wiki_horizontal_rule
597 assert_equal '<hr />', textilizable('---')
622 assert_equal '<hr />', textilizable('---')
598 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
623 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
599 end
624 end
600
625
601 def test_footnotes
626 def test_footnotes
602 raw = <<-RAW
627 raw = <<-RAW
603 This is some text[1].
628 This is some text[1].
604
629
605 fn1. This is the foot note
630 fn1. This is the foot note
606 RAW
631 RAW
607
632
608 expected = <<-EXPECTED
633 expected = <<-EXPECTED
609 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
634 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
610 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
635 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
611 EXPECTED
636 EXPECTED
612
637
613 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
638 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
614 end
639 end
615
640
616 def test_headings
641 def test_headings
617 raw = 'h1. Some heading'
642 raw = 'h1. Some heading'
618 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
643 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
619
644
620 assert_equal expected, textilizable(raw)
645 assert_equal expected, textilizable(raw)
621 end
646 end
622
647
623 def test_headings_with_special_chars
648 def test_headings_with_special_chars
624 # This test makes sure that the generated anchor names match the expected
649 # This test makes sure that the generated anchor names match the expected
625 # ones even if the heading text contains unconventional characters
650 # ones even if the heading text contains unconventional characters
626 raw = 'h1. Some heading related to version 0.5'
651 raw = 'h1. Some heading related to version 0.5'
627 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
652 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
628 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
653 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
629
654
630 assert_equal expected, textilizable(raw)
655 assert_equal expected, textilizable(raw)
631 end
656 end
632
657
633 def test_wiki_links_within_wiki_page_context
658 def test_wiki_links_within_wiki_page_context
634
659
635 page = WikiPage.find_by_title('Another_page' )
660 page = WikiPage.find_by_title('Another_page' )
636
661
637 to_test = {
662 to_test = {
638 # link to another page
663 # link to another page
639 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
664 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
640 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
665 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
641 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
666 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
642 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
667 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
643 # link to the current page
668 # link to the current page
644 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
669 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
645 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
670 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
646 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
671 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
647 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
672 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
648 # page that doesn't exist
673 # page that doesn't exist
649 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
674 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
650 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
675 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
651 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">Unknown page</a>',
676 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">Unknown page</a>',
652 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">404</a>',
677 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">404</a>',
653 }
678 }
654
679
655 @project = Project.find(1)
680 @project = Project.find(1)
656
681
657 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.generate!( :text => text, :page => page ), :text) }
682 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.generate!( :text => text, :page => page ), :text) }
658 end
683 end
659
684
660 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
685 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
661
686
662 to_test = {
687 to_test = {
663 # link to a page
688 # link to a page
664 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
689 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
665 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
690 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
666 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
691 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
667 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
692 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
668 # page that doesn't exist
693 # page that doesn't exist
669 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
694 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
670 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
695 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
671 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
696 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
672 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
697 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
673 }
698 }
674
699
675 @project = Project.find(1)
700 @project = Project.find(1)
676
701
677 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
702 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
678 end
703 end
679
704
680 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
705 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
681 page = WikiPage.generate!( :title => 'Page Title' )
706 page = WikiPage.generate!( :title => 'Page Title' )
682 content = WikiContent.generate!( :text => 'h1. Some heading', :page => page )
707 content = WikiContent.generate!( :text => 'h1. Some heading', :page => page )
683
708
684 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
709 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
685
710
686 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
711 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
687 end
712 end
688
713
689 def test_table_of_content
714 def test_table_of_content
690 raw = <<-RAW
715 raw = <<-RAW
691 {{toc}}
716 {{toc}}
692
717
693 h1. Title
718 h1. Title
694
719
695 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
720 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
696
721
697 h2. Subtitle with a [[Wiki]] link
722 h2. Subtitle with a [[Wiki]] link
698
723
699 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
724 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
700
725
701 h2. Subtitle with [[Wiki|another Wiki]] link
726 h2. Subtitle with [[Wiki|another Wiki]] link
702
727
703 h2. Subtitle with %{color:red}red text%
728 h2. Subtitle with %{color:red}red text%
704
729
705 <pre>
730 <pre>
706 some code
731 some code
707 </pre>
732 </pre>
708
733
709 h3. Subtitle with *some* _modifiers_
734 h3. Subtitle with *some* _modifiers_
710
735
711 h1. Another title
736 h1. Another title
712
737
713 h3. An "Internet link":http://www.redmine.org/ inside subtitle
738 h3. An "Internet link":http://www.redmine.org/ inside subtitle
714
739
715 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
740 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
716
741
717 RAW
742 RAW
718
743
719 expected = '<ul class="toc">' +
744 expected = '<ul class="toc">' +
720 '<li><a href="#Title">Title</a>' +
745 '<li><a href="#Title">Title</a>' +
721 '<ul>' +
746 '<ul>' +
722 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
747 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
723 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
748 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
724 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
749 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
725 '<ul>' +
750 '<ul>' +
726 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
751 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
727 '</ul>' +
752 '</ul>' +
728 '</li>' +
753 '</li>' +
729 '</ul>' +
754 '</ul>' +
730 '</li>' +
755 '</li>' +
731 '<li><a href="#Another-title">Another title</a>' +
756 '<li><a href="#Another-title">Another title</a>' +
732 '<ul>' +
757 '<ul>' +
733 '<li>' +
758 '<li>' +
734 '<ul>' +
759 '<ul>' +
735 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
760 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
736 '</ul>' +
761 '</ul>' +
737 '</li>' +
762 '</li>' +
738 '<li><a href="#Project-Name">Project Name</a></li>' +
763 '<li><a href="#Project-Name">Project Name</a></li>' +
739 '</ul>' +
764 '</ul>' +
740 '</li>' +
765 '</li>' +
741 '</ul>'
766 '</ul>'
742
767
743 @project = Project.find(1)
768 @project = Project.find(1)
744 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
769 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
745 end
770 end
746
771
747 def test_table_of_content_should_contain_included_page_headings
772 def test_table_of_content_should_contain_included_page_headings
748 raw = <<-RAW
773 raw = <<-RAW
749 {{toc}}
774 {{toc}}
750
775
751 h1. Included
776 h1. Included
752
777
753 {{include(Child_1)}}
778 {{include(Child_1)}}
754 RAW
779 RAW
755
780
756 expected = '<ul class="toc">' +
781 expected = '<ul class="toc">' +
757 '<li><a href="#Included">Included</a></li>' +
782 '<li><a href="#Included">Included</a></li>' +
758 '<li><a href="#Child-page-1">Child page 1</a></li>' +
783 '<li><a href="#Child-page-1">Child page 1</a></li>' +
759 '</ul>'
784 '</ul>'
760
785
761 @project = Project.find(1)
786 @project = Project.find(1)
762 assert textilizable(raw).gsub("\n", "").include?(expected)
787 assert textilizable(raw).gsub("\n", "").include?(expected)
763 end
788 end
764
789
765 def test_default_formatter
790 def test_default_formatter
766 Setting.text_formatting = 'unknown'
791 Setting.text_formatting = 'unknown'
767 text = 'a *link*: http://www.example.net/'
792 text = 'a *link*: http://www.example.net/'
768 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
793 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
769 Setting.text_formatting = 'textile'
794 Setting.text_formatting = 'textile'
770 end
795 end
771
796
772 def test_due_date_distance_in_words
797 def test_due_date_distance_in_words
773 to_test = { Date.today => 'Due in 0 days',
798 to_test = { Date.today => 'Due in 0 days',
774 Date.today + 1 => 'Due in 1 day',
799 Date.today + 1 => 'Due in 1 day',
775 Date.today + 100 => 'Due in about 3 months',
800 Date.today + 100 => 'Due in about 3 months',
776 Date.today + 20000 => 'Due in over 54 years',
801 Date.today + 20000 => 'Due in over 54 years',
777 Date.today - 1 => '1 day late',
802 Date.today - 1 => '1 day late',
778 Date.today - 100 => 'about 3 months late',
803 Date.today - 100 => 'about 3 months late',
779 Date.today - 20000 => 'over 54 years late',
804 Date.today - 20000 => 'over 54 years late',
780 }
805 }
781 ::I18n.locale = :en
806 ::I18n.locale = :en
782 to_test.each do |date, expected|
807 to_test.each do |date, expected|
783 assert_equal expected, due_date_distance_in_words(date)
808 assert_equal expected, due_date_distance_in_words(date)
784 end
809 end
785 end
810 end
786
811
787 def test_avatar
812 def test_avatar
788 # turn on avatars
813 # turn on avatars
789 Setting.gravatar_enabled = '1'
814 Setting.gravatar_enabled = '1'
790 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
815 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
791 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
816 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
792 assert_nil avatar('jsmith')
817 assert_nil avatar('jsmith')
793 assert_nil avatar(nil)
818 assert_nil avatar(nil)
794
819
795 # turn off avatars
820 # turn off avatars
796 Setting.gravatar_enabled = '0'
821 Setting.gravatar_enabled = '0'
797 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
822 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
798 end
823 end
799
824
800 def test_link_to_user
825 def test_link_to_user
801 user = User.find(2)
826 user = User.find(2)
802 t = link_to_user(user)
827 t = link_to_user(user)
803 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
828 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
804 end
829 end
805
830
806 def test_link_to_user_should_not_link_to_locked_user
831 def test_link_to_user_should_not_link_to_locked_user
807 user = User.find(5)
832 user = User.find(5)
808 assert user.locked?
833 assert user.locked?
809 t = link_to_user(user)
834 t = link_to_user(user)
810 assert_equal user.name, t
835 assert_equal user.name, t
811 end
836 end
812
837
813 def test_link_to_user_should_not_link_to_anonymous
838 def test_link_to_user_should_not_link_to_anonymous
814 user = User.anonymous
839 user = User.anonymous
815 assert user.anonymous?
840 assert user.anonymous?
816 t = link_to_user(user)
841 t = link_to_user(user)
817 assert_equal ::I18n.t(:label_user_anonymous), t
842 assert_equal ::I18n.t(:label_user_anonymous), t
818 end
843 end
819
844
820 def test_link_to_project
845 def test_link_to_project
821 project = Project.find(1)
846 project = Project.find(1)
822 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
847 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
823 link_to_project(project)
848 link_to_project(project)
824 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
849 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
825 link_to_project(project, :action => 'settings')
850 link_to_project(project, :action => 'settings')
826 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
851 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
827 link_to_project(project, {:only_path => false, :jump => 'blah'})
852 link_to_project(project, {:only_path => false, :jump => 'blah'})
828 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
853 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
829 link_to_project(project, {:action => 'settings'}, :class => "project")
854 link_to_project(project, {:action => 'settings'}, :class => "project")
830 end
855 end
831
856
832 def test_principals_options_for_select_with_users
857 def test_principals_options_for_select_with_users
833 users = [User.find(2), User.find(4)]
858 users = [User.find(2), User.find(4)]
834 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
859 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
835 principals_options_for_select(users)
860 principals_options_for_select(users)
836 end
861 end
837
862
838 def test_principals_options_for_select_with_selected
863 def test_principals_options_for_select_with_selected
839 users = [User.find(2), User.find(4)]
864 users = [User.find(2), User.find(4)]
840 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
865 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
841 principals_options_for_select(users, User.find(4))
866 principals_options_for_select(users, User.find(4))
842 end
867 end
843
868
844 def test_principals_options_for_select_with_users_and_groups
869 def test_principals_options_for_select_with_users_and_groups
845 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
870 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
846 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
871 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
847 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
872 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
848 principals_options_for_select(users)
873 principals_options_for_select(users)
849 end
874 end
850
875
851 def test_principals_options_for_select_with_empty_collection
876 def test_principals_options_for_select_with_empty_collection
852 assert_equal '', principals_options_for_select([])
877 assert_equal '', principals_options_for_select([])
853 end
878 end
854 end
879 end
General Comments 0
You need to be logged in to leave comments. Login now