mattermost_spec.rb 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Webhook > Mattermost', integration: true, performs_jobs: true, required_envs: %w[MATTERMOST_URL MATTERMOST_USER MATTERMOST_PASSWORD MATTERMOST_CHANNEL], time_zone: 'Europe/London' do # rubocop:disable RSpec/DescribeClass
  4. # Shared/persistent variables
  5. mattermost_hook_initialized = false
  6. mattermost_access_token = ''
  7. mattermost_zammad_channel = nil
  8. zammad_webhook = nil
  9. let(:zammad_base_url) { "#{Capybara.app_host}:#{Capybara.current_session.server.port}" }
  10. let(:mattermost_url) { ENV['MATTERMOST_URL'] }
  11. let(:mattermost_api_url) { "#{mattermost_url}/api/v4" }
  12. let(:mattermost_auth_header) { { Authorization: "Bearer #{mattermost_access_token}" } }
  13. let(:mattermost_default_headers) { { headers: mattermost_auth_header, json: true } }
  14. let(:mattermost_endpoints) do
  15. {
  16. auth: "#{mattermost_api_url}/users/login",
  17. channel_list: "#{mattermost_api_url}/channels",
  18. incoming_hooks: "#{mattermost_api_url}/hooks/incoming",
  19. hooks: "#{mattermost_url}/hooks",
  20. }
  21. end
  22. let(:mattermost_payloads) do
  23. {
  24. auth: { login_id: ENV['MATTERMOST_USER'], password: ENV['MATTERMOST_PASSWORD'] },
  25. incoming_hooks: { display_name: 'Zammad', description: 'Incoming webhook for Zammad' },
  26. }
  27. end
  28. before do
  29. next if mattermost_hook_initialized
  30. # Get auth token.
  31. auth_response = UserAgent.post(mattermost_endpoints[:auth], mattermost_payloads[:auth], { json: true })
  32. raise 'Authentication failed' if !auth_response.success?
  33. mattermost_access_token = auth_response.header['token']
  34. raise 'No access_token found' if mattermost_access_token.blank?
  35. # Get channel id.
  36. channel_response = UserAgent.get(mattermost_endpoints[:channel_list], {}, mattermost_default_headers)
  37. raise 'No channel found' if !channel_response.success? || channel_response.data.blank?
  38. mattermost_zammad_channel = channel_response.data.find { |channel| channel['name'].eql?(ENV['MATTERMOST_CHANNEL']) }
  39. raise 'No channel found' if mattermost_zammad_channel.nil?
  40. # Create incoming webhook.
  41. incoming_webhook_response = UserAgent.post(mattermost_endpoints[:incoming_hooks], mattermost_payloads[:incoming_hooks].merge(channel_id: mattermost_zammad_channel['id']), mattermost_default_headers)
  42. raise 'No incoming webhook found' if !incoming_webhook_response.success?
  43. webhook_id = incoming_webhook_response.data['id']
  44. raise 'No incoming webhook found' if webhook_id.blank?
  45. zammad_webhook = create(
  46. :mattermost_webhook,
  47. endpoint: "#{mattermost_endpoints[:hooks]}/#{webhook_id}",
  48. preferences: {
  49. pre_defined_webhook: {
  50. messaging_username: Faker::Internet.unique.username,
  51. messaging_channel: mattermost_zammad_channel['name'],
  52. messaging_icon_url: Faker::Internet.unique.url,
  53. },
  54. }
  55. )
  56. mattermost_hook_initialized = true
  57. end
  58. context 'when a trigger for ticket create is used' do
  59. let(:condition) { { 'ticket.action' => { 'operator' => 'is', 'value' => 'create' } } }
  60. let(:perform) { { 'notification.webhook' => { 'webhook_id' => zammad_webhook.id.to_s } } }
  61. let(:trigger) { create(:trigger, activator: 'action', condition: condition, perform: perform) }
  62. let(:message) { "Test for Mattermost (#{SecureRandom.uuid})" }
  63. before do
  64. trigger
  65. end
  66. it 'creates a post in the related Mattermost channel', :aggregate_failures do
  67. create(:ticket, group: Group.first, title: message)
  68. perform_enqueued_jobs commit_transaction: true
  69. posts_response = UserAgent.get(
  70. "#{mattermost_api_url}/channels/#{mattermost_zammad_channel['id']}/posts",
  71. {},
  72. mattermost_default_headers
  73. )
  74. last_post_id = posts_response.data['order'].first
  75. expect(last_post_id).not_to be_nil
  76. expect(posts_response.data.dig('posts', last_post_id, 'message')).to eq("# #{message}")
  77. end
  78. end
  79. end