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