starts_controller_spec.rb 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Ticket Shared Drafts Start API endpoints', authenticated_as: :agent, type: :request do
  4. let(:group_a) { create(:group, shared_drafts: true) }
  5. let(:group_b) { create(:group, shared_drafts: true) }
  6. let(:group_c) { create(:group, shared_drafts: false) }
  7. let(:group_d) { create(:group, shared_drafts: true) }
  8. let(:role_group_d) { create(:role, :agent, groups: [group_d]) }
  9. let(:draft_a) { create(:ticket_shared_draft_start, group: group_a) }
  10. let(:draft_b) { create(:ticket_shared_draft_start, group: group_b) }
  11. let(:draft_c) { create(:ticket_shared_draft_start, group: group_c) }
  12. let(:draft_d) { create(:ticket_shared_draft_start, group: group_d) }
  13. let(:agent) do
  14. user = create(:agent, roles: [Role.find_by(name: 'Agent'), role_group_d])
  15. user.user_groups.create! group: group_a, access: :full
  16. user.user_groups.create! group: group_c, access: :full
  17. user
  18. end
  19. let(:other_agent) { create(:agent) }
  20. let(:customer) { create(:customer) }
  21. let(:form_id) { SecureRandom.uuid }
  22. let(:base_params) do
  23. {
  24. name: 'draft name',
  25. group_id: group_a.id,
  26. form_id: form_id,
  27. content: { attrs: true }
  28. }
  29. end
  30. let(:path) { '/api/v1/tickets/shared_drafts' }
  31. let(:path_draft_a) { "#{path}/#{draft_a.id}" }
  32. let(:path_draft_b) { "#{path}/#{draft_b.id}" }
  33. let(:path_draft_d) { "#{path}/#{draft_d.id}" }
  34. let(:path_draft_nonexistant) { "#{path}/asd" }
  35. describe 'request handling' do
  36. describe '#index' do
  37. it 'returns drafts that user has access to' do
  38. draft_a && draft_b && draft_d
  39. get path, as: :json
  40. expect(json_response).to include('shared_draft_ids' => [draft_a.id, draft_d.id])
  41. end
  42. it 'returns empty array when no drafts available' do
  43. get path, as: :json
  44. expect(json_response).to include('shared_draft_ids' => [])
  45. end
  46. it 'raises error when user has no permissions', authenticated_as: :customer do
  47. get path, as: :json
  48. expect(response).to have_http_status(:forbidden)
  49. end
  50. end
  51. describe '#show' do
  52. it 'returns draft' do
  53. get path_draft_a, as: :json
  54. expect(json_response).to include('shared_draft_id' => draft_a.id)
  55. end
  56. it 'returns 404 when draft does not exist' do
  57. get path_draft_nonexistant, as: :json
  58. expect(response).to have_http_status(:not_found)
  59. end
  60. it 'returns 404 when user has no permissions to drafts', authenticated_as: :other_agent do
  61. get path_draft_b, as: :json
  62. expect(response).to have_http_status(:forbidden)
  63. end
  64. it 'returns 404 when user has no permissions to this draft' do
  65. get path_draft_b, as: :json
  66. expect(response).to have_http_status(:not_found)
  67. end
  68. it 'returns error when user has no permissions', authenticated_as: :customer do
  69. get path_draft_b, as: :json
  70. expect(response).to have_http_status(:forbidden)
  71. end
  72. it 'grants access via role groups' do
  73. get path_draft_d, as: :json
  74. expect(json_response).to include('shared_draft_id' => draft_d.id)
  75. end
  76. end
  77. describe '#create' do
  78. it 'creates draft' do
  79. post path, params: base_params, as: :json
  80. expect(Ticket::SharedDraftStart).to exist json_response['shared_draft_id']
  81. end
  82. it 'creates draft with attachment' do
  83. create(:store, :image, o_id: form_id)
  84. post path, params: base_params, as: :json
  85. new_draft = Ticket::SharedDraftStart.find json_response['shared_draft_id']
  86. expect(new_draft.attachments).to be_one
  87. end
  88. it 'verifies user has access to given group' do
  89. post path, params: base_params.merge(group_id: group_b.id), as: :json
  90. expect(json_response).to include 'error_human' => %r{does not have access}
  91. end
  92. it 'grants access via role groups' do
  93. post path, params: base_params.merge(group_id: group_d.id), as: :json
  94. expect(Ticket::SharedDraftStart).to exist json_response['shared_draft_id']
  95. end
  96. it 'raises error when user has no create permission on any group', authenticated_as: :other_agent do
  97. post path, params: base_params, as: :json
  98. expect(response).to have_http_status(:forbidden)
  99. end
  100. it 'raises error when user has no permissions', authenticated_as: :customer do
  101. post path, params: base_params, as: :json
  102. expect(response).to have_http_status(:forbidden)
  103. end
  104. end
  105. describe '#update' do
  106. it 'updates draft' do
  107. patch path_draft_a, params: base_params, as: :json
  108. expect(draft_a.reload).to have_attributes(content: { attrs: true })
  109. end
  110. it 'updates draft with attachment' do
  111. create(:store, :image, o_id: form_id)
  112. expect { patch path_draft_a, params: base_params, as: :json }
  113. .to change { draft_a.attachments.count }
  114. .by(1)
  115. end
  116. it 'updates draft to have no attachments' do
  117. create(:store, :image, o_id: draft_a.id, object: draft_a.class.name)
  118. expect { patch path_draft_a, params: base_params, as: :json }
  119. .to change { draft_a.attachments.count }
  120. .by(-1)
  121. end
  122. it 'returns 404 when draft does not exist' do
  123. patch path_draft_nonexistant, params: base_params, as: :json
  124. expect(response).to have_http_status(:not_found)
  125. end
  126. it 'changes draft group' do
  127. agent.user_groups.create! group: group_b, access: :full
  128. patch path_draft_b, params: base_params.merge(group_id: group_b.id), as: :json
  129. expect(draft_b.reload.group).to eq group_b
  130. end
  131. it 'returns updated draft ID' do
  132. patch path_draft_a, params: base_params, as: :json
  133. expect(json_response).to include 'shared_draft_id' => draft_a.id
  134. end
  135. it 'verifies user has access to given groups' do
  136. patch path_draft_a, params: base_params.merge(group_id: group_b.id), as: :json
  137. expect(response).to have_http_status(:unprocessable_entity)
  138. end
  139. it 'grants access via role groups' do
  140. patch path_draft_d, params: base_params.merge(group_id: group_d.id), as: :json
  141. expect(json_response).to include 'shared_draft_id' => draft_d.id
  142. end
  143. it 'returns error when user has no permissions', authenticated_as: :customer do
  144. patch path_draft_a, params: base_params, as: :json
  145. expect(response).to have_http_status(:forbidden)
  146. end
  147. end
  148. describe '#destroy' do
  149. it 'destroys draft' do
  150. delete path_draft_a, as: :json
  151. expect(Ticket::SharedDraftStart).not_to exist draft_a.id
  152. end
  153. it 'grants access via role groups' do
  154. delete path_draft_d, as: :json
  155. expect(Ticket::SharedDraftStart).not_to exist draft_d.id
  156. end
  157. it 'returns 404 when draft does not exist' do
  158. delete path_draft_nonexistant, as: :json
  159. expect(response).to have_http_status(:not_found)
  160. end
  161. it 'returns 404 when user has no permissions to this draft' do
  162. delete path_draft_b, as: :json
  163. expect(response).to have_http_status(:not_found)
  164. end
  165. it 'returns error when user has no permissions', authenticated_as: :customer do
  166. delete path_draft_b, as: :json
  167. expect(response).to have_http_status(:forbidden)
  168. end
  169. end
  170. describe '#import_attachments' do
  171. let(:import_path_a) { "#{path_draft_a}/import_attachments" }
  172. let(:import_path_d) { "#{path_draft_d}/import_attachments" }
  173. let(:import_params) do
  174. {
  175. form_id: form_id
  176. }
  177. end
  178. it 'imports attachments from draft to given form ID' do
  179. create(:store, :image, o_id: draft_a.id, object: draft_a.class.name)
  180. expect { post import_path_a, params: import_params, as: :json }
  181. .to change { Store.list(object: 'UploadCache', o_id: form_id).count }
  182. .by(1)
  183. end
  184. it 'grants access via role groups' do
  185. create(:store, :image, o_id: draft_d.id, object: draft_d.class.name)
  186. expect { post import_path_d, params: import_params, as: :json }
  187. .to change { Store.list(object: 'UploadCache', o_id: form_id).count }
  188. .by(1)
  189. end
  190. it 'returns success if draft has no attachments' do
  191. post import_path_a, params: import_params, as: :json
  192. expect(response).to have_http_status(:ok)
  193. end
  194. end
  195. end
  196. describe 'clean up' do
  197. it 'removes draft when creating a ticket' do
  198. post_new_ticket group_a.id, draft_a.id
  199. expect(Ticket::SharedDraftStart).not_to exist(draft_a.id)
  200. end
  201. it 'grants access via role groups' do
  202. post_new_ticket group_d.id, draft_d.id
  203. expect(Ticket::SharedDraftStart).not_to exist(draft_d.id)
  204. end
  205. it 'not removes draft when fails creating a ticket' do
  206. post_new_ticket group_a.id, draft_a.id, valid: false
  207. expect(Ticket::SharedDraftStart).to exist(draft_a.id)
  208. end
  209. it 'raises error if draft is not applicable in this context' do
  210. post_new_ticket group_b.id, draft_a.id
  211. expect(response).to have_http_status(:unprocessable_entity)
  212. end
  213. it 'keeps draft if not applicable in this context' do
  214. post_new_ticket group_b.id, draft_a.id
  215. expect(Ticket::SharedDraftStart).to exist(draft_a.id)
  216. end
  217. it 'raises error if group does not support drafts' do
  218. post_new_ticket group_c.id, draft_c.id
  219. expect(response).to have_http_status(:unprocessable_entity)
  220. end
  221. it 'succeeds when draft does not exist' do
  222. post_new_ticket group_a.id, 1_234
  223. expect(response).to have_http_status(:created)
  224. end
  225. def post_new_ticket(group_id, shared_draft_id, valid: true)
  226. params = {
  227. title: 'a new ticket #1',
  228. group_id: group_id,
  229. customer_id: create(:customer).id,
  230. shared_draft_id: shared_draft_id,
  231. article: {
  232. content_type: 'text/plain',
  233. body: valid ? 'some body' : nil,
  234. sender: 'Customer',
  235. type: 'note',
  236. },
  237. }
  238. post '/api/v1/tickets', params: params, as: :json
  239. end
  240. end
  241. end