diff --git a/app/models/deliverable.rb b/app/models/deliverable.rb index 70d025b..1d15b64 100644 --- a/app/models/deliverable.rb +++ b/app/models/deliverable.rb @@ -17,12 +17,14 @@ class Deliverable < ActiveRecord::Base # TODO LATER: Shouldn't require the default_done_ratio patch def progress return 100 unless self.issues.size > 0 - - total = self.issues.collect(&:estimated_hours).inject {|sum, n| sum + n} + + total ||= self.issues.collect(&:estimated_hours).delete_if {|e| e.nil? }.inject {|sum, n| sum + n} || 0 + + return 100 unless total > 0 balance = 0.0 self.issues.each do |issue| - balance += issue.status.default_done_ratio * issue.estimated_hours + balance += issue.status.default_done_ratio * issue.estimated_hours unless issue.estimated_hours.nil? end return (balance / total).round diff --git a/spec/models/deliverable_spec.rb b/spec/models/deliverable_spec.rb index fca962c..2b60581 100644 --- a/spec/models/deliverable_spec.rb +++ b/spec/models/deliverable_spec.rb @@ -146,16 +146,16 @@ describe Deliverable, '.progress' do it 'should be calculated by the weighted average of the estimated hours of issues' do @issue1 = mock_model(Issue) @issue1.should_receive(:status).and_return(@status_in_progress) - @issue1.should_receive(:estimated_hours).twice.and_return(3.0) + @issue1.should_receive(:estimated_hours).exactly(3).times.and_return(3.0) @issue2 = mock_model(Issue) @issue2.should_receive(:status).and_return(@status_new) - @issue2.should_receive(:estimated_hours).twice.and_return(2.0) + @issue2.should_receive(:estimated_hours).exactly(3).times.and_return(2.0) @issue3 = mock_model(Issue) @issue3.should_receive(:status).and_return(@status_pending) - @issue3.should_receive(:estimated_hours).twice.and_return(10.0) + @issue3.should_receive(:estimated_hours).exactly(3).times.and_return(10.0) @issue4 = mock_model(Issue) @issue4.should_receive(:status).and_return(@status_complete) - @issue4.should_receive(:estimated_hours).twice.and_return(1.0) + @issue4.should_receive(:estimated_hours).exactly(3).times.and_return(1.0) @issues = [@issue1, @issue2, @issue3, @issue4] @issues.stub!(:count).and_return(4) @@ -171,6 +171,36 @@ describe Deliverable, '.progress' do @deliverable.progress.should eql(100) end + + it 'should not count issues with no estimated time' do + @issue1 = mock_model(Issue) + @issue1.should_receive(:status).and_return(@status_in_progress) + @issue1.should_receive(:estimated_hours).exactly(3).times.and_return(3.0) + @issue2 = mock_model(Issue) + @issue2.should_receive(:estimated_hours).exactly(2).times.and_return(nil) + @issues = [@issue1, @issue2] + @issues.stub!(:count).and_return(2) + + @deliverable = Deliverable.new({ :subject => 'test' }) + @deliverable.should_receive(:issues).exactly(3).times.and_return(@issues) + + @deliverable.progress.should eql(50) + end + + it 'should return 100 if there are no estimates on any of the assigned issues' do + @issue1 = mock_model(Issue) + @issue1.should_receive(:estimated_hours).and_return(nil) + @issue2 = mock_model(Issue) + @issue2.should_receive(:estimated_hours).and_return(nil) + @issues = [@issue1, @issue2] + @issues.stub!(:count).and_return(2) + + @deliverable = Deliverable.new({ :subject => 'test' }) + @deliverable.should_receive(:issues).exactly(2).times.and_return(@issues) + + @deliverable.progress.should eql(100) + + end it 'should not change when hours are clocked'