article_spec.rb 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. require 'rails_helper'
  2. RSpec.describe 'Ticket Article API endpoints', type: :request do
  3. let(:admin) do
  4. create(:admin, groups: Group.all)
  5. end
  6. let!(:group) { create(:group) }
  7. let(:agent) do
  8. create(:agent, groups: Group.all)
  9. end
  10. let(:customer) do
  11. create(:customer)
  12. end
  13. describe 'request handling' do
  14. it 'does ticket create with agent and articles' do
  15. params = {
  16. title: 'a new ticket #1',
  17. group: 'Users',
  18. customer_id: customer.id,
  19. article: {
  20. body: 'some body',
  21. }
  22. }
  23. authenticated_as(agent)
  24. post '/api/v1/tickets', params: params, as: :json
  25. expect(response).to have_http_status(:created)
  26. params = {
  27. ticket_id: json_response['id'],
  28. content_type: 'text/plain', # or text/html
  29. body: 'some body',
  30. type: 'note',
  31. }
  32. post '/api/v1/ticket_articles', params: params, as: :json
  33. expect(response).to have_http_status(:created)
  34. expect(json_response).to be_a_kind_of(Hash)
  35. expect(json_response['subject']).to be_nil
  36. expect(json_response['body']).to eq('some body')
  37. expect(json_response['content_type']).to eq('text/plain')
  38. expect(json_response['updated_by_id']).to eq(agent.id)
  39. expect(json_response['created_by_id']).to eq(agent.id)
  40. ticket = Ticket.find(json_response['ticket_id'])
  41. expect(ticket.articles.count).to eq(2)
  42. expect(ticket.articles[0].attachments.count).to eq(0)
  43. expect(ticket.articles[1].attachments.count).to eq(0)
  44. params = {
  45. ticket_id: json_response['ticket_id'],
  46. content_type: 'text/html', # or text/html
  47. body: 'some body <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
  48. AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
  49. 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />',
  50. type: 'note',
  51. }
  52. post '/api/v1/ticket_articles', params: params, as: :json
  53. expect(response).to have_http_status(:created)
  54. expect(json_response).to be_a_kind_of(Hash)
  55. expect(json_response['subject']).to be_nil
  56. expect(json_response['body']).not_to match(/some body <img src="cid:.+?/)
  57. expect(json_response['body']).to match(%r{some body <img src="/api/v1/ticket_attachment/.+?" alt="Red dot"})
  58. expect(json_response['content_type']).to eq('text/html')
  59. expect(json_response['updated_by_id']).to eq(agent.id)
  60. expect(json_response['created_by_id']).to eq(agent.id)
  61. expect(ticket.articles.count).to eq(3)
  62. expect(ticket.articles[0].attachments.count).to eq(0)
  63. expect(ticket.articles[1].attachments.count).to eq(0)
  64. expect(ticket.articles[2].attachments.count).to eq(1)
  65. expect(ticket.articles[2].attachments[0]['id']).to be_truthy
  66. expect(ticket.articles[2].attachments[0]['filename']).to eq('image1.png')
  67. expect(ticket.articles[2].attachments[0]['size']).to eq('21')
  68. expect(ticket.articles[2].attachments[0]['preferences']['Mime-Type']).to eq('image/png')
  69. expect(ticket.articles[2].attachments[0]['preferences']['Content-Disposition']).to eq('inline')
  70. expect(ticket.articles[2].attachments[0]['preferences']['Content-ID']).to match(/@zammad.example.com/)
  71. params = {
  72. ticket_id: json_response['ticket_id'],
  73. content_type: 'text/html', # or text/html
  74. body: 'some body',
  75. type: 'note',
  76. attachments: [
  77. 'filename' => 'some_file.txt',
  78. 'data' => 'dGVzdCAxMjM=',
  79. 'mime-type' => 'text/plain',
  80. ],
  81. }
  82. post '/api/v1/ticket_articles', params: params, as: :json
  83. expect(response).to have_http_status(:created)
  84. expect(json_response).to be_a_kind_of(Hash)
  85. expect(json_response['subject']).to be_nil
  86. expect(json_response['body']).to eq('some body')
  87. expect(json_response['content_type']).to eq('text/html')
  88. expect(json_response['updated_by_id']).to eq(agent.id)
  89. expect(json_response['created_by_id']).to eq(agent.id)
  90. expect(ticket.articles.count).to eq(4)
  91. expect(ticket.articles[0].attachments.count).to eq(0)
  92. expect(ticket.articles[1].attachments.count).to eq(0)
  93. expect(ticket.articles[2].attachments.count).to eq(1)
  94. expect(ticket.articles[3].attachments.count).to eq(1)
  95. get "/api/v1/ticket_articles/#{json_response['id']}?expand=true", params: {}, as: :json
  96. expect(response).to have_http_status(:ok)
  97. expect(json_response).to be_a_kind_of(Hash)
  98. expect(json_response['attachments'].count).to eq(1)
  99. expect(json_response['attachments'][0]['id']).to be_truthy
  100. expect(json_response['attachments'][0]['filename']).to eq('some_file.txt')
  101. expect(json_response['attachments'][0]['size']).to eq('8')
  102. expect(json_response['attachments'][0]['preferences']['Mime-Type']).to eq('text/plain')
  103. params = {
  104. ticket_id: json_response['ticket_id'],
  105. content_type: 'text/plain',
  106. body: 'some body',
  107. type: 'note',
  108. preferences: {
  109. some_key1: 123,
  110. },
  111. }
  112. post '/api/v1/ticket_articles', params: params, as: :json
  113. expect(response).to have_http_status(:created)
  114. expect(json_response).to be_a_kind_of(Hash)
  115. expect(json_response['subject']).to be_nil
  116. expect(json_response['body']).to eq('some body')
  117. expect(json_response['content_type']).to eq('text/plain')
  118. expect(json_response['updated_by_id']).to eq(agent.id)
  119. expect(json_response['created_by_id']).to eq(agent.id)
  120. expect(json_response['preferences']['some_key1']).to eq(123)
  121. expect(ticket.articles.count).to eq(5)
  122. params = {
  123. body: 'some body 2',
  124. preferences: {
  125. some_key2: 'abc',
  126. },
  127. }
  128. put "/api/v1/ticket_articles/#{json_response['id']}", params: params, as: :json
  129. expect(response).to have_http_status(:ok)
  130. expect(json_response).to be_a_kind_of(Hash)
  131. expect(json_response['subject']).to be_nil
  132. expect(json_response['body']).to eq('some body 2')
  133. expect(json_response['content_type']).to eq('text/plain')
  134. expect(json_response['updated_by_id']).to eq(agent.id)
  135. expect(json_response['created_by_id']).to eq(agent.id)
  136. expect(json_response['preferences']['some_key1']).to eq(123)
  137. expect(json_response['preferences']['some_key2']).to eq('abc')
  138. end
  139. it 'does ticket create with customer and articles' do
  140. params = {
  141. title: 'a new ticket #2',
  142. group: 'Users',
  143. article: {
  144. body: 'some body',
  145. }
  146. }
  147. authenticated_as(customer)
  148. post '/api/v1/tickets', params: params, as: :json
  149. expect(response).to have_http_status(:created)
  150. params = {
  151. ticket_id: json_response['id'],
  152. content_type: 'text/plain', # or text/html
  153. body: 'some body',
  154. type: 'note',
  155. }
  156. post '/api/v1/ticket_articles', params: params, as: :json
  157. expect(response).to have_http_status(:created)
  158. expect(json_response).to be_a_kind_of(Hash)
  159. expect(json_response['subject']).to be_nil
  160. expect(json_response['body']).to eq('some body')
  161. expect(json_response['content_type']).to eq('text/plain')
  162. expect(json_response['updated_by_id']).to eq(customer.id)
  163. expect(json_response['created_by_id']).to eq(customer.id)
  164. ticket = Ticket.find(json_response['ticket_id'])
  165. expect(ticket.articles.count).to eq(2)
  166. expect(ticket.articles[1].sender.name).to eq('Customer')
  167. expect(ticket.articles[0].attachments.count).to eq(0)
  168. expect(ticket.articles[1].attachments.count).to eq(0)
  169. params = {
  170. ticket_id: json_response['ticket_id'],
  171. content_type: 'text/plain', # or text/html
  172. body: 'some body',
  173. sender: 'Agent',
  174. type: 'note',
  175. }
  176. post '/api/v1/ticket_articles', params: params, as: :json
  177. expect(response).to have_http_status(:created)
  178. expect(json_response).to be_a_kind_of(Hash)
  179. expect(json_response['subject']).to be_nil
  180. expect(json_response['body']).to eq('some body')
  181. expect(json_response['content_type']).to eq('text/plain')
  182. expect(json_response['updated_by_id']).to eq(customer.id)
  183. expect(json_response['created_by_id']).to eq(customer.id)
  184. ticket = Ticket.find(json_response['ticket_id'])
  185. expect(ticket.articles.count).to eq(3)
  186. expect(ticket.articles[2].sender.name).to eq('Customer')
  187. expect(ticket.articles[2].internal).to eq(false)
  188. expect(ticket.articles[0].attachments.count).to eq(0)
  189. expect(ticket.articles[1].attachments.count).to eq(0)
  190. expect(ticket.articles[2].attachments.count).to eq(0)
  191. params = {
  192. ticket_id: json_response['ticket_id'],
  193. content_type: 'text/plain', # or text/html
  194. body: 'some body 2',
  195. sender: 'Agent',
  196. type: 'note',
  197. internal: true,
  198. }
  199. post '/api/v1/ticket_articles', params: params, as: :json
  200. expect(response).to have_http_status(:created)
  201. expect(json_response).to be_a_kind_of(Hash)
  202. expect(json_response['subject']).to be_nil
  203. expect(json_response['body']).to eq('some body 2')
  204. expect(json_response['content_type']).to eq('text/plain')
  205. expect(json_response['updated_by_id']).to eq(customer.id)
  206. expect(json_response['created_by_id']).to eq(customer.id)
  207. ticket = Ticket.find(json_response['ticket_id'])
  208. expect(ticket.articles.count).to eq(4)
  209. expect(ticket.articles[3].sender.name).to eq('Customer')
  210. expect(ticket.articles[3].internal).to eq(false)
  211. expect(ticket.articles[0].attachments.count).to eq(0)
  212. expect(ticket.articles[1].attachments.count).to eq(0)
  213. expect(ticket.articles[2].attachments.count).to eq(0)
  214. expect(ticket.articles[3].attachments.count).to eq(0)
  215. # add internal article
  216. article = create(
  217. :ticket_article,
  218. ticket_id: ticket.id,
  219. internal: true,
  220. sender: Ticket::Article::Sender.find_by(name: 'Agent'),
  221. type: Ticket::Article::Type.find_by(name: 'note'),
  222. )
  223. expect(ticket.articles.count).to eq(5)
  224. expect(ticket.articles[4].sender.name).to eq('Agent')
  225. expect(ticket.articles[4].updated_by_id).to eq(1)
  226. expect(ticket.articles[4].created_by_id).to eq(1)
  227. expect(ticket.articles[0].attachments.count).to eq(0)
  228. expect(ticket.articles[1].attachments.count).to eq(0)
  229. expect(ticket.articles[2].attachments.count).to eq(0)
  230. expect(ticket.articles[3].attachments.count).to eq(0)
  231. expect(ticket.articles[4].attachments.count).to eq(0)
  232. get "/api/v1/ticket_articles/#{article.id}", params: {}, as: :json
  233. expect(response).to have_http_status(:unauthorized)
  234. expect(json_response).to be_a_kind_of(Hash)
  235. expect(json_response['error']).to eq('Not authorized')
  236. put "/api/v1/ticket_articles/#{article.id}", params: { internal: false }, as: :json
  237. expect(response).to have_http_status(:unauthorized)
  238. expect(json_response).to be_a_kind_of(Hash)
  239. expect(json_response['error']).to eq('Not authorized')
  240. end
  241. it 'does create phone ticket for customer and expected origin_by_id' do
  242. params = {
  243. title: 'a new ticket #1',
  244. group: 'Users',
  245. customer_id: customer.id,
  246. article: {
  247. body: 'some body',
  248. sender: 'Customer',
  249. type: 'phone',
  250. }
  251. }
  252. authenticated_as(agent)
  253. post '/api/v1/tickets', params: params, as: :json
  254. expect(response).to have_http_status(:created)
  255. expect(json_response).to be_a_kind_of(Hash)
  256. expect(json_response['title']).to eq('a new ticket #1')
  257. expect(Ticket::Article.where(ticket_id: json_response['id']).count).to eq(2) # original + auto responder
  258. article = Ticket::Article.where(ticket_id: json_response['id']).first
  259. expect(article.origin_by_id).to eq(customer.id)
  260. expect(article.from).to eq("#{customer.firstname} #{customer.lastname} <#{customer.email}>")
  261. end
  262. it 'does create phone ticket by customer and manipulate origin_by_id' do
  263. params = {
  264. title: 'a new ticket #1',
  265. group: 'Users',
  266. customer_id: customer.id,
  267. article: {
  268. body: 'some body',
  269. sender: 'Customer',
  270. type: 'phone',
  271. origin_by_id: 1,
  272. }
  273. }
  274. authenticated_as(customer)
  275. post '/api/v1/tickets', params: params, as: :json
  276. expect(response).to have_http_status(:created)
  277. expect(json_response).to be_a_kind_of(Hash)
  278. expect(Ticket::Article.where(ticket_id: json_response['id']).count).to eq(1) # ony original
  279. article = Ticket::Article.where(ticket_id: json_response['id']).first
  280. expect(article.origin_by_id).to eq(customer.id)
  281. end
  282. it 'does ticket split with html - check attachments' do
  283. ticket = create(:ticket, group: group)
  284. article = create(
  285. :ticket_article,
  286. ticket_id: ticket.id,
  287. type: Ticket::Article::Type.lookup(name: 'note'),
  288. sender: Ticket::Article::Sender.lookup(name: 'Customer'),
  289. body: '<b>test</b> <img src="cid:15.274327094.140938@ZAMMAD.example.com"/> test <img src="cid:15.274327094.140938.3@ZAMMAD.example.com"/>',
  290. content_type: 'text/html',
  291. )
  292. Store.add(
  293. object: 'Ticket::Article',
  294. o_id: article.id,
  295. data: 'content_file1_normally_should_be_an_image',
  296. filename: 'some_file1.jpg',
  297. preferences: {
  298. 'Content-Type' => 'image/jpeg',
  299. 'Mime-Type' => 'image/jpeg',
  300. 'Content-ID' => '15.274327094.140938@zammad.example.com',
  301. 'Content-Disposition' => 'inline',
  302. },
  303. created_by_id: 1,
  304. )
  305. Store.add(
  306. object: 'Ticket::Article',
  307. o_id: article.id,
  308. data: 'content_file2_normally_should_be_an_image',
  309. filename: 'some_file2.jpg',
  310. preferences: {
  311. 'Content-Type' => 'image/jpeg',
  312. 'Mime-Type' => 'image/jpeg',
  313. 'Content-ID' => '15.274327094.140938.2@zammad.example.com',
  314. 'Content-Disposition' => 'inline',
  315. },
  316. created_by_id: 1,
  317. )
  318. Store.add(
  319. object: 'Ticket::Article',
  320. o_id: article.id,
  321. data: 'content_file3_normally_should_be_an_image',
  322. filename: 'some_file3.jpg',
  323. preferences: {
  324. 'Content-Type' => 'image/jpeg',
  325. 'Mime-Type' => 'image/jpeg',
  326. 'Content-ID' => '15.274327094.140938.3@zammad.example.com',
  327. },
  328. created_by_id: 1,
  329. )
  330. Store.add(
  331. object: 'Ticket::Article',
  332. o_id: article.id,
  333. data: 'content_file4_normally_should_be_an_image',
  334. filename: 'some_file4.jpg',
  335. preferences: {
  336. 'Content-Type' => 'image/jpeg',
  337. 'Mime-Type' => 'image/jpeg',
  338. 'Content-ID' => '15.274327094.140938.4@zammad.example.com',
  339. },
  340. created_by_id: 1,
  341. )
  342. Store.add(
  343. object: 'Ticket::Article',
  344. o_id: article.id,
  345. data: 'content_file1_normally_should_be_an_pdf',
  346. filename: 'Rechnung_RE-2018-200.pdf',
  347. preferences: {
  348. 'Content-Type' => 'application/octet-stream; name="Rechnung_RE-2018-200.pdf"',
  349. 'Mime-Type' => 'application/octet-stream',
  350. 'Content-ID' => '8AB0BEC88984EE4EBEF643C79C8E0346@zammad.example.com',
  351. 'Content-Description' => 'Rechnung_RE-2018-200.pdf',
  352. 'Content-Disposition' => 'attachment',
  353. },
  354. created_by_id: 1,
  355. )
  356. params = {
  357. form_id: 'new_form_id123',
  358. }
  359. authenticated_as(agent)
  360. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params, as: :json
  361. expect(response).to have_http_status(:ok)
  362. expect(json_response).to be_a_kind_of(Hash)
  363. expect(json_response['attachments']).to be_truthy
  364. expect(json_response['attachments'].count).to eq(3)
  365. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params, as: :json
  366. expect(response).to have_http_status(:ok)
  367. expect(json_response).to be_a_kind_of(Hash)
  368. expect(json_response['attachments']).to be_truthy
  369. expect(json_response['attachments'].count).to eq(0)
  370. end
  371. it 'does ticket split with plain - check attachments' do
  372. ticket = create(
  373. :ticket,
  374. group: group,
  375. updated_by_id: agent.id,
  376. created_by_id: agent.id,
  377. )
  378. article = create(
  379. :ticket_article,
  380. ticket_id: ticket.id,
  381. type: Ticket::Article::Type.lookup(name: 'note'),
  382. sender: Ticket::Article::Sender.lookup(name: 'Customer'),
  383. body: '<b>test</b> <img src="cid:15.274327094.140938@zammad.example.com"/>',
  384. content_type: 'text/plain',
  385. updated_by_id: 1,
  386. created_by_id: 1,
  387. )
  388. Store.add(
  389. object: 'Ticket::Article',
  390. o_id: article.id,
  391. data: 'content_file1_normally_should_be_an_image',
  392. filename: 'some_file1.jpg',
  393. preferences: {
  394. 'Content-Type' => 'image/jpeg',
  395. 'Mime-Type' => 'image/jpeg',
  396. 'Content-ID' => '15.274327094.140938@zammad.example.com',
  397. 'Content-Disposition' => 'inline',
  398. },
  399. created_by_id: 1,
  400. )
  401. Store.add(
  402. object: 'Ticket::Article',
  403. o_id: article.id,
  404. data: 'content_file1_normally_should_be_an_image',
  405. filename: 'some_file2.jpg',
  406. preferences: {
  407. 'Content-Type' => 'image/jpeg',
  408. 'Mime-Type' => 'image/jpeg',
  409. 'Content-ID' => '15.274327094.140938.2@zammad.example.com',
  410. 'Content-Disposition' => 'inline',
  411. },
  412. created_by_id: 1,
  413. )
  414. Store.add(
  415. object: 'Ticket::Article',
  416. o_id: article.id,
  417. data: 'content_file1_normally_should_be_an_pdf',
  418. filename: 'Rechnung_RE-2018-200.pdf',
  419. preferences: {
  420. 'Content-Type' => 'application/octet-stream; name="Rechnung_RE-2018-200.pdf"',
  421. 'Mime-Type' => 'application/octet-stream',
  422. 'Content-ID' => '8AB0BEC88984EE4EBEF643C79C8E0346@zammad.example.com',
  423. 'Content-Description' => 'Rechnung_RE-2018-200.pdf',
  424. 'Content-Disposition' => 'attachment',
  425. },
  426. created_by_id: 1,
  427. )
  428. params = {
  429. form_id: 'new_form_id123',
  430. }
  431. authenticated_as(agent)
  432. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params, as: :json
  433. expect(response).to have_http_status(:ok)
  434. expect(json_response).to be_a_kind_of(Hash)
  435. expect(json_response['attachments']).to be_truthy
  436. expect(json_response['attachments'].count).to eq(3)
  437. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params, as: :json
  438. expect(response).to have_http_status(:ok)
  439. expect(json_response).to be_a_kind_of(Hash)
  440. expect(json_response['attachments']).to be_truthy
  441. expect(json_response['attachments'].count).to eq(0)
  442. end
  443. end
  444. describe 'DELETE /api/v1/ticket_articles/:id', authenticated_as: -> { user } do
  445. let(:other_agent) { create(:agent, groups: [Group.first]) }
  446. let(:ticket) do
  447. create(:ticket, group: Group.first)
  448. end
  449. let(:article_communication) do
  450. create(:ticket_article,
  451. sender_name: 'Agent', type_name: 'email', ticket: ticket,
  452. updated_by_id: agent.id, created_by_id: agent.id )
  453. end
  454. let(:article_note_self) do
  455. create(:ticket_article,
  456. sender_name: 'Agent', internal: true, type_name: 'note', ticket: ticket,
  457. updated_by_id: user.id, created_by_id: user.id )
  458. end
  459. let(:article_note_other) do
  460. create(:ticket_article,
  461. sender_name: 'Agent', internal: true, type_name: 'note', ticket: ticket,
  462. updated_by_id: other_agent.id, created_by_id: other_agent.id )
  463. end
  464. let(:article_note_customer) do
  465. create(:ticket_article,
  466. sender_name: 'Customer', internal: false, type_name: 'note', ticket: ticket,
  467. updated_by_id: customer.id, created_by_id: customer.id )
  468. end
  469. let(:article_note_communication_self) do
  470. create(:ticket_article_type, name: 'note_communication', communication: true)
  471. create(:ticket_article,
  472. sender_name: 'Agent', internal: true, type_name: 'note_communication', ticket: ticket,
  473. updated_by_id: user.id, created_by_id: user.id )
  474. end
  475. let(:article_note_communication_other) do
  476. create(:ticket_article_type, name: 'note_communication', communication: true)
  477. create(:ticket_article,
  478. sender_name: 'Agent', internal: true, type_name: 'note_communication', ticket: ticket,
  479. updated_by_id: other_agent.id, created_by_id: other_agent.id )
  480. end
  481. def delete_article_via_rest(article)
  482. delete "/api/v1/ticket_articles/#{article.id}", params: {}, as: :json
  483. end
  484. shared_examples 'succeeds' do
  485. it 'succeeds' do
  486. expect { delete_article_via_rest(article) }.to change { Ticket::Article.exists?(id: article.id) }
  487. end
  488. end
  489. shared_examples 'fails' do
  490. it 'fails' do
  491. expect { delete_article_via_rest(article) }.not_to change { Ticket::Article.exists?(id: article.id) }
  492. end
  493. end
  494. shared_examples 'deleting' do |item:, now:, later:, much_later:|
  495. context "deleting #{item}" do
  496. let(:article) { send(item) }
  497. include_examples now ? 'succeeds' : 'fails'
  498. context '8 minutes later' do
  499. before { article && travel(8.minutes) }
  500. include_examples later ? 'succeeds' : 'fails'
  501. end
  502. context '11 minutes later' do
  503. before { article && travel(11.minutes) }
  504. include_examples much_later ? 'succeeds' : 'fails'
  505. end
  506. end
  507. end
  508. context 'as admin' do
  509. let(:user) { admin }
  510. include_examples 'deleting',
  511. item: 'article_communication',
  512. now: false, later: false, much_later: false
  513. include_examples 'deleting',
  514. item: 'article_note_self',
  515. now: true, later: true, much_later: false
  516. include_examples 'deleting',
  517. item: 'article_note_other',
  518. now: false, later: false, much_later: false
  519. include_examples 'deleting',
  520. item: 'article_note_customer',
  521. now: false, later: false, much_later: false
  522. include_examples 'deleting',
  523. item: 'article_note_communication_self',
  524. now: false, later: false, much_later: false
  525. include_examples 'deleting',
  526. item: 'article_note_communication_other',
  527. now: false, later: false, much_later: false
  528. end
  529. context 'as agent' do
  530. let(:user) { agent }
  531. include_examples 'deleting',
  532. item: 'article_communication',
  533. now: false, later: false, much_later: false
  534. include_examples 'deleting',
  535. item: 'article_note_self',
  536. now: true, later: true, much_later: false
  537. include_examples 'deleting',
  538. item: 'article_note_other',
  539. now: false, later: false, much_later: false
  540. include_examples 'deleting',
  541. item: 'article_note_customer',
  542. now: false, later: false, much_later: false
  543. include_examples 'deleting',
  544. item: 'article_note_communication_self',
  545. now: false, later: false, much_later: false
  546. include_examples 'deleting',
  547. item: 'article_note_communication_other',
  548. now: false, later: false, much_later: false
  549. end
  550. context 'as customer' do
  551. let(:user) { customer }
  552. include_examples 'deleting',
  553. item: 'article_communication',
  554. now: false, later: false, much_later: false
  555. include_examples 'deleting',
  556. item: 'article_note_other',
  557. now: false, later: false, much_later: false
  558. include_examples 'deleting',
  559. item: 'article_note_customer',
  560. now: false, later: false, much_later: false
  561. include_examples 'deleting',
  562. item: 'article_note_communication_self',
  563. now: false, later: false, much_later: false
  564. include_examples 'deleting',
  565. item: 'article_note_communication_other',
  566. now: false, later: false, much_later: false
  567. end
  568. context 'with custom timeframe' do
  569. before { Setting.set 'ui_ticket_zoom_article_delete_timeframe', 6000 }
  570. let(:article) { article_note_self }
  571. context 'as admin' do
  572. let(:user) { admin }
  573. context 'deleting before timeframe' do
  574. before { article && travel(5000.seconds) }
  575. include_examples 'succeeds'
  576. end
  577. context 'deleting after timeframe' do
  578. before { article && travel(8000.seconds) }
  579. include_examples 'fails'
  580. end
  581. end
  582. context 'as agent' do
  583. let(:user) { agent }
  584. context 'deleting before timeframe' do
  585. before { article && travel(5000.seconds) }
  586. include_examples 'succeeds'
  587. end
  588. context 'deleting after timeframe' do
  589. before { article && travel(8000.seconds) }
  590. include_examples 'fails'
  591. end
  592. end
  593. end
  594. context 'with timeframe as 0' do
  595. before { Setting.set 'ui_ticket_zoom_article_delete_timeframe', 0 }
  596. let(:article) { article_note_self }
  597. context 'as agent' do
  598. let(:user) { agent }
  599. context 'deleting long after' do
  600. before { article && travel(99.days) }
  601. include_examples 'succeeds'
  602. end
  603. end
  604. end
  605. end
  606. end