Update slack provider to deal with new channel structure

This commit is contained in:
David Taylor 2017-07-13 23:21:15 +01:00
parent ab2e4c2de8
commit ebb6fa947d
4 changed files with 52 additions and 28 deletions

View File

@ -22,7 +22,7 @@ module DiscourseChat::Provider::SlackProvider
tokens = params[:text].split(" ") tokens = params[:text].split(" ")
# channel name fix # channel name fix
channel = channel_id =
case params[:channel_name] case params[:channel_name]
when 'directmessage' when 'directmessage'
"@#{params[:user_name]}" "@#{params[:user_name]}"
@ -34,6 +34,11 @@ module DiscourseChat::Provider::SlackProvider
provider = DiscourseChat::Provider::SlackProvider::PROVIDER_NAME provider = DiscourseChat::Provider::SlackProvider::PROVIDER_NAME
channel = DiscourseChat::Channel.with_provider(provider).with_data_value('identifier',channel_id).first
# Create channel if doesn't exist
channel ||= DiscourseChat::Channel.create!(provider:provider, data:{identifier: channel_id})
cmd = tokens.shift if tokens.size >= 1 cmd = tokens.shift if tokens.size >= 1
error_text = I18n.t("chat_integration.provider.slack.parse_error") error_text = I18n.t("chat_integration.provider.slack.parse_error")
@ -72,7 +77,7 @@ module DiscourseChat::Provider::SlackProvider
end end
category_id = category.nil? ? nil : category.id category_id = category.nil? ? nil : category.id
case DiscourseChat::Helper.smart_create_rule(provider: provider, channel:channel, filter:cmd, category_id: category_id, tags:tags) case DiscourseChat::Helper.smart_create_rule(channel:channel, filter:cmd, category_id: category_id, tags:tags)
when :created when :created
return I18n.t("chat_integration.provider.slack.create.created") return I18n.t("chat_integration.provider.slack.create.created")
when :updated when :updated
@ -86,13 +91,13 @@ module DiscourseChat::Provider::SlackProvider
rule_number = tokens[0].to_i rule_number = tokens[0].to_i
return error_text unless rule_number.to_s == tokens[0] # Check we were given a number return error_text unless rule_number.to_s == tokens[0] # Check we were given a number
if DiscourseChat::Helper.delete_by_index(provider, channel, rule_number) if DiscourseChat::Helper.delete_by_index(channel, rule_number)
return I18n.t("chat_integration.provider.slack.delete.success") return I18n.t("chat_integration.provider.slack.delete.success")
else else
return I18n.t("chat_integration.provider.slack.delete.error") return I18n.t("chat_integration.provider.slack.delete.error")
end end
when "status" when "status"
return DiscourseChat::Helper.status_for_channel(provider, channel) return DiscourseChat::Helper.status_for_channel(channel)
when "help" when "help"
return I18n.t("chat_integration.provider.slack.help") return I18n.t("chat_integration.provider.slack.help")
else else

View File

