##// END OF EJS Templates
fix unit search test failure (#13405)...
Toshi MARUYAMA -
r11444:919d4589b9e1
parent child
Show More
@@ -1,104 +1,104
1 ---
1 ---
2 changesets_001:
2 changesets_001:
3 commit_date: 2007-04-11
3 commit_date: 2007-04-11
4 committed_on: 2007-04-11 15:14:44 +02:00
4 committed_on: 2007-04-11 15:14:44 +02:00
5 revision: 1
5 revision: 1
6 scmid: 691322a8eb01e11fd7
6 scmid: 691322a8eb01e11fd7
7 id: 100
7 id: 100
8 comments: 'do not escaping #<>&'
8 comments: 'My very first commit do not escaping #<>&'
9 repository_id: 10
9 repository_id: 10
10 committer: dlopper
10 committer: dlopper
11 user_id: 3
11 user_id: 3
12 changesets_002:
12 changesets_002:
13 commit_date: 2007-04-12
13 commit_date: 2007-04-12
14 committed_on: 2007-04-12 15:14:44 +02:00
14 committed_on: 2007-04-12 15:14:44 +02:00
15 revision: 2
15 revision: 2
16 id: 101
16 id: 101
17 comments: 'This commit fixes #1, #2 and references #1 & #3'
17 comments: 'This commit fixes #1, #2 and references #1 & #3'
18 repository_id: 10
18 repository_id: 10
19 committer: dlopper
19 committer: dlopper
20 user_id: 3
20 user_id: 3
21 changesets_003:
21 changesets_003:
22 commit_date: 2007-04-12
22 commit_date: 2007-04-12
23 committed_on: 2007-04-12 15:14:44 +02:00
23 committed_on: 2007-04-12 15:14:44 +02:00
24 revision: 3
24 revision: 3
25 id: 102
25 id: 102
26 comments: |-
26 comments: |-
27 A commit with wrong issue ids
27 A commit with wrong issue ids
28 IssueID #666 #3
28 IssueID #666 #3
29 repository_id: 10
29 repository_id: 10
30 committer: dlopper
30 committer: dlopper
31 user_id: 3
31 user_id: 3
32 changesets_004:
32 changesets_004:
33 commit_date: 2007-04-12
33 commit_date: 2007-04-12
34 committed_on: 2007-04-12 15:14:44 +02:00
34 committed_on: 2007-04-12 15:14:44 +02:00
35 revision: 4
35 revision: 4
36 id: 103
36 id: 103
37 comments: |-
37 comments: |-
38 A commit with an issue id of an other project
38 A commit with an issue id of an other project
39 IssueID 4 2
39 IssueID 4 2
40 repository_id: 10
40 repository_id: 10
41 committer: dlopper
41 committer: dlopper
42 user_id: 3
42 user_id: 3
43 changesets_005:
43 changesets_005:
44 commit_date: "2007-09-10"
44 commit_date: "2007-09-10"
45 comments: Modified one file in the folder.
45 comments: Modified one file in the folder.
46 committed_on: 2007-09-10 19:01:08
46 committed_on: 2007-09-10 19:01:08
47 revision: "5"
47 revision: "5"
48 id: 104
48 id: 104
49 scmid:
49 scmid:
50 user_id: 3
50 user_id: 3
51 repository_id: 10
51 repository_id: 10
52 committer: dlopper
52 committer: dlopper
53 changesets_006:
53 changesets_006:
54 commit_date: "2007-09-10"
54 commit_date: "2007-09-10"
55 comments: Moved helloworld.rb from / to /folder.
55 comments: Moved helloworld.rb from / to /folder.
56 committed_on: 2007-09-10 19:01:47
56 committed_on: 2007-09-10 19:01:47
57 revision: "6"
57 revision: "6"
58 id: 105
58 id: 105
59 scmid:
59 scmid:
60 user_id: 3
60 user_id: 3
61 repository_id: 10
61 repository_id: 10
62 committer: dlopper
62 committer: dlopper
63 changesets_007:
63 changesets_007:
64 commit_date: "2007-09-10"
64 commit_date: "2007-09-10"
65 comments: Removed one file.
65 comments: Removed one file.
66 committed_on: 2007-09-10 19:02:16
66 committed_on: 2007-09-10 19:02:16
67 revision: "7"
67 revision: "7"
68 id: 106
68 id: 106
69 scmid:
69 scmid:
70 user_id: 3
70 user_id: 3
71 repository_id: 10
71 repository_id: 10
72 committer: dlopper
72 committer: dlopper
73 changesets_008:
73 changesets_008:
74 commit_date: "2007-09-10"
74 commit_date: "2007-09-10"
75 comments: |-
75 comments: |-
76 This commits references an issue.
76 This commits references an issue.
77 Refs #2
77 Refs #2
78 committed_on: 2007-09-10 19:04:35
78 committed_on: 2007-09-10 19:04:35
79 revision: "8"
79 revision: "8"
80 id: 107
80 id: 107
81 scmid:
81 scmid:
82 user_id: 3
82 user_id: 3
83 repository_id: 10
83 repository_id: 10
84 committer: dlopper
84 committer: dlopper
85 changesets_009:
85 changesets_009:
86 commit_date: "2009-09-10"
86 commit_date: "2009-09-10"
87 comments: One file added.
87 comments: One file added.
88 committed_on: 2009-09-10 19:04:35
88 committed_on: 2009-09-10 19:04:35
89 revision: "9"
89 revision: "9"
90 id: 108
90 id: 108
91 scmid:
91 scmid:
92 user_id: 3
92 user_id: 3
93 repository_id: 10
93 repository_id: 10
94 committer: dlopper
94 committer: dlopper
95 changesets_010:
95 changesets_010:
96 commit_date: "2009-09-10"
96 commit_date: "2009-09-10"
97 comments: Same file modified.
97 comments: Same file modified.
98 committed_on: 2009-09-10 19:04:35
98 committed_on: 2009-09-10 19:04:35
99 revision: "10"
99 revision: "10"
100 id: 109
100 id: 109
101 scmid:
101 scmid:
102 user_id: 3
102 user_id: 3
103 repository_id: 10
103 repository_id: 10
104 committer: dlopper
104 committer: dlopper
@@ -1,1212 +1,1213
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require File.expand_path('../../../test_helper', __FILE__)
20 require File.expand_path('../../../test_helper', __FILE__)
21
21
22 class ApplicationHelperTest < ActionView::TestCase
22 class ApplicationHelperTest < ActionView::TestCase
23 include ERB::Util
23 include ERB::Util
24 include Rails.application.routes.url_helpers
24 include Rails.application.routes.url_helpers
25
25
26 fixtures :projects, :roles, :enabled_modules, :users,
26 fixtures :projects, :roles, :enabled_modules, :users,
27 :repositories, :changesets,
27 :repositories, :changesets,
28 :trackers, :issue_statuses, :issues, :versions, :documents,
28 :trackers, :issue_statuses, :issues, :versions, :documents,
29 :wikis, :wiki_pages, :wiki_contents,
29 :wikis, :wiki_pages, :wiki_contents,
30 :boards, :messages, :news,
30 :boards, :messages, :news,
31 :attachments, :enumerations
31 :attachments, :enumerations
32
32
33 def setup
33 def setup
34 super
34 super
35 set_tmp_attachments_directory
35 set_tmp_attachments_directory
36 end
36 end
37
37
38 context "#link_to_if_authorized" do
38 context "#link_to_if_authorized" do
39 context "authorized user" do
39 context "authorized user" do
40 should "be tested"
40 should "be tested"
41 end
41 end
42
42
43 context "unauthorized user" do
43 context "unauthorized user" do
44 should "be tested"
44 should "be tested"
45 end
45 end
46
46
47 should "allow using the :controller and :action for the target link" do
47 should "allow using the :controller and :action for the target link" do
48 User.current = User.find_by_login('admin')
48 User.current = User.find_by_login('admin')
49
49
50 @project = Issue.first.project # Used by helper
50 @project = Issue.first.project # Used by helper
51 response = link_to_if_authorized("By controller/action",
51 response = link_to_if_authorized("By controller/action",
52 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
52 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
53 assert_match /href/, response
53 assert_match /href/, response
54 end
54 end
55
55
56 end
56 end
57
57
58 def test_auto_links
58 def test_auto_links
59 to_test = {
59 to_test = {
60 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
60 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
61 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
61 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
62 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
62 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
63 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
63 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
64 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
64 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
65 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
65 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
66 '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>.',
66 '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>.',
67 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
67 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
68 '(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>)',
68 '(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>)',
69 '(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>)',
69 '(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>)',
70 '(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>).',
70 '(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>).',
71 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
71 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
72 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
72 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
73 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
73 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
74 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
74 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
75 '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>',
75 '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>',
76 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
76 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
77 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
77 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
78 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
78 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
79 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
79 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
80 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
80 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
81 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
81 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
82 # two exclamation marks
82 # two exclamation marks
83 '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>',
83 '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>',
84 # escaping
84 # escaping
85 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
85 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
86 # wrap in angle brackets
86 # wrap in angle brackets
87 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
87 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
88 # invalid urls
88 # invalid urls
89 'http://' => 'http://',
89 'http://' => 'http://',
90 'www.' => 'www.',
90 'www.' => 'www.',
91 'test-www.bar.com' => 'test-www.bar.com',
91 'test-www.bar.com' => 'test-www.bar.com',
92 }
92 }
93 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
93 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
94 end
94 end
95
95
96 if 'ruby'.respond_to?(:encoding)
96 if 'ruby'.respond_to?(:encoding)
97 def test_auto_links_with_non_ascii_characters
97 def test_auto_links_with_non_ascii_characters
98 to_test = {
98 to_test = {
99 'http://foo.bar/тСст' => '<a class="external" href="http://foo.bar/тСст">http://foo.bar/тСст</a>'
99 'http://foo.bar/тСст' => '<a class="external" href="http://foo.bar/тСст">http://foo.bar/тСст</a>'
100 }
100 }
101 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
101 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
102 end
102 end
103 else
103 else
104 puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version'
104 puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version'
105 end
105 end
106
106
107 def test_auto_mailto
107 def test_auto_mailto
108 to_test = {
108 to_test = {
109 'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
109 'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
110 'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
110 'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
111 }
111 }
112 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
112 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
113 end
113 end
114
114
115 def test_inline_images
115 def test_inline_images
116 to_test = {
116 to_test = {
117 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
117 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
118 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
118 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
119 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
119 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
120 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
120 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
121 '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" />',
121 '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" />',
122 '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;" />',
122 '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;" />',
123 }
123 }
124 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
124 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
125 end
125 end
126
126
127 def test_inline_images_inside_tags
127 def test_inline_images_inside_tags
128 raw = <<-RAW
128 raw = <<-RAW
129 h1. !foo.png! Heading
129 h1. !foo.png! Heading
130
130
131 Centered image:
131 Centered image:
132
132
133 p=. !bar.gif!
133 p=. !bar.gif!
134 RAW
134 RAW
135
135
136 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
136 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
137 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
137 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
138 end
138 end
139
139
140 def test_attached_images
140 def test_attached_images
141 to_test = {
141 to_test = {
142 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
142 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
143 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
143 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
144 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
144 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
145 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
145 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
146 # link image
146 # link image
147 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
147 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
148 }
148 }
149 attachments = Attachment.all
149 attachments = Attachment.all
150 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
150 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
151 end
151 end
152
152
153 def test_attached_images_filename_extension
153 def test_attached_images_filename_extension
154 set_tmp_attachments_directory
154 set_tmp_attachments_directory
155 a1 = Attachment.new(
155 a1 = Attachment.new(
156 :container => Issue.find(1),
156 :container => Issue.find(1),
157 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
157 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
158 :author => User.find(1))
158 :author => User.find(1))
159 assert a1.save
159 assert a1.save
160 assert_equal "testtest.JPG", a1.filename
160 assert_equal "testtest.JPG", a1.filename
161 assert_equal "image/jpeg", a1.content_type
161 assert_equal "image/jpeg", a1.content_type
162 assert a1.image?
162 assert a1.image?
163
163
164 a2 = Attachment.new(
164 a2 = Attachment.new(
165 :container => Issue.find(1),
165 :container => Issue.find(1),
166 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
166 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
167 :author => User.find(1))
167 :author => User.find(1))
168 assert a2.save
168 assert a2.save
169 assert_equal "testtest.jpeg", a2.filename
169 assert_equal "testtest.jpeg", a2.filename
170 assert_equal "image/jpeg", a2.content_type
170 assert_equal "image/jpeg", a2.content_type
171 assert a2.image?
171 assert a2.image?
172
172
173 a3 = Attachment.new(
173 a3 = Attachment.new(
174 :container => Issue.find(1),
174 :container => Issue.find(1),
175 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
175 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
176 :author => User.find(1))
176 :author => User.find(1))
177 assert a3.save
177 assert a3.save
178 assert_equal "testtest.JPE", a3.filename
178 assert_equal "testtest.JPE", a3.filename
179 assert_equal "image/jpeg", a3.content_type
179 assert_equal "image/jpeg", a3.content_type
180 assert a3.image?
180 assert a3.image?
181
181
182 a4 = Attachment.new(
182 a4 = Attachment.new(
183 :container => Issue.find(1),
183 :container => Issue.find(1),
184 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
184 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
185 :author => User.find(1))
185 :author => User.find(1))
186 assert a4.save
186 assert a4.save
187 assert_equal "Testtest.BMP", a4.filename
187 assert_equal "Testtest.BMP", a4.filename
188 assert_equal "image/x-ms-bmp", a4.content_type
188 assert_equal "image/x-ms-bmp", a4.content_type
189 assert a4.image?
189 assert a4.image?
190
190
191 to_test = {
191 to_test = {
192 'Inline image: !testtest.jpg!' =>
192 'Inline image: !testtest.jpg!' =>
193 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
193 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
194 'Inline image: !testtest.jpeg!' =>
194 'Inline image: !testtest.jpeg!' =>
195 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
195 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
196 'Inline image: !testtest.jpe!' =>
196 'Inline image: !testtest.jpe!' =>
197 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
197 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
198 'Inline image: !testtest.bmp!' =>
198 'Inline image: !testtest.bmp!' =>
199 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
199 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
200 }
200 }
201
201
202 attachments = [a1, a2, a3, a4]
202 attachments = [a1, a2, a3, a4]
203 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
203 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
204 end
204 end
205
205
206 def test_attached_images_should_read_later
206 def test_attached_images_should_read_later
207 set_fixtures_attachments_directory
207 set_fixtures_attachments_directory
208 a1 = Attachment.find(16)
208 a1 = Attachment.find(16)
209 assert_equal "testfile.png", a1.filename
209 assert_equal "testfile.png", a1.filename
210 assert a1.readable?
210 assert a1.readable?
211 assert (! a1.visible?(User.anonymous))
211 assert (! a1.visible?(User.anonymous))
212 assert a1.visible?(User.find(2))
212 assert a1.visible?(User.find(2))
213 a2 = Attachment.find(17)
213 a2 = Attachment.find(17)
214 assert_equal "testfile.PNG", a2.filename
214 assert_equal "testfile.PNG", a2.filename
215 assert a2.readable?
215 assert a2.readable?
216 assert (! a2.visible?(User.anonymous))
216 assert (! a2.visible?(User.anonymous))
217 assert a2.visible?(User.find(2))
217 assert a2.visible?(User.find(2))
218 assert a1.created_on < a2.created_on
218 assert a1.created_on < a2.created_on
219
219
220 to_test = {
220 to_test = {
221 'Inline image: !testfile.png!' =>
221 'Inline image: !testfile.png!' =>
222 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
222 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
223 'Inline image: !Testfile.PNG!' =>
223 'Inline image: !Testfile.PNG!' =>
224 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
224 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
225 }
225 }
226 attachments = [a1, a2]
226 attachments = [a1, a2]
227 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
227 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
228 set_tmp_attachments_directory
228 set_tmp_attachments_directory
229 end
229 end
230
230
231 def test_textile_external_links
231 def test_textile_external_links
232 to_test = {
232 to_test = {
233 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
233 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
234 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
234 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
235 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
235 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
236 '"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>',
236 '"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>',
237 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
237 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
238 # no multiline link text
238 # no multiline link text
239 "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",
239 "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",
240 # mailto link
240 # mailto link
241 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
241 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
242 # two exclamation marks
242 # two exclamation marks
243 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
243 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
244 # escaping
244 # escaping
245 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
245 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
246 }
246 }
247 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
247 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
248 end
248 end
249
249
250 if 'ruby'.respond_to?(:encoding)
250 if 'ruby'.respond_to?(:encoding)
251 def test_textile_external_links_with_non_ascii_characters
251 def test_textile_external_links_with_non_ascii_characters
252 to_test = {
252 to_test = {
253 'This is a "link":http://foo.bar/тСст' => 'This is a <a href="http://foo.bar/тСст" class="external">link</a>'
253 'This is a "link":http://foo.bar/тСст' => 'This is a <a href="http://foo.bar/тСст" class="external">link</a>'
254 }
254 }
255 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
255 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
256 end
256 end
257 else
257 else
258 puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version'
258 puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version'
259 end
259 end
260
260
261 def test_redmine_links
261 def test_redmine_links
262 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
262 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
263 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
263 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
264 note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
264 note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
265 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
265 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
266
266
267 revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
267 revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
268 :class => 'changeset', :title => 'do not escaping #<>&')
268 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
269 revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
269 revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
270 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
270 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
271
271
272 changeset_link2 = link_to('691322a8eb01e11fd7', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
272 changeset_link2 = link_to('691322a8eb01e11fd7',
273 :class => 'changeset', :title => 'do not escaping #<>&')
273 {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
274 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
274
275
275 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
276 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
276 :class => 'document')
277 :class => 'document')
277
278
278 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
279 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
279 :class => 'version')
280 :class => 'version')
280
281
281 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
282 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
282
283
283 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
284 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
284
285
285 news_url = {:controller => 'news', :action => 'show', :id => 1}
286 news_url = {:controller => 'news', :action => 'show', :id => 1}
286
287
287 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
288 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
288
289
289 source_url = '/projects/ecookbook/repository/entry/some/file'
290 source_url = '/projects/ecookbook/repository/entry/some/file'
290 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
291 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
291 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
292 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
292 source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
293 source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
293 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
294 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
294
295
295 export_url = '/projects/ecookbook/repository/raw/some/file'
296 export_url = '/projects/ecookbook/repository/raw/some/file'
296 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
297 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
297 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
298 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
298 export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
299 export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
299 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
300 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
300
301
301 to_test = {
302 to_test = {
302 # tickets
303 # tickets
303 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
304 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
304 # ticket notes
305 # ticket notes
305 '#3-14' => note_link,
306 '#3-14' => note_link,
306 '#3#note-14' => note_link,
307 '#3#note-14' => note_link,
307 # should not ignore leading zero
308 # should not ignore leading zero
308 '#03' => '#03',
309 '#03' => '#03',
309 # changesets
310 # changesets
310 'r1' => revision_link,
311 'r1' => revision_link,
311 'r1.' => "#{revision_link}.",
312 'r1.' => "#{revision_link}.",
312 'r1, r2' => "#{revision_link}, #{revision_link2}",
313 'r1, r2' => "#{revision_link}, #{revision_link2}",
313 'r1,r2' => "#{revision_link},#{revision_link2}",
314 'r1,r2' => "#{revision_link},#{revision_link2}",
314 'commit:691322a8eb01e11fd7' => changeset_link2,
315 'commit:691322a8eb01e11fd7' => changeset_link2,
315 # documents
316 # documents
316 'document#1' => document_link,
317 'document#1' => document_link,
317 'document:"Test document"' => document_link,
318 'document:"Test document"' => document_link,
318 # versions
319 # versions
319 'version#2' => version_link,
320 'version#2' => version_link,
320 'version:1.0' => version_link,
321 'version:1.0' => version_link,
321 'version:"1.0"' => version_link,
322 'version:"1.0"' => version_link,
322 # source
323 # source
323 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
324 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
324 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
325 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
325 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
326 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
326 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
327 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
327 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
328 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
328 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
329 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
329 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
330 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
330 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
331 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
331 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
332 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
332 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
333 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
333 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
334 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
334 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
335 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
335 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
336 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
336 # export
337 # export
337 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
338 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
338 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
339 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
339 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
340 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
340 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
341 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
341 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
342 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
342 # forum
343 # forum
343 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
344 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
344 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
345 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
345 # message
346 # message
346 'message#4' => link_to('Post 2', message_url, :class => 'message'),
347 'message#4' => link_to('Post 2', message_url, :class => 'message'),
347 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
348 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
348 # news
349 # news
349 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
350 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
350 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
351 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
351 # project
352 # project
352 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
354 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
354 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
355 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
355 # not found
356 # not found
356 '#0123456789' => '#0123456789',
357 '#0123456789' => '#0123456789',
357 # invalid expressions
358 # invalid expressions
358 'source:' => 'source:',
359 'source:' => 'source:',
359 # url hash
360 # url hash
360 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
361 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
361 }
362 }
362 @project = Project.find(1)
363 @project = Project.find(1)
363 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
364 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
364 end
365 end
365
366
366 def test_redmine_links_with_a_different_project_before_current_project
367 def test_redmine_links_with_a_different_project_before_current_project
367 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
368 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
368 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
369 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
369
370
370 @project = Project.find(3)
371 @project = Project.find(3)
371 assert_equal %(<p><a href="/versions/#{vp1.id}" class="version">1.4.4</a> <a href="/versions/#{vp3.id}" class="version">1.4.4</a></p>),
372 assert_equal %(<p><a href="/versions/#{vp1.id}" class="version">1.4.4</a> <a href="/versions/#{vp3.id}" class="version">1.4.4</a></p>),
372 textilizable("ecookbook:version:1.4.4 version:1.4.4")
373 textilizable("ecookbook:version:1.4.4 version:1.4.4")
373 end
374 end
374
375
375 def test_escaped_redmine_links_should_not_be_parsed
376 def test_escaped_redmine_links_should_not_be_parsed
376 to_test = [
377 to_test = [
377 '#3.',
378 '#3.',
378 '#3-14.',
379 '#3-14.',
379 '#3#-note14.',
380 '#3#-note14.',
380 'r1',
381 'r1',
381 'document#1',
382 'document#1',
382 'document:"Test document"',
383 'document:"Test document"',
383 'version#2',
384 'version#2',
384 'version:1.0',
385 'version:1.0',
385 'version:"1.0"',
386 'version:"1.0"',
386 'source:/some/file'
387 'source:/some/file'
387 ]
388 ]
388 @project = Project.find(1)
389 @project = Project.find(1)
389 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
390 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
390 end
391 end
391
392
392 def test_cross_project_redmine_links
393 def test_cross_project_redmine_links
393 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
394 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
394 :class => 'source')
395 :class => 'source')
395
396
396 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
397 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
397 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
398 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
398
399
399 to_test = {
400 to_test = {
400 # documents
401 # documents
401 'document:"Test document"' => 'document:"Test document"',
402 'document:"Test document"' => 'document:"Test document"',
402 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
403 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
403 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
404 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
404 # versions
405 # versions
405 'version:"1.0"' => 'version:"1.0"',
406 'version:"1.0"' => 'version:"1.0"',
406 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
407 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
407 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
408 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
408 # changeset
409 # changeset
409 'r2' => 'r2',
410 'r2' => 'r2',
410 'ecookbook:r2' => changeset_link,
411 'ecookbook:r2' => changeset_link,
411 'invalid:r2' => 'invalid:r2',
412 'invalid:r2' => 'invalid:r2',
412 # source
413 # source
413 'source:/some/file' => 'source:/some/file',
414 'source:/some/file' => 'source:/some/file',
414 'ecookbook:source:/some/file' => source_link,
415 'ecookbook:source:/some/file' => source_link,
415 'invalid:source:/some/file' => 'invalid:source:/some/file',
416 'invalid:source:/some/file' => 'invalid:source:/some/file',
416 }
417 }
417 @project = Project.find(3)
418 @project = Project.find(3)
418 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
419 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
419 end
420 end
420
421
421 def test_multiple_repositories_redmine_links
422 def test_multiple_repositories_redmine_links
422 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
423 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
423 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
424 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
424 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
425 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
425 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
426 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
426
427
427 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
428 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
428 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
429 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
429 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
430 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
430 :class => 'changeset', :title => '')
431 :class => 'changeset', :title => '')
431 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
432 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
432 :class => 'changeset', :title => '')
433 :class => 'changeset', :title => '')
433
434
434 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
435 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
435 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
436 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
436
437
437 to_test = {
438 to_test = {
438 'r2' => changeset_link,
439 'r2' => changeset_link,
439 'svn_repo-1|r123' => svn_changeset_link,
440 'svn_repo-1|r123' => svn_changeset_link,
440 'invalid|r123' => 'invalid|r123',
441 'invalid|r123' => 'invalid|r123',
441 'commit:hg1|abcd' => hg_changeset_link,
442 'commit:hg1|abcd' => hg_changeset_link,
442 'commit:invalid|abcd' => 'commit:invalid|abcd',
443 'commit:invalid|abcd' => 'commit:invalid|abcd',
443 # source
444 # source
444 'source:some/file' => source_link,
445 'source:some/file' => source_link,
445 'source:hg1|some/file' => hg_source_link,
446 'source:hg1|some/file' => hg_source_link,
446 'source:invalid|some/file' => 'source:invalid|some/file',
447 'source:invalid|some/file' => 'source:invalid|some/file',
447 }
448 }
448
449
449 @project = Project.find(1)
450 @project = Project.find(1)
450 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
451 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
451 end
452 end
452
453
453 def test_cross_project_multiple_repositories_redmine_links
454 def test_cross_project_multiple_repositories_redmine_links
454 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
455 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
455 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
456 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
456 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
457 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
457 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
458 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
458
459
459 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
460 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
460 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
461 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
461 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
462 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
462 :class => 'changeset', :title => '')
463 :class => 'changeset', :title => '')
463 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
464 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
464 :class => 'changeset', :title => '')
465 :class => 'changeset', :title => '')
465
466
466 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
467 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
467 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
468 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
468
469
469 to_test = {
470 to_test = {
470 'ecookbook:r2' => changeset_link,
471 'ecookbook:r2' => changeset_link,
471 'ecookbook:svn1|r123' => svn_changeset_link,
472 'ecookbook:svn1|r123' => svn_changeset_link,
472 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
473 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
473 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
474 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
474 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
475 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
475 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
476 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
476 # source
477 # source
477 'ecookbook:source:some/file' => source_link,
478 'ecookbook:source:some/file' => source_link,
478 'ecookbook:source:hg1|some/file' => hg_source_link,
479 'ecookbook:source:hg1|some/file' => hg_source_link,
479 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
480 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
480 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
481 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
481 }
482 }
482
483
483 @project = Project.find(3)
484 @project = Project.find(3)
484 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
485 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
485 end
486 end
486
487
487 def test_redmine_links_git_commit
488 def test_redmine_links_git_commit
488 changeset_link = link_to('abcd',
489 changeset_link = link_to('abcd',
489 {
490 {
490 :controller => 'repositories',
491 :controller => 'repositories',
491 :action => 'revision',
492 :action => 'revision',
492 :id => 'subproject1',
493 :id => 'subproject1',
493 :rev => 'abcd',
494 :rev => 'abcd',
494 },
495 },
495 :class => 'changeset', :title => 'test commit')
496 :class => 'changeset', :title => 'test commit')
496 to_test = {
497 to_test = {
497 'commit:abcd' => changeset_link,
498 'commit:abcd' => changeset_link,
498 }
499 }
499 @project = Project.find(3)
500 @project = Project.find(3)
500 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
501 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
501 assert r
502 assert r
502 c = Changeset.new(:repository => r,
503 c = Changeset.new(:repository => r,
503 :committed_on => Time.now,
504 :committed_on => Time.now,
504 :revision => 'abcd',
505 :revision => 'abcd',
505 :scmid => 'abcd',
506 :scmid => 'abcd',
506 :comments => 'test commit')
507 :comments => 'test commit')
507 assert( c.save )
508 assert( c.save )
508 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
509 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
509 end
510 end
510
511
511 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
512 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
512 def test_redmine_links_darcs_commit
513 def test_redmine_links_darcs_commit
513 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
514 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
514 {
515 {
515 :controller => 'repositories',
516 :controller => 'repositories',
516 :action => 'revision',
517 :action => 'revision',
517 :id => 'subproject1',
518 :id => 'subproject1',
518 :rev => '123',
519 :rev => '123',
519 },
520 },
520 :class => 'changeset', :title => 'test commit')
521 :class => 'changeset', :title => 'test commit')
521 to_test = {
522 to_test = {
522 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
523 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
523 }
524 }
524 @project = Project.find(3)
525 @project = Project.find(3)
525 r = Repository::Darcs.create!(
526 r = Repository::Darcs.create!(
526 :project => @project, :url => '/tmp/test/darcs',
527 :project => @project, :url => '/tmp/test/darcs',
527 :log_encoding => 'UTF-8')
528 :log_encoding => 'UTF-8')
528 assert r
529 assert r
529 c = Changeset.new(:repository => r,
530 c = Changeset.new(:repository => r,
530 :committed_on => Time.now,
531 :committed_on => Time.now,
531 :revision => '123',
532 :revision => '123',
532 :scmid => '20080308225258-98289-abcd456efg.gz',
533 :scmid => '20080308225258-98289-abcd456efg.gz',
533 :comments => 'test commit')
534 :comments => 'test commit')
534 assert( c.save )
535 assert( c.save )
535 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
536 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
536 end
537 end
537
538
538 def test_redmine_links_mercurial_commit
539 def test_redmine_links_mercurial_commit
539 changeset_link_rev = link_to('r123',
540 changeset_link_rev = link_to('r123',
540 {
541 {
541 :controller => 'repositories',
542 :controller => 'repositories',
542 :action => 'revision',
543 :action => 'revision',
543 :id => 'subproject1',
544 :id => 'subproject1',
544 :rev => '123' ,
545 :rev => '123' ,
545 },
546 },
546 :class => 'changeset', :title => 'test commit')
547 :class => 'changeset', :title => 'test commit')
547 changeset_link_commit = link_to('abcd',
548 changeset_link_commit = link_to('abcd',
548 {
549 {
549 :controller => 'repositories',
550 :controller => 'repositories',
550 :action => 'revision',
551 :action => 'revision',
551 :id => 'subproject1',
552 :id => 'subproject1',
552 :rev => 'abcd' ,
553 :rev => 'abcd' ,
553 },
554 },
554 :class => 'changeset', :title => 'test commit')
555 :class => 'changeset', :title => 'test commit')
555 to_test = {
556 to_test = {
556 'r123' => changeset_link_rev,
557 'r123' => changeset_link_rev,
557 'commit:abcd' => changeset_link_commit,
558 'commit:abcd' => changeset_link_commit,
558 }
559 }
559 @project = Project.find(3)
560 @project = Project.find(3)
560 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
561 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
561 assert r
562 assert r
562 c = Changeset.new(:repository => r,
563 c = Changeset.new(:repository => r,
563 :committed_on => Time.now,
564 :committed_on => Time.now,
564 :revision => '123',
565 :revision => '123',
565 :scmid => 'abcd',
566 :scmid => 'abcd',
566 :comments => 'test commit')
567 :comments => 'test commit')
567 assert( c.save )
568 assert( c.save )
568 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
569 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
569 end
570 end
570
571
571 def test_attachment_links
572 def test_attachment_links
572 to_test = {
573 to_test = {
573 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
574 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
574 }
575 }
575 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
576 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
576 end
577 end
577
578
578 def test_attachment_link_should_link_to_latest_attachment
579 def test_attachment_link_should_link_to_latest_attachment
579 set_tmp_attachments_directory
580 set_tmp_attachments_directory
580 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
581 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
581 a2 = Attachment.generate!(:filename => "test.txt")
582 a2 = Attachment.generate!(:filename => "test.txt")
582
583
583 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
584 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
584 textilizable('attachment:test.txt', :attachments => [a1, a2])
585 textilizable('attachment:test.txt', :attachments => [a1, a2])
585 end
586 end
586
587
587 def test_wiki_links
588 def test_wiki_links
588 to_test = {
589 to_test = {
589 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
590 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
590 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
591 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
591 # title content should be formatted
592 # title content should be formatted
592 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
593 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
593 '[[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>',
594 '[[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>',
594 # link with anchor
595 # link with anchor
595 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
596 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
596 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
597 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
597 # UTF8 anchor
598 # UTF8 anchor
598 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
599 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
599 # page that doesn't exist
600 # page that doesn't exist
600 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
601 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
601 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
602 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
602 # link to another project wiki
603 # link to another project wiki
603 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
604 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
604 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
605 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
605 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
606 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
606 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
607 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
607 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 # striked through link
609 # striked through link
609 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
610 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
610 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
611 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
611 # escaping
612 # escaping
612 '![[Another page|Page]]' => '[[Another page|Page]]',
613 '![[Another page|Page]]' => '[[Another page|Page]]',
613 # project does not exist
614 # project does not exist
614 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
615 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
615 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
616 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
616 }
617 }
617
618
618 @project = Project.find(1)
619 @project = Project.find(1)
619 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
620 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
620 end
621 end
621
622
622 def test_wiki_links_within_local_file_generation_context
623 def test_wiki_links_within_local_file_generation_context
623
624
624 to_test = {
625 to_test = {
625 # link to a page
626 # link to a page
626 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
627 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
627 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
628 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
628 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
629 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
629 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
630 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
630 # page that doesn't exist
631 # page that doesn't exist
631 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
632 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
632 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
633 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
633 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
634 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
634 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
635 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
635 }
636 }
636
637
637 @project = Project.find(1)
638 @project = Project.find(1)
638
639
639 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
640 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
640 end
641 end
641
642
642 def test_wiki_links_within_wiki_page_context
643 def test_wiki_links_within_wiki_page_context
643
644
644 page = WikiPage.find_by_title('Another_page' )
645 page = WikiPage.find_by_title('Another_page' )
645
646
646 to_test = {
647 to_test = {
647 # link to another page
648 # link to another page
648 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
649 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
649 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
650 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
650 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
651 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
651 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
652 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
652 # link to the current page
653 # link to the current page
653 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
654 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
654 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
655 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
655 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
656 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
656 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
657 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
657 # page that doesn't exist
658 # page that doesn't exist
658 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
659 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
659 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
660 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
660 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
661 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
661 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
662 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
662 }
663 }
663
664
664 @project = Project.find(1)
665 @project = Project.find(1)
665
666
666 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
667 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
667 end
668 end
668
669
669 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
670 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
670
671
671 to_test = {
672 to_test = {
672 # link to a page
673 # link to a page
673 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
674 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
674 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
675 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
675 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
676 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
676 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
677 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
677 # page that doesn't exist
678 # page that doesn't exist
678 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
679 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
679 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
680 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
680 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
681 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
681 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
682 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
682 }
683 }
683
684
684 @project = Project.find(1)
685 @project = Project.find(1)
685
686
686 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
687 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
687 end
688 end
688
689
689 def test_html_tags
690 def test_html_tags
690 to_test = {
691 to_test = {
691 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
692 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
692 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
693 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
693 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
694 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
694 # do not escape pre/code tags
695 # do not escape pre/code tags
695 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
696 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
696 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
697 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
697 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
698 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
698 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
699 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
699 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
700 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
700 # remove attributes except class
701 # remove attributes except class
701 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
702 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
702 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
703 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
703 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
704 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
704 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
705 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
705 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
706 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
706 # xss
707 # xss
707 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
708 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
708 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
709 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
709 }
710 }
710 to_test.each { |text, result| assert_equal result, textilizable(text) }
711 to_test.each { |text, result| assert_equal result, textilizable(text) }
711 end
712 end
712
713
713 def test_allowed_html_tags
714 def test_allowed_html_tags
714 to_test = {
715 to_test = {
715 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
716 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
716 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
717 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
717 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
718 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
718 }
719 }
719 to_test.each { |text, result| assert_equal result, textilizable(text) }
720 to_test.each { |text, result| assert_equal result, textilizable(text) }
720 end
721 end
721
722
722 def test_pre_tags
723 def test_pre_tags
723 raw = <<-RAW
724 raw = <<-RAW
724 Before
725 Before
725
726
726 <pre>
727 <pre>
727 <prepared-statement-cache-size>32</prepared-statement-cache-size>
728 <prepared-statement-cache-size>32</prepared-statement-cache-size>
728 </pre>
729 </pre>
729
730
730 After
731 After
731 RAW
732 RAW
732
733
733 expected = <<-EXPECTED
734 expected = <<-EXPECTED
734 <p>Before</p>
735 <p>Before</p>
735 <pre>
736 <pre>
736 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
737 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
737 </pre>
738 </pre>
738 <p>After</p>
739 <p>After</p>
739 EXPECTED
740 EXPECTED
740
741
741 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
742 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
742 end
743 end
743
744
744 def test_pre_content_should_not_parse_wiki_and_redmine_links
745 def test_pre_content_should_not_parse_wiki_and_redmine_links
745 raw = <<-RAW
746 raw = <<-RAW
746 [[CookBook documentation]]
747 [[CookBook documentation]]
747
748
748 #1
749 #1
749
750
750 <pre>
751 <pre>
751 [[CookBook documentation]]
752 [[CookBook documentation]]
752
753
753 #1
754 #1
754 </pre>
755 </pre>
755 RAW
756 RAW
756
757
757 expected = <<-EXPECTED
758 expected = <<-EXPECTED
758 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
759 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
759 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
760 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
760 <pre>
761 <pre>
761 [[CookBook documentation]]
762 [[CookBook documentation]]
762
763
763 #1
764 #1
764 </pre>
765 </pre>
765 EXPECTED
766 EXPECTED
766
767
767 @project = Project.find(1)
768 @project = Project.find(1)
768 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
769 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
769 end
770 end
770
771
771 def test_non_closing_pre_blocks_should_be_closed
772 def test_non_closing_pre_blocks_should_be_closed
772 raw = <<-RAW
773 raw = <<-RAW
773 <pre><code>
774 <pre><code>
774 RAW
775 RAW
775
776
776 expected = <<-EXPECTED
777 expected = <<-EXPECTED
777 <pre><code>
778 <pre><code>
778 </code></pre>
779 </code></pre>
779 EXPECTED
780 EXPECTED
780
781
781 @project = Project.find(1)
782 @project = Project.find(1)
782 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
783 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
783 end
784 end
784
785
785 def test_syntax_highlight
786 def test_syntax_highlight
786 raw = <<-RAW
787 raw = <<-RAW
787 <pre><code class="ruby">
788 <pre><code class="ruby">
788 # Some ruby code here
789 # Some ruby code here
789 </code></pre>
790 </code></pre>
790 RAW
791 RAW
791
792
792 expected = <<-EXPECTED
793 expected = <<-EXPECTED
793 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
794 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
794 </code></pre>
795 </code></pre>
795 EXPECTED
796 EXPECTED
796
797
797 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
798 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
798 end
799 end
799
800
800 def test_to_path_param
801 def test_to_path_param
801 assert_equal 'test1/test2', to_path_param('test1/test2')
802 assert_equal 'test1/test2', to_path_param('test1/test2')
802 assert_equal 'test1/test2', to_path_param('/test1/test2/')
803 assert_equal 'test1/test2', to_path_param('/test1/test2/')
803 assert_equal 'test1/test2', to_path_param('//test1/test2/')
804 assert_equal 'test1/test2', to_path_param('//test1/test2/')
804 assert_equal nil, to_path_param('/')
805 assert_equal nil, to_path_param('/')
805 end
806 end
806
807
807 def test_wiki_links_in_tables
808 def test_wiki_links_in_tables
808 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
809 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
809 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
810 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
810 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
811 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
811 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
812 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
812 }
813 }
813 @project = Project.find(1)
814 @project = Project.find(1)
814 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
815 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
815 end
816 end
816
817
817 def test_text_formatting
818 def test_text_formatting
818 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
819 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
819 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
820 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
820 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
821 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
821 '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>',
822 '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>',
822 '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',
823 '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',
823 }
824 }
824 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
825 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
825 end
826 end
826
827
827 def test_wiki_horizontal_rule
828 def test_wiki_horizontal_rule
828 assert_equal '<hr />', textilizable('---')
829 assert_equal '<hr />', textilizable('---')
829 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
830 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
830 end
831 end
831
832
832 def test_footnotes
833 def test_footnotes
833 raw = <<-RAW
834 raw = <<-RAW
834 This is some text[1].
835 This is some text[1].
835
836
836 fn1. This is the foot note
837 fn1. This is the foot note
837 RAW
838 RAW
838
839
839 expected = <<-EXPECTED
840 expected = <<-EXPECTED
840 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
841 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
841 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
842 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
842 EXPECTED
843 EXPECTED
843
844
844 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
845 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
845 end
846 end
846
847
847 def test_headings
848 def test_headings
848 raw = 'h1. Some heading'
849 raw = 'h1. Some heading'
849 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
850 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
850
851
851 assert_equal expected, textilizable(raw)
852 assert_equal expected, textilizable(raw)
852 end
853 end
853
854
854 def test_headings_with_special_chars
855 def test_headings_with_special_chars
855 # This test makes sure that the generated anchor names match the expected
856 # This test makes sure that the generated anchor names match the expected
856 # ones even if the heading text contains unconventional characters
857 # ones even if the heading text contains unconventional characters
857 raw = 'h1. Some heading related to version 0.5'
858 raw = 'h1. Some heading related to version 0.5'
858 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
859 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
859 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
860 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
860
861
861 assert_equal expected, textilizable(raw)
862 assert_equal expected, textilizable(raw)
862 end
863 end
863
864
864 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
865 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
865 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
866 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
866 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
867 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
867
868
868 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
869 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
869
870
870 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
871 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
871 end
872 end
872
873
873 def test_table_of_content
874 def test_table_of_content
874 raw = <<-RAW
875 raw = <<-RAW
875 {{toc}}
876 {{toc}}
876
877
877 h1. Title
878 h1. Title
878
879
879 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
880 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
880
881
881 h2. Subtitle with a [[Wiki]] link
882 h2. Subtitle with a [[Wiki]] link
882
883
883 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
884 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
884
885
885 h2. Subtitle with [[Wiki|another Wiki]] link
886 h2. Subtitle with [[Wiki|another Wiki]] link
886
887
887 h2. Subtitle with %{color:red}red text%
888 h2. Subtitle with %{color:red}red text%
888
889
889 <pre>
890 <pre>
890 some code
891 some code
891 </pre>
892 </pre>
892
893
893 h3. Subtitle with *some* _modifiers_
894 h3. Subtitle with *some* _modifiers_
894
895
895 h3. Subtitle with @inline code@
896 h3. Subtitle with @inline code@
896
897
897 h1. Another title
898 h1. Another title
898
899
899 h3. An "Internet link":http://www.redmine.org/ inside subtitle
900 h3. An "Internet link":http://www.redmine.org/ inside subtitle
900
901
901 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
902 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
902
903
903 RAW
904 RAW
904
905
905 expected = '<ul class="toc">' +
906 expected = '<ul class="toc">' +
906 '<li><a href="#Title">Title</a>' +
907 '<li><a href="#Title">Title</a>' +
907 '<ul>' +
908 '<ul>' +
908 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
909 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
909 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
910 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
910 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
911 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
911 '<ul>' +
912 '<ul>' +
912 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
913 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
913 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
914 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
914 '</ul>' +
915 '</ul>' +
915 '</li>' +
916 '</li>' +
916 '</ul>' +
917 '</ul>' +
917 '</li>' +
918 '</li>' +
918 '<li><a href="#Another-title">Another title</a>' +
919 '<li><a href="#Another-title">Another title</a>' +
919 '<ul>' +
920 '<ul>' +
920 '<li>' +
921 '<li>' +
921 '<ul>' +
922 '<ul>' +
922 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
923 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
923 '</ul>' +
924 '</ul>' +
924 '</li>' +
925 '</li>' +
925 '<li><a href="#Project-Name">Project Name</a></li>' +
926 '<li><a href="#Project-Name">Project Name</a></li>' +
926 '</ul>' +
927 '</ul>' +
927 '</li>' +
928 '</li>' +
928 '</ul>'
929 '</ul>'
929
930
930 @project = Project.find(1)
931 @project = Project.find(1)
931 assert textilizable(raw).gsub("\n", "").include?(expected)
932 assert textilizable(raw).gsub("\n", "").include?(expected)
932 end
933 end
933
934
934 def test_table_of_content_should_generate_unique_anchors
935 def test_table_of_content_should_generate_unique_anchors
935 raw = <<-RAW
936 raw = <<-RAW
936 {{toc}}
937 {{toc}}
937
938
938 h1. Title
939 h1. Title
939
940
940 h2. Subtitle
941 h2. Subtitle
941
942
942 h2. Subtitle
943 h2. Subtitle
943 RAW
944 RAW
944
945
945 expected = '<ul class="toc">' +
946 expected = '<ul class="toc">' +
946 '<li><a href="#Title">Title</a>' +
947 '<li><a href="#Title">Title</a>' +
947 '<ul>' +
948 '<ul>' +
948 '<li><a href="#Subtitle">Subtitle</a></li>' +
949 '<li><a href="#Subtitle">Subtitle</a></li>' +
949 '<li><a href="#Subtitle-2">Subtitle</a></li>'
950 '<li><a href="#Subtitle-2">Subtitle</a></li>'
950 '</ul>'
951 '</ul>'
951 '</li>' +
952 '</li>' +
952 '</ul>'
953 '</ul>'
953
954
954 @project = Project.find(1)
955 @project = Project.find(1)
955 result = textilizable(raw).gsub("\n", "")
956 result = textilizable(raw).gsub("\n", "")
956 assert_include expected, result
957 assert_include expected, result
957 assert_include '<a name="Subtitle">', result
958 assert_include '<a name="Subtitle">', result
958 assert_include '<a name="Subtitle-2">', result
959 assert_include '<a name="Subtitle-2">', result
959 end
960 end
960
961
961 def test_table_of_content_should_contain_included_page_headings
962 def test_table_of_content_should_contain_included_page_headings
962 raw = <<-RAW
963 raw = <<-RAW
963 {{toc}}
964 {{toc}}
964
965
965 h1. Included
966 h1. Included
966
967
967 {{include(Child_1)}}
968 {{include(Child_1)}}
968 RAW
969 RAW
969
970
970 expected = '<ul class="toc">' +
971 expected = '<ul class="toc">' +
971 '<li><a href="#Included">Included</a></li>' +
972 '<li><a href="#Included">Included</a></li>' +
972 '<li><a href="#Child-page-1">Child page 1</a></li>' +
973 '<li><a href="#Child-page-1">Child page 1</a></li>' +
973 '</ul>'
974 '</ul>'
974
975
975 @project = Project.find(1)
976 @project = Project.find(1)
976 assert textilizable(raw).gsub("\n", "").include?(expected)
977 assert textilizable(raw).gsub("\n", "").include?(expected)
977 end
978 end
978
979
979 def test_section_edit_links
980 def test_section_edit_links
980 raw = <<-RAW
981 raw = <<-RAW
981 h1. Title
982 h1. Title
982
983
983 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
984 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
984
985
985 h2. Subtitle with a [[Wiki]] link
986 h2. Subtitle with a [[Wiki]] link
986
987
987 h2. Subtitle with *some* _modifiers_
988 h2. Subtitle with *some* _modifiers_
988
989
989 h2. Subtitle with @inline code@
990 h2. Subtitle with @inline code@
990
991
991 <pre>
992 <pre>
992 some code
993 some code
993
994
994 h2. heading inside pre
995 h2. heading inside pre
995
996
996 <h2>html heading inside pre</h2>
997 <h2>html heading inside pre</h2>
997 </pre>
998 </pre>
998
999
999 h2. Subtitle after pre tag
1000 h2. Subtitle after pre tag
1000 RAW
1001 RAW
1001
1002
1002 @project = Project.find(1)
1003 @project = Project.find(1)
1003 set_language_if_valid 'en'
1004 set_language_if_valid 'en'
1004 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1005 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1005
1006
1006 # heading that contains inline code
1007 # heading that contains inline code
1007 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1008 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1008 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1009 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1009 '<a name="Subtitle-with-inline-code"></a>' +
1010 '<a name="Subtitle-with-inline-code"></a>' +
1010 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1011 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1011 result
1012 result
1012
1013
1013 # last heading
1014 # last heading
1014 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1015 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1015 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1016 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1016 '<a name="Subtitle-after-pre-tag"></a>' +
1017 '<a name="Subtitle-after-pre-tag"></a>' +
1017 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1018 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1018 result
1019 result
1019 end
1020 end
1020
1021
1021 def test_default_formatter
1022 def test_default_formatter
1022 with_settings :text_formatting => 'unknown' do
1023 with_settings :text_formatting => 'unknown' do
1023 text = 'a *link*: http://www.example.net/'
1024 text = 'a *link*: http://www.example.net/'
1024 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1025 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1025 end
1026 end
1026 end
1027 end
1027
1028
1028 def test_due_date_distance_in_words
1029 def test_due_date_distance_in_words
1029 to_test = { Date.today => 'Due in 0 days',
1030 to_test = { Date.today => 'Due in 0 days',
1030 Date.today + 1 => 'Due in 1 day',
1031 Date.today + 1 => 'Due in 1 day',
1031 Date.today + 100 => 'Due in about 3 months',
1032 Date.today + 100 => 'Due in about 3 months',
1032 Date.today + 20000 => 'Due in over 54 years',
1033 Date.today + 20000 => 'Due in over 54 years',
1033 Date.today - 1 => '1 day late',
1034 Date.today - 1 => '1 day late',
1034 Date.today - 100 => 'about 3 months late',
1035 Date.today - 100 => 'about 3 months late',
1035 Date.today - 20000 => 'over 54 years late',
1036 Date.today - 20000 => 'over 54 years late',
1036 }
1037 }
1037 ::I18n.locale = :en
1038 ::I18n.locale = :en
1038 to_test.each do |date, expected|
1039 to_test.each do |date, expected|
1039 assert_equal expected, due_date_distance_in_words(date)
1040 assert_equal expected, due_date_distance_in_words(date)
1040 end
1041 end
1041 end
1042 end
1042
1043
1043 def test_avatar_enabled
1044 def test_avatar_enabled
1044 with_settings :gravatar_enabled => '1' do
1045 with_settings :gravatar_enabled => '1' do
1045 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1046 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1046 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1047 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1047 # Default size is 50
1048 # Default size is 50
1048 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1049 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1049 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1050 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1050 # Non-avatar options should be considered html options
1051 # Non-avatar options should be considered html options
1051 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1052 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1052 # The default class of the img tag should be gravatar
1053 # The default class of the img tag should be gravatar
1053 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1054 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1054 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1055 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1055 assert_nil avatar('jsmith')
1056 assert_nil avatar('jsmith')
1056 assert_nil avatar(nil)
1057 assert_nil avatar(nil)
1057 end
1058 end
1058 end
1059 end
1059
1060
1060 def test_avatar_disabled
1061 def test_avatar_disabled
1061 with_settings :gravatar_enabled => '0' do
1062 with_settings :gravatar_enabled => '0' do
1062 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1063 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1063 end
1064 end
1064 end
1065 end
1065
1066
1066 def test_link_to_user
1067 def test_link_to_user
1067 user = User.find(2)
1068 user = User.find(2)
1068 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1069 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1069 end
1070 end
1070
1071
1071 def test_link_to_user_should_not_link_to_locked_user
1072 def test_link_to_user_should_not_link_to_locked_user
1072 with_current_user nil do
1073 with_current_user nil do
1073 user = User.find(5)
1074 user = User.find(5)
1074 assert user.locked?
1075 assert user.locked?
1075 assert_equal 'Dave2 Lopper2', link_to_user(user)
1076 assert_equal 'Dave2 Lopper2', link_to_user(user)
1076 end
1077 end
1077 end
1078 end
1078
1079
1079 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1080 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1080 with_current_user User.find(1) do
1081 with_current_user User.find(1) do
1081 user = User.find(5)
1082 user = User.find(5)
1082 assert user.locked?
1083 assert user.locked?
1083 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1084 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1084 end
1085 end
1085 end
1086 end
1086
1087
1087 def test_link_to_user_should_not_link_to_anonymous
1088 def test_link_to_user_should_not_link_to_anonymous
1088 user = User.anonymous
1089 user = User.anonymous
1089 assert user.anonymous?
1090 assert user.anonymous?
1090 t = link_to_user(user)
1091 t = link_to_user(user)
1091 assert_equal ::I18n.t(:label_user_anonymous), t
1092 assert_equal ::I18n.t(:label_user_anonymous), t
1092 end
1093 end
1093
1094
1094 def test_link_to_attachment
1095 def test_link_to_attachment
1095 a = Attachment.find(3)
1096 a = Attachment.find(3)
1096 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1097 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1097 link_to_attachment(a)
1098 link_to_attachment(a)
1098 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1099 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1099 link_to_attachment(a, :text => 'Text')
1100 link_to_attachment(a, :text => 'Text')
1100 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1101 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1101 link_to_attachment(a, :class => 'foo')
1102 link_to_attachment(a, :class => 'foo')
1102 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1103 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1103 link_to_attachment(a, :download => true)
1104 link_to_attachment(a, :download => true)
1104 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1105 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1105 link_to_attachment(a, :only_path => false)
1106 link_to_attachment(a, :only_path => false)
1106 end
1107 end
1107
1108
1108 def test_thumbnail_tag
1109 def test_thumbnail_tag
1109 a = Attachment.find(3)
1110 a = Attachment.find(3)
1110 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1111 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1111 thumbnail_tag(a)
1112 thumbnail_tag(a)
1112 end
1113 end
1113
1114
1114 def test_link_to_project
1115 def test_link_to_project
1115 project = Project.find(1)
1116 project = Project.find(1)
1116 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1117 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1117 link_to_project(project)
1118 link_to_project(project)
1118 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1119 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1119 link_to_project(project, :action => 'settings')
1120 link_to_project(project, :action => 'settings')
1120 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1121 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1121 link_to_project(project, {:only_path => false, :jump => 'blah'})
1122 link_to_project(project, {:only_path => false, :jump => 'blah'})
1122 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1123 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1123 link_to_project(project, {:action => 'settings'}, :class => "project")
1124 link_to_project(project, {:action => 'settings'}, :class => "project")
1124 end
1125 end
1125
1126
1126 def test_link_to_project_settings
1127 def test_link_to_project_settings
1127 project = Project.find(1)
1128 project = Project.find(1)
1128 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1129 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1129
1130
1130 project.status = Project::STATUS_CLOSED
1131 project.status = Project::STATUS_CLOSED
1131 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1132 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1132
1133
1133 project.status = Project::STATUS_ARCHIVED
1134 project.status = Project::STATUS_ARCHIVED
1134 assert_equal 'eCookbook', link_to_project_settings(project)
1135 assert_equal 'eCookbook', link_to_project_settings(project)
1135 end
1136 end
1136
1137
1137 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1138 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1138 # numeric identifier are no longer allowed
1139 # numeric identifier are no longer allowed
1139 Project.update_all "identifier=25", "id=1"
1140 Project.update_all "identifier=25", "id=1"
1140
1141
1141 assert_equal '<a href="/projects/1">eCookbook</a>',
1142 assert_equal '<a href="/projects/1">eCookbook</a>',
1142 link_to_project(Project.find(1))
1143 link_to_project(Project.find(1))
1143 end
1144 end
1144
1145
1145 def test_principals_options_for_select_with_users
1146 def test_principals_options_for_select_with_users
1146 User.current = nil
1147 User.current = nil
1147 users = [User.find(2), User.find(4)]
1148 users = [User.find(2), User.find(4)]
1148 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1149 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1149 principals_options_for_select(users)
1150 principals_options_for_select(users)
1150 end
1151 end
1151
1152
1152 def test_principals_options_for_select_with_selected
1153 def test_principals_options_for_select_with_selected
1153 User.current = nil
1154 User.current = nil
1154 users = [User.find(2), User.find(4)]
1155 users = [User.find(2), User.find(4)]
1155 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1156 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1156 principals_options_for_select(users, User.find(4))
1157 principals_options_for_select(users, User.find(4))
1157 end
1158 end
1158
1159
1159 def test_principals_options_for_select_with_users_and_groups
1160 def test_principals_options_for_select_with_users_and_groups
1160 User.current = nil
1161 User.current = nil
1161 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1162 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1162 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1163 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1163 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1164 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1164 principals_options_for_select(users)
1165 principals_options_for_select(users)
1165 end
1166 end
1166
1167
1167 def test_principals_options_for_select_with_empty_collection
1168 def test_principals_options_for_select_with_empty_collection
1168 assert_equal '', principals_options_for_select([])
1169 assert_equal '', principals_options_for_select([])
1169 end
1170 end
1170
1171
1171 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1172 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1172 users = [User.find(2), User.find(4)]
1173 users = [User.find(2), User.find(4)]
1173 User.current = User.find(4)
1174 User.current = User.find(4)
1174 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1175 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1175 end
1176 end
1176
1177
1177 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1178 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1178 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1179 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1179 end
1180 end
1180
1181
1181 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1182 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1182 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1183 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1183 end
1184 end
1184
1185
1185 def test_image_tag_should_pick_the_default_image
1186 def test_image_tag_should_pick_the_default_image
1186 assert_match 'src="/images/image.png"', image_tag("image.png")
1187 assert_match 'src="/images/image.png"', image_tag("image.png")
1187 end
1188 end
1188
1189
1189 def test_image_tag_should_pick_the_theme_image_if_it_exists
1190 def test_image_tag_should_pick_the_theme_image_if_it_exists
1190 theme = Redmine::Themes.themes.last
1191 theme = Redmine::Themes.themes.last
1191 theme.images << 'image.png'
1192 theme.images << 'image.png'
1192
1193
1193 with_settings :ui_theme => theme.id do
1194 with_settings :ui_theme => theme.id do
1194 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1195 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1195 assert_match %|src="/images/other.png"|, image_tag("other.png")
1196 assert_match %|src="/images/other.png"|, image_tag("other.png")
1196 end
1197 end
1197 ensure
1198 ensure
1198 theme.images.delete 'image.png'
1199 theme.images.delete 'image.png'
1199 end
1200 end
1200
1201
1201 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1202 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1202 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1203 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1203 end
1204 end
1204
1205
1205 def test_javascript_include_tag_should_pick_the_default_javascript
1206 def test_javascript_include_tag_should_pick_the_default_javascript
1206 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1207 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1207 end
1208 end
1208
1209
1209 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1210 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1210 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1211 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1211 end
1212 end
1212 end
1213 end
General Comments 0
You need to be logged in to leave comments. Login now