2f5c51cb6 vor 32 Sekunden Felix Schäfer (HEAD -> master) Add subproject categories to issue list category filter #26023 diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb index 506ae483d..561c2c997 100644 --- a/app/models/issue_category.rb +++ b/app/models/issue_category.rb @@ -28,6 +28,10 @@ class IssueCategory < ActiveRecord::Base safe_attributes 'name', 'assigned_to_id' scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} + scope :visible, lambda {|user = User.current| + joins(:project). + where(Project.allowed_to_condition(user, :view_issues)) + } alias :destroy_without_reassign :destroy diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index c342dc456..c4d593c4d 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -124,7 +124,7 @@ class IssueQuery < Query add_available_filter "category_id", :type => :list_optional, - :values => lambda { project.issue_categories.collect{|s| [s.name, s.id.to_s] } } if project + :values => lambda { issue_category_values } add_available_filter "subject", :type => :text add_available_filter "description", :type => :text diff --git a/app/models/project.rb b/app/models/project.rb index 038398e04..9c8565172 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -330,6 +330,7 @@ class Project < ActiveRecord::Base @users = nil @shared_versions = nil @rolled_up_versions = nil + @rolled_up_issue_categories = nil @rolled_up_trackers = nil @rolled_up_statuses = nil @rolled_up_custom_fields = nil @@ -482,6 +483,13 @@ class Project < ActiveRecord::Base where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED) end + def rolled_up_issue_categories + @rolled_up_issue_categories ||= + IssueCategory. + joins(:project). + where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED) + end + # Returns a scope of the Versions used by the project def shared_versions if new_record? diff --git a/app/models/query.rb b/app/models/query.rb index fa5c926ba..a435dba84 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -570,6 +570,16 @@ class Query < ActiveRecord::Base watcher_values end + def issue_category_values + categories = + if project + project.rolled_up_issue_categories + else + IssueCategory + end + categories.visible.collect {|c| [c.name, c.id.to_s] } + end + # Returns a scope of issue custom fields that are available as columns or filters def issue_custom_fields if project diff --git a/test/fixtures/issue_categories.yml b/test/fixtures/issue_categories.yml index 5c2f30f52..55853e983 100644 --- a/test/fixtures/issue_categories.yml +++ b/test/fixtures/issue_categories.yml @@ -19,3 +19,8 @@ issue_categories_004: project_id: 2 assigned_to_id: id: 4 +issue_categories_005: + name: Services + project_id: 5 + assigned_to_id: + id: 5 diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 713368265..c16a8857c 100644 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -605,6 +605,27 @@ class QueriesControllerTest < Redmine::ControllerTest assert_include ["eCookbook - 2.0", "3", "open"], json end + def test_issue_categories_filter_should_not_return_issue_categories_from_invisible_subprojects + # Remove "jsmith" user from "Private child of eCookbook" project + Project.find(5).memberships.find_by(:user_id => 2).destroy + + @request.session[:user_id] = 2 + get :filter, :params => + { + :project_id => 1, + :name => 'category_id' + } + + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + + assert_include ["Printing", "1"], json + assert_include ["Recipes", "2"], json + + assert_not_include ["Services", "5"], json + end + def test_version_filter_without_project_id_should_return_all_visible_fixed_versions # Remove "jsmith" user from "Private child of eCookbook" project Project.find(5).memberships.find_by(:user_id => 2).destroy diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index d86c30d13..219f3f943 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -555,6 +555,53 @@ class ProjectTest < ActiveSupport::TestCase project.rolled_up_versions.sort end + test "#rolled_up_issue_categories should include the categories for the current project" do + project = Project.generate! + current_category_1 = IssueCategory.create!(:name => 'Current Category 1' ,:project => project) + current_category_2 = IssueCategory.create!(:name => 'Current Category 2' ,:project => project) + expected_categories = [current_category_1, current_category_2].sort + + assert_equal expected_categories, project.rolled_up_issue_categories.sort + end + + test "#rolled_up_issue_categories should include categories for a subproject" do + project = Project.generate! + parent_category_1 = IssueCategory.create!(:name => 'Parent Category 1' ,:project => project) + parent_category_2 = IssueCategory.create!(:name => 'Parent Category 2' ,:project => project) + subproject = Project.generate_with_parent!(project) + subproject_category = IssueCategory.create!(:name => 'Subproject Category' ,:project => subproject) + expected_categories = [parent_category_1, parent_category_2, subproject_category].sort + + assert_equal expected_categories, project.rolled_up_issue_categories.sort + end + + test "#rolled_up_issue_categories should include categories for a sub-subproject" do + project = Project.generate! + parent_category_1 = IssueCategory.create!(:name => 'Parent Category 1' ,:project => project) + parent_category_2 = IssueCategory.create!(:name => 'Parent Category 2' ,:project => project) + subproject = Project.generate_with_parent!(project) + sub_subproject = Project.generate_with_parent!(subproject) + sub_subproject_category = IssueCategory.create!(:name => 'Sub Subproject Category' ,:project => sub_subproject) + project.reload + expected_categories = [parent_category_1, parent_category_2, sub_subproject_category].sort + + assert_equal expected_categories, project.rolled_up_issue_categories.sort + end + + test "#rolled_up_issue_categories should only check active projects" do + project = Project.generate! + parent_category_1 = IssueCategory.create!(:name => 'Parent Category 1' ,:project => project) + parent_category_2 = IssueCategory.create!(:name => 'Parent Category 2' ,:project => project) + subproject = Project.generate_with_parent!(project) + IssueCategory.create!(:name => 'Subproject Category' ,:project => subproject) + assert subproject.archive + project.reload + expected_categories = [parent_category_1, parent_category_2].sort + + assert !subproject.active? + assert_equal expected_categories, project.rolled_up_issue_categories.sort + end + def test_shared_versions_none_sharing p = Project.find(5) v = Version.create!(:name => 'none_sharing', :project => p, :sharing => 'none')