Model changes
This commit is contained in:
parent
b04b5c22dd
commit
e07a4da460
|
@ -2,6 +2,36 @@ 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: [ :name ], coder: JSON
|
store :value, accessors: [ :provider, :descriptor ], coder: JSON
|
||||||
|
|
||||||
|
validate :provider_and_descriptor_valid?
|
||||||
|
|
||||||
|
def provider_and_descriptor_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")
|
||||||
|
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}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rules
|
||||||
|
DiscourseChat::Rule.with_channel_id(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
scope :with_provider, ->(provider) { where("value::json->>'provider'=?", provider)}
|
||||||
|
|
||||||
end
|
end
|
|
@ -2,7 +2,7 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel
|
||||||
KEY_PREFIX = 'rule:'
|
KEY_PREFIX = 'rule:'
|
||||||
|
|
||||||
# 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, :channel, :category_id, :tags, :filter, :error_key ], coder: JSON
|
store :value, accessors: [ :channel_id, :category_id, :tags, :filter, :error_key ], coder: JSON
|
||||||
|
|
||||||
after_initialize :init_filter
|
after_initialize :init_filter
|
||||||
|
|
||||||
|
@ -13,27 +13,12 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel
|
||||||
validates :filter, :inclusion => { :in => %w(watch follow mute),
|
validates :filter, :inclusion => { :in => %w(watch follow mute),
|
||||||
:message => "%{value} is not a valid filter" }
|
:message => "%{value} is not a valid filter" }
|
||||||
|
|
||||||
validate :provider_and_channel_valid?, :category_valid?, :tags_valid?
|
validate :channel_valid?, :category_valid?, :tags_valid?
|
||||||
|
|
||||||
def provider_and_channel_valid?
|
def channel_valid?
|
||||||
# Validate provider
|
# Validate category
|
||||||
if not ::DiscourseChat::Provider.provider_names.include? provider
|
if not (channel_id.nil? or DiscourseChat::Channel.where(id: channel_id).exists?)
|
||||||
errors.add(:provider, "#{provider} is not a valid provider")
|
errors.add(:channel_id, "#{channel_id} is not a valid channel id")
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
# Validate channel
|
|
||||||
if channel.blank?
|
|
||||||
errors.add(:channel, "channel cannot be blank")
|
|
||||||
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?(channel)
|
|
||||||
errors.add(:channel, "#{channel} is not a valid channel for provider #{provider}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -72,12 +57,18 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :with_provider, ->(provider) { where("value::json->>'provider'=?", provider)}
|
# Mock foreign key
|
||||||
|
# Could raise RecordNotFound
|
||||||
|
def channel
|
||||||
|
DiscourseChat::Channel.find(channel_id)
|
||||||
|
end
|
||||||
|
def channel=(val)
|
||||||
|
self.channel_id = val.id
|
||||||
|
end
|
||||||
|
|
||||||
scope :with_channel, ->(provider, channel) { with_provider(provider).where("value::json->>'channel'=?", channel)}
|
scope :with_channel, ->(channel) { with_channel_id(channel.id) }
|
||||||
|
scope :with_channel_id, ->(channel_id) { where("value::json->>'channel_id'=?", channel_id.to_s)}
|
||||||
|
|
||||||
scope :with_category, ->(category_id) { category_id.nil? ? where("(value::json->'category_id') IS NULL OR json_typeof(value::json->'category_id')='null'") : where("value::json->>'category_id'=?", category_id.to_s)}
|
scope :with_category_id, ->(category_id) { category_id.nil? ? where("(value::json->'category_id') IS NULL OR json_typeof(value::json->'category_id')='null'") : where("value::json->>'category_id'=?", category_id.to_s)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
|
@ -22,10 +22,10 @@ module DiscourseChat
|
||||||
return if topic.blank? || topic.archetype == Archetype.private_message
|
return if topic.blank? || topic.archetype == Archetype.private_message
|
||||||
|
|
||||||
# Load all the rules that apply to this topic's category
|
# Load all the rules that apply to this topic's category
|
||||||
matching_rules = DiscourseChat::Rule.with_category(topic.category_id)
|
matching_rules = DiscourseChat::Rule.with_category_id(topic.category_id)
|
||||||
|
|
||||||
if topic.category # Also load the rules for the wildcard category
|
if topic.category # Also load the rules for the wildcard category
|
||||||
matching_rules += DiscourseChat::Rule.with_category(nil)
|
matching_rules += DiscourseChat::Rule.with_category_id(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
# If tagging is enabled, thow away rules that don't apply to this topic
|
# If tagging is enabled, thow away rules that don't apply to this topic
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require_relative '../dummy_provider'
|
||||||
|
|
||||||
|
RSpec.describe DiscourseChat::Channel do
|
||||||
|
include_context "dummy provider"
|
||||||
|
|
||||||
|
|
||||||
|
it 'should save and load successfully' do
|
||||||
|
expect(DiscourseChat::Channel.all.length).to eq(0)
|
||||||
|
|
||||||
|
chan = DiscourseChat::Channel.create({
|
||||||
|
provider:"dummy",
|
||||||
|
descriptor: "#random",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(DiscourseChat::Channel.all.length).to eq(1)
|
||||||
|
|
||||||
|
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'})
|
||||||
|
|
||||||
|
expect(DiscourseChat::Channel.all.length).to eq(3)
|
||||||
|
|
||||||
|
expect(DiscourseChat::Channel.with_provider('slack').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'})
|
||||||
|
expect(channel.rules.size).to eq(0)
|
||||||
|
DiscourseChat::Rule.create(channel: channel)
|
||||||
|
DiscourseChat::Rule.create(channel: channel)
|
||||||
|
expect(channel.rules.size).to eq(2)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'validations' do
|
||||||
|
let(:channel) { DiscourseChat::Channel.create(
|
||||||
|
provider:"dummy",
|
||||||
|
descriptor: "#general"
|
||||||
|
) }
|
||||||
|
|
||||||
|
it 'validates provider correctly' do
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,24 +1,33 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
require_relative '../dummy_provider'
|
||||||
|
|
||||||
RSpec.describe DiscourseChat::Rule do
|
RSpec.describe DiscourseChat::Rule do
|
||||||
|
include_context "dummy provider"
|
||||||
|
|
||||||
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')}
|
||||||
|
|
||||||
describe '.alloc_key' do
|
describe '.alloc_key' do
|
||||||
it 'should return sequential numbers' do
|
it 'should return sequential numbers' do
|
||||||
expect( DiscourseChat::Rule.create(provider:'slack',channel:'#general').key ).to eq("rule:1")
|
expect( DiscourseChat::Rule.create(channel: channel).key ).to eq("rule:1")
|
||||||
expect( DiscourseChat::Rule.create(provider:'slack',channel:'#general').key ).to eq("rule:2")
|
expect( DiscourseChat::Rule.create(channel: channel).key ).to eq("rule:2")
|
||||||
expect( DiscourseChat::Rule.create(provider:'slack',channel:'#general').key ).to eq("rule:3")
|
expect( DiscourseChat::Rule.create(channel: channel).key ).to eq("rule:3")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should convert between channel and channel_id successfully' do
|
||||||
|
rule = DiscourseChat::Rule.create(channel: channel)
|
||||||
|
expect( rule.channel_id ).to eq(channel.id)
|
||||||
|
expect( rule.channel.id ).to eq(channel.id)
|
||||||
|
end
|
||||||
|
|
||||||
it 'should save and load successfully' do
|
it 'should save and load successfully' do
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(0)
|
expect(DiscourseChat::Rule.all.length).to eq(0)
|
||||||
|
|
||||||
rule = DiscourseChat::Rule.create({
|
rule = DiscourseChat::Rule.create({
|
||||||
provider:"slack",
|
channel: channel,
|
||||||
channel: "#general",
|
|
||||||
category_id: 1,
|
category_id: 1,
|
||||||
tags: [tag1.name, tag2.name],
|
tags: [tag1.name, tag2.name],
|
||||||
filter: 'watch'
|
filter: 'watch'
|
||||||
|
@ -28,8 +37,7 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
|
|
||||||
loadedRule = DiscourseChat::Rule.find(rule.id)
|
loadedRule = DiscourseChat::Rule.find(rule.id)
|
||||||
|
|
||||||
expect(loadedRule.provider).to eq('slack')
|
expect(loadedRule.channel.id).to eq(channel.id)
|
||||||
expect(loadedRule.channel).to eq('#general')
|
|
||||||
expect(loadedRule.category_id).to eq(1)
|
expect(loadedRule.category_id).to eq(1)
|
||||||
expect(loadedRule.tags).to contain_exactly(tag1.name,tag2.name)
|
expect(loadedRule.tags).to contain_exactly(tag1.name,tag2.name)
|
||||||
expect(loadedRule.filter).to eq('watch')
|
expect(loadedRule.filter).to eq('watch')
|
||||||
|
@ -39,8 +47,7 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
describe 'general operations' do
|
describe 'general operations' do
|
||||||
before do
|
before do
|
||||||
rule = DiscourseChat::Rule.create({
|
rule = DiscourseChat::Rule.create({
|
||||||
provider:"slack",
|
channel: channel,
|
||||||
channel: "#general",
|
|
||||||
category_id: 1,
|
category_id: 1,
|
||||||
tags: [tag1.name, tag2.name]
|
tags: [tag1.name, tag2.name]
|
||||||
})
|
})
|
||||||
|
@ -48,16 +55,16 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
|
|
||||||
it 'can be modified' do
|
it 'can be modified' do
|
||||||
rule = DiscourseChat::Rule.all.first
|
rule = DiscourseChat::Rule.all.first
|
||||||
rule.channel = "#random"
|
rule.tags = [tag1.name]
|
||||||
|
|
||||||
rule.save!
|
rule.save!
|
||||||
|
|
||||||
rule = DiscourseChat::Rule.all.first
|
rule = DiscourseChat::Rule.all.first
|
||||||
expect(rule.channel).to eq('#random')
|
expect(rule.tags).to contain_exactly(tag1.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be deleted' do
|
it 'can be deleted' do
|
||||||
DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
DiscourseChat::Rule.new(channel:channel).save!
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(2)
|
expect(DiscourseChat::Rule.all.length).to eq(2)
|
||||||
|
|
||||||
rule = DiscourseChat::Rule.all.first
|
rule = DiscourseChat::Rule.all.first
|
||||||
|
@ -67,10 +74,10 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can delete all' do
|
it 'can delete all' do
|
||||||
DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
DiscourseChat::Rule.create({channel:channel})
|
||||||
DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
DiscourseChat::Rule.create({channel:channel})
|
||||||
DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
DiscourseChat::Rule.create({channel:channel})
|
||||||
DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
DiscourseChat::Rule.create({channel:channel})
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(5)
|
expect(DiscourseChat::Rule.all.length).to eq(5)
|
||||||
|
|
||||||
|
@ -79,36 +86,29 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(0)
|
expect(DiscourseChat::Rule.all.length).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be filtered by provider' do
|
|
||||||
rule2 = DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
|
||||||
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah'}).save!
|
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(3)
|
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.with_provider('slack').length).to eq(2)
|
|
||||||
expect(DiscourseChat::Rule.with_provider('telegram').length).to eq(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'can be filtered by channel' do
|
it 'can be filtered by channel' do
|
||||||
rule2 = DiscourseChat::Rule.new({provider:'telegram', channel:'blah'}).save!
|
channel2 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#random')
|
||||||
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah'}).save!
|
channel3 = DiscourseChat::Channel.create(provider:'dummy', descriptor:'#another')
|
||||||
rule4 = DiscourseChat::Rule.new({provider:'slack', channel:'#general'}).save!
|
|
||||||
rule5 = DiscourseChat::Rule.new({provider:'slack', channel:'#general'}).save!
|
|
||||||
|
|
||||||
|
rule2 = DiscourseChat::Rule.create(channel:channel)
|
||||||
|
rule3 = DiscourseChat::Rule.create(channel:channel)
|
||||||
|
rule4 = DiscourseChat::Rule.create(channel:channel2)
|
||||||
|
rule5 = DiscourseChat::Rule.create(channel:channel3)
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(5)
|
expect(DiscourseChat::Rule.all.length).to eq(5)
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.with_channel('slack','#general').length).to eq(3)
|
expect(DiscourseChat::Rule.with_channel(channel).length).to eq(3)
|
||||||
expect(DiscourseChat::Rule.with_channel('slack', '#blah').length).to eq(1)
|
expect(DiscourseChat::Rule.with_channel(channel2).length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be filtered by category' do
|
it 'can be filtered by category' do
|
||||||
rule2 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah', category_id: 1}).save!
|
rule2 = DiscourseChat::Rule.create(channel:channel, category_id: 1)
|
||||||
rule3 = DiscourseChat::Rule.new({provider:'slack', channel:'#blah', category_id: nil}).save!
|
rule3 = DiscourseChat::Rule.create(channel:channel, category_id: nil)
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.all.length).to eq(3)
|
expect(DiscourseChat::Rule.all.length).to eq(3)
|
||||||
|
|
||||||
expect(DiscourseChat::Rule.with_category(1).length).to eq(2)
|
expect(DiscourseChat::Rule.with_category_id(1).length).to eq(2)
|
||||||
expect(DiscourseChat::Rule.with_category(nil).length).to eq(1)
|
expect(DiscourseChat::Rule.with_category_id(nil).length).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,23 +117,16 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
let(:rule) do
|
let(:rule) do
|
||||||
DiscourseChat::Rule.create({
|
DiscourseChat::Rule.create({
|
||||||
filter: 'watch',
|
filter: 'watch',
|
||||||
provider:"slack",
|
channel: channel,
|
||||||
channel: "#general",
|
|
||||||
category_id: 1,
|
category_id: 1,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'validates provider correctly' do
|
|
||||||
expect(rule.valid?).to eq(true)
|
|
||||||
rule.provider = 'somerandomprovider'
|
|
||||||
expect(rule.valid?).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'validates channel correctly' do
|
it 'validates channel correctly' do
|
||||||
expect(rule.valid?).to eq(true)
|
expect(rule.valid?).to eq(true)
|
||||||
rule.channel = ''
|
rule.channel_id = 'blahblahblah'
|
||||||
expect(rule.valid?).to eq(false)
|
expect(rule.valid?).to eq(false)
|
||||||
rule.channel = 'blah'
|
rule.channel_id = -1
|
||||||
expect(rule.valid?).to eq(false)
|
expect(rule.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -167,7 +160,7 @@ RSpec.describe DiscourseChat::Rule do
|
||||||
|
|
||||||
it "doesn't allow save when invalid" do
|
it "doesn't allow save when invalid" do
|
||||||
expect(rule.valid?).to eq(true)
|
expect(rule.valid?).to eq(true)
|
||||||
rule.provider = 'somerandomprovider'
|
rule.filter = 'somerandomfilter'
|
||||||
expect(rule.valid?).to eq(false)
|
expect(rule.valid?).to eq(false)
|
||||||
expect(rule.save).to eq(false)
|
expect(rule.save).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue