version_times.patch

Artem Vasiliev, 2008-07-21 19:28

Download (52.2 KB)

 
app/views/versions/show.rhtml (working copy)
9 9
<fieldset><legend><%= l(:label_time_tracking) %></legend>
10 10
<table>
11 11
<tr>
12
    <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
13
    <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %></td>
12
    <td class="label"><%= l(:field_estimated_hours) %></td>
13
    <td class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %></td>
14 14
</tr>
15 15
<% if User.current.allowed_to?(:view_time_entries, @project) %>
16 16
<tr>
17
    <td width="130px" align="right"><%= l(:label_spent_time) %></td>
18
    <td width="240px" class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %></td>
17
    <td class="label"><%= l(:label_spent_time) %></td>
18
    <td class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %></td>
19 19
</tr>
20
<tr>
21
    <td class="label"><%= l(:label_remaining_time) %></td>
22
    <td class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.remaining_hours)) %></td>
23
</tr>
24
<tr>
25
    <% title = "#{l(:label_spent_time)} + #{l(:label_remaining_time)}" %>
26
    <td class="label" title="<%= title %>"><%= l(:label_current_total_time) %></td>
27
    <td class="total-hours" title="<%= title %>"><%= html_hours(lwr(:label_f_hour, @version.total_hours)) %></td>
28
</tr>
20 29
<% end %>
21 30
</table>
22 31
</fieldset>
app/views/versions/_issue_counts.rhtml (working copy)
8 8
                   :onchange => remote_function(:url => { :action => :status_by, :id => version },
9 9
                                                :with => "Form.serialize('status_by_form')"))) %>
10 10
</legend>
11
<% if counts.empty? %>
11
<% if grouped_metrics.empty? %>
12 12
    <p><em><%= l(:label_no_data) %></em></p>
13 13
<% else %>
14
    <table>
15
    <% counts.each do |count| %>
16
    <tr>
17
        <td width="130px" align="right" >
18
            <%= link_to count[:group], {:controller => 'issues', 
19
                                        :action => 'index',
20
                                        :project_id => version.project,
21
                                        :set_filter => 1,
22
                                        :fixed_version_id => version,
23
                                        "#{criteria}_id" => count[:group]} %>
24
        </td>
25
        <td width="240px">
26
            <%= progress_bar((count[:closed].to_f / count[:total])*100, 
27
                  :legend => "#{count[:closed]}/#{count[:total]}",
28
                  :width => "#{(count[:total].to_f / max * 200).floor}px;") %>
29
        </td>
30
    </tr>
14
    <table class="category_metrics">
15
    <% grouped_metrics.each do |metrics_group| 
16
      category, metrics = *metrics_group
17
    %>
18
    <% color_class = cycle('odd', 'even')%>
19
        <tr class="header <%= color_class %>">
20
            <td colspan="5">
21
                <%= criteria_operator = category ? "=" : "!*" 
22
                link_to category || "[#{l(:text_not_assigned)}]", 
23
                                            {:controller => 'issues', 
24
                                            :action => 'index',
25
                                            :project_id => version.project,
26
                                            :set_filter => 1,
27
                                            :fields => ["#{criteria}_id", "fixed_version_id", "status_id"],
28
                                            :values => {"#{criteria}_id" => [category], "fixed_version_id" => [version], "status_id" => [1]},
29
                                            :operators => {"#{criteria}_id" => criteria_operator, "fixed_version_id" => "=", "status_id" => "*"}
30
                                            }
31
                                          %>
32
            </td>
33
        </tr>
34
        <tr class="<%= color_class %>">
35
            <td><%= l(:label_issues_count) %> </td>
36
            <% if spent_time_allowed %>
37
            <td><%= l(:label_time) %></td>
38
            <% end %>
39
            <td class="metric_comment">
40
                <span title="<%= l(:field_estimated_hours) %>">
41
                    <%= l(:label_estimated_time_short) %> 
42
                </span>
43
            </td>
44
            <% if spent_time_allowed %>
45
            <td class="metric_comment">
