Index: test/unit/issue_test.rb =================================================================== --- test/unit/issue_test.rb (revision 1977) +++ test/unit/issue_test.rb (working copy) @@ -20,7 +20,7 @@ class IssueTest < Test::Unit::TestCase fixtures :projects, :users, :members, :trackers, :projects_trackers, - :issue_statuses, :issue_categories, + :issue_statuses, :issue_categories, :issue_relations, :workflows, :enumerations, :issues, :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values, @@ -190,4 +190,36 @@ assert_nil Issue.find_by_id(1) assert_nil TimeEntry.find_by_issue_id(1) end + + def test_blocked + blocked_issue = Issue.find(7) + blocking_issue = Issue.find(8) + + assert blocked_issue.blocked? + assert !blocking_issue.blocked? + end + + def test_blocked_issues_dont_allow_closed_statuses + blocked_issue = Issue.find(7) + + allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002)) + assert !allowed_statuses.empty? + + allowed_statuses.each do |status| + assert !status.is_closed? + end + + closed_statuses = allowed_statuses.find_all {|st| st.is_closed?} + assert closed_statuses.empty? + end + + def test_unblocked_issues_allow_closed_statuses + blocking_issue = Issue.find(8) + + allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002)) + assert !allowed_statuses.empty? + + closed_statuses = allowed_statuses.find_all {|st| st.is_closed?} + assert !closed_statuses.empty? + end end Index: test/fixtures/issues.yml =================================================================== --- test/fixtures/issues.yml (revision 1977) +++ test/fixtures/issues.yml (working copy) @@ -91,4 +91,35 @@ status_id: 1 start_date: <%= Date.today.to_s(:db) %> due_date: <%= 1.days.from_now.to_date.to_s(:db) %> - \ No newline at end of file +issues_007: + created_on: <%= 1.minute.ago.to_date.to_s(:db) %> + project_id: 5 + updated_on: <%= 1.minute.ago.to_date.to_s(:db) %> + priority_id: 3 + subject: Blocked Issue + id: 7 + fixed_version_id: + category_id: + description: This is an issue that is blocked by another + tracker_id: 1 + assigned_to_id: + author_id: 2 + status_id: 1 + start_date: <%= Date.today.to_s(:db) %> + due_date: <%= 1.days.from_now.to_date.to_s(:db) %> +issues_008: + created_on: <%= 1.minute.ago.to_date.to_s(:db) %> + project_id: 5 + updated_on: <%= 1.minute.ago.to_date.to_s(:db) %> + priority_id: 3 + subject: Issue Doing the Blocking + id: 8 + fixed_version_id: + category_id: + description: This is an issue that blocks issue 7 + tracker_id: 1 + assigned_to_id: + author_id: 2 + status_id: 1 + start_date: <%= Date.today.to_s(:db) %> + due_date: <%= 1.days.from_now.to_date.to_s(:db) %> Index: test/fixtures/issue_relations.yml =================================================================== --- test/fixtures/issue_relations.yml (revision 0) +++ test/fixtures/issue_relations.yml (revision 0) @@ -0,0 +1,8 @@ +issue_relation_001: + id: 1 + issue_from_id: 8 + issue_to_id: 7 + relation_type: blocks + delay: + + \ No newline at end of file Index: app/models/issue.rb =================================================================== --- app/models/issue.rb (revision 1977) +++ app/models/issue.rb (working copy) @@ -199,11 +199,19 @@ project.assignable_users end + # Returns true if this issue is blocked by another issue that is still open + def blocked? + !(relations_to.find_all {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.empty?) + end + # Returns an array of status that user is able to apply def new_statuses_allowed_to(user) statuses = status.find_new_statuses_allowed_to(user.role_for_project(project), tracker) statuses << status unless statuses.empty? - statuses.uniq.sort + + unified_list = statuses.uniq.sort + + blocked? ? unified_list.reject {|s| s.is_closed?} : unified_list end # Returns the mail adresses of users that should be notified for the issue