diff --git a/app/controllers/trackers_controller.rb b/app/controllers/trackers_controller.rb index fdb5f0e377..c69721f520 100644 --- a/app/controllers/trackers_controller.rb +++ b/app/controllers/trackers_controller.rb @@ -36,6 +36,9 @@ class TrackersController < ApplicationController def new @tracker ||= Tracker.new(:default_status => IssueStatus.sorted.first) @tracker.safe_attributes = params[:tracker] + if params[:copy].present? && @copy_from = Tracker.find_by_id(params[:copy]) + @tracker.copy_from(@copy_from) + end @trackers = Tracker.sorted.to_a @projects = Project.all end diff --git a/app/models/tracker.rb b/app/models/tracker.rb index 7bd5c97592..8a4cbced83 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -76,6 +76,16 @@ class Tracker < ActiveRecord::Base 'project_ids', 'description') + def copy_from(arg, options={}) + return unless arg.present? + + tracker = arg.is_a?(Tracker) ? arg : Tracker.find_by_id(arg.to_s) + self.attributes = tracker.attributes.dup.except("id", "name", "position") + self.custom_field_ids = tracker.custom_field_ids.dup + self.project_ids = tracker.project_ids.dup + self + end + def to_s; name end def <=>(tracker) diff --git a/app/views/trackers/_form.html.erb b/app/views/trackers/_form.html.erb index 27e086e568..b7c4b773f2 100644 --- a/app/views/trackers/_form.html.erb +++ b/app/views/trackers/_form.html.erb @@ -39,7 +39,7 @@ <% if @tracker.new_record? && @trackers.any? %>

-<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@trackers, :id, :name)) %>

+<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@trackers, :id, :name, @copy_from.try(:id))) %>

<% end %> diff --git a/app/views/trackers/index.html.erb b/app/views/trackers/index.html.erb index 20d09754d2..85d3249fc4 100644 --- a/app/views/trackers/index.html.erb +++ b/app/views/trackers/index.html.erb @@ -28,6 +28,7 @@ <%= reorder_handle(tracker) %> + <%= link_to l(:button_copy), new_tracker_path(:copy => tracker), :class => 'icon icon-copy' %> <%= delete_link tracker_path(tracker) %> diff --git a/test/functional/trackers_controller_test.rb b/test/functional/trackers_controller_test.rb index 0e036e643c..187bb2f5bf 100644 --- a/test/functional/trackers_controller_test.rb +++ b/test/functional/trackers_controller_test.rb @@ -54,6 +54,55 @@ class TrackersControllerTest < Redmine::ControllerTest end end + def test_new_with_copy + core_fields = ["assigned_to_id", "category_id", "fixed_version_id", "parent_issue_id", "start_date", "due_date"] + custom_field_ids = custom_field_ids = [1, 2, 6] + project_ids = [1, 3, 5] + + copy_from = Tracker.find(1) + copy_from.core_fields = core_fields + copy_from.custom_field_ids = custom_field_ids + copy_from.project_ids = project_ids + copy_from.save + + get :new, :params => {:copy => copy_from.id.to_s} + assert_response :success + assert_select 'input[name=?]', 'tracker[name]' + + assert_select 'form' do + # blank name + assert_select 'input[name=?][value=""]', 'tracker[name]' + # core field checked + copy_from.core_fields.each do |core_field| + assert_select "input[type=checkbox][name=?][value=#{core_field}][checked=checked]", 'tracker[core_fields][]' + end + # core field not checked + copy_from.disabled_core_fields do |core_field| + assert_select "input[type=checkbox][name=?][value=#{core_field}]", 'tracker[core_fields][]' + end + # custom field checked + custom_field_ids.each do |custom_field_id| + assert_select "input[type=checkbox][name=?][value=#{custom_field_id}][checked=checked]", 'tracker[custom_field_ids][]' + end + # custom field not checked + (IssueCustomField.sorted.pluck(:id) - custom_field_ids).each do |custom_field_id| + assert_select "input[type=checkbox][name=?][value=#{custom_field_id}]", 'tracker[custom_field_ids][]' + end + # project checked + project_ids.each do |project_id| + assert_select "input[type=checkbox][name=?][value=#{project_id}][checked=checked]", 'tracker[project_ids][]' + end + # project not checked + (Project.all.pluck(:id) - project_ids).each do |project_id| + assert_select "input[type=checkbox][name=?][value=#{project_id}]", 'tracker[project_ids][]' + end + # workflow copy selected + assert_select 'select[name=?]', 'copy_workflow_from' do + assert_select 'option[value="1"][selected=selected]' + end + end + end + def test_create assert_difference 'Tracker.count' do post :create, :params => { diff --git a/test/unit/tracker_test.rb b/test/unit/tracker_test.rb index 89a711fdd6..1f3447da7c 100644 --- a/test/unit/tracker_test.rb +++ b/test/unit/tracker_test.rb @@ -46,6 +46,34 @@ class TrackerTest < ActiveSupport::TestCase assert_equal [2], project.rolled_up_trackers(false).visible(user).map(&:id) end + def test_copy_from + tracker = Tracker.find(1) + copy = Tracker.new.copy_from(tracker) + + assert_nil copy.id + assert_nil copy.position + assert_equal '', copy.name + assert_equal tracker.default_status_id, copy.default_status_id + assert_equal tracker.is_in_roadmap, copy.is_in_roadmap + assert_equal tracker.core_fields, copy.core_fields + assert_equal tracker.description, copy.description + + copy.name = 'Copy' + assert copy.save + end + + def test_copy_from_should_copy_custom_fields + tracker = Tracker.generate!(:custom_field_ids => [1, 2, 6]) + copy = Tracker.new.copy_from(tracker) + assert_equal [1, 2, 6], copy.custom_field_ids.sort + end + + def test_copy_from_should_copy_projects + tracker = Tracker.generate!(:project_ids => [1, 2, 3, 4, 5, 6]) + copy = Tracker.new.copy_from(tracker) + assert_equal [1, 2, 3, 4, 5, 6], copy.project_ids.sort + end + def test_copy_workflows source = Tracker.find(1) rules_count = source.workflow_rules.count