checklist_spec.rb 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Ticket zoom > Checklist', authenticated_as: :authenticate, type: :system do
  4. let(:other_agent) { create(:agent, groups: Group.all) }
  5. let(:ticket) { create(:ticket, group: Group.first) }
  6. def authenticate
  7. Setting.set('checklist', true)
  8. true
  9. end
  10. def perform_item_action(id, action)
  11. page.find(".checklistShow tr[data-id='#{id}'] .js-action", wait: 0).click
  12. page.find(".checklistShow tr[data-id='#{id}'] li[data-table-action='#{action}']", wait: 0).click
  13. rescue => e
  14. retry_click ||= 5
  15. retry_click -= 1
  16. sleep 1
  17. raise e if retry_click < 1
  18. retry
  19. end
  20. def perform_checklist_action(text)
  21. click '.sidebar[data-tab=checklist] .js-actions'
  22. click_on text
  23. rescue => e
  24. retry_click ||= 5
  25. retry_click -= 1
  26. sleep 1
  27. raise e if retry_click < 1
  28. retry
  29. end
  30. before do
  31. visit "#ticket/zoom/#{ticket.id}"
  32. end
  33. it 'does show the sidebar for the checklists' do
  34. expect(page).to have_css('.tabsSidebar-tab[data-tab=checklist]')
  35. Setting.set('checklist', false)
  36. expect(page).to have_no_css('.tabsSidebar-tab[data-tab=checklist]')
  37. end
  38. it 'does create a checklist' do
  39. click '.tabsSidebar-tab[data-tab=checklist]'
  40. expect(page).to have_button('Add empty checklist')
  41. click_on('Add empty checklist')
  42. expect(page).to have_no_button('Add empty checklist')
  43. wait.until { Checklist.where(ticket: ticket).present? }
  44. end
  45. context 'when checklist exists' do
  46. let(:checklist) { create(:checklist, ticket: ticket) }
  47. let(:item) { checklist.items.last }
  48. before do
  49. checklist
  50. click '.tabsSidebar-tab[data-tab=checklist]'
  51. wait.until { page.text.include?(checklist.name) }
  52. await_empty_ajax_queue
  53. end
  54. it 'does show handle subscriptions' do
  55. item.update(text: SecureRandom.uuid)
  56. expect(page).to have_text(item.text)
  57. item.destroy
  58. expect(page).to have_no_text(item.text)
  59. checklist.destroy
  60. expect(page).to have_button('Add empty checklist')
  61. end
  62. it 'does remove the checklist' do
  63. perform_checklist_action('Remove checklist')
  64. click_on 'delete'
  65. expect(page).to have_text('Add empty checklist')
  66. end
  67. it 'does rename the checklist' do
  68. perform_checklist_action('Rename checklist')
  69. checklist_name = SecureRandom.uuid
  70. find('#checklistTitleEditText').fill_in with: checklist_name, fill_options: { clear: :backspace }
  71. page.find('.js-confirm').click
  72. wait.until { checklist.reload.name == checklist_name }
  73. end
  74. it 'does add item' do
  75. find('.checklistShowButtons .js-add').click
  76. wait.until { checklist.items.last.text == '' }
  77. end
  78. it 'does check item' do
  79. perform_item_action(item.id, 'check')
  80. wait.until { item.reload.checked == true }
  81. end
  82. it 'does uncheck item' do
  83. item.update(checked: true)
  84. perform_item_action(item.id, 'uncheck')
  85. wait.until { item.reload.checked == false }
  86. end
  87. it 'does edit item' do
  88. perform_item_action(item.id, 'edit')
  89. item_text = SecureRandom.uuid
  90. find(".checklistShow tr[data-id='#{item.id}'] .js-input").fill_in with: item_text, fill_options: { clear: :backspace }
  91. page.find('.js-confirm').click
  92. wait.until { item.reload.text == item_text }
  93. end
  94. it 'does not abort edit when subscription is updating but including it afterwards' do
  95. perform_item_action(item.id, 'edit')
  96. item_text = SecureRandom.uuid
  97. find(".checklistShow tr[data-id='#{item.id}'] .js-input").fill_in with: item_text, fill_options: { clear: :backspace }
  98. # simulate other users change
  99. other_item_text = SecureRandom.uuid
  100. checklist.items.create!(text: other_item_text, created_by: other_agent, updated_by: other_agent)
  101. # not really another way to be absolutely sure that this works
  102. sleep 5
  103. # the new item will be synced after saving
  104. expect(page).to have_no_text(other_item_text)
  105. # it's important that the old edit mode does not abort
  106. page.find('.js-confirm').click
  107. # then both items arrive in the UI
  108. expect(page).to have_text(item_text)
  109. expect(page).to have_text(other_item_text)
  110. end
  111. it 'does delete item' do
  112. perform_item_action(item.id, 'delete')
  113. click_on 'delete'
  114. wait.until { Checklist::Item.find_by(id: item.id).blank? }
  115. end
  116. context 'with links' do
  117. let(:checklist) do
  118. checklist = create(:checklist, ticket: ticket)
  119. checklist.items.last.update(text: 'http://google.de test')
  120. checklist
  121. end
  122. it 'does edit item with link' do
  123. expect(page).to have_link('google.de')
  124. perform_item_action(item.id, 'edit')
  125. item_text = SecureRandom.uuid
  126. find(".checklistShow tr[data-id='#{item.id}'] .js-input").fill_in with: item_text, fill_options: { clear: :backspace }
  127. page.find('.js-confirm').click
  128. wait.until { item.reload.text == item_text }
  129. end
  130. end
  131. end
  132. context 'when using a checklist template' do
  133. let(:checklist_template) { create(:checklist_template) }
  134. before do
  135. click '.tabsSidebar-tab[data-tab=checklist]'
  136. checklist_template
  137. wait.until { page.find('[name="checklist_template_id"]') }
  138. await_empty_ajax_queue
  139. end
  140. it 'does add checklist from template' do
  141. expect(page).to have_button('Add from a template')
  142. expect(page).to have_select('checklist_template_id')
  143. click_on('Add from a template')
  144. expect(page).to have_text('Please select a checklist template.')
  145. select checklist_template.name, from: 'checklist_template_id'
  146. wait.until { page.has_no_content?('Please select a checklist template.') }
  147. click_on('Add from a template')
  148. wait.until { Checklist.where(ticket: ticket).present? }
  149. expect(Checklist.where(ticket: ticket).last.items.count).to eq(checklist_template.items.count)
  150. checklist_template.items.each do |item|
  151. expect(page).to have_text(item.text)
  152. end
  153. end
  154. end
  155. context 'when checklist modal on submit' do
  156. let(:checklist) { create(:checklist, ticket: ticket, name: SecureRandom.uuid) }
  157. def authenticate
  158. pre_auth
  159. true
  160. end
  161. context 'when activated and set' do
  162. let(:pre_auth) do
  163. Setting.set('checklist', true)
  164. checklist
  165. end
  166. it 'does show modal' do
  167. select 'closed', from: 'State'
  168. click '.js-submit'
  169. expect(page).to have_text('You have unchecked items in the checklist')
  170. end
  171. it 'does switch to sidebar' do
  172. select 'closed', from: 'State'
  173. click '.js-submit'
  174. page.find('.modal-footer .js-submit').click
  175. expect(page).to have_text(checklist.name.upcase)
  176. end
  177. context 'when time accounting is also activated' do
  178. let(:pre_auth) do
  179. Setting.set('checklist', true)
  180. Setting.set('time_accounting', true)
  181. checklist
  182. end
  183. it 'does show both modals' do
  184. find('.articleNewEdit-body').send_keys('Forwarding with the attachment')
  185. select 'closed', from: 'State'
  186. click '.js-submit'
  187. expect(page.find('.modal-body')).to have_text('You have unchecked items in the checklist')
  188. page.find('.modal-footer .js-skip').click
  189. expect(page.find('.modal-body')).to have_text('Accounted Time'.upcase)
  190. page.find('.modal-footer .js-skip').click
  191. wait.until { ticket.reload.state.name == 'closed' }
  192. end
  193. end
  194. end
  195. context 'when deactivated and set' do
  196. let(:pre_auth) do
  197. Setting.set('checklist', false)
  198. checklist
  199. end
  200. it 'does not show modal' do
  201. select 'closed', from: 'State'
  202. click '.js-submit'
  203. wait.until { ticket.reload.state.name == 'closed' }
  204. expect(page).to have_no_text('You have unchecked items in the checklist')
  205. end
  206. end
  207. context 'when activated and completed' do
  208. let(:pre_auth) do
  209. Setting.set('checklist', true)
  210. checklist.items.map { |item| item.update(checked: true) }
  211. end
  212. it 'does not show modal' do
  213. select 'closed', from: 'State'
  214. click '.js-submit'
  215. wait.until { ticket.reload.state.name == 'closed' }
  216. expect(page).to have_no_text('You have unchecked items in the checklist')
  217. end
  218. end
  219. context 'when activated and no checklist' do
  220. let(:pre_auth) do
  221. Setting.set('checklist', true)
  222. end
  223. it 'does not show modal' do
  224. select 'closed', from: 'State'
  225. click '.js-submit'
  226. wait.until { ticket.reload.state.name == 'closed' }
  227. expect(page).to have_no_text('You have unchecked items in the checklist')
  228. end
  229. end
  230. end
  231. end