From 66f6bf0e8df52e842d948362bda2ed14754860d6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sat, 8 Jul 2017 12:56:27 +0000 Subject: [PATCH] Merged r16766 to r16768 (#26376). git-svn-id: http://svn.redmine.org/redmine/branches/3.4-stable@16771 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/user.rb | 58 +++++++++++---------- app/views/projects/show.html.erb | 2 +- test/functional/projects_controller_test.rb | 10 ++++ test/unit/user_test.rb | 8 +++ 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 308889fcf..62a0289f0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -603,36 +603,40 @@ class User < Principal # Includes the projects that the user is a member of and the projects # that grant custom permissions to the builtin groups. def project_ids_by_role - return @project_ids_by_role if @project_ids_by_role - - group_class = anonymous? ? GroupAnonymous : GroupNonMember - group_id = group_class.pluck(:id).first - - members = Member.joins(:project, :member_roles). - where("#{Project.table_name}.status <> 9"). - where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Member.table_name}.user_id = ?)", self.id, true, group_id). - pluck(:user_id, :role_id, :project_id) - - hash = {} - members.each do |user_id, role_id, project_id| - # Ignore the roles of the builtin group if the user is a member of the project - next if user_id != id && project_ids.include?(project_id) - - hash[role_id] ||= [] - hash[role_id] << project_id - end - - result = Hash.new([]) - if hash.present? - roles = Role.where(:id => hash.keys).to_a - hash.each do |role_id, proj_ids| - role = roles.detect {|r| r.id == role_id} - if role - result[role] = proj_ids.uniq + # Clear project condition for when called from chained scopes + # eg. project.children.visible(user) + Project.unscoped do + return @project_ids_by_role if @project_ids_by_role + + group_class = anonymous? ? GroupAnonymous : GroupNonMember + group_id = group_class.pluck(:id).first + + members = Member.joins(:project, :member_roles). + where("#{Project.table_name}.status <> 9"). + where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Member.table_name}.user_id = ?)", self.id, true, group_id). + pluck(:user_id, :role_id, :project_id) + + hash = {} + members.each do |user_id, role_id, project_id| + # Ignore the roles of the builtin group if the user is a member of the project + next if user_id != id && project_ids.include?(project_id) + + hash[role_id] ||= [] + hash[role_id] << project_id + end + + result = Hash.new([]) + if hash.present? + roles = Role.where(:id => hash.keys).to_a + hash.each do |role_id, proj_ids| + role = roles.detect {|r| r.id == role_id} + if role + result[role] = proj_ids.uniq + end end end + @project_ids_by_role = result end - @project_ids_by_role = result end # Returns the ids of visible projects diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 7de31023c..2368a29c4 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -59,7 +59,7 @@ <%= link_to (@total_issues_by_tracker[tracker].to_i - @open_issues_by_tracker[tracker].to_i), project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id, :status_id => 'c') %> - + <%= link_to @total_issues_by_tracker[tracker].to_i, project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id, :status_id => '*') %> diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb index bc66e86d9..955ef2fb4 100644 --- a/test/functional/projects_controller_test.rb +++ b/test/functional/projects_controller_test.rb @@ -543,6 +543,16 @@ class ProjectsControllerTest < Redmine::ControllerTest assert_select 'a', :text => /Private child/ end + def test_show_by_member_on_leaf_project_should_display_issue_counts + @request.session[:user_id] = 2 + get :show, :params => { + :id => 'onlinestore' + } + assert_response :success + # Make sure there's a > 0 issue count + assert_select 'table.issue-report td.total a', :text => %r{\A[1-9]\d*\z} + end + def test_settings @request.session[:user_id] = 2 # manager get :settings, :params => { diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 7c0224ed8..858dc3209 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -952,6 +952,14 @@ class UserTest < ActiveSupport::TestCase assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort end + def test_project_ids_by_role_should_not_poison_cache_when_first_called_from_chained_scopes + user = User.find(2) + project = Project.find(1) + + project.children.visible(user) + assert_equal [1, 2, 5], user.project_ids_by_role.values.flatten.sort + end + def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array user = User.find(2) assert_equal [], user.projects_by_role[Role.find(3)] -- 2.39.5