diff --git a/app/models/issue.rb b/app/models/issue.rb old mode 100644 new mode 100755 index 3d8df79..8ddd66f --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1505,8 +1505,15 @@ class Issue < ActiveRecord::Base end # Returns a scope of projects that user can assign the issue to - def allowed_target_projects(user=User.current) - current_project = new_record? ? nil : project + def allowed_target_projects(user=User.current, context=nil) + if new_record? && context.is_a?(Project) && !copy? + current_project = context.self_and_descendants + elsif new_record? + current_project = nil + else + current_project = project + end + self.class.allowed_target_projects(user, current_project) end @@ -1514,8 +1521,10 @@ class Issue < ActiveRecord::Base # If current_project is given, it will be included in the scope def self.allowed_target_projects(user=User.current, current_project=nil) condition = Project.allowed_to_condition(user, :add_issues) - if current_project + if current_project.is_a?(Project) condition = ["(#{condition}) OR #{Project.table_name}.id = ?", current_project.id] + elsif current_project + condition = ["(#{condition}) AND #{Project.table_name}.id IN (?)", current_project.map(&:id)] end Project.where(condition).having_trackers end diff --git a/app/models/project.rb b/app/models/project.rb old mode 100644 new mode 100755 diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb old mode 100644 new mode 100755 index 011928d..6c3d30b --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -9,8 +9,9 @@

<% end %> -<% if (@issue.safe_attribute?('project_id') || @issue.project_id_changed?) && (!@issue.new_record? || @project.nil? || @issue.copy?) %> -

<%= f.select :project_id, project_tree_options_for_select(@issue.allowed_target_projects, :selected => @issue.project), {:required => true}, +<% projects = @issue.allowed_target_projects(User.current, @project) %> +<% if (@issue.safe_attribute?('project_id') || @issue.project_id_changed?) && (@project.nil? || projects.count > 1 || @issue.copy?) %> +

<%= f.select :project_id, project_tree_options_for_select(projects, :selected => @issue.project), {:required => true}, :onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %>

<% end %> diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb old mode 100644 new mode 100755 index dacbd37..03a4993 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -1812,7 +1812,7 @@ class IssuesControllerTest < Redmine::ControllerTest assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues' assert_select 'form#issue-form' do assert_select 'input[name=?]', 'issue[is_private]' - assert_select 'select[name=?]', 'issue[project_id]', 0 + assert_select 'select[name=?]', 'issue[project_id]' assert_select 'select[name=?]', 'issue[tracker_id]' assert_select 'input[name=?]', 'issue[subject]' assert_select 'textarea[name=?]', 'issue[description]' @@ -1836,6 +1836,30 @@ class IssuesControllerTest < Redmine::ControllerTest end end + def test_get_new_should_show_project_selector_for_project_with_subprojects + @request.session[:user_id] = 2 + get :new, :project_id => 1, :tracker_id => 1 + assert_response :success + + assert_select 'select[name="issue[project_id]"]' do + assert_select 'option', 3 + assert_select 'option[selected=selected]', :text => 'eCookbook' + assert_select 'option[value=?]', '5', :text => '  » Private child of eCookbook' + assert_select 'option[value=?]', '3', :text => '  » eCookbook Subproject 1' + + # user_id 2 is not allowed to add issues on project_id 4 (it's not a member) + assert_select 'option[value=?]', '4', 0 + end + end + + def test_get_new_should_not_show_project_selector_for_project_without_subprojects + @request.session[:user_id] = 2 + get :new, :project_id => 2, :tracker_id => 1 + assert_response :success + + assert_select 'select[name="issue[project_id]"]', 0 + end + def test_get_new_with_minimal_permissions Role.find(1).update_attribute :permissions, [:add_issues] WorkflowTransition.where(:role_id => 1).delete_all @@ -1846,7 +1870,7 @@ class IssuesControllerTest < Redmine::ControllerTest assert_select 'form#issue-form' do assert_select 'input[name=?]', 'issue[is_private]', 0 - assert_select 'select[name=?]', 'issue[project_id]', 0 + assert_select 'select[name=?]', 'issue[project_id]' assert_select 'select[name=?]', 'issue[tracker_id]' assert_select 'input[name=?]', 'issue[subject]' assert_select 'textarea[name=?]', 'issue[description]' diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb old mode 100644 new mode 100755 index 53833c6..f8fde82 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -354,12 +354,12 @@ class IssueTest < ActiveSupport::TestCase :subject => 'Assignment test', :assigned_to => group, :is_private => true) - + Role.find(2).update! :issues_visibility => 'default' issues = Issue.visible(User.find(8)).to_a assert issues.any? assert issues.include?(issue) - + Role.find(2).update! :issues_visibility => 'own' issues = Issue.visible(User.find(8)).to_a assert issues.any?