You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

workflows_controller_test.rb 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. # Redmine - project management software
  2. # Copyright (C) 2006-2015 Jean-Philippe Lang
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. require File.expand_path('../../test_helper', __FILE__)
  18. class WorkflowsControllerTest < ActionController::TestCase
  19. fixtures :roles, :trackers, :workflows, :users, :issue_statuses
  20. def setup
  21. User.current = nil
  22. @request.session[:user_id] = 1 # admin
  23. end
  24. def test_index
  25. get :index
  26. assert_response :success
  27. assert_template 'index'
  28. count = WorkflowTransition.where(:role_id => 1, :tracker_id => 2).count
  29. assert_select 'a[href=?]', '/workflows/edit?role_id=1&tracker_id=2', :content => count.to_s
  30. end
  31. def test_get_edit
  32. get :edit
  33. assert_response :success
  34. assert_template 'edit'
  35. end
  36. def test_get_edit_with_role_and_tracker
  37. WorkflowTransition.delete_all
  38. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
  39. WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
  40. get :edit, :role_id => 2, :tracker_id => 1
  41. assert_response :success
  42. assert_template 'edit'
  43. # used status only
  44. assert_not_nil assigns(:statuses)
  45. assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
  46. # allowed transitions
  47. assert_select 'input[type=checkbox][name=?][value="1"][checked=checked]', 'transitions[3][5][always]'
  48. # not allowed
  49. assert_select 'input[type=checkbox][name=?][value="1"]:not([checked=checked])', 'transitions[3][2][always]'
  50. # unused
  51. assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]', 0
  52. end
  53. def test_get_edit_should_include_allowed_statuses_for_new_issues
  54. WorkflowTransition.delete_all
  55. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 1)
  56. get :edit, :role_id => 1, :tracker_id => 1
  57. assert_response :success
  58. assert_select 'td', 'New issue'
  59. assert_select 'input[type=checkbox][name=?][value="1"][checked=checked]', 'transitions[0][1][always]'
  60. end
  61. def test_get_edit_with_all_roles_and_all_trackers
  62. get :edit, :role_id => 'all', :tracker_id => 'all'
  63. assert_response :success
  64. assert_equal Role.sorted.to_a, assigns(:roles)
  65. assert_equal Tracker.sorted.to_a, assigns(:trackers)
  66. end
  67. def test_get_edit_with_role_and_tracker_and_all_statuses
  68. WorkflowTransition.delete_all
  69. get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
  70. assert_response :success
  71. assert_template 'edit'
  72. assert_not_nil assigns(:statuses)
  73. assert_equal IssueStatus.count, assigns(:statuses).size
  74. assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]'
  75. end
  76. def test_post_edit
  77. WorkflowTransition.delete_all
  78. post :edit, :role_id => 2, :tracker_id => 1,
  79. :transitions => {
  80. '4' => {'5' => {'always' => '1'}},
  81. '3' => {'1' => {'always' => '1'}, '2' => {'always' => '1'}}
  82. }
  83. assert_response 302
  84. assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
  85. assert_not_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
  86. assert_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
  87. end
  88. def test_post_edit_with_allowed_statuses_for_new_issues
  89. WorkflowTransition.delete_all
  90. post :edit, :role_id => 2, :tracker_id => 1,
  91. :transitions => {
  92. '0' => {'1' => {'always' => '1'}, '2' => {'always' => '1'}}
  93. }
  94. assert_response 302
  95. assert WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 0, :new_status_id => 1).any?
  96. assert WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2).any?
  97. assert_equal 2, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
  98. end
  99. def test_post_edit_with_additional_transitions
  100. WorkflowTransition.delete_all
  101. post :edit, :role_id => 2, :tracker_id => 1,
  102. :transitions => {
  103. '4' => {'5' => {'always' => '1', 'author' => '0', 'assignee' => '0'}},
  104. '3' => {'1' => {'always' => '0', 'author' => '1', 'assignee' => '0'},
  105. '2' => {'always' => '0', 'author' => '0', 'assignee' => '1'},
  106. '4' => {'always' => '0', 'author' => '1', 'assignee' => '1'}}
  107. }
  108. assert_response 302
  109. assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
  110. w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
  111. assert ! w.author
  112. assert ! w.assignee
  113. w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
  114. assert w.author
  115. assert ! w.assignee
  116. w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
  117. assert ! w.author
  118. assert w.assignee
  119. w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
  120. assert w.author
  121. assert w.assignee
  122. end
  123. def test_get_permissions
  124. get :permissions
  125. assert_response :success
  126. assert_template 'permissions'
  127. end
  128. def test_get_permissions_with_role_and_tracker
  129. WorkflowPermission.delete_all
  130. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
  131. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
  132. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
  133. get :permissions, :role_id => 1, :tracker_id => 2
  134. assert_response :success
  135. assert_template 'permissions'
  136. assert_select 'input[name=?][value="1"]', 'role_id[]'
  137. assert_select 'input[name=?][value="2"]', 'tracker_id[]'
  138. # Required field
  139. assert_select 'select[name=?]', 'permissions[2][assigned_to_id]' do
  140. assert_select 'option[value=""]'
  141. assert_select 'option[value=""][selected=selected]', 0
  142. assert_select 'option[value=readonly]', :text => 'Read-only'
  143. assert_select 'option[value=readonly][selected=selected]', 0
  144. assert_select 'option[value=required]', :text => 'Required'
  145. assert_select 'option[value=required][selected=selected]'
  146. end
  147. # Read-only field
  148. assert_select 'select[name=?]', 'permissions[3][fixed_version_id]' do
  149. assert_select 'option[value=""]'
  150. assert_select 'option[value=""][selected=selected]', 0
  151. assert_select 'option[value=readonly]', :text => 'Read-only'
  152. assert_select 'option[value=readonly][selected=selected]'
  153. assert_select 'option[value=required]', :text => 'Required'
  154. assert_select 'option[value=required][selected=selected]', 0
  155. end
  156. # Other field
  157. assert_select 'select[name=?]', 'permissions[3][due_date]' do
  158. assert_select 'option[value=""]'
  159. assert_select 'option[value=""][selected=selected]', 0
  160. assert_select 'option[value=readonly]', :text => 'Read-only'
  161. assert_select 'option[value=readonly][selected=selected]', 0
  162. assert_select 'option[value=required]', :text => 'Required'
  163. assert_select 'option[value=required][selected=selected]', 0
  164. end
  165. end
  166. def test_get_permissions_with_required_custom_field_should_not_show_required_option
  167. cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :tracker_ids => [1], :is_required => true)
  168. get :permissions, :role_id => 1, :tracker_id => 1
  169. assert_response :success
  170. assert_template 'permissions'
  171. # Custom field that is always required
  172. # The default option is "(Required)"
  173. assert_select 'select[name=?]', "permissions[3][#{cf.id}]" do
  174. assert_select 'option[value=""]'
  175. assert_select 'option[value=readonly]', :text => 'Read-only'
  176. assert_select 'option[value=required]', 0
  177. end
  178. end
  179. def test_get_permissions_should_disable_hidden_custom_fields
  180. cf1 = IssueCustomField.generate!(:tracker_ids => [1], :visible => true)
  181. cf2 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1])
  182. cf3 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1, 2])
  183. get :permissions, :role_id => 2, :tracker_id => 1
  184. assert_response :success
  185. assert_template 'permissions'
  186. assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf1.id}]"
  187. assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf3.id}]"
  188. assert_select 'select[name=?][disabled=disabled]', "permissions[1][#{cf2.id}]" do
  189. assert_select 'option[value=""][selected=selected]', :text => 'Hidden'
  190. end
  191. end
  192. def test_get_permissions_with_missing_permissions_for_roles_should_default_to_no_change
  193. WorkflowPermission.delete_all
  194. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
  195. get :permissions, :role_id => [1, 2], :tracker_id => 2
  196. assert_response :success
  197. assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
  198. assert_select 'option[selected]', 1
  199. assert_select 'option[selected][value=no_change]'
  200. end
  201. end
  202. def test_get_permissions_with_different_permissions_for_roles_should_default_to_no_change
  203. WorkflowPermission.delete_all
  204. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
  205. WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'readonly')
  206. get :permissions, :role_id => [1, 2], :tracker_id => 2
  207. assert_response :success
  208. assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
  209. assert_select 'option[selected]', 1
  210. assert_select 'option[selected][value=no_change]'
  211. end
  212. end
  213. def test_get_permissions_with_same_permissions_for_roles_should_default_to_permission
  214. WorkflowPermission.delete_all
  215. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
  216. WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
  217. get :permissions, :role_id => [1, 2], :tracker_id => 2
  218. assert_response :success
  219. assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
  220. assert_select 'option[selected]', 1
  221. assert_select 'option[selected][value=required]'
  222. end
  223. end
  224. def test_get_permissions_with_role_and_tracker_and_all_statuses_should_show_all_statuses
  225. WorkflowTransition.delete_all
  226. get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0'
  227. assert_response :success
  228. assert_equal IssueStatus.sorted.to_a, assigns(:statuses)
  229. end
  230. def test_get_permissions_should_set_css_class
  231. WorkflowPermission.delete_all
  232. WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
  233. get :permissions, :role_id => 1, :tracker_id => 2
  234. assert_response :success
  235. assert_select 'td.required > select[name=?]', 'permissions[1][assigned_to_id]'
  236. end
  237. def test_post_permissions
  238. WorkflowPermission.delete_all
  239. post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
  240. '1' => {'assigned_to_id' => '', 'fixed_version_id' => 'required', 'due_date' => ''},
  241. '2' => {'assigned_to_id' => 'readonly', 'fixed_version_id' => 'readonly', 'due_date' => ''},
  242. '3' => {'assigned_to_id' => '', 'fixed_version_id' => '', 'due_date' => ''}
  243. }
  244. assert_response 302
  245. workflows = WorkflowPermission.all
  246. assert_equal 3, workflows.size
  247. workflows.each do |workflow|
  248. assert_equal 1, workflow.role_id
  249. assert_equal 2, workflow.tracker_id
  250. end
  251. assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
  252. assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
  253. assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
  254. end
  255. def test_get_copy
  256. get :copy
  257. assert_response :success
  258. assert_template 'copy'
  259. assert_select 'select[name=source_tracker_id]' do
  260. assert_select 'option[value="1"]', :text => 'Bug'
  261. end
  262. assert_select 'select[name=source_role_id]' do
  263. assert_select 'option[value="2"]', :text => 'Developer'
  264. end
  265. assert_select 'select[name=?]', 'target_tracker_ids[]' do
  266. assert_select 'option[value="3"]', :text => 'Support request'
  267. end
  268. assert_select 'select[name=?]', 'target_role_ids[]' do
  269. assert_select 'option[value="1"]', :text => 'Manager'
  270. end
  271. end
  272. def test_post_copy_one_to_one
  273. source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
  274. post :copy, :source_tracker_id => '1', :source_role_id => '2',
  275. :target_tracker_ids => ['3'], :target_role_ids => ['1']
  276. assert_response 302
  277. assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
  278. end
  279. def test_post_copy_one_to_many
  280. source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
  281. post :copy, :source_tracker_id => '1', :source_role_id => '2',
  282. :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
  283. assert_response 302
  284. assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
  285. assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
  286. assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
  287. assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
  288. end
  289. def test_post_copy_many_to_many
  290. source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
  291. source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
  292. post :copy, :source_tracker_id => 'any', :source_role_id => '2',
  293. :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
  294. assert_response 302
  295. assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
  296. assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
  297. assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
  298. assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
  299. end
  300. def test_post_copy_with_incomplete_source_specification_should_fail
  301. assert_no_difference 'WorkflowRule.count' do
  302. post :copy,
  303. :source_tracker_id => '', :source_role_id => '2',
  304. :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
  305. assert_response 200
  306. assert_select 'div.flash.error', :text => 'Please select a source tracker or role'
  307. end
  308. end
  309. def test_post_copy_with_incomplete_target_specification_should_fail
  310. assert_no_difference 'WorkflowRule.count' do
  311. post :copy,
  312. :source_tracker_id => '1', :source_role_id => '2',
  313. :target_tracker_ids => ['2', '3']
  314. assert_response 200
  315. assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
  316. end
  317. end
  318. # Returns an array of status transitions that can be compared
  319. def status_transitions(conditions)
  320. WorkflowTransition.
  321. where(conditions).
  322. order('tracker_id, role_id, old_status_id, new_status_id').
  323. collect {|w| [w.old_status, w.new_status_id]}
  324. end
  325. end