46
                <span title="<%= l(:label_spent_time) %>">
47
                    <%= l(:label_spent_time_short) %> 
48
                </span>
49
            </td>
50
            <td class="metric_comment">
51
                <span title="<%= l(:label_remaining_time) %>">
52
                    <%= l(:label_remaining_time_short) %> 
53
                </span>
54
            </td>
55
            <% max_progress_width = 70 %>
56
            <% else
57
                max_progress_width = 150
58
            end %>
59
        </tr>
60
        <tr class="<%= color_class %>">
61
            <td class="progress count">
62
                <%= count = metrics[:count]; progress_bar((count[:closed].to_f / count[:total])*100, 
63
                      :legend => 
64
                        "<span title=\"#{l(:label_closed_issues_plural)}\">" + 
65
                        "#{count[:closed]}</span>/" + 
66
                        "<span title=\"#{l(:label_total).chars.downcase}\">" + 
67
                        "#{count[:total]}</span>",                          
68
                      :width => "#{(count[:total].to_f / max[:count] * max_progress_width).floor}px;") %>
69
            </td>
70
            <% 
71
              time = metrics[:time]
72
              if spent_time_allowed %>
73
            <td class="progress time">
74
                <%= progress_bar(time_progress(time)*100, 
75
                      :legend => 
76
                        "<span title=\"#{l(:label_spent_time)}\">" + 
77
                        "#{time[:spent].ceil}</span>/" + 
78
                        "<span title=\"#{l(:label_current_total_time)}\">" + 
79
                        "#{time[:total].ceil}</span>",                          
80
                      :width => "#{(time[:total] / max[:time] * max_progress_width).floor}px;") %>
81
            </td>
82
            <% end %>
83
            <% hours = l(:text_hours_short) %>
84
            <td class="metric_comment">
85
                <span title="<%= l(:field_estimated_hours) %>">
86
                    <%= "#{time[:estimated].ceil}#{hours}" %>
87
                </span>                
88
            </td>
89
            <% if spent_time_allowed %>
90
            <td class="metric_comment">
91
                <span title="<%= l(:label_spent_time) %>">
92
                    <%= "#{time[:spent].ceil}#{hours}" %>
93
                </span>                                
94
            </td>
95
            <td class="metric_comment">
96
                <span title="<%= l(:label_remaining_time) %>">
97
                    <%= "#{time[:remaining].ceil}#{hours}" %>
98
                </span>                                                
99
            </td>
100
            <% end %>
101
        </tr>
31 102
    <% end %>
32 103
    </table>
33 104
<% end %>
app/helpers/versions_helper.rb (working copy)
23 23
    criteria ||= 'category'
24 24
    raise 'Unknown criteria' unless STATUS_BY_CRITERIAS.include?(criteria)
25 25
    
26
    h = Hash.new {|k,v| k[v] = [0, 0]}
27
    begin
28
      # Total issue count
29
      Issue.count(:group => criteria,
30
                  :conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s}
31
      # Open issues count
32
      Issue.count(:group => criteria,
33
                  :include => :status,
34
                  :conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s}
35
    rescue ActiveRecord::RecordNotFound
36
    # When grouping by an association, Rails throws this exception if there's no result (bug)
26
    #sort them alphabetically by category name
27
    metrics = version.get_grouped_metrics(criteria).to_a.sort {|x, y| x[0].to_s <=> y[0].to_s} 
28
    max = {}
29
    
30
    [{:count => :total}, {:time => :total}].each do |metric_info| 
31
      metrics_group, total_metric = metric_info.to_a.flatten
32
      max[metrics_group] = metrics.map{|item| item[1]}.map {|item| item[metrics_group]}.map {|item| item[total_metric]}.max
33
      max[metrics_group] = 1 if max[metrics_group] == 0
37 34
    end
38
    counts = h.keys.compact.sort.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}}
39
    max = counts.collect {|c| c[:total]}.max
40 35
    
41
    render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max}
