##// END OF EJS Templates
fix test failure (#13405)...
Toshi MARUYAMA -
r11442:31590e307a39
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 id: 100
7 id: 100
7 comments: My very first commit
8 comments: 'do not escaping #<>&'
8 repository_id: 10
9 repository_id: 10
9 committer: dlopper
10 committer: dlopper
10 user_id: 3
11 user_id: 3
11 changesets_002:
12 changesets_002:
12 commit_date: 2007-04-12
13 commit_date: 2007-04-12
13 committed_on: 2007-04-12 15:14:44 +02:00
14 committed_on: 2007-04-12 15:14:44 +02:00
14 revision: 2
15 revision: 2
15 id: 101
16 id: 101
16 scmid: 691322a8eb01e11fd7
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,1212
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 => 'My very first commit')
268 :class => 'changeset', :title => '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 => 2},
272 changeset_link2 = link_to('691322a8eb01e11fd7', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
273 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
273 :class => 'changeset', :title => 'do not escaping #<>&')
274
274
275 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
275 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
276 :class => 'document')
276 :class => 'document')
277
277
278 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
278 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
279 :class => 'version')
279 :class => 'version')
280
280
281 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
281 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
282
282
283 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
283 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
284
284
285 news_url = {:controller => 'news', :action => 'show', :id => 1}
285 news_url = {:controller => 'news', :action => 'show', :id => 1}
286
286
287 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
287 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
288
288
289 source_url = '/projects/ecookbook/repository/entry/some/file'
289 source_url = '/projects/ecookbook/repository/entry/some/file'
290 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
290 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
291 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
291 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'
292 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'
293 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
294
294
295 export_url = '/projects/ecookbook/repository/raw/some/file'
295 export_url = '/projects/ecookbook/repository/raw/some/file'
296 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
296 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
297 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
297 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'
298 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'
299 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
300
300
301 to_test = {
301 to_test = {
302 # tickets
302 # tickets
303 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
303 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
304 # ticket notes
304 # ticket notes
305 '#3-14' => note_link,
305 '#3-14' => note_link,
306 '#3#note-14' => note_link,
306 '#3#note-14' => note_link,
307 # should not ignore leading zero
307 # should not ignore leading zero
308 '#03' => '#03',
308 '#03' => '#03',
309 # changesets
309 # changesets
310 'r1' => revision_link,
310 'r1' => revision_link,
311 'r1.' => "#{revision_link}.",
311 'r1.' => "#{revision_link}.",
312 'r1, r2' => "#{revision_link}, #{revision_link2}",
312 'r1, r2' => "#{revision_link}, #{revision_link2}",
313 'r1,r2' => "#{revision_link},#{revision_link2}",
313 'r1,r2' => "#{revision_link},#{revision_link2}",
314 'commit:691322a8eb01e11fd7' => changeset_link2,
314 'commit:691322a8eb01e11fd7' => changeset_link2,
315 # documents
315 # documents
316 'document#1' => document_link,
316 'document#1' => document_link,
317 'document:"Test document"' => document_link,
317 'document:"Test document"' => document_link,
318 # versions
318 # versions
319 'version#2' => version_link,
319 'version#2' => version_link,
320 'version:1.0' => version_link,
320 'version:1.0' => version_link,
321 'version:"1.0"' => version_link,
321 'version:"1.0"' => version_link,
322 # source
322 # source
323 'source:some/file' => link_to('source:some/file', source_url, :class => '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.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
326 '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') + ".",
327 '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') + ".",
328 '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') + ",",
329 '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'),
330 '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'),
331 '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'),
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#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
333 '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'),
334 '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'),
335 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
336 # export
336 # export
337 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
337 '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'),
338 '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'),
339 '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'),
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@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
341 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
342 # forum
342 # forum
343 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
343 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
344 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
344 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
345 # message
345 # message
346 'message#4' => link_to('Post 2', message_url, :class => 'message'),
346 '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'),
347 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
348 # news
348 # news
349 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
349 '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'),
350 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
351 # project
351 # project
352 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
352 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 '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'),
354 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
355 # not found
355 # not found
356 '#0123456789' => '#0123456789',
356 '#0123456789' => '#0123456789',
357 # invalid expressions
357 # invalid expressions
358 'source:' => 'source:',
358 'source:' => 'source:',
359 # url hash
359 # url hash
360 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
360 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
361 }
361 }
362 @project = Project.find(1)
362 @project = Project.find(1)
363 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
363 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
364 end
364 end
365
365
366 def test_redmine_links_with_a_different_project_before_current_project
366 def test_redmine_links_with_a_different_project_before_current_project
367 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
367 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
368 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
368 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
369
369
370 @project = Project.find(3)
370 @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>),
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 textilizable("ecookbook:version:1.4.4 version:1.4.4")
372 textilizable("ecookbook:version:1.4.4 version:1.4.4")
373 end
373 end
374
374
375 def test_escaped_redmine_links_should_not_be_parsed
375 def test_escaped_redmine_links_should_not_be_parsed
376 to_test = [
376 to_test = [
377 '#3.',
377 '#3.',
378 '#3-14.',
378 '#3-14.',
379 '#3#-note14.',
379 '#3#-note14.',
380 'r1',
380 'r1',
381 'document#1',
381 'document#1',
382 'document:"Test document"',
382 'document:"Test document"',
383 'version#2',
383 'version#2',
384 'version:1.0',
384 'version:1.0',
385 'version:"1.0"',
385 'version:"1.0"',
386 'source:/some/file'
386 'source:/some/file'
387 ]
387 ]
388 @project = Project.find(1)
388 @project = Project.find(1)
389 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
389 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
390 end
390 end
391
391
392 def test_cross_project_redmine_links
392 def test_cross_project_redmine_links
393 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
393 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
394 :class => 'source')
394 :class => 'source')
395
395
396 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
396 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')
397 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
398
398
399 to_test = {
399 to_test = {
400 # documents
400 # documents
401 'document:"Test document"' => 'document:"Test document"',
401 'document:"Test document"' => 'document:"Test document"',
402 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
402 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
403 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
403 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
404 # versions
404 # versions
405 'version:"1.0"' => 'version:"1.0"',
405 'version:"1.0"' => 'version:"1.0"',
406 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
406 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
407 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
407 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
408 # changeset
408 # changeset
409 'r2' => 'r2',
409 'r2' => 'r2',
410 'ecookbook:r2' => changeset_link,
410 'ecookbook:r2' => changeset_link,
411 'invalid:r2' => 'invalid:r2',
411 'invalid:r2' => 'invalid:r2',
412 # source
412 # source
413 'source:/some/file' => 'source:/some/file',
413 'source:/some/file' => 'source:/some/file',
414 'ecookbook:source:/some/file' => source_link,
414 'ecookbook:source:/some/file' => source_link,
415 'invalid:source:/some/file' => 'invalid:source:/some/file',
415 'invalid:source:/some/file' => 'invalid:source:/some/file',
416 }
416 }
417 @project = Project.find(3)
417 @project = Project.find(3)
418 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
418 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
419 end
419 end
420
420
421 def test_multiple_repositories_redmine_links
421 def test_multiple_repositories_redmine_links
422 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
422 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')
423 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
424 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
424 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')
425 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
426
426
427 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
427 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')
428 :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},
429 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 => '')
430 :class => 'changeset', :title => '')
431 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
431 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
432 :class => 'changeset', :title => '')
432 :class => 'changeset', :title => '')
433
433
434 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
434 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')
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
436
437 to_test = {
437 to_test = {
438 'r2' => changeset_link,
438 'r2' => changeset_link,
439 'svn_repo-1|r123' => svn_changeset_link,
439 'svn_repo-1|r123' => svn_changeset_link,
440 'invalid|r123' => 'invalid|r123',
440 'invalid|r123' => 'invalid|r123',
441 'commit:hg1|abcd' => hg_changeset_link,
441 'commit:hg1|abcd' => hg_changeset_link,
442 'commit:invalid|abcd' => 'commit:invalid|abcd',
442 'commit:invalid|abcd' => 'commit:invalid|abcd',
443 # source
443 # source
444 'source:some/file' => source_link,
444 'source:some/file' => source_link,
445 'source:hg1|some/file' => hg_source_link,
445 'source:hg1|some/file' => hg_source_link,
446 'source:invalid|some/file' => 'source:invalid|some/file',
446 'source:invalid|some/file' => 'source:invalid|some/file',
447 }
447 }
448
448
449 @project = Project.find(1)
449 @project = Project.find(1)
450 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
450 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
451 end
451 end
452
452
453 def test_cross_project_multiple_repositories_redmine_links
453 def test_cross_project_multiple_repositories_redmine_links
454 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
454 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
455 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
455 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
456 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
456 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')
457 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
458
458
459 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
459 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')
460 :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},
461 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
462 :class => 'changeset', :title => '')
462 :class => 'changeset', :title => '')
463 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
463 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
464 :class => 'changeset', :title => '')
464 :class => 'changeset', :title => '')
465
465
466 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
466 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')
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
468
469 to_test = {
469 to_test = {
470 'ecookbook:r2' => changeset_link,
470 'ecookbook:r2' => changeset_link,
471 'ecookbook:svn1|r123' => svn_changeset_link,
471 'ecookbook:svn1|r123' => svn_changeset_link,
472 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
472 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
473 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
473 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
474 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
474 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
475 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
475 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
476 # source
476 # source
477 'ecookbook:source:some/file' => source_link,
477 'ecookbook:source:some/file' => source_link,
478 'ecookbook:source:hg1|some/file' => hg_source_link,
478 'ecookbook:source:hg1|some/file' => hg_source_link,
479 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
479 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
480 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
480 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
481 }
481 }
482
482
483 @project = Project.find(3)
483 @project = Project.find(3)
484 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
484 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
485 end
485 end
486
486
487 def test_redmine_links_git_commit
487 def test_redmine_links_git_commit
488 changeset_link = link_to('abcd',
488 changeset_link = link_to('abcd',
489 {
489 {
490 :controller => 'repositories',
490 :controller => 'repositories',
491 :action => 'revision',
491 :action => 'revision',
492 :id => 'subproject1',
492 :id => 'subproject1',
493 :rev => 'abcd',
493 :rev => 'abcd',
494 },
494 },
495 :class => 'changeset', :title => 'test commit')
495 :class => 'changeset', :title => 'test commit')
496 to_test = {
496 to_test = {
497 'commit:abcd' => changeset_link,
497 'commit:abcd' => changeset_link,
498 }
498 }
499 @project = Project.find(3)
499 @project = Project.find(3)
500 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
500 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
501 assert r
501 assert r
502 c = Changeset.new(:repository => r,
502 c = Changeset.new(:repository => r,
503 :committed_on => Time.now,
503 :committed_on => Time.now,
504 :revision => 'abcd',
504 :revision => 'abcd',
505 :scmid => 'abcd',
505 :scmid => 'abcd',
506 :comments => 'test commit')
506 :comments => 'test commit')
507 assert( c.save )
507 assert( c.save )
508 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
508 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
509 end
509 end
510
510
511 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
511 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
512 def test_redmine_links_darcs_commit
512 def test_redmine_links_darcs_commit
513 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
513 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
514 {
514 {
515 :controller => 'repositories',
515 :controller => 'repositories',
516 :action => 'revision',
516 :action => 'revision',
517 :id => 'subproject1',
517 :id => 'subproject1',
518 :rev => '123',
518 :rev => '123',
519 },
519 },
520 :class => 'changeset', :title => 'test commit')
520 :class => 'changeset', :title => 'test commit')
521 to_test = {
521 to_test = {
522 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
522 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
523 }
523 }
524 @project = Project.find(3)
524 @project = Project.find(3)
525 r = Repository::Darcs.create!(
525 r = Repository::Darcs.create!(
526 :project => @project, :url => '/tmp/test/darcs',
526 :project => @project, :url => '/tmp/test/darcs',
527 :log_encoding => 'UTF-8')
527 :log_encoding => 'UTF-8')
528 assert r
528 assert r
529 c = Changeset.new(:repository => r,
529 c = Changeset.new(:repository => r,
530 :committed_on => Time.now,
530 :committed_on => Time.now,
531 :revision => '123',
531 :revision => '123',
532 :scmid => '20080308225258-98289-abcd456efg.gz',
532 :scmid => '20080308225258-98289-abcd456efg.gz',
533 :comments => 'test commit')
533 :comments => 'test commit')
534 assert( c.save )
534 assert( c.save )
535 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
535 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
536 end
536 end
537
537
538 def test_redmine_links_mercurial_commit
538 def test_redmine_links_mercurial_commit
539 changeset_link_rev = link_to('r123',
539 changeset_link_rev = link_to('r123',
540 {
540 {
541 :controller => 'repositories',
541 :controller => 'repositories',
542 :action => 'revision',
542 :action => 'revision',
543 :id => 'subproject1',
543 :id => 'subproject1',
544 :rev => '123' ,
544 :rev => '123' ,
545 },
545 },
546 :class => 'changeset', :title => 'test commit')
546 :class => 'changeset', :title => 'test commit')
547 changeset_link_commit = link_to('abcd',
547 changeset_link_commit = link_to('abcd',
548 {
548 {
549 :controller => 'repositories',
549 :controller => 'repositories',
550 :action => 'revision',
550 :action => 'revision',
551 :id => 'subproject1',
551 :id => 'subproject1',
552 :rev => 'abcd' ,
552 :rev => 'abcd' ,
553 },
553 },
554 :class => 'changeset', :title => 'test commit')
554 :class => 'changeset', :title => 'test commit')
555 to_test = {
555 to_test = {
556 'r123' => changeset_link_rev,
556 'r123' => changeset_link_rev,
557 'commit:abcd' => changeset_link_commit,
557 'commit:abcd' => changeset_link_commit,
558 }
558 }
559 @project = Project.find(3)
559 @project = Project.find(3)
560 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
560 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
561 assert r
561 assert r
562 c = Changeset.new(:repository => r,
562 c = Changeset.new(:repository => r,
563 :committed_on => Time.now,
563 :committed_on => Time.now,
564 :revision => '123',
564 :revision => '123',
565 :scmid => 'abcd',
565 :scmid => 'abcd',
566 :comments => 'test commit')
566 :comments => 'test commit')
567 assert( c.save )
567 assert( c.save )
568 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
568 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
569 end
569 end
570
570
571 def test_attachment_links
571 def test_attachment_links
572 to_test = {
572 to_test = {
573 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
573 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
574 }
574 }
575 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
575 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
576 end
576 end
577
577
578 def test_attachment_link_should_link_to_latest_attachment
578 def test_attachment_link_should_link_to_latest_attachment
579 set_tmp_attachments_directory
579 set_tmp_attachments_directory
580 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
580 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
581 a2 = Attachment.generate!(:filename => "test.txt")
581 a2 = Attachment.generate!(:filename => "test.txt")
582
582
583 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
583 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])
584 textilizable('attachment:test.txt', :attachments => [a1, a2])
585 end
585 end
586
586
587 def test_wiki_links
587 def test_wiki_links
588 to_test = {
588 to_test = {
589 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
589 '[[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>',
590 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
591 # title content should be formatted
591 # 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>',
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 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>',
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 # link with anchor
594 # link with anchor
595 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
595 '[[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>',
596 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
597 # UTF8 anchor
597 # UTF8 anchor
598 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
598 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
599 # page that doesn't exist
599 # page that doesn't exist
600 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
600 '[[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>',
601 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
602 # link to another project wiki
602 # link to another project wiki
603 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
603 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
604 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
604 '[[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>',
605 '[[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>',
606 '[[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>',
607 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 # striked through link
608 # striked through link
609 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
609 '-[[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>',
610 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
611 # escaping
611 # escaping
612 '![[Another page|Page]]' => '[[Another page|Page]]',
612 '![[Another page|Page]]' => '[[Another page|Page]]',
613 # project does not exist
613 # project does not exist
614 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
614 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
615 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
615 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
616 }
616 }
617
617
618 @project = Project.find(1)
618 @project = Project.find(1)
619 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
619 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
620 end
620 end
621
621
622 def test_wiki_links_within_local_file_generation_context
622 def test_wiki_links_within_local_file_generation_context
623
623
624 to_test = {
624 to_test = {
625 # link to a page
625 # link to a page
626 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
626 '[[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>',
627 '[[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>',
628 '[[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>',
629 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
630 # page that doesn't exist
630 # page that doesn't exist
631 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
631 '[[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>',
632 '[[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>',
633 '[[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>',
634 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
635 }
635 }
636
636
637 @project = Project.find(1)
637 @project = Project.find(1)
638
638
639 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
639 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
640 end
640 end
641
641
642 def test_wiki_links_within_wiki_page_context
642 def test_wiki_links_within_wiki_page_context
643
643
644 page = WikiPage.find_by_title('Another_page' )
644 page = WikiPage.find_by_title('Another_page' )
645
645
646 to_test = {
646 to_test = {
647 # link to another page
647 # link to another page
648 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
648 '[[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>',
649 '[[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>',
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|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
651 '[[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
652 # link to the current page
653 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
653 '[[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>',
654 '[[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>',
655 '[[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>',
656 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
657 # page that doesn't exist
657 # 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>',
658 '[[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>',
659 '[[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>',
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|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
661 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
662 }
662 }
663
663
664 @project = Project.find(1)
664 @project = Project.find(1)
665
665
666 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
666 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
667 end
667 end
668
668
669 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
669 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
670
670
671 to_test = {
671 to_test = {
672 # link to a page
672 # link to a page
673 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
673 '[[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>',
674 '[[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>',
675 '[[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>',
676 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
677 # page that doesn't exist
677 # page that doesn't exist
678 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
678 '[[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>',
679 '[[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>',
680 '[[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>',
681 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
682 }
682 }
683
683
684 @project = Project.find(1)
684 @project = Project.find(1)
685
685
686 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
686 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
687 end
687 end
688
688
689 def test_html_tags
689 def test_html_tags
690 to_test = {
690 to_test = {
691 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
691 "<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>",
692 "<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>",
693 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
694 # do not escape pre/code tags
694 # do not escape pre/code tags
695 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
695 "<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>",
696 "<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>",
697 "<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>",
698 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
699 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
699 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
700 # remove attributes except class
700 # remove attributes except class
701 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
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 bar'>some text</pre>" => "<pre class='foo bar'>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 onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
705 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
706 # xss
706 # xss
707 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
707 '<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>',
708 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
709 }
709 }
710 to_test.each { |text, result| assert_equal result, textilizable(text) }
710 to_test.each { |text, result| assert_equal result, textilizable(text) }
711 end
711 end
712
712
713 def test_allowed_html_tags
713 def test_allowed_html_tags
714 to_test = {
714 to_test = {
715 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
715 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
716 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
716 "<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;"
717 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
718 }
718 }
719 to_test.each { |text, result| assert_equal result, textilizable(text) }
719 to_test.each { |text, result| assert_equal result, textilizable(text) }
720 end
720 end
721
721
722 def test_pre_tags
722 def test_pre_tags
723 raw = <<-RAW
723 raw = <<-RAW
724 Before
724 Before
725
725
726 <pre>
726 <pre>
727 <prepared-statement-cache-size>32</prepared-statement-cache-size>
727 <prepared-statement-cache-size>32</prepared-statement-cache-size>
728 </pre>
728 </pre>
729
729
730 After
730 After
731 RAW
731 RAW
732
732
733 expected = <<-EXPECTED
733 expected = <<-EXPECTED
734 <p>Before</p>
734 <p>Before</p>
735 <pre>
735 <pre>
736 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
736 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
737 </pre>
737 </pre>
738 <p>After</p>
738 <p>After</p>
739 EXPECTED
739 EXPECTED
740
740
741 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
741 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
742 end
742 end
743
743
744 def test_pre_content_should_not_parse_wiki_and_redmine_links
744 def test_pre_content_should_not_parse_wiki_and_redmine_links
745 raw = <<-RAW
745 raw = <<-RAW
746 [[CookBook documentation]]
746 [[CookBook documentation]]
747
747
748 #1
748 #1
749
749
750 <pre>
750 <pre>
751 [[CookBook documentation]]
751 [[CookBook documentation]]
752
752
753 #1
753 #1
754 </pre>
754 </pre>
755 RAW
755 RAW
756
756
757 expected = <<-EXPECTED
757 expected = <<-EXPECTED
758 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
758 <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>
759 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
760 <pre>
760 <pre>
761 [[CookBook documentation]]
761 [[CookBook documentation]]
762
762
763 #1
763 #1
764 </pre>
764 </pre>
765 EXPECTED
765 EXPECTED
766
766
767 @project = Project.find(1)
767 @project = Project.find(1)
768 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
768 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
769 end
769 end
770
770
771 def test_non_closing_pre_blocks_should_be_closed
771 def test_non_closing_pre_blocks_should_be_closed
772 raw = <<-RAW
772 raw = <<-RAW
773 <pre><code>
773 <pre><code>
774 RAW
774 RAW
775
775
776 expected = <<-EXPECTED
776 expected = <<-EXPECTED
777 <pre><code>
777 <pre><code>
778 </code></pre>
778 </code></pre>
779 EXPECTED
779 EXPECTED
780
780
781 @project = Project.find(1)
781 @project = Project.find(1)
782 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
782 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
783 end
783 end
784
784
785 def test_syntax_highlight
785 def test_syntax_highlight
786 raw = <<-RAW
786 raw = <<-RAW
787 <pre><code class="ruby">
787 <pre><code class="ruby">
788 # Some ruby code here
788 # Some ruby code here
789 </code></pre>
789 </code></pre>
790 RAW
790 RAW
791
791
792 expected = <<-EXPECTED
792 expected = <<-EXPECTED
793 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
793 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
794 </code></pre>
794 </code></pre>
795 EXPECTED
795 EXPECTED
796
796
797 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
797 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
798 end
798 end
799
799
800 def test_to_path_param
800 def test_to_path_param
801 assert_equal 'test1/test2', to_path_param('test1/test2')
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 nil, to_path_param('/')
804 assert_equal nil, to_path_param('/')
805 end
805 end
806
806
807 def test_wiki_links_in_tables
807 def test_wiki_links_in_tables
808 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
808 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>' +
809 '<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>' +
810 '<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>'
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 }
812 }
813 @project = Project.find(1)
813 @project = Project.find(1)
814 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
814 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
815 end
815 end
816
816
817 def test_text_formatting
817 def test_text_formatting
818 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
818 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>)',
819 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
820 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
820 '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>',
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 <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
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 }
823 }
824 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
824 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
825 end
825 end
826
826
827 def test_wiki_horizontal_rule
827 def test_wiki_horizontal_rule
828 assert_equal '<hr />', textilizable('---')
828 assert_equal '<hr />', textilizable('---')
829 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
829 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
830 end
830 end
831
831
832 def test_footnotes
832 def test_footnotes
833 raw = <<-RAW
833 raw = <<-RAW
834 This is some text[1].
834 This is some text[1].
835
835
836 fn1. This is the foot note
836 fn1. This is the foot note
837 RAW
837 RAW
838
838
839 expected = <<-EXPECTED
839 expected = <<-EXPECTED
840 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
840 <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>
841 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
842 EXPECTED
842 EXPECTED
843
843
844 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
844 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
845 end
845 end
846
846
847 def test_headings
847 def test_headings
848 raw = 'h1. Some heading'
848 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>|
849 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
850
850
851 assert_equal expected, textilizable(raw)
851 assert_equal expected, textilizable(raw)
852 end
852 end
853
853
854 def test_headings_with_special_chars
854 def test_headings_with_special_chars
855 # This test makes sure that the generated anchor names match the expected
855 # This test makes sure that the generated anchor names match the expected
856 # ones even if the heading text contains unconventional characters
856 # ones even if the heading text contains unconventional characters
857 raw = 'h1. Some heading related to version 0.5'
857 raw = 'h1. Some heading related to version 0.5'
858 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
858 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>|
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
860
861 assert_equal expected, textilizable(raw)
861 assert_equal expected, textilizable(raw)
862 end
862 end
863
863
864 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
864 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
865 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
865 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
866 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
866 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
867
867
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>|
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
869
870 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
870 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
871 end
871 end
872
872
873 def test_table_of_content
873 def test_table_of_content
874 raw = <<-RAW
874 raw = <<-RAW
875 {{toc}}
875 {{toc}}
876
876
877 h1. Title
877 h1. Title
878
878
879 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
879 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
880
880
881 h2. Subtitle with a [[Wiki]] link
881 h2. Subtitle with a [[Wiki]] link
882
882
883 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
883 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
884
884
885 h2. Subtitle with [[Wiki|another Wiki]] link
885 h2. Subtitle with [[Wiki|another Wiki]] link
886
886
887 h2. Subtitle with %{color:red}red text%
887 h2. Subtitle with %{color:red}red text%
888
888
889 <pre>
889 <pre>
890 some code
890 some code
891 </pre>
891 </pre>
892
892
893 h3. Subtitle with *some* _modifiers_
893 h3. Subtitle with *some* _modifiers_
894
894
895 h3. Subtitle with @inline code@
895 h3. Subtitle with @inline code@
896
896
897 h1. Another title
897 h1. Another title
898
898
899 h3. An "Internet link":http://www.redmine.org/ inside subtitle
899 h3. An "Internet link":http://www.redmine.org/ inside subtitle
900
900
901 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
901 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
902
902
903 RAW
903 RAW
904
904
905 expected = '<ul class="toc">' +
905 expected = '<ul class="toc">' +
906 '<li><a href="#Title">Title</a>' +
906 '<li><a href="#Title">Title</a>' +
907 '<ul>' +
907 '<ul>' +
908 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
908 '<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>' +
909 '<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>' +
910 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
911 '<ul>' +
911 '<ul>' +
912 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
912 '<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>' +
913 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
914 '</ul>' +
914 '</ul>' +
915 '</li>' +
915 '</li>' +
916 '</ul>' +
916 '</ul>' +
917 '</li>' +
917 '</li>' +
918 '<li><a href="#Another-title">Another title</a>' +
918 '<li><a href="#Another-title">Another title</a>' +
919 '<ul>' +
919 '<ul>' +
920 '<li>' +
920 '<li>' +
921 '<ul>' +
921 '<ul>' +
922 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
922 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
923 '</ul>' +
923 '</ul>' +
924 '</li>' +
924 '</li>' +
925 '<li><a href="#Project-Name">Project Name</a></li>' +
925 '<li><a href="#Project-Name">Project Name</a></li>' +
926 '</ul>' +
926 '</ul>' +
927 '</li>' +
927 '</li>' +
928 '</ul>'
928 '</ul>'
929
929
930 @project = Project.find(1)
930 @project = Project.find(1)
931 assert textilizable(raw).gsub("\n", "").include?(expected)
931 assert textilizable(raw).gsub("\n", "").include?(expected)
932 end
932 end
933
933
934 def test_table_of_content_should_generate_unique_anchors
934 def test_table_of_content_should_generate_unique_anchors
935 raw = <<-RAW
935 raw = <<-RAW
936 {{toc}}
936 {{toc}}
937
937
938 h1. Title
938 h1. Title
939
939
940 h2. Subtitle
940 h2. Subtitle
941
941
942 h2. Subtitle
942 h2. Subtitle
943 RAW
943 RAW
944
944
945 expected = '<ul class="toc">' +
945 expected = '<ul class="toc">' +
946 '<li><a href="#Title">Title</a>' +
946 '<li><a href="#Title">Title</a>' +
947 '<ul>' +
947 '<ul>' +
948 '<li><a href="#Subtitle">Subtitle</a></li>' +
948 '<li><a href="#Subtitle">Subtitle</a></li>' +
949 '<li><a href="#Subtitle-2">Subtitle</a></li>'
949 '<li><a href="#Subtitle-2">Subtitle</a></li>'
950 '</ul>'
950 '</ul>'
951 '</li>' +
951 '</li>' +
952 '</ul>'
952 '</ul>'
953
953
954 @project = Project.find(1)
954 @project = Project.find(1)
955 result = textilizable(raw).gsub("\n", "")
955 result = textilizable(raw).gsub("\n", "")
956 assert_include expected, result
956 assert_include expected, result
957 assert_include '<a name="Subtitle">', result
957 assert_include '<a name="Subtitle">', result
958 assert_include '<a name="Subtitle-2">', result
958 assert_include '<a name="Subtitle-2">', result
959 end
959 end
960
960
961 def test_table_of_content_should_contain_included_page_headings
961 def test_table_of_content_should_contain_included_page_headings
962 raw = <<-RAW
962 raw = <<-RAW
963 {{toc}}
963 {{toc}}
964
964
965 h1. Included
965 h1. Included
966
966
967 {{include(Child_1)}}
967 {{include(Child_1)}}
968 RAW
968 RAW
969
969
970 expected = '<ul class="toc">' +
970 expected = '<ul class="toc">' +
971 '<li><a href="#Included">Included</a></li>' +
971 '<li><a href="#Included">Included</a></li>' +
972 '<li><a href="#Child-page-1">Child page 1</a></li>' +
972 '<li><a href="#Child-page-1">Child page 1</a></li>' +
973 '</ul>'
973 '</ul>'
974
974
975 @project = Project.find(1)
975 @project = Project.find(1)
976 assert textilizable(raw).gsub("\n", "").include?(expected)
976 assert textilizable(raw).gsub("\n", "").include?(expected)
977 end
977 end
978
978
979 def test_section_edit_links
979 def test_section_edit_links
980 raw = <<-RAW
980 raw = <<-RAW
981 h1. Title
981 h1. Title
982
982
983 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
983 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
984
984
985 h2. Subtitle with a [[Wiki]] link
985 h2. Subtitle with a [[Wiki]] link
986
986
987 h2. Subtitle with *some* _modifiers_
987 h2. Subtitle with *some* _modifiers_
988
988
989 h2. Subtitle with @inline code@
989 h2. Subtitle with @inline code@
990
990
991 <pre>
991 <pre>
992 some code
992 some code
993
993
994 h2. heading inside pre
994 h2. heading inside pre
995
995
996 <h2>html heading inside pre</h2>
996 <h2>html heading inside pre</h2>
997 </pre>
997 </pre>
998
998
999 h2. Subtitle after pre tag
999 h2. Subtitle after pre tag
1000 RAW
1000 RAW
1001
1001
1002 @project = Project.find(1)
1002 @project = Project.find(1)
1003 set_language_if_valid 'en'
1003 set_language_if_valid 'en'
1004 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1004 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1005
1005
1006 # heading that contains inline code
1006 # heading that contains inline code
1007 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1007 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>' +
1008 '<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>' +
1009 '<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>'),
1010 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1011 result
1011 result
1012
1012
1013 # last heading
1013 # last heading
1014 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1014 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>' +
1015 '<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>' +
1016 '<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>'),
1017 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1018 result
1018 result
1019 end
1019 end
1020
1020
1021 def test_default_formatter
1021 def test_default_formatter
1022 with_settings :text_formatting => 'unknown' do
1022 with_settings :text_formatting => 'unknown' do
1023 text = 'a *link*: http://www.example.net/'
1023 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)
1024 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1025 end
1025 end
1026 end
1026 end
1027
1027
1028 def test_due_date_distance_in_words
1028 def test_due_date_distance_in_words
1029 to_test = { Date.today => 'Due in 0 days',
1029 to_test = { Date.today => 'Due in 0 days',
1030 Date.today + 1 => 'Due in 1 day',
1030 Date.today + 1 => 'Due in 1 day',
1031 Date.today + 100 => 'Due in about 3 months',
1031 Date.today + 100 => 'Due in about 3 months',
1032 Date.today + 20000 => 'Due in over 54 years',
1032 Date.today + 20000 => 'Due in over 54 years',
1033 Date.today - 1 => '1 day late',
1033 Date.today - 1 => '1 day late',
1034 Date.today - 100 => 'about 3 months late',
1034 Date.today - 100 => 'about 3 months late',
1035 Date.today - 20000 => 'over 54 years late',
1035 Date.today - 20000 => 'over 54 years late',
1036 }
1036 }
1037 ::I18n.locale = :en
1037 ::I18n.locale = :en
1038 to_test.each do |date, expected|
1038 to_test.each do |date, expected|
1039 assert_equal expected, due_date_distance_in_words(date)
1039 assert_equal expected, due_date_distance_in_words(date)
1040 end
1040 end
1041 end
1041 end
1042
1042
1043 def test_avatar_enabled
1043 def test_avatar_enabled
1044 with_settings :gravatar_enabled => '1' do
1044 with_settings :gravatar_enabled => '1' do
1045 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1045 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'))
1046 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1047 # Default size is 50
1047 # Default size is 50
1048 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1048 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1049 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1049 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1050 # Non-avatar options should be considered html options
1050 # Non-avatar options should be considered html options
1051 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1051 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1052 # The default class of the img tag should be gravatar
1052 # The default class of the img tag should be gravatar
1053 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1053 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1054 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1054 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1055 assert_nil avatar('jsmith')
1055 assert_nil avatar('jsmith')
1056 assert_nil avatar(nil)
1056 assert_nil avatar(nil)
1057 end
1057 end
1058 end
1058 end
1059
1059
1060 def test_avatar_disabled
1060 def test_avatar_disabled
1061 with_settings :gravatar_enabled => '0' do
1061 with_settings :gravatar_enabled => '0' do
1062 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1062 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1063 end
1063 end
1064 end
1064 end
1065
1065
1066 def test_link_to_user
1066 def test_link_to_user
1067 user = User.find(2)
1067 user = User.find(2)
1068 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1068 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1069 end
1069 end
1070
1070
1071 def test_link_to_user_should_not_link_to_locked_user
1071 def test_link_to_user_should_not_link_to_locked_user
1072 with_current_user nil do
1072 with_current_user nil do
1073 user = User.find(5)
1073 user = User.find(5)
1074 assert user.locked?
1074 assert user.locked?
1075 assert_equal 'Dave2 Lopper2', link_to_user(user)
1075 assert_equal 'Dave2 Lopper2', link_to_user(user)
1076 end
1076 end
1077 end
1077 end
1078
1078
1079 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1079 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1080 with_current_user User.find(1) do
1080 with_current_user User.find(1) do
1081 user = User.find(5)
1081 user = User.find(5)
1082 assert user.locked?
1082 assert user.locked?
1083 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1083 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1084 end
1084 end
1085 end
1085 end
1086
1086
1087 def test_link_to_user_should_not_link_to_anonymous
1087 def test_link_to_user_should_not_link_to_anonymous
1088 user = User.anonymous
1088 user = User.anonymous
1089 assert user.anonymous?
1089 assert user.anonymous?
1090 t = link_to_user(user)
1090 t = link_to_user(user)
1091 assert_equal ::I18n.t(:label_user_anonymous), t
1091 assert_equal ::I18n.t(:label_user_anonymous), t
1092 end
1092 end
1093
1093
1094 def test_link_to_attachment
1094 def test_link_to_attachment
1095 a = Attachment.find(3)
1095 a = Attachment.find(3)
1096 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1096 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1097 link_to_attachment(a)
1097 link_to_attachment(a)
1098 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1098 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1099 link_to_attachment(a, :text => 'Text')
1099 link_to_attachment(a, :text => 'Text')
1100 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1100 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1101 link_to_attachment(a, :class => 'foo')
1101 link_to_attachment(a, :class => 'foo')
1102 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1102 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1103 link_to_attachment(a, :download => true)
1103 link_to_attachment(a, :download => true)
1104 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1104 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1105 link_to_attachment(a, :only_path => false)
1105 link_to_attachment(a, :only_path => false)
1106 end
1106 end
1107
1107
1108 def test_thumbnail_tag
1108 def test_thumbnail_tag
1109 a = Attachment.find(3)
1109 a = Attachment.find(3)
1110 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1110 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1111 thumbnail_tag(a)
1111 thumbnail_tag(a)
1112 end
1112 end
1113
1113
1114 def test_link_to_project
1114 def test_link_to_project
1115 project = Project.find(1)
1115 project = Project.find(1)
1116 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1116 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1117 link_to_project(project)
1117 link_to_project(project)
1118 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1118 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1119 link_to_project(project, :action => 'settings')
1119 link_to_project(project, :action => 'settings')
1120 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1120 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1121 link_to_project(project, {:only_path => false, :jump => 'blah'})
1121 link_to_project(project, {:only_path => false, :jump => 'blah'})
1122 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1122 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1123 link_to_project(project, {:action => 'settings'}, :class => "project")
1123 link_to_project(project, {:action => 'settings'}, :class => "project")
1124 end
1124 end
1125
1125
1126 def test_link_to_project_settings
1126 def test_link_to_project_settings
1127 project = Project.find(1)
1127 project = Project.find(1)
1128 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1128 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1129
1129
1130 project.status = Project::STATUS_CLOSED
1130 project.status = Project::STATUS_CLOSED
1131 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1131 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1132
1132
1133 project.status = Project::STATUS_ARCHIVED
1133 project.status = Project::STATUS_ARCHIVED
1134 assert_equal 'eCookbook', link_to_project_settings(project)
1134 assert_equal 'eCookbook', link_to_project_settings(project)
1135 end
1135 end
1136
1136
1137 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1137 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1138 # numeric identifier are no longer allowed
1138 # numeric identifier are no longer allowed
1139 Project.update_all "identifier=25", "id=1"
1139 Project.update_all "identifier=25", "id=1"
1140
1140
1141 assert_equal '<a href="/projects/1">eCookbook</a>',
1141 assert_equal '<a href="/projects/1">eCookbook</a>',
1142 link_to_project(Project.find(1))
1142 link_to_project(Project.find(1))
1143 end
1143 end
1144
1144
1145 def test_principals_options_for_select_with_users
1145 def test_principals_options_for_select_with_users
1146 User.current = nil
1146 User.current = nil
1147 users = [User.find(2), User.find(4)]
1147 users = [User.find(2), User.find(4)]
1148 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1148 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1149 principals_options_for_select(users)
1149 principals_options_for_select(users)
1150 end
1150 end
1151
1151
1152 def test_principals_options_for_select_with_selected
1152 def test_principals_options_for_select_with_selected
1153 User.current = nil
1153 User.current = nil
1154 users = [User.find(2), User.find(4)]
1154 users = [User.find(2), User.find(4)]
1155 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1155 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))
1156 principals_options_for_select(users, User.find(4))
1157 end
1157 end
1158
1158
1159 def test_principals_options_for_select_with_users_and_groups
1159 def test_principals_options_for_select_with_users_and_groups
1160 User.current = nil
1160 User.current = nil
1161 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1161 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>) +
1162 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>),
1163 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1164 principals_options_for_select(users)
1164 principals_options_for_select(users)
1165 end
1165 end
1166
1166
1167 def test_principals_options_for_select_with_empty_collection
1167 def test_principals_options_for_select_with_empty_collection
1168 assert_equal '', principals_options_for_select([])
1168 assert_equal '', principals_options_for_select([])
1169 end
1169 end
1170
1170
1171 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1171 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1172 users = [User.find(2), User.find(4)]
1172 users = [User.find(2), User.find(4)]
1173 User.current = User.find(4)
1173 User.current = User.find(4)
1174 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1174 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1175 end
1175 end
1176
1176
1177 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1177 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1178 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1178 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1179 end
1179 end
1180
1180
1181 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1181 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)
1182 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1183 end
1183 end
1184
1184
1185 def test_image_tag_should_pick_the_default_image
1185 def test_image_tag_should_pick_the_default_image
1186 assert_match 'src="/images/image.png"', image_tag("image.png")
1186 assert_match 'src="/images/image.png"', image_tag("image.png")
1187 end
1187 end
1188
1188
1189 def test_image_tag_should_pick_the_theme_image_if_it_exists
1189 def test_image_tag_should_pick_the_theme_image_if_it_exists
1190 theme = Redmine::Themes.themes.last
1190 theme = Redmine::Themes.themes.last
1191 theme.images << 'image.png'
1191 theme.images << 'image.png'
1192
1192
1193 with_settings :ui_theme => theme.id do
1193 with_settings :ui_theme => theme.id do
1194 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1194 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1195 assert_match %|src="/images/other.png"|, image_tag("other.png")
1195 assert_match %|src="/images/other.png"|, image_tag("other.png")
1196 end
1196 end
1197 ensure
1197 ensure
1198 theme.images.delete 'image.png'
1198 theme.images.delete 'image.png'
1199 end
1199 end
1200
1200
1201 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1201 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)
1202 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1203 end
1203 end
1204
1204
1205 def test_javascript_include_tag_should_pick_the_default_javascript
1205 def test_javascript_include_tag_should_pick_the_default_javascript
1206 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1206 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1207 end
1207 end
1208
1208
1209 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1209 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)
1210 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1211 end
1211 end
1212 end
1212 end
General Comments 0
You need to be logged in to leave comments. Login now