pop3_spec.rb 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Channel::Driver::Pop3 do
  4. before do
  5. stub_const('MockedMessage', Struct.new(:pop, :delete))
  6. allow_any_instance_of(Net::POP3)
  7. .to receive(:start)
  8. allow_any_instance_of(Net::POP3)
  9. .to receive(:finish)
  10. allow_any_instance_of(Net::POP3)
  11. .to receive(:enable_ssl)
  12. allow_any_instance_of(Net::POP3)
  13. .to receive(:mails)
  14. .and_return(message_ids)
  15. end
  16. describe '#check_configuration' do
  17. context 'when no messages exist' do
  18. let(:message_ids) { [] }
  19. it 'finds no content messages' do
  20. response = described_class
  21. .new
  22. .check_configuration({})
  23. expect(response).to include(
  24. result: 'ok',
  25. content_messages: be_zero,
  26. )
  27. end
  28. end
  29. context 'when a verify message exist' do
  30. let(:message_ids) do
  31. [
  32. MockedMessage.new(mock_a_message(verify: true)),
  33. ]
  34. end
  35. it 'finds no content messages' do
  36. response = described_class
  37. .new
  38. .check_configuration({})
  39. expect(response).to include(
  40. result: 'ok',
  41. content_messages: be_zero,
  42. )
  43. end
  44. end
  45. context 'when some content messages exist' do
  46. let(:message_ids) do
  47. [
  48. MockedMessage.new(mock_a_message),
  49. MockedMessage.new(mock_a_message),
  50. MockedMessage.new(mock_a_message),
  51. ]
  52. end
  53. it 'finds content messages' do
  54. response = described_class
  55. .new
  56. .check_configuration({})
  57. expect(response).to include(
  58. result: 'ok',
  59. content_messages: 3,
  60. )
  61. end
  62. end
  63. context 'when a verify and a content message exists' do
  64. let(:message_ids) do
  65. [
  66. MockedMessage.new(mock_a_message(verify: true)),
  67. MockedMessage.new(mock_a_message),
  68. ]
  69. end
  70. it 'finds content messages' do
  71. response = described_class
  72. .new
  73. .check_configuration({})
  74. expect(response).to include(
  75. result: 'ok',
  76. content_messages: 2,
  77. )
  78. end
  79. end
  80. end
  81. describe '#verify_transport' do
  82. let(:verify_message) { Faker::Lorem.unique.sentence }
  83. context 'when no messages exist' do
  84. let(:message_ids) { [] }
  85. it 'returns falsy response' do
  86. response = described_class
  87. .new
  88. .verify_transport({}, verify_message)
  89. expect(response).to include(result: 'verify not ok')
  90. end
  91. end
  92. context 'when a content message exists' do
  93. let(:message_ids) { [MockedMessage.new(mock_a_message)] }
  94. it 'returns falsy response' do
  95. response = described_class
  96. .new
  97. .verify_transport({}, verify_message)
  98. expect(response).to include(result: 'verify not ok')
  99. end
  100. end
  101. context 'when a verify message exists' do
  102. let(:message_ids) { [MockedMessage.new(mock_a_message(verify: verify_message))] }
  103. it 'returns truthy response with the correct verify string' do
  104. response = described_class
  105. .new
  106. .verify_transport({}, verify_message)
  107. expect(response).to include(result: 'ok')
  108. end
  109. it 'deletes the correct verify message' do
  110. allow(message_ids.first).to receive(:delete)
  111. described_class
  112. .new
  113. .verify_transport({}, verify_message)
  114. expect(message_ids.first).to have_received(:delete)
  115. end
  116. it 'returns falsy response with the wrong verify string' do
  117. response = described_class
  118. .new
  119. .verify_transport({}, 'another message')
  120. expect(response).to include(result: 'verify not ok')
  121. end
  122. it 'does not delete not matching verify message' do
  123. allow(message_ids.first).to receive(:delete)
  124. described_class
  125. .new
  126. .verify_transport({}, 'another message')
  127. expect(message_ids.first).not_to have_received(:delete)
  128. end
  129. end
  130. context 'when a content and a verify message exists' do
  131. let(:message_ids) { [MockedMessage.new(mock_a_message(verify: verify_message)), MockedMessage.new(mock_a_message)] }
  132. it 'returns truthy response' do
  133. response = described_class
  134. .new
  135. .verify_transport({}, verify_message)
  136. expect(response).to include(result: 'ok')
  137. end
  138. end
  139. end
  140. describe '#fetch', :aggregate_failures do
  141. let(:channel) { create(:email_channel, :pop3) }
  142. let(:message) { mock_a_message(subject: title) }
  143. let(:title) { Faker::Lorem.unique.sentence }
  144. let(:message_ids) { [MockedMessage.new(message)] }
  145. context 'when fetching a regular email' do
  146. it 'handles messages correctly' do
  147. expect { channel.fetch }.to change(Ticket, :count)
  148. expect(Ticket).to exist(title:)
  149. expect(channel.reload.status_in).to eq('ok')
  150. end
  151. end
  152. context 'when fetching oversized emails' do
  153. before do
  154. Setting.set('postmaster_max_size', 0.00001)
  155. end
  156. context 'with email reply' do
  157. it 'creates email reply correctly' do
  158. expect_any_instance_of(described_class).to receive(:process_oversized_mail)
  159. channel.fetch
  160. end
  161. end
  162. context 'without email reply' do
  163. before do
  164. Setting.set('postmaster_send_reject_if_mail_too_large', false)
  165. end
  166. it 'does not create email reply' do
  167. expect_any_instance_of(described_class).not_to receive(:process_oversized_mail)
  168. channel.fetch
  169. expect(channel.reload.status_in).to eq('error')
  170. end
  171. end
  172. end
  173. end
  174. def mock_a_message(subject: nil, verify: false)
  175. attrs = {
  176. from: Faker::Internet.unique.email,
  177. to: Faker::Internet.unique.email,
  178. body: Faker::Lorem.sentence,
  179. subject: verify.presence || subject.presence || Faker::Lorem.word,
  180. content_type: 'text/html',
  181. }
  182. if verify.present?
  183. attrs[:'X-Zammad-Ignore'] = 'true'
  184. attrs[:'X-Zammad-Verify'] = 'true'
  185. attrs[:'X-Zammad-Verify-Time'] = Time.current.to_s
  186. end
  187. Channel::EmailBuild.build(**attrs).to_s
  188. end
  189. end