36
    render :partial => 'issue_counts', :locals => {:version => version, 
37
      :criteria => criteria, :grouped_metrics => metrics, :max => max, 
38
      :spent_time_allowed => User.current.allowed_to?(:view_time_entries, @project), 
39
      }
42 40
  end
41

  
42
  def time_progress(time_info)  
43
    logger.debug "time_info[:spent] = #{time_info[:spent].inspect}"
44
    logger.debug "time_info[:total] = #{time_info[:total].inspect}"
45
    if (time_info[:total] != 0)
46
      time_progress = time_info[:spent].to_f / time_info[:total]
47
    else
48
      time_progress = 0 #no total also means there's no spent time
49
    end    
50
    time_progress
51
  end
43 52
  
44 53
  def status_by_options_for_select(value)
45 54
    options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value)
app/models/version.rb (working copy)
43 43
  def spent_hours
44 44
    @spent_hours ||= TimeEntry.sum(:hours, :include => :issue, :conditions => ["#{Issue.table_name}.fixed_version_id = ?", id]).to_f
45 45
  end
46

  
46 47
  
48
  def calc_remaining_and_total_time
49
    @remaining_hours = 0
50
    @total_hours = 0
51
    get_grouped_metrics(:category).to_a.map{|item| item[1]}.map {|item| item[:time]}.each do |times| 
52
      @remaining_hours += times[:remaining]
53
      @total_hours += times[:total]
54
    end
55
  end
56
  
57
  def remaining_hours
58
    return @remaining_hours if @remaining_hours
59
    calc_remaining_and_total_time
60
    @remaining_hours    
61
  end
62
  
63
  def total_hours
64
    return @total_hours if @total_hours
65
    calc_remaining_and_total_time
66
    @total_hours
67
  end
68
  
47 69
  # Returns true if the version is completed: due date reached and no open issues
48 70
  def completed?
49 71
    effective_date && (effective_date <= Date.today) && (open_issues_count == 0)
......
99 121
    end
100 122
  end
101 123
  
102
private
124
  def get_grouped_metrics(criteria)
125
    condition = issues_version_condition
126
    
127
    issues = Issue.find(:all, :include => [:status, criteria], 
128
      :conditions => condition)
129
    
130
    spent_times = {}
131
    TimeEntry.sum(:hours, :group => :issue_id, :include => :issue,
132
        :conditions => condition).each do |issue_id, hours| 
133
        
134
      spent_times[issue_id] = hours
135
    end
136

  
137
    categories_metrics = {}
138
    issues.each do |issue|
139
      category = issue.send(criteria)
140
      categories_metrics[category] ||= {}
141
      categories_metrics[category][:time] ||= {:estimated => 0, 
142
        :spent => 0, :remaining => 0, :total => 0}
143
      metrics = categories_metrics[category][:time]
144
      
145
      estimated = issue.estimated_hours || 0
146
      metrics[:estimated] += estimated
147
      spent = spent_times[issue.id] || 0
148
      metrics[:spent] += spent
149
      remaining = issue.closed? ? 0 : estimated - spent
150
      remaining = 0 if remaining < 0
151
      metrics[:remaining] += remaining
152
      metrics[:total] += (remaining + spent)
153
      
154
      categories_metrics[category][:count] ||= {:open => 0, :closed => 0, :total => 0}
155
      metrics = categories_metrics[category][:count]
156
      metrics[:total] += 1
157
      if issue.closed?
158
        metrics[:closed] += 1 
159
      else
160
        metrics[:open] += 1 
161
      end
162
    end
163
    categories_metrics
164
  end
165
  
166
  def issues_version_condition
167
    ["#{Issue.table_name}.fixed_version_id = ?", id]
168
  end
169

  
170
  private
103 171
  def check_integrity
104 172
    raise "Can't delete version" if self.fixed_issues.find(:first)
105 173
  end
public/stylesheets/application.css (working copy)
616 616
  #main { background: #fff; }
617 617
  #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
