@@ -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 | before_filter :find_project, :only => [:new, :create, :update_form] |
|
24 | before_filter :find_project, :only => [:new, :create, :update_form] | |
25 | before_filter :authorize, :except => [:index] |
|
25 | before_filter :authorize, :except => [:index] | |
26 | before_filter :find_optional_project, :only => [:index] |
|
26 | before_filter :find_optional_project, :only => [:index] | |
27 | before_filter :check_for_default_issue_status, :only => [:new, :create] |
|
|||
28 | before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] |
|
27 | before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] | |
29 | accept_rss_auth :index, :show |
|
28 | accept_rss_auth :index, :show | |
30 | accept_api_auth :index, :show, :create, :update, :destroy |
|
29 | accept_api_auth :index, :show, :create, :update, :destroy | |
@@ -234,7 +233,8 class IssuesController < ApplicationController | |||||
234 | target_projects ||= @projects |
|
233 | target_projects ||= @projects | |
235 |
|
234 | |||
236 | if @copy |
|
235 | if @copy | |
237 | @available_statuses = [IssueStatus.default] |
|
236 | # Copied issues will get their default statuses | |
|
237 | @available_statuses = [] | |||
238 | else |
|
238 | else | |
239 | @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) |
|
239 | @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) | |
240 | end |
|
240 | end | |
@@ -425,12 +425,21 class IssuesController < ApplicationController | |||||
425 | @issue = @project.issues.visible.find(params[:id]) |
|
425 | @issue = @project.issues.visible.find(params[:id]) | |
426 | end |
|
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 | @issue.tracker ||= @project.trackers.first |
|
434 | @issue.tracker ||= @project.trackers.first | |
430 | if @issue.tracker.nil? |
|
435 | if @issue.tracker.nil? | |
431 | render_error l(:error_no_tracker_in_project) |
|
436 | render_error l(:error_no_tracker_in_project) | |
432 | return false |
|
437 | return false | |
433 | end |
|
438 | end | |
|
439 | if @issue.status.nil? | |||
|
440 | render_error l(:error_no_default_issue_status) | |||
|
441 | return false | |||
|
442 | end | |||
434 |
|
443 | |||
435 | @priorities = IssuePriority.active |
|
444 | @priorities = IssuePriority.active | |
436 | @allowed_statuses = @issue.new_statuses_allowed_to(User.current, @issue.new_record?) |
|
445 | @allowed_statuses = @issue.new_statuses_allowed_to(User.current, @issue.new_record?) | |
@@ -440,13 +449,6 class IssuesController < ApplicationController | |||||
440 | end |
|
449 | end | |
441 | end |
|
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 | def parse_params_for_bulk_issue_attributes(params) |
|
452 | def parse_params_for_bulk_issue_attributes(params) | |
451 | attributes = (params[:issue] || {}).reject {|k,v| v.blank?} |
|
453 | attributes = (params[:issue] || {}).reject {|k,v| v.blank?} | |
452 | attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} |
|
454 | attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} |
@@ -162,7 +162,6 class Issue < ActiveRecord::Base | |||||
162 | super |
|
162 | super | |
163 | if new_record? |
|
163 | if new_record? | |
164 | # set default values for new records only |
|
164 | # set default values for new records only | |
165 | self.status ||= IssueStatus.default |
|
|||
166 | self.priority ||= IssuePriority.default |
|
165 | self.priority ||= IssuePriority.default | |
167 | self.watcher_user_ids = [] |
|
166 | self.watcher_user_ids = [] | |
168 | end |
|
167 | end | |
@@ -273,11 +272,19 class Issue < ActiveRecord::Base | |||||
273 | issue.save ? issue : false |
|
272 | issue.save ? issue : false | |
274 | end |
|
273 | end | |
275 |
|
274 | |||
276 | def status_id=(sid) |
|
275 | def status_id=(status_id) | |
277 | self.status = nil |
|
276 | if status_id.to_s != self.status_id.to_s | |
278 | result = write_attribute(:status_id, sid) |
|
277 | self.status = (status_id.present? ? IssueStatus.find_by_id(status_id) : nil) | |
279 | @workflow_rule_by_attribute = nil |
|
278 | end | |
280 | result |
|
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 | end |
|
288 | end | |
282 |
|
289 | |||
283 | def priority_id=(pid) |
|
290 | def priority_id=(pid) | |
@@ -302,12 +309,24 class Issue < ActiveRecord::Base | |||||
302 | self.tracker_id |
|
309 | self.tracker_id | |
303 | end |
|
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 | def tracker=(tracker) |
|
317 | def tracker=(tracker) | |
306 | if tracker != self.tracker |
|
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 | @custom_field_values = nil |
|
324 | @custom_field_values = nil | |
308 | @workflow_rule_by_attribute = nil |
|
325 | @workflow_rule_by_attribute = nil | |
309 | end |
|
326 | end | |
310 | association(:tracker).writer(tracker) |
|
327 | association(:tracker).writer(tracker) | |
|
328 | self.status ||= default_status | |||
|
329 | self.tracker | |||
311 | end |
|
330 | end | |
312 |
|
331 | |||
313 | def project_id=(project_id) |
|
332 | def project_id=(project_id) | |
@@ -317,6 +336,14 class Issue < ActiveRecord::Base | |||||
317 | self.project_id |
|
336 | self.project_id | |
318 | end |
|
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 | def project=(project, keep_tracker=false) |
|
347 | def project=(project, keep_tracker=false) | |
321 | project_was = self.project |
|
348 | project_was = self.project | |
322 | association(:project).writer(project) |
|
349 | association(:project).writer(project) | |
@@ -339,7 +366,9 class Issue < ActiveRecord::Base | |||||
339 | self.parent_issue_id = nil |
|
366 | self.parent_issue_id = nil | |
340 | end |
|
367 | end | |
341 | @custom_field_values = nil |
|
368 | @custom_field_values = nil | |
|
369 | @workflow_rule_by_attribute = nil | |||
342 | end |
|
370 | end | |
|
371 | self.project | |||
343 | end |
|
372 | end | |
344 |
|
373 | |||
345 | def description=(arg) |
|
374 | def description=(arg) | |
@@ -776,14 +805,28 class Issue < ActiveRecord::Base | |||||
776 | !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil? |
|
805 | !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil? | |
777 | end |
|
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 | # Returns an array of statuses that user is able to apply |
|
814 | # Returns an array of statuses that user is able to apply | |
780 | def new_statuses_allowed_to(user=User.current, include_default=false) |
|
815 | def new_statuses_allowed_to(user=User.current, include_default=false) | |
781 | if new_record? && @copied_from |
|
816 | if new_record? && @copied_from | |
782 |
[ |
|
817 | [default_status, @copied_from.status].compact.uniq.sort | |
783 | else |
|
818 | else | |
784 | initial_status = nil |
|
819 | initial_status = nil | |
785 | if new_record? |
|
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 | else |
|
830 | else | |
788 | initial_status = status_was |
|
831 | initial_status = status_was | |
789 | end |
|
832 | end | |
@@ -802,7 +845,7 class Issue < ActiveRecord::Base | |||||
802 | ) |
|
845 | ) | |
803 | end |
|
846 | end | |
804 | statuses << initial_status unless statuses.empty? |
|
847 | statuses << initial_status unless statuses.empty? | |
805 |
statuses << |
|
848 | statuses << default_status if include_default | |
806 | statuses = statuses.compact.uniq.sort |
|
849 | statuses = statuses.compact.uniq.sort | |
807 | if blocked? |
|
850 | if blocked? | |
808 | statuses.reject!(&:is_closed?) |
|
851 | statuses.reject!(&:is_closed?) |
@@ -22,7 +22,6 class IssueStatus < ActiveRecord::Base | |||||
22 | acts_as_list |
|
22 | acts_as_list | |
23 |
|
23 | |||
24 | before_destroy :delete_workflow_rules |
|
24 | before_destroy :delete_workflow_rules | |
25 | after_save :update_default |
|
|||
26 |
|
25 | |||
27 | validates_presence_of :name |
|
26 | validates_presence_of :name | |
28 | validates_uniqueness_of :name |
|
27 | validates_uniqueness_of :name | |
@@ -33,15 +32,6 class IssueStatus < ActiveRecord::Base | |||||
33 | scope :sorted, lambda { order(:position) } |
|
32 | scope :sorted, lambda { order(:position) } | |
34 | scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} |
|
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 | # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+ |
|
35 | # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+ | |
46 | def self.update_issue_done_ratios |
|
36 | def self.update_issue_done_ratios | |
47 | if Issue.use_status_for_done_ratio? |
|
37 | if Issue.use_status_for_done_ratio? | |
@@ -100,7 +90,11 class IssueStatus < ActiveRecord::Base | |||||
100 | private |
|
90 | private | |
101 |
|
91 | |||
102 | def check_integrity |
|
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 | end |
|
98 | end | |
105 |
|
99 | |||
106 | # Deletes associated workflows |
|
100 | # Deletes associated workflows |
@@ -24,6 +24,7 class Tracker < ActiveRecord::Base | |||||
24 | CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze |
|
24 | CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze | |
25 |
|
25 | |||
26 | before_destroy :check_integrity |
|
26 | before_destroy :check_integrity | |
|
27 | belongs_to :default_status, :class_name => 'IssueStatus' | |||
27 | has_many :issues |
|
28 | has_many :issues | |
28 | has_many :workflow_rules, :dependent => :delete_all do |
|
29 | has_many :workflow_rules, :dependent => :delete_all do | |
29 | def copy(source_tracker) |
|
30 | def copy(source_tracker) | |
@@ -37,6 +38,7 class Tracker < ActiveRecord::Base | |||||
37 |
|
38 | |||
38 | attr_protected :fields_bits |
|
39 | attr_protected :fields_bits | |
39 |
|
40 | |||
|
41 | validates_presence_of :default_status | |||
40 | validates_presence_of :name |
|
42 | validates_presence_of :name | |
41 | validates_uniqueness_of :name |
|
43 | validates_uniqueness_of :name | |
42 | validates_length_of :name, :maximum => 30 |
|
44 | validates_length_of :name, :maximum => 30 | |
@@ -53,14 +55,15 class Tracker < ActiveRecord::Base | |||||
53 | # Returns an array of IssueStatus that are used |
|
55 | # Returns an array of IssueStatus that are used | |
54 | # in the tracker's workflows |
|
56 | # in the tracker's workflows | |
55 | def issue_statuses |
|
57 | def issue_statuses | |
56 | if @issue_statuses |
|
58 | @issue_statuses ||= IssueStatus.where(:id => issue_status_ids).to_a.sort | |
57 | return @issue_statuses |
|
59 | end | |
58 | elsif new_record? |
|
|||
59 | return [] |
|
|||
60 | end |
|
|||
61 |
|
60 | |||
62 | status_ids = WorkflowTransition.where(:tracker_id => id).uniq.pluck(:old_status_id, :new_status_id).flatten.uniq |
|
61 | def issue_status_ids | |
63 | @issue_statuses = IssueStatus.where(:id => status_ids).to_a.sort |
|
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 | end |
|
67 | end | |
65 |
|
68 | |||
66 | def disabled_core_fields |
|
69 | def disabled_core_fields |
@@ -6,7 +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> |
|
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 | <% end %> |
|
7 | <% end %> | |
8 | <p><%= f.check_box :is_closed %></p> |
|
8 | <p><%= f.check_box :is_closed %></p> | |
9 | <p><%= f.check_box :is_default %></p> |
|
|||
10 |
|
9 | |||
11 | <%= call_hook(:view_issue_statuses_form, :issue_status => @issue_status) %> |
|
10 | <%= call_hook(:view_issue_statuses_form, :issue_status => @issue_status) %> | |
12 | </div> |
|
11 | </div> |
@@ -3,7 +3,6 api.array :issue_statuses do | |||||
3 | api.issue_status do |
|
3 | api.issue_status do | |
4 | api.id status.id |
|
4 | api.id status.id | |
5 | api.name status.name |
|
5 | api.name status.name | |
6 | api.is_default status.is_default |
|
|||
7 | api.is_closed status.is_closed |
|
6 | api.is_closed status.is_closed | |
8 | end |
|
7 | end | |
9 | end |
|
8 | end |
@@ -11,7 +11,6 | |||||
11 | <% if Issue.use_status_for_done_ratio? %> |
|
11 | <% if Issue.use_status_for_done_ratio? %> | |
12 | <th><%=l(:field_done_ratio)%></th> |
|
12 | <th><%=l(:field_done_ratio)%></th> | |
13 | <% end %> |
|
13 | <% end %> | |
14 | <th><%=l(:field_is_default)%></th> |
|
|||
15 | <th><%=l(:field_is_closed)%></th> |
|
14 | <th><%=l(:field_is_closed)%></th> | |
16 | <th><%=l(:button_sort)%></th> |
|
15 | <th><%=l(:button_sort)%></th> | |
17 | <th></th> |
|
16 | <th></th> | |
@@ -23,7 +22,6 | |||||
23 | <% if Issue.use_status_for_done_ratio? %> |
|
22 | <% if Issue.use_status_for_done_ratio? %> | |
24 | <td><%= h status.default_done_ratio %></td> |
|
23 | <td><%= h status.default_done_ratio %></td> | |
25 | <% end %> |
|
24 | <% end %> | |
26 | <td><%= checked_image status.is_default? %></td> |
|
|||
27 | <td><%= checked_image status.is_closed? %></td> |
|
25 | <td><%= checked_image status.is_closed? %></td> | |
28 | <td class="reorder"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td> |
|
26 | <td class="reorder"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td> | |
29 | <td class="buttons"> |
|
27 | <td class="buttons"> |
@@ -5,9 +5,9 | |||||
5 | <% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %> |
|
5 | <% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %> | |
6 | <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true}, |
|
6 | <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true}, | |
7 | :onchange => "updateIssueFrom('#{escape_javascript project_issue_form_path(@project, :id => @issue, :format => 'js')}')" %></p> |
|
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 | <% else %> |
|
9 | <% else %> | |
10 |
<p><label><%= l(:field_status) %></label> <%= |
|
10 | <p><label><%= l(:field_status) %></label> <%= @issue.status %></p> | |
11 | <% end %> |
|
11 | <% end %> | |
12 |
|
12 | |||
13 | <% if @issue.safe_attribute? 'priority_id' %> |
|
13 | <% if @issue.safe_attribute? 'priority_id' %> |
@@ -4,8 +4,12 | |||||
4 | <div class="box tabular"> |
|
4 | <div class="box tabular"> | |
5 | <!--[form:tracker]--> |
|
5 | <!--[form:tracker]--> | |
6 | <p><%= f.text_field :name, :required => true %></p> |
|
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 | <p><%= f.check_box :is_in_roadmap %></p> |
|
12 | <p><%= f.check_box :is_in_roadmap %></p> | |
8 |
|
||||
9 | <p> |
|
13 | <p> | |
10 | <label><%= l(:field_core_fields) %></label> |
|
14 | <label><%= l(:field_core_fields) %></label> | |
11 | <% Tracker::CORE_FIELDS.each do |field| %> |
|
15 | <% Tracker::CORE_FIELDS.each do |field| %> |
@@ -3,6 +3,7 api.array :trackers do | |||||
3 | api.tracker do |
|
3 | api.tracker do | |
4 | api.id tracker.id |
|
4 | api.id tracker.id | |
5 | api.name tracker.name |
|
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 | end |
|
7 | end | |
7 | end |
|
8 | end | |
8 | end |
|
9 | end |
@@ -337,6 +337,7 en: | |||||
337 | field_inherit_members: Inherit members |
|
337 | field_inherit_members: Inherit members | |
338 | field_generate_password: Generate password |
|
338 | field_generate_password: Generate password | |
339 | field_must_change_passwd: Must change password at next logon |
|
339 | field_must_change_passwd: Must change password at next logon | |
|
340 | field_default_status: Default status | |||
340 |
|
341 | |||
341 | setting_app_title: Application title |
|
342 | setting_app_title: Application title | |
342 | setting_app_subtitle: Application subtitle |
|
343 | setting_app_subtitle: Application subtitle |
@@ -357,6 +357,7 fr: | |||||
357 | field_inherit_members: Hériter les membres |
|
357 | field_inherit_members: Hériter les membres | |
358 | field_generate_password: Générer un mot de passe |
|
358 | field_generate_password: Générer un mot de passe | |
359 | field_must_change_passwd: Doit changer de mot de passe à la prochaine connexion |
|
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 | setting_app_title: Titre de l'application |
|
362 | setting_app_title: Titre de l'application | |
362 | setting_app_subtitle: Sous-titre de l'application |
|
363 | setting_app_subtitle: Sous-titre de l'application |
@@ -125,18 +125,18 module Redmine | |||||
125 | :browse_repository, |
|
125 | :browse_repository, | |
126 | :view_changesets] |
|
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 | # Issue statuses |
|
128 | # Issue statuses | |
134 |
new = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, |
|
129 | new = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, :position => 1) | |
135 |
in_progress = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, |
|
130 | in_progress = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, :position => 2) | |
136 |
resolved = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, |
|
131 | resolved = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, :position => 3) | |
137 |
feedback = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, |
|
132 | feedback = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, :position => 4) | |
138 |
closed = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, |
|
133 | closed = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, :position => 5) | |
139 |
rejected = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, |
|
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 | # Workflow |
|
141 | # Workflow | |
142 | Tracker.all.each { |t| |
|
142 | Tracker.all.each { |t| |
@@ -25,15 +25,15 task :migrate_from_mantis => :environment do | |||||
25 |
|
25 | |||
26 | module MantisMigrate |
|
26 | module MantisMigrate | |
27 |
|
27 | |||
28 | DEFAULT_STATUS = IssueStatus.default |
|
28 | new_status = IssueStatus.find_by_position(1) | |
29 | assigned_status = IssueStatus.find_by_position(2) |
|
29 | assigned_status = IssueStatus.find_by_position(2) | |
30 | resolved_status = IssueStatus.find_by_position(3) |
|
30 | resolved_status = IssueStatus.find_by_position(3) | |
31 | feedback_status = IssueStatus.find_by_position(4) |
|
31 | feedback_status = IssueStatus.find_by_position(4) | |
32 | closed_status = IssueStatus.where(:is_closed => true).first |
|
32 | closed_status = IssueStatus.where(:is_closed => true).first | |
33 |
STATUS_MAPPING = {10 => |
|
33 | STATUS_MAPPING = {10 => new_status, # new | |
34 | 20 => feedback_status, # feedback |
|
34 | 20 => feedback_status, # feedback | |
35 |
30 => |
|
35 | 30 => new_status, # acknowledged | |
36 |
40 => |
|
36 | 40 => new_status, # confirmed | |
37 | 50 => assigned_status, # assigned |
|
37 | 50 => assigned_status, # assigned | |
38 | 80 => resolved_status, # resolved |
|
38 | 80 => resolved_status, # resolved | |
39 | 90 => closed_status # closed |
|
39 | 90 => closed_status # closed | |
@@ -317,8 +317,8 task :migrate_from_mantis => :environment do | |||||
317 | i.author = User.find_by_id(users_map[bug.reporter_id]) |
|
317 | i.author = User.find_by_id(users_map[bug.reporter_id]) | |
318 | i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank? |
|
318 | i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank? | |
319 | i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank? |
|
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 | i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG) |
|
320 | i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG) | |
|
321 | i.status = STATUS_MAPPING[bug.status] || i.status | |||
322 | i.id = bug.id if keep_bug_ids |
|
322 | i.id = bug.id if keep_bug_ids | |
323 | next unless i.save |
|
323 | next unless i.save | |
324 | issues_map[bug.id] = i.id |
|
324 | issues_map[bug.id] = i.id |
@@ -25,12 +25,12 namespace :redmine do | |||||
25 | module TracMigrate |
|
25 | module TracMigrate | |
26 | TICKET_MAP = [] |
|
26 | TICKET_MAP = [] | |
27 |
|
27 | |||
28 | DEFAULT_STATUS = IssueStatus.default |
|
28 | new_status = IssueStatus.find_by_position(1) | |
29 | assigned_status = IssueStatus.find_by_position(2) |
|
29 | assigned_status = IssueStatus.find_by_position(2) | |
30 | resolved_status = IssueStatus.find_by_position(3) |
|
30 | resolved_status = IssueStatus.find_by_position(3) | |
31 | feedback_status = IssueStatus.find_by_position(4) |
|
31 | feedback_status = IssueStatus.find_by_position(4) | |
32 | closed_status = IssueStatus.where(:is_closed => true).first |
|
32 | closed_status = IssueStatus.where(:is_closed => true).first | |
33 |
STATUS_MAPPING = {'new' => |
|
33 | STATUS_MAPPING = {'new' => new_status, | |
34 | 'reopened' => feedback_status, |
|
34 | 'reopened' => feedback_status, | |
35 | 'assigned' => assigned_status, |
|
35 | 'assigned' => assigned_status, | |
36 | 'closed' => closed_status |
|
36 | 'closed' => closed_status | |
@@ -476,8 +476,8 namespace :redmine do | |||||
476 | i.author = find_or_create_user(ticket.reporter) |
|
476 | i.author = find_or_create_user(ticket.reporter) | |
477 | i.category = issues_category_map[ticket.component] unless ticket.component.blank? |
|
477 | i.category = issues_category_map[ticket.component] unless ticket.component.blank? | |
478 | i.fixed_version = version_map[ticket.milestone] unless ticket.milestone.blank? |
|
478 | i.fixed_version = version_map[ticket.milestone] unless ticket.milestone.blank? | |
479 | i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS |
|
|||
480 | i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER |
|
479 | i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER | |
|
480 | i.status = STATUS_MAPPING[ticket.status] || i.default_status | |||
481 | i.id = ticket.id unless Issue.exists?(ticket.id) |
|
481 | i.id = ticket.id unless Issue.exists?(ticket.id) | |
482 | next unless Time.fake(ticket.changetime) { i.save } |
|
482 | next unless Time.fake(ticket.changetime) { i.save } | |
483 | TICKET_MAP[ticket.id] = i.id |
|
483 | TICKET_MAP[ticket.id] = i.id |
@@ -2,36 +2,30 | |||||
2 | issue_statuses_001: |
|
2 | issue_statuses_001: | |
3 | id: 1 |
|
3 | id: 1 | |
4 | name: New |
|
4 | name: New | |
5 | is_default: true |
|
|||
6 | is_closed: false |
|
5 | is_closed: false | |
7 | position: 1 |
|
6 | position: 1 | |
8 | issue_statuses_002: |
|
7 | issue_statuses_002: | |
9 | id: 2 |
|
8 | id: 2 | |
10 | name: Assigned |
|
9 | name: Assigned | |
11 | is_default: false |
|
|||
12 | is_closed: false |
|
10 | is_closed: false | |
13 | position: 2 |
|
11 | position: 2 | |
14 | issue_statuses_003: |
|
12 | issue_statuses_003: | |
15 | id: 3 |
|
13 | id: 3 | |
16 | name: Resolved |
|
14 | name: Resolved | |
17 | is_default: false |
|
|||
18 | is_closed: false |
|
15 | is_closed: false | |
19 | position: 3 |
|
16 | position: 3 | |
20 | issue_statuses_004: |
|
17 | issue_statuses_004: | |
21 | name: Feedback |
|
18 | name: Feedback | |
22 | id: 4 |
|
19 | id: 4 | |
23 | is_default: false |
|
|||
24 | is_closed: false |
|
20 | is_closed: false | |
25 | position: 4 |
|
21 | position: 4 | |
26 | issue_statuses_005: |
|
22 | issue_statuses_005: | |
27 | id: 5 |
|
23 | id: 5 | |
28 | name: Closed |
|
24 | name: Closed | |
29 | is_default: false |
|
|||
30 | is_closed: true |
|
25 | is_closed: true | |
31 | position: 5 |
|
26 | position: 5 | |
32 | issue_statuses_006: |
|
27 | issue_statuses_006: | |
33 | id: 6 |
|
28 | id: 6 | |
34 | name: Rejected |
|
29 | name: Rejected | |
35 | is_default: false |
|
|||
36 | is_closed: true |
|
30 | is_closed: true | |
37 | position: 6 |
|
31 | position: 6 |
@@ -3,14 +3,17 trackers_001: | |||||
3 | name: Bug |
|
3 | name: Bug | |
4 | id: 1 |
|
4 | id: 1 | |
5 | is_in_chlog: true |
|
5 | is_in_chlog: true | |
|
6 | default_status_id: 1 | |||
6 | position: 1 |
|
7 | position: 1 | |
7 | trackers_002: |
|
8 | trackers_002: | |
8 | name: Feature request |
|
9 | name: Feature request | |
9 | id: 2 |
|
10 | id: 2 | |
10 | is_in_chlog: true |
|
11 | is_in_chlog: true | |
|
12 | default_status_id: 1 | |||
11 | position: 2 |
|
13 | position: 2 | |
12 | trackers_003: |
|
14 | trackers_003: | |
13 | name: Support request |
|
15 | name: Support request | |
14 | id: 3 |
|
16 | id: 3 | |
15 | is_in_chlog: false |
|
17 | is_in_chlog: false | |
|
18 | default_status_id: 1 | |||
16 | position: 3 |
|
19 | position: 3 |
@@ -86,7 +86,8 class IssueStatusesControllerTest < ActionController::TestCase | |||||
86 | end |
|
86 | end | |
87 |
|
87 | |||
88 | def test_destroy |
|
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 | assert_difference 'IssueStatus.count', -1 do |
|
92 | assert_difference 'IssueStatus.count', -1 do | |
92 | delete :destroy, :id => '1' |
|
93 | delete :destroy, :id => '1' | |
@@ -96,7 +97,19 class IssueStatusesControllerTest < ActionController::TestCase | |||||
96 | end |
|
97 | end | |
97 |
|
98 | |||
98 | def test_destroy_should_block_if_status_in_use |
|
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 | assert_no_difference 'IssueStatus.count' do |
|
114 | assert_no_difference 'IssueStatus.count' do | |
102 | delete :destroy, :id => '1' |
|
115 | delete :destroy, :id => '1' |
@@ -1511,6 +1511,30 class IssuesControllerTest < ActionController::TestCase | |||||
1511 | end |
|
1511 | end | |
1512 | end |
|
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 | def test_get_new_with_list_custom_field |
|
1538 | def test_get_new_with_list_custom_field | |
1515 | @request.session[:user_id] = 2 |
|
1539 | @request.session[:user_id] = 2 | |
1516 | get :new, :project_id => 1, :tracker_id => 1 |
|
1540 | get :new, :project_id => 1, :tracker_id => 1 | |
@@ -1731,6 +1755,20 class IssuesControllerTest < ActionController::TestCase | |||||
1731 | assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort |
|
1755 | assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort | |
1732 | end |
|
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 | def test_post_create |
|
1772 | def test_post_create | |
1735 | @request.session[:user_id] = 2 |
|
1773 | @request.session[:user_id] = 2 | |
1736 | assert_difference 'Issue.count' do |
|
1774 | assert_difference 'Issue.count' do | |
@@ -2266,13 +2304,17 class IssuesControllerTest < ActionController::TestCase | |||||
2266 | get :new, :project_id => 1 |
|
2304 | get :new, :project_id => 1 | |
2267 | assert_response :success |
|
2305 | assert_response :success | |
2268 | assert_template 'new' |
|
2306 | assert_template 'new' | |
|
2307 | ||||
|
2308 | issue = assigns(:issue) | |||
|
2309 | assert_not_nil issue.default_status | |||
|
2310 | ||||
2269 | assert_select 'select[name=?]', 'issue[status_id]' do |
|
2311 | assert_select 'select[name=?]', 'issue[status_id]' do | |
2270 | assert_select 'option', 1 |
|
2312 | assert_select 'option', 1 | |
2271 |
assert_select 'option[value=?]', |
|
2313 | assert_select 'option[value=?]', issue.default_status.id.to_s | |
2272 | end |
|
2314 | end | |
2273 | end |
|
2315 | end | |
2274 |
|
2316 | |||
2275 |
test "without workflow privilege # |
|
2317 | test "without workflow privilege #create should accept default status" do | |
2276 | setup_without_workflow_privilege |
|
2318 | setup_without_workflow_privilege | |
2277 | assert_difference 'Issue.count' do |
|
2319 | assert_difference 'Issue.count' do | |
2278 | post :create, :project_id => 1, |
|
2320 | post :create, :project_id => 1, | |
@@ -2281,10 +2323,11 class IssuesControllerTest < ActionController::TestCase | |||||
2281 | :status_id => 1} |
|
2323 | :status_id => 1} | |
2282 | end |
|
2324 | end | |
2283 | issue = Issue.order('id').last |
|
2325 | issue = Issue.order('id').last | |
2284 |
assert_ |
|
2326 | assert_not_nil issue.default_status | |
|
2327 | assert_equal issue.default_status, issue.status | |||
2285 | end |
|
2328 | end | |
2286 |
|
2329 | |||
2287 |
test "without workflow privilege # |
|
2330 | test "without workflow privilege #create should ignore unauthorized status" do | |
2288 | setup_without_workflow_privilege |
|
2331 | setup_without_workflow_privilege | |
2289 | assert_difference 'Issue.count' do |
|
2332 | assert_difference 'Issue.count' do | |
2290 | post :create, :project_id => 1, |
|
2333 | post :create, :project_id => 1, | |
@@ -2293,7 +2336,8 class IssuesControllerTest < ActionController::TestCase | |||||
2293 | :status_id => 3} |
|
2336 | :status_id => 3} | |
2294 | end |
|
2337 | end | |
2295 | issue = Issue.order('id').last |
|
2338 | issue = Issue.order('id').last | |
2296 |
assert_ |
|
2339 | assert_not_nil issue.default_status | |
|
2340 | assert_equal issue.default_status, issue.status | |||
2297 | end |
|
2341 | end | |
2298 |
|
2342 | |||
2299 | test "without workflow privilege #update should ignore status change" do |
|
2343 | test "without workflow privilege #update should ignore status change" do |
@@ -18,7 +18,7 | |||||
18 | require File.expand_path('../../test_helper', __FILE__) |
|
18 | require File.expand_path('../../test_helper', __FILE__) | |
19 |
|
19 | |||
20 | class TrackersControllerTest < ActionController::TestCase |
|
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 | def setup |
|
23 | def setup | |
24 | User.current = nil |
|
24 | User.current = nil | |
@@ -51,7 +51,7 class TrackersControllerTest < ActionController::TestCase | |||||
51 |
|
51 | |||
52 | def test_create |
|
52 | def test_create | |
53 | assert_difference 'Tracker.count' do |
|
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 | end |
|
55 | end | |
56 | assert_redirected_to :action => 'index' |
|
56 | assert_redirected_to :action => 'index' | |
57 | tracker = Tracker.order('id DESC').first |
|
57 | tracker = Tracker.order('id DESC').first | |
@@ -62,9 +62,9 class TrackersControllerTest < ActionController::TestCase | |||||
62 | assert_equal 0, tracker.workflow_rules.count |
|
62 | assert_equal 0, tracker.workflow_rules.count | |
63 | end |
|
63 | end | |
64 |
|
64 | |||
65 | def create_with_disabled_core_fields |
|
65 | def test_create_with_disabled_core_fields | |
66 | assert_difference 'Tracker.count' do |
|
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 | end |
|
68 | end | |
69 | assert_redirected_to :action => 'index' |
|
69 | assert_redirected_to :action => 'index' | |
70 | tracker = Tracker.order('id DESC').first |
|
70 | tracker = Tracker.order('id DESC').first | |
@@ -74,7 +74,7 class TrackersControllerTest < ActionController::TestCase | |||||
74 |
|
74 | |||
75 | def test_create_new_with_workflow_copy |
|
75 | def test_create_new_with_workflow_copy | |
76 | assert_difference 'Tracker.count' do |
|
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 | end |
|
78 | end | |
79 | assert_redirected_to :action => 'index' |
|
79 | assert_redirected_to :action => 'index' | |
80 | tracker = Tracker.find_by_name('New tracker') |
|
80 | tracker = Tracker.find_by_name('New tracker') | |
@@ -164,7 +164,7 class TrackersControllerTest < ActionController::TestCase | |||||
164 | end |
|
164 | end | |
165 |
|
165 | |||
166 | def test_destroy |
|
166 | def test_destroy | |
167 |
tracker = Tracker. |
|
167 | tracker = Tracker.generate!(:name => 'Destroyable') | |
168 | assert_difference 'Tracker.count', -1 do |
|
168 | assert_difference 'Tracker.count', -1 do | |
169 | delete :destroy, :id => tracker.id |
|
169 | delete :destroy, :id => tracker.id | |
170 | end |
|
170 | end |
@@ -45,11 +45,22 module ObjectHelpers | |||||
45 | project |
|
45 | project | |
46 | end |
|
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 | def Tracker.generate!(attributes={}) |
|
58 | def Tracker.generate!(attributes={}) | |
49 | @generated_tracker_name ||= 'Tracker 0' |
|
59 | @generated_tracker_name ||= 'Tracker 0' | |
50 | @generated_tracker_name.succ! |
|
60 | @generated_tracker_name.succ! | |
51 | tracker = Tracker.new(attributes) |
|
61 | tracker = Tracker.new(attributes) | |
52 | tracker.name = @generated_tracker_name.dup if tracker.name.blank? |
|
62 | tracker.name = @generated_tracker_name.dup if tracker.name.blank? | |
|
63 | tracker.default_status ||= IssueStatus.order('position').first || IssueStatus.generate! | |||
53 | yield tracker if block_given? |
|
64 | yield tracker if block_given? | |
54 | tracker.save! |
|
65 | tracker.save! | |
55 | tracker |
|
66 | tracker | |
@@ -188,6 +199,27 module ObjectHelpers | |||||
188 | end |
|
199 | end | |
189 | end |
|
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 | module IssueObjectHelpers |
|
223 | module IssueObjectHelpers | |
192 | def close! |
|
224 | def close! | |
193 | self.status = IssueStatus.where(:is_closed => true).first |
|
225 | self.status = IssueStatus.where(:is_closed => true).first | |
@@ -198,5 +230,4 module IssueObjectHelpers | |||||
198 | Issue.generate!(attributes.merge(:parent_issue_id => self.id)) |
|
230 | Issue.generate!(attributes.merge(:parent_issue_id => self.id)) | |
199 | end |
|
231 | end | |
200 | end |
|
232 | end | |
201 |
|
||||
202 | Issue.send :include, IssueObjectHelpers |
|
233 | Issue.send :include, IssueObjectHelpers |
@@ -28,7 +28,6 class IssueStatusTest < ActiveSupport::TestCase | |||||
28 |
|
28 | |||
29 | status.name = "Test Status" |
|
29 | status.name = "Test Status" | |
30 | assert status.save |
|
30 | assert status.save | |
31 | assert !status.is_default |
|
|||
32 | end |
|
31 | end | |
33 |
|
32 | |||
34 | def test_destroy |
|
33 | def test_destroy | |
@@ -46,29 +45,6 class IssueStatusTest < ActiveSupport::TestCase | |||||
46 | assert_raise(RuntimeError, "Can't delete status") { status.destroy } |
|
45 | assert_raise(RuntimeError, "Can't delete status") { status.destroy } | |
47 | end |
|
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 | def test_new_statuses_allowed_to |
|
48 | def test_new_statuses_allowed_to | |
73 | WorkflowTransition.delete_all |
|
49 | WorkflowTransition.delete_all | |
74 |
|
50 |
@@ -40,11 +40,11 class IssueTest < ActiveSupport::TestCase | |||||
40 |
|
40 | |||
41 | assert_nil issue.project_id |
|
41 | assert_nil issue.project_id | |
42 | assert_nil issue.tracker_id |
|
42 | assert_nil issue.tracker_id | |
|
43 | assert_nil issue.status_id | |||
43 | assert_nil issue.author_id |
|
44 | assert_nil issue.author_id | |
44 | assert_nil issue.assigned_to_id |
|
45 | assert_nil issue.assigned_to_id | |
45 | assert_nil issue.category_id |
|
46 | assert_nil issue.category_id | |
46 |
|
47 | |||
47 | assert_equal IssueStatus.default, issue.status |
|
|||
48 | assert_equal IssuePriority.default, issue.priority |
|
48 | assert_equal IssuePriority.default, issue.priority | |
49 | end |
|
49 | end | |
50 |
|
50 | |||
@@ -59,10 +59,9 class IssueTest < ActiveSupport::TestCase | |||||
59 | end |
|
59 | end | |
60 |
|
60 | |||
61 | def test_create_minimal |
|
61 | def test_create_minimal | |
62 | issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, |
|
62 | issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :subject => 'test_create') | |
63 | :status_id => 1, :priority => IssuePriority.all.first, |
|
|||
64 | :subject => 'test_create') |
|
|||
65 | assert issue.save |
|
63 | assert issue.save | |
|
64 | assert_equal issue.tracker.default_status, issue.status | |||
66 | assert issue.description.nil? |
|
65 | assert issue.description.nil? | |
67 | assert_nil issue.estimated_hours |
|
66 | assert_nil issue.estimated_hours | |
68 | end |
|
67 | end | |
@@ -908,7 +907,7 class IssueTest < ActiveSupport::TestCase | |||||
908 |
|
907 | |||
909 | def test_copy_should_copy_status |
|
908 | def test_copy_should_copy_status | |
910 | orig = Issue.find(8) |
|
909 | orig = Issue.find(8) | |
911 |
assert orig.status != |
|
910 | assert orig.status != orig.default_status | |
912 |
|
911 | |||
913 | issue = Issue.new.copy_from(orig) |
|
912 | issue = Issue.new.copy_from(orig) | |
914 | assert issue.save |
|
913 | assert issue.save | |
@@ -2480,4 +2479,67 class IssueTest < ActiveSupport::TestCase | |||||
2480 | issue.save! |
|
2479 | issue.save! | |
2481 | assert_equal false, issue.reopening? |
|
2480 | assert_equal false, issue.reopening? | |
2482 | end |
|
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 | end |
|
2545 | end |
@@ -412,7 +412,7 class MailHandlerTest < ActiveSupport::TestCase | |||||
412 |
|
412 | |||
413 | def test_add_issue_with_japanese_keywords |
|
413 | def test_add_issue_with_japanese_keywords | |
414 | ja_dev = "\xe9\x96\x8b\xe7\x99\xba".force_encoding('UTF-8') |
|
414 | ja_dev = "\xe9\x96\x8b\xe7\x99\xba".force_encoding('UTF-8') | |
415 |
tracker = Tracker. |
|
415 | tracker = Tracker.generate!(:name => ja_dev) | |
416 | Project.find(1).trackers << tracker |
|
416 | Project.find(1).trackers << tracker | |
417 | issue = submit_email( |
|
417 | issue = submit_email( | |
418 | 'japanese_keywords_iso_2022_jp.eml', |
|
418 | 'japanese_keywords_iso_2022_jp.eml', |
@@ -32,7 +32,7 class TrackerTest < ActiveSupport::TestCase | |||||
32 | source = Tracker.find(1) |
|
32 | source = Tracker.find(1) | |
33 | assert_equal 89, source.workflow_rules.size |
|
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 | assert target.save |
|
36 | assert target.save | |
37 | target.workflow_rules.copy(source) |
|
37 | target.workflow_rules.copy(source) | |
38 | target.reload |
|
38 | target.reload |
General Comments 0
You need to be logged in to leave comments.
Login now