##// END OF EJS Templates
Include url helpers in helper tests....
Jean-Philippe Lang -
r15304:ff50094d3e45
parent child
Show More
@@ -1,42 +1,43
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class GroupsHelperTest < Redmine::HelperTest
21 21 include Redmine::I18n
22 22 include ERB::Util
23 23 include GroupsHelper
24 include Rails.application.routes.url_helpers
24 25
25 26 fixtures :users
26 27
27 28 def test_render_principals_for_new_group_users
28 29 group = Group.generate!
29 30
30 31 result = render_principals_for_new_group_users(group)
31 32 assert_select_in result, 'input[name=?][value="2"]', 'user_ids[]'
32 33 end
33 34
34 35 def test_render_principals_for_new_group_users_with_limited_results_should_paginate
35 36 group = Group.generate!
36 37
37 38 result = render_principals_for_new_group_users(group, 3)
38 39 assert_select_in result, 'span.pagination'
39 40 assert_select_in result, 'span.pagination li.current span', :text => '1'
40 41 assert_select_in result, 'a[href=?]', "/groups/#{group.id}/autocomplete_for_user.js?page=2", :text => '2'
41 42 end
42 43 end
@@ -1,339 +1,339
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class IssuesHelperTest < Redmine::HelperTest
21 21 include Redmine::I18n
22 22 include IssuesHelper
23 23 include CustomFieldsHelper
24 24 include ERB::Util
25 25 include Rails.application.routes.url_helpers
26 26
27 27 fixtures :projects, :trackers, :issue_statuses, :issues,
28 28 :enumerations, :users, :issue_categories,
29 29 :projects_trackers,
30 30 :roles,
31 31 :member_roles,
32 32 :members,
33 33 :enabled_modules,
34 34 :custom_fields,
35 35 :attachments,
36 36 :versions
37 37
38 38 def setup
39 39 super
40 40 set_language_if_valid('en')
41 41 User.current = nil
42 42 end
43 43
44 44 def test_issue_heading
45 45 assert_equal "Bug #1", issue_heading(Issue.find(1))
46 46 end
47 47
48 48 def test_issues_destroy_confirmation_message_with_one_root_issue
49 49 assert_equal l(:text_issues_destroy_confirmation),
50 50 issues_destroy_confirmation_message(Issue.find(1))
51 51 end
52 52
53 53 def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
54 54 assert_equal l(:text_issues_destroy_confirmation),
55 55 issues_destroy_confirmation_message(Issue.find([1, 2]))
56 56 end
57 57
58 58 def test_issues_destroy_confirmation_message_with_one_parent_issue
59 Issue.find(2).update_attribute :parent_issue_id, 1
59 Issue.find(2).update! :parent_issue_id => 1
60 60 assert_equal l(:text_issues_destroy_confirmation) + "\n" +
61 61 l(:text_issues_destroy_descendants_confirmation, :count => 1),
62 62 issues_destroy_confirmation_message(Issue.find(1))
63 63 end
64 64
65 65 def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
66 Issue.find(2).update_attribute :parent_issue_id, 1
66 Issue.find(2).update! :parent_issue_id => 1
67 67 assert_equal l(:text_issues_destroy_confirmation),
68 68 issues_destroy_confirmation_message(Issue.find([1, 2]))
69 69 end
70 70
71 71 def test_issues_destroy_confirmation_message_with_issues_that_share_descendants
72 72 root = Issue.generate!
73 73 child = Issue.generate!(:parent_issue_id => root.id)
74 74 Issue.generate!(:parent_issue_id => child.id)
75 75
76 76 assert_equal l(:text_issues_destroy_confirmation) + "\n" +
77 77 l(:text_issues_destroy_descendants_confirmation, :count => 1),
78 78 issues_destroy_confirmation_message([root.reload, child.reload])
79 79 end
80 80
81 81 test 'show_detail with no_html should show a changing attribute' do
82 82 detail = JournalDetail.new(:property => 'attr', :old_value => '40',
83 83 :value => '100', :prop_key => 'done_ratio')
84 84 assert_equal "% Done changed from 40 to 100", show_detail(detail, true)
85 85 end
86 86
87 87 test 'show_detail with no_html should show a new attribute' do
88 88 detail = JournalDetail.new(:property => 'attr', :old_value => nil,
89 89 :value => '100', :prop_key => 'done_ratio')
90 90 assert_equal "% Done set to 100", show_detail(detail, true)
91 91 end
92 92
93 93 test 'show_detail with no_html should show a deleted attribute' do
94 94 detail = JournalDetail.new(:property => 'attr', :old_value => '50',
95 95 :value => nil, :prop_key => 'done_ratio')
96 96 assert_equal "% Done deleted (50)", show_detail(detail, true)
97 97 end
98 98
99 99 test 'show_detail with html should show a changing attribute with HTML highlights' do
100 100 detail = JournalDetail.new(:property => 'attr', :old_value => '40',
101 101 :value => '100', :prop_key => 'done_ratio')
102 102 html = show_detail(detail, false)
103 103 assert_include '<strong>% Done</strong>', html
104 104 assert_include '<i>40</i>', html
105 105 assert_include '<i>100</i>', html
106 106 end
107 107
108 108 test 'show_detail with html should show a new attribute with HTML highlights' do
109 109 detail = JournalDetail.new(:property => 'attr', :old_value => nil,
110 110 :value => '100', :prop_key => 'done_ratio')
111 111 html = show_detail(detail, false)
112 112 assert_include '<strong>% Done</strong>', html
113 113 assert_include '<i>100</i>', html
114 114 end
115 115
116 116 test 'show_detail with html should show a deleted attribute with HTML highlights' do
117 117 detail = JournalDetail.new(:property => 'attr', :old_value => '50',
118 118 :value => nil, :prop_key => 'done_ratio')
119 119 html = show_detail(detail, false)
120 120 assert_include '<strong>% Done</strong>', html
121 121 assert_include '<del><i>50</i></del>', html
122 122 end
123 123
124 124 test 'show_detail with a start_date attribute should format the dates' do
125 125 detail = JournalDetail.new(
126 126 :property => 'attr',
127 127 :old_value => '2010-01-01',
128 128 :value => '2010-01-31',
129 129 :prop_key => 'start_date'
130 130 )
131 131 with_settings :date_format => '%m/%d/%Y' do
132 132 assert_match "01/31/2010", show_detail(detail, true)
133 133 assert_match "01/01/2010", show_detail(detail, true)
134 134 end
135 135 end
136 136
137 137 test 'show_detail with a due_date attribute should format the dates' do
138 138 detail = JournalDetail.new(
139 139 :property => 'attr',
140 140 :old_value => '2010-01-01',
141 141 :value => '2010-01-31',
142 142 :prop_key => 'due_date'
143 143 )
144 144 with_settings :date_format => '%m/%d/%Y' do
145 145 assert_match "01/31/2010", show_detail(detail, true)
146 146 assert_match "01/01/2010", show_detail(detail, true)
147 147 end
148 148 end
149 149
150 150 test 'show_detail should show old and new values with a project attribute' do
151 151 detail = JournalDetail.new(:property => 'attr', :prop_key => 'project_id',
152 152 :old_value => 1, :value => 2)
153 153 assert_match 'eCookbook', show_detail(detail, true)
154 154 assert_match 'OnlineStore', show_detail(detail, true)
155 155 end
156 156
157 157 test 'show_detail should show old and new values with a issue status attribute' do
158 158 detail = JournalDetail.new(:property => 'attr', :prop_key => 'status_id',
159 159 :old_value => 1, :value => 2)
160 160 assert_match 'New', show_detail(detail, true)
161 161 assert_match 'Assigned', show_detail(detail, true)
162 162 end
163 163
164 164 test 'show_detail should show old and new values with a tracker attribute' do
165 165 detail = JournalDetail.new(:property => 'attr', :prop_key => 'tracker_id',
166 166 :old_value => 1, :value => 2)
167 167 assert_match 'Bug', show_detail(detail, true)
168 168 assert_match 'Feature request', show_detail(detail, true)
169 169 end
170 170
171 171 test 'show_detail should show old and new values with a assigned to attribute' do
172 172 detail = JournalDetail.new(:property => 'attr', :prop_key => 'assigned_to_id',
173 173 :old_value => 1, :value => 2)
174 174 assert_match 'Redmine Admin', show_detail(detail, true)
175 175 assert_match 'John Smith', show_detail(detail, true)
176 176 end
177 177
178 178 test 'show_detail should show old and new values with a priority attribute' do
179 179 detail = JournalDetail.new(:property => 'attr', :prop_key => 'priority_id',
180 180 :old_value => 4, :value => 5)
181 181 assert_match 'Low', show_detail(detail, true)
182 182 assert_match 'Normal', show_detail(detail, true)
183 183 end
184 184
185 185 test 'show_detail should show old and new values with a category attribute' do
186 186 detail = JournalDetail.new(:property => 'attr', :prop_key => 'category_id',
187 187 :old_value => 1, :value => 2)
188 188 assert_match 'Printing', show_detail(detail, true)
189 189 assert_match 'Recipes', show_detail(detail, true)
190 190 end
191 191
192 192 test 'show_detail should show old and new values with a fixed version attribute' do
193 193 detail = JournalDetail.new(:property => 'attr', :prop_key => 'fixed_version_id',
194 194 :old_value => 1, :value => 2)
195 195 assert_match '0.1', show_detail(detail, true)
196 196 assert_match '1.0', show_detail(detail, true)
197 197 end
198 198
199 199 test 'show_detail should show old and new values with a estimated hours attribute' do
200 200 detail = JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours',
201 201 :old_value => '5', :value => '6.3')
202 202 assert_match '5.00', show_detail(detail, true)
203 203 assert_match '6.30', show_detail(detail, true)
204 204 end
205 205
206 206 test 'show_detail should not show values with a description attribute' do
207 207 detail = JournalDetail.new(:property => 'attr', :prop_key => 'description',
208 208 :old_value => 'Foo', :value => 'Bar')
209 209 assert_equal 'Description updated', show_detail(detail, true)
210 210 end
211 211
212 212 test 'show_detail should show old and new values with a custom field' do
213 213 detail = JournalDetail.new(:property => 'cf', :prop_key => '1',
214 214 :old_value => 'MySQL', :value => 'PostgreSQL')
215 215 assert_equal 'Database changed from MySQL to PostgreSQL', show_detail(detail, true)
216 216 end
217 217
218 218 test 'show_detail should not show values with a long text custom field' do
219 219 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text')
220 220 detail = JournalDetail.new(:property => 'cf', :prop_key => field.id,
221 221 :old_value => 'Foo', :value => 'Bar')
222 222 assert_equal 'Long field updated', show_detail(detail, true)
223 223 end
224 224
225 225 test 'show_detail should show added file' do
226 226 detail = JournalDetail.new(:property => 'attachment', :prop_key => '1',
227 227 :old_value => nil, :value => 'error281.txt')
228 228 assert_match 'error281.txt', show_detail(detail, true)
229 229 end
230 230
231 231 test 'show_detail should show removed file' do
232 232 detail = JournalDetail.new(:property => 'attachment', :prop_key => '1',
233 233 :old_value => 'error281.txt', :value => nil)
234 234 assert_match 'error281.txt', show_detail(detail, true)
235 235 end
236 236
237 237 def test_show_detail_relation_added
238 238 detail = JournalDetail.new(:property => 'relation',
239 239 :prop_key => 'precedes',
240 240 :value => 1)
241 241 assert_equal "Precedes Bug #1: Cannot print recipes added", show_detail(detail, true)
242 242 str = link_to("Bug #1", "/issues/1", :class => Issue.find(1).css_classes)
243 243 assert_equal "<strong>Precedes</strong> <i>#{str}: Cannot print recipes</i> added",
244 244 show_detail(detail, false)
245 245 end
246 246
247 247 def test_show_detail_relation_added_with_inexistant_issue
248 248 inexistant_issue_number = 9999
249 249 assert_nil Issue.find_by_id(inexistant_issue_number)
250 250 detail = JournalDetail.new(:property => 'relation',
251 251 :prop_key => 'precedes',
252 252 :value => inexistant_issue_number)
253 253 assert_equal "Precedes Issue ##{inexistant_issue_number} added", show_detail(detail, true)
254 254 assert_equal "<strong>Precedes</strong> <i>Issue ##{inexistant_issue_number}</i> added", show_detail(detail, false)
255 255 end
256 256
257 257 def test_show_detail_relation_added_should_not_disclose_issue_that_is_not_visible
258 258 issue = Issue.generate!(:is_private => true)
259 259 detail = JournalDetail.new(:property => 'relation',
260 260 :prop_key => 'precedes',
261 261 :value => issue.id)
262 262
263 263 assert_equal "Precedes Issue ##{issue.id} added", show_detail(detail, true)
264 264 assert_equal "<strong>Precedes</strong> <i>Issue ##{issue.id}</i> added", show_detail(detail, false)
265 265 end
266 266
267 267 def test_show_detail_relation_deleted
268 268 detail = JournalDetail.new(:property => 'relation',
269 269 :prop_key => 'precedes',
270 270 :old_value => 1)
271 271 assert_equal "Precedes deleted (Bug #1: Cannot print recipes)", show_detail(detail, true)
272 272 str = link_to("Bug #1",
273 273 "/issues/1",
274 274 :class => Issue.find(1).css_classes)
275 275 assert_equal "<strong>Precedes</strong> deleted (<i>#{str}: Cannot print recipes</i>)",
276 276 show_detail(detail, false)
277 277 end
278 278
279 279 def test_show_detail_relation_deleted_with_inexistant_issue
280 280 inexistant_issue_number = 9999
281 281 assert_nil Issue.find_by_id(inexistant_issue_number)
282 282 detail = JournalDetail.new(:property => 'relation',
283 283 :prop_key => 'precedes',
284 284 :old_value => inexistant_issue_number)
285 285 assert_equal "Precedes deleted (Issue #9999)", show_detail(detail, true)
286 286 assert_equal "<strong>Precedes</strong> deleted (<i>Issue #9999</i>)", show_detail(detail, false)
287 287 end
288 288
289 289 def test_show_detail_relation_deleted_should_not_disclose_issue_that_is_not_visible
290 290 issue = Issue.generate!(:is_private => true)
291 291 detail = JournalDetail.new(:property => 'relation',
292 292 :prop_key => 'precedes',
293 293 :old_value => issue.id)
294 294
295 295 assert_equal "Precedes deleted (Issue ##{issue.id})", show_detail(detail, true)
296 296 assert_equal "<strong>Precedes</strong> deleted (<i>Issue ##{issue.id}</i>)", show_detail(detail, false)
297 297 end
298 298
299 299 def test_details_to_strings_with_multiple_values_removed_from_custom_field
300 300 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
301 301 details = []
302 302 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '1', :value => nil)
303 303 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '3', :value => nil)
304 304
305 305 assert_equal ["User deleted (Dave Lopper, Redmine Admin)"], details_to_strings(details, true)
306 306 assert_equal ["<strong>User</strong> deleted (<del><i>Dave Lopper, Redmine Admin</i></del>)"], details_to_strings(details, false)
307 307 end
308 308
309 309 def test_details_to_strings_with_multiple_values_added_to_custom_field
310 310 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
311 311 details = []
312 312 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '1')
313 313 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '3')
314 314
315 315 assert_equal ["User Dave Lopper, Redmine Admin added"], details_to_strings(details, true)
316 316 assert_equal ["<strong>User</strong> <i>Dave Lopper, Redmine Admin</i> added"], details_to_strings(details, false)
317 317 end
318 318
319 319 def test_details_to_strings_with_multiple_values_added_and_removed_from_custom_field
320 320 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
321 321 details = []
322 322 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '1')
323 323 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '2', :value => nil)
324 324 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '3', :value => nil)
325 325
326 326 assert_equal [
327 327 "User Redmine Admin added",
328 328 "User deleted (Dave Lopper, John Smith)"
329 329 ], details_to_strings(details, true)
330 330 assert_equal [
331 331 "<strong>User</strong> <i>Redmine Admin</i> added",
332 332 "<strong>User</strong> deleted (<del><i>Dave Lopper, John Smith</i></del>)"
333 333 ], details_to_strings(details, false)
334 334 end
335 335
336 336 def test_find_name_by_reflection_should_return_nil_for_missing_record
337 337 assert_nil find_name_by_reflection('status', 99)
338 338 end
339 339 end
@@ -1,43 +1,44
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class MembersHelperTest < Redmine::HelperTest
21 21 include Redmine::I18n
22 22 include ERB::Util
23 23 include MembersHelper
24 include Rails.application.routes.url_helpers
24 25
25 26 fixtures :projects, :users, :members, :member_roles,
26 27 :trackers, :issue_statuses
27 28
28 29 def test_render_principals_for_new_members
29 30 project = Project.generate!
30 31
31 32 result = render_principals_for_new_members(project)
32 33 assert_select_in result, 'input[name=?][value="2"]', 'membership[user_ids][]'
33 34 end
34 35
35 36 def test_render_principals_for_new_members_with_limited_results_should_paginate
36 37 project = Project.generate!
37 38
38 39 result = render_principals_for_new_members(project, 3)
39 40 assert_select_in result, 'span.pagination'
40 41 assert_select_in result, 'span.pagination li.current span', :text => '1'
41 42 assert_select_in result, 'a[href=?]', "/projects/#{project.identifier}/memberships/autocomplete.js?page=2", :text => '2'
42 43 end
43 44 end
@@ -1,498 +1,498
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 class Redmine::Helpers::GanttHelperTest < ActionView::TestCase
20 class Redmine::Helpers::GanttHelperTest < Redmine::HelperTest
21 21 fixtures :projects, :trackers, :issue_statuses,
22 22 :enumerations, :users, :issue_categories
23 23
24 24 include ProjectsHelper
25 25 include IssuesHelper
26 26 include ERB::Util
27 27 include Rails.application.routes.url_helpers
28 28
29 29 def setup
30 30 setup_with_controller
31 31 User.current = User.find(1)
32 32 end
33 33
34 34 def today
35 35 @today ||= Date.today
36 36 end
37 37 private :today
38 38
39 39 def gantt_start
40 40 @gantt.date_from
41 41 end
42 42
43 43 # Creates a Gantt chart for a 4 week span
44 44 def create_gantt(project=Project.generate!, options={})
45 45 @project = project
46 46 @gantt = Redmine::Helpers::Gantt.new(options)
47 47 @gantt.project = @project
48 48 @gantt.query = IssueQuery.new(:project => @project, :name => 'Gantt')
49 49 @gantt.view = self
50 50 @gantt.instance_variable_set('@date_from', options[:date_from] || (today - 14))
51 51 @gantt.instance_variable_set('@date_to', options[:date_to] || (today + 14))
52 52 end
53 53 private :create_gantt
54 54
55 55 test "#number_of_rows with one project should return the number of rows just for that project" do
56 56 p1, p2 = Project.generate!, Project.generate!
57 57 i1, i2 = Issue.generate!(:project => p1), Issue.generate!(:project => p2)
58 58 create_gantt(p1)
59 59 assert_equal 2, @gantt.number_of_rows
60 60 end
61 61
62 62 test "#number_of_rows with no project should return the total number of rows for all the projects, resursively" do
63 63 p1, p2 = Project.generate!, Project.generate!
64 64 create_gantt(nil)
65 65 # fix the return value of #number_of_rows_on_project() to an arbitrary value
66 66 # so that we really only test #number_of_rows
67 67 @gantt.stubs(:number_of_rows_on_project).returns(7)
68 68 # also fix #projects because we want to test #number_of_rows in isolation
69 69 @gantt.stubs(:projects).returns(Project.all)
70 70 # actual test
71 71 assert_equal Project.count*7, @gantt.number_of_rows
72 72 end
73 73
74 74 test "#number_of_rows should not exceed max_rows option" do
75 75 p = Project.generate!
76 76 5.times do
77 77 Issue.generate!(:project => p)
78 78 end
79 79 create_gantt(p)
80 80 @gantt.render
81 81 assert_equal 6, @gantt.number_of_rows
82 82 assert !@gantt.truncated
83 83 create_gantt(p, :max_rows => 3)
84 84 @gantt.render
85 85 assert_equal 3, @gantt.number_of_rows
86 86 assert @gantt.truncated
87 87 end
88 88
89 89 test "#number_of_rows_on_project should count 0 for an empty the project" do
90 90 create_gantt
91 91 assert_equal 0, @gantt.number_of_rows_on_project(@project)
92 92 end
93 93
94 94 test "#number_of_rows_on_project should count the number of issues without a version" do
95 95 create_gantt
96 96 @project.issues << Issue.generate!(:project => @project, :fixed_version => nil)
97 97 assert_equal 2, @gantt.number_of_rows_on_project(@project)
98 98 end
99 99
100 100 test "#number_of_rows_on_project should count the number of issues on versions, including cross-project" do
101 101 create_gantt
102 102 version = Version.generate!
103 103 @project.versions << version
104 104 @project.issues << Issue.generate!(:project => @project, :fixed_version => version)
105 105 assert_equal 3, @gantt.number_of_rows_on_project(@project)
106 106 end
107 107
108 108 def setup_subjects
109 109 create_gantt
110 110 @project.enabled_module_names = [:issue_tracking]
111 111 @tracker = Tracker.generate!
112 112 @project.trackers << @tracker
113 113 @version = Version.generate!(:effective_date => (today + 7), :sharing => 'none')
114 114 @project.versions << @version
115 115 @issue = Issue.generate!(:fixed_version => @version,
116 116 :subject => "gantt#line_for_project",
117 117 :tracker => @tracker,
118 118 :project => @project,
119 119 :done_ratio => 30,
120 120 :start_date => (today - 1),
121 121 :due_date => (today + 7))
122 122 @project.issues << @issue
123 123 end
124 124 private :setup_subjects
125 125
126 126 # TODO: more of an integration test
127 127 test "#subjects project should be rendered" do
128 128 setup_subjects
129 129 @output_buffer = @gantt.subjects
130 130 assert_select "div.project-name a", /#{@project.name}/
131 131 assert_select 'div.project-name[style*="left:4px"]'
132 132 end
133 133
134 134 test "#subjects version should be rendered" do
135 135 setup_subjects
136 136 @output_buffer = @gantt.subjects
137 137 assert_select "div.version-name a", /#{@version.name}/
138 138 assert_select 'div.version-name[style*="left:24px"]'
139 139 end
140 140
141 141 test "#subjects version without assigned issues should not be rendered" do
142 142 setup_subjects
143 143 @version = Version.generate!(:effective_date => (today + 14),
144 144 :sharing => 'none',
145 145 :name => 'empty_version')
146 146 @project.versions << @version
147 147 @output_buffer = @gantt.subjects
148 148 assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
149 149 end
150 150
151 151 test "#subjects issue should be rendered" do
152 152 setup_subjects
153 153 @output_buffer = @gantt.subjects
154 154 assert_select "div.issue-subject", /#{@issue.subject}/
155 155 assert_select 'div.issue-subject[style*="left:44px"]'
156 156 end
157 157
158 158 test "#subjects issue assigned to a shared version of another project should be rendered" do
159 159 setup_subjects
160 160 p = Project.generate!
161 161 p.enabled_module_names = [:issue_tracking]
162 162 @shared_version = Version.generate!(:sharing => 'system')
163 163 p.versions << @shared_version
164 164 # Reassign the issue to a shared version of another project
165 165 @issue = Issue.generate!(:fixed_version => @shared_version,
166 166 :subject => "gantt#assigned_to_shared_version",
167 167 :tracker => @tracker,
168 168 :project => @project,
169 169 :done_ratio => 30,
170 170 :start_date => (today - 1),
171 171 :due_date => (today + 7))
172 172 @project.issues << @issue
173 173 @output_buffer = @gantt.subjects
174 174 assert_select "div.issue-subject", /#{@issue.subject}/
175 175 end
176 176
177 177 test "#subjects issue with subtasks should indent subtasks" do
178 178 setup_subjects
179 179 attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
180 180 @child1 = Issue.generate!(
181 181 attrs.merge(:subject => 'child1',
182 182 :parent_issue_id => @issue.id,
183 183 :start_date => (today - 1),
184 184 :due_date => (today + 2))
185 185 )
186 186 @child2 = Issue.generate!(
187 187 attrs.merge(:subject => 'child2',
188 188 :parent_issue_id => @issue.id,
189 189 :start_date => today,
190 190 :due_date => (today + 7))
191 191 )
192 192 @grandchild = Issue.generate!(
193 193 attrs.merge(:subject => 'grandchild',
194 194 :parent_issue_id => @child1.id,
195 195 :start_date => (today - 1),
196 196 :due_date => (today + 2))
197 197 )
198 198 @output_buffer = @gantt.subjects
199 199 # parent task 44px
200 200 assert_select 'div.issue-subject[style*="left:44px"]', /#{@issue.subject}/
201 201 # children 64px
202 202 assert_select 'div.issue-subject[style*="left:64px"]', /child1/
203 203 assert_select 'div.issue-subject[style*="left:64px"]', /child2/
204 204 # grandchild 84px
205 205 assert_select 'div.issue-subject[style*="left:84px"]', /grandchild/, @output_buffer
206 206 end
207 207
208 208 test "#lines" do
209 209 create_gantt
210 210 @project.enabled_module_names = [:issue_tracking]
211 211 @tracker = Tracker.generate!
212 212 @project.trackers << @tracker
213 213 @version = Version.generate!(:effective_date => (today + 7))
214 214 @project.versions << @version
215 215 @issue = Issue.generate!(:fixed_version => @version,
216 216 :subject => "gantt#line_for_project",
217 217 :tracker => @tracker,
218 218 :project => @project,
219 219 :done_ratio => 30,
220 220 :start_date => (today - 1),
221 221 :due_date => (today + 7))
222 222 @project.issues << @issue
223 223 @output_buffer = @gantt.lines
224 224
225 225 assert_select "div.project.task_todo"
226 226 assert_select "div.project.starting"
227 227 assert_select "div.project.ending"
228 228 assert_select "div.label.project", /#{@project.name}/
229 229
230 230 assert_select "div.version.task_todo"
231 231 assert_select "div.version.starting"
232 232 assert_select "div.version.ending"
233 233 assert_select "div.label.version", /#{@version.name}/
234 234
235 235 assert_select "div.task_todo"
236 236 assert_select "div.task.label", /#{@issue.done_ratio}/
237 237 assert_select "div.tooltip", /#{@issue.subject}/
238 238 end
239 239
240 240 test "#subject_for_project" do
241 241 create_gantt
242 242 @output_buffer = @gantt.subject_for_project(@project, :format => :html)
243 243 assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
244 244 end
245 245
246 246 test "#subject_for_project should style overdue projects" do
247 247 create_gantt
248 248 @project.stubs(:overdue?).returns(true)
249 249 @output_buffer = @gantt.subject_for_project(@project, :format => :html)
250 250 assert_select 'div span.project-overdue'
251 251 end
252 252
253 253 test "#subject_for_version" do
254 254 create_gantt
255 255 version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
256 256 @output_buffer = @gantt.subject_for_version(version, :format => :html)
257 257 assert_select 'a[href=?]', "/versions/#{version.to_param}", :text => /Foo/
258 258 end
259 259
260 260 test "#subject_for_version should style overdue versions" do
261 261 create_gantt
262 262 version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
263 263 version.stubs(:overdue?).returns(true)
264 264 @output_buffer = @gantt.subject_for_version(version, :format => :html)
265 265 assert_select 'div span.version-overdue'
266 266 end
267 267
268 268 test "#subject_for_version should style behind schedule versions" do
269 269 create_gantt
270 270 version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
271 271 version.stubs(:behind_schedule?).returns(true)
272 272 @output_buffer = @gantt.subject_for_version(version, :format => :html)
273 273 assert_select 'div span.version-behind-schedule'
274 274 end
275 275
276 276 test "#subject_for_issue" do
277 277 create_gantt
278 278 issue = Issue.generate!(:project => @project)
279 279 @output_buffer = @gantt.subject_for_issue(issue, :format => :html)
280 280 assert_select 'div', :text => /#{issue.subject}/
281 281 assert_select 'a[href=?]', "/issues/#{issue.to_param}", :text => /#{issue.tracker.name} ##{issue.id}/
282 282 end
283 283
284 284 test "#subject_for_issue should style overdue issues" do
285 285 create_gantt
286 286 issue = Issue.generate!(:project => @project)
287 287 issue.stubs(:overdue?).returns(true)
288 288 @output_buffer = @gantt.subject_for_issue(issue, :format => :html)
289 289 assert_select 'div span.issue-overdue'
290 290 end
291 291
292 292 test "#subject should add an absolute positioned div" do
293 293 create_gantt
294 294 @output_buffer = @gantt.subject('subject', :format => :html)
295 295 assert_select "div[style*=absolute]", :text => 'subject'
296 296 end
297 297
298 298 test "#subject should use the indent option to move the div to the right" do
299 299 create_gantt
300 300 @output_buffer = @gantt.subject('subject', :format => :html, :indent => 40)
301 301 assert_select 'div[style*="left:40"]'
302 302 end
303 303
304 304 test "#line_for_project" do
305 305 create_gantt
306 306 @project.stubs(:start_date).returns(today - 7)
307 307 @project.stubs(:due_date).returns(today + 7)
308 308 @output_buffer = @gantt.line_for_project(@project, :format => :html)
309 309 assert_select "div.project.label", :text => @project.name
310 310 end
311 311
312 312 test "#line_for_version" do
313 313 create_gantt
314 314 version = Version.generate!(:name => 'Foo', :project => @project)
315 315 version.stubs(:start_date).returns(today - 7)
316 316 version.stubs(:due_date).returns(today + 7)
317 317 version.stubs(:completed_percent).returns(30)
318 318 @output_buffer = @gantt.line_for_version(version, :format => :html)
319 319 assert_select "div.version.label", :text => /Foo/
320 320 assert_select "div.version.label", :text => /30%/
321 321 end
322 322
323 323 test "#line_for_issue" do
324 324 create_gantt
325 325 issue = Issue.generate!(:project => @project, :start_date => today - 7, :due_date => today + 7, :done_ratio => 30)
326 326 @output_buffer = @gantt.line_for_issue(issue, :format => :html)
327 327 assert_select "div.task.label", :text => /#{issue.status.name}/
328 328 assert_select "div.task.label", :text => /30%/
329 329 assert_select "div.tooltip", /#{issue.subject}/
330 330 end
331 331
332 332 test "#line todo line should start from the starting point on the left" do
333 333 create_gantt
334 334 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
335 335 assert_select 'div.task_todo[style*="left:28px"]', 1
336 336 end
337 337
338 338 test "#line todo line should be the total width" do
339 339 create_gantt
340 340 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
341 341 assert_select 'div.task_todo[style*="width:58px"]', 1
342 342 end
343 343
344 344 test "#line late line should start from the starting point on the left" do
345 345 create_gantt
346 346 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
347 347 assert_select 'div.task_late[style*="left:28px"]', 1
348 348 end
349 349
350 350 test "#line late line should be the total delayed width" do
351 351 create_gantt
352 352 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
353 353 assert_select 'div.task_late[style*="width:30px"]', 1
354 354 end
355 355
356 356 test "#line done line should start from the starting point on the left" do
357 357 create_gantt
358 358 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
359 359 assert_select 'div.task_done[style*="left:28px"]', 1
360 360 end
361 361
362 362 test "#line done line should be the width for the done ratio" do
363 363 create_gantt
364 364 @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
365 365 # 15 days * 4 px * 30% - 2 px for borders = 16 px
366 366 assert_select 'div.task_done[style*="width:16px"]', 1
367 367 end
368 368
369 369 test "#line done line should be the total width for 100% done ratio" do
370 370 create_gantt
371 371 @output_buffer = @gantt.line(today - 7, today + 7, 100, false, 'line', :format => :html, :zoom => 4)
372 372 # 15 days * 4 px - 2 px for borders = 58 px
373 373 assert_select 'div.task_done[style*="width:58px"]', 1
374 374 end
375 375
376 376 test "#line done line should be the total width for 100% done ratio with same start and end dates" do
377 377 create_gantt
378 378 @output_buffer = @gantt.line(today + 7, today + 7, 100, false, 'line', :format => :html, :zoom => 4)
379 379 assert_select 'div.task_done[style*="width:2px"]', 1
380 380 end
381 381
382 382 test "#line done line should not be the total done width if the gantt starts after start date" do
383 383 create_gantt
384 384 @output_buffer = @gantt.line(today - 16, today - 2, 30, false, 'line', :format => :html, :zoom => 4)
385 385 assert_select 'div.task_done[style*="left:0px"]', 1
386 386 assert_select 'div.task_done[style*="width:8px"]', 1
387 387 end
388 388
389 389 test "#line starting marker should appear at the start date" do
390 390 create_gantt
391 391 @output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
392 392 assert_select "div.starting", 1
393 393 assert_select 'div.starting[style*="left:28px"]', 1
394 394 end
395 395
396 396 test "#line starting marker should not appear if the start date is before gantt start date" do
397 397 create_gantt
398 398 @output_buffer = @gantt.line(gantt_start - 2, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
399 399 assert_select "div.starting", 0
400 400 end
401 401
402 402 test "#line ending marker should appear at the end date" do
403 403 create_gantt
404 404 @output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
405 405 assert_select "div.ending", 1
406 406 assert_select 'div.ending[style*="left:88px"]', 1
407 407 end
408 408
409 409 test "#line ending marker should not appear if the end date is before gantt start date" do
410 410 create_gantt
411 411 @output_buffer = @gantt.line(gantt_start - 30, gantt_start - 21, 30, true, 'line', :format => :html)
412 412 assert_select "div.ending", 0
413 413 end
414 414
415 415 test "#line label should appear at the far left, even if it's before gantt start date" do
416 416 create_gantt
417 417 @output_buffer = @gantt.line(gantt_start - 30, gantt_start - 21, 30, true, 'line', :format => :html)
418 418 assert_select "div.label", :text => 'line'
419 419 end
420 420
421 421 def test_sort_issues_no_date
422 422 project = Project.generate!
423 423 issue1 = Issue.generate!(:subject => "test", :project => project)
424 424 issue2 = Issue.generate!(:subject => "test", :project => project)
425 425 assert issue1.root_id < issue2.root_id
426 426 child1 = Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
427 427 :project => project)
428 428 child2 = Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
429 429 :project => project)
430 430 child3 = Issue.generate!(:parent_issue_id => child1.id, :subject => 'child',
431 431 :project => project)
432 432 assert_equal child1.root_id, child2.root_id
433 433 assert child1.lft < child2.lft
434 434 assert child3.lft < child2.lft
435 435 issues = [child3, child2, child1, issue2, issue1]
436 436 Redmine::Helpers::Gantt.sort_issues!(issues)
437 437 assert_equal [issue1.id, child1.id, child3.id, child2.id, issue2.id],
438 438 issues.map{|v| v.id}
439 439 end
440 440
441 441 def test_sort_issues_root_only
442 442 project = Project.generate!
443 443 issue1 = Issue.generate!(:subject => "test", :project => project)
444 444 issue2 = Issue.generate!(:subject => "test", :project => project)
445 445 issue3 = Issue.generate!(:subject => "test", :project => project,
446 446 :start_date => (today - 1))
447 447 issue4 = Issue.generate!(:subject => "test", :project => project,
448 448 :start_date => (today - 2))
449 449 issues = [issue4, issue3, issue2, issue1]
450 450 Redmine::Helpers::Gantt.sort_issues!(issues)
451 451 assert_equal [issue1.id, issue2.id, issue4.id, issue3.id],
452 452 issues.map{|v| v.id}
453 453 end
454 454
455 455 def test_sort_issues_tree
456 456 project = Project.generate!
457 457 issue1 = Issue.generate!(:subject => "test", :project => project)
458 458 issue2 = Issue.generate!(:subject => "test", :project => project,
459 459 :start_date => (today - 2))
460 460 issue1_child1 =
461 461 Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
462 462 :project => project)
463 463 issue1_child2 =
464 464 Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
465 465 :project => project, :start_date => (today - 10))
466 466 issue1_child1_child1 =
467 467 Issue.generate!(:parent_issue_id => issue1_child1.id, :subject => 'child',
468 468 :project => project, :start_date => (today - 8))
469 469 issue1_child1_child2 =
470 470 Issue.generate!(:parent_issue_id => issue1_child1.id, :subject => 'child',
471 471 :project => project, :start_date => (today - 9))
472 472 issue1_child1_child1_logic = Redmine::Helpers::Gantt.sort_issue_logic(issue1_child1_child1)
473 473 assert_equal [[today - 10, issue1.id], [today - 9, issue1_child1.id],
474 474 [today - 8, issue1_child1_child1.id]],
475 475 issue1_child1_child1_logic
476 476 issue1_child1_child2_logic = Redmine::Helpers::Gantt.sort_issue_logic(issue1_child1_child2)
477 477 assert_equal [[today - 10, issue1.id], [today - 9, issue1_child1.id],
478 478 [today - 9, issue1_child1_child2.id]],
479 479 issue1_child1_child2_logic
480 480 issues = [issue1_child1_child2, issue1_child1_child1, issue1_child2,
481 481 issue1_child1, issue2, issue1]
482 482 Redmine::Helpers::Gantt.sort_issues!(issues)
483 483 assert_equal [issue1.id, issue1_child1.id, issue1_child2.id,
484 484 issue1_child1_child2.id, issue1_child1_child1.id, issue2.id],
485 485 issues.map{|v| v.id}
486 486 end
487 487
488 488 def test_sort_versions
489 489 project = Project.generate!
490 490 versions = []
491 491 versions << Version.create!(:project => project, :name => 'test1')
492 492 versions << Version.create!(:project => project, :name => 'test2', :effective_date => '2013-10-25')
493 493 versions << Version.create!(:project => project, :name => 'test3')
494 494 versions << Version.create!(:project => project, :name => 'test4', :effective_date => '2013-10-02')
495 495
496 496 assert_equal versions.sort, Redmine::Helpers::Gantt.sort_versions!(versions.dup)
497 497 end
498 498 end
@@ -1,341 +1,342
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 class Redmine::MenuManager::MenuHelperTest < ActionView::TestCase
21
20 class Redmine::MenuManager::MenuHelperTest < Redmine::HelperTest
22 21 include Redmine::MenuManager::MenuHelper
23 22 include ERB::Util
23 include Rails.application.routes.url_helpers
24
24 25 fixtures :users, :members, :projects, :enabled_modules, :roles, :member_roles
25 26
26 27 def setup
27 28 setup_with_controller
28 29 # Stub the current menu item in the controller
29 30 def current_menu_item
30 31 :index
31 32 end
32 33 end
33 34
34 35 def test_render_single_menu_node
35 36 node = Redmine::MenuManager::MenuItem.new(:testing, '/test', { })
36 37 @output_buffer = render_single_menu_node(node, 'This is a test', node.url, false)
37 38
38 39 assert_select("a.testing", "This is a test")
39 40 end
40 41
41 42 def test_render_menu_node
42 43 single_node = Redmine::MenuManager::MenuItem.new(:single_node, '/test', { })
43 44 @output_buffer = render_menu_node(single_node, nil)
44 45
45 46 assert_select("li") do
46 47 assert_select("a.single-node", "Single node")
47 48 end
48 49 end
49 50
50 51 def test_render_menu_node_with_symbol_as_url
51 52 node = Redmine::MenuManager::MenuItem.new(:testing, :issues_path)
52 53 @output_buffer = render_menu_node(node, nil)
53 54
54 55 assert_select 'a[href="/issues"]', "Testing"
55 56 end
56 57
57 58 def test_render_menu_node_with_symbol_as_url_and_project
58 59 node = Redmine::MenuManager::MenuItem.new(:testing, :project_issues_path)
59 60 @output_buffer = render_menu_node(node, Project.find(1))
60 61
61 62 assert_select 'a[href="/projects/ecookbook/issues"]', "Testing"
62 63 end
63 64
64 65 def test_render_menu_node_with_nested_items
65 66 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { })
66 67 parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { })
67 68 parent_node << Redmine::MenuManager::MenuItem.new(:child_two_node, '/test', { })
68 69 parent_node <<
69 70 Redmine::MenuManager::MenuItem.new(:child_three_node, '/test', { }) <<
70 71 Redmine::MenuManager::MenuItem.new(:child_three_inner_node, '/test', { })
71 72
72 73 @output_buffer = render_menu_node(parent_node, nil)
73 74
74 75 assert_select("li") do
75 76 assert_select("a.parent-node", "Parent node")
76 77 assert_select("ul") do
77 78 assert_select("li a.child-one-node", "Child one node")
78 79 assert_select("li a.child-two-node", "Child two node")
79 80 assert_select("li") do
80 81 assert_select("a.child-three-node", "Child three node")
81 82 assert_select("ul") do
82 83 assert_select("li a.child-three-inner-node", "Child three inner node")
83 84 end
84 85 end
85 86 end
86 87 end
87 88
88 89 end
89 90
90 91 def test_render_menu_node_with_children
91 92 User.current = User.find(2)
92 93
93 94 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
94 95 '/test',
95 96 {
96 97 :children => Proc.new {|p|
97 98 children = []
98 99 3.times do |time|
99 100 children << Redmine::MenuManager::MenuItem.new("test_child_#{time}",
100 101 {:controller => 'issues', :action => 'index'},
101 102 {})
102 103 end
103 104 children
104 105 }
105 106 })
106 107 @output_buffer = render_menu_node(parent_node, Project.find(1))
107 108
108 109 assert_select("li") do
109 110 assert_select("a.parent-node", "Parent node")
110 111 assert_select("ul") do
111 112 assert_select("li a.test-child-0", "Test child 0")
112 113 assert_select("li a.test-child-1", "Test child 1")
113 114 assert_select("li a.test-child-2", "Test child 2")
114 115 end
115 116 end
116 117 end
117 118
118 119 def test_render_menu_node_with_nested_items_and_children
119 120 User.current = User.find(2)
120 121
121 122 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
122 123 {:controller => 'issues', :action => 'index'},
123 124 {
124 125 :children => Proc.new {|p|
125 126 children = []
126 127 3.times do |time|
127 128 children << Redmine::MenuManager::MenuItem.new("test_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
128 129 end
129 130 children
130 131 }
131 132 })
132 133
133 134 parent_node << Redmine::MenuManager::MenuItem.new(:child_node,
134 135 {:controller => 'issues', :action => 'index'},
135 136 {
136 137 :children => Proc.new {|p|
137 138 children = []
138 139 6.times do |time|
139 140 children << Redmine::MenuManager::MenuItem.new("test_dynamic_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
140 141 end
141 142 children
142 143 }
143 144 })
144 145
145 146 @output_buffer = render_menu_node(parent_node, Project.find(1))
146 147
147 148 assert_select("li") do
148 149 assert_select("a.parent-node", "Parent node")
149 150 assert_select("ul") do
150 151 assert_select("li a.child-node", "Child node")
151 152 assert_select("ul") do
152 153 assert_select("li a.test-dynamic-child-0", "Test dynamic child 0")
153 154 assert_select("li a.test-dynamic-child-1", "Test dynamic child 1")
154 155 assert_select("li a.test-dynamic-child-2", "Test dynamic child 2")
155 156 assert_select("li a.test-dynamic-child-3", "Test dynamic child 3")
156 157 assert_select("li a.test-dynamic-child-4", "Test dynamic child 4")
157 158 assert_select("li a.test-dynamic-child-5", "Test dynamic child 5")
158 159 end
159 160 assert_select("li a.test-child-0", "Test child 0")
160 161 assert_select("li a.test-child-1", "Test child 1")
161 162 assert_select("li a.test-child-2", "Test child 2")
162 163 end
163 164 end
164 165 end
165 166
166 167 def test_render_menu_node_with_allowed_and_unallowed_unattached_children
167 168 User.current = User.find(2)
168 169
169 170 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
170 171 {:controller => 'issues', :action => 'index'},
171 172 {
172 173 :children => Proc.new {|p|
173 174 [
174 175 Redmine::MenuManager::MenuItem.new("test_child_allowed", {:controller => 'issues', :action => 'index'}, {}),
175 176 Redmine::MenuManager::MenuItem.new("test_child_unallowed", {:controller => 'issues', :action => 'unallowed'}, {}),
176 177 ]
177 178 }
178 179 })
179 180
180 181 @output_buffer = render_menu_node(parent_node, Project.find(1))
181 182
182 183 assert_select("li") do
183 184 assert_select("a.parent-node", "Parent node")
184 185 assert_select("ul.menu-children.unattached") do
185 186 assert_select("li a.test-child-allowed", "Test child allowed")
186 187 assert_select("li a.test-child-unallowed", false)
187 188 end
188 189 end
189 190 end
190 191
191 192 def test_render_menu_node_with_allowed_and_unallowed_standard_children
192 193 User.current = User.find(6)
193 194
194 195 Redmine::MenuManager.map :some_menu do |menu|
195 196 menu.push(:parent_node, {:controller => 'issues', :action => 'index'}, { })
196 197 menu.push(:test_child_allowed, {:controller => 'issues', :action => 'index'}, {:parent => :parent_node})
197 198 menu.push(:test_child_unallowed, {:controller => 'issues', :action => 'new'}, {:parent => :parent_node})
198 199 end
199 200
200 201 @output_buffer = render_menu(:some_menu, Project.find(1))
201 202
202 203 assert_select("li") do
203 204 assert_select("a.parent-node", "Parent node")
204 205 assert_select("ul.menu-children.unattached", false)
205 206 assert_select("ul.menu-children") do
206 207 assert_select("li a.test-child-allowed", "Test child allowed")
207 208 assert_select("li a.test-child-unallowed", false)
208 209 end
209 210 end
210 211 end
211 212
212 213 def test_render_empty_virtual_menu_node_with_children
213 214
214 215 # only empty item with no click target
215 216 Redmine::MenuManager.map :menu1 do |menu|
216 217 menu.push(:parent_node, nil, { })
217 218 end
218 219
219 220 # parent with unallowed unattached child
220 221 Redmine::MenuManager.map :menu2 do |menu|
221 222 menu.push(:parent_node, nil, {:children => Proc.new {|p|
222 223 [Redmine::MenuManager::MenuItem.new("test_child_unallowed", {:controller => 'issues', :action => 'new'}, {})]
223 224 } })
224 225 end
225 226
226 227 # parent with unallowed standard child
227 228 Redmine::MenuManager.map :menu3 do |menu|
228 229 menu.push(:parent_node, nil, {})
229 230 menu.push(:test_child_unallowed, {:controller =>'issues', :action => 'new'}, {:parent => :parent_node})
230 231 end
231 232
232 233 # should not be displayed to anonymous
233 234 User.current = User.find(6)
234 235 assert_nil render_menu(:menu1, Project.find(1))
235 236 assert_nil render_menu(:menu2, Project.find(1))
236 237 assert_nil render_menu(:menu3, Project.find(1))
237 238
238 239 # should be displayed to an admin
239 240 User.current = User.find(1)
240 241 @output_buffer = render_menu(:menu2, Project.find(1))
241 242 assert_select("ul li a.parent-node", "Parent node")
242 243 @output_buffer = render_menu(:menu3, Project.find(1))
243 244 assert_select("ul li a.parent-node", "Parent node")
244 245
245 246 end
246 247
247 248 def test_render_menu_node_with_children_without_an_array
248 249 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
249 250 '/test',
250 251 {
251 252 :children => Proc.new {|p| Redmine::MenuManager::MenuItem.new("test_child", "/testing", {})}
252 253 })
253 254
254 255 assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
255 256 @output_buffer = render_menu_node(parent_node, Project.find(1))
256 257 end
257 258 end
258 259
259 260 def test_render_menu_node_with_incorrect_children
260 261 parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
261 262 '/test',
262 263 {
263 264 :children => Proc.new {|p| ["a string"] }
264 265 })
265 266
266 267 assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
267 268 @output_buffer = render_menu_node(parent_node, Project.find(1))
268 269 end
269 270
270 271 end
271 272
272 273 def test_menu_items_for_should_yield_all_items_if_passed_a_block
273 274 menu_name = :test_menu_items_for_should_yield_all_items_if_passed_a_block
274 275 Redmine::MenuManager.map menu_name do |menu|
275 276 menu.push(:a_menu, '/', { })
276 277 menu.push(:a_menu_2, '/', { })
277 278 menu.push(:a_menu_3, '/', { })
278 279 end
279 280
280 281 items_yielded = []
281 282 menu_items_for(menu_name) do |item|
282 283 items_yielded << item
283 284 end
284 285
285 286 assert_equal 3, items_yielded.size
286 287 end
287 288
288 289 def test_menu_items_for_should_return_all_items
289 290 menu_name = :test_menu_items_for_should_return_all_items
290 291 Redmine::MenuManager.map menu_name do |menu|
291 292 menu.push(:a_menu, '/', { })
292 293 menu.push(:a_menu_2, '/', { })
293 294 menu.push(:a_menu_3, '/', { })
294 295 end
295 296
296 297 items = menu_items_for(menu_name)
297 298 assert_equal 3, items.size
298 299 end
299 300
300 301 def test_menu_items_for_should_skip_unallowed_items_on_a_project
301 302 menu_name = :test_menu_items_for_should_skip_unallowed_items_on_a_project
302 303 Redmine::MenuManager.map menu_name do |menu|
303 304 menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
304 305 menu.push(:a_menu_2, {:controller => 'issues', :action => 'index' }, { })
305 306 menu.push(:unallowed, {:controller => 'issues', :action => 'unallowed' }, { })
306 307 end
307 308
308 309 User.current = User.find(2)
309 310
310 311 items = menu_items_for(menu_name, Project.find(1))
311 312 assert_equal 2, items.size
312 313 end
313 314
314 315 def test_menu_items_for_should_skip_items_that_fail_the_permission
315 316 menu_name = :test_menu_items_for_should_skip_items_that_fail_the_permission
316 317 Redmine::MenuManager.map menu_name do |menu|
317 318 menu.push(:a_menu, :project_issues_path)
318 319 menu.push(:unallowed, :project_issues_path, :permission => :unallowed)
319 320 end
320 321
321 322 User.current = User.find(2)
322 323
323 324 items = menu_items_for(menu_name, Project.find(1))
324 325 assert_equal 1, items.size
325 326 end
326 327
327 328 def test_menu_items_for_should_skip_items_that_fail_the_conditions
328 329 menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions
329 330 Redmine::MenuManager.map menu_name do |menu|
330 331 menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
331 332 menu.push(:unallowed,
332 333 {:controller => 'issues', :action => 'index' },
333 334 { :if => Proc.new { false }})
334 335 end
335 336
336 337 User.current = User.find(2)
337 338
338 339 items = menu_items_for(menu_name, Project.find(1))
339 340 assert_equal 1, items.size
340 341 end
341 342 end
@@ -1,29 +1,30
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 class Redmine::Views::LabelledFormBuilderTest < ActionView::TestCase
20 class Redmine::Views::LabelledFormBuilderTest < Redmine::HelperTest
21 include Rails.application.routes.url_helpers
21 22
22 23 def test_label_should_output_one_element
23 24 set_language_if_valid 'en'
24 25 labelled_form_for(Issue.new) do |f|
25 26 output = f.label :subject
26 27 assert_equal output, '<label for="issue_subject">Subject</label>'
27 28 end
28 29 end
29 30 end
@@ -1,401 +1,402
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
20 class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
21 21 include ApplicationHelper
22 22 include ActionView::Helpers::TextHelper
23 23 include ActionView::Helpers::SanitizeHelper
24 24 include ERB::Util
25 include Rails.application.routes.url_helpers
25 26 extend ActionView::Helpers::SanitizeHelper::ClassMethods
26 27
27 28 fixtures :projects, :roles, :enabled_modules, :users,
28 29 :repositories, :changesets,
29 30 :trackers, :issue_statuses, :issues,
30 31 :versions, :documents,
31 32 :wikis, :wiki_pages, :wiki_contents,
32 33 :boards, :messages,
33 34 :attachments
34 35
35 36 def setup
36 37 super
37 38 @project = nil
38 39 end
39 40
40 41 def teardown
41 42 end
42 43
43 44 def test_macro_registration
44 45 Redmine::WikiFormatting::Macros.register do
45 46 macro :foo do |obj, args|
46 47 "Foo: #{args.size} (#{args.join(',')}) (#{args.class.name})"
47 48 end
48 49 end
49 50
50 51 assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo}}")
51 52 assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo()}}")
52 53 assert_equal '<p>Foo: 1 (arg1) (Array)</p>', textilizable("{{foo(arg1)}}")
53 54 assert_equal '<p>Foo: 2 (arg1,arg2) (Array)</p>', textilizable("{{foo(arg1, arg2)}}")
54 55 end
55 56
56 57 def test_macro_registration_parse_args_set_to_false_should_disable_arguments_parsing
57 58 Redmine::WikiFormatting::Macros.register do
58 59 macro :bar, :parse_args => false do |obj, args|
59 60 "Bar: (#{args}) (#{args.class.name})"
60 61 end
61 62 end
62 63
63 64 assert_equal '<p>Bar: (args, more args) (String)</p>', textilizable("{{bar(args, more args)}}")
64 65 assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar}}")
65 66 assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar()}}")
66 67 end
67 68
68 69 def test_macro_registration_with_3_args_should_receive_text_argument
69 70 Redmine::WikiFormatting::Macros.register do
70 71 macro :baz do |obj, args, text|
71 72 "Baz: (#{args.join(',')}) (#{text.class.name}) (#{text})"
72 73 end
73 74 end
74 75
75 76 assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz}}")
76 77 assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz()}}")
77 78 assert_equal "<p>Baz: () (String) (line1\nline2)</p>", textilizable("{{baz()\nline1\nline2\n}}")
78 79 assert_equal "<p>Baz: (arg1,arg2) (String) (line1\nline2)</p>", textilizable("{{baz(arg1, arg2)\nline1\nline2\n}}")
79 80 end
80 81
81 82 def test_macro_name_with_upper_case
82 83 Redmine::WikiFormatting::Macros.macro(:UpperCase) {|obj, args| "Upper"}
83 84
84 85 assert_equal "<p>Upper</p>", textilizable("{{UpperCase}}")
85 86 end
86 87
87 88 def test_multiple_macros_on_the_same_line
88 89 Redmine::WikiFormatting::Macros.macro :foo do |obj, args|
89 90 args.any? ? "args: #{args.join(',')}" : "no args"
90 91 end
91 92
92 93 assert_equal '<p>no args no args</p>', textilizable("{{foo}} {{foo}}")
93 94 assert_equal '<p>args: a,b no args</p>', textilizable("{{foo(a,b)}} {{foo}}")
94 95 assert_equal '<p>args: a,b args: c,d</p>', textilizable("{{foo(a,b)}} {{foo(c,d)}}")
95 96 assert_equal '<p>no args args: c,d</p>', textilizable("{{foo}} {{foo(c,d)}}")
96 97 end
97 98
98 99 def test_macro_should_receive_the_object_as_argument_when_with_object_and_attribute
99 100 issue = Issue.find(1)
100 101 issue.description = "{{hello_world}}"
101 102 assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(issue, :description)
102 103 end
103 104
104 105 def test_macro_should_receive_the_object_as_argument_when_called_with_object_option
105 106 text = "{{hello_world}}"
106 107 assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
107 108 end
108 109
109 110 def test_extract_macro_options_should_with_args
110 111 options = extract_macro_options(["arg1", "arg2"], :foo, :size)
111 112 assert_equal([["arg1", "arg2"], {}], options)
112 113 end
113 114
114 115 def test_extract_macro_options_should_with_options
115 116 options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
116 117 assert_equal([[], {:foo => "bar", :size => "2"}], options)
117 118 end
118 119
119 120 def test_extract_macro_options_should_with_args_and_options
120 121 options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
121 122 assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
122 123 end
123 124
124 125 def test_extract_macro_options_should_parse_options_lazily
125 126 options = extract_macro_options(["params=x=1&y=2"], :params)
126 127 assert_equal([[], {:params => "x=1&y=2"}], options)
127 128 end
128 129
129 130 def test_macro_exception_should_be_displayed
130 131 Redmine::WikiFormatting::Macros.macro :exception do |obj, args|
131 132 raise "My message"
132 133 end
133 134
134 135 text = "{{exception}}"
135 136 assert_include '<div class="flash error">Error executing the <strong>exception</strong> macro (My message)</div>', textilizable(text)
136 137 end
137 138
138 139 def test_macro_arguments_should_not_be_parsed_by_formatters
139 140 text = '{{hello_world(http://www.redmine.org, #1)}}'
140 141 assert_include 'Arguments: http://www.redmine.org, #1', textilizable(text)
141 142 end
142 143
143 144 def test_exclamation_mark_should_not_run_macros
144 145 text = "!{{hello_world}}"
145 146 assert_equal '<p>{{hello_world}}</p>', textilizable(text)
146 147 end
147 148
148 149 def test_exclamation_mark_should_escape_macros
149 150 text = "!{{hello_world(<tag>)}}"
150 151 assert_equal '<p>{{hello_world(&lt;tag&gt;)}}</p>', textilizable(text)
151 152 end
152 153
153 154 def test_unknown_macros_should_not_be_replaced
154 155 text = "{{unknown}}"
155 156 assert_equal '<p>{{unknown}}</p>', textilizable(text)
156 157 end
157 158
158 159 def test_unknown_macros_should_parsed_as_text
159 160 text = "{{unknown(*test*)}}"
160 161 assert_equal '<p>{{unknown(<strong>test</strong>)}}</p>', textilizable(text)
161 162 end
162 163
163 164 def test_unknown_macros_should_be_escaped
164 165 text = "{{unknown(<tag>)}}"
165 166 assert_equal '<p>{{unknown(&lt;tag&gt;)}}</p>', textilizable(text)
166 167 end
167 168
168 169 def test_html_safe_macro_output_should_not_be_escaped
169 170 Redmine::WikiFormatting::Macros.macro :safe_macro do |obj, args|
170 171 "<tag>".html_safe
171 172 end
172 173 assert_equal '<p><tag></p>', textilizable("{{safe_macro}}")
173 174 end
174 175
175 176 def test_macro_hello_world
176 177 text = "{{hello_world}}"
177 178 assert textilizable(text).match(/Hello world!/)
178 179 end
179 180
180 181 def test_macro_hello_world_should_escape_arguments
181 182 text = "{{hello_world(<tag>)}}"
182 183 assert_include 'Arguments: &lt;tag&gt;', textilizable(text)
183 184 end
184 185
185 186 def test_macro_macro_list
186 187 text = "{{macro_list}}"
187 188 assert_match %r{<code>hello_world</code>}, textilizable(text)
188 189 end
189 190
190 191 def test_macro_include
191 192 @project = Project.find(1)
192 193 # include a page of the current project wiki
193 194 text = "{{include(Another page)}}"
194 195 assert_include 'This is a link to a ticket', textilizable(text)
195 196
196 197 @project = nil
197 198 # include a page of a specific project wiki
198 199 text = "{{include(ecookbook:Another page)}}"
199 200 assert_include 'This is a link to a ticket', textilizable(text)
200 201
201 202 text = "{{include(ecookbook:)}}"
202 203 assert_include 'CookBook documentation', textilizable(text)
203 204
204 205 text = "{{include(unknowidentifier:somepage)}}"
205 206 assert_include 'Page not found', textilizable(text)
206 207 end
207 208
208 209 def test_macro_collapse
209 210 text = "{{collapse\n*Collapsed* block of text\n}}"
210 211 with_locale 'en' do
211 212 result = textilizable(text)
212 213
213 214 assert_select_in result, 'div.collapsed-text'
214 215 assert_select_in result, 'strong', :text => 'Collapsed'
215 216 assert_select_in result, 'a.collapsible.collapsed', :text => 'Show'
216 217 assert_select_in result, 'a.collapsible', :text => 'Hide'
217 218 end
218 219 end
219 220
220 221 def test_macro_collapse_with_one_arg
221 222 text = "{{collapse(Example)\n*Collapsed* block of text\n}}"
222 223 result = textilizable(text)
223 224
224 225 assert_select_in result, 'div.collapsed-text'
225 226 assert_select_in result, 'strong', :text => 'Collapsed'
226 227 assert_select_in result, 'a.collapsible.collapsed', :text => 'Example'
227 228 assert_select_in result, 'a.collapsible', :text => 'Example'
228 229 end
229 230
230 231 def test_macro_collapse_with_two_args
231 232 text = "{{collapse(Show example, Hide example)\n*Collapsed* block of text\n}}"
232 233 result = textilizable(text)
233 234
234 235 assert_select_in result, 'div.collapsed-text'
235 236 assert_select_in result, 'strong', :text => 'Collapsed'
236 237 assert_select_in result, 'a.collapsible.collapsed', :text => 'Show example'
237 238 assert_select_in result, 'a.collapsible', :text => 'Hide example'
238 239 end
239 240
240 241 def test_macro_collapse_should_not_break_toc
241 242 text = <<-RAW
242 243 {{toc}}
243 244
244 245 h1. Title
245 246
246 247 {{collapse(Show example, Hide example)
247 248 h2. Heading
248 249 }}"
249 250 RAW
250 251
251 252 expected_toc = '<ul class="toc"><li><a href="#Title">Title</a><ul><li><a href="#Heading">Heading</a></li></ul></li></ul>'
252 253
253 254 assert_include expected_toc, textilizable(text).gsub(/[\r\n]/, '')
254 255 end
255 256
256 257 def test_macro_child_pages
257 258 expected = "<p><ul class=\"pages-hierarchy\">\n" +
258 259 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
259 260 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
260 261 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
261 262 "</ul>\n</p>"
262 263
263 264 @project = Project.find(1)
264 265 # child pages of the current wiki page
265 266 assert_equal expected, textilizable("{{child_pages}}", :object => WikiPage.find(2).content)
266 267 # child pages of another page
267 268 assert_equal expected, textilizable("{{child_pages(Another_page)}}", :object => WikiPage.find(1).content)
268 269
269 270 @project = Project.find(2)
270 271 assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
271 272 end
272 273
273 274 def test_macro_child_pages_with_parent_option
274 275 expected = "<p><ul class=\"pages-hierarchy\">\n" +
275 276 "<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
276 277 "<ul class=\"pages-hierarchy\">\n" +
277 278 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
278 279 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
279 280 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
280 281 "</ul>\n</li>\n</ul>\n</p>"
281 282
282 283 @project = Project.find(1)
283 284 # child pages of the current wiki page
284 285 assert_equal expected, textilizable("{{child_pages(parent=1)}}", :object => WikiPage.find(2).content)
285 286 # child pages of another page
286 287 assert_equal expected, textilizable("{{child_pages(Another_page, parent=1)}}", :object => WikiPage.find(1).content)
287 288
288 289 @project = Project.find(2)
289 290 assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
290 291 end
291 292
292 293 def test_macro_child_pages_with_depth_option
293 294 expected = "<p><ul class=\"pages-hierarchy\">\n" +
294 295 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
295 296 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
296 297 "</ul>\n</p>"
297 298
298 299 @project = Project.find(1)
299 300 assert_equal expected, textilizable("{{child_pages(depth=1)}}", :object => WikiPage.find(2).content)
300 301 end
301 302
302 303 def test_macro_child_pages_without_wiki_page_should_fail
303 304 assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}")
304 305 end
305 306
306 307 def test_macro_thumbnail
307 308 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
308 309 "/attachments/17",
309 310 :class => "thumbnail",
310 311 :title => "testfile.PNG")
311 312 assert_equal "<p>#{link}</p>",
312 313 textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14))
313 314 end
314 315
315 316 def test_macro_thumbnail_with_full_path
316 317 link = link_to('<img alt="testfile.PNG" src="http://test.host/attachments/thumbnail/17" />'.html_safe,
317 318 "http://test.host/attachments/17",
318 319 :class => "thumbnail",
319 320 :title => "testfile.PNG")
320 321 assert_equal "<p>#{link}</p>",
321 322 textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14), :only_path => false)
322 323 end
323 324
324 325 def test_macro_thumbnail_with_size
325 326 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
326 327 "/attachments/17",
327 328 :class => "thumbnail",
328 329 :title => "testfile.PNG")
329 330 assert_equal "<p>#{link}</p>",
330 331 textilizable("{{thumbnail(testfile.png, size=200)}}", :object => Issue.find(14))
331 332 end
332 333
333 334 def test_macro_thumbnail_with_title
334 335 link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
335 336 "/attachments/17",
336 337 :class => "thumbnail",
337 338 :title => "Cool image")
338 339 assert_equal "<p>#{link}</p>",
339 340 textilizable("{{thumbnail(testfile.png, title=Cool image)}}", :object => Issue.find(14))
340 341 end
341 342
342 343 def test_macro_thumbnail_with_invalid_filename_should_fail
343 344 assert_include 'test.png not found',
344 345 textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
345 346 end
346 347
347 348 def test_macros_should_not_be_executed_in_pre_tags
348 349 text = <<-RAW
349 350 {{hello_world(foo)}}
350 351
351 352 <pre>
352 353 {{hello_world(pre)}}
353 354 !{{hello_world(pre)}}
354 355 </pre>
355 356
356 357 {{hello_world(bar)}}
357 358 RAW
358 359
359 360 expected = <<-EXPECTED
360 361 <p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
361 362
362 363 <pre>
363 364 {{hello_world(pre)}}
364 365 !{{hello_world(pre)}}
365 366 </pre>
366 367
367 368 <p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
368 369 EXPECTED
369 370
370 371 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
371 372 end
372 373
373 374 def test_macros_should_be_escaped_in_pre_tags
374 375 text = "<pre>{{hello_world(<tag>)}}</pre>"
375 376 assert_equal "<pre>{{hello_world(&lt;tag&gt;)}}</pre>", textilizable(text)
376 377 end
377 378
378 379 def test_macros_should_not_mangle_next_macros_outputs
379 380 text = '{{macro(2)}} !{{macro(2)}} {{hello_world(foo)}}'
380 381 assert_equal '<p>{{macro(2)}} {{macro(2)}} Hello world! Object: NilClass, Arguments: foo and no block of text.</p>', textilizable(text)
381 382 end
382 383
383 384 def test_macros_with_text_should_not_mangle_following_macros
384 385 text = <<-RAW
385 386 {{hello_world
386 387 Line of text
387 388 }}
388 389
389 390 {{hello_world
390 391 Another line of text
391 392 }}
392 393 RAW
393 394
394 395 expected = <<-EXPECTED
395 396 <p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
396 397 <p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
397 398 EXPECTED
398 399
399 400 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
400 401 end
401 402 end
General Comments 0
You need to be logged in to leave comments. Login now