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.

issues_controller_transaction_test.rb 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2022 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require File.expand_path('../../test_helper', __FILE__)
  19. require 'issues_controller'
  20. class IssuesControllerTransactionTest < Redmine::ControllerTest
  21. tests IssuesController
  22. fixtures :projects,
  23. :users,
  24. :roles,
  25. :members,
  26. :member_roles,
  27. :issues,
  28. :issue_statuses,
  29. :versions,
  30. :trackers,
  31. :projects_trackers,
  32. :issue_categories,
  33. :enabled_modules,
  34. :enumerations,
  35. :attachments,
  36. :workflows,
  37. :custom_fields,
  38. :custom_values,
  39. :custom_fields_projects,
  40. :custom_fields_trackers,
  41. :time_entries,
  42. :journals,
  43. :journal_details,
  44. :queries
  45. self.use_transactional_tests = false
  46. def setup
  47. User.current = nil
  48. end
  49. def test_update_stale_issue_should_not_update_the_issue
  50. issue = Issue.find(2)
  51. @request.session[:user_id] = 2
  52. assert_no_difference 'Journal.count' do
  53. assert_no_difference 'TimeEntry.count' do
  54. put(
  55. :update,
  56. :params => {
  57. :id => issue.id,
  58. :issue => {
  59. :fixed_version_id => 4,
  60. :notes => 'My notes',
  61. :lock_version => (issue.lock_version - 1)
  62. },
  63. :time_entry => {
  64. :hours => '2.5',
  65. :comments => '',
  66. :activity_id => TimeEntryActivity.first.id
  67. }
  68. }
  69. )
  70. end
  71. end
  72. assert_response :success
  73. assert_select 'div.conflict'
  74. assert_select 'input[name=?][value=?]', 'conflict_resolution', 'overwrite'
  75. assert_select 'input[name=?][value=?]', 'conflict_resolution', 'add_notes'
  76. assert_select 'label' do
  77. assert_select 'input[name=?][value=?]', 'conflict_resolution', 'cancel'
  78. assert_select 'a[href="/issues/2"]'
  79. end
  80. end
  81. def test_update_stale_issue_should_save_attachments
  82. set_tmp_attachments_directory
  83. issue = Issue.find(2)
  84. @request.session[:user_id] = 2
  85. assert_no_difference 'Journal.count' do
  86. assert_no_difference 'TimeEntry.count' do
  87. assert_difference 'Attachment.count' do
  88. put(
  89. :update,
  90. :params => {
  91. :id => issue.id,
  92. :issue => {
  93. :fixed_version_id => 4,
  94. :notes => 'My notes',
  95. :lock_version => (issue.lock_version - 1)
  96. },
  97. :attachments => {
  98. '1' => {
  99. 'file' => uploaded_test_file('testfile.txt', 'text/plain')
  100. }
  101. },
  102. :time_entry => {
  103. :hours => '2.5',
  104. :comments => '',
  105. :activity_id => TimeEntryActivity.first.id
  106. }
  107. }
  108. )
  109. end
  110. end
  111. end
  112. assert_response :success
  113. attachment = Attachment.order('id DESC').first
  114. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  115. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  116. end
  117. def test_update_stale_issue_without_notes_should_not_show_add_notes_option
  118. issue = Issue.find(2)
  119. @request.session[:user_id] = 2
  120. put(
  121. :update,
  122. :params => {
  123. :id => issue.id,
  124. :issue => {
  125. :fixed_version_id => 4,
  126. :notes => '',
  127. :lock_version => (issue.lock_version - 1)
  128. }
  129. }
  130. )
  131. assert_response :success
  132. assert_select 'div.conflict'
  133. assert_select 'input[name=conflict_resolution][value=overwrite]'
  134. assert_select 'input[name=conflict_resolution][value=add_notes]', 0
  135. assert_select 'input[name=conflict_resolution][value=cancel]'
  136. end
  137. def test_update_stale_issue_should_show_conflicting_journals
  138. @request.session[:user_id] = 2
  139. put(
  140. :update,
  141. :params => {
  142. :id => 1,
  143. :issue => {
  144. :fixed_version_id => 4,
  145. :notes => '',
  146. :lock_version => 2
  147. },
  148. :last_journal_id => 1
  149. }
  150. )
  151. assert_response :success
  152. assert_select '.conflict-journal', 1
  153. assert_select 'div.conflict', :text => /Some notes with Redmine links/
  154. end
  155. def test_update_stale_issue_without_previous_journal_should_show_all_journals
  156. @request.session[:user_id] = 2
  157. put(
  158. :update,
  159. :params => {
  160. :id => 1,
  161. :issue => {
  162. :fixed_version_id => 4,
  163. :notes => '',
  164. :lock_version => 2
  165. },
  166. :last_journal_id => ''
  167. }
  168. )
  169. assert_response :success
  170. assert_select '.conflict-journal', 2
  171. assert_select 'div.conflict', :text => /Some notes with Redmine links/
  172. assert_select 'div.conflict', :text => /Journal notes/
  173. end
  174. def test_update_stale_issue_should_show_private_journals_with_permission_only
  175. journal = Journal.create!(:journalized => Issue.find(1), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
  176. @request.session[:user_id] = 2
  177. put(
  178. :update,
  179. :params => {
  180. :id => 1,
  181. :issue => {
  182. :fixed_version_id => 4,
  183. :lock_version => 2
  184. },
  185. :last_journal_id => ''
  186. }
  187. )
  188. assert_response :success
  189. assert_select '.conflict-journal', :text => /Privates notes/
  190. Role.find(1).remove_permission! :view_private_notes
  191. put(
  192. :update,
  193. :params => {
  194. :id => 1,
  195. :issue => {
  196. :fixed_version_id => 4,
  197. :lock_version => 2
  198. },
  199. :last_journal_id => ''
  200. }
  201. )
  202. assert_response :success
  203. assert_select '.conflict-journal', :text => /Privates notes/, :count => 0
  204. end
  205. def test_update_stale_issue_with_overwrite_conflict_resolution_should_update
  206. @request.session[:user_id] = 2
  207. assert_difference 'Journal.count' do
  208. put(
  209. :update,
  210. :params => {
  211. :id => 1,
  212. :issue => {
  213. :fixed_version_id => 4,
  214. :notes => 'overwrite_conflict_resolution',
  215. :lock_version => 2
  216. },
  217. :conflict_resolution => 'overwrite'
  218. }
  219. )
  220. end
  221. assert_response 302
  222. issue = Issue.find(1)
  223. assert_equal 4, issue.fixed_version_id
  224. journal = Journal.order('id DESC').first
  225. assert_equal 'overwrite_conflict_resolution', journal.notes
  226. assert journal.details.any?
  227. end
  228. def test_update_stale_issue_with_add_notes_conflict_resolution_should_update
  229. @request.session[:user_id] = 2
  230. assert_difference 'Journal.count' do
  231. put(
  232. :update,
  233. :params => {
  234. :id => 1,
  235. :issue => {
  236. :fixed_version_id => 4,
  237. :notes => 'add_notes_conflict_resolution',
  238. :lock_version => 2
  239. },
  240. :conflict_resolution => 'add_notes'
  241. }
  242. )
  243. end
  244. assert_response 302
  245. issue = Issue.find(1)
  246. assert_nil issue.fixed_version_id
  247. journal = Journal.order('id DESC').first
  248. assert_equal 'add_notes_conflict_resolution', journal.notes
  249. assert_equal false, journal.private_notes
  250. assert journal.details.empty?
  251. end
  252. def test_update_stale_issue_with_add_notes_conflict_resolution_should_preserve_private_notes
  253. @request.session[:user_id] = 2
  254. journal = new_record(Journal) do
  255. put(
  256. :update,
  257. :params => {
  258. :id => 1,
  259. :issue => {
  260. :fixed_version_id => 4,
  261. :notes => 'add_privates_notes_conflict_resolution',
  262. :private_notes => '1',
  263. :lock_version => 2
  264. },
  265. :conflict_resolution => 'add_notes'
  266. }
  267. )
  268. end
  269. assert_response 302
  270. assert_equal 'add_privates_notes_conflict_resolution', journal.notes
  271. assert_equal true, journal.private_notes
  272. assert journal.details.empty?
  273. end
  274. def test_update_stale_issue_with_cancel_conflict_resolution_should_redirect_without_updating
  275. @request.session[:user_id] = 2
  276. assert_no_difference 'Journal.count' do
  277. put(
  278. :update,
  279. :params => {
  280. :id => 1,
  281. :issue => {
  282. :fixed_version_id => 4,
  283. :notes => 'add_notes_conflict_resolution',
  284. :lock_version => 2
  285. },
  286. :conflict_resolution => 'cancel'
  287. }
  288. )
  289. end
  290. assert_redirected_to '/issues/1'
  291. issue = Issue.find(1)
  292. assert_nil issue.fixed_version_id
  293. end
  294. def test_put_update_with_spent_time_and_failure_should_not_add_spent_time
  295. @request.session[:user_id] = 2
  296. assert_no_difference('TimeEntry.count') do
  297. put(
  298. :update,
  299. :params => {
  300. :id => 1,
  301. :issue => {
  302. :subject => ''
  303. },
  304. :time_entry => {
  305. :hours => '2:30',
  306. :comments => 'should not be added',
  307. :activity_id => TimeEntryActivity.first.id
  308. }
  309. }
  310. )
  311. assert_response :success
  312. end
  313. assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2:30'
  314. assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'should not be added'
  315. assert_select 'select[name=?]', 'time_entry[activity_id]' do
  316. assert_select 'option[value=?][selected=selected]', TimeEntryActivity.first.id.to_s
  317. end
  318. end
  319. def test_index_should_rescue_invalid_sql_query
  320. IssueQuery.any_instance.stubs(:statement).returns("INVALID STATEMENT")
  321. get :index
  322. assert_response 500
  323. assert_select 'p', :text => /An error occurred/
  324. assert_nil session[:query]
  325. assert_nil session[:issues_index_sort]
  326. end
  327. end