Allow providers to define a data schema for their channel parameters
This commit is contained in:
parent
e07a4da460
commit
4b25dcec8f
|
@ -2,28 +2,39 @@ class DiscourseChat::Channel < DiscourseChat::PluginModel
|
||||||
KEY_PREFIX = 'channel:'
|
KEY_PREFIX = 'channel:'
|
||||||
|
|
||||||
# Setup ActiveRecord::Store to use the JSON field to read/write these values
|
# Setup ActiveRecord::Store to use the JSON field to read/write these values
|
||||||
store :value, accessors: [ :provider, :descriptor ], coder: JSON
|
store :value, accessors: [ :provider, :data ], coder: JSON
|
||||||
|
|
||||||
validate :provider_and_descriptor_valid?
|
after_initialize :init_data
|
||||||
|
|
||||||
def provider_and_descriptor_valid?
|
def init_data
|
||||||
|
self.data = {} if self.data.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
validate :provider_valid?, :data_valid?
|
||||||
|
|
||||||
|
def provider_valid?
|
||||||
# Validate provider
|
# Validate provider
|
||||||
if not ::DiscourseChat::Provider.provider_names.include? provider
|
if not ::DiscourseChat::Provider.provider_names.include? provider
|
||||||
errors.add(:provider, "#{provider} is not a valid provider")
|
errors.add(:provider, "#{provider} is not a valid provider")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Validate descriptor
|
def data_valid?
|
||||||
if descriptor.blank?
|
# If provider is invalid, don't try and check data
|
||||||
errors.add(:descriptor, "channel descriptor cannot be blank")
|
return unless ::DiscourseChat::Provider.provider_names.include? provider
|
||||||
|
|
||||||
|
params = ::DiscourseChat::Provider.get_by_name(provider)::CHANNEL_PARAMETERS
|
||||||
|
|
||||||
|
unless params.keys.sort == data.keys.sort
|
||||||
|
errors.add(:data, "data does not match the required structure for provider #{provider}")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
provider_class = ::DiscourseChat::Provider.get_by_name(provider)
|
data.each do |key, value|
|
||||||
if defined? provider_class::PROVIDER_CHANNEL_REGEX
|
regex_string = params[key]
|
||||||
channel_regex = Regexp.new provider_class::PROVIDER_CHANNEL_REGEX
|
if !Regexp.new(regex_string).match?(value)
|
||||||
if not channel_regex.match?(descriptor)
|
errors.add(:data, "data.#{key} is invalid")
|
||||||
errors.add(:descriptor, "#{descriptor} is not a valid channel descriptor for provider #{provider}")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ module DiscourseChat::Provider::SlackProvider
|
||||||
|
|
||||||
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
|
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
|
||||||
|
|
||||||
PROVIDER_CHANNEL_REGEX = '^[@#]\S*$'
|
CHANNEL_PARAMETERS = {"channel" => '^[@#]\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,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
module DiscourseChat
|
module DiscourseChat
|
||||||
module Provider
|
module Provider
|
||||||
module TelegramProvider
|
module TelegramProvider
|
||||||
include Provider
|
|
||||||
|
|
||||||
PROVIDER_NAME = "telegram".freeze
|
PROVIDER_NAME = "telegram".freeze
|
||||||
PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled
|
PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled
|
||||||
|
CHANNEL_PARAMETERS = {}
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,8 @@ RSpec.shared_context "dummy provider" do
|
||||||
module ::DiscourseChat::Provider::DummyProvider
|
module ::DiscourseChat::Provider::DummyProvider
|
||||||
PROVIDER_NAME = "dummy".freeze
|
PROVIDER_NAME = "dummy".freeze
|
||||||
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
||||||
|
CHANNEL_PARAMETERS = {}
|
||||||
|
|
||||||
@@sent_messages = []
|
@@sent_messages = []
|
||||||
@@raise_exception = nil
|
@@raise_exception = nil
|
||||||
|
|
||||||
|
@ -30,9 +32,37 @@ RSpec.shared_context "dummy provider" do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:provider){::DiscourseChat::Provider::DummyProvider}
|
let(:provider){::DiscourseChat::Provider::DummyProvider}
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.shared_context "validated dummy provider" do
|
||||||
|
before(:each) do
|
||||||
|
if defined? ::DiscourseChat::Provider::Dummy2Provider
|
||||||
|
::DiscourseChat::Provider.send(:remove_const, :Dummy2Provider)
|
||||||
|
end
|
||||||
|
|
||||||
|
module ::DiscourseChat::Provider::Dummy2Provider
|
||||||
|
PROVIDER_NAME = "dummy2".freeze
|
||||||
|
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
||||||
|
CHANNEL_PARAMETERS = {"val" => '\S+'}
|
||||||
|
|
||||||
|
@@sent_messages = []
|
||||||
|
|
||||||
|
def self.trigger_notification(post, channel)
|
||||||
|
@@sent_messages.push(post: post.id, channel: channel)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.sent_messages
|
||||||
|
@@sent_messages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:provider){::DiscourseChat::Provider::DummyProvider}
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |rspec|
|
RSpec.configure do |rspec|
|
||||||
rspec.include_context "dummy provider"
|
rspec.include_context "dummy provider"
|
||||||
|
rspec.include_context "validated dummy provider"
|
||||||
|
|
||||||
end
|
end
|
|
@ -3,6 +3,7 @@ require_relative '../dummy_provider'
|
||||||
|
|
||||||
RSpec.describe DiscourseChat::Channel do
|
RSpec.describe DiscourseChat::Channel do
|
||||||
include_context "dummy provider"
|
include_context "dummy provider"
|
||||||
|
include_context "validated dummy provider"
|
||||||
|
|
||||||
|
|
||||||
it 'should save and load successfully' do
|
it 'should save and load successfully' do
|
||||||
|
@ -10,7 +11,6 @@ RSpec.describe DiscourseChat::Channel do
|
||||||
|
|
||||||
chan = DiscourseChat::Channel.create({
|
chan = DiscourseChat::Channel.create({
|
||||||
provider:"dummy",
|
provider:"dummy",
|
||||||
descriptor: "#random",
|
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(DiscourseChat::Channel.all.length).to eq(1)
|
expect(DiscourseChat::Channel.all.length).to eq(1)
|
||||||
|
@ -18,23 +18,22 @@ RSpec.describe DiscourseChat::Channel do
|
||||||
loadedChan = DiscourseChat::Channel.find(chan.id)
|
loadedChan = DiscourseChat::Channel.find(chan.id)
|
||||||
|
|
||||||
expect(loadedChan.provider).to eq('dummy')
|
expect(loadedChan.provider).to eq('dummy')
|
||||||
expect(loadedChan.descriptor).to eq('#random')
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be filtered by provider' do
|
it 'can be filtered by provider' do
|
||||||
channel1 = DiscourseChat::Channel.create({provider:'dummy', descriptor:'blah'})
|
channel1 = DiscourseChat::Channel.create!(provider:'dummy')
|
||||||
channel2 = DiscourseChat::Channel.create({provider:'slack', descriptor:'#blah'})
|
channel2 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"})
|
||||||
channel3 = DiscourseChat::Channel.create({provider:'slack', descriptor:'#blah'})
|
channel3 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"})
|
||||||
|
|
||||||
expect(DiscourseChat::Channel.all.length).to eq(3)
|
expect(DiscourseChat::Channel.all.length).to eq(3)
|
||||||
|
|
||||||
expect(DiscourseChat::Channel.with_provider('slack').length).to eq(2)
|
expect(DiscourseChat::Channel.with_provider('dummy2').length).to eq(2)
|
||||||
expect(DiscourseChat::Channel.with_provider('dummy').length).to eq(1)
|
expect(DiscourseChat::Channel.with_provider('dummy').length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can find its own rules' do
|
it 'can find its own rules' do
|
||||||
channel = DiscourseChat::Channel.create({provider:'dummy', descriptor:'blah'})
|
channel = DiscourseChat::Channel.create({provider:'dummy'})
|
||||||
expect(channel.rules.size).to eq(0)
|
expect(channel.rules.size).to eq(0)
|
||||||
DiscourseChat::Rule.create(channel: channel)
|
DiscourseChat::Rule.create(channel: channel)
|
||||||
DiscourseChat::Rule.create(channel: channel)
|
DiscourseChat::Rule.create(channel: channel)
|
||||||
|
@ -43,21 +42,33 @@ RSpec.describe DiscourseChat::Channel do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'validations' do
|
describe 'validations' do
|
||||||
let(:channel) { DiscourseChat::Channel.create(
|
let(:channel) { }
|
||||||
provider:"dummy",
|
|
||||||
descriptor: "#general"
|
|
||||||
) }
|
|
||||||
|
|
||||||
it 'validates provider correctly' do
|
it 'validates provider correctly' do
|
||||||
|
channel = DiscourseChat::Channel.create!(provider:"dummy")
|
||||||
expect(channel.valid?).to eq(true)
|
expect(channel.valid?).to eq(true)
|
||||||
channel.provider = 'somerandomprovider'
|
channel.provider = 'somerandomprovider'
|
||||||
expect(channel.valid?).to eq(false)
|
expect(channel.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'validates channel correctly' do
|
it 'succeeds with valid data' do
|
||||||
expect(channel.valid?).to eq(true)
|
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{val:"hello"})
|
||||||
channel.descriptor = ''
|
expect(channel2.valid?).to eq(true)
|
||||||
expect(channel.valid?).to eq(false)
|
end
|
||||||
|
|
||||||
|
it 'disallows invalid data' do
|
||||||
|
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{val:''})
|
||||||
|
expect(channel2.valid?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'disallows unknown keys' do
|
||||||
|
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{val:"hello", unknown:"world"})
|
||||||
|
expect(channel2.valid?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'requires all keys' do
|
||||||
|
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{})
|
||||||
|
expect(channel2.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
let(:tag1){Fabricate(:tag)}
|
let(:tag1){Fabricate(:tag)}
|
||||||
let(:tag2){Fabricate(:tag)}
|
let(:tag2){Fabricate(:tag)}
|
||||||
|
|
||||||
let(:channel){DiscourseChat::Channel.create(provider:'dummy', descriptor:'#general')}
|
let(:channel){DiscourseChat::Channel.create(provider:'dummy')}
|
||||||
|
|
||||||
describe '.alloc_key' do
|
describe '.alloc_key' do
|
||||||
it 'should return sequential numbers' do
|
it 'should return sequential numbers' do
|
||||||
|
@ -87,8 +87,8 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be filtered by channel' do
|
it 'can be filtered by channel' do
|
||||||
channel2 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#random')
|
channel2 = DiscourseChat::Channel.create(provider:'dummy')
|
||||||
channel3 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#another')
|
channel3 = DiscourseChat::Channel.create(provider:'dummy')
|
||||||
|
|
||||||
rule2 = DiscourseChat::Rule.create(channel:channel)
|
rule2 = DiscourseChat::Rule.create(channel:channel)
|
||||||
rule3 = DiscourseChat::Rule.create(channel:channel)
|
rule3 = DiscourseChat::Rule.create(channel:channel)
|
||||||
|
|
Loading…
Reference in New Issue