@@ -0,0 +1,15 | |||
|
1 | class AddTrackersDefaultStatusId < ActiveRecord::Migration | |
|
2 | def up | |
|
3 | add_column :trackers, :default_status_id, :integer | |
|
4 | ||
|
5 | status_id = IssueStatus.where(:is_default => true).pluck(:id).first | |
|
6 | status_id ||= IssueStatus.order(:position).pluck(:id).first | |
|
7 | if status_id | |
|
8 | Tracker.update_all :default_status_id => status_id | |
|
9 | end | |
|
10 | end | |
|
11 | ||
|
12 | def down | |
|
13 | remove_column :trackers, :default_status_id | |
|
14 | end | |
|
15 | end |
@@ -0,0 +1,12 | |||
|
1 | class RemoveIssueStatusesIsDefault < ActiveRecord::Migration | |
|
2 | def up | |
|
3 | remove_column :issue_statuses, :is_default | |
|
4 | end | |
|
5 | ||
|
6 | def down | |
|
7 | add_column :issue_statuses, :is_default, :boolean, :null => false, :default => false | |
|
8 | # Restores the first status as default | |
|
9 | default_status_id = IssueStatus.order("position").first.pluck(:id) | |
|
10 | IssueStatus.where(:id => default_status_id).update_all(:is_default => true) | |
|
11 | end | |
|
12 | end |
@@ -24,7 +24,6 class IssuesController < ApplicationController | |||
|
24 | 24 | before_filter :find_project, :only => [:new, :create, :update_form] |
|
25 | 25 | before_filter :authorize, :except => [:index] |
|
26 | 26 | before_filter :find_optional_project, :only => [:index] |
|
27 | before_filter :check_for_default_issue_status, :only => [:new, :create] | |
|
28 | 27 | before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] |
|
29 | 28 | accept_rss_auth :index, :show |
|
30 | 29 | accept_api_auth :index, :show, :create, :update, :destroy |
@@ -234,7 +233,8 class IssuesController < ApplicationController | |||
|
234 | 233 | target_projects ||= @projects |
|
235 | 234 | |
|
236 | 235 | if @copy |
|
237 | @available_statuses = [IssueStatus.default] | |
|
236 | # Copied issues will get their default statuses | |
|
237 | @available_statuses = [] | |
|
238 | 238 | else |
|
239 | 239 | @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) |
|
240 | 240 | end |
@@ -425,12 +425,21 class IssuesController < ApplicationController | |||
|
425 | 425 | @issue = @project.issues.visible.find(params[:id]) |
|
426 | 426 | end |
|
427 | 427 | |
|
428 |
|
|
|
428 | if attrs = params[:issue].deep_dup | |
|
429 | if params[:was_default_status] == attrs[:status_id] | |
|
430 | attrs.delete(:status_id) | |
|
431 | end | |
|
432 | @issue.safe_attributes = attrs | |
|
433 | end | |
|
429 | 434 | @issue.tracker ||= @project.trackers.first |
|
430 | 435 | if @issue.tracker.nil? |
|
431 | 436 | render_error l(:error_no_tracker_in_project) |
|
432 | 437 | return false |
|
433 | 438 | end |
|
439 | if @issue.status.nil? | |
|
440 | render_error l(:error_no_default_issue_status) | |
|
441 | return false | |
|
442 | end | |
|
434 | 443 | |
|
435 | 444 | @priorities = IssuePriority.active |
|
436 | 445 | @allowed_statuses = @issue.new_statuses_allowed_to(User.current, @issue.new_record?) |
@@ -440,13 +449,6 class IssuesController < ApplicationController | |||
|
440 | 449 | end |
|
441 | 450 | end |
|
442 | 451 | |
|
443 | def check_for_default_issue_status | |
|
444 | if IssueStatus.default.nil? | |
|
445 | render_error l(:error_no_default_issue_status) | |
|
446 | return false | |
|
447 | end | |
|
448 | end | |
|
449 | ||
|
450 | 452 | def parse_params_for_bulk_issue_attributes(params) |
|
451 | 453 | attributes = (params[:issue] || {}).reject {|k,v| v.blank?} |
|
452 | 454 | attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} |
@@ -162,7 +162,6 class Issue < ActiveRecord::Base | |||
|
162 | 162 | super |
|
163 | 163 | if new_record? |
|
164 | 164 | # set default values for new records only |
|
165 | self.status ||= IssueStatus.default | |
|
166 | 165 | self.priority ||= IssuePriority.default |
|
167 | 166 | self.watcher_user_ids = [] |
|
168 | 167 | end |
@@ -273,11 +272,19 class Issue < ActiveRecord::Base | |||
|
273 | 272 | issue.save ? issue : false |
|
274 | 273 | end |
|
275 | 274 | |
|
276 | def status_id=(sid) | |
|
277 | self.status = nil | |
|
278 | result = write_attribute(:status_id, sid) | |
|
279 | @workflow_rule_by_attribute = nil | |
|
280 | result | |
|
275 | def status_id=(status_id) | |
|
276 | if status_id.to_s != self.status_id.to_s | |
|
277 | self.status = (status_id.present? ? IssueStatus.find_by_id(status_id) : nil) | |
|
278 | end | |
|
279 | self.status_id | |
|
280 | end | |
|
281 | ||
|
282 | # Sets the status. | |
|
283 | def self.status=(status) | |
|
284 | if status != self.status | |
|
285 | @workflow_rule_by_attribute = nil | |
|
286 | end | |
|
287 | association(:status).writer(status) | |
|
281 | 288 | end |
|
282 | 289 | |
|
283 | 290 | def priority_id=(pid) |
@@ -302,12 +309,24 class Issue < ActiveRecord::Base | |||
|
302 | 309 | self.tracker_id |
|
303 | 310 | end |
|
304 | 311 | |
|
312 | # Sets the tracker. | |
|
313 | # This will set the status to the default status of the new tracker if: | |
|
314 | # * the status was the default for the previous tracker | |
|
315 | # * or if the status was not part of the new tracker statuses | |
|
316 | # * or the status was nil | |
|
305 | 317 | def tracker=(tracker) |
|
306 | 318 | if tracker != self.tracker |
|
319 | if status == default_status | |
|
320 | self.status = nil | |
|
321 | elsif status && tracker && !tracker.issue_status_ids.include?(status.id) | |
|
322 | self.status = nil | |
|
323 | end | |
|
307 | 324 | @custom_field_values = nil |
|
308 | 325 | @workflow_rule_by_attribute = nil |
|
309 | 326 | end |
|
310 | 327 | association(:tracker).writer(tracker) |
|
328 | self.status ||= default_status | |
|
329 | self.tracker | |
|
311 | 330 | end |
|
312 | 331 | |
|
313 | 332 | def project_id=(project_id) |
@@ -317,6 +336,14 class Issue < ActiveRecord::Base | |||
|
317 | 336 | self.project_id |
|
318 | 337 | end |
|
319 | 338 | |
|
339 | # Sets the project. | |
|
340 | # Unless keep_tracker argument is set to true, this will change the tracker | |
|
341 | # to the first tracker of the new project if the previous tracker is not part | |
|
342 | # of the new project trackers. | |
|
343 | # This will clear the fixed_version is it's no longer valid for the new project. | |
|
344 | # This will clear the parent issue if it's no longer valid for the new project. | |
|
345 | # This will set the category to the category with the same name in the new | |
|
346 | # project if it exists, or clear it if it doesn't. | |
|
320 | 347 | def project=(project, keep_tracker=false) |
|
321 | 348 | project_was = self.project |
|
322 | 349 | association(:project).writer(project) |
@@ -339,7 +366,9 class Issue < ActiveRecord::Base | |||
|
339 | 366 | self.parent_issue_id = nil |
|
340 | 367 | end |
|
341 | 368 | @custom_field_values = nil |
|
369 | @workflow_rule_by_attribute = nil | |
|
342 | 370 | end |
|
371 | self.project | |
|
343 | 372 | end |
|
344 | 373 | |
|
345 | 374 | def description=(arg) |
@@ -776,14 +805,28 class Issue < ActiveRecord::Base | |||
|
776 | 805 | !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil? |
|
777 | 806 | end |
|
778 | 807 | |
|
808 | # Returns the default status of the issue based on its tracker | |
|
809 | # Returns nil if tracker is nil | |
|
810 | def default_status | |
|
811 | tracker.try(:default_status) | |
|
812 | end | |
|
813 | ||
|
779 | 814 | # Returns an array of statuses that user is able to apply |
|
780 | 815 | def new_statuses_allowed_to(user=User.current, include_default=false) |
|
781 | 816 | if new_record? && @copied_from |
|
782 |
[ |
|
|
817 | [default_status, @copied_from.status].compact.uniq.sort | |
|
783 | 818 | else |
|
784 | 819 | initial_status = nil |
|
785 | 820 | if new_record? |
|
786 |
initial_status = |
|
|
821 | initial_status = default_status | |
|
822 | elsif tracker_id_changed? | |
|
823 | if Tracker.where(:id => tracker_id_was, :default_status_id => status_id_was).any? | |
|
824 | initial_status = default_status | |
|
825 | elsif tracker.issue_status_ids.include?(status_id_was) | |
|
826 | initial_status = IssueStatus.find_by_id(status_id_was) | |
|
827 | else | |
|
828 | initial_status = default_status | |
|
829 | end | |
|
787 | 830 | else |
|
788 | 831 | initial_status = status_was |
|
789 | 832 | end |
@@ -802,7 +845,7 class Issue < ActiveRecord::Base | |||
|
802 | 845 | ) |
|
803 | 846 | end |
|
804 | 847 | statuses << initial_status unless statuses.empty? |
|
805 |
statuses << |
|
|
848 | statuses << default_status if include_default | |
|
806 | 849 | statuses = statuses.compact.uniq.sort |
|
807 | 850 | if blocked? |
|
808 | 851 | statuses.reject!(&:is_closed?) |
@@ -22,7 +22,6 class IssueStatus < ActiveRecord::Base | |||
|
22 | 22 | acts_as_list |
|
23 | 23 | |
|
24 | 24 | before_destroy :delete_workflow_rules |
|
25 | after_save :update_default | |
|
26 | 25 | |
|
27 | 26 | validates_presence_of :name |
|
28 | 27 | validates_uniqueness_of :name |
@@ -33,15 +32,6 class IssueStatus < ActiveRecord::Base | |||
|
33 | 32 | scope :sorted, lambda { order(:position) } |
|
34 | 33 | scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} |
|
35 | 34 | |
|
36 | def update_default | |
|
37 | IssueStatus.where(['id <> ?', id]).update_all({:is_default => false}) if self.is_default? | |
|
38 | end | |
|
39 | ||
|
40 | # Returns the default status for new issues | |
|
41 | def self.default | |
|
42 | where(:is_default => true).first | |
|
43 | end | |
|
44 | ||
|
45 | 35 | # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+ |
|
46 | 36 | def self.update_issue_done_ratios |
|
47 | 37 | if Issue.use_status_for_done_ratio? |
@@ -100,7 +90,11 class IssueStatus < ActiveRecord::Base | |||
|
100 | 90 | private |
|
101 | 91 | |
|
102 | 92 | def check_integrity |
|
103 |
|
|
|
93 | if Issue.where(:status_id => id).any? | |
|
94 | raise "This status is used by some issues" | |
|
95 | elsif Tracker.where(:default_status_id => id).any? | |
|
96 | raise "This status is used as the default status by some trackers" | |
|
97 | end | |
|
104 | 98 | end |
|
105 | 99 | |
|
106 | 100 | # Deletes associated workflows |
@@ -24,6 +24,7 class Tracker < ActiveRecord::Base | |||
|
24 | 24 | CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze |
|
25 | 25 | |
|
26 | 26 | before_destroy :check_integrity |
|
27 | belongs_to :default_status, :class_name => 'IssueStatus' | |
|
27 | 28 | has_many :issues |
|
28 | 29 | has_many :workflow_rules, :dependent => :delete_all do |
|
29 | 30 | def copy(source_tracker) |
@@ -37,6 +38,7 class Tracker < ActiveRecord::Base | |||
|
37 | 38 | |
|
38 | 39 | attr_protected :fields_bits |
|
39 | 40 | |
|
41 | validates_presence_of :default_status | |
|
40 | 42 | validates_presence_of :name |
|
41 | 43 | validates_uniqueness_of :name |
|
42 | 44 | validates_length_of :name, :maximum => 30 |
@@ -53,14 +55,15 class Tracker < ActiveRecord::Base | |||
|
53 | 55 | # Returns an array of IssueStatus that are used |
|
54 | 56 | # in the tracker's workflows |
|
55 | 57 | def issue_statuses |
|
56 | if @issue_statuses | |
|
57 | return @issue_statuses | |
|
58 | elsif new_record? | |
|
59 | return [] | |
|
60 | end | |
|
58 | @issue_statuses ||= IssueStatus.where(:id => issue_status_ids).to_a.sort | |
|
59 | end | |
|
61 | 60 | |
|
62 | status_ids = WorkflowTransition.where(:tracker_id => id).uniq.pluck(:old_status_id, :new_status_id).flatten.uniq | |
|
63 | @issue_statuses = IssueStatus.where(:id => status_ids).to_a.sort | |
|
61 | def issue_status_ids | |
|
62 | if new_record? | |
|
63 | [] | |
|
64 | else | |
|
65 | @issue_status_ids ||= WorkflowTransition.where(:tracker_id => id).uniq.pluck(:old_status_id, :new_status_id).flatten.uniq | |
|
66 | end | |
|
64 | 67 | end |
|
65 | 68 | |
|
66 | 69 | def disabled_core_fields |
@@ -6,7 +6,6 | |||
|
6 | 6 | <p><%= f.select :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :include_blank => true, :label => :field_done_ratio %></p> |
|
7 | 7 | <% end %> |
|
8 | 8 | <p><%= f.check_box :is_closed %></p> |
|
9 | <p><%= f.check_box :is_default %></p> | |
|
10 | 9 | |
|
11 | 10 | <%= call_hook(:view_issue_statuses_form, :issue_status => @issue_status) %> |
|
12 | 11 | </div> |
@@ -3,7 +3,6 api.array :issue_statuses do | |||
|
3 | 3 | api.issue_status do |
|
4 | 4 | api.id status.id |
|
5 | 5 | api.name status.name |
|
6 | api.is_default status.is_default | |
|
7 | 6 | api.is_closed status.is_closed |
|
8 | 7 | end |
|
9 | 8 | end |
@@ -11,7 +11,6 | |||
|
11 | 11 | <% if Issue.use_status_for_done_ratio? %> |
|
12 | 12 | <th><%=l(:field_done_ratio)%></th> |
|
13 | 13 | <% end %> |
|
14 | <th><%=l(:field_is_default)%></th> | |
|
15 | 14 | <th><%=l(:field_is_closed)%></th> |
|
16 | 15 | <th><%=l(:button_sort)%></th> |
|
17 | 16 | <th></th> |
@@ -23,7 +22,6 | |||
|
23 | 22 | <% if Issue.use_status_for_done_ratio? %> |
|
24 | 23 | <td><%= h status.default_done_ratio %></td> |
|
25 | 24 | <% end %> |
|
26 | <td><%= checked_image status.is_default? %></td> | |
|
27 | 25 | <td><%= checked_image status.is_closed? %></td> |
|
28 | 26 | <td class="reorder"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td> |
|
29 | 27 | <td class="buttons"> |
@@ -5,9 +5,9 | |||
|
5 | 5 | <% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %> |
|
6 | 6 | <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true}, |
|
7 | 7 | :onchange => "updateIssueFrom('#{escape_javascript project_issue_form_path(@project, :id => @issue, :format => 'js')}')" %></p> |
|
8 | ||
|
8 | <%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %> | |
|
9 | 9 | <% else %> |
|
10 |
<p><label><%= l(:field_status) %></label> <%= |
|
|
10 | <p><label><%= l(:field_status) %></label> <%= @issue.status %></p> | |
|
11 | 11 | <% end %> |
|
12 | 12 | |
|
13 | 13 | <% if @issue.safe_attribute? 'priority_id' %> |
@@ -4,8 +4,12 | |||
|
4 | 4 | <div class="box tabular"> |
|
5 | 5 | <!--[form:tracker]--> |
|
6 | 6 | <p><%= f.text_field :name, :required => true %></p> |
|
7 | <p><%= f.select :default_status_id, | |
|
8 | IssueStatus.sorted.map {|s| [s.name, s.id]}, | |
|
9 | :include_blank => @tracker.default_status.nil?, | |
|
10 | :required => true %> | |
|
11 | </p> | |
|
7 | 12 | <p><%= f.check_box :is_in_roadmap %></p> |
|
8 | ||
|
9 | 13 | <p> |
|
10 | 14 | <label><%= l(:field_core_fields) %></label> |
|
11 | 15 | <% Tracker::CORE_FIELDS.each do |field| %> |
@@ -3,6 +3,7 api.array :trackers do | |||
|
3 | 3 | api.tracker do |
|
4 | 4 | api.id tracker.id |
|
5 | 5 | api.name tracker.name |
|
6 | api.default_status(:id => tracker.default_status.id, :name => tracker.default_status.name) unless tracker.default_status.nil? | |
|
6 | 7 | end |
|
7 | 8 | end |
|
8 | 9 | end |
@@ -337,6 +337,7 en: | |||
|
337 | 337 | field_inherit_members: Inherit members |
|
338 | 338 | field_generate_password: Generate password |
|
339 | 339 | field_must_change_passwd: Must change password at next logon |
|
340 | field_default_status: Default status | |
|
340 | 341 | |
|
341 | 342 | setting_app_title: Application title |
|
342 | 343 | setting_app_subtitle: Application subtitle |
@@ -357,6 +357,7 fr: | |||
|
357 | 357 | field_inherit_members: Hériter les membres |
|
358 | 358 | field_generate_password: Générer un mot de passe |
|
359 | 359 | field_must_change_passwd: Doit changer de mot de passe à la prochaine connexion |
|
360 | field_default_status: Statut par défaut | |
|
360 | 361 | |
|
361 | 362 | setting_app_title: Titre de l'application |
|
362 | 363 | setting_app_subtitle: Sous-titre de l'application |
@@ -125,18 +125,18 module Redmine | |||
|
125 | 125 | :browse_repository, |
|
126 | 126 | :view_changesets] |
|
127 | 127 | |
|
128 | # Trackers | |
|
129 | Tracker.create!(:name => l(:default_tracker_bug), :is_in_chlog => true, :is_in_roadmap => false, :position => 1) | |
|
130 | Tracker.create!(:name => l(:default_tracker_feature), :is_in_chlog => true, :is_in_roadmap => true, :position => 2) | |
|
131 | Tracker.create!(:name => l(:default_tracker_support), :is_in_chlog => false, :is_in_roadmap => false, :position => 3) | |
|
132 | ||
|
133 | 128 | # Issue statuses |
|
134 |
new = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, |
|
|
135 |
in_progress = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, |
|
|
136 |
resolved = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, |
|
|
137 |
feedback = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, |
|
|
138 |
closed = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, |
|
|
139 |
rejected = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, |
|
|
129 | new = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, :position => 1) | |
|
130 | in_progress = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, :position => 2) | |
|
131 | resolved = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, :position => 3) | |
|
132 | feedback = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, :position => 4) | |
|
133 | closed = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, :position => 5) | |
|
134 | rejected = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, :position => 6) | |
|
135 | ||
|
136 | # Trackers | |
|
137 | Tracker.create!(:name => l(:default_tracker_bug), :default_status_id => new.id, :is_in_chlog => true, :is_in_roadmap => false, :position => 1) | |
|
138 | Tracker.create!(:name => l(:default_tracker_feature), :default_status_id => new.id, :is_in_chlog => true, :is_in_roadmap => true, :position => 2) | |
|
139 | Tracker.create!(:name => l(:default_tracker_support), :default_status_id => new.id, :is_in_chlog => false, :is_in_roadmap => false, :position => 3) | |
|
140 | 140 | |
|
141 | 141 | # Workflow |
|
142 | 142 | Tracker.all.each { |t| |
@@ -25,15 +25,15 task :migrate_from_mantis => :environment do | |||
|
25 | 25 | |
|
26 | 26 | module MantisMigrate |
|
27 | 27 | |
|
28 | DEFAULT_STATUS = IssueStatus.default | |
|
28 | new_status = IssueStatus.find_by_position(1) | |
|
29 | 29 | assigned_status = IssueStatus.find_by_position(2) |
|
30 | 30 | resolved_status = IssueStatus.find_by_position(3) |
|
31 | 31 | feedback_status = IssueStatus.find_by_position(4) |
|
32 | 32 | closed_status = IssueStatus.where(:is_closed => true).first |
|
33 |
STATUS_MAPPING = {10 => |
|
|
33 | STATUS_MAPPING = {10 => new_status, # new | |
|
34 | 34 | 20 => feedback_status, # feedback |
|
35 |
30 => |
|
|
36 |
40 => |
|
|
35 | 30 => new_status, # acknowledged | |
|
36 | 40 => new_status, # confirmed | |
|
37 | 37 | 50 => assigned_status, # assigned |
|
38 | 38 | 80 => resolved_status, # resolved |
|
39 | 39 | 90 => closed_status # closed |
@@ -317,8 +317,8 task :migrate_from_mantis => :environment do | |||
|
317 | 317 | i.author = User.find_by_id(users_map[bug.reporter_id]) |
|
318 | 318 | i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank? |
|
319 | 319 | i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank? |
|
320 | i.status = STATUS_MAPPING[bug.status] || DEFAULT_STATUS | |
|
321 | 320 | i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG) |
|
321 | i.status = STATUS_MAPPING[bug.status] || i.status | |
|
322 | 322 | i.id = bug.id if keep_bug_ids |
|
323 | 323 | next unless i.save |
|
324 | 324 | issues_map[bug.id] = i.id |
@@ -25,12 +25,12 namespace :redmine do | |||
|
25 | 25 | module TracMigrate |
|
26 | 26 | TICKET_MAP = [] |
|
27 | 27 | |
|
28 | DEFAULT_STATUS = IssueStatus.default | |
|
28 | new_status = IssueStatus.find_by_position(1) | |
|
29 | 29 | assigned_status = IssueStatus.find_by_position(2) |
|
30 | 30 | resolved_status = IssueStatus.find_by_position(3) |
|
31 | 31 | feedback_status = IssueStatus.find_by_position(4) |
|
32 | 32 | closed_status = IssueStatus.where(:is_closed => true).first |
|
33 |
STATUS_MAPPING = {'new' => |
|
|
33 | STATUS_MAPPING = {'new' => new_status, | |
|
34 | 34 | 'reopened' => feedback_status, |
|
35 | 35 | 'assigned' => assigned_status, |
|
36 | 36 | 'closed' => closed_status |
@@ -476,8 +476,8 namespace :redmine do | |||
|
476 | 476 | i.author = find_or_create_user(ticket.reporter) |
|
477 | 477 | i.category = issues_category_map[ticket.component] unless ticket.component.blank? |
|
478 | 478 | i.fixed_version = version_map[ticket.milestone] unless ticket.milestone.blank? |
|
479 | i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS | |
|
480 | 479 | i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER |
|
480 | i.status = STATUS_MAPPING[ticket.status] || i.default_status | |
|
481 | 481 | i.id = ticket.id unless Issue.exists?(ticket.id) |
|
482 | 482 | next unless Time.fake(ticket.changetime) { i.save } |
|
483 | 483 | TICKET_MAP[ticket.id] = i.id |
@@ -2,36 +2,30 | |||
|
2 | 2 | issue_statuses_001: |
|
3 | 3 | id: 1 |
|
4 | 4 | name: New |
|
5 | is_default: true | |
|
6 | 5 | is_closed: false |
|
7 | 6 | position: 1 |
|
8 | 7 | issue_statuses_002: |
|
9 | 8 | id: 2 |
|
10 | 9 | name: Assigned |
|
11 | is_default: false | |
|
12 | 10 | is_closed: false |
|
13 | 11 | position: 2 |
|
14 | 12 | issue_statuses_003: |
|
15 | 13 | id: 3 |
|
16 | 14 | name: Resolved |
|
17 | is_default: false | |
|
18 | 15 | is_closed: false |
|
19 | 16 | position: 3 |
|
20 | 17 | issue_statuses_004: |
|
21 | 18 | name: Feedback |
|
22 | 19 | id: 4 |
|
23 | is_default: false | |
|
24 | 20 | is_closed: false |
|
25 | 21 | position: 4 |
|
26 | 22 | issue_statuses_005: |
|
27 | 23 | id: 5 |
|
28 | 24 | name: Closed |
|
29 | is_default: false | |
|
30 | 25 | is_closed: true |
|
31 | 26 | position: 5 |
|
32 | 27 | issue_statuses_006: |
|
33 | 28 | id: 6 |
|
34 | 29 | name: Rejected |
|
35 | is_default: false | |
|
36 | 30 | is_closed: true |
|
37 | 31 | position: 6 |
@@ -3,14 +3,17 trackers_001: | |||
|
3 | 3 | name: Bug |
|
4 | 4 | id: 1 |
|
5 | 5 | is_in_chlog: true |
|
6 | default_status_id: 1 | |
|
6 | 7 | position: 1 |
|
7 | 8 | trackers_002: |
|
8 | 9 | name: Feature request |
|
9 | 10 | id: 2 |
|
10 | 11 | is_in_chlog: true |
|
12 | default_status_id: 1 | |
|
11 | 13 | position: 2 |
|
12 | 14 | trackers_003: |
|
13 | 15 | name: Support request |
|
14 | 16 | id: 3 |
|
15 | 17 | is_in_chlog: false |
|
18 | default_status_id: 1 | |
|
16 | 19 | position: 3 |
@@ -86,7 +86,8 class IssueStatusesControllerTest < ActionController::TestCase | |||
|
86 | 86 | end |
|
87 | 87 | |
|
88 | 88 | def test_destroy |
|
89 | Issue.delete_all("status_id = 1") | |
|
89 | Issue.where(:status_id => 1).delete_all | |
|
90 | Tracker.where(:default_status_id => 1).delete_all | |
|
90 | 91 | |
|
91 | 92 | assert_difference 'IssueStatus.count', -1 do |
|
92 | 93 | delete :destroy, :id => '1' |
@@ -96,7 +97,19 class IssueStatusesControllerTest < ActionController::TestCase | |||
|
96 | 97 | end |
|
97 | 98 | |
|
98 | 99 | def test_destroy_should_block_if_status_in_use |
|
99 |
assert |
|
|
100 | assert Issue.where(:status_id => 1).any? | |
|
101 | Tracker.where(:default_status_id => 1).delete_all | |
|
102 | ||
|
103 | assert_no_difference 'IssueStatus.count' do | |
|
104 | delete :destroy, :id => '1' | |
|
105 | end | |
|
106 | assert_redirected_to :action => 'index' | |
|
107 | assert_not_nil IssueStatus.find_by_id(1) | |
|
108 | end | |
|
109 | ||
|
110 | def test_destroy_should_block_if_status_in_use | |
|
111 | Issue.where(:status_id => 1).delete_all | |
|
112 | assert Tracker.where(:default_status_id => 1).any? | |
|
100 | 113 | |
|
101 | 114 | assert_no_difference 'IssueStatus.count' do |
|
102 | 115 | delete :destroy, :id => '1' |
@@ -1511,6 +1511,30 class IssuesControllerTest < ActionController::TestCase | |||
|
1511 | 1511 | end |
|
1512 | 1512 | end |
|
1513 | 1513 | |
|
1514 | def test_new_should_select_default_status | |
|
1515 | @request.session[:user_id] = 2 | |
|
1516 | ||
|
1517 | get :new, :project_id => 1 | |
|
1518 | assert_response :success | |
|
1519 | assert_template 'new' | |
|
1520 | assert_select 'select[name=?]', 'issue[status_id]' do | |
|
1521 | assert_select 'option[value=1][selected=selected]' | |
|
1522 | end | |
|
1523 | assert_select 'input[name=was_default_status][value=1]' | |
|
1524 | end | |
|
1525 | ||
|
1526 | def test_new_should_select_default_status | |
|
1527 | @request.session[:user_id] = 2 | |
|
1528 | ||
|
1529 | get :new, :project_id => 1 | |
|
1530 | assert_response :success | |
|
1531 | assert_template 'new' | |
|
1532 | assert_select 'select[name=?]', 'issue[status_id]' do | |
|
1533 | assert_select 'option[value=1][selected=selected]' | |
|
1534 | end | |
|
1535 | assert_select 'input[name=was_default_status][value=1]' | |
|
1536 | end | |
|
1537 | ||
|
1514 | 1538 | def test_get_new_with_list_custom_field |
|
1515 | 1539 | @request.session[:user_id] = 2 |
|
1516 | 1540 | get :new, :project_id => 1, :tracker_id => 1 |
@@ -1731,6 +1755,20 class IssuesControllerTest < ActionController::TestCase | |||
|
1731 | 1755 | assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort |
|
1732 | 1756 | end |
|
1733 | 1757 | |
|
1758 | def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals | |
|
1759 | @request.session[:user_id] = 2 | |
|
1760 | tracker = Tracker.find(2) | |
|
1761 | tracker.update! :default_status_id => 2 | |
|
1762 | tracker.generate_transitions! 2, 1, :clear => true | |
|
1763 | ||
|
1764 | xhr :post, :update_form, :project_id => 1, | |
|
1765 | :issue => {:tracker_id => 2, | |
|
1766 | :status_id => 1}, | |
|
1767 | :was_default_status => 1 | |
|
1768 | ||
|
1769 | assert_equal 2, assigns(:issue).status_id | |
|
1770 | end | |
|
1771 | ||
|
1734 | 1772 | def test_post_create |
|
1735 | 1773 | @request.session[:user_id] = 2 |
|
1736 | 1774 | assert_difference 'Issue.count' do |
@@ -2266,13 +2304,17 class IssuesControllerTest < ActionController::TestCase | |||
|
2266 | 2304 | get :new, :project_id => 1 |
|
2267 | 2305 | assert_response :success |
|
2268 | 2306 | assert_template 'new' |
|
2307 | ||
|
2308 | issue = assigns(:issue) | |
|
2309 | assert_not_nil issue.default_status | |
|
2310 | ||
|
2269 | 2311 | assert_select 'select[name=?]', 'issue[status_id]' do |
|
2270 | 2312 | assert_select 'option', 1 |
|
2271 |
assert_select 'option[value=?]', |
|
|
2313 | assert_select 'option[value=?]', issue.default_status.id.to_s | |
|
2272 | 2314 | end |
|
2273 | 2315 | end |
|
2274 | 2316 | |
|
2275 |
test "without workflow privilege # |
|
|
2317 | test "without workflow privilege #create should accept default status" do | |
|
2276 | 2318 | setup_without_workflow_privilege |
|
2277 | 2319 | assert_difference 'Issue.count' do |
|
2278 | 2320 | post :create, :project_id => 1, |
@@ -2281,10 +2323,11 class IssuesControllerTest < ActionController::TestCase | |||
|
2281 | 2323 | :status_id => 1} |
|
2282 | 2324 | end |
|
2283 | 2325 | issue = Issue.order('id').last |
|
2284 |
assert_ |
|
|
2326 | assert_not_nil issue.default_status | |
|
2327 | assert_equal issue.default_status, issue.status | |
|
2285 | 2328 | end |
|
2286 | 2329 | |
|
2287 |
test "without workflow privilege # |
|
|
2330 | test "without workflow privilege #create should ignore unauthorized status" do | |
|
2288 | 2331 | setup_without_workflow_privilege |
|
2289 | 2332 | assert_difference 'Issue.count' do |
|
2290 | 2333 | post :create, :project_id => 1, |
@@ -2293,7 +2336,8 class IssuesControllerTest < ActionController::TestCase | |||
|
2293 | 2336 | :status_id => 3} |
|
2294 | 2337 | end |
|
2295 | 2338 | issue = Issue.order('id').last |
|
2296 |
assert_ |
|
|
2339 | assert_not_nil issue.default_status | |
|
2340 | assert_equal issue.default_status, issue.status | |
|
2297 | 2341 | end |
|
2298 | 2342 | |
|
2299 | 2343 | test "without workflow privilege #update should ignore status change" do |
@@ -18,7 +18,7 | |||
|
18 | 18 | require File.expand_path('../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class TrackersControllerTest < ActionController::TestCase |
|
21 | fixtures :trackers, :projects, :projects_trackers, :users, :issues, :custom_fields | |
|
21 | fixtures :trackers, :projects, :projects_trackers, :users, :issues, :custom_fields, :issue_statuses | |
|
22 | 22 | |
|
23 | 23 | def setup |
|
24 | 24 | User.current = nil |
@@ -51,7 +51,7 class TrackersControllerTest < ActionController::TestCase | |||
|
51 | 51 | |
|
52 | 52 | def test_create |
|
53 | 53 | assert_difference 'Tracker.count' do |
|
54 | post :create, :tracker => { :name => 'New tracker', :project_ids => ['1', '', ''], :custom_field_ids => ['1', '6', ''] } | |
|
54 | post :create, :tracker => { :name => 'New tracker', :default_status_id => 1, :project_ids => ['1', '', ''], :custom_field_ids => ['1', '6', ''] } | |
|
55 | 55 | end |
|
56 | 56 | assert_redirected_to :action => 'index' |
|
57 | 57 | tracker = Tracker.order('id DESC').first |
@@ -62,9 +62,9 class TrackersControllerTest < ActionController::TestCase | |||
|
62 | 62 | assert_equal 0, tracker.workflow_rules.count |
|
63 | 63 | end |
|
64 | 64 | |
|
65 | def create_with_disabled_core_fields | |
|
65 | def test_create_with_disabled_core_fields | |
|
66 | 66 | assert_difference 'Tracker.count' do |
|
67 | post :create, :tracker => { :name => 'New tracker', :core_fields => ['assigned_to_id', 'fixed_version_id', ''] } | |
|
67 | post :create, :tracker => { :name => 'New tracker', :default_status_id => 1, :core_fields => ['assigned_to_id', 'fixed_version_id', ''] } | |
|
68 | 68 | end |
|
69 | 69 | assert_redirected_to :action => 'index' |
|
70 | 70 | tracker = Tracker.order('id DESC').first |
@@ -74,7 +74,7 class TrackersControllerTest < ActionController::TestCase | |||
|
74 | 74 | |
|
75 | 75 | def test_create_new_with_workflow_copy |
|
76 | 76 | assert_difference 'Tracker.count' do |
|
77 | post :create, :tracker => { :name => 'New tracker' }, :copy_workflow_from => 1 | |
|
77 | post :create, :tracker => { :name => 'New tracker', :default_status_id => 1 }, :copy_workflow_from => 1 | |
|
78 | 78 | end |
|
79 | 79 | assert_redirected_to :action => 'index' |
|
80 | 80 | tracker = Tracker.find_by_name('New tracker') |
@@ -164,7 +164,7 class TrackersControllerTest < ActionController::TestCase | |||
|
164 | 164 | end |
|
165 | 165 | |
|
166 | 166 | def test_destroy |
|
167 |
tracker = Tracker. |
|
|
167 | tracker = Tracker.generate!(:name => 'Destroyable') | |
|
168 | 168 | assert_difference 'Tracker.count', -1 do |
|
169 | 169 | delete :destroy, :id => tracker.id |
|
170 | 170 | end |
@@ -45,11 +45,22 module ObjectHelpers | |||
|
45 | 45 | project |
|
46 | 46 | end |
|
47 | 47 | |
|
48 | def IssueStatus.generate!(attributes={}) | |
|
49 | @generated_status_name ||= 'Status 0' | |
|
50 | @generated_status_name.succ! | |
|
51 | status = IssueStatus.new(attributes) | |
|
52 | status.name = @generated_status_name.dup if status.name.blank? | |
|
53 | yield status if block_given? | |
|
54 | status.save! | |
|
55 | status | |
|
56 | end | |
|
57 | ||
|
48 | 58 | def Tracker.generate!(attributes={}) |
|
49 | 59 | @generated_tracker_name ||= 'Tracker 0' |
|
50 | 60 | @generated_tracker_name.succ! |
|
51 | 61 | tracker = Tracker.new(attributes) |
|
52 | 62 | tracker.name = @generated_tracker_name.dup if tracker.name.blank? |
|
63 | tracker.default_status ||= IssueStatus.order('position').first || IssueStatus.generate! | |
|
53 | 64 | yield tracker if block_given? |
|
54 | 65 | tracker.save! |
|
55 | 66 | tracker |
@@ -188,6 +199,27 module ObjectHelpers | |||
|
188 | 199 | end |
|
189 | 200 | end |
|
190 | 201 | |
|
202 | module TrackerObjectHelpers | |
|
203 | def generate_transitions!(*args) | |
|
204 | options = args.last.is_a?(Hash) ? args.pop : {} | |
|
205 | if args.size == 1 | |
|
206 | args << args.first | |
|
207 | end | |
|
208 | if options[:clear] | |
|
209 | WorkflowTransition.where(:tracker_id => id).delete_all | |
|
210 | end | |
|
211 | args.each_cons(2) do |old_status_id, new_status_id| | |
|
212 | WorkflowTransition.create!( | |
|
213 | :tracker => self, | |
|
214 | :role_id => (options[:role_id] || 1), | |
|
215 | :old_status_id => old_status_id, | |
|
216 | :new_status_id => new_status_id | |
|
217 | ) | |
|
218 | end | |
|
219 | end | |
|
220 | end | |
|
221 | Tracker.send :include, TrackerObjectHelpers | |
|
222 | ||
|
191 | 223 | module IssueObjectHelpers |
|
192 | 224 | def close! |
|
193 | 225 | self.status = IssueStatus.where(:is_closed => true).first |
@@ -198,5 +230,4 module IssueObjectHelpers | |||
|
198 | 230 | Issue.generate!(attributes.merge(:parent_issue_id => self.id)) |
|
199 | 231 | end |
|
200 | 232 | end |
|
201 | ||
|
202 | 233 | Issue.send :include, IssueObjectHelpers |
@@ -28,7 +28,6 class IssueStatusTest < ActiveSupport::TestCase | |||
|
28 | 28 | |
|
29 | 29 | status.name = "Test Status" |
|
30 | 30 | assert status.save |
|
31 | assert !status.is_default | |
|
32 | 31 | end |
|
33 | 32 | |
|
34 | 33 | def test_destroy |
@@ -46,29 +45,6 class IssueStatusTest < ActiveSupport::TestCase | |||
|
46 | 45 | assert_raise(RuntimeError, "Can't delete status") { status.destroy } |
|
47 | 46 | end |
|
48 | 47 | |
|
49 | def test_default | |
|
50 | status = IssueStatus.default | |
|
51 | assert_kind_of IssueStatus, status | |
|
52 | end | |
|
53 | ||
|
54 | def test_change_default | |
|
55 | status = IssueStatus.find(2) | |
|
56 | assert !status.is_default | |
|
57 | status.is_default = true | |
|
58 | assert status.save | |
|
59 | status.reload | |
|
60 | ||
|
61 | assert_equal status, IssueStatus.default | |
|
62 | assert !IssueStatus.find(1).is_default | |
|
63 | end | |
|
64 | ||
|
65 | def test_reorder_should_not_clear_default_status | |
|
66 | status = IssueStatus.default | |
|
67 | status.move_to_bottom | |
|
68 | status.reload | |
|
69 | assert status.is_default? | |
|
70 | end | |
|
71 | ||
|
72 | 48 | def test_new_statuses_allowed_to |
|
73 | 49 | WorkflowTransition.delete_all |
|
74 | 50 |
@@ -40,11 +40,11 class IssueTest < ActiveSupport::TestCase | |||
|
40 | 40 | |
|
41 | 41 | assert_nil issue.project_id |
|
42 | 42 | assert_nil issue.tracker_id |
|
43 | assert_nil issue.status_id | |
|
43 | 44 | assert_nil issue.author_id |
|
44 | 45 | assert_nil issue.assigned_to_id |
|
45 | 46 | assert_nil issue.category_id |
|
46 | 47 | |
|
47 | assert_equal IssueStatus.default, issue.status | |
|
48 | 48 | assert_equal IssuePriority.default, issue.priority |
|
49 | 49 | end |
|
50 | 50 | |
@@ -59,10 +59,9 class IssueTest < ActiveSupport::TestCase | |||
|
59 | 59 | end |
|
60 | 60 | |
|
61 | 61 | def test_create_minimal |
|
62 | issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, | |
|
63 | :status_id => 1, :priority => IssuePriority.all.first, | |
|
64 | :subject => 'test_create') | |
|
62 | issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :subject => 'test_create') | |
|
65 | 63 | assert issue.save |
|
64 | assert_equal issue.tracker.default_status, issue.status | |
|
66 | 65 | assert issue.description.nil? |
|
67 | 66 | assert_nil issue.estimated_hours |
|
68 | 67 | end |
@@ -908,7 +907,7 class IssueTest < ActiveSupport::TestCase | |||
|
908 | 907 | |
|
909 | 908 | def test_copy_should_copy_status |
|
910 | 909 | orig = Issue.find(8) |
|
911 |
assert orig.status != |
|
|
910 | assert orig.status != orig.default_status | |
|
912 | 911 | |
|
913 | 912 | issue = Issue.new.copy_from(orig) |
|
914 | 913 | assert issue.save |
@@ -2480,4 +2479,67 class IssueTest < ActiveSupport::TestCase | |||
|
2480 | 2479 | issue.save! |
|
2481 | 2480 | assert_equal false, issue.reopening? |
|
2482 | 2481 | end |
|
2482 | ||
|
2483 | def test_default_status_without_tracker_should_be_nil | |
|
2484 | issue = Issue.new | |
|
2485 | assert_nil issue.tracker | |
|
2486 | assert_nil issue.default_status | |
|
2487 | end | |
|
2488 | ||
|
2489 | def test_default_status_should_be_tracker_default_status | |
|
2490 | issue = Issue.new(:tracker_id => 1) | |
|
2491 | assert_not_nil issue.status | |
|
2492 | assert_equal issue.tracker.default_status, issue.default_status | |
|
2493 | end | |
|
2494 | ||
|
2495 | def test_initializing_with_tracker_should_set_default_status | |
|
2496 | issue = Issue.new(:tracker => Tracker.find(1)) | |
|
2497 | assert_not_nil issue.status | |
|
2498 | assert_equal issue.default_status, issue.status | |
|
2499 | end | |
|
2500 | ||
|
2501 | def test_initializing_with_tracker_id_should_set_default_status | |
|
2502 | issue = Issue.new(:tracker_id => 1) | |
|
2503 | assert_not_nil issue.status | |
|
2504 | assert_equal issue.default_status, issue.status | |
|
2505 | end | |
|
2506 | ||
|
2507 | def test_setting_tracker_should_set_default_status | |
|
2508 | issue = Issue.new | |
|
2509 | issue.tracker = Tracker.find(1) | |
|
2510 | assert_not_nil issue.status | |
|
2511 | assert_equal issue.default_status, issue.status | |
|
2512 | end | |
|
2513 | ||
|
2514 | def test_changing_tracker_should_set_default_status_if_status_was_default | |
|
2515 | WorkflowTransition.delete_all | |
|
2516 | WorkflowTransition.create! :role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1 | |
|
2517 | Tracker.find(2).update! :default_status_id => 2 | |
|
2518 | ||
|
2519 | issue = Issue.new(:tracker_id => 1, :status_id => 1) | |
|
2520 | assert_equal IssueStatus.find(1), issue.status | |
|
2521 | issue.tracker = Tracker.find(2) | |
|
2522 | assert_equal IssueStatus.find(2), issue.status | |
|
2523 | end | |
|
2524 | ||
|
2525 | def test_changing_tracker_should_set_default_status_if_status_is_not_used_by_tracker | |
|
2526 | WorkflowTransition.delete_all | |
|
2527 | Tracker.find(2).update! :default_status_id => 2 | |
|
2528 | ||
|
2529 | issue = Issue.new(:tracker_id => 1, :status_id => 3) | |
|
2530 | assert_equal IssueStatus.find(3), issue.status | |
|
2531 | issue.tracker = Tracker.find(2) | |
|
2532 | assert_equal IssueStatus.find(2), issue.status | |
|
2533 | end | |
|
2534 | ||
|
2535 | def test_changing_tracker_should_keep_status_if_status_was_not_default_and_is_used_by_tracker | |
|
2536 | WorkflowTransition.delete_all | |
|
2537 | WorkflowTransition.create! :role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3 | |
|
2538 | Tracker.find(2).update! :default_status_id => 2 | |
|
2539 | ||
|
2540 | issue = Issue.new(:tracker_id => 1, :status_id => 3) | |
|
2541 | assert_equal IssueStatus.find(3), issue.status | |
|
2542 | issue.tracker = Tracker.find(2) | |
|
2543 | assert_equal IssueStatus.find(3), issue.status | |
|
2544 | end | |
|
2483 | 2545 | end |
@@ -412,7 +412,7 class MailHandlerTest < ActiveSupport::TestCase | |||
|
412 | 412 | |
|
413 | 413 | def test_add_issue_with_japanese_keywords |
|
414 | 414 | ja_dev = "\xe9\x96\x8b\xe7\x99\xba".force_encoding('UTF-8') |
|
415 |
tracker = Tracker. |
|
|
415 | tracker = Tracker.generate!(:name => ja_dev) | |
|
416 | 416 | Project.find(1).trackers << tracker |
|
417 | 417 | issue = submit_email( |
|
418 | 418 | 'japanese_keywords_iso_2022_jp.eml', |
@@ -32,7 +32,7 class TrackerTest < ActiveSupport::TestCase | |||
|
32 | 32 | source = Tracker.find(1) |
|
33 | 33 | assert_equal 89, source.workflow_rules.size |
|
34 | 34 | |
|
35 | target = Tracker.new(:name => 'Target') | |
|
35 | target = Tracker.new(:name => 'Target', :default_status_id => 1) | |
|
36 | 36 | assert target.save |
|
37 | 37 | target.workflow_rules.copy(source) |
|
38 | 38 | target.reload |
General Comments 0
You need to be logged in to leave comments.
Login now