478 lines
20 KiB
Ruby
478 lines
20 KiB
Ruby
require File.dirname(__FILE__) + '/../test_helper'
|
|
|
|
class DeliverableTest < ActiveSupport::TestCase
|
|
should_belong_to :contract
|
|
should_belong_to :manager
|
|
should_have_many :labor_budgets
|
|
should_have_many :overhead_budgets
|
|
should_have_many :fixed_budgets
|
|
should_have_many :issues
|
|
|
|
should_validate_presence_of :title
|
|
should_validate_presence_of :type
|
|
should_validate_presence_of :manager
|
|
|
|
should_allow_values_for :status, "", nil, 'open', 'locked', 'closed'
|
|
should_not_allow_values_for :status, "other", "things", "1"
|
|
|
|
should "default status to open" do
|
|
assert_equal "open", Deliverable.new.status
|
|
end
|
|
|
|
context "#total=" do
|
|
should "strip dollar signs when writing" do
|
|
d = Deliverable.new
|
|
d.total = '$100.00'
|
|
|
|
assert_equal 100.00, d.total.to_f
|
|
end
|
|
|
|
should "strip commas when writing" do
|
|
d = Deliverable.new
|
|
d.total = '20,100.00'
|
|
|
|
assert_equal 20100.00, d.total.to_f
|
|
end
|
|
|
|
should "strip spaces when writing" do
|
|
d = Deliverable.new
|
|
d.total = '20 100.00'
|
|
|
|
assert_equal 20100.00, d.total.to_f
|
|
end
|
|
end
|
|
|
|
context "with a locked contract" do
|
|
should "block creating a new deliverable" do
|
|
contract = Contract.generate!(:status => "locked")
|
|
deliverable = FixedDeliverable.spawn(:contract => contract)
|
|
|
|
assert !deliverable.valid?
|
|
assert deliverable.errors.on_base.include?("Can't create a deliverable on a locked contract")
|
|
end
|
|
|
|
should "block deleting a deliverable" do
|
|
contract = Contract.generate!
|
|
deliverable = FixedDeliverable.generate!(:contract => contract).reload
|
|
assert contract.lock!
|
|
|
|
assert_no_difference("Deliverable.count") do
|
|
deliverable.destroy
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
context "with a closed contract" do
|
|
should "block creating a new deliverable" do
|
|
contract = Contract.generate!(:status => "closed")
|
|
deliverable = FixedDeliverable.spawn(:contract => contract)
|
|
|
|
assert !deliverable.valid?
|
|
assert deliverable.errors.on_base.include?("Can't create a deliverable on a closed contract")
|
|
end
|
|
|
|
should "block deleting a deliverable" do
|
|
contract = Contract.generate!
|
|
deliverable = FixedDeliverable.generate!(:contract => contract).reload
|
|
assert contract.close!
|
|
|
|
assert_no_difference("Deliverable.count") do
|
|
deliverable.destroy
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
context "#billable_time_entry_activities" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
end
|
|
|
|
should "include all billable activities" do
|
|
@billable_activity2 = TimeEntryActivity.generate!.reload
|
|
@billable_activity2.custom_field_values = { @custom_field.id => 'true' }
|
|
assert @billable_activity2.save
|
|
|
|
assert @deliverable.billable_time_entry_activities.include?(@billable_activity), "Activity not included"
|
|
assert @deliverable.billable_time_entry_activities.include?(@billable_activity2), "Activity not included"
|
|
|
|
end
|
|
|
|
should "not include nonbillable activities" do
|
|
assert !@deliverable.billable_time_entry_activities.include?(@non_billable_activity), "Non billable Activity included"
|
|
end
|
|
|
|
end
|
|
|
|
context "#non_billable_time_entry_activities" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
end
|
|
|
|
should "include all billable activities" do
|
|
@non_billable_activity2 = TimeEntryActivity.generate!.reload
|
|
@non_billable_activity2.custom_field_values = { @custom_field.id => 'false' }
|
|
assert @non_billable_activity2.save
|
|
|
|
assert @deliverable.non_billable_time_entry_activities.include?(@non_billable_activity), "Activity not included"
|
|
assert @deliverable.non_billable_time_entry_activities.include?(@non_billable_activity2), "Activity not included"
|
|
|
|
end
|
|
|
|
should "not include billable activities" do
|
|
assert !@deliverable.non_billable_time_entry_activities.include?(@billable_activity), "Billable Activity included"
|
|
end
|
|
|
|
end
|
|
|
|
context "#spent_for_activity" do
|
|
should "return the total amount spent for an activity" do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100
|
|
})
|
|
|
|
assert_equal 500.0, @deliverable.spent_for_activity(@billable_activity).to_f
|
|
end
|
|
end
|
|
|
|
context "#budget_for_activity" do
|
|
should "return the total amount budgeted for an activity" do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
|
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
|
@deliverable.save!
|
|
|
|
assert_equal 600.0, @deliverable.budget_for_activity(@billable_activity).to_f # 200 * 3 months (retainer)
|
|
end
|
|
|
|
end
|
|
|
|
context "#hours_spent_for_activity" do
|
|
should "return the total hours spent for an activity" do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100
|
|
})
|
|
|
|
assert_equal 5.0, @deliverable.hours_spent_for_activity(@billable_activity).to_f
|
|
|
|
end
|
|
|
|
end
|
|
|
|
context "#hours_budget_for_activity" do
|
|
should "return the total hours budgeted for an activity" do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
|
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
|
@deliverable.save!
|
|
|
|
assert_equal 60.0, @deliverable.hours_budget_for_activity(@billable_activity).to_f # 20 * 3 months (retainer)
|
|
end
|
|
|
|
end
|
|
|
|
context "#users_with_billable_time" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager
|
|
})
|
|
@non_billable_user = User.generate!
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @non_billable_user
|
|
})
|
|
|
|
end
|
|
|
|
should "include users with billable Time Entries" do
|
|
assert @deliverable.users_with_billable_time.include?(@manager), "Manager not included"
|
|
end
|
|
|
|
should "not include users with only nonbillable Time Entries" do
|
|
assert !@deliverable.users_with_billable_time.include?(@non_billable_user), "Non billable user included"
|
|
end
|
|
end
|
|
|
|
context "#users_with_non_billable_time" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager
|
|
})
|
|
@billable_user = User.generate!
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @billable_user
|
|
})
|
|
|
|
end
|
|
|
|
should "include users with billable Time Entries" do
|
|
assert @deliverable.users_with_non_billable_time.include?(@manager), "Manager not included"
|
|
end
|
|
|
|
should "not include users with only nonbillable Time Entries" do
|
|
assert !@deliverable.users_with_non_billable_time.include?(@billable_user), "Billable user included"
|
|
end
|
|
end
|
|
|
|
context "#hours_spent_for_user" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:hours => 5
|
|
})
|
|
|
|
end
|
|
|
|
context "with billable_time_only as true" do
|
|
should "return the total number of hours the user has logged on billable time entries" do
|
|
assert_equal 10, @deliverable.hours_spent_for_user(@manager, true)
|
|
end
|
|
end
|
|
|
|
context "with billable_time_only as false" do
|
|
should "return the total number of hours the user has logged on non-billable time entries" do
|
|
assert_equal 5, @deliverable.hours_spent_for_user(@manager, false)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
context "#spent_for_user" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100
|
|
})
|
|
|
|
end
|
|
|
|
context "with billable_time_only as true" do
|
|
should "return the total cost the user has logged on billable time entries" do
|
|
assert_equal 1000, @deliverable.spent_for_user(@manager, true)
|
|
end
|
|
end
|
|
|
|
context "with billable_time_only as false" do
|
|
should "return the total cost the user has logged on non-billable time entries" do
|
|
assert_equal 500, @deliverable.spent_for_user(@manager, false)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
context "#issue_categories_with_billable_time" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@category_one = IssueCategory.generate!(:project => @project)
|
|
@category_two = IssueCategory.generate!(:project => @project)
|
|
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_two
|
|
})
|
|
|
|
end
|
|
|
|
should "include categories with billable Time Entries" do
|
|
assert @deliverable.issue_categories_with_billable_time.include?(@category_one)
|
|
end
|
|
|
|
should "not include categories with only nonbillable Time Entries" do
|
|
assert !@deliverable.issue_categories_with_billable_time.include?(@category_two)
|
|
end
|
|
end
|
|
|
|
context "#issue_categories_with_non_billable_time" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@category_one = IssueCategory.generate!(:project => @project)
|
|
@category_two = IssueCategory.generate!(:project => @project)
|
|
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:issue_category => @category_two
|
|
})
|
|
|
|
end
|
|
|
|
should "include categories with non-billable Time Entries" do
|
|
assert @deliverable.issue_categories_with_non_billable_time.include?(@category_one)
|
|
end
|
|
|
|
should "not include categories with only billable Time Entries" do
|
|
assert !@deliverable.issue_categories_with_non_billable_time.include?(@category_two)
|
|
end
|
|
end
|
|
|
|
context "#spent_for_issue_category" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@category_one = IssueCategory.generate!(:project => @project)
|
|
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
|
|
end
|
|
|
|
context "with billable_time_only as true" do
|
|
should "return the total cost the category has logged on billable time entries" do
|
|
assert_equal 1000, @deliverable.spent_for_issue_category(@category_one, true)
|
|
end
|
|
end
|
|
|
|
context "with billable_time_only as false" do
|
|
should "return the total cost the category has logged on non-billable time entries" do
|
|
assert_equal 500, @deliverable.spent_for_issue_category(@category_one, false)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
context "#hours_spent_for_issue_category" do
|
|
setup do
|
|
configure_overhead_plugin
|
|
create_contract_and_deliverable
|
|
@category_one = IssueCategory.generate!(:project => @project)
|
|
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
create_issue_with_time_for_deliverable(@deliverable, {
|
|
:activity => @non_billable_activity,
|
|
:user => @manager,
|
|
:hours => 5,
|
|
:amount => 100,
|
|
:issue_category => @category_one
|
|
})
|
|
|
|
end
|
|
|
|
context "with billable_time_only as true" do
|
|
should "return the total hours the category has logged on billable time entries" do
|
|
assert_equal 10, @deliverable.hours_spent_for_issue_category(@category_one, true)
|
|
end
|
|
end
|
|
|
|
context "with billable_time_only as false" do
|
|
should "return the total hours the category has logged on non-billable time entries" do
|
|
assert_equal 5, @deliverable.hours_spent_for_issue_category(@category_one, false)
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|