zoom_spec.rb 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. require 'rails_helper'
  2. RSpec.describe 'Ticket zoom', type: :system do
  3. describe 'owner auto-assignment' do
  4. let!(:ticket) { create(:ticket, group: Group.find_by(name: 'Users'), state: Ticket::State.find_by(name: 'new')) }
  5. let!(:session_user) { User.find_by(login: 'master@example.com') }
  6. context 'for agent disabled' do
  7. before do
  8. Setting.set('ticket_auto_assignment', false)
  9. Setting.set('ticket_auto_assignment_selector', { condition: { 'ticket.state_id' => { operator: 'is', value: Ticket::State.by_category(:work_on).pluck(:id) } } })
  10. Setting.set('ticket_auto_assignment_user_ids_ignore', [])
  11. end
  12. it 'do not assign ticket to current session user' do
  13. refresh
  14. visit "#ticket/zoom/#{ticket.id}"
  15. within(:active_content) do
  16. expect(page).to have_css('select[name=owner_id]')
  17. expect(page).to have_select('owner_id',
  18. selected: '-',
  19. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  20. end
  21. end
  22. end
  23. context 'for agent enabled' do
  24. before do
  25. Setting.set('ticket_auto_assignment', true)
  26. Setting.set('ticket_auto_assignment_selector', { condition: { 'ticket.state_id' => { operator: 'is', value: Ticket::State.by_category(:work_on).pluck(:id) } } })
  27. end
  28. context 'with empty "ticket_auto_assignment_user_ids_ignore"' do
  29. it 'assigns ticket to current session user' do
  30. refresh
  31. visit "#ticket/zoom/#{ticket.id}"
  32. within(:active_content) do
  33. expect(page).to have_css('.content.active select[name=owner_id]')
  34. expect(page).to have_select('owner_id',
  35. selected: session_user.fullname,
  36. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  37. end
  38. end
  39. end
  40. context 'with "ticket_auto_assignment_user_ids_ignore" (as integer)' do
  41. it 'assigns ticket not to current session user' do
  42. Setting.set('ticket_auto_assignment_user_ids_ignore', session_user.id)
  43. refresh
  44. visit "#ticket/zoom/#{ticket.id}"
  45. within(:active_content) do
  46. expect(page).to have_css('select[name=owner_id]')
  47. expect(page).to have_select('owner_id',
  48. selected: '-',
  49. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  50. end
  51. end
  52. end
  53. context 'with "ticket_auto_assignment_user_ids_ignore" (as string)' do
  54. it 'assigns ticket not to current session user' do
  55. Setting.set('ticket_auto_assignment_user_ids_ignore', session_user.id.to_s)
  56. refresh
  57. visit "#ticket/zoom/#{ticket.id}"
  58. within(:active_content) do
  59. expect(page).to have_css('select[name=owner_id]')
  60. expect(page).to have_select('owner_id',
  61. selected: '-',
  62. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  63. end
  64. end
  65. end
  66. context 'with "ticket_auto_assignment_user_ids_ignore" (as [integer])' do
  67. it 'assigns ticket not to current session user' do
  68. Setting.set('ticket_auto_assignment_user_ids_ignore', [session_user.id])
  69. refresh
  70. visit "#ticket/zoom/#{ticket.id}"
  71. within(:active_content) do
  72. expect(page).to have_css('select[name=owner_id]')
  73. expect(page).to have_select('owner_id',
  74. selected: '-',
  75. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  76. end
  77. end
  78. end
  79. context 'with "ticket_auto_assignment_user_ids_ignore" (as [string])' do
  80. it 'assigns ticket not to current session user' do
  81. Setting.set('ticket_auto_assignment_user_ids_ignore', [session_user.id.to_s])
  82. refresh
  83. visit "#ticket/zoom/#{ticket.id}"
  84. within(:active_content) do
  85. expect(page).to have_css('select[name=owner_id]')
  86. expect(page).to have_select('owner_id',
  87. selected: '-',
  88. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  89. end
  90. end
  91. end
  92. context 'with "ticket_auto_assignment_user_ids_ignore" and other user ids' do
  93. it 'assigns ticket to current session user' do
  94. Setting.set('ticket_auto_assignment_user_ids_ignore', [99_999, 999_999])
  95. refresh
  96. visit "#ticket/zoom/#{ticket.id}"
  97. within(:active_content) do
  98. expect(page).to have_css('select[name=owner_id]')
  99. expect(page).to have_select('owner_id',
  100. selected: session_user.fullname,
  101. options: ['-', 'Agent 1 Test', 'Test Master Agent'])
  102. end
  103. end
  104. end
  105. end
  106. end
  107. context 'when ticket has an attachment' do
  108. let(:group) { Group.find_by(name: 'Users') }
  109. let(:ticket) { create(:ticket, group: group) }
  110. let(:article) { create(:ticket_article, ticket: ticket) }
  111. let(:attachment_name) { 'some_file.txt' }
  112. before do
  113. Store.add(
  114. object: 'Ticket::Article',
  115. o_id: article.id,
  116. data: 'some content',
  117. filename: attachment_name,
  118. preferences: {
  119. 'Content-Type' => 'text/plain',
  120. },
  121. created_by_id: 1,
  122. )
  123. end
  124. context 'article was already forwarded once' do
  125. before do
  126. visit "#ticket/zoom/#{ticket.id}"
  127. within(:active_content) do
  128. find('a[data-type=emailForward]').click
  129. click('.js-reset')
  130. have_no_css('.js-reset')
  131. end
  132. end
  133. it 'adds attachments when forwarding multiple times' do
  134. within(:active_content) do
  135. find('a[data-type=emailForward]').click
  136. end
  137. within('.js-writeArea') do
  138. expect(page).to have_text attachment_name
  139. end
  140. end
  141. end
  142. end
  143. context 'replying' do
  144. context 'Group without signature' do
  145. let(:ticket) { create(:ticket) }
  146. let(:current_user) { create(:agent_user, password: 'test', groups: [ticket.group]) }
  147. before do
  148. # initial article to reply to
  149. create(:ticket_article, ticket: ticket)
  150. end
  151. it 'ensures that text input opens on multiple replies', authenticated: -> { current_user } do
  152. visit "ticket/zoom/#{ticket.id}"
  153. 2.times do |article_offset|
  154. articles_existing = 1
  155. articles_expected = articles_existing + (article_offset + 1)
  156. all('a[data-type=emailReply]').last.click
  157. # wait till input box expands completely
  158. find('.attachmentPlaceholder-label').in_fixed_postion
  159. expect(page).not_to have_css('.attachmentPlaceholder-hint', wait: 0)
  160. find('.articleNewEdit-body').send_keys('Some reply')
  161. click '.js-submit'
  162. expect(page).to have_css('.ticket-article-item', count: articles_expected)
  163. end
  164. end
  165. end
  166. end
  167. describe 'delete article', authenticated: -> { user } do
  168. let(:admin_user) { User.find_by! email: 'master@example.com' }
  169. let(:agent_user) { create :agent, password: 'test', groups: [Group.first] }
  170. let(:customer_user) { create :customer, password: 'test' }
  171. let(:ticket) { create :ticket, group: agent_user.groups.first, customer: customer_user }
  172. let(:article) { send(item) }
  173. def article_communication
  174. create_ticket_article(sender_name: 'Agent', internal: false, type_name: 'email', updated_by: customer_user)
  175. end
  176. def article_note
  177. create_ticket_article(sender_name: 'Agent', internal: true, type_name: 'note', updated_by: agent_user)
  178. end
  179. def article_note_customer
  180. create_ticket_article(sender_name: 'Customer', internal: false, type_name: 'note', updated_by: customer_user)
  181. end
  182. def article_note_communication
  183. create(:ticket_article_type, name: 'note_communication', communication: true)
  184. create_ticket_article(sender_name: 'Agent', internal: true, type_name: 'note_communication', updated_by: agent_user)
  185. end
  186. def create_ticket_article(sender_name:, internal:, type_name:, updated_by:)
  187. create(:ticket_article,
  188. sender_name: sender_name, internal: internal, type_name: type_name, ticket: ticket,
  189. body: "to be deleted #{offset} #{item}",
  190. updated_by_id: updated_by.id, created_by_id: updated_by.id,
  191. created_at: offset.ago, updated_at: offset.ago)
  192. end
  193. context 'going through full stack' do
  194. context 'as admin' do
  195. let(:user) { admin_user }
  196. let(:item) { 'article_communication' }
  197. let(:offset) { 0.minutes }
  198. it 'succeeds' do
  199. refresh # make sure user roles are loaded
  200. ensure_websocket do
  201. visit "ticket/zoom/#{ticket.id}"
  202. end
  203. within :active_ticket_article, article, wait: 15 do
  204. click '.js-ArticleAction[data-type=delete]'
  205. end
  206. in_modal do
  207. click '.js-submit'
  208. end
  209. wait.until_disappears { find :active_ticket_article, article, wait: false }
  210. end
  211. end
  212. end
  213. context 'verifying permissions matrix' do
  214. shared_examples 'according to permission matrix' do |item:, expects_visible:, offset:, description:|
  215. context "looking at #{description} #{item}" do
  216. let(:item) { item }
  217. let!(:article) { send(item) }
  218. let(:offset) { offset }
  219. let(:matcher) { expects_visible ? :have_css : :have_no_css }
  220. it expects_visible ? 'delete button is visible' : 'delete button is not visible' do
  221. refresh # make sure user roles are loaded
  222. visit "ticket/zoom/#{ticket.id}"
  223. within :active_ticket_article, article, wait: 15 do
  224. expect(page).to send(matcher, '.js-ArticleAction[data-type=delete]', wait: 0)
  225. end
  226. end
  227. end
  228. end
  229. shared_examples 'deleting ticket article' do |item:, now:, later:, much_later:|
  230. include_examples 'according to permission matrix', item: item, expects_visible: now, offset: 0.minutes, description: 'just created'
  231. include_examples 'according to permission matrix', item: item, expects_visible: later, offset: 6.minutes, description: 'few minutes old'
  232. include_examples 'according to permission matrix', item: item, expects_visible: much_later, offset: 11.minutes, description: 'very old'
  233. end
  234. context 'as admin' do
  235. let(:user) { admin_user }
  236. include_examples 'deleting ticket article',
  237. item: 'article_communication',
  238. now: true, later: true, much_later: true
  239. include_examples 'deleting ticket article',
  240. item: 'article_note',
  241. now: true, later: true, much_later: true
  242. include_examples 'deleting ticket article',
  243. item: 'article_note_customer',
  244. now: true, later: true, much_later: true
  245. include_examples 'deleting ticket article',
  246. item: 'article_note_communication',
  247. now: true, later: true, much_later: true
  248. end
  249. context 'as agent' do
  250. let(:user) { agent_user }
  251. include_examples 'deleting ticket article',
  252. item: 'article_communication',
  253. now: false, later: false, much_later: false
  254. include_examples 'deleting ticket article',
  255. item: 'article_note',
  256. now: true, later: true, much_later: false
  257. include_examples 'deleting ticket article',
  258. item: 'article_note_customer',
  259. now: false, later: false, much_later: false
  260. include_examples 'deleting ticket article',
  261. item: 'article_note_communication',
  262. now: true, later: true, much_later: false
  263. end
  264. context 'as customer' do
  265. let(:user) { customer_user }
  266. include_examples 'deleting ticket article',
  267. item: 'article_communication',
  268. now: false, later: false, much_later: false
  269. include_examples 'deleting ticket article',
  270. item: 'article_note_customer',
  271. now: false, later: false, much_later: false
  272. end
  273. end
  274. end
  275. end