diff --git a/app/helpers/helper.rb b/app/helpers/helper.rb index d04b4e9..50c0479 100644 --- a/app/helpers/helper.rb +++ b/app/helpers/helper.rb @@ -3,7 +3,7 @@ module DiscourseChat # Produce a string with a list of all rules associated with a channel def self.status_for_channel(channel) - rules = channel.rules + rules = channel.rules.order_by_precedence provider = channel.provider text = I18n.t("chat_integration.provider.#{provider}.status.header") + "\n" @@ -45,7 +45,7 @@ module DiscourseChat # Delete a rule based on its (1 based) index as seen in the # status_for_channel function def self.delete_by_index(channel, index) - rules = DiscourseChat::Rule.with_channel(channel) + rules = channel.rules.order_by_precedence return false if index < 1 or index > rules.size diff --git a/app/models/rule.rb b/app/models/rule.rb index 0357b3f..79baa64 100644 --- a/app/models/rule.rb +++ b/app/models/rule.rb @@ -80,4 +80,10 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel 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)} + scope :order_by_precedence, ->{ order("CASE + WHEN value::json->>'filter' = 'mute' THEN 1 + WHEN value::json->>'filter' = 'watch' THEN 2 + WHEN value::json->>'filter' = 'follow' THEN 3 + END") } + end \ No newline at end of file diff --git a/app/serializers/channel_serializer.rb b/app/serializers/channel_serializer.rb index 4022976..2317434 100644 --- a/app/serializers/channel_serializer.rb +++ b/app/serializers/channel_serializer.rb @@ -4,7 +4,7 @@ class DiscourseChat::ChannelSerializer < ApplicationSerializer attributes :id, :provider, :data, :rules def rules - object.rules.map do |rule| + object.rules.order_by_precedence.map do |rule| DiscourseChat::RuleSerializer.new(rule, root:false) end end diff --git a/spec/models/rule_spec.rb b/spec/models/rule_spec.rb index 0c218ad..f292741 100644 --- a/spec/models/rule_spec.rb +++ b/spec/models/rule_spec.rb @@ -110,6 +110,16 @@ RSpec.describe DiscourseChat::Rule do expect(DiscourseChat::Rule.with_category_id(1).length).to eq(2) expect(DiscourseChat::Rule.with_category_id(nil).length).to eq(1) end + + it 'can be sorted by precedence' do + rule2 = DiscourseChat::Rule.create(channel:channel, filter:'mute') + rule3 = DiscourseChat::Rule.create(channel:channel, filter:'follow') + rule4 = DiscourseChat::Rule.create(channel:channel, filter:'mute') + + expect(DiscourseChat::Rule.all.length).to eq(4) + + expect(DiscourseChat::Rule.all.order_by_precedence.map(&:filter)).to eq(["mute", "mute", "watch", "follow"]) + end end describe 'validations' do