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:'
|
||||
|
||||
# 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
|
||||
if not ::DiscourseChat::Provider.provider_names.include? provider
|
||||
errors.add(:provider, "#{provider} is not a valid provider")
|
||||
return
|
||||
end
|
||||
|
||||
# Validate descriptor
|
||||
if descriptor.blank?
|
||||
errors.add(:descriptor, "channel descriptor cannot be blank")
|
||||
end
|
||||
|
||||
def data_valid?
|
||||
# If provider is invalid, don't try and check data
|
||||
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
|
||||
end
|
||||
|
||||
provider_class = ::DiscourseChat::Provider.get_by_name(provider)
|
||||
if defined? provider_class::PROVIDER_CHANNEL_REGEX
|
||||
channel_regex = Regexp.new provider_class::PROVIDER_CHANNEL_REGEX
|
||||
if not channel_regex.match?(descriptor)
|
||||
errors.add(:descriptor, "#{descriptor} is not a valid channel descriptor for provider #{provider}")
|
||||
data.each do |key, value|
|
||||
regex_string = params[key]
|
||||
if !Regexp.new(regex_string).match?(value)
|
||||
errors.add(:data, "data.#{key} is invalid")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module DiscourseChat::Provider::SlackProvider
|
|||
|
||||
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)
|
||||
doc = Nokogiri::HTML.fragment(post.excerpt(max_length,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
module DiscourseChat
|
||||
module Provider
|
||||
module TelegramProvider
|
||||
include Provider
|
||||
|
||||
PROVIDER_NAME = "telegram".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled
|
||||
CHANNEL_PARAMETERS = {}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,8 @@ RSpec.shared_context "dummy provider" do
|
|||
module ::DiscourseChat::Provider::DummyProvider
|
||||
PROVIDER_NAME = "dummy".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
||||
CHANNEL_PARAMETERS = {}
|
||||
|
||||
@@sent_messages = []
|
||||
@@raise_exception = nil
|
||||
|
||||
|
@ -30,9 +32,37 @@ RSpec.shared_context "dummy provider" do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
RSpec.configure do |rspec|
|
||||
rspec.include_context "dummy provider"
|
||||
rspec.include_context "validated dummy provider"
|
||||
|
||||
end
|
|
@ -3,6 +3,7 @@ require_relative '../dummy_provider'
|
|||
|
||||
RSpec.describe DiscourseChat::Channel do
|
||||
include_context "dummy provider"
|
||||
include_context "validated dummy provider"
|
||||
|
||||
|
||||
it 'should save and load successfully' do
|
||||
|
@ -10,7 +11,6 @@ RSpec.describe DiscourseChat::Channel do
|
|||
|
||||
chan = DiscourseChat::Channel.create({
|
||||
provider:"dummy",
|
||||
descriptor: "#random",
|
||||
})
|
||||
|
||||
expect(DiscourseChat::Channel.all.length).to eq(1)
|
||||
|
@ -18,23 +18,22 @@ RSpec.describe DiscourseChat::Channel do
|
|||
loadedChan = DiscourseChat::Channel.find(chan.id)
|
||||
|
||||
expect(loadedChan.provider).to eq('dummy')
|
||||
expect(loadedChan.descriptor).to eq('#random')
|
||||
|
||||
end
|
||||
|
||||
it 'can be filtered by provider' do
|
||||
channel1 = DiscourseChat::Channel.create({provider:'dummy', descriptor:'blah'})
|
||||
channel2 = DiscourseChat::Channel.create({provider:'slack', descriptor:'#blah'})
|
||||
channel3 = DiscourseChat::Channel.create({provider:'slack', descriptor:'#blah'})
|
||||
channel1 = DiscourseChat::Channel.create!(provider:'dummy')
|
||||
channel2 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"})
|
||||
channel3 = DiscourseChat::Channel.create!(provider:'dummy2', data:{val:"blah"})
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
DiscourseChat::Rule.create(channel: channel)
|
||||
DiscourseChat::Rule.create(channel: channel)
|
||||
|
@ -43,21 +42,33 @@ RSpec.describe DiscourseChat::Channel do
|
|||
end
|
||||
|
||||
describe 'validations' do
|
||||
let(:channel) { DiscourseChat::Channel.create(
|
||||
provider:"dummy",
|
||||
descriptor: "#general"
|
||||
) }
|
||||
let(:channel) { }
|
||||
|
||||
it 'validates provider correctly' do
|
||||
channel = DiscourseChat::Channel.create!(provider:"dummy")
|
||||
expect(channel.valid?).to eq(true)
|
||||
channel.provider = 'somerandomprovider'
|
||||
expect(channel.valid?).to eq(false)
|
||||
end
|
||||
|
||||
it 'validates channel correctly' do
|
||||
expect(channel.valid?).to eq(true)
|
||||
channel.descriptor = ''
|
||||
expect(channel.valid?).to eq(false)
|
||||
it 'succeeds with valid data' do
|
||||
channel2 = DiscourseChat::Channel.new(provider:"dummy2", data:{val:"hello"})
|
||||
expect(channel2.valid?).to eq(true)
|
||||
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
|
||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe DiscourseChat::Rule do
|
|||
let(:tag1){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
|
||||
it 'should return sequential numbers' do
|
||||
|
@ -87,8 +87,8 @@ RSpec.describe DiscourseChat::Rule do
|
|||
end
|
||||
|
||||
it 'can be filtered by channel' do
|
||||
channel2 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#random')
|
||||
channel3 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#another')
|
||||
channel2 = DiscourseChat::Channel.create(provider:'dummy')
|
||||
channel3 = DiscourseChat::Channel.create(provider:'dummy')
|
||||
|
||||
rule2 = DiscourseChat::Rule.create(channel:channel)
|
||||
rule3 = DiscourseChat::Rule.create(channel:channel)
|
||||
|
|
Loading…
Reference in New Issue