diff --git a/app/models/channel.rb b/app/models/channel.rb index 7317836..00e72f0 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -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 diff --git a/lib/discourse_chat/provider/slack/slack_provider.rb b/lib/discourse_chat/provider/slack/slack_provider.rb index b4ee843..dbd3afe 100644 --- a/lib/discourse_chat/provider/slack/slack_provider.rb +++ b/lib/discourse_chat/provider/slack/slack_provider.rb @@ -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, diff --git a/lib/discourse_chat/provider/telegram/telegram_provider.rb b/lib/discourse_chat/provider/telegram/telegram_provider.rb index d63aee6..8e7afed 100644 --- a/lib/discourse_chat/provider/telegram/telegram_provider.rb +++ b/lib/discourse_chat/provider/telegram/telegram_provider.rb @@ -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 diff --git a/spec/dummy_provider.rb b/spec/dummy_provider.rb index 92c79f9..709f926 100644 --- a/spec/dummy_provider.rb +++ b/spec/dummy_provider.rb @@ -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 \ No newline at end of file diff --git a/spec/models/channel_spec.rb b/spec/models/channel_spec.rb index 6a424e1..4094bf0 100644 --- a/spec/models/channel_spec.rb +++ b/spec/models/channel_spec.rb @@ -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 diff --git a/spec/models/rule_spec.rb b/spec/models/rule_spec.rb index 27b7369..0c218ad 100644 --- a/spec/models/rule_spec.rb +++ b/spec/models/rule_spec.rb @@ -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)