attachments_spec.rb 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Gql::Queries::Ticket::Attachments, authenticated_as: :user, type: :graphql do
  4. let(:query) do
  5. <<~QUERY
  6. query ticketAttachments($ticketId: ID!) {
  7. ticketAttachments(ticketId: $ticketId) {
  8. id
  9. internalId
  10. name
  11. size
  12. type
  13. preferences
  14. }
  15. }
  16. QUERY
  17. end
  18. let(:ticket) { create(:ticket) }
  19. let(:cid) { "#{SecureRandom.uuid}@zammad.example.com" }
  20. let(:attachment_file_type) { 'image/jpeg' }
  21. let(:attachment_content_type) { attachment_file_type }
  22. let(:attachment_mime_type) { attachment_file_type }
  23. let(:articles) do
  24. create_list(:ticket_article, 2, ticket: ticket, content_type: 'text/html', body: "<img src=\"cid:#{cid}\"> some text") do |article, _i|
  25. create(
  26. :store,
  27. object: 'Ticket::Article',
  28. o_id: article.id,
  29. data: 'fake',
  30. filename: 'inline_image.jpg',
  31. preferences: {
  32. 'Content-Type' => attachment_content_type,
  33. 'Mime-Type' => attachment_mime_type,
  34. 'Content-ID' => "<#{cid}>",
  35. 'Content-Disposition' => 'inline',
  36. }
  37. )
  38. create(
  39. :store,
  40. object: 'Ticket::Article',
  41. o_id: article.id,
  42. data: 'fake',
  43. filename: 'attached_image.jpg',
  44. preferences: {
  45. 'Content-Type' => attachment_content_type,
  46. 'Mime-Type' => attachment_mime_type,
  47. 'Content-ID' => "<#{cid}.not.referenced>",
  48. }
  49. )
  50. end
  51. end
  52. let(:variables) { { ticketId: gql.id(ticket) } }
  53. context 'when an agent is fetching ticket attachments' do
  54. let(:user) { create(:agent, groups: [ticket.group]) }
  55. before do
  56. articles
  57. gql.execute(query, variables: variables)
  58. end
  59. it 'returns the ticket attachments' do
  60. expect(gql.result.data).to include(hash_including(
  61. 'id' => gql.id(articles.first.attachments.last),
  62. 'internalId' => articles.first.attachments.last.id,
  63. 'name' => 'attached_image.jpg',
  64. 'type' => attachment_file_type,
  65. ))
  66. end
  67. context 'when the attachment has mime type only' do
  68. let(:attachment_content_type) { nil }
  69. it 'returns inferred attachment file type' do
  70. expect(gql.result.data).to include(hash_including(
  71. 'type' => attachment_file_type,
  72. ))
  73. end
  74. end
  75. context 'when the ticket is in a group the agent is not a member of' do
  76. let(:user) { create(:agent, groups: []) }
  77. it 'returns an error' do
  78. expect(gql.result.error_type).to eq(Exceptions::Forbidden)
  79. end
  80. end
  81. end
  82. context 'when a customer is fetching ticket attachments' do
  83. let(:user) { create(:customer) }
  84. context 'when no access to the ticket' do
  85. before do
  86. articles
  87. gql.execute(query, variables: variables)
  88. end
  89. it 'returns an error' do
  90. expect(gql.result.error_type).to eq(Exceptions::Forbidden)
  91. end
  92. end
  93. context 'when access to the ticket' do
  94. context 'when all articles are public' do
  95. before do
  96. ticket.update!(customer: user)
  97. articles.each { |article| article.update!(internal: false) }
  98. gql.execute(query, variables: variables)
  99. end
  100. it 'returns the ticket attachments' do
  101. expect(gql.result.data).to include(hash_including(
  102. 'id' => gql.id(articles.first.attachments.last),
  103. 'internalId' => articles.first.attachments.last.id,
  104. 'name' => 'attached_image.jpg',
  105. ))
  106. end
  107. end
  108. context 'when some articles are internal' do
  109. before do
  110. ticket.update!(customer: user)
  111. articles.each { |article| article.update!(internal: true) }
  112. gql.execute(query, variables: variables)
  113. end
  114. it 'returns the ticket attachments (empty)' do
  115. expect(gql.result.data).to eq([])
  116. end
  117. end
  118. end
  119. end
  120. context 'when not authenticated' do
  121. let(:user) { nil }
  122. before do
  123. gql.execute(query, variables: variables)
  124. end
  125. it_behaves_like 'graphql responds with error if unauthenticated'
  126. end
  127. end