618 618
}
619

  
620
div.category_metrics {
621
  padding: 0.5em 0 0.5em 0;
622
}
623

  
624
table.category_metrics {
625
    border-collapse: collapse;    
626
}
627

  
628
.category_metrics .header {
629
  font-weight:bold;
630
}
631

  
632
.category_metrics th {
633
  text-align: left;
634
  font-weight:normal;    
635
}
636

  
637
.category_metrics td.progress {
638
  text-align: left;
639
  white-space: nowrap;
640
}
641

  
642
.category_metrics td.progress.count {
643
  width: 30%;
644
}
645
    
646
.category_metrics td.progress.time {
647
  width: 30%;
648
}
649
    
650
th.metric_comment, td.metric_comment {
651
  font-weight:normal;    
652
  font-size:90%;
653
  width: 5%;
654
}
655

  
656
#version-summary td.label {
657
    text-align:right;
658
    width: 40%;    
659
}
660

  
661
#version-summary td.total-hours {
662
    text-align:right;
663
}
664

  
665
#version-summary table {
666
    width:100%;
667
}
test/unit/version_test.rb (revision 0)
1
# redMine - project management software
2
# Copyright (C) 2006-2008  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
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
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class VersionTest < Test::Unit::TestCase
21
  fixtures :all
22

  
23
  def verify_counts(count_metrics, open, closed)
24
    assert_equal open + closed, count_metrics[:total]
25
    assert_equal open, count_metrics[:open]
26
    assert_equal closed, count_metrics[:closed]    
27
  end
28
  
29
  def test_get_grouped_metrics_count
30
    version = versions(:versions_002)
31
    grouped_metrics = version.get_grouped_metrics(:tracker)
32
    verify_counts(grouped_metrics[trackers(:trackers_001)][:count], 2, 1)
33
    verify_counts(grouped_metrics[trackers(:trackers_002)][:count], 1, 0)
34
  end
35
  
36
  def test_get_grouped_metrics_time
37
    version = versions(:versions_002)
38
    grouped_metrics = version.get_grouped_metrics(:tracker)
39
    time_metrics = grouped_metrics[trackers(:trackers_001)][:time]
40
    
41
    estimated = [:issues_001, :issues_003, :issues_007].inject(0) do |prev, current| 
42
      issues(current).estimated_hours + prev
43
    end
44
    
45
    assert_equal estimated, time_metrics[:estimated]
46

  
47
    spent = [:issues_001, :issues_003].inject(0) do |prev, current| 
48
      issues(current).spent_hours + prev
49
    end    
50
    assert_equal spent, time_metrics[:spent]
51

  
52
    i3 = issues(:issues_003)    
53
    #issue 1 is not counted because it spent more than estimated; 
54
    #  issue 7 not counted because because it's closed
55
    remaining = i3.estimated_hours - i3.spent_hours 
56
    assert_equal remaining, time_metrics[:remaining]
57
    
58
    assert_equal spent + remaining, time_metrics[:total]
59
  end
60
  
61
end
62
# redMine - project management software
63
# Copyright (C) 2006-2008  Jean-Philippe Lang
64
#
65
# This program is free software; you can redistribute it and/or
66
# modify it under the terms of the GNU General Public License
67
# as published by the Free Software Foundation; either version 2
68
# of the License, or (at your option) any later version.
69
# 
70
# This program is distributed in the hope that it will be useful,
71
# but WITHOUT ANY WARRANTY; without even the implied warranty of
72
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73
# GNU General Public License for more details.
74
# 
75
# You should have received a copy of the GNU General Public License
76
# along with this program; if not, write to the Free Software
77
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
78

  
79
require File.dirname(__FILE__) + '/../test_helper'
80

  
81
class VersionTest < Test::Unit::TestCase
82
  fixtures :all
83

  
84
  def verify_counts(count_metrics, open, closed)
85
    assert_equal open + closed, count_metrics[:total]
86
    assert_equal open, count_metrics[:open]
87
    assert_equal closed, count_metrics[:closed]    
88
  end
89
  
90
  def test_get_grouped_metrics_count
91
    version = versions(:versions_002)
92
    grouped_metrics = version.get_grouped_metrics(:tracker)
93
    verify_counts(grouped_metrics[trackers(:trackers_001)][:count], 2, 1)
