create_spec.rb 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Service::Ticket::Article::Create, current_user_id: -> { user.id } do
  4. subject(:service) { described_class.new(current_user: user) }
  5. let(:ticket) { create(:ticket, customer: create(:agent)) }
  6. let(:user) { create(:agent, groups: [ticket.group]) }
  7. let(:payload) { { body: 'test' } }
  8. let(:article) { service.execute(article_data: payload, ticket: ticket) }
  9. describe '#execute' do
  10. it 'creates an article' do
  11. expect(article).to be_persisted
  12. end
  13. it 'creates an article even if contains wrong ticket id' do
  14. payload[:ticket_id] = 123_456
  15. expect(article).to be_persisted.and(have_attributes(ticket_id: ticket.id))
  16. end
  17. describe 'time accounting' do
  18. let(:time_accounting_enabled) { true }
  19. before do
  20. Setting.set('time_accounting', time_accounting_enabled)
  21. payload[:time_unit] = 60
  22. end
  23. it 'adds time accounting if present' do
  24. expect(article.ticket_time_accounting).to be_present
  25. end
  26. context 'when time accounting is not enabled' do
  27. let(:time_accounting_enabled) { false }
  28. it 'does not save article and raises error' do
  29. expect { article }
  30. .to raise_error(%r{Time Accounting is not enabled})
  31. end
  32. end
  33. end
  34. describe 'to and cc fields processing' do
  35. it 'translates to and cc fields from arrays to strings' do
  36. payload.merge!({ to: %w[a b], cc: %w[b c] })
  37. expect(article).to have_attributes(to: 'a, b', cc: 'b, c')
  38. end
  39. it 'handles string and nil values' do
  40. payload.merge!({ to: 'a,b', cc: nil })
  41. expect(article).to have_attributes(to: 'a,b', cc: '')
  42. end
  43. end
  44. describe 'sender processing' do
  45. context 'when user is agent' do
  46. it 'agent is set to agent' do
  47. expect(article.sender.name).to eq 'Agent'
  48. end
  49. it 'preserves original value if given' do
  50. payload[:sender] = 'Customer'
  51. expect(article.sender.name).to eq 'Customer'
  52. end
  53. end
  54. context 'when user is customer' do
  55. let(:user) { ticket.customer }
  56. let(:ticket) { create(:ticket, customer: create(:customer)) }
  57. it 'ensures sender is set to customer' do
  58. expect(article.sender.name).to eq 'Customer'
  59. end
  60. end
  61. # Agent-Customer is incorrectly detected as Agent in a group he has no access to
  62. # https://github.com/zammad/zammad/issues/4649
  63. context 'when user is agent-customer' do
  64. let(:user) { ticket.customer }
  65. it 'ensures sender is set to customer' do
  66. expect(article.sender.name).to eq 'Agent'
  67. end
  68. end
  69. end
  70. describe 'processing for customer' do
  71. context 'when user is customer' do
  72. let(:user) { ticket.customer }
  73. let(:ticket) { create(:ticket, customer: create(:customer)) }
  74. it 'ensures internal is false' do
  75. payload[:internal] = true
  76. expect(article.internal).to be_falsey
  77. end
  78. it 'changes type from web to note' do
  79. payload[:type] = 'phone'
  80. expect(article.type.name).to eq('note')
  81. end
  82. end
  83. # Agent-Customer is incorrectly detected as Agent in a group he has no access to
  84. # https://github.com/zammad/zammad/issues/4649
  85. context 'when user is agent-customer' do
  86. let(:user) { ticket.customer }
  87. it 'ensures internal is false' do
  88. payload[:internal] = false
  89. expect(article.internal).to be_falsey
  90. end
  91. it 'changes type from web to note' do
  92. payload[:type] = 'phone'
  93. expect(article.type.name).to eq('phone')
  94. end
  95. end
  96. context 'when user is agent' do
  97. it 'allows internal to be true' do
  98. payload[:internal] = true
  99. expect(article.internal).to be_truthy
  100. end
  101. it 'applies no changes to type' do
  102. payload[:type] = 'phone'
  103. expect(article.type.name).to eq('phone')
  104. end
  105. end
  106. end
  107. describe 'transforming attachments' do
  108. it 'adds attachments with inlines' do
  109. payload[:content_type] = 'text/html'
  110. payload[:body] = 'some body <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
  111. AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
  112. 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />'
  113. expect(article.attachments).to be_one
  114. end
  115. end
  116. describe 'mentions', aggregate_failures: true do
  117. def text_blob_with(user)
  118. "Lorem ipsum dolor <a data-mention-user-id='#{user.id}'>#{user.fullname}</a>"
  119. end
  120. let(:payload) { { body: body } }
  121. context 'when author can mention other users' do
  122. context 'when valid user is mentioned' do
  123. let(:body) { text_blob_with(user) }
  124. it 'create ticket with mentions' do
  125. expect { article }.to change(Mention, :count).by(1)
  126. end
  127. end
  128. context 'when user without access to the ticket is mentioned' do
  129. let(:body) { text_blob_with(create(:agent)) }
  130. it 'raises an error with one of mentions being invalid' do
  131. expect { article }
  132. .to raise_error(ActiveRecord::RecordInvalid)
  133. expect(Mention.count).to eq(0)
  134. end
  135. end
  136. end
  137. context 'when author does not have permissions to create mentions' do
  138. let(:user) { create(:customer) }
  139. let(:body) { text_blob_with(create(:agent, groups: [ticket.group])) }
  140. it 'raise an error if author does not have permissions to create mentions' do
  141. expect { article }
  142. .to raise_error(Pundit::NotAuthorizedError)
  143. expect(Mention.count).to eq(0)
  144. end
  145. end
  146. end
  147. end
  148. end