channels_whatsapp_spec.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'WhatsApp channel webhook endpoints', aggregate_failures: true, type: :request do
  4. let(:channel) { create(:whatsapp_channel) }
  5. describe 'GET /api/v1/channels_whatsapp_webhook/:callback_url_uuid' do
  6. let(:hub_mode) { 'subscribe' }
  7. let(:params) do
  8. {
  9. 'hub.mode': hub_mode,
  10. 'hub.challenge': '123',
  11. 'hub.verify_token': channel.options[:verify_token],
  12. }
  13. end
  14. context 'when no channel exists' do
  15. it 'returns 422' do
  16. get "/api/v1/channels_whatsapp_webhook/1337#{Faker::Number.unique.number(digits: 15)}", params: params
  17. expect(response).to have_http_status(:unprocessable_entity)
  18. end
  19. end
  20. context 'when everything is valid' do
  21. it 'returns the challenge' do
  22. get "/api/v1/channels_whatsapp_webhook/#{channel.options[:callback_url_uuid]}", params: params
  23. expect(response).to have_http_status(:ok)
  24. expect(response.body).to eq('123')
  25. end
  26. end
  27. end
  28. describe 'POST /api/v1/channels_whatsapp_webhook' do
  29. let(:from) do
  30. {
  31. phone: Faker::PhoneNumber.cell_phone_in_e164.delete('+'),
  32. name: Faker::Name.unique.name
  33. }
  34. end
  35. let(:json) do
  36. {
  37. object: 'whatsapp_business_account',
  38. entry: [{
  39. id: '222259550976437',
  40. changes: [{
  41. value: {
  42. messaging_product: 'whatsapp',
  43. metadata: {
  44. display_phone_number: '15551340563',
  45. phone_number_id: channel.options[:phone_number_id]
  46. },
  47. contacts: [{
  48. profile: {
  49. name: from[:name]
  50. },
  51. wa_id: from[:phone]
  52. }],
  53. messages: [{
  54. from: from[:phone],
  55. id: 'wamid.HBgNNDkxNTE1NjA4MDY5OBUCABIYFjNFQjBDMUM4M0I5NDRFNThBMUQyMjYA',
  56. timestamp: '1707921703',
  57. text: {
  58. body: 'Hello, world!'
  59. },
  60. type: 'text'
  61. }]
  62. },
  63. field: 'messages'
  64. }]
  65. }]
  66. }.to_json
  67. end
  68. let(:signature) do
  69. OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), channel.options[:app_secret], json)
  70. end
  71. context 'when payload validation fails' do
  72. let(:signature) { 'invalid' }
  73. it 'returns 422' do
  74. post "/api/v1/channels_whatsapp_webhook/#{channel.options[:callback_url_uuid]}", headers: { 'X-Hub-Signature-256': "sha256=#{signature}" }, params: json
  75. expect(response).to have_http_status(:unprocessable_entity)
  76. end
  77. end
  78. context 'when everything is valid' do
  79. it 'returns 200' do
  80. post "/api/v1/channels_whatsapp_webhook/#{channel.options[:callback_url_uuid]}", headers: { 'X-Hub-Signature-256': "sha256=#{signature}" }, params: json
  81. expect(response).to have_http_status(:ok)
  82. end
  83. end
  84. end
  85. end