94
    verify_counts(grouped_metrics[trackers(:trackers_002)][:count], 1, 0)
95
  end
96
  
97
  def test_get_grouped_metrics_time
98
    version = versions(:versions_002)
99
    grouped_metrics = version.get_grouped_metrics(:tracker)
100
    time_metrics = grouped_metrics[trackers(:trackers_001)][:time]
101
    
102
    estimated = [:issues_001, :issues_003, :issues_007].inject(0) do |prev, current| 
103
      issues(current).estimated_hours + prev
104
    end
105
    
106
    assert_equal estimated, time_metrics[:estimated]
107

  
108
    spent = [:issues_001, :issues_003].inject(0) do |prev, current| 
109
      issues(current).spent_hours + prev
110
    end    
111
    assert_equal spent, time_metrics[:spent]
112

  
113
    i3 = issues(:issues_003)    
114
    #issue 1 is not counted because it spent more than estimated; 
115
    #  issue 7 not counted because because it's closed
116
    remaining = i3.estimated_hours - i3.spent_hours 
117
    assert_equal remaining, time_metrics[:remaining]
118
    
119
    assert_equal spent + remaining, time_metrics[:total]
120
  end
121
  
122
end
123
# redMine - project management software
124
# Copyright (C) 2006-2008  Jean-Philippe Lang
125
#
126
# This program is free software; you can redistribute it and/or
127
# modify it under the terms of the GNU General Public License
128
# as published by the Free Software Foundation; either version 2
129
# of the License, or (at your option) any later version.
130
# 
131
# This program is distributed in the hope that it will be useful,
132
# but WITHOUT ANY WARRANTY; without even the implied warranty of
133
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
134
# GNU General Public License for more details.
135
# 
136
# You should have received a copy of the GNU General Public License
137
# along with this program; if not, write to the Free Software
138
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
139

  
140
require File.dirname(__FILE__) + '/../test_helper'
141

  
142
class VersionTest < Test::Unit::TestCase
143
  fixtures :all
144

  
145
  def verify_counts(count_metrics, open, closed)
146
    assert_equal open + closed, count_metrics[:total]
147
    assert_equal open, count_metrics[:open]
148
    assert_equal closed, count_metrics[:closed]    
149
  end
150
  
151
  def test_get_grouped_metrics_count
152
    version = versions(:versions_002)
153
    grouped_metrics = version.get_grouped_metrics(:tracker)
154
    verify_counts(grouped_metrics[trackers(:trackers_001)][:count], 2, 1)
155
    verify_counts(grouped_metrics[trackers(:trackers_002)][:count], 1, 0)
156
  end
157
  
158
  def test_get_grouped_metrics_time
159
    version = versions(:versions_002)
160
    grouped_metrics = version.get_grouped_metrics(:tracker)
161
    time_metrics = grouped_metrics[trackers(:trackers_001)][:time]
162
    
163
    estimated = [:issues_001, :issues_003, :issues_007].inject(0) do |prev, current| 
164
      issues(current).estimated_hours + prev
165
    end
166
    
167
    assert_equal estimated, time_metrics[:estimated]
168

  
169
    spent = [:issues_001, :issues_003].inject(0) do |prev, current| 
170
      issues(current).spent_hours + prev
171
    end    
172
    assert_equal spent, time_metrics[:spent]
173

  
174
    i3 = issues(:issues_003)    
175
    #issue 1 is not counted because it spent more than estimated; 
176
    #  issue 7 not counted because because it's closed
177
    remaining = i3.estimated_hours - i3.spent_hours 
178
    assert_equal remaining, time_metrics[:remaining]
179
    
180
    assert_equal spent + remaining, time_metrics[:total]
181
  end
182
  
