twilio_sms_spec.rb 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Twilio SMS', performs_jobs: true, type: :request do
  4. describe 'request handling' do
  5. let(:group) { create(:group) }
  6. let(:agent) { create(:agent, groups: [group]) }
  7. let(:channel) do
  8. create(
  9. :channel,
  10. area: 'Sms::Account',
  11. options: {
  12. adapter: 'sms/twilio',
  13. webhook_token: 'secret_webhook_token',
  14. account_id: '111',
  15. token: '223',
  16. sender: '333',
  17. },
  18. group_id: group&.id,
  19. )
  20. end
  21. before do
  22. channel
  23. UserInfo.current_user_id = 1
  24. end
  25. it 'does basic call' do
  26. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms1'), as: :json
  27. expect(response).to have_http_status(:ok)
  28. xml_response = REXML::Document.new(response.body)
  29. expect(xml_response.elements.count).to eq(1)
  30. ticket = Ticket.last
  31. article = Ticket::Article.last
  32. customer = User.last
  33. expect(ticket.articles.count).to eq(1)
  34. expect(ticket.title).to eq('Ldfhxhcuffufuf. Fifififig. Fifififiif F...')
  35. expect(ticket.state.name).to eq('new')
  36. expect(ticket.group_id).to eq(group.id)
  37. expect(ticket.customer_id).to eq(customer.id)
  38. expect(ticket.created_by_id).to eq(customer.id)
  39. expect(article.from).to eq('+491710000000')
  40. expect(article.to).to eq('+4915700000000')
  41. expect(article.cc).to be_nil
  42. expect(article.subject).to be_nil
  43. expect(article.body).to eq('Ldfhxhcuffufuf. Fifififig. Fifififiif Fifififiif Fifififiif Fifififiif Fifififiif')
  44. expect(article.created_by_id).to eq(customer.id)
  45. expect(article.sender.name).to eq('Customer')
  46. expect(article.type.name).to eq('sms')
  47. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms2'), as: :json
  48. expect(response).to have_http_status(:ok)
  49. xml_response = REXML::Document.new(response.body)
  50. expect(xml_response.elements.count).to eq(1)
  51. ticket.reload
  52. expect(ticket.articles.count).to eq(2)
  53. expect(ticket.state.name).to eq('new')
  54. article = Ticket::Article.last
  55. expect(article.from).to eq('+491710000000')
  56. expect(article.to).to eq('+4915700000000')
  57. expect(article.cc).to be_nil
  58. expect(article.subject).to be_nil
  59. expect(article.body).to eq('Follow-up')
  60. expect(article.sender.name).to eq('Customer')
  61. expect(article.type.name).to eq('sms')
  62. expect(article.created_by_id).to eq(customer.id)
  63. # check duplicate callbacks
  64. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms2'), as: :json
  65. expect(response).to have_http_status(:ok)
  66. xml_response = REXML::Document.new(response.body)
  67. expect(xml_response.elements.count).to eq(1)
  68. ticket.reload
  69. expect(ticket.articles.count).to eq(2)
  70. expect(ticket.state.name).to eq('new')
  71. expect(article.id).to eq(Ticket::Article.last.id)
  72. # new ticket needs to be created
  73. ticket.state = Ticket::State.find_by(name: 'closed')
  74. ticket.save!
  75. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms3'), as: :json
  76. expect(response).to have_http_status(:ok)
  77. xml_response = REXML::Document.new(response.body)
  78. expect(xml_response.elements.count).to eq(1)
  79. ticket.reload
  80. expect(ticket.articles.count).to eq(2)
  81. expect(ticket.id).not_to eq(Ticket.last.id)
  82. expect(ticket.state.name).to eq('closed')
  83. ticket = Ticket.last
  84. article = Ticket::Article.last
  85. customer = User.last
  86. expect(ticket.articles.count).to eq(1)
  87. expect(ticket.title).to eq('new 2')
  88. expect(ticket.group_id).to eq(group.id)
  89. expect(ticket.customer_id).to eq(customer.id)
  90. expect(ticket.created_by_id).to eq(customer.id)
  91. expect(article.from).to eq('+491710000000')
  92. expect(article.to).to eq('+4915700000000')
  93. expect(article.cc).to be_nil
  94. expect(article.subject).to be_nil
  95. expect(article.body).to eq('new 2')
  96. expect(article.created_by_id).to eq(customer.id)
  97. expect(article.sender.name).to eq('Customer')
  98. expect(article.type.name).to eq('sms')
  99. # reply by agent
  100. params = {
  101. ticket_id: ticket.id,
  102. body: 'some test',
  103. type: 'sms',
  104. }
  105. authenticated_as(agent)
  106. post '/api/v1/ticket_articles', params: params, as: :json
  107. expect(response).to have_http_status(:created)
  108. expect(json_response).to be_a(Hash)
  109. expect(json_response['subject']).to be_nil
  110. expect(json_response['body']).to eq('some test')
  111. expect(json_response['content_type']).to eq('text/plain')
  112. expect(json_response['updated_by_id']).to eq(agent.id)
  113. expect(json_response['created_by_id']).to eq(agent.id)
  114. stub_request(:post, 'https://api.twilio.com/2010-04-01/Accounts/111/Messages.json')
  115. .with(
  116. body: {
  117. 'Body' => 'some test',
  118. 'From' => '333',
  119. 'To' => nil,
  120. },
  121. headers: {
  122. 'Accept' => 'application/json',
  123. 'Accept-Charset' => 'utf-8',
  124. 'Authorization' => 'Basic MTExOjIyMw==',
  125. 'Content-Type' => 'application/x-www-form-urlencoded',
  126. }
  127. ).to_return(status: 200, body: '', headers: {})
  128. expect(article.preferences[:delivery_retry]).to be_nil
  129. expect(article.preferences[:delivery_status]).to be_nil
  130. perform_enqueued_jobs commit_transaction: true
  131. article = Ticket::Article.find(json_response['id'])
  132. expect(article.preferences[:delivery_retry]).to eq(1)
  133. expect(article.preferences[:delivery_status]).to eq('success')
  134. end
  135. context 'when channel is not configured correctly' do
  136. let(:group) { nil }
  137. it 'does basic call' do
  138. # process inbound sms
  139. post '/api/v1/sms_webhook', params: read_message('inbound_sms1'), as: :json
  140. expect(response).to have_http_status(:not_found)
  141. post '/api/v1/sms_webhook/not_existing', params: read_message('inbound_sms1'), as: :json
  142. expect(response).to have_http_status(:not_found)
  143. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms1'), as: :json
  144. expect(response).to have_http_status(:unprocessable_entity)
  145. expect(json_response['error']).to eq('Can\'t use Channel::Driver::Sms::Twilio: #<Exceptions::UnprocessableEntity: Group needed in channel definition!>')
  146. end
  147. end
  148. context 'when customer is based on already existing mobile attribute' do
  149. let(:group) { Group.first }
  150. it 'does basic call' do
  151. customer = create(
  152. :customer,
  153. email: 'me@example.com',
  154. mobile: '01710000000',
  155. )
  156. perform_enqueued_jobs commit_transaction: true
  157. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms1'), as: :json
  158. expect(response).to have_http_status(:ok)
  159. xml_response = REXML::Document.new(response.body)
  160. expect(xml_response.elements.count).to eq(1)
  161. expect(customer.id).to eq(User.last.id)
  162. end
  163. end
  164. context 'when ticket has a custom attribute' do
  165. let(:group) { Group.first }
  166. it 'does basic call', db_strategy: :reset do
  167. create(:object_manager_attribute_text, :required_screen)
  168. ObjectManager::Attribute.migration_execute
  169. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms1'), as: :json
  170. expect(response).to have_http_status(:ok)
  171. end
  172. end
  173. context 'when incoming message is of an unsupported type (#5289)' do
  174. it 'does basic call' do
  175. post '/api/v1/sms_webhook/secret_webhook_token', params: read_message('inbound_sms4'), as: :json
  176. expect(response).to have_http_status(:ok)
  177. xml_response = REXML::Document.new(response.body)
  178. expect(xml_response.elements.count).to eq(1)
  179. ticket = Ticket.last
  180. article = Ticket::Article.last
  181. customer = User.last
  182. expect(ticket.articles.count).to eq(1)
  183. expect(ticket.title).to eq('')
  184. expect(ticket.state.name).to eq('new')
  185. expect(ticket.group_id).to eq(group.id)
  186. expect(ticket.customer_id).to eq(customer.id)
  187. expect(ticket.created_by_id).to eq(customer.id)
  188. expect(article.from).to eq('+491710000000')
  189. expect(article.to).to eq('+4915700000000')
  190. expect(article.cc).to be_nil
  191. expect(article.subject).to be_nil
  192. expect(article.body).to eq('')
  193. expect(article.created_by_id).to eq(customer.id)
  194. expect(article.sender.name).to eq('Customer')
  195. expect(article.type.name).to eq('sms')
  196. end
  197. end
  198. def read_message(file)
  199. JSON.parse(Rails.root.join('test', 'data', 'twilio', "#{file}.json").read)
  200. end
  201. end
  202. end