Feature #3088 » 3088-v4.patch
app/controllers/projects_controller.rb | ||
---|---|---|
189 | 189 | |
190 | 190 |
if User.current.allowed_to_view_all_time_entries?(@project) |
191 | 191 |
@total_hours = TimeEntry.visible.where(cond).sum(:hours).to_f |
192 |
end |
|
193 |
if User.current.allowed_to?(:view_estimated_hours, @project) |
|
192 | 194 |
@total_estimated_hours = Issue.visible.where(cond).sum(:estimated_hours).to_f |
193 | 195 |
end |
194 | 196 |
app/models/issue.rb | ||
---|---|---|
490 | 490 |
'start_date', |
491 | 491 |
'due_date', |
492 | 492 |
'done_ratio', |
493 |
'estimated_hours', |
|
494 | 493 |
'custom_field_values', |
495 | 494 |
'custom_fields', |
496 | 495 |
'lock_version', |
... | ... | |
520 | 519 |
'deleted_attachment_ids', |
521 | 520 |
:if => lambda {|issue, user| issue.attachments_deletable?(user)}) |
522 | 521 | |
522 |
safe_attributes 'estimated_hours', |
|
523 |
:if => lambda {|issue, user| user.allowed_to?(:view_estimated_hours, issue.project)} |
|
524 | ||
523 | 525 |
def safe_attribute_names(user=nil) |
524 | 526 |
names = super |
525 | 527 |
names -= disabled_core_fields |
app/models/issue_query.rb | ||
---|---|---|
47 | 47 |
:groupable => true), |
48 | 48 |
QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date", :groupable => true), |
49 | 49 |
QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), |
50 |
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", |
|
51 |
:totalable => true), |
|
52 |
QueryColumn.new( |
|
53 |
:total_estimated_hours, |
|
54 |
:sortable => |
|
55 |
lambda do |
|
56 |
"COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" \ |
|
57 |
" WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')}" \ |
|
58 |
" AND subtasks.root_id = #{Issue.table_name}.root_id" \ |
|
59 |
" AND subtasks.lft >= #{Issue.table_name}.lft" \ |
|
60 |
" AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" |
|
61 |
end, |
|
62 |
:default_order => 'desc'), |
|
63 | 50 |
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true), |
64 | 51 |
TimestampQueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", |
65 | 52 |
:default_order => 'desc', :groupable => true), |
... | ... | |
205 | 192 |
add_available_filter "closed_on", :type => :date_past |
206 | 193 |
add_available_filter "start_date", :type => :date |
207 | 194 |
add_available_filter "due_date", :type => :date |
208 |
add_available_filter "estimated_hours", :type => :float |
|
209 | ||
210 |
if User.current.allowed_to?(:view_time_entries, project, :global => true) |
|
211 |
add_available_filter "spent_time", :type => :float, :label => :label_spent_time |
|
195 |
if User.current.allowed_to?(:view_estimated_hours, nil, :global => true) |
|
196 |
add_available_filter "estimated_hours", :type => :float |
|
212 | 197 |
end |
213 | ||
214 | 198 |
add_available_filter "done_ratio", :type => :integer |
215 | 199 | |
216 | 200 |
if User.current.allowed_to?(:set_issues_private, nil, :global => true) || |
... | ... | |
283 | 267 |
@available_columns = self.class.available_columns.dup |
284 | 268 |
@available_columns += issue_custom_fields.visible.collect {|cf| QueryCustomFieldColumn.new(cf)} |
285 | 269 | |
270 |
if User.current.allowed_to?(:view_estimated_hours, project, :global => true) |
|
271 |
# insert the columns after due_date or at the end |
|
272 |
index = @available_columns.rindex {|column| column.name == :due_date} |
|
273 |
index = (index ? index + 1 : -1) |
|
274 | ||
275 |
@available_columns.insert index, QueryColumn.new(:estimated_hours, |
|
276 |
:sortable => "#{Issue.table_name}.estimated_hours", |
|
277 |
:totalable => true |
|
278 |
) |
|
279 |
index = (index.negative? ? index : index + 1) |
|
280 |
@available_columns.insert index, QueryColumn.new(:total_estimated_hours, |
|
281 |
:sortable => -> { |
|
282 |
"COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" \ |
|
283 |
" WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')} AND" \ |
|
284 |
" subtasks.root_id = #{Issue.table_name}.root_id AND" \ |
|
285 |
" subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" |
|
286 |
}, |
|
287 |
:default_order => 'desc' |
|
288 |
) |
|
289 |
end |
|
290 | ||
286 | 291 |
if User.current.allowed_to?(:view_time_entries, project, :global => true) |
287 |
# insert the columns after total_estimated_hours or at the end |
|
288 |
index = @available_columns.find_index {|column| column.name == :total_estimated_hours}
|
|
292 |
# insert the columns after total_estimated_hours or the columns after due_date or at the end
|
|
293 |
index = @available_columns.rindex {|column| column.name == :total_estimated_hours || column.name == :due_date }
|
|
289 | 294 |
index = (index ? index + 1 : -1) |
290 | 295 | |
291 | 296 |
subselect = "SELECT SUM(hours) FROM #{TimeEntry.table_name}" + |
... | ... | |
307 | 312 |
" WHERE (#{TimeEntry.visible_condition(User.current)})" + |
308 | 313 |
" AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt" |
309 | 314 | |
315 |
index = (index.negative? ? index : index + 1) |
|
310 | 316 |
@available_columns.insert( |
311 |
index + 1,
|
|
317 |
index, |
|
312 | 318 |
QueryColumn.new(:total_spent_hours, |
313 | 319 |
:sortable => "COALESCE((#{subselect}), 0)", |
314 | 320 |
:default_order => 'desc', |
app/models/journal.rb | ||
---|---|---|
111 | 111 |
detail.custom_field && detail.custom_field.visible_by?(project, user) |
112 | 112 |
elsif detail.property == 'relation' |
113 | 113 |
Issue.find_by_id(detail.value || detail.old_value).try(:visible?, user) |
114 |
elsif detail.property == 'attr' && detail.prop_key == 'estimated_hours' |
|
115 |
user.allowed_to?(:view_estimated_hours, project) |
|
114 | 116 |
else |
115 | 117 |
true |
116 | 118 |
end |
app/views/issues/show.api.rsb | ||
---|---|---|
16 | 16 |
api.due_date @issue.due_date |
17 | 17 |
api.done_ratio @issue.done_ratio |
18 | 18 |
api.is_private @issue.is_private |
19 |
api.estimated_hours @issue.estimated_hours |
|
20 |
api.total_estimated_hours @issue.total_estimated_hours |
|
19 |
if User.current.allowed_to?(:view_estimated_hours, @project) |
|
20 |
api.estimated_hours @issue.estimated_hours |
|
21 |
api.total_estimated_hours @issue.total_estimated_hours |
|
22 |
end |
|
21 | 23 |
if User.current.allowed_to?(:view_time_entries, @project) |
22 | 24 |
api.spent_hours(@issue.spent_hours) |
23 | 25 |
api.total_spent_hours(@issue.total_spent_hours) |
app/views/issues/show.html.erb | ||
---|---|---|
68 | 68 |
unless @issue.disabled_core_fields.include?('done_ratio') |
69 | 69 |
rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :legend => "#{@issue.done_ratio}%"), :class => 'progress' |
70 | 70 |
end |
71 |
unless @issue.disabled_core_fields.include?('estimated_hours')
|
|
71 |
if User.current.allowed_to?(:view_estimated_hours, @project) && !@issue.disabled_core_fields.include?('estimated_hours')
|
|
72 | 72 |
rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours' |
73 | 73 |
end |
74 | 74 |
if User.current.allowed_to?(:view_time_entries, @project) && @issue.total_spent_hours > 0 |
app/views/projects/show.html.erb | ||
---|---|---|
97 | 97 |
</div> |
98 | 98 |
<% end %> |
99 | 99 | |
100 |
<% if User.current.allowed_to?(:view_time_entries, @project) %> |
|
100 |
<% allowed_to_view_time_entries, allowed_to_view_estimated_hours = User.current.allowed_to?(:view_time_entries, @project), User.current.allowed_to?(:view_estimated_hours, @project) %> |
|
101 |
<% if allowed_to_view_time_entries || allowed_to_view_estimated_hours %> |
|
101 | 102 |
<div class="spent_time box"> |
102 | 103 |
<h3 class="icon icon-time"><%= l(:label_time_tracking) %></h3> |
103 | 104 |
<ul> |
104 |
<% if @total_estimated_hours.present? %>
|
|
105 |
<li><%= l(:field_estimated_hours) %>: <%= l_hours(@total_estimated_hours) %>
|
|
106 |
<% end %>
|
|
107 |
<% if @total_hours.present? %>
|
|
108 |
<li><%= l(:label_spent_time) %>: <%= l_hours(@total_hours) %>
|
|
109 |
<% end %>
|
|
105 |
<% if @total_estimated_hours.present? && allowed_to_view_estimated_hours %>
|
|
106 |
<li><%= l(:field_estimated_hours) %>: <%= l_hours(@total_estimated_hours) %> |
|
107 |
<% end %> |
|
108 |
<% if @total_hours.present? && allowed_to_view_time_entries %>
|
|
109 |
<li><%= l(:label_spent_time) %>: <%= l_hours(@total_hours) %> |
|
110 |
<% end %> |
|
110 | 111 |
</ul> |
112 |
<% if allowed_to_view_time_entries %> |
|
111 | 113 |
<p> |
112 |
<% if User.current.allowed_to?(:log_time, @project) %> |
|
114 |
<% if User.current.allowed_to?(:log_time, @project) %>
|
|
113 | 115 |
<%= link_to l(:button_log_time), new_project_time_entry_path(@project) %> | |
114 |
<% end %> |
|
116 |
<% end %>
|
|
115 | 117 |
<%= link_to(l(:label_details), project_time_entries_path(@project)) %> | |
116 | 118 |
<%= link_to(l(:label_report), report_project_time_entries_path(@project)) %> |
117 | 119 |
</p> |
120 |
<% end %> |
|
118 | 121 |
</div> |
119 |
<% end %> |
|
122 |
<% end %>
|
|
120 | 123 |
<%= call_hook(:view_projects_show_left, :project => @project) %> |
121 | 124 |
</div> |
122 | 125 | |
... | ... | |
137 | 140 |
<ul class="subprojects"> |
138 | 141 |
<% @subprojects.each do |project| %> |
139 | 142 |
<li><%= link_to(project.name, project_path(project), :class => project.css_classes).html_safe %></li> |
140 |
<% end %>
|
|
143 |
<% end %> |
|
141 | 144 |
</ul> |
142 | 145 |
</div> |
143 | 146 |
<% end %> |
app/views/versions/show.html.erb | ||
---|---|---|
14 | 14 |
<%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %> |
15 | 15 | |
16 | 16 |
<div id="version-summary"> |
17 |
<% if @version.visible_fixed_issues.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %> |
|
17 |
<% allowed_to_view_all_time_entries, allowed_to_view_estimated_hours = User.current.allowed_to_view_all_time_entries?(@project), User.current.allowed_to?(:view_estimated_hours, @project) %> |
|
18 |
<% if (@version.visible_fixed_issues.estimated_hours > 0 && allowed_to_view_estimated_hours) || allowed_to_view_all_time_entries %> |
|
18 | 19 |
<fieldset class="time-tracking"><legend><%= l(:label_time_tracking) %></legend> |
19 | 20 |
<table> |
21 |
<% if allowed_to_view_estimated_hours %> |
|
20 | 22 |
<tr> |
21 | 23 |
<th><%= l(:field_estimated_hours) %></th> |
22 | 24 |
<td class="total-hours"><%= link_to html_hours(l_hours(@version.visible_fixed_issues.estimated_hours)), |
23 | 25 |
project_issues_path(@version.project, :set_filter => 1, :status_id => '*', :fixed_version_id => @version.id, :c => [:tracker, :status, :subject, :estimated_hours], :t => [:estimated_hours]) %></td> |
24 | 26 |
</tr> |
25 |
<% if User.current.allowed_to_view_all_time_entries?(@project) %> |
|
27 |
<% end %> |
|
28 |
<% if allowed_to_view_all_time_entries %> |
|
26 | 29 |
<tr> |
27 | 30 |
<th><%= l(:label_spent_time) %></th> |
28 | 31 |
<td class="total-hours"><%= link_to html_hours(l_hours(@version.spent_hours)), |
config/locales/en.yml | ||
---|---|---|
548 | 548 |
permission_delete_issue_watchers: Delete watchers |
549 | 549 |
permission_log_time: Log spent time |
550 | 550 |
permission_view_time_entries: View spent time |
551 |
permission_view_estimated_hours: View estimated time |
|
551 | 552 |
permission_edit_time_entries: Edit time logs |
552 | 553 |
permission_edit_own_time_entries: Edit own time logs |
553 | 554 |
permission_view_news: View news |
db/migrate/20220729101502_add_view_estimated_hours_to_all_existing_roles.rb | ||
---|---|---|
1 |
class AddViewEstimatedHoursToAllExistingRoles < ActiveRecord::Migration[6.1] |
|
2 |
def up |
|
3 |
Role.all.each { |role| role.add_permission! :view_estimated_hours } |
|
4 |
end |
|
5 | ||
6 |
def down |
|
7 |
Role.all.each { |role| role.remove_permission! :view_estimated_hours } |
|
8 |
end |
|
9 |
end |
lib/redmine/default_data/loader.rb | ||
---|---|---|
71 | 71 |
:view_calendar, |
72 | 72 |
:log_time, |
73 | 73 |
:view_time_entries, |
74 |
:view_estimated_hours, |
|
74 | 75 |
:view_news, |
75 | 76 |
:comment_news, |
76 | 77 |
:view_documents, |
... | ... | |
102 | 103 |
:view_calendar, |
103 | 104 |
:log_time, |
104 | 105 |
:view_time_entries, |
106 |
:view_estimated_hours, |
|
105 | 107 |
:view_news, |
106 | 108 |
:comment_news, |
107 | 109 |
:view_documents, |
... | ... | |
122 | 124 |
:view_gantt, |
123 | 125 |
:view_calendar, |
124 | 126 |
:view_time_entries, |
127 |
:view_estimated_hours, |
|
125 | 128 |
:view_news, |
126 | 129 |
:comment_news, |
127 | 130 |
:view_documents, |
... | ... | |
137 | 140 |
:view_gantt, |
138 | 141 |
:view_calendar, |
139 | 142 |
:view_time_entries, |
143 |
:view_estimated_hours, |
|
140 | 144 |
:view_news, |
141 | 145 |
:view_documents, |
142 | 146 |
:view_wiki_pages, |
lib/redmine/export/pdf/issues_pdf_helper.rb | ||
---|---|---|
57 | 57 |
right << [l(:field_start_date), format_date(issue.start_date)] unless issue.disabled_core_fields.include?('start_date') |
58 | 58 |
right << [l(:field_due_date), format_date(issue.due_date)] unless issue.disabled_core_fields.include?('due_date') |
59 | 59 |
right << [l(:field_done_ratio), "#{issue.done_ratio}%"] unless issue.disabled_core_fields.include?('done_ratio') |
60 |
right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] unless issue.disabled_core_fields.include?('estimated_hours') |
|
60 |
right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] if \ |
|
61 |
User.current.allowed_to?(:view_estimated_hours, issue.project) && !issue.disabled_core_fields.include?('estimated_hours') |
|
61 | 62 |
right << [l(:label_spent_time), l_hours(issue.total_spent_hours)] if User.current.allowed_to?(:view_time_entries, issue.project) |
62 | 63 | |
63 | 64 |
rows = left.size > right.size ? left.size : right.size |
lib/redmine/preparation.rb | ||
---|---|---|
84 | 84 | |
85 | 85 |
map.project_module :time_tracking do |map| |
86 | 86 |
map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true |
87 |
map.permission :view_estimated_hours, {}, :read => true |
|
87 | 88 |
map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin |
88 | 89 |
map.permission :edit_time_entries, |
89 | 90 |
{:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, |
test/fixtures/roles.yml | ||
---|---|---|
35 | 35 |
- :view_calendar |
36 | 36 |
- :log_time |
37 | 37 |
- :view_time_entries |
38 |
- :view_estimated_hours |
|
38 | 39 |
- :edit_time_entries |
39 | 40 |
- :delete_time_entries |
40 | 41 |
- :import_time_entries |
... | ... | |
102 | 103 |
- :view_calendar |
103 | 104 |
- :log_time |
104 | 105 |
- :view_time_entries |
106 |
- :view_estimated_hours |
|
105 | 107 |
- :edit_own_time_entries |
106 | 108 |
- :view_news |
107 | 109 |
- :manage_news |
... | ... | |
151 | 153 |
- :view_calendar |
152 | 154 |
- :log_time |
153 | 155 |
- :view_time_entries |
156 |
- :view_estimated_hours |
|
154 | 157 |
- :view_news |
155 | 158 |
- :manage_news |
156 | 159 |
- :comment_news |
... | ... | |
191 | 194 |
- :view_calendar |
192 | 195 |
- :log_time |
193 | 196 |
- :view_time_entries |
197 |
- :view_estimated_hours |
|
194 | 198 |
- :view_news |
195 | 199 |
- :comment_news |
196 | 200 |
- :view_documents |
... | ... | |
218 | 222 |
- :view_gantt |
219 | 223 |
- :view_calendar |
220 | 224 |
- :view_time_entries |
225 |
- :view_estimated_hours |
|
221 | 226 |
- :view_news |
222 | 227 |
- :view_documents |
223 | 228 |
- :view_wiki_pages |
test/functional/issues_controller_test.rb | ||
---|---|---|
1581 | 1581 |
assert_select 'table.issues td.total_estimated_hours' |
1582 | 1582 |
end |
1583 | 1583 | |
1584 |
def test_index_should_not_show_estimated_hours_column_without_permission |
|
1585 |
Role.anonymous.remove_permission! :view_estimated_hours |
|
1586 |
get( |
|
1587 |
:index, |
|
1588 |
:params => { |
|
1589 |
:set_filter => 1, |
|
1590 |
:c => %w(subject estimated_hours) |
|
1591 |
} |
|
1592 |
) |
|
1593 |
assert_select 'td.estimated_hours', 0 |
|
1594 |
end |
|
1595 | ||
1584 | 1596 |
def test_index_should_not_show_spent_hours_column_without_permission |
1585 | 1597 |
Role.anonymous.remove_permission! :view_time_entries |
1586 | 1598 |
get( |
test/functional/projects_controller_test.rb | ||
---|---|---|
837 | 837 |
end |
838 | 838 |
end |
839 | 839 | |
840 |
def test_show_by_non_admin_user_with_view_estimated_hours_permission_should_show_estimated_time |
|
841 |
@request.session[:user_id] = 2 # manager |
|
842 |
get(:show, :params => {:id => 'ecookbook'}) |
|
843 | ||
844 |
assert_select 'div.spent_time.box>ul' do |
|
845 |
assert_select '>li', :text => 'Estimated time: 203:30 hours' |
|
846 |
end |
|
847 |
end |
|
848 | ||
849 |
def test_show_by_non_admin_user_without_view_estimated_hours_permission_should_not_show_estimated_time |
|
850 |
Role.find_by(name: 'Manager').remove_permission! :view_estimated_hours |
|
851 |
@request.session[:user_id] = 2 # manager |
|
852 |
get(:show, :params => {:id => 'ecookbook'}) |
|
853 | ||
854 |
assert_select 'div.spent_time.box>ul' do |
|
855 |
assert_select '>li', :text => 'Estimated time: 203.50 hours', :count => 0 |
|
856 |
end |
|
857 |
end |
|
858 | ||
840 | 859 |
def test_settings |
841 | 860 |
@request.session[:user_id] = 2 # manager |
842 | 861 |
get(:settings, :params => {:id => 1}) |
test/functional/versions_controller_test.rb | ||
---|---|---|
165 | 165 |
assert_select 'a', :text => '1 open' |
166 | 166 |
end |
167 | 167 | |
168 |
assert_select '.time-tracking td.total-hours a:first-child', :text => '2:00 hours' |
|
168 |
assert_select '.time-tracking tr:first-child' do |
|
169 |
assert_select 'th', :text => 'Estimated time' |
|
170 |
assert_select 'td.total-hours a', :text => '2:00 hours' |
|
171 |
end |
|
172 | ||
173 |
Role.non_member.remove_permission! :view_estimated_hours |
|
174 | ||
175 |
get :show, :params => {:id => 4} |
|
176 |
assert_response :success |
|
177 | ||
178 |
assert_select 'p.progress-info' do |
|
179 |
assert_select 'a', :text => '1 issue' |
|
180 |
assert_select 'a', :text => '1 open' |
|
181 |
end |
|
182 | ||
183 |
assert_select '.time-tracking th', :text => 'Estimated time', :count => 0 |
|
169 | 184 |
end |
170 | 185 | |
171 | 186 |
def test_show_should_link_to_spent_time_on_version |
test/integration/api_test/issues_test.rb | ||
---|---|---|
489 | 489 |
end |
490 | 490 |
end |
491 | 491 | |
492 |
test "GET /issues/:id.xml should contains total_spent_hours, and should not contains estimated_hours and total_estimated_hours when permission does not exists" do |
|
493 |
parent = Issue.find(3) |
|
494 |
parent.update_columns :estimated_hours => 2.0 |
|
495 |
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0) |
|
496 |
TimeEntry.create!(:project => child.project, :issue => child, :user => child.author, :spent_on => child.author.today, |
|
497 |
:hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id) |
|
498 |
# remove permission! |
|
499 |
Role.anonymous.remove_permission! :view_estimated_hours |
|
500 | ||
501 |
get '/issues/3.xml' |
|
502 | ||
503 |
assert_equal 'application/xml; charset=utf-8', response.content_type |
|
504 |
assert_select 'issue' do |
|
505 |
assert_select 'estimated_hours', false |
|
506 |
assert_select 'total_estimated_hours', false |
|
507 |
assert_select 'spent_hours', parent.spent_hours.to_s |
|
508 |
assert_select 'total_spent_hours', (parent.spent_hours.to_f + 2.5).to_s |
|
509 |
end |
|
510 |
end |
|
511 | ||
492 | 512 |
test "GET /issues/:id.xml should contains visible spent_hours only" do |
493 | 513 |
user = User.find_by_login('jsmith') |
494 | 514 |
Role.find(1).update(:time_entries_visibility => 'own') |
... | ... | |
537 | 557 |
assert_nil json['issue']['total_spent_hours'] |
538 | 558 |
end |
539 | 559 | |
560 |
test "GET /issues/:id.json should contains total_spent_hours, and should not contains estimated_hours and total_estimated_hours when permission does not exists" do |
|
561 |
parent = Issue.find(3) |
|
562 |
parent.update_columns :estimated_hours => 2.0 |
|
563 |
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0) |
|
564 |
TimeEntry.create!(:project => child.project, :issue => child, :user => child.author, :spent_on => child.author.today, |
|
565 |
:hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id) |
|
566 |
# remove permission! |
|
567 |
Role.anonymous.remove_permission! :view_estimated_hours |
|
568 | ||
569 |
get '/issues/3.json' |
|
570 | ||
571 |
assert_equal 'application/json; charset=utf-8', response.content_type |
|
572 |
json = ActiveSupport::JSON.decode(response.body) |
|
573 |
assert_nil json['issue']['estimated_hours'] |
|
574 |
assert_nil json['issue']['total_estimated_hours'] |
|
575 |
assert_equal parent.spent_hours, json['issue']['spent_hours'] |
|
576 |
assert_equal (parent.spent_hours.to_f + 2.5), json['issue']['total_spent_hours'] |
|
577 |
end |
|
578 | ||
540 | 579 |
test "GET /issues/:id.json should contains visible spent_hours only" do |
541 | 580 |
user = User.find_by_login('jsmith') |
542 | 581 |
Role.find(1).update(:time_entries_visibility => 'own') |
test/unit/journal_test.rb | ||
---|---|---|
245 | 245 |
assert_equal 2, visible_details.size |
246 | 246 |
end |
247 | 247 | |
248 |
def test_visible_details_should_have_privilege_to_view_estimated_hours |
|
249 |
journal = Journal.generate! do |j| |
|
250 |
j.details << |
|
251 |
JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours', :old_value => '200.00', :value => '100.00') |
|
252 |
end |
|
253 |
project = journal.journalized.project |
|
254 | ||
255 |
user = User.find(2) |
|
256 |
assert user.allowed_to?(:view_estimated_hours, project) |
|
257 |
visible_details = journal.visible_details(user) |
|
258 |
assert_equal 1, visible_details.size |
|
259 |
detail = visible_details.first |
|
260 |
assert_equal 'attr', detail.property |
|
261 |
assert_equal 'estimated_hours', detail.prop_key |
|
262 |
assert_equal '200.00', detail.old_value |
|
263 |
assert_equal '100.00', detail.value |
|
264 | ||
265 |
Role.anonymous.remove_permission!(:view_estimated_hours) |
|
266 |
assert !User.anonymous.allowed_to?(:view_estimated_hours, project) |
|
267 |
visible_details = journal.visible_details(User.anonymous) |
|
268 |
assert_equal 0, visible_details.size |
|
269 |
end |
|
270 | ||
248 | 271 |
def test_attachments |
249 | 272 |
journal = Journal.new |
250 | 273 |
[0, 1].map{ |i| Attachment.generate!(:file => mock_file_with_options(:original_filename => "image#{i}.png")) }.each do |attachment| |
test/unit/mail_handler_test.rb | ||
---|---|---|
43 | 43 |
end |
44 | 44 | |
45 | 45 |
def test_add_issue_with_specific_overrides |
46 |
project = Project.find_by(name: 'OnlineStore') |
|
47 |
project.enabled_module_names += [:time_tracking] |
|
48 |
project.save! |
|
49 | ||
46 | 50 |
issue = |
47 | 51 |
submit_email( |
48 | 52 |
'ticket_on_given_project.eml', |
... | ... | |
74 | 78 |
end |
75 | 79 | |
76 | 80 |
def test_add_issue_with_all_overrides |
81 |
project = Project.find_by_name('OnlineStore') |
|
82 |
project.enabled_module_names += [:time_tracking] |
|
83 |
project.save! |
|
84 | ||
77 | 85 |
issue = submit_email('ticket_on_given_project.eml', :allow_override => 'all') |
78 | 86 |
assert issue.is_a?(Issue) |
79 | 87 |
assert !issue.new_record? |
- « Previous
- 1
- …
- 4
- 5
- 6
- Next »