183
end
184
# redMine - project management software
185
# Copyright (C) 2006-2008  Jean-Philippe Lang
186
#
187
# This program is free software; you can redistribute it and/or
188
# modify it under the terms of the GNU General Public License
189
# as published by the Free Software Foundation; either version 2
190
# of the License, or (at your option) any later version.
191
# 
192
# This program is distributed in the hope that it will be useful,
193
# but WITHOUT ANY WARRANTY; without even the implied warranty of
194
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
195
# GNU General Public License for more details.
196
# 
197
# You should have received a copy of the GNU General Public License
198
# along with this program; if not, write to the Free Software
199
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
200

  
201
require File.dirname(__FILE__) + '/../test_helper'
202

  
203
class VersionTest < Test::Unit::TestCase
204
  fixtures :all
205

  
206
  def verify_counts(count_metrics, open, closed)
207
    assert_equal open + closed, count_metrics[:total]
208
    assert_equal open, count_metrics[:open]
209
    assert_equal closed, count_metrics[:closed]    
210
  end
211
  
212
  def test_get_grouped_metrics_count
213
    version = versions(:versions_002)
214
    grouped_metrics = version.get_grouped_metrics(:tracker)
215
    verify_counts(grouped_metrics[trackers(:trackers_001)][:count], 2, 1)
216
    verify_counts(grouped_metrics[trackers(:trackers_002)][:count], 1, 0)
217
  end
218
  
219
  def test_get_grouped_metrics_time
220
    version = versions(:versions_002)
221
    grouped_metrics = version.get_grouped_metrics(:tracker)
222
    time_metrics = grouped_metrics[trackers(:trackers_001)][:time]
223
    
224
    estimated = [:issues_001, :issues_003, :issues_007].inject(0) do |prev, current| 
225
      issues(current).estimated_hours + prev
226
    end
227
    
228
    assert_equal estimated, time_metrics[:estimated]
229

  
230
    spent = [:issues_001, :issues_003].inject(0) do |prev, current| 
231
      issues(current).spent_hours + prev
232
    end    
233
    assert_equal spent, time_metrics[:spent]
234

  
235
    i3 = issues(:issues_003)    
236
    #issue 1 is not counted because it spent more than estimated; 
237
    #  issue 7 not counted because because it's closed
238
    remaining = i3.estimated_hours - i3.spent_hours 
239
    assert_equal remaining, time_metrics[:remaining]
240
    
241
    assert_equal spent + remaining, time_metrics[:total]
242
  end
243
  
244
end
test/unit/enumeration_test.rb (working copy)
25 25
  
26 26
  def test_objects_count
27 27
    # low priority
28
    assert_equal 5, Enumeration.find(4).objects_count
28
    assert_equal 7, Enumeration.find(4).objects_count
29 29
    # urgent
30 30
    assert_equal 0, Enumeration.find(7).objects_count
31 31
  end
......
40 40
  def test_destroy_with_reassign
41 41
    Enumeration.find(4).destroy(Enumeration.find(6))
42 42
    assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
43
    assert_equal 5, Enumeration.find(6).objects_count
43
    assert_equal 7, Enumeration.find(6).objects_count
44 44
  end
45 45
end
test/unit/user_test.rb (working copy)
118 118
    assert_equal "Manager", role.name
119 119
    
120 120
    # user with no role
121
    assert !@dlopper.role_for_project(Project.find(2)).member?
121
    assert !@dlopper.role_for_project(Project.find(3)).member?
122 122
  end
123 123
  
124 124
  def test_mail_notification_all
test/functional/versions_controller_test.rb (working copy)
22 22
class VersionsController; def rescue_action(e) raise e end; end
23 23

  
24 24
class VersionsControllerTest < Test::Unit::TestCase
25
  fixtures :projects, :versions, :issues, :users, :roles, :members, :enabled_modules
25
  fixtures :projects, :versions, :issues, :users, :roles, :members, :enabled_modules, :issue_statuses, :trackers
26 26
  
27 27
  def setup
28 28
    @controller = VersionsController.new
......
31 31
    User.current = nil
32 32
  end
33 33
  
34
  def test_show
35
    get :show, :id => 2
34
  {:view_time_entries_allowed => {:version_id => 2},
35
      :view_time_entries_not_allowed => {:user_id => 3, :version_id => 4}
36
  }.each do |case_key, case_info|
