##// END OF EJS Templates
Fixes version url....
Jean-Philippe Lang -
r6065:da69f086e7e0
parent child
Show More
@@ -1,678 +1,678
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class ApplicationHelperTest < ActionView::TestCase
20 class ApplicationHelperTest < ActionView::TestCase
21
21
22 fixtures :projects, :roles, :enabled_modules, :users,
22 fixtures :projects, :roles, :enabled_modules, :users,
23 :repositories, :changesets,
23 :repositories, :changesets,
24 :trackers, :issue_statuses, :issues, :versions, :documents,
24 :trackers, :issue_statuses, :issues, :versions, :documents,
25 :wikis, :wiki_pages, :wiki_contents,
25 :wikis, :wiki_pages, :wiki_contents,
26 :boards, :messages,
26 :boards, :messages,
27 :attachments,
27 :attachments,
28 :enumerations
28 :enumerations
29
29
30 def setup
30 def setup
31 super
31 super
32 end
32 end
33
33
34 context "#link_to_if_authorized" do
34 context "#link_to_if_authorized" do
35 context "authorized user" do
35 context "authorized user" do
36 should "be tested"
36 should "be tested"
37 end
37 end
38
38
39 context "unauthorized user" do
39 context "unauthorized user" do
40 should "be tested"
40 should "be tested"
41 end
41 end
42
42
43 should "allow using the :controller and :action for the target link" do
43 should "allow using the :controller and :action for the target link" do
44 User.current = User.find_by_login('admin')
44 User.current = User.find_by_login('admin')
45
45
46 @project = Issue.first.project # Used by helper
46 @project = Issue.first.project # Used by helper
47 response = link_to_if_authorized("By controller/action",
47 response = link_to_if_authorized("By controller/action",
48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
49 assert_match /href/, response
49 assert_match /href/, response
50 end
50 end
51
51
52 end
52 end
53
53
54 def test_auto_links
54 def test_auto_links
55 to_test = {
55 to_test = {
56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
57 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
57 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
58 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
58 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
59 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
59 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
60 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
60 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
61 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
61 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
62 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
62 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
63 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
63 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
64 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
64 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
65 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
65 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
66 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
66 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
67 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
67 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
68 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
68 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
69 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
69 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
70 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
70 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
71 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
71 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
72 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
72 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
73 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
73 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
74 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
74 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
75 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
75 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
76 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
76 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
77 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
77 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
78 # two exclamation marks
78 # two exclamation marks
79 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
79 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
80 # escaping
80 # escaping
81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
82 # wrap in angle brackets
82 # wrap in angle brackets
83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
84 }
84 }
85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
86 end
86 end
87
87
88 def test_auto_mailto
88 def test_auto_mailto
89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
90 textilizable('test@foo.bar')
90 textilizable('test@foo.bar')
91 end
91 end
92
92
93 def test_inline_images
93 def test_inline_images
94 to_test = {
94 to_test = {
95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
96 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
96 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
97 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
97 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
98 # inline styles should be stripped
98 # inline styles should be stripped
99 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
99 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
100 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
100 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
101 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
101 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
102 }
102 }
103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
104 end
104 end
105
105
106 def test_inline_images_inside_tags
106 def test_inline_images_inside_tags
107 raw = <<-RAW
107 raw = <<-RAW
108 h1. !foo.png! Heading
108 h1. !foo.png! Heading
109
109
110 Centered image:
110 Centered image:
111
111
112 p=. !bar.gif!
112 p=. !bar.gif!
113 RAW
113 RAW
114
114
115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
117 end
117 end
118
118
119 def test_attached_images
119 def test_attached_images
120 to_test = {
120 to_test = {
121 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
121 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
123 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
123 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
124 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
124 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
125 # link image
125 # link image
126 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
126 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
127 }
127 }
128 attachments = Attachment.find(:all)
128 attachments = Attachment.find(:all)
129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
130 end
130 end
131
131
132 def test_textile_external_links
132 def test_textile_external_links
133 to_test = {
133 to_test = {
134 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
134 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
135 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
135 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
136 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
136 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
137 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
137 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
138 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
138 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
139 # no multiline link text
139 # no multiline link text
140 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
140 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
141 # mailto link
141 # mailto link
142 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
142 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
143 # two exclamation marks
143 # two exclamation marks
144 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
144 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
145 # escaping
145 # escaping
146 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
146 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
147 }
147 }
148 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
148 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
149 end
149 end
150
150
151 def test_redmine_links
151 def test_redmine_links
152 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
152 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
153 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
153 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
154
154
155 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
155 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
156 :class => 'changeset', :title => 'My very first commit')
156 :class => 'changeset', :title => 'My very first commit')
157 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
157 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
158 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
158 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
159
159
160 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
160 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
161 :class => 'document')
161 :class => 'document')
162
162
163 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
163 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
164 :class => 'version')
164 :class => 'version')
165
165
166 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
166 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
167
167
168 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
168 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
169
169
170 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
170 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
171 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
171 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
172
172
173 to_test = {
173 to_test = {
174 # tickets
174 # tickets
175 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
175 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
176 # changesets
176 # changesets
177 'r1' => changeset_link,
177 'r1' => changeset_link,
178 'r1.' => "#{changeset_link}.",
178 'r1.' => "#{changeset_link}.",
179 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
179 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
180 'r1,r2' => "#{changeset_link},#{changeset_link2}",
180 'r1,r2' => "#{changeset_link},#{changeset_link2}",
181 # documents
181 # documents
182 'document#1' => document_link,
182 'document#1' => document_link,
183 'document:"Test document"' => document_link,
183 'document:"Test document"' => document_link,
184 # versions
184 # versions
185 'version#2' => version_link,
185 'version#2' => version_link,
186 'version:1.0' => version_link,
186 'version:1.0' => version_link,
187 'version:"1.0"' => version_link,
187 'version:"1.0"' => version_link,
188 # source
188 # source
189 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
189 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
190 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
190 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
191 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
191 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
192 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
192 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
193 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
193 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
194 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
194 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
195 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
195 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
196 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
196 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
197 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
197 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
198 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
198 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
199 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
199 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
200 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
200 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
201 # message
201 # message
202 'message#4' => link_to('Post 2', message_url, :class => 'message'),
202 'message#4' => link_to('Post 2', message_url, :class => 'message'),
203 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
203 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
204 # project
204 # project
205 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
205 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
206 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
206 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
207 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
207 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
208 # escaping
208 # escaping
209 '!#3.' => '#3.',
209 '!#3.' => '#3.',
210 '!r1' => 'r1',
210 '!r1' => 'r1',
211 '!document#1' => 'document#1',
211 '!document#1' => 'document#1',
212 '!document:"Test document"' => 'document:"Test document"',
212 '!document:"Test document"' => 'document:"Test document"',
213 '!version#2' => 'version#2',
213 '!version#2' => 'version#2',
214 '!version:1.0' => 'version:1.0',
214 '!version:1.0' => 'version:1.0',
215 '!version:"1.0"' => 'version:"1.0"',
215 '!version:"1.0"' => 'version:"1.0"',
216 '!source:/some/file' => 'source:/some/file',
216 '!source:/some/file' => 'source:/some/file',
217 # not found
217 # not found
218 '#0123456789' => '#0123456789',
218 '#0123456789' => '#0123456789',
219 # invalid expressions
219 # invalid expressions
220 'source:' => 'source:',
220 'source:' => 'source:',
221 # url hash
221 # url hash
222 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
222 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
223 }
223 }
224 @project = Project.find(1)
224 @project = Project.find(1)
225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
226 end
226 end
227
227
228 def test_cross_project_redmine_links
228 def test_cross_project_redmine_links
229 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
229 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
230 :class => 'source')
230 :class => 'source')
231
231
232 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
232 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
233 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
233 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
234
234
235 to_test = {
235 to_test = {
236 # documents
236 # documents
237 'document:"Test document"' => 'document:"Test document"',
237 'document:"Test document"' => 'document:"Test document"',
238 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
238 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
239 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
239 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
240 # versions
240 # versions
241 'version:"1.0"' => 'version:"1.0"',
241 'version:"1.0"' => 'version:"1.0"',
242 'ecookbook:version:"1.0"' => '<a href="/versions/show/2" class="version">1.0</a>',
242 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
243 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
243 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
244 # changeset
244 # changeset
245 'r2' => 'r2',
245 'r2' => 'r2',
246 'ecookbook:r2' => changeset_link,
246 'ecookbook:r2' => changeset_link,
247 'invalid:r2' => 'invalid:r2',
247 'invalid:r2' => 'invalid:r2',
248 # source
248 # source
249 'source:/some/file' => 'source:/some/file',
249 'source:/some/file' => 'source:/some/file',
250 'ecookbook:source:/some/file' => source_link,
250 'ecookbook:source:/some/file' => source_link,
251 'invalid:source:/some/file' => 'invalid:source:/some/file',
251 'invalid:source:/some/file' => 'invalid:source:/some/file',
252 }
252 }
253 @project = Project.find(3)
253 @project = Project.find(3)
254 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
254 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
255 end
255 end
256
256
257 def test_redmine_links_git_commit
257 def test_redmine_links_git_commit
258 changeset_link = link_to('abcd',
258 changeset_link = link_to('abcd',
259 {
259 {
260 :controller => 'repositories',
260 :controller => 'repositories',
261 :action => 'revision',
261 :action => 'revision',
262 :id => 'subproject1',
262 :id => 'subproject1',
263 :rev => 'abcd',
263 :rev => 'abcd',
264 },
264 },
265 :class => 'changeset', :title => 'test commit')
265 :class => 'changeset', :title => 'test commit')
266 to_test = {
266 to_test = {
267 'commit:abcd' => changeset_link,
267 'commit:abcd' => changeset_link,
268 }
268 }
269 @project = Project.find(3)
269 @project = Project.find(3)
270 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
270 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
271 assert r
271 assert r
272 c = Changeset.new(:repository => r,
272 c = Changeset.new(:repository => r,
273 :committed_on => Time.now,
273 :committed_on => Time.now,
274 :revision => 'abcd',
274 :revision => 'abcd',
275 :scmid => 'abcd',
275 :scmid => 'abcd',
276 :comments => 'test commit')
276 :comments => 'test commit')
277 assert( c.save )
277 assert( c.save )
278 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
278 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
279 end
279 end
280
280
281 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
281 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
282 def test_redmine_links_darcs_commit
282 def test_redmine_links_darcs_commit
283 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
283 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
284 {
284 {
285 :controller => 'repositories',
285 :controller => 'repositories',
286 :action => 'revision',
286 :action => 'revision',
287 :id => 'subproject1',
287 :id => 'subproject1',
288 :rev => '123',
288 :rev => '123',
289 },
289 },
290 :class => 'changeset', :title => 'test commit')
290 :class => 'changeset', :title => 'test commit')
291 to_test = {
291 to_test = {
292 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
292 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
293 }
293 }
294 @project = Project.find(3)
294 @project = Project.find(3)
295 r = Repository::Darcs.create!(
295 r = Repository::Darcs.create!(
296 :project => @project, :url => '/tmp/test/darcs',
296 :project => @project, :url => '/tmp/test/darcs',
297 :log_encoding => 'UTF-8')
297 :log_encoding => 'UTF-8')
298 assert r
298 assert r
299 c = Changeset.new(:repository => r,
299 c = Changeset.new(:repository => r,
300 :committed_on => Time.now,
300 :committed_on => Time.now,
301 :revision => '123',
301 :revision => '123',
302 :scmid => '20080308225258-98289-abcd456efg.gz',
302 :scmid => '20080308225258-98289-abcd456efg.gz',
303 :comments => 'test commit')
303 :comments => 'test commit')
304 assert( c.save )
304 assert( c.save )
305 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
305 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
306 end
306 end
307
307
308 def test_redmine_links_mercurial_commit
308 def test_redmine_links_mercurial_commit
309 changeset_link_rev = link_to('r123',
309 changeset_link_rev = link_to('r123',
310 {
310 {
311 :controller => 'repositories',
311 :controller => 'repositories',
312 :action => 'revision',
312 :action => 'revision',
313 :id => 'subproject1',
313 :id => 'subproject1',
314 :rev => '123' ,
314 :rev => '123' ,
315 },
315 },
316 :class => 'changeset', :title => 'test commit')
316 :class => 'changeset', :title => 'test commit')
317 changeset_link_commit = link_to('abcd',
317 changeset_link_commit = link_to('abcd',
318 {
318 {
319 :controller => 'repositories',
319 :controller => 'repositories',
320 :action => 'revision',
320 :action => 'revision',
321 :id => 'subproject1',
321 :id => 'subproject1',
322 :rev => 'abcd' ,
322 :rev => 'abcd' ,
323 },
323 },
324 :class => 'changeset', :title => 'test commit')
324 :class => 'changeset', :title => 'test commit')
325 to_test = {
325 to_test = {
326 'r123' => changeset_link_rev,
326 'r123' => changeset_link_rev,
327 'commit:abcd' => changeset_link_commit,
327 'commit:abcd' => changeset_link_commit,
328 }
328 }
329 @project = Project.find(3)
329 @project = Project.find(3)
330 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
330 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
331 assert r
331 assert r
332 c = Changeset.new(:repository => r,
332 c = Changeset.new(:repository => r,
333 :committed_on => Time.now,
333 :committed_on => Time.now,
334 :revision => '123',
334 :revision => '123',
335 :scmid => 'abcd',
335 :scmid => 'abcd',
336 :comments => 'test commit')
336 :comments => 'test commit')
337 assert( c.save )
337 assert( c.save )
338 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
338 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
339 end
339 end
340
340
341 def test_attachment_links
341 def test_attachment_links
342 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
342 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
343 to_test = {
343 to_test = {
344 'attachment:error281.txt' => attachment_link
344 'attachment:error281.txt' => attachment_link
345 }
345 }
346 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
346 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
347 end
347 end
348
348
349 def test_wiki_links
349 def test_wiki_links
350 to_test = {
350 to_test = {
351 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
351 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
352 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
352 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
353 # link with anchor
353 # link with anchor
354 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
354 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
355 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
355 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
356 # page that doesn't exist
356 # page that doesn't exist
357 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
357 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
358 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
358 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
359 # link to another project wiki
359 # link to another project wiki
360 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
360 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
361 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
361 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
362 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
362 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
363 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
363 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
364 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
364 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
365 # striked through link
365 # striked through link
366 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
366 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
367 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
367 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
368 # escaping
368 # escaping
369 '![[Another page|Page]]' => '[[Another page|Page]]',
369 '![[Another page|Page]]' => '[[Another page|Page]]',
370 # project does not exist
370 # project does not exist
371 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
371 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
372 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
372 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
373 }
373 }
374 @project = Project.find(1)
374 @project = Project.find(1)
375 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
375 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
376 end
376 end
377
377
378 def test_html_tags
378 def test_html_tags
379 to_test = {
379 to_test = {
380 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
380 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
381 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
381 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
382 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
382 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
383 # do not escape pre/code tags
383 # do not escape pre/code tags
384 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
384 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
385 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
385 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
386 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
386 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
387 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
387 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
388 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
388 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
389 # remove attributes except class
389 # remove attributes except class
390 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
390 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
391 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
391 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
392 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
392 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
393 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
393 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
394 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
394 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
395 # xss
395 # xss
396 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
396 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
397 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
397 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
398 }
398 }
399 to_test.each { |text, result| assert_equal result, textilizable(text) }
399 to_test.each { |text, result| assert_equal result, textilizable(text) }
400 end
400 end
401
401
402 def test_allowed_html_tags
402 def test_allowed_html_tags
403 to_test = {
403 to_test = {
404 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
404 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
405 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
405 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
406 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
406 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
407 }
407 }
408 to_test.each { |text, result| assert_equal result, textilizable(text) }
408 to_test.each { |text, result| assert_equal result, textilizable(text) }
409 end
409 end
410
410
411 def test_pre_tags
411 def test_pre_tags
412 raw = <<-RAW
412 raw = <<-RAW
413 Before
413 Before
414
414
415 <pre>
415 <pre>
416 <prepared-statement-cache-size>32</prepared-statement-cache-size>
416 <prepared-statement-cache-size>32</prepared-statement-cache-size>
417 </pre>
417 </pre>
418
418
419 After
419 After
420 RAW
420 RAW
421
421
422 expected = <<-EXPECTED
422 expected = <<-EXPECTED
423 <p>Before</p>
423 <p>Before</p>
424 <pre>
424 <pre>
425 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
425 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
426 </pre>
426 </pre>
427 <p>After</p>
427 <p>After</p>
428 EXPECTED
428 EXPECTED
429
429
430 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
430 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
431 end
431 end
432
432
433 def test_pre_content_should_not_parse_wiki_and_redmine_links
433 def test_pre_content_should_not_parse_wiki_and_redmine_links
434 raw = <<-RAW
434 raw = <<-RAW
435 [[CookBook documentation]]
435 [[CookBook documentation]]
436
436
437 #1
437 #1
438
438
439 <pre>
439 <pre>
440 [[CookBook documentation]]
440 [[CookBook documentation]]
441
441
442 #1
442 #1
443 </pre>
443 </pre>
444 RAW
444 RAW
445
445
446 expected = <<-EXPECTED
446 expected = <<-EXPECTED
447 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
447 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
448 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
448 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
449 <pre>
449 <pre>
450 [[CookBook documentation]]
450 [[CookBook documentation]]
451
451
452 #1
452 #1
453 </pre>
453 </pre>
454 EXPECTED
454 EXPECTED
455
455
456 @project = Project.find(1)
456 @project = Project.find(1)
457 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
457 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
458 end
458 end
459
459
460 def test_non_closing_pre_blocks_should_be_closed
460 def test_non_closing_pre_blocks_should_be_closed
461 raw = <<-RAW
461 raw = <<-RAW
462 <pre><code>
462 <pre><code>
463 RAW
463 RAW
464
464
465 expected = <<-EXPECTED
465 expected = <<-EXPECTED
466 <pre><code>
466 <pre><code>
467 </code></pre>
467 </code></pre>
468 EXPECTED
468 EXPECTED
469
469
470 @project = Project.find(1)
470 @project = Project.find(1)
471 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
471 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
472 end
472 end
473
473
474 def test_syntax_highlight
474 def test_syntax_highlight
475 raw = <<-RAW
475 raw = <<-RAW
476 <pre><code class="ruby">
476 <pre><code class="ruby">
477 # Some ruby code here
477 # Some ruby code here
478 </code></pre>
478 </code></pre>
479 RAW
479 RAW
480
480
481 expected = <<-EXPECTED
481 expected = <<-EXPECTED
482 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
482 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
483 </code></pre>
483 </code></pre>
484 EXPECTED
484 EXPECTED
485
485
486 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
486 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
487 end
487 end
488
488
489 def test_wiki_links_in_tables
489 def test_wiki_links_in_tables
490 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
490 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
491 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
491 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
492 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
492 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
493 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
493 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
494 }
494 }
495 @project = Project.find(1)
495 @project = Project.find(1)
496 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
496 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
497 end
497 end
498
498
499 def test_text_formatting
499 def test_text_formatting
500 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
500 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
501 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
501 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
502 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
502 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
503 '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>',
503 '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>',
504 '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',
504 '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',
505 }
505 }
506 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
506 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
507 end
507 end
508
508
509 def test_wiki_horizontal_rule
509 def test_wiki_horizontal_rule
510 assert_equal '<hr />', textilizable('---')
510 assert_equal '<hr />', textilizable('---')
511 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
511 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
512 end
512 end
513
513
514 def test_footnotes
514 def test_footnotes
515 raw = <<-RAW
515 raw = <<-RAW
516 This is some text[1].
516 This is some text[1].
517
517
518 fn1. This is the foot note
518 fn1. This is the foot note
519 RAW
519 RAW
520
520
521 expected = <<-EXPECTED
521 expected = <<-EXPECTED
522 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
522 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
523 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
523 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
524 EXPECTED
524 EXPECTED
525
525
526 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
526 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
527 end
527 end
528
528
529 def test_headings
529 def test_headings
530 raw = 'h1. Some heading'
530 raw = 'h1. Some heading'
531 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
531 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
532
532
533 assert_equal expected, textilizable(raw)
533 assert_equal expected, textilizable(raw)
534 end
534 end
535
535
536 def test_table_of_content
536 def test_table_of_content
537 raw = <<-RAW
537 raw = <<-RAW
538 {{toc}}
538 {{toc}}
539
539
540 h1. Title
540 h1. Title
541
541
542 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
542 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
543
543
544 h2. Subtitle with a [[Wiki]] link
544 h2. Subtitle with a [[Wiki]] link
545
545
546 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
546 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
547
547
548 h2. Subtitle with [[Wiki|another Wiki]] link
548 h2. Subtitle with [[Wiki|another Wiki]] link
549
549
550 h2. Subtitle with %{color:red}red text%
550 h2. Subtitle with %{color:red}red text%
551
551
552 <pre>
552 <pre>
553 some code
553 some code
554 </pre>
554 </pre>
555
555
556 h3. Subtitle with *some* _modifiers_
556 h3. Subtitle with *some* _modifiers_
557
557
558 h1. Another title
558 h1. Another title
559
559
560 h3. An "Internet link":http://www.redmine.org/ inside subtitle
560 h3. An "Internet link":http://www.redmine.org/ inside subtitle
561
561
562 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
562 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
563
563
564 RAW
564 RAW
565
565
566 expected = '<ul class="toc">' +
566 expected = '<ul class="toc">' +
567 '<li><a href="#Title">Title</a>' +
567 '<li><a href="#Title">Title</a>' +
568 '<ul>' +
568 '<ul>' +
569 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
569 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
570 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
570 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
571 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
571 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
572 '<ul>' +
572 '<ul>' +
573 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
573 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
574 '</ul>' +
574 '</ul>' +
575 '</li>' +
575 '</li>' +
576 '</ul>' +
576 '</ul>' +
577 '</li>' +
577 '</li>' +
578 '<li><a href="#Another-title">Another title</a>' +
578 '<li><a href="#Another-title">Another title</a>' +
579 '<ul>' +
579 '<ul>' +
580 '<li>' +
580 '<li>' +
581 '<ul>' +
581 '<ul>' +
582 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
582 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
583 '</ul>' +
583 '</ul>' +
584 '</li>' +
584 '</li>' +
585 '<li><a href="#Project-Name">Project Name</a></li>' +
585 '<li><a href="#Project-Name">Project Name</a></li>' +
586 '</ul>' +
586 '</ul>' +
587 '</li>' +
587 '</li>' +
588 '</ul>'
588 '</ul>'
589
589
590 @project = Project.find(1)
590 @project = Project.find(1)
591 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
591 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
592 end
592 end
593
593
594 def test_table_of_content_should_contain_included_page_headings
594 def test_table_of_content_should_contain_included_page_headings
595 raw = <<-RAW
595 raw = <<-RAW
596 {{toc}}
596 {{toc}}
597
597
598 h1. Included
598 h1. Included
599
599
600 {{include(Child_1)}}
600 {{include(Child_1)}}
601 RAW
601 RAW
602
602
603 expected = '<ul class="toc">' +
603 expected = '<ul class="toc">' +
604 '<li><a href="#Included">Included</a></li>' +
604 '<li><a href="#Included">Included</a></li>' +
605 '<li><a href="#Child-page-1">Child page 1</a></li>' +
605 '<li><a href="#Child-page-1">Child page 1</a></li>' +
606 '</ul>'
606 '</ul>'
607
607
608 @project = Project.find(1)
608 @project = Project.find(1)
609 assert textilizable(raw).gsub("\n", "").include?(expected)
609 assert textilizable(raw).gsub("\n", "").include?(expected)
610 end
610 end
611
611
612 def test_default_formatter
612 def test_default_formatter
613 Setting.text_formatting = 'unknown'
613 Setting.text_formatting = 'unknown'
614 text = 'a *link*: http://www.example.net/'
614 text = 'a *link*: http://www.example.net/'
615 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
615 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
616 Setting.text_formatting = 'textile'
616 Setting.text_formatting = 'textile'
617 end
617 end
618
618
619 def test_due_date_distance_in_words
619 def test_due_date_distance_in_words
620 to_test = { Date.today => 'Due in 0 days',
620 to_test = { Date.today => 'Due in 0 days',
621 Date.today + 1 => 'Due in 1 day',
621 Date.today + 1 => 'Due in 1 day',
622 Date.today + 100 => 'Due in about 3 months',
622 Date.today + 100 => 'Due in about 3 months',
623 Date.today + 20000 => 'Due in over 54 years',
623 Date.today + 20000 => 'Due in over 54 years',
624 Date.today - 1 => '1 day late',
624 Date.today - 1 => '1 day late',
625 Date.today - 100 => 'about 3 months late',
625 Date.today - 100 => 'about 3 months late',
626 Date.today - 20000 => 'over 54 years late',
626 Date.today - 20000 => 'over 54 years late',
627 }
627 }
628 ::I18n.locale = :en
628 ::I18n.locale = :en
629 to_test.each do |date, expected|
629 to_test.each do |date, expected|
630 assert_equal expected, due_date_distance_in_words(date)
630 assert_equal expected, due_date_distance_in_words(date)
631 end
631 end
632 end
632 end
633
633
634 def test_avatar
634 def test_avatar
635 # turn on avatars
635 # turn on avatars
636 Setting.gravatar_enabled = '1'
636 Setting.gravatar_enabled = '1'
637 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
637 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
638 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
638 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
639 assert_nil avatar('jsmith')
639 assert_nil avatar('jsmith')
640 assert_nil avatar(nil)
640 assert_nil avatar(nil)
641
641
642 # turn off avatars
642 # turn off avatars
643 Setting.gravatar_enabled = '0'
643 Setting.gravatar_enabled = '0'
644 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
644 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
645 end
645 end
646
646
647 def test_link_to_user
647 def test_link_to_user
648 user = User.find(2)
648 user = User.find(2)
649 t = link_to_user(user)
649 t = link_to_user(user)
650 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
650 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
651 end
651 end
652
652
653 def test_link_to_user_should_not_link_to_locked_user
653 def test_link_to_user_should_not_link_to_locked_user
654 user = User.find(5)
654 user = User.find(5)
655 assert user.locked?
655 assert user.locked?
656 t = link_to_user(user)
656 t = link_to_user(user)
657 assert_equal user.name, t
657 assert_equal user.name, t
658 end
658 end
659
659
660 def test_link_to_user_should_not_link_to_anonymous
660 def test_link_to_user_should_not_link_to_anonymous
661 user = User.anonymous
661 user = User.anonymous
662 assert user.anonymous?
662 assert user.anonymous?
663 t = link_to_user(user)
663 t = link_to_user(user)
664 assert_equal ::I18n.t(:label_user_anonymous), t
664 assert_equal ::I18n.t(:label_user_anonymous), t
665 end
665 end
666
666
667 def test_link_to_project
667 def test_link_to_project
668 project = Project.find(1)
668 project = Project.find(1)
669 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
669 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
670 link_to_project(project)
670 link_to_project(project)
671 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
671 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
672 link_to_project(project, :action => 'settings')
672 link_to_project(project, :action => 'settings')
673 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
673 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
674 link_to_project(project, {:only_path => false, :jump => 'blah'})
674 link_to_project(project, {:only_path => false, :jump => 'blah'})
675 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
675 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
676 link_to_project(project, {:action => 'settings'}, :class => "project")
676 link_to_project(project, {:action => 'settings'}, :class => "project")
677 end
677 end
678 end
678 end
@@ -1,68 +1,68
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class ProjectsHelperTest < ActionView::TestCase
20 class ProjectsHelperTest < ActionView::TestCase
21 include ApplicationHelper
21 include ApplicationHelper
22 include ProjectsHelper
22 include ProjectsHelper
23
23
24 fixtures :all
24 fixtures :all
25
25
26 def setup
26 def setup
27 super
27 super
28 set_language_if_valid('en')
28 set_language_if_valid('en')
29 User.current = nil
29 User.current = nil
30 end
30 end
31
31
32 def test_link_to_version_within_project
32 def test_link_to_version_within_project
33 @project = Project.find(2)
33 @project = Project.find(2)
34 User.current = User.find(1)
34 User.current = User.find(1)
35 assert_equal '<a href="/versions/show/5">Alpha</a>', link_to_version(Version.find(5))
35 assert_equal '<a href="/versions/5">Alpha</a>', link_to_version(Version.find(5))
36 end
36 end
37
37
38 def test_link_to_version
38 def test_link_to_version
39 User.current = User.find(1)
39 User.current = User.find(1)
40 assert_equal '<a href="/versions/show/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5))
40 assert_equal '<a href="/versions/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5))
41 end
41 end
42
42
43 def test_link_to_private_version
43 def test_link_to_private_version
44 assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5))
44 assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5))
45 end
45 end
46
46
47 def test_link_to_version_invalid_version
47 def test_link_to_version_invalid_version
48 assert_equal '', link_to_version(Object)
48 assert_equal '', link_to_version(Object)
49 end
49 end
50
50
51 def test_format_version_name_within_project
51 def test_format_version_name_within_project
52 @project = Project.find(1)
52 @project = Project.find(1)
53 assert_equal "0.1", format_version_name(Version.find(1))
53 assert_equal "0.1", format_version_name(Version.find(1))
54 end
54 end
55
55
56 def test_format_version_name
56 def test_format_version_name
57 assert_equal "eCookbook - 0.1", format_version_name(Version.find(1))
57 assert_equal "eCookbook - 0.1", format_version_name(Version.find(1))
58 end
58 end
59
59
60 def test_format_version_name_for_system_version
60 def test_format_version_name_for_system_version
61 assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7))
61 assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7))
62 end
62 end
63
63
64 def test_version_options_for_select_with_no_versions
64 def test_version_options_for_select_with_no_versions
65 assert_equal '', version_options_for_select([])
65 assert_equal '', version_options_for_select([])
66 assert_equal '<option value="1" selected="selected">0.1</option>', version_options_for_select([], Version.find(1))
66 assert_equal '<option value="1" selected="selected">0.1</option>', version_options_for_select([], Version.find(1))
67 end
67 end
68 end
68 end
@@ -1,779 +1,779
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../../../test_helper', __FILE__)
18 require File.expand_path('../../../../../test_helper', __FILE__)
19
19
20 class Redmine::Helpers::GanttTest < ActiveSupport::TestCase
20 class Redmine::Helpers::GanttTest < ActiveSupport::TestCase
21 # Utility methods and classes so assert_select can be used.
21 # Utility methods and classes so assert_select can be used.
22 class GanttViewTest < ActionView::Base
22 class GanttViewTest < ActionView::Base
23 include ActionView::Helpers::UrlHelper
23 include ActionView::Helpers::UrlHelper
24 include ActionView::Helpers::TextHelper
24 include ActionView::Helpers::TextHelper
25 include ActionController::UrlWriter
25 include ActionController::UrlWriter
26 include ApplicationHelper
26 include ApplicationHelper
27 include ProjectsHelper
27 include ProjectsHelper
28 include IssuesHelper
28 include IssuesHelper
29
29
30 def self.default_url_options
30 def self.default_url_options
31 {:only_path => true }
31 {:only_path => true }
32 end
32 end
33
33
34 end
34 end
35
35
36 include ActionController::Assertions::SelectorAssertions
36 include ActionController::Assertions::SelectorAssertions
37
37
38 def setup
38 def setup
39 @response = ActionController::TestResponse.new
39 @response = ActionController::TestResponse.new
40 # Fixtures
40 # Fixtures
41 ProjectCustomField.delete_all
41 ProjectCustomField.delete_all
42 Project.destroy_all
42 Project.destroy_all
43
43
44 User.current = User.find(1)
44 User.current = User.find(1)
45 end
45 end
46
46
47 def build_view
47 def build_view
48 @view = GanttViewTest.new
48 @view = GanttViewTest.new
49 end
49 end
50
50
51 def html_document
51 def html_document
52 HTML::Document.new(@response.body)
52 HTML::Document.new(@response.body)
53 end
53 end
54
54
55 # Creates a Gantt chart for a 4 week span
55 # Creates a Gantt chart for a 4 week span
56 def create_gantt(project=Project.generate!, options={})
56 def create_gantt(project=Project.generate!, options={})
57 @project = project
57 @project = project
58 @gantt = Redmine::Helpers::Gantt.new(options)
58 @gantt = Redmine::Helpers::Gantt.new(options)
59 @gantt.project = @project
59 @gantt.project = @project
60 @gantt.query = Query.generate_default!(:project => @project)
60 @gantt.query = Query.generate_default!(:project => @project)
61 @gantt.view = build_view
61 @gantt.view = build_view
62 @gantt.instance_variable_set('@date_from', options[:date_from] || 2.weeks.ago.to_date)
62 @gantt.instance_variable_set('@date_from', options[:date_from] || 2.weeks.ago.to_date)
63 @gantt.instance_variable_set('@date_to', options[:date_to] || 2.weeks.from_now.to_date)
63 @gantt.instance_variable_set('@date_to', options[:date_to] || 2.weeks.from_now.to_date)
64 end
64 end
65
65
66 context "#number_of_rows" do
66 context "#number_of_rows" do
67
67
68 context "with one project" do
68 context "with one project" do
69 should "return the number of rows just for that project"
69 should "return the number of rows just for that project"
70 end
70 end
71
71
72 context "with no project" do
72 context "with no project" do
73 should "return the total number of rows for all the projects, resursively"
73 should "return the total number of rows for all the projects, resursively"
74 end
74 end
75
75
76 should "not exceed max_rows option" do
76 should "not exceed max_rows option" do
77 p = Project.generate!
77 p = Project.generate!
78 5.times do
78 5.times do
79 Issue.generate_for_project!(p)
79 Issue.generate_for_project!(p)
80 end
80 end
81
81
82 create_gantt(p)
82 create_gantt(p)
83 @gantt.render
83 @gantt.render
84 assert_equal 6, @gantt.number_of_rows
84 assert_equal 6, @gantt.number_of_rows
85 assert !@gantt.truncated
85 assert !@gantt.truncated
86
86
87 create_gantt(p, :max_rows => 3)
87 create_gantt(p, :max_rows => 3)
88 @gantt.render
88 @gantt.render
89 assert_equal 3, @gantt.number_of_rows
89 assert_equal 3, @gantt.number_of_rows
90 assert @gantt.truncated
90 assert @gantt.truncated
91 end
91 end
92 end
92 end
93
93
94 context "#number_of_rows_on_project" do
94 context "#number_of_rows_on_project" do
95 setup do
95 setup do
96 create_gantt
96 create_gantt
97 end
97 end
98
98
99 should "count 0 for an empty the project" do
99 should "count 0 for an empty the project" do
100 assert_equal 0, @gantt.number_of_rows_on_project(@project)
100 assert_equal 0, @gantt.number_of_rows_on_project(@project)
101 end
101 end
102
102
103 should "count the number of issues without a version" do
103 should "count the number of issues without a version" do
104 @project.issues << Issue.generate_for_project!(@project, :fixed_version => nil)
104 @project.issues << Issue.generate_for_project!(@project, :fixed_version => nil)
105 assert_equal 2, @gantt.number_of_rows_on_project(@project)
105 assert_equal 2, @gantt.number_of_rows_on_project(@project)
106 end
106 end
107
107
108 should "count the number of issues on versions, including cross-project" do
108 should "count the number of issues on versions, including cross-project" do
109 version = Version.generate!
109 version = Version.generate!
110 @project.versions << version
110 @project.versions << version
111 @project.issues << Issue.generate_for_project!(@project, :fixed_version => version)
111 @project.issues << Issue.generate_for_project!(@project, :fixed_version => version)
112
112
113 assert_equal 3, @gantt.number_of_rows_on_project(@project)
113 assert_equal 3, @gantt.number_of_rows_on_project(@project)
114 end
114 end
115 end
115 end
116
116
117 # TODO: more of an integration test
117 # TODO: more of an integration test
118 context "#subjects" do
118 context "#subjects" do
119 setup do
119 setup do
120 create_gantt
120 create_gantt
121 @project.enabled_module_names = [:issue_tracking]
121 @project.enabled_module_names = [:issue_tracking]
122 @tracker = Tracker.generate!
122 @tracker = Tracker.generate!
123 @project.trackers << @tracker
123 @project.trackers << @tracker
124 @version = Version.generate!(:effective_date => 1.week.from_now.to_date, :sharing => 'none')
124 @version = Version.generate!(:effective_date => 1.week.from_now.to_date, :sharing => 'none')
125 @project.versions << @version
125 @project.versions << @version
126
126
127 @issue = Issue.generate!(:fixed_version => @version,
127 @issue = Issue.generate!(:fixed_version => @version,
128 :subject => "gantt#line_for_project",
128 :subject => "gantt#line_for_project",
129 :tracker => @tracker,
129 :tracker => @tracker,
130 :project => @project,
130 :project => @project,
131 :done_ratio => 30,
131 :done_ratio => 30,
132 :start_date => Date.yesterday,
132 :start_date => Date.yesterday,
133 :due_date => 1.week.from_now.to_date)
133 :due_date => 1.week.from_now.to_date)
134 @project.issues << @issue
134 @project.issues << @issue
135 end
135 end
136
136
137 context "project" do
137 context "project" do
138 should "be rendered" do
138 should "be rendered" do
139 @response.body = @gantt.subjects
139 @response.body = @gantt.subjects
140 assert_select "div.project-name a", /#{@project.name}/
140 assert_select "div.project-name a", /#{@project.name}/
141 end
141 end
142
142
143 should "have an indent of 4" do
143 should "have an indent of 4" do
144 @response.body = @gantt.subjects
144 @response.body = @gantt.subjects
145 assert_select "div.project-name[style*=left:4px]"
145 assert_select "div.project-name[style*=left:4px]"
146 end
146 end
147 end
147 end
148
148
149 context "version" do
149 context "version" do
150 should "be rendered" do
150 should "be rendered" do
151 @response.body = @gantt.subjects
151 @response.body = @gantt.subjects
152 assert_select "div.version-name a", /#{@version.name}/
152 assert_select "div.version-name a", /#{@version.name}/
153 end
153 end
154
154
155 should "be indented 24 (one level)" do
155 should "be indented 24 (one level)" do
156 @response.body = @gantt.subjects
156 @response.body = @gantt.subjects
157 assert_select "div.version-name[style*=left:24px]"
157 assert_select "div.version-name[style*=left:24px]"
158 end
158 end
159
159
160 context "without assigned issues" do
160 context "without assigned issues" do
161 setup do
161 setup do
162 @version = Version.generate!(:effective_date => 2.week.from_now.to_date, :sharing => 'none', :name => 'empty_version')
162 @version = Version.generate!(:effective_date => 2.week.from_now.to_date, :sharing => 'none', :name => 'empty_version')
163 @project.versions << @version
163 @project.versions << @version
164 end
164 end
165
165
166 should "not be rendered" do
166 should "not be rendered" do
167 @response.body = @gantt.subjects
167 @response.body = @gantt.subjects
168 assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
168 assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
169 end
169 end
170 end
170 end
171 end
171 end
172
172
173 context "issue" do
173 context "issue" do
174 should "be rendered" do
174 should "be rendered" do
175 @response.body = @gantt.subjects
175 @response.body = @gantt.subjects
176 assert_select "div.issue-subject", /#{@issue.subject}/
176 assert_select "div.issue-subject", /#{@issue.subject}/
177 end
177 end
178
178
179 should "be indented 44 (two levels)" do
179 should "be indented 44 (two levels)" do
180 @response.body = @gantt.subjects
180 @response.body = @gantt.subjects
181 assert_select "div.issue-subject[style*=left:44px]"
181 assert_select "div.issue-subject[style*=left:44px]"
182 end
182 end
183
183
184 context "assigned to a shared version of another project" do
184 context "assigned to a shared version of another project" do
185 setup do
185 setup do
186 p = Project.generate!
186 p = Project.generate!
187 p.trackers << @tracker
187 p.trackers << @tracker
188 p.enabled_module_names = [:issue_tracking]
188 p.enabled_module_names = [:issue_tracking]
189 @shared_version = Version.generate!(:sharing => 'system')
189 @shared_version = Version.generate!(:sharing => 'system')
190 p.versions << @shared_version
190 p.versions << @shared_version
191 # Reassign the issue to a shared version of another project
191 # Reassign the issue to a shared version of another project
192
192
193 @issue = Issue.generate!(:fixed_version => @shared_version,
193 @issue = Issue.generate!(:fixed_version => @shared_version,
194 :subject => "gantt#assigned_to_shared_version",
194 :subject => "gantt#assigned_to_shared_version",
195 :tracker => @tracker,
195 :tracker => @tracker,
196 :project => @project,
196 :project => @project,
197 :done_ratio => 30,
197 :done_ratio => 30,
198 :start_date => Date.yesterday,
198 :start_date => Date.yesterday,
199 :due_date => 1.week.from_now.to_date)
199 :due_date => 1.week.from_now.to_date)
200 @project.issues << @issue
200 @project.issues << @issue
201 end
201 end
202
202
203 should "be rendered" do
203 should "be rendered" do
204 @response.body = @gantt.subjects
204 @response.body = @gantt.subjects
205 assert_select "div.issue-subject", /#{@issue.subject}/
205 assert_select "div.issue-subject", /#{@issue.subject}/
206 end
206 end
207 end
207 end
208
208
209 context "with subtasks" do
209 context "with subtasks" do
210 setup do
210 setup do
211 attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
211 attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
212 @child1 = Issue.generate!(attrs.merge(:subject => 'child1', :parent_issue_id => @issue.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
212 @child1 = Issue.generate!(attrs.merge(:subject => 'child1', :parent_issue_id => @issue.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
213 @child2 = Issue.generate!(attrs.merge(:subject => 'child2', :parent_issue_id => @issue.id, :start_date => Date.today, :due_date => 1.week.from_now.to_date))
213 @child2 = Issue.generate!(attrs.merge(:subject => 'child2', :parent_issue_id => @issue.id, :start_date => Date.today, :due_date => 1.week.from_now.to_date))
214 @grandchild = Issue.generate!(attrs.merge(:subject => 'grandchild', :parent_issue_id => @child1.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
214 @grandchild = Issue.generate!(attrs.merge(:subject => 'grandchild', :parent_issue_id => @child1.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
215 end
215 end
216
216
217 should "indent subtasks" do
217 should "indent subtasks" do
218 @response.body = @gantt.subjects
218 @response.body = @gantt.subjects
219 # parent task 44px
219 # parent task 44px
220 assert_select "div.issue-subject[style*=left:44px]", /#{@issue.subject}/
220 assert_select "div.issue-subject[style*=left:44px]", /#{@issue.subject}/
221 # children 64px
221 # children 64px
222 assert_select "div.issue-subject[style*=left:64px]", /child1/
222 assert_select "div.issue-subject[style*=left:64px]", /child1/
223 assert_select "div.issue-subject[style*=left:64px]", /child2/
223 assert_select "div.issue-subject[style*=left:64px]", /child2/
224 # grandchild 84px
224 # grandchild 84px
225 assert_select "div.issue-subject[style*=left:84px]", /grandchild/, @response.body
225 assert_select "div.issue-subject[style*=left:84px]", /grandchild/, @response.body
226 end
226 end
227 end
227 end
228 end
228 end
229 end
229 end
230
230
231 context "#lines" do
231 context "#lines" do
232 setup do
232 setup do
233 create_gantt
233 create_gantt
234 @project.enabled_module_names = [:issue_tracking]
234 @project.enabled_module_names = [:issue_tracking]
235 @tracker = Tracker.generate!
235 @tracker = Tracker.generate!
236 @project.trackers << @tracker
236 @project.trackers << @tracker
237 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
237 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
238 @project.versions << @version
238 @project.versions << @version
239 @issue = Issue.generate!(:fixed_version => @version,
239 @issue = Issue.generate!(:fixed_version => @version,
240 :subject => "gantt#line_for_project",
240 :subject => "gantt#line_for_project",
241 :tracker => @tracker,
241 :tracker => @tracker,
242 :project => @project,
242 :project => @project,
243 :done_ratio => 30,
243 :done_ratio => 30,
244 :start_date => Date.yesterday,
244 :start_date => Date.yesterday,
245 :due_date => 1.week.from_now.to_date)
245 :due_date => 1.week.from_now.to_date)
246 @project.issues << @issue
246 @project.issues << @issue
247
247
248 @response.body = @gantt.lines
248 @response.body = @gantt.lines
249 end
249 end
250
250
251 context "project" do
251 context "project" do
252 should "be rendered" do
252 should "be rendered" do
253 assert_select "div.project.task_todo"
253 assert_select "div.project.task_todo"
254 assert_select "div.project.starting"
254 assert_select "div.project.starting"
255 assert_select "div.project.ending"
255 assert_select "div.project.ending"
256 assert_select "div.label.project", /#{@project.name}/
256 assert_select "div.label.project", /#{@project.name}/
257 end
257 end
258 end
258 end
259
259
260 context "version" do
260 context "version" do
261 should "be rendered" do
261 should "be rendered" do
262 assert_select "div.version.task_todo"
262 assert_select "div.version.task_todo"
263 assert_select "div.version.starting"
263 assert_select "div.version.starting"
264 assert_select "div.version.ending"
264 assert_select "div.version.ending"
265 assert_select "div.label.version", /#{@version.name}/
265 assert_select "div.label.version", /#{@version.name}/
266 end
266 end
267 end
267 end
268
268
269 context "issue" do
269 context "issue" do
270 should "be rendered" do
270 should "be rendered" do
271 assert_select "div.task_todo"
271 assert_select "div.task_todo"
272 assert_select "div.task.label", /#{@issue.done_ratio}/
272 assert_select "div.task.label", /#{@issue.done_ratio}/
273 assert_select "div.tooltip", /#{@issue.subject}/
273 assert_select "div.tooltip", /#{@issue.subject}/
274 end
274 end
275 end
275 end
276 end
276 end
277
277
278 context "#render_project" do
278 context "#render_project" do
279 should "be tested"
279 should "be tested"
280 end
280 end
281
281
282 context "#render_issues" do
282 context "#render_issues" do
283 should "be tested"
283 should "be tested"
284 end
284 end
285
285
286 context "#render_version" do
286 context "#render_version" do
287 should "be tested"
287 should "be tested"
288 end
288 end
289
289
290 context "#subject_for_project" do
290 context "#subject_for_project" do
291 setup do
291 setup do
292 create_gantt
292 create_gantt
293 end
293 end
294
294
295 context ":html format" do
295 context ":html format" do
296 should "add an absolute positioned div" do
296 should "add an absolute positioned div" do
297 @response.body = @gantt.subject_for_project(@project, {:format => :html})
297 @response.body = @gantt.subject_for_project(@project, {:format => :html})
298 assert_select "div[style*=absolute]"
298 assert_select "div[style*=absolute]"
299 end
299 end
300
300
301 should "use the indent option to move the div to the right" do
301 should "use the indent option to move the div to the right" do
302 @response.body = @gantt.subject_for_project(@project, {:format => :html, :indent => 40})
302 @response.body = @gantt.subject_for_project(@project, {:format => :html, :indent => 40})
303 assert_select "div[style*=left:40]"
303 assert_select "div[style*=left:40]"
304 end
304 end
305
305
306 should "include the project name" do
306 should "include the project name" do
307 @response.body = @gantt.subject_for_project(@project, {:format => :html})
307 @response.body = @gantt.subject_for_project(@project, {:format => :html})
308 assert_select 'div', :text => /#{@project.name}/
308 assert_select 'div', :text => /#{@project.name}/
309 end
309 end
310
310
311 should "include a link to the project" do
311 should "include a link to the project" do
312 @response.body = @gantt.subject_for_project(@project, {:format => :html})
312 @response.body = @gantt.subject_for_project(@project, {:format => :html})
313 assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
313 assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
314 end
314 end
315
315
316 should "style overdue projects" do
316 should "style overdue projects" do
317 @project.enabled_module_names = [:issue_tracking]
317 @project.enabled_module_names = [:issue_tracking]
318 @project.versions << Version.generate!(:effective_date => Date.yesterday)
318 @project.versions << Version.generate!(:effective_date => Date.yesterday)
319
319
320 assert @project.overdue?, "Need an overdue project for this test"
320 assert @project.overdue?, "Need an overdue project for this test"
321 @response.body = @gantt.subject_for_project(@project, {:format => :html})
321 @response.body = @gantt.subject_for_project(@project, {:format => :html})
322
322
323 assert_select 'div span.project-overdue'
323 assert_select 'div span.project-overdue'
324 end
324 end
325
325
326
326
327 end
327 end
328
328
329 should "test the PNG format"
329 should "test the PNG format"
330 should "test the PDF format"
330 should "test the PDF format"
331 end
331 end
332
332
333 context "#line_for_project" do
333 context "#line_for_project" do
334 setup do
334 setup do
335 create_gantt
335 create_gantt
336 @project.enabled_module_names = [:issue_tracking]
336 @project.enabled_module_names = [:issue_tracking]
337 @tracker = Tracker.generate!
337 @tracker = Tracker.generate!
338 @project.trackers << @tracker
338 @project.trackers << @tracker
339 @version = Version.generate!(:effective_date => Date.yesterday)
339 @version = Version.generate!(:effective_date => Date.yesterday)
340 @project.versions << @version
340 @project.versions << @version
341
341
342 @project.issues << Issue.generate!(:fixed_version => @version,
342 @project.issues << Issue.generate!(:fixed_version => @version,
343 :subject => "gantt#line_for_project",
343 :subject => "gantt#line_for_project",
344 :tracker => @tracker,
344 :tracker => @tracker,
345 :project => @project,
345 :project => @project,
346 :done_ratio => 30,
346 :done_ratio => 30,
347 :start_date => 1.week.ago.to_date,
347 :start_date => 1.week.ago.to_date,
348 :due_date => 1.week.from_now.to_date)
348 :due_date => 1.week.from_now.to_date)
349 end
349 end
350
350
351 context ":html format" do
351 context ":html format" do
352 context "todo line" do
352 context "todo line" do
353 should "start from the starting point on the left" do
353 should "start from the starting point on the left" do
354 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
354 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
355 assert_select "div.project.task_todo[style*=left:28px]", true, @response.body
355 assert_select "div.project.task_todo[style*=left:28px]", true, @response.body
356 end
356 end
357
357
358 should "be the total width of the project" do
358 should "be the total width of the project" do
359 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
359 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
360 assert_select "div.project.task_todo[style*=width:58px]", true, @response.body
360 assert_select "div.project.task_todo[style*=width:58px]", true, @response.body
361 end
361 end
362
362
363 end
363 end
364
364
365 context "late line" do
365 context "late line" do
366 should_eventually "start from the starting point on the left" do
366 should_eventually "start from the starting point on the left" do
367 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
367 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
368 assert_select "div.project.task_late[style*=left:28px]", true, @response.body
368 assert_select "div.project.task_late[style*=left:28px]", true, @response.body
369 end
369 end
370
370
371 should_eventually "be the total delayed width of the project" do
371 should_eventually "be the total delayed width of the project" do
372 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
372 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
373 assert_select "div.project.task_late[style*=width:30px]", true, @response.body
373 assert_select "div.project.task_late[style*=width:30px]", true, @response.body
374 end
374 end
375 end
375 end
376
376
377 context "done line" do
377 context "done line" do
378 should_eventually "start from the starting point on the left" do
378 should_eventually "start from the starting point on the left" do
379 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
379 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
380 assert_select "div.project.task_done[style*=left:28px]", true, @response.body
380 assert_select "div.project.task_done[style*=left:28px]", true, @response.body
381 end
381 end
382
382
383 should_eventually "Be the total done width of the project" do
383 should_eventually "Be the total done width of the project" do
384 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
384 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
385 assert_select "div.project.task_done[style*=width:18px]", true, @response.body
385 assert_select "div.project.task_done[style*=width:18px]", true, @response.body
386 end
386 end
387 end
387 end
388
388
389 context "starting marker" do
389 context "starting marker" do
390 should "not appear if the starting point is off the gantt chart" do
390 should "not appear if the starting point is off the gantt chart" do
391 # Shift the date range of the chart
391 # Shift the date range of the chart
392 @gantt.instance_variable_set('@date_from', Date.today)
392 @gantt.instance_variable_set('@date_from', Date.today)
393
393
394 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
394 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
395 assert_select "div.project.starting", false, @response.body
395 assert_select "div.project.starting", false, @response.body
396 end
396 end
397
397
398 should "appear at the starting point" do
398 should "appear at the starting point" do
399 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
399 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
400 assert_select "div.project.starting[style*=left:28px]", true, @response.body
400 assert_select "div.project.starting[style*=left:28px]", true, @response.body
401 end
401 end
402 end
402 end
403
403
404 context "ending marker" do
404 context "ending marker" do
405 should "not appear if the starting point is off the gantt chart" do
405 should "not appear if the starting point is off the gantt chart" do
406 # Shift the date range of the chart
406 # Shift the date range of the chart
407 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
407 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
408
408
409 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
409 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
410 assert_select "div.project.ending", false, @response.body
410 assert_select "div.project.ending", false, @response.body
411
411
412 end
412 end
413
413
414 should "appear at the end of the date range" do
414 should "appear at the end of the date range" do
415 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
415 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
416 assert_select "div.project.ending[style*=left:88px]", true, @response.body
416 assert_select "div.project.ending[style*=left:88px]", true, @response.body
417 end
417 end
418 end
418 end
419
419
420 context "status content" do
420 context "status content" do
421 should "appear at the far left, even if it's far in the past" do
421 should "appear at the far left, even if it's far in the past" do
422 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
422 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
423
423
424 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
424 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
425 assert_select "div.project.label", /#{@project.name}/
425 assert_select "div.project.label", /#{@project.name}/
426 end
426 end
427
427
428 should "show the project name" do
428 should "show the project name" do
429 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
429 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
430 assert_select "div.project.label", /#{@project.name}/
430 assert_select "div.project.label", /#{@project.name}/
431 end
431 end
432
432
433 should_eventually "show the percent complete" do
433 should_eventually "show the percent complete" do
434 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
434 @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
435 assert_select "div.project.label", /0%/
435 assert_select "div.project.label", /0%/
436 end
436 end
437 end
437 end
438 end
438 end
439
439
440 should "test the PNG format"
440 should "test the PNG format"
441 should "test the PDF format"
441 should "test the PDF format"
442 end
442 end
443
443
444 context "#subject_for_version" do
444 context "#subject_for_version" do
445 setup do
445 setup do
446 create_gantt
446 create_gantt
447 @project.enabled_module_names = [:issue_tracking]
447 @project.enabled_module_names = [:issue_tracking]
448 @tracker = Tracker.generate!
448 @tracker = Tracker.generate!
449 @project.trackers << @tracker
449 @project.trackers << @tracker
450 @version = Version.generate!(:effective_date => Date.yesterday)
450 @version = Version.generate!(:effective_date => Date.yesterday)
451 @project.versions << @version
451 @project.versions << @version
452
452
453 @project.issues << Issue.generate!(:fixed_version => @version,
453 @project.issues << Issue.generate!(:fixed_version => @version,
454 :subject => "gantt#subject_for_version",
454 :subject => "gantt#subject_for_version",
455 :tracker => @tracker,
455 :tracker => @tracker,
456 :project => @project,
456 :project => @project,
457 :start_date => Date.today)
457 :start_date => Date.today)
458
458
459 end
459 end
460
460
461 context ":html format" do
461 context ":html format" do
462 should "add an absolute positioned div" do
462 should "add an absolute positioned div" do
463 @response.body = @gantt.subject_for_version(@version, {:format => :html})
463 @response.body = @gantt.subject_for_version(@version, {:format => :html})
464 assert_select "div[style*=absolute]"
464 assert_select "div[style*=absolute]"
465 end
465 end
466
466
467 should "use the indent option to move the div to the right" do
467 should "use the indent option to move the div to the right" do
468 @response.body = @gantt.subject_for_version(@version, {:format => :html, :indent => 40})
468 @response.body = @gantt.subject_for_version(@version, {:format => :html, :indent => 40})
469 assert_select "div[style*=left:40]"
469 assert_select "div[style*=left:40]"
470 end
470 end
471
471
472 should "include the version name" do
472 should "include the version name" do
473 @response.body = @gantt.subject_for_version(@version, {:format => :html})
473 @response.body = @gantt.subject_for_version(@version, {:format => :html})
474 assert_select 'div', :text => /#{@version.name}/
474 assert_select 'div', :text => /#{@version.name}/
475 end
475 end
476
476
477 should "include a link to the version" do
477 should "include a link to the version" do
478 @response.body = @gantt.subject_for_version(@version, {:format => :html})
478 @response.body = @gantt.subject_for_version(@version, {:format => :html})
479 assert_select 'a[href=?]', Regexp.escape("/versions/show/#{@version.to_param}"), :text => /#{@version.name}/
479 assert_select 'a[href=?]', Regexp.escape("/versions/#{@version.to_param}"), :text => /#{@version.name}/
480 end
480 end
481
481
482 should "style late versions" do
482 should "style late versions" do
483 assert @version.overdue?, "Need an overdue version for this test"
483 assert @version.overdue?, "Need an overdue version for this test"
484 @response.body = @gantt.subject_for_version(@version, {:format => :html})
484 @response.body = @gantt.subject_for_version(@version, {:format => :html})
485
485
486 assert_select 'div span.version-behind-schedule'
486 assert_select 'div span.version-behind-schedule'
487 end
487 end
488
488
489 should "style behind schedule versions" do
489 should "style behind schedule versions" do
490 assert @version.behind_schedule?, "Need a behind schedule version for this test"
490 assert @version.behind_schedule?, "Need a behind schedule version for this test"
491 @response.body = @gantt.subject_for_version(@version, {:format => :html})
491 @response.body = @gantt.subject_for_version(@version, {:format => :html})
492
492
493 assert_select 'div span.version-behind-schedule'
493 assert_select 'div span.version-behind-schedule'
494 end
494 end
495 end
495 end
496 should "test the PNG format"
496 should "test the PNG format"
497 should "test the PDF format"
497 should "test the PDF format"
498 end
498 end
499
499
500 context "#line_for_version" do
500 context "#line_for_version" do
501 setup do
501 setup do
502 create_gantt
502 create_gantt
503 @project.enabled_module_names = [:issue_tracking]
503 @project.enabled_module_names = [:issue_tracking]
504 @tracker = Tracker.generate!
504 @tracker = Tracker.generate!
505 @project.trackers << @tracker
505 @project.trackers << @tracker
506 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
506 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
507 @project.versions << @version
507 @project.versions << @version
508
508
509 @project.issues << Issue.generate!(:fixed_version => @version,
509 @project.issues << Issue.generate!(:fixed_version => @version,
510 :subject => "gantt#line_for_project",
510 :subject => "gantt#line_for_project",
511 :tracker => @tracker,
511 :tracker => @tracker,
512 :project => @project,
512 :project => @project,
513 :done_ratio => 30,
513 :done_ratio => 30,
514 :start_date => 1.week.ago.to_date,
514 :start_date => 1.week.ago.to_date,
515 :due_date => 1.week.from_now.to_date)
515 :due_date => 1.week.from_now.to_date)
516 end
516 end
517
517
518 context ":html format" do
518 context ":html format" do
519 context "todo line" do
519 context "todo line" do
520 should "start from the starting point on the left" do
520 should "start from the starting point on the left" do
521 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
521 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
522 assert_select "div.version.task_todo[style*=left:28px]", true, @response.body
522 assert_select "div.version.task_todo[style*=left:28px]", true, @response.body
523 end
523 end
524
524
525 should "be the total width of the version" do
525 should "be the total width of the version" do
526 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
526 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
527 assert_select "div.version.task_todo[style*=width:58px]", true, @response.body
527 assert_select "div.version.task_todo[style*=width:58px]", true, @response.body
528 end
528 end
529
529
530 end
530 end
531
531
532 context "late line" do
532 context "late line" do
533 should "start from the starting point on the left" do
533 should "start from the starting point on the left" do
534 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
534 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
535 assert_select "div.version.task_late[style*=left:28px]", true, @response.body
535 assert_select "div.version.task_late[style*=left:28px]", true, @response.body
536 end
536 end
537
537
538 should "be the total delayed width of the version" do
538 should "be the total delayed width of the version" do
539 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
539 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
540 assert_select "div.version.task_late[style*=width:30px]", true, @response.body
540 assert_select "div.version.task_late[style*=width:30px]", true, @response.body
541 end
541 end
542 end
542 end
543
543
544 context "done line" do
544 context "done line" do
545 should "start from the starting point on the left" do
545 should "start from the starting point on the left" do
546 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
546 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
547 assert_select "div.version.task_done[style*=left:28px]", true, @response.body
547 assert_select "div.version.task_done[style*=left:28px]", true, @response.body
548 end
548 end
549
549
550 should "be the total done width of the version" do
550 should "be the total done width of the version" do
551 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
551 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
552 assert_select "div.version.task_done[style*=width:16px]", true, @response.body
552 assert_select "div.version.task_done[style*=width:16px]", true, @response.body
553 end
553 end
554 end
554 end
555
555
556 context "starting marker" do
556 context "starting marker" do
557 should "not appear if the starting point is off the gantt chart" do
557 should "not appear if the starting point is off the gantt chart" do
558 # Shift the date range of the chart
558 # Shift the date range of the chart
559 @gantt.instance_variable_set('@date_from', Date.today)
559 @gantt.instance_variable_set('@date_from', Date.today)
560
560
561 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
561 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
562 assert_select "div.version.starting", false
562 assert_select "div.version.starting", false
563 end
563 end
564
564
565 should "appear at the starting point" do
565 should "appear at the starting point" do
566 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
566 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
567 assert_select "div.version.starting[style*=left:28px]", true, @response.body
567 assert_select "div.version.starting[style*=left:28px]", true, @response.body
568 end
568 end
569 end
569 end
570
570
571 context "ending marker" do
571 context "ending marker" do
572 should "not appear if the starting point is off the gantt chart" do
572 should "not appear if the starting point is off the gantt chart" do
573 # Shift the date range of the chart
573 # Shift the date range of the chart
574 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
574 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
575
575
576 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
576 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
577 assert_select "div.version.ending", false
577 assert_select "div.version.ending", false
578
578
579 end
579 end
580
580
581 should "appear at the end of the date range" do
581 should "appear at the end of the date range" do
582 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
582 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
583 assert_select "div.version.ending[style*=left:88px]", true, @response.body
583 assert_select "div.version.ending[style*=left:88px]", true, @response.body
584 end
584 end
585 end
585 end
586
586
587 context "status content" do
587 context "status content" do
588 should "appear at the far left, even if it's far in the past" do
588 should "appear at the far left, even if it's far in the past" do
589 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
589 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
590
590
591 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
591 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
592 assert_select "div.version.label", /#{@version.name}/
592 assert_select "div.version.label", /#{@version.name}/
593 end
593 end
594
594
595 should "show the version name" do
595 should "show the version name" do
596 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
596 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
597 assert_select "div.version.label", /#{@version.name}/
597 assert_select "div.version.label", /#{@version.name}/
598 end
598 end
599
599
600 should "show the percent complete" do
600 should "show the percent complete" do
601 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
601 @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
602 assert_select "div.version.label", /30%/
602 assert_select "div.version.label", /30%/
603 end
603 end
604 end
604 end
605 end
605 end
606
606
607 should "test the PNG format"
607 should "test the PNG format"
608 should "test the PDF format"
608 should "test the PDF format"
609 end
609 end
610
610
611 context "#subject_for_issue" do
611 context "#subject_for_issue" do
612 setup do
612 setup do
613 create_gantt
613 create_gantt
614 @project.enabled_module_names = [:issue_tracking]
614 @project.enabled_module_names = [:issue_tracking]
615 @tracker = Tracker.generate!
615 @tracker = Tracker.generate!
616 @project.trackers << @tracker
616 @project.trackers << @tracker
617
617
618 @issue = Issue.generate!(:subject => "gantt#subject_for_issue",
618 @issue = Issue.generate!(:subject => "gantt#subject_for_issue",
619 :tracker => @tracker,
619 :tracker => @tracker,
620 :project => @project,
620 :project => @project,
621 :start_date => 3.days.ago.to_date,
621 :start_date => 3.days.ago.to_date,
622 :due_date => Date.yesterday)
622 :due_date => Date.yesterday)
623 @project.issues << @issue
623 @project.issues << @issue
624
624
625 end
625 end
626
626
627 context ":html format" do
627 context ":html format" do
628 should "add an absolute positioned div" do
628 should "add an absolute positioned div" do
629 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
629 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
630 assert_select "div[style*=absolute]"
630 assert_select "div[style*=absolute]"
631 end
631 end
632
632
633 should "use the indent option to move the div to the right" do
633 should "use the indent option to move the div to the right" do
634 @response.body = @gantt.subject_for_issue(@issue, {:format => :html, :indent => 40})
634 @response.body = @gantt.subject_for_issue(@issue, {:format => :html, :indent => 40})
635 assert_select "div[style*=left:40]"
635 assert_select "div[style*=left:40]"
636 end
636 end
637
637
638 should "include the issue subject" do
638 should "include the issue subject" do
639 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
639 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
640 assert_select 'div', :text => /#{@issue.subject}/
640 assert_select 'div', :text => /#{@issue.subject}/
641 end
641 end
642
642
643 should "include a link to the issue" do
643 should "include a link to the issue" do
644 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
644 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
645 assert_select 'a[href=?]', Regexp.escape("/issues/#{@issue.to_param}"), :text => /#{@tracker.name} ##{@issue.id}/
645 assert_select 'a[href=?]', Regexp.escape("/issues/#{@issue.to_param}"), :text => /#{@tracker.name} ##{@issue.id}/
646 end
646 end
647
647
648 should "style overdue issues" do
648 should "style overdue issues" do
649 assert @issue.overdue?, "Need an overdue issue for this test"
649 assert @issue.overdue?, "Need an overdue issue for this test"
650 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
650 @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
651
651
652 assert_select 'div span.issue-overdue'
652 assert_select 'div span.issue-overdue'
653 end
653 end
654
654
655 end
655 end
656 should "test the PNG format"
656 should "test the PNG format"
657 should "test the PDF format"
657 should "test the PDF format"
658 end
658 end
659
659
660 context "#line_for_issue" do
660 context "#line_for_issue" do
661 setup do
661 setup do
662 create_gantt
662 create_gantt
663 @project.enabled_module_names = [:issue_tracking]
663 @project.enabled_module_names = [:issue_tracking]
664 @tracker = Tracker.generate!
664 @tracker = Tracker.generate!
665 @project.trackers << @tracker
665 @project.trackers << @tracker
666 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
666 @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
667 @project.versions << @version
667 @project.versions << @version
668 @issue = Issue.generate!(:fixed_version => @version,
668 @issue = Issue.generate!(:fixed_version => @version,
669 :subject => "gantt#line_for_project",
669 :subject => "gantt#line_for_project",
670 :tracker => @tracker,
670 :tracker => @tracker,
671 :project => @project,
671 :project => @project,
672 :done_ratio => 30,
672 :done_ratio => 30,
673 :start_date => 1.week.ago.to_date,
673 :start_date => 1.week.ago.to_date,
674 :due_date => 1.week.from_now.to_date)
674 :due_date => 1.week.from_now.to_date)
675 @project.issues << @issue
675 @project.issues << @issue
676 end
676 end
677
677
678 context ":html format" do
678 context ":html format" do
679 context "todo line" do
679 context "todo line" do
680 should "start from the starting point on the left" do
680 should "start from the starting point on the left" do
681 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
681 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
682 assert_select "div.task_todo[style*=left:28px]", true, @response.body
682 assert_select "div.task_todo[style*=left:28px]", true, @response.body
683 end
683 end
684
684
685 should "be the total width of the issue" do
685 should "be the total width of the issue" do
686 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
686 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
687 assert_select "div.task_todo[style*=width:58px]", true, @response.body
687 assert_select "div.task_todo[style*=width:58px]", true, @response.body
688 end
688 end
689
689
690 end
690 end
691
691
692 context "late line" do
692 context "late line" do
693 should "start from the starting point on the left" do
693 should "start from the starting point on the left" do
694 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
694 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
695 assert_select "div.task_late[style*=left:28px]", true, @response.body
695 assert_select "div.task_late[style*=left:28px]", true, @response.body
696 end
696 end
697
697
698 should "be the total delayed width of the issue" do
698 should "be the total delayed width of the issue" do
699 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
699 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
700 assert_select "div.task_late[style*=width:30px]", true, @response.body
700 assert_select "div.task_late[style*=width:30px]", true, @response.body
701 end
701 end
702 end
702 end
703
703
704 context "done line" do
704 context "done line" do
705 should "start from the starting point on the left" do
705 should "start from the starting point on the left" do
706 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
706 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
707 assert_select "div.task_done[style*=left:28px]", true, @response.body
707 assert_select "div.task_done[style*=left:28px]", true, @response.body
708 end
708 end
709
709
710 should "be the total done width of the issue" do
710 should "be the total done width of the issue" do
711 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
711 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
712 # 15 days * 4 px * 30% - 2 px for borders = 16 px
712 # 15 days * 4 px * 30% - 2 px for borders = 16 px
713 assert_select "div.task_done[style*=width:16px]", true, @response.body
713 assert_select "div.task_done[style*=width:16px]", true, @response.body
714 end
714 end
715
715
716 should "not be the total done width if the chart starts after issue start date" do
716 should "not be the total done width if the chart starts after issue start date" do
717 create_gantt(@project, :date_from => 5.days.ago.to_date)
717 create_gantt(@project, :date_from => 5.days.ago.to_date)
718
718
719 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
719 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
720 assert_select "div.task_done[style*=left:0px]", true, @response.body
720 assert_select "div.task_done[style*=left:0px]", true, @response.body
721 assert_select "div.task_done[style*=width:8px]", true, @response.body
721 assert_select "div.task_done[style*=width:8px]", true, @response.body
722 end
722 end
723
723
724 context "for completed issue" do
724 context "for completed issue" do
725 setup do
725 setup do
726 @issue.done_ratio = 100
726 @issue.done_ratio = 100
727 end
727 end
728
728
729 should "be the total width of the issue" do
729 should "be the total width of the issue" do
730 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
730 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
731 assert_select "div.task_done[style*=width:58px]", true, @response.body
731 assert_select "div.task_done[style*=width:58px]", true, @response.body
732 end
732 end
733
733
734 should "be the total width of the issue with due_date=start_date" do
734 should "be the total width of the issue with due_date=start_date" do
735 @issue.due_date = @issue.start_date
735 @issue.due_date = @issue.start_date
736 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
736 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
737 assert_select "div.task_done[style*=width:2px]", true, @response.body
737 assert_select "div.task_done[style*=width:2px]", true, @response.body
738 end
738 end
739 end
739 end
740 end
740 end
741
741
742 context "status content" do
742 context "status content" do
743 should "appear at the far left, even if it's far in the past" do
743 should "appear at the far left, even if it's far in the past" do
744 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
744 @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
745
745
746 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
746 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
747 assert_select "div.task.label", true, @response.body
747 assert_select "div.task.label", true, @response.body
748 end
748 end
749
749
750 should "show the issue status" do
750 should "show the issue status" do
751 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
751 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
752 assert_select "div.task.label", /#{@issue.status.name}/
752 assert_select "div.task.label", /#{@issue.status.name}/
753 end
753 end
754
754
755 should "show the percent complete" do
755 should "show the percent complete" do
756 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
756 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
757 assert_select "div.task.label", /30%/
757 assert_select "div.task.label", /30%/
758 end
758 end
759 end
759 end
760 end
760 end
761
761
762 should "have an issue tooltip" do
762 should "have an issue tooltip" do
763 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
763 @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
764 assert_select "div.tooltip", /#{@issue.subject}/
764 assert_select "div.tooltip", /#{@issue.subject}/
765 end
765 end
766
766
767 should "test the PNG format"
767 should "test the PNG format"
768 should "test the PDF format"
768 should "test the PDF format"
769 end
769 end
770
770
771 context "#to_image" do
771 context "#to_image" do
772 should "be tested"
772 should "be tested"
773 end
773 end
774
774
775 context "#to_pdf" do
775 context "#to_pdf" do
776 should "be tested"
776 should "be tested"
777 end
777 end
778
778
779 end
779 end
General Comments 0
You need to be logged in to leave comments. Login now