@ -3,7 +3,7 @@ module DiscourseChat::Provider::SlackProvider
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
CHANNEL_PARAMETERS = {"channel" => '^[@#]\S*$'} CHANNEL_PARAMETERS = {"identifier" => '^[@#]\S*$'}
def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length) def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length)
doc = Nokogiri::HTML.fragment(post.excerpt(max_length, doc = Nokogiri::HTML.fragment(post.excerpt(max_length,
@ -137,12 +137,13 @@ module DiscourseChat::Provider::SlackProvider
end end
def self.trigger_notification(post, channel) def self.trigger_notification(post, channel)
message = slack_message(post, channel) channel_id = channel.data['identifier']
message = slack_message(post, channel_id)
if SiteSetting.chat_integration_slack_access_token.empty? if SiteSetting.chat_integration_slack_access_token.empty?
self.send_via_webhook(message) self.send_via_webhook(message)
else else
self.send_via_api(post, channel, message) self.send_via_api(post, channel_id, message)
end end
end end

View File

@ -4,6 +4,7 @@ describe 'Slack Command Controller', type: :request do
let(:category) { Fabricate(:category) } let(:category) { Fabricate(:category) }
let(:tag) { Fabricate(:tag) } let(:tag) { Fabricate(:tag) }
let(:tag2) { Fabricate(:tag) } let(:tag2) { Fabricate(:tag) }
let!(:chan1){DiscourseChat::Channel.create!(provider:'slack', data:{identifier: '#welcome'})}
describe 'with plugin disabled' do describe 'with plugin disabled' do
it 'should return a 404' do it 'should return a 404' do
@ -24,8 +25,6 @@ describe 'Slack Command Controller', type: :request do
end end
end end
describe 'slash commands endpoint' do describe 'slash commands endpoint' do
before do before do
SiteSetting.chat_integration_enabled = true SiteSetting.chat_integration_enabled = true
@ -82,8 +81,7 @@ describe 'Slack Command Controller', type: :request do
expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created"))
rule = DiscourseChat::Rule.all.first rule = DiscourseChat::Rule.all.first
expect(rule.provider).to eq('slack') expect(rule.channel).to eq(chan1)
expect(rule.channel).to eq('#welcome')
expect(rule.filter).to eq('watch') expect(rule.filter).to eq('watch')
expect(rule.category_id).to eq(category.id) expect(rule.category_id).to eq(category.id)
expect(rule.tags).to eq(nil) expect(rule.tags).to eq(nil)
@ -144,8 +142,7 @@ describe 'Slack Command Controller', type: :request do
expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created"))
rule = DiscourseChat::Rule.all.first rule = DiscourseChat::Rule.all.first
expect(rule.provider).to eq('slack') expect(rule.channel).to eq(chan1)
expect(rule.channel).to eq('#welcome')
expect(rule.filter).to eq('watch') expect(rule.filter).to eq('watch')
expect(rule.category_id).to eq(nil) expect(rule.category_id).to eq(nil)
expect(rule.tags).to eq([tag.name]) expect(rule.tags).to eq([tag.name])
@ -164,8 +161,7 @@ describe 'Slack Command Controller', type: :request do
expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created"))
rule = DiscourseChat::Rule.all.first rule = DiscourseChat::Rule.all.first
expect(rule.provider).to eq('slack') expect(rule.channel).to eq(chan1)
expect(rule.channel).to eq('#welcome')
expect(rule.filter).to eq('watch') expect(rule.filter).to eq('watch')
expect(rule.category_id).to eq(category.id) expect(rule.category_id).to eq(category.id)
expect(rule.tags).to contain_exactly(tag.name, tag2.name) expect(rule.tags).to contain_exactly(tag.name, tag2.name)
@ -184,16 +180,36 @@ describe 'Slack Command Controller', type: :request do
expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.not_found.tag", name:"blah")) expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.not_found.tag", name:"blah"))
end end
end end
context 'from an unknown channel' do
it 'creates the channel' do
post "/chat-integration/slack/command.json",
text: "watch #{category.slug}",
channel_name: 'general',
token: token
json = JSON.parse(response.body)
expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created"))
chan = DiscourseChat::Channel.with_provider('slack').with_data_value('identifier','#general').first
expect(chan.provider).to eq('slack')
rule = chan.rules.first
expect(rule.filter).to eq('watch')
expect(rule.category_id).to eq(category.id)
expect(rule.tags).to eq(nil)
end
end
end end
describe 'remove rule' do describe 'remove rule' do
it 'removes the rule' do it 'removes the rule' do
rule1 = DiscourseChat::Rule.new({provider: 'slack', rule1 = DiscourseChat::Rule.create(channel: chan1,
channel: '#welcome',
filter: 'watch', filter: 'watch',
category_id: category.id, category_id: category.id,
tags: [tag.name, tag2.name] tags: [tag.name, tag2.name]
}).save! )
expect(DiscourseChat::Rule.all.size).to eq(1) expect(DiscourseChat::Rule.all.size).to eq(1)
post "/chat-integration/slack/command.json", post "/chat-integration/slack/command.json",
@ -250,7 +266,7 @@ describe 'Slack Command Controller', type: :request do
json = JSON.parse(response.body) json = JSON.parse(response.body)
expect(json["text"]).to eq(DiscourseChat::Helper.status_for_channel('slack','#welcome')) expect(json["text"]).to eq(DiscourseChat::Helper.status_for_channel(chan1))
end end
end end

View File

@ -57,16 +57,18 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do
SiteSetting.chat_integration_slack_enabled = true SiteSetting.chat_integration_slack_enabled = true
end end
let(:chan1){DiscourseChat::Channel.create!(provider:'slack', data:{identifier: '#general'})}
it 'sends a webhook request' do it 'sends a webhook request' do
stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(body: "success") stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(body: "success")
described_class.trigger_notification(post, '#general') described_class.trigger_notification(post, chan1)
expect(stub1).to have_been_requested.once expect(stub1).to have_been_requested.once
end end
it 'handles errors correctly' do it 'handles errors correctly' do
stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(status: 400, body: "error") stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(status: 400, body: "error")
expect(stub1).to have_been_requested.times(0) expect(stub1).to have_been_requested.times(0)
expect{described_class.trigger_notification(post, '#general')}.to raise_exception(::DiscourseChat::ProviderError) expect{described_class.trigger_notification(post, chan1)}.to raise_exception(::DiscourseChat::ProviderError)
expect(stub1).to have_been_requested.once expect(stub1).to have_been_requested.once
end end
@ -81,14 +83,14 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do
it 'sends an api request' do it 'sends an api request' do
expect(@stub2).to have_been_requested.times(0) expect(@stub2).to have_been_requested.times(0)
described_class.trigger_notification(post, '#general') described_class.trigger_notification(post, chan1)
expect(@stub1).to have_been_requested.times(0) expect(@stub1).to have_been_requested.times(0)
expect(@stub2).to have_been_requested.once expect(@stub2).to have_been_requested.once
end end
it 'handles errors correctly' do it 'handles errors correctly' do
@stub2 = stub_request(:post, %r{https://slack.com/api/chat.postMessage}).to_return(body: "{\"ok\":false }", headers: {'Content-Type' => 'application/json'}) @stub2 = stub_request(:post, %r{https://slack.com/api/chat.postMessage}).to_return(body: "{\"ok\":false }", headers: {'Content-Type' => 'application/json'})
expect{described_class.trigger_notification(post, '#general')}.to raise_exception(::DiscourseChat::ProviderError) expect{described_class.trigger_notification(post, chan1)}.to raise_exception(::DiscourseChat::ProviderError)
expect(@stub2).to have_been_requested.once expect(@stub2).to have_been_requested.once
end end
@ -97,8 +99,8 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do
expect(@stub2).to have_been_requested.times(0) expect(@stub2).to have_been_requested.times(0)
expect(@stub3).to have_been_requested.times(0) expect(@stub3).to have_been_requested.times(0)
described_class.trigger_notification(post, '#general') described_class.trigger_notification(post, chan1)
described_class.trigger_notification(second_post, '#general') described_class.trigger_notification(second_post, chan1)
expect(@stub1).to have_been_requested.times(0) expect(@stub1).to have_been_requested.times(0)
expect(@stub2).to have_been_requested.once # Initial creation of message expect(@stub2).to have_been_requested.once # Initial creation of message
expect(@stub3).to have_been_requested.once # Requests to update the existing message expect(@stub3).to have_been_requested.once # Requests to update the existing message