ticket_articles_controller_test.rb 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. require 'test_helper'
  2. class TicketArticlesControllerTest < ActionDispatch::IntegrationTest
  3. setup do
  4. # set accept header
  5. @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
  6. # create agent
  7. roles = Role.where(name: %w[Admin Agent])
  8. groups = Group.all
  9. UserInfo.current_user_id = 1
  10. @admin = User.create!(
  11. login: 'tickets-admin',
  12. firstname: 'Tickets',
  13. lastname: 'Admin',
  14. email: 'tickets-admin@example.com',
  15. password: 'adminpw',
  16. active: true,
  17. roles: roles,
  18. groups: groups,
  19. )
  20. # create agent
  21. roles = Role.where(name: 'Agent')
  22. @agent = User.create!(
  23. login: 'tickets-agent@example.com',
  24. firstname: 'Tickets',
  25. lastname: 'Agent',
  26. email: 'tickets-agent@example.com',
  27. password: 'agentpw',
  28. active: true,
  29. roles: roles,
  30. groups: groups,
  31. )
  32. # create customer without org
  33. roles = Role.where(name: 'Customer')
  34. @customer_without_org = User.create!(
  35. login: 'tickets-customer1@example.com',
  36. firstname: 'Tickets',
  37. lastname: 'Customer1',
  38. email: 'tickets-customer1@example.com',
  39. password: 'customer1pw',
  40. active: true,
  41. roles: roles,
  42. )
  43. end
  44. test '01.01 ticket create with agent and articles' do
  45. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
  46. params = {
  47. title: 'a new ticket #1',
  48. group: 'Users',
  49. customer_id: @customer_without_org.id,
  50. article: {
  51. body: 'some body',
  52. }
  53. }
  54. post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  55. assert_response(201)
  56. result = JSON.parse(@response.body)
  57. params = {
  58. ticket_id: result['id'],
  59. content_type: 'text/plain', # or text/html
  60. body: 'some body',
  61. type: 'note',
  62. }
  63. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  64. assert_response(201)
  65. result = JSON.parse(@response.body)
  66. assert_equal(Hash, result.class)
  67. assert_nil(result['subject'])
  68. assert_equal('some body', result['body'])
  69. assert_equal('text/plain', result['content_type'])
  70. assert_equal(@agent.id, result['updated_by_id'])
  71. assert_equal(@agent.id, result['created_by_id'])
  72. ticket = Ticket.find(result['ticket_id'])
  73. assert_equal(2, ticket.articles.count)
  74. assert_equal(0, ticket.articles[0].attachments.count)
  75. assert_equal(0, ticket.articles[1].attachments.count)
  76. params = {
  77. ticket_id: result['ticket_id'],
  78. content_type: 'text/html', # or text/html
  79. body: 'some body <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
  80. AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
  81. 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />',
  82. type: 'note',
  83. }
  84. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  85. assert_response(201)
  86. result = JSON.parse(@response.body)
  87. assert_equal(Hash, result.class)
  88. assert_nil(result['subject'])
  89. assert_no_match(/some body <img src="cid:.+?/, result['body'])
  90. assert_match(%r{some body <img src="/api/v1/ticket_attachment/.+?" alt="Red dot"}, result['body'])
  91. assert_equal('text/html', result['content_type'])
  92. assert_equal(@agent.id, result['updated_by_id'])
  93. assert_equal(@agent.id, result['created_by_id'])
  94. assert_equal(3, ticket.articles.count)
  95. assert_equal(0, ticket.articles[0].attachments.count)
  96. assert_equal(0, ticket.articles[1].attachments.count)
  97. assert_equal(1, ticket.articles[2].attachments.count)
  98. assert(ticket.articles[2].attachments[0]['id'])
  99. assert_equal('image1.png', ticket.articles[2].attachments[0]['filename'])
  100. assert_equal('21', ticket.articles[2].attachments[0]['size'])
  101. assert_equal('image/png', ticket.articles[2].attachments[0]['preferences']['Mime-Type'])
  102. assert_equal('inline', ticket.articles[2].attachments[0]['preferences']['Content-Disposition'])
  103. assert_match(/@zammad.example.com/, ticket.articles[2].attachments[0]['preferences']['Content-ID'])
  104. params = {
  105. ticket_id: result['ticket_id'],
  106. content_type: 'text/html', # or text/html
  107. body: 'some body',
  108. type: 'note',
  109. attachments: [
  110. 'filename' => 'some_file.txt',
  111. 'data' => 'dGVzdCAxMjM=',
  112. 'mime-type' => 'text/plain',
  113. ],
  114. }
  115. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  116. assert_response(201)
  117. result = JSON.parse(@response.body)
  118. assert_equal(Hash, result.class)
  119. assert_nil(result['subject'])
  120. assert_equal('some body', result['body'])
  121. assert_equal('text/html', result['content_type'])
  122. assert_equal(@agent.id, result['updated_by_id'])
  123. assert_equal(@agent.id, result['created_by_id'])
  124. assert_equal(4, ticket.articles.count)
  125. assert_equal(0, ticket.articles[0].attachments.count)
  126. assert_equal(0, ticket.articles[1].attachments.count)
  127. assert_equal(1, ticket.articles[2].attachments.count)
  128. assert_equal(1, ticket.articles[3].attachments.count)
  129. get "/api/v1/ticket_articles/#{result['id']}?expand=true", params: {}.to_json, headers: @headers.merge('Authorization' => credentials)
  130. assert_response(200)
  131. result = JSON.parse(@response.body)
  132. assert_equal(Hash, result.class)
  133. assert_equal(1, result['attachments'].count)
  134. assert(result['attachments'][0]['id'])
  135. assert_equal('some_file.txt', result['attachments'][0]['filename'])
  136. assert_equal('8', result['attachments'][0]['size'])
  137. assert_equal('text/plain', result['attachments'][0]['preferences']['Mime-Type'])
  138. params = {
  139. ticket_id: result['ticket_id'],
  140. content_type: 'text/plain',
  141. body: 'some body',
  142. type: 'note',
  143. preferences: {
  144. some_key1: 123,
  145. },
  146. }
  147. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  148. assert_response(201)
  149. result = JSON.parse(@response.body)
  150. assert_equal(Hash, result.class)
  151. assert_nil(result['subject'])
  152. assert_equal('some body', result['body'])
  153. assert_equal('text/plain', result['content_type'])
  154. assert_equal(@agent.id, result['updated_by_id'])
  155. assert_equal(@agent.id, result['created_by_id'])
  156. assert_equal(123, result['preferences']['some_key1'])
  157. assert_equal(5, ticket.articles.count)
  158. params = {
  159. body: 'some body 2',
  160. preferences: {
  161. some_key2: 'abc',
  162. },
  163. }
  164. put "/api/v1/ticket_articles/#{result['id']}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  165. assert_response(200)
  166. result = JSON.parse(@response.body)
  167. assert_equal(Hash, result.class)
  168. assert_nil(result['subject'])
  169. assert_equal('some body 2', result['body'])
  170. assert_equal('text/plain', result['content_type'])
  171. assert_equal(@agent.id, result['updated_by_id'])
  172. assert_equal(@agent.id, result['created_by_id'])
  173. assert_equal(123, result['preferences']['some_key1'])
  174. assert_equal('abc', result['preferences']['some_key2'])
  175. end
  176. test '02.01 ticket create with customer and articles' do
  177. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-customer1@example.com', 'customer1pw')
  178. params = {
  179. title: 'a new ticket #2',
  180. group: 'Users',
  181. article: {
  182. body: 'some body',
  183. }
  184. }
  185. post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  186. assert_response(201)
  187. result = JSON.parse(@response.body)
  188. params = {
  189. ticket_id: result['id'],
  190. content_type: 'text/plain', # or text/html
  191. body: 'some body',
  192. type: 'note',
  193. }
  194. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  195. assert_response(201)
  196. result = JSON.parse(@response.body)
  197. assert_equal(Hash, result.class)
  198. assert_nil(result['subject'])
  199. assert_equal('some body', result['body'])
  200. assert_equal('text/plain', result['content_type'])
  201. assert_equal(@customer_without_org.id, result['updated_by_id'])
  202. assert_equal(@customer_without_org.id, result['created_by_id'])
  203. ticket = Ticket.find(result['ticket_id'])
  204. assert_equal(2, ticket.articles.count)
  205. assert_equal('Customer', ticket.articles[1].sender.name)
  206. assert_equal(0, ticket.articles[0].attachments.count)
  207. assert_equal(0, ticket.articles[1].attachments.count)
  208. params = {
  209. ticket_id: result['ticket_id'],
  210. content_type: 'text/plain', # or text/html
  211. body: 'some body',
  212. sender: 'Agent',
  213. type: 'note',
  214. }
  215. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  216. assert_response(201)
  217. result = JSON.parse(@response.body)
  218. assert_equal(Hash, result.class)
  219. assert_nil(result['subject'])
  220. assert_equal('some body', result['body'])
  221. assert_equal('text/plain', result['content_type'])
  222. assert_equal(@customer_without_org.id, result['updated_by_id'])
  223. assert_equal(@customer_without_org.id, result['created_by_id'])
  224. ticket = Ticket.find(result['ticket_id'])
  225. assert_equal(3, ticket.articles.count)
  226. assert_equal('Customer', ticket.articles[2].sender.name)
  227. assert_equal(false, ticket.articles[2].internal)
  228. assert_equal(0, ticket.articles[0].attachments.count)
  229. assert_equal(0, ticket.articles[1].attachments.count)
  230. assert_equal(0, ticket.articles[2].attachments.count)
  231. params = {
  232. ticket_id: result['ticket_id'],
  233. content_type: 'text/plain', # or text/html
  234. body: 'some body 2',
  235. sender: 'Agent',
  236. type: 'note',
  237. internal: true,
  238. }
  239. post '/api/v1/ticket_articles', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  240. assert_response(201)
  241. result = JSON.parse(@response.body)
  242. assert_equal(Hash, result.class)
  243. assert_nil(result['subject'])
  244. assert_equal('some body 2', result['body'])
  245. assert_equal('text/plain', result['content_type'])
  246. assert_equal(@customer_without_org.id, result['updated_by_id'])
  247. assert_equal(@customer_without_org.id, result['created_by_id'])
  248. ticket = Ticket.find(result['ticket_id'])
  249. assert_equal(4, ticket.articles.count)
  250. assert_equal('Customer', ticket.articles[3].sender.name)
  251. assert_equal(false, ticket.articles[3].internal)
  252. assert_equal(0, ticket.articles[0].attachments.count)
  253. assert_equal(0, ticket.articles[1].attachments.count)
  254. assert_equal(0, ticket.articles[2].attachments.count)
  255. assert_equal(0, ticket.articles[3].attachments.count)
  256. # add internal article
  257. article = Ticket::Article.create!(
  258. ticket_id: ticket.id,
  259. from: 'some_sender@example.com',
  260. to: 'some_recipient@example.com',
  261. subject: 'some subject',
  262. message_id: 'some@id',
  263. body: 'some message 123',
  264. internal: true,
  265. sender: Ticket::Article::Sender.find_by(name: 'Agent'),
  266. type: Ticket::Article::Type.find_by(name: 'note'),
  267. updated_by_id: 1,
  268. created_by_id: 1,
  269. )
  270. assert_equal(5, ticket.articles.count)
  271. assert_equal('Agent', ticket.articles[4].sender.name)
  272. assert_equal(1, ticket.articles[4].updated_by_id)
  273. assert_equal(1, ticket.articles[4].created_by_id)
  274. assert_equal(0, ticket.articles[0].attachments.count)
  275. assert_equal(0, ticket.articles[1].attachments.count)
  276. assert_equal(0, ticket.articles[2].attachments.count)
  277. assert_equal(0, ticket.articles[3].attachments.count)
  278. assert_equal(0, ticket.articles[4].attachments.count)
  279. get "/api/v1/ticket_articles/#{article.id}", params: {}.to_json, headers: @headers.merge('Authorization' => credentials)
  280. assert_response(401)
  281. result = JSON.parse(@response.body)
  282. assert_equal(Hash, result.class)
  283. assert_equal('Not authorized', result['error'])
  284. put "/api/v1/ticket_articles/#{article.id}", params: { internal: false }.to_json, headers: @headers.merge('Authorization' => credentials)
  285. assert_response(401)
  286. result = JSON.parse(@response.body)
  287. assert_equal(Hash, result.class)
  288. assert_equal('Not authorized', result['error'])
  289. end
  290. test '03.01 create phone ticket for customer and expected origin_by_id' do
  291. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
  292. params = {
  293. title: 'a new ticket #1',
  294. group: 'Users',
  295. customer_id: @customer_without_org.id,
  296. article: {
  297. body: 'some body',
  298. sender: 'Customer',
  299. type: 'phone',
  300. }
  301. }
  302. post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  303. assert_response(201)
  304. result = JSON.parse(@response.body)
  305. assert_equal(Hash, result.class)
  306. assert_equal('a new ticket #1', result['title'])
  307. article = Ticket::Article.find_by(ticket_id: result['id'])
  308. assert_equal(@customer_without_org.id, article.origin_by_id)
  309. assert_equal('Tickets Customer1 <tickets-customer1@example.com>', article.from)
  310. end
  311. test '03.02 create phone ticket by customer and manipulate origin_by_id' do
  312. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-customer1@example.com', 'customer1pw')
  313. params = {
  314. title: 'a new ticket #1',
  315. group: 'Users',
  316. customer_id: @customer_without_org.id,
  317. article: {
  318. body: 'some body',
  319. sender: 'Customer',
  320. type: 'phone',
  321. origin_by_id: 1,
  322. }
  323. }
  324. post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  325. assert_response(201)
  326. result = JSON.parse(@response.body)
  327. assert_equal(Hash, result.class)
  328. article = Ticket::Article.find_by(ticket_id: result['id'])
  329. assert_equal(@customer_without_org.id, article.origin_by_id)
  330. end
  331. test '04.01 ticket split with html - check attachments' do
  332. ticket = Ticket.create!(
  333. title: 'some title',
  334. group: Group.lookup(name: 'Users'),
  335. customer_id: @customer_without_org.id,
  336. state: Ticket::State.lookup(name: 'new'),
  337. priority: Ticket::Priority.lookup(name: '2 normal'),
  338. updated_by_id: @agent.id,
  339. created_by_id: @agent.id,
  340. )
  341. article = Ticket::Article.create!(
  342. type: Ticket::Article::Type.lookup(name: 'note'),
  343. sender: Ticket::Article::Sender.lookup(name: 'Customer'),
  344. from: 'sender',
  345. subject: 'subject',
  346. body: '<b>test</b> <img src="cid:15.274327094.140938@ZAMMAD.example.com"/> test <img src="cid:15.274327094.140938.3@ZAMMAD.example.com"/>',
  347. content_type: 'text/html',
  348. ticket_id: ticket.id,
  349. updated_by_id: 1,
  350. created_by_id: 1,
  351. )
  352. Store.add(
  353. object: 'Ticket::Article',
  354. o_id: article.id,
  355. data: 'content_file1_normally_should_be_an_image',
  356. filename: 'some_file1.jpg',
  357. preferences: {
  358. 'Content-Type' => 'image/jpeg',
  359. 'Mime-Type' => 'image/jpeg',
  360. 'Content-ID' => '15.274327094.140938@zammad.example.com',
  361. 'Content-Disposition' => 'inline',
  362. },
  363. created_by_id: 1,
  364. )
  365. Store.add(
  366. object: 'Ticket::Article',
  367. o_id: article.id,
  368. data: 'content_file2_normally_should_be_an_image',
  369. filename: 'some_file2.jpg',
  370. preferences: {
  371. 'Content-Type' => 'image/jpeg',
  372. 'Mime-Type' => 'image/jpeg',
  373. 'Content-ID' => '15.274327094.140938.2@zammad.example.com',
  374. 'Content-Disposition' => 'inline',
  375. },
  376. created_by_id: 1,
  377. )
  378. Store.add(
  379. object: 'Ticket::Article',
  380. o_id: article.id,
  381. data: 'content_file3_normally_should_be_an_image',
  382. filename: 'some_file3.jpg',
  383. preferences: {
  384. 'Content-Type' => 'image/jpeg',
  385. 'Mime-Type' => 'image/jpeg',
  386. 'Content-ID' => '15.274327094.140938.3@zammad.example.com',
  387. },
  388. created_by_id: 1,
  389. )
  390. Store.add(
  391. object: 'Ticket::Article',
  392. o_id: article.id,
  393. data: 'content_file4_normally_should_be_an_image',
  394. filename: 'some_file4.jpg',
  395. preferences: {
  396. 'Content-Type' => 'image/jpeg',
  397. 'Mime-Type' => 'image/jpeg',
  398. 'Content-ID' => '15.274327094.140938.4@zammad.example.com',
  399. },
  400. created_by_id: 1,
  401. )
  402. Store.add(
  403. object: 'Ticket::Article',
  404. o_id: article.id,
  405. data: 'content_file1_normally_should_be_an_pdf',
  406. filename: 'Rechnung_RE-2018-200.pdf',
  407. preferences: {
  408. 'Content-Type' => 'application/octet-stream; name="Rechnung_RE-2018-200.pdf"',
  409. 'Mime-Type' => 'application/octet-stream',
  410. 'Content-ID' => '8AB0BEC88984EE4EBEF643C79C8E0346@zammad.example.com',
  411. 'Content-Description' => 'Rechnung_RE-2018-200.pdf',
  412. 'Content-Disposition' => 'attachment',
  413. },
  414. created_by_id: 1,
  415. )
  416. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
  417. params = {
  418. form_id: 'new_form_id123',
  419. }
  420. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  421. assert_response(200)
  422. result = JSON.parse(@response.body)
  423. assert_equal(Hash, result.class)
  424. assert(result['attachments'])
  425. assert_equal(result['attachments'].count, 3)
  426. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  427. assert_response(200)
  428. result = JSON.parse(@response.body)
  429. assert_equal(Hash, result.class)
  430. assert(result['attachments'])
  431. assert_equal(result['attachments'].count, 0)
  432. end
  433. test '04.02 ticket split with plain - check attachments' do
  434. ticket = Ticket.create!(
  435. title: 'some title',
  436. group: Group.lookup(name: 'Users'),
  437. customer_id: @customer_without_org.id,
  438. state: Ticket::State.lookup(name: 'new'),
  439. priority: Ticket::Priority.lookup(name: '2 normal'),
  440. updated_by_id: @agent.id,
  441. created_by_id: @agent.id,
  442. )
  443. article = Ticket::Article.create!(
  444. type: Ticket::Article::Type.lookup(name: 'note'),
  445. sender: Ticket::Article::Sender.lookup(name: 'Customer'),
  446. from: 'sender',
  447. subject: 'subject',
  448. body: '<b>test</b> <img src="cid:15.274327094.140938@zammad.example.com"/>',
  449. content_type: 'text/plain',
  450. ticket_id: ticket.id,
  451. updated_by_id: 1,
  452. created_by_id: 1,
  453. )
  454. Store.add(
  455. object: 'Ticket::Article',
  456. o_id: article.id,
  457. data: 'content_file1_normally_should_be_an_image',
  458. filename: 'some_file1.jpg',
  459. preferences: {
  460. 'Content-Type' => 'image/jpeg',
  461. 'Mime-Type' => 'image/jpeg',
  462. 'Content-ID' => '15.274327094.140938@zammad.example.com',
  463. 'Content-Disposition' => 'inline',
  464. },
  465. created_by_id: 1,
  466. )
  467. Store.add(
  468. object: 'Ticket::Article',
  469. o_id: article.id,
  470. data: 'content_file1_normally_should_be_an_image',
  471. filename: 'some_file2.jpg',
  472. preferences: {
  473. 'Content-Type' => 'image/jpeg',
  474. 'Mime-Type' => 'image/jpeg',
  475. 'Content-ID' => '15.274327094.140938.2@zammad.example.com',
  476. 'Content-Disposition' => 'inline',
  477. },
  478. created_by_id: 1,
  479. )
  480. Store.add(
  481. object: 'Ticket::Article',
  482. o_id: article.id,
  483. data: 'content_file1_normally_should_be_an_pdf',
  484. filename: 'Rechnung_RE-2018-200.pdf',
  485. preferences: {
  486. 'Content-Type' => 'application/octet-stream; name="Rechnung_RE-2018-200.pdf"',
  487. 'Mime-Type' => 'application/octet-stream',
  488. 'Content-ID' => '8AB0BEC88984EE4EBEF643C79C8E0346@zammad.example.com',
  489. 'Content-Description' => 'Rechnung_RE-2018-200.pdf',
  490. 'Content-Disposition' => 'attachment',
  491. },
  492. created_by_id: 1,
  493. )
  494. credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
  495. params = {
  496. form_id: 'new_form_id123',
  497. }
  498. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  499. assert_response(200)
  500. result = JSON.parse(@response.body)
  501. assert_equal(Hash, result.class)
  502. assert(result['attachments'])
  503. assert_equal(result['attachments'].count, 3)
  504. post "/api/v1/ticket_attachment_upload_clone_by_article/#{article.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
  505. assert_response(200)
  506. result = JSON.parse(@response.body)
  507. assert_equal(Hash, result.class)
  508. assert(result['attachments'])
  509. assert_equal(result['attachments'].count, 0)
  510. end
  511. end