37
    define_method "test_show_when_#{case_key}" do
38
      @request.session[:user_id] = case_info[:user_id] if case_info[:user_id]
39
      if case_info[:verify]
40
        case_info[:verify].call()
41
      end
42
      get :show, :id => case_info[:version_id]
43
      assert_response :success
44
      assert_template 'show'
45
      assert_not_nil assigns(:version)
46
      
47
      assert_tag :tag => 'h2', :content => Version.find(case_info[:version_id]).name
48
    end
49

  
50
    define_method "test_issue_status_by_when_#{case_key}" do
51
      @request.session[:user_id] = case_info[:user_id] if case_info[:user_id]
52
      xhr :get, :status_by, :id => case_info[:version_id]
53
      assert_response :success
54
      assert_template '_issue_counts'
55
    end
56
  end
57
  
58
  #specific bug was reproduced when there were no time records and all the issues were closed
59
  def test_issue_status_by_no_division_by_zero
60
    version = versions(:versions_003)
61
    user = users(:users_002)
62
    @request.session[:user_id] = user.id
63
    
64
    assert version.fixed_issues.size > 0, "version should have issues"
65
    project = version.project
66
    assert user.allowed_to?(:view_time_entries, project), "user should have :view_time_entries permission to project #{project.id}"
67
    version.fixed_issues.all? do |i| 
68
      assert_equal 0, i.spent_hours 
69
      assert !i.estimated_hours || i.estimated_hours == 0
70
      assert i.closed?
71
    end
72
    xhr :get, :status_by, :id => version.id
36 73
    assert_response :success
37
    assert_template 'show'
38
    assert_not_nil assigns(:version)
39
    
40
    assert_tag :tag => 'h2', :content => /1.0/
74
    assert_template '_issue_counts'
41 75
  end
42
  
76

  
43 77
  def test_get_edit
44 78
    @request.session[:user_id] = 2
45 79
    get :edit, :id => 2
......
60 94

  
61 95
  def test_destroy
62 96
    @request.session[:user_id] = 2
63
    post :destroy, :id => 3
97
    version = versions(:versions_001)
98
    assert version.fixed_issues.empty?, "version should have no issues"
99
    post :destroy, :id => version.id
64 100
    assert_redirected_to 'projects/settings/ecookbook'
65
    assert_nil Version.find_by_id(3)
101
    assert_nil Version.find_by_id(version.id)
66 102
  end
67
  
68
  def test_issue_status_by
69
    xhr :get, :status_by, :id => 2
70
    assert_response :success
71
    assert_template '_issue_counts'
72
  end
73 103
end
test/fixtures/roles.yml (working copy)
160 160
    - :view_changesets
161 161

  
162 162
  position: 5
163
  
163

  
164
roles_006: 
165
  name: NoTimeEntries
166
  id: 6
167
  builtin: 0
168
  permissions: |
169
    --- 
170
    - :add_issue_notes
171
    - :view_gantt
172
    - :view_calendar
173
    - :view_documents
174
    - :view_wiki_pages
175
    - :view_files
176
    - :browse_repository
177
    - :view_changesets
178

  
179
  position: 6
test/fixtures/issues.yml (working copy)
6 6
  priority_id: 4
7 7
  subject: Can't print recipes
8 8
  id: 1
9
  fixed_version_id: 
9
  fixed_version_id: 2
10 10
  category_id: 1
11 11
  description: Unable to print recipes
12 12
  tracker_id: 1
......
15 15
  status_id: 1
16 16
  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
17 17
  due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
18
  estimated_hours: 100
18 19
issues_002: 
19 20
  created_on: 2006-07-19 21:04:21 +02:00
20 21
  project_id: 1
......
38 39
  priority_id: 4
39 40
  subject: Error 281 when updating a recipe
40 41
  id: 3
41
  fixed_version_id: 
42
  fixed_version_id: 2
42 43
  category_id: 
43 44
  description: Error 281 is encountered when saving a recipe
44 45
  tracker_id: 1
......
47 48
  status_id: 1