@@ -0,0 +1,40 | |||
|
1 | <table class="list transitions-<%= name %>"> | |
|
2 | <thead> | |
|
3 | <tr> | |
|
4 | <th align="left"> | |
|
5 | <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input')", | |
|
6 | :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> | |
|
7 | <%=l(:label_current_status)%> | |
|
8 | </th> | |
|
9 | <th align="center" colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th> | |
|
10 | </tr> | |
|
11 | <tr> | |
|
12 | <td></td> | |
|
13 | <% for new_status in @statuses %> | |
|
14 | <td width="<%= 75 / @statuses.size %>%" align="center"> | |
|
15 | <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.new-status-#{new_status.id}')", | |
|
16 | :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> | |
|
17 | <%=h new_status.name %> | |
|
18 | </td> | |
|
19 | <% end %> | |
|
20 | </tr> | |
|
21 | </thead> | |
|
22 | <tbody> | |
|
23 | <% for old_status in @statuses %> | |
|
24 | <tr class="<%= cycle("odd", "even") %>"> | |
|
25 | <td> | |
|
26 | <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.old-status-#{old_status.id}')", | |
|
27 | :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> | |
|
28 | ||
|
29 | <%=h old_status.name %> | |
|
30 | </td> | |
|
31 | <% for new_status in @statuses -%> | |
|
32 | <td align="center"> | |
|
33 | <%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id}, | |
|
34 | :class => "old-status-#{old_status.id} new-status-#{new_status.id}" %> | |
|
35 | </td> | |
|
36 | <% end -%> | |
|
37 | </tr> | |
|
38 | <% end %> | |
|
39 | </tbody> | |
|
40 | </table> No newline at end of file |
@@ -0,0 +1,13 | |||
|
1 | class AddWorkflowsAssigneeAndAuthor < ActiveRecord::Migration | |
|
2 | def self.up | |
|
3 | add_column :workflows, :assignee, :boolean, :null => false, :default => false | |
|
4 | add_column :workflows, :author, :boolean, :null => false, :default => false | |
|
5 | Workflow.update_all("assignee = #{Workflow.connection.quoted_false}") | |
|
6 | Workflow.update_all("author = #{Workflow.connection.quoted_false}") | |
|
7 | end | |
|
8 | ||
|
9 | def self.down | |
|
10 | remove_column :workflows, :assignee | |
|
11 | remove_column :workflows, :author | |
|
12 | end | |
|
13 | end |
@@ -32,14 +32,17 class WorkflowsController < ApplicationController | |||
|
32 | 32 | |
|
33 | 33 | if request.post? |
|
34 | 34 | Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id]) |
|
35 |
(params[:issue_status] || []).each { | |
|
|
36 | news.each { |new| | |
|
37 | @role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new) | |
|
35 | (params[:issue_status] || []).each { |status_id, transitions| | |
|
36 | transitions.each { |new_status_id, options| | |
|
37 | author = options.is_a?(Array) && options.include?('author') && !options.include?('always') | |
|
38 | assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always') | |
|
39 | @role.workflows.build(:tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee) | |
|
38 | 40 | } |
|
39 | 41 | } |
|
40 | 42 | if @role.save |
|
41 | 43 | flash[:notice] = l(:notice_successful_update) |
|
42 | 44 | redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker |
|
45 | return | |
|
43 | 46 | end |
|
44 | 47 | end |
|
45 | 48 | |
@@ -48,6 +51,14 class WorkflowsController < ApplicationController | |||
|
48 | 51 | @statuses = @tracker.issue_statuses |
|
49 | 52 | end |
|
50 | 53 | @statuses ||= IssueStatus.find(:all, :order => 'position') |
|
54 | ||
|
55 | if @tracker && @role && @statuses.any? | |
|
56 | workflows = Workflow.all(:conditions => {:role_id => @role.id, :tracker_id => @tracker.id}) | |
|
57 | @workflows = {} | |
|
58 | @workflows['always'] = workflows.select {|w| !w.author && !w.assignee} | |
|
59 | @workflows['author'] = workflows.select {|w| w.author} | |
|
60 | @workflows['assignee'] = workflows.select {|w| w.assignee} | |
|
61 | end | |
|
51 | 62 | end |
|
52 | 63 | |
|
53 | 64 | def copy |
@@ -422,7 +422,12 class Issue < ActiveRecord::Base | |||
|
422 | 422 | |
|
423 | 423 | # Returns an array of status that user is able to apply |
|
424 | 424 | def new_statuses_allowed_to(user, include_default=false) |
|
425 |
statuses = status.find_new_statuses_allowed_to( |
|
|
425 | statuses = status.find_new_statuses_allowed_to( | |
|
426 | user.roles_for_project(project), | |
|
427 | tracker, | |
|
428 | author == user, | |
|
429 | assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id | |
|
430 | ) | |
|
426 | 431 | statuses << status unless statuses.empty? |
|
427 | 432 | statuses << IssueStatus.default if include_default |
|
428 | 433 | statuses = statuses.uniq.sort |
@@ -50,10 +50,16 class IssueStatus < ActiveRecord::Base | |||
|
50 | 50 | |
|
51 | 51 | # Returns an array of all statuses the given role can switch to |
|
52 | 52 | # Uses association cache when called more than one time |
|
53 | def new_statuses_allowed_to(roles, tracker) | |
|
53 | def new_statuses_allowed_to(roles, tracker, author=false, assignee=false) | |
|
54 | 54 | if roles && tracker |
|
55 | 55 | role_ids = roles.collect(&:id) |
|
56 | new_statuses = workflows.select {|w| role_ids.include?(w.role_id) && w.tracker_id == tracker.id}.collect{|w| w.new_status}.compact.sort | |
|
56 | transitions = workflows.select do |w| | |
|
57 | role_ids.include?(w.role_id) && | |
|
58 | w.tracker_id == tracker.id && | |
|
59 | (author || !w.author) && | |
|
60 | (assignee || !w.assignee) | |
|
61 | end | |
|
62 | transitions.collect{|w| w.new_status}.compact.sort | |
|
57 | 63 | else |
|
58 | 64 | [] |
|
59 | 65 | end |
@@ -61,24 +67,19 class IssueStatus < ActiveRecord::Base | |||
|
61 | 67 | |
|
62 | 68 | # Same thing as above but uses a database query |
|
63 | 69 | # More efficient than the previous method if called just once |
|
64 | def find_new_statuses_allowed_to(roles, tracker) | |
|
70 | def find_new_statuses_allowed_to(roles, tracker, author=false, assignee=false) | |
|
65 | 71 | if roles && tracker |
|
72 | conditions = {:role_id => roles.collect(&:id), :tracker_id => tracker.id} | |
|
73 | conditions[:author] = false unless author | |
|
74 | conditions[:assignee] = false unless assignee | |
|
75 | ||
|
66 | 76 | workflows.find(:all, |
|
67 | 77 | :include => :new_status, |
|
68 |
:conditions => |
|
|
69 | :tracker_id => tracker.id}).collect{ |w| w.new_status }.compact.sort | |
|
78 | :conditions => conditions).collect{|w| w.new_status}.compact.sort | |
|
70 | 79 | else |
|
71 | 80 | [] |
|
72 | 81 | end |
|
73 | 82 | end |
|
74 | ||
|
75 | def new_status_allowed_to?(status, roles, tracker) | |
|
76 | if status && roles && tracker | |
|
77 | !workflows.find(:first, :conditions => {:new_status_id => status.id, :role_id => roles.collect(&:id), :tracker_id => tracker.id}).nil? | |
|
78 | else | |
|
79 | false | |
|
80 | end | |
|
81 | end | |
|
82 | 83 | |
|
83 | 84 | def <=>(status) |
|
84 | 85 | position <=> status.position |
@@ -20,54 +20,31 | |||
|
20 | 20 | </p> |
|
21 | 21 | <% end %> |
|
22 | 22 | |
|
23 | ||
|
24 | 23 | <% if @tracker && @role && @statuses.any? %> |
|
25 | <% form_tag({}, :id => 'workflow_form' ) do %> | |
|
26 | <%= hidden_field_tag 'tracker_id', @tracker.id %> | |
|
27 | <%= hidden_field_tag 'role_id', @role.id %> | |
|
28 | <div class="autoscroll"> | |
|
29 | <table class="list"> | |
|
30 | <thead> | |
|
31 | <tr> | |
|
32 | <th align="left"><%=l(:label_current_status)%></th> | |
|
33 | <th align="center" colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th> | |
|
34 | </tr> | |
|
35 | <tr> | |
|
36 | <td></td> | |
|
37 | <% for new_status in @statuses %> | |
|
38 | <td width="<%= 75 / @statuses.size %>%" align="center"> | |
|
39 | <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.new-status-#{new_status.id}')", | |
|
40 | :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> | |
|
41 | <%= new_status.name %> | |
|
42 | </td> | |
|
43 | <% end %> | |
|
44 | </tr> | |
|
45 | </thead> | |
|
46 | <tbody> | |
|
47 | <% for old_status in @statuses %> | |
|
48 | <tr class="<%= cycle("odd", "even") %>"> | |
|
49 | <td> | |
|
50 | <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.old-status-#{old_status.id}')", | |
|
51 | :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> | |
|
52 | ||
|
53 | <%= old_status.name %> | |
|
54 | </td> | |
|
55 | <% new_status_ids_allowed = old_status.find_new_statuses_allowed_to([@role], @tracker).collect(&:id) -%> | |
|
56 | <% for new_status in @statuses -%> | |
|
57 | <td align="center"> | |
|
58 | <%= check_box_tag "issue_status[#{ old_status.id }][]", new_status.id, new_status_ids_allowed.include?(new_status.id), | |
|
59 | :class => "old-status-#{old_status.id} new-status-#{new_status.id}" %> | |
|
60 | </td> | |
|
61 | <% end -%> | |
|
62 | </tr> | |
|
63 | <% end %> | |
|
64 | </tbody> | |
|
65 | </table> | |
|
66 | </div> | |
|
67 | <p><%= check_all_links 'workflow_form' %></p> | |
|
68 | ||
|
69 | <%= submit_tag l(:button_save) %> | |
|
70 | <% end %> | |
|
24 | <% form_tag({}, :id => 'workflow_form' ) do %> | |
|
25 | <%= hidden_field_tag 'tracker_id', @tracker.id %> | |
|
26 | <%= hidden_field_tag 'role_id', @role.id %> | |
|
27 | <div class="autoscroll"> | |
|
28 | <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %> | |
|
29 | ||
|
30 | <fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;"> | |
|
31 | <legend onclick="toggleFieldset(this);">Autorisations supplémentaires lorsque l'utilisateur a créé la demande</legend> | |
|
32 | <div id="author_workflows" style="margin: 0.5em 0 0.5em 0;"> | |
|
33 | <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %> | |
|
34 | </div> | |
|
35 | </fieldset> | |
|
36 | <%= javascript_tag "hideFieldset($('author_workflows'))" unless @workflows['author'].present? %> | |
|
37 | ||
|
38 | <fieldset class="collapsible" style="padding: 0;"> | |
|
39 | <legend onclick="toggleFieldset(this);">Autorisations supplémentaires lorsque la demande est assignée à l'utilisateur</legend> | |
|
40 | <div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;"> | |
|
41 | <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %> | |
|
42 | </div> | |
|
43 | </fieldset> | |
|
44 | <%= javascript_tag "hideFieldset($('assignee_workflows'))" unless @workflows['assignee'].present? %> | |
|
45 | </div> | |
|
46 | <%= submit_tag l(:button_save) %> | |
|
47 | <% end %> | |
|
71 | 48 | <% end %> |
|
72 | 49 | |
|
73 | 50 | <% html_title(l(:label_workflow)) -%> |
@@ -46,6 +46,12 function toggleFieldset(el) { | |||
|
46 | 46 | Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2}); |
|
47 | 47 | } |
|
48 | 48 | |
|
49 | function hideFieldset(el) { | |
|
50 | var fieldset = Element.up(el, 'fieldset'); | |
|
51 | fieldset.toggleClassName('collapsed'); | |
|
52 | fieldset.down('div').hide(); | |
|
53 | } | |
|
54 | ||
|
49 | 55 | var fileFieldCount = 1; |
|
50 | 56 | |
|
51 | 57 | function addFileField() { |
@@ -1,31 +1,37 | |||
|
1 | 1 | --- |
|
2 | issue_statuses_006: | |
|
3 | name: Rejected | |
|
4 | is_default: false | |
|
5 | is_closed: true | |
|
6 | id: 6 | |
|
7 | 2 | issue_statuses_001: |
|
3 | id: 1 | |
|
8 | 4 | name: New |
|
9 | 5 | is_default: true |
|
10 | 6 | is_closed: false |
|
11 |
|
|
|
7 | position: 1 | |
|
12 | 8 | issue_statuses_002: |
|
9 | id: 2 | |
|
13 | 10 | name: Assigned |
|
14 | 11 | is_default: false |
|
15 | 12 | is_closed: false |
|
16 |
|
|
|
13 | position: 2 | |
|
17 | 14 | issue_statuses_003: |
|
15 | id: 3 | |
|
18 | 16 | name: Resolved |
|
19 | 17 | is_default: false |
|
20 | 18 | is_closed: false |
|
21 |
|
|
|
19 | position: 3 | |
|
22 | 20 | issue_statuses_004: |
|
23 | 21 | name: Feedback |
|
22 | id: 4 | |
|
24 | 23 | is_default: false |
|
25 | 24 | is_closed: false |
|
26 |
|
|
|
25 | position: 4 | |
|
27 | 26 | issue_statuses_005: |
|
27 | id: 5 | |
|
28 | 28 | name: Closed |
|
29 | 29 | is_default: false |
|
30 | 30 | is_closed: true |
|
31 |
|
|
|
31 | position: 5 | |
|
32 | issue_statuses_006: | |
|
33 | id: 6 | |
|
34 | name: Rejected | |
|
35 | is_default: false | |
|
36 | is_closed: true | |
|
37 | position: 6 |
@@ -65,17 +65,17 class WorkflowsControllerTest < ActionController::TestCase | |||
|
65 | 65 | |
|
66 | 66 | # allowed transitions |
|
67 | 67 | assert_tag :tag => 'input', :attributes => { :type => 'checkbox', |
|
68 | :name => 'issue_status[3][]', | |
|
69 |
:value => ' |
|
|
68 | :name => 'issue_status[3][5][]', | |
|
69 | :value => 'always', | |
|
70 | 70 | :checked => 'checked' } |
|
71 | 71 | # not allowed |
|
72 | 72 | assert_tag :tag => 'input', :attributes => { :type => 'checkbox', |
|
73 | :name => 'issue_status[3][]', | |
|
74 |
:value => ' |
|
|
73 | :name => 'issue_status[3][2][]', | |
|
74 | :value => 'always', | |
|
75 | 75 | :checked => nil } |
|
76 | 76 | # unused |
|
77 | 77 | assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox', |
|
78 |
:name => 'issue_status[ |
|
|
78 | :name => 'issue_status[1][1][]' } | |
|
79 | 79 | end |
|
80 | 80 | |
|
81 | 81 | def test_get_edit_with_role_and_tracker_and_all_statuses |
@@ -89,13 +89,17 class WorkflowsControllerTest < ActionController::TestCase | |||
|
89 | 89 | assert_equal IssueStatus.count, assigns(:statuses).size |
|
90 | 90 | |
|
91 | 91 | assert_tag :tag => 'input', :attributes => { :type => 'checkbox', |
|
92 | :name => 'issue_status[1][]', | |
|
93 |
:value => ' |
|
|
92 | :name => 'issue_status[1][1][]', | |
|
93 | :value => 'always', | |
|
94 | 94 | :checked => nil } |
|
95 | 95 | end |
|
96 | 96 | |
|
97 | 97 | def test_post_edit |
|
98 |
post :edit, :role_id => 2, :tracker_id => 1, |
|
|
98 | post :edit, :role_id => 2, :tracker_id => 1, | |
|
99 | :issue_status => { | |
|
100 | '4' => {'5' => ['always']}, | |
|
101 | '3' => {'1' => ['always'], '2' => ['always']} | |
|
102 | } | |
|
99 | 103 | assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1' |
|
100 | 104 | |
|
101 | 105 | assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) |
@@ -103,6 +107,30 class WorkflowsControllerTest < ActionController::TestCase | |||
|
103 | 107 | assert_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4}) |
|
104 | 108 | end |
|
105 | 109 | |
|
110 | def test_post_edit_with_additional_transitions | |
|
111 | post :edit, :role_id => 2, :tracker_id => 1, | |
|
112 | :issue_status => { | |
|
113 | '4' => {'5' => ['always']}, | |
|
114 | '3' => {'1' => ['author'], '2' => ['assignee'], '4' => ['author', 'assignee']} | |
|
115 | } | |
|
116 | assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1' | |
|
117 | ||
|
118 | assert_equal 4, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) | |
|
119 | ||
|
120 | w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5}) | |
|
121 | assert ! w.author | |
|
122 | assert ! w.assignee | |
|
123 | w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1}) | |
|
124 | assert w.author | |
|
125 | assert ! w.assignee | |
|
126 | w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2}) | |
|
127 | assert ! w.author | |
|
128 | assert w.assignee | |
|
129 | w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4}) | |
|
130 | assert w.author | |
|
131 | assert w.assignee | |
|
132 | end | |
|
133 | ||
|
106 | 134 | def test_clear_workflow |
|
107 | 135 | assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0 |
|
108 | 136 |
@@ -18,7 +18,7 | |||
|
18 | 18 | require File.expand_path('../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class IssueStatusTest < ActiveSupport::TestCase |
|
21 | fixtures :issue_statuses, :issues | |
|
21 | fixtures :issue_statuses, :issues, :roles, :trackers | |
|
22 | 22 | |
|
23 | 23 | def test_create |
|
24 | 24 | status = IssueStatus.new :name => "Assigned" |
@@ -68,6 +68,30 class IssueStatusTest < ActiveSupport::TestCase | |||
|
68 | 68 | status.reload |
|
69 | 69 | assert status.is_default? |
|
70 | 70 | end |
|
71 | ||
|
72 | def test_new_statuses_allowed_to | |
|
73 | Workflow.delete_all | |
|
74 | ||
|
75 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false) | |
|
76 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false) | |
|
77 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true) | |
|
78 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true) | |
|
79 | status = IssueStatus.find(1) | |
|
80 | role = Role.find(1) | |
|
81 | tracker = Tracker.find(1) | |
|
82 | ||
|
83 | assert_equal [2], status.new_statuses_allowed_to([role], tracker, false, false).map(&:id) | |
|
84 | assert_equal [2], status.find_new_statuses_allowed_to([role], tracker, false, false).map(&:id) | |
|
85 | ||
|
86 | assert_equal [2, 3], status.new_statuses_allowed_to([role], tracker, true, false).map(&:id) | |
|
87 | assert_equal [2, 3], status.find_new_statuses_allowed_to([role], tracker, true, false).map(&:id) | |
|
88 | ||
|
89 | assert_equal [2, 4], status.new_statuses_allowed_to([role], tracker, false, true).map(&:id) | |
|
90 | assert_equal [2, 4], status.find_new_statuses_allowed_to([role], tracker, false, true).map(&:id) | |
|
91 | ||
|
92 | assert_equal [2, 3, 4, 5], status.new_statuses_allowed_to([role], tracker, true, true).map(&:id) | |
|
93 | assert_equal [2, 3, 4, 5], status.find_new_statuses_allowed_to([role], tracker, true, true).map(&:id) | |
|
94 | end | |
|
71 | 95 | |
|
72 | 96 | context "#update_done_ratios" do |
|
73 | 97 | setup do |
@@ -210,6 +210,33 class IssueTest < ActiveSupport::TestCase | |||
|
210 | 210 | assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to |
|
211 | 211 | end |
|
212 | 212 | |
|
213 | ||
|
214 | ||
|
215 | def test_new_statuses_allowed_to | |
|
216 | Workflow.delete_all | |
|
217 | ||
|
218 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false) | |
|
219 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false) | |
|
220 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true) | |
|
221 | Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true) | |
|
222 | status = IssueStatus.find(1) | |
|
223 | role = Role.find(1) | |
|
224 | tracker = Tracker.find(1) | |
|
225 | user = User.find(2) | |
|
226 | ||
|
227 | issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1) | |
|
228 | assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id) | |
|
229 | ||
|
230 | issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user) | |
|
231 | assert_equal [1, 2, 3], issue.new_statuses_allowed_to(user).map(&:id) | |
|
232 | ||
|
233 | issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :assigned_to => user) | |
|
234 | assert_equal [1, 2, 4], issue.new_statuses_allowed_to(user).map(&:id) | |
|
235 | ||
|
236 | issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user) | |
|
237 | assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id) | |
|
238 | end | |
|
239 | ||
|
213 | 240 | def test_copy |
|
214 | 241 | issue = Issue.new.copy_from(1) |
|
215 | 242 | assert issue.save |
General Comments 0
You need to be logged in to leave comments.
Login now