slack_spec.rb 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. require 'slack-ruby-client' # Only load this gem when it is really used.
  4. CHANNEL_NAME = ENV['SLACK_CI_CHANNEL_NAME']
  5. OAUTH_TOKEN = ENV['SLACK_CI_OAUTH_TOKEN']
  6. WEBHOOK_URL = ENV['SLACK_CI_WEBHOOK_URL']
  7. RSpec.describe 'Slack Integration', integration: true, performs_jobs: true, required_envs: %w[SLACK_CI_CHANNEL_NAME SLACK_CI_OAUTH_TOKEN SLACK_CI_WEBHOOK_URL], time_zone: 'Europe/London', use_vcr: true do # rubocop:disable RSpec/DescribeClass
  8. let(:slack_group) { create(:group) }
  9. let(:types) { %w[create update reminder_reached] }
  10. let(:items) do
  11. [
  12. {
  13. group_ids: [slack_group.id],
  14. types: types,
  15. webhook: WEBHOOK_URL,
  16. channel: CHANNEL_NAME,
  17. username: 'zammad_agent',
  18. expand: false,
  19. }
  20. ]
  21. end
  22. let(:group) { slack_group }
  23. let(:customer) { create(:customer) }
  24. let(:state_name) { 'new' }
  25. let(:ticket) { create(:ticket, customer: customer, group: group, title: message, state_name: state_name) }
  26. let(:article) { create(:ticket_article, :outbound_note, ticket: ticket, body: message, sender_name: 'Customer', from: customer.fullname) }
  27. before :all do # rubocop:disable RSpec/BeforeAfterAll
  28. delete_all_test_chat_messages if live_mode?
  29. end
  30. before do
  31. Setting.set('slack_integration', true)
  32. Setting.set('slack_config', { items: items })
  33. ticket && article
  34. perform_enqueued_jobs commit_transaction: true
  35. end
  36. context 'with default group' do
  37. let(:message) { 'foo' }
  38. let(:group) { Group.first }
  39. it 'publishes no ticket updates', :aggregate_failures do
  40. expect(message).to have_message_count(0)
  41. ticket.update!(state: Ticket::State.find_by(name: 'open'))
  42. perform_enqueued_jobs commit_transaction: true
  43. expect(message).to have_message_count(0)
  44. end
  45. context 'with create event only' do
  46. let(:types) { 'create' }
  47. let(:message) { 'bar' }
  48. it 'publishes no ticket updates', :aggregate_failures do
  49. expect(message).to have_message_count(0)
  50. ticket.update!(state: Ticket::State.find_by(name: 'open'))
  51. perform_enqueued_jobs commit_transaction: true
  52. expect(message).to have_message_count(0)
  53. end
  54. end
  55. end
  56. context 'with slack group' do
  57. let(:message) { 'baz' }
  58. it 'publishes ticket updates', :aggregate_failures do
  59. expect(message).to have_message_count(1)
  60. new_message = 'qux'
  61. ticket.update!(title: new_message)
  62. perform_enqueued_jobs commit_transaction: true
  63. expect(new_message).to have_message_count(1)
  64. ticket.update!(state: Ticket::State.find_by(name: 'pending reminder'), pending_time: Time.zone.local(2023, 2, 7, 12))
  65. perform_enqueued_jobs commit_transaction: true
  66. expect(new_message).to have_message_count(2)
  67. Ticket.process_pending
  68. perform_enqueued_jobs commit_transaction: true
  69. expect(new_message).to have_message_count(3)
  70. Ticket.process_pending
  71. perform_enqueued_jobs commit_transaction: true
  72. expect(new_message).to have_message_count(3)
  73. end
  74. context 'with create event only' do
  75. let(:types) { 'create' }
  76. let(:message) { 'corge' }
  77. it 'publishes no ticket updates', :aggregate_failures do
  78. expect(message).to have_message_count(1)
  79. new_message = 'grault'
  80. ticket.update!(title: new_message)
  81. perform_enqueued_jobs commit_transaction: true
  82. expect(new_message).to have_message_count(0)
  83. end
  84. end
  85. end
  86. def live_mode?
  87. %w[1 true].include?(ENV['CI_IGNORE_CASSETTES'])
  88. end
  89. def delete_all_test_chat_messages
  90. client = slack_client
  91. channel_id = slack_channel_id(client)
  92. channel_history = slack_channel_history(client, channel_id)
  93. message_count = 0
  94. channel_history['messages'].each do |message|
  95. next if message['subtype'] != 'bot_message'
  96. next if !message['ts']
  97. client.chat_delete channel: channel_id, ts: message['ts'], as_user: true
  98. message_count += 1
  99. end
  100. Rails.logger.debug { "Deleted #{message_count} existing bot message(s)..." } if message_count > 0
  101. end
  102. def slack_client
  103. Slack.configure do |config|
  104. config.token = OAUTH_TOKEN
  105. end
  106. client = Slack::Web::Client.new
  107. client.auth_test
  108. client
  109. end
  110. def slack_channel_id(client)
  111. channels = client.conversations_list['channels']
  112. channel_id = nil
  113. channels.each do |channel|
  114. next if channel['name'] != CHANNEL_NAME
  115. channel_id = channel['id']
  116. end
  117. if !channel_id
  118. raise "ERROR: No such channel '#{CHANNEL_NAME}'"
  119. end
  120. channel_id
  121. end
  122. def slack_channel_history(client, channel_id)
  123. channel_history = client.conversations_history(channel: channel_id)
  124. if !channel_history
  125. raise "ERROR: No history for channel #{CHANNEL_NAME}/#{channel_id}"
  126. end
  127. if !channel_history['messages']
  128. raise "ERROR: No history messages for channel #{CHANNEL_NAME}/#{channel_id}"
  129. end
  130. channel_history
  131. end
  132. define :have_message_count do
  133. match do
  134. check_message_count
  135. end
  136. def check_message_count
  137. client = slack_client
  138. channel_id = slack_channel_id(client)
  139. channel_history = slack_channel_history(client, channel_id)
  140. message_count = get_message_count(channel_history)
  141. expect(message_count).to eq(expected)
  142. end
  143. def get_message_count(channel_history)
  144. message_count = 0
  145. channel_history['messages'].each do |message|
  146. next if !message['text']
  147. if message['text'].include?(actual)
  148. message_count += 1
  149. end
  150. end
  151. message_count
  152. end
  153. end
  154. end