mirror of
https://github.com/discourse/discourse-chat-integration.git
synced 2025-07-06 22:02:14 +00:00
commit
4c379876b6
@ -118,7 +118,7 @@ class DiscourseChat::ChatController < ApplicationController
|
|||||||
|
|
||||||
def create_rule
|
def create_rule
|
||||||
begin
|
begin
|
||||||
hash = params.require(:rule).permit(:channel_id, :filter, :category_id, tags:[])
|
hash = params.require(:rule).permit(:channel_id, :type, :filter, :group_id, :category_id, tags:[])
|
||||||
|
|
||||||
rule = DiscourseChat::Rule.new(hash)
|
rule = DiscourseChat::Rule.new(hash)
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ class DiscourseChat::ChatController < ApplicationController
|
|||||||
def update_rule
|
def update_rule
|
||||||
begin
|
begin
|
||||||
rule = DiscourseChat::Rule.find(params[:id].to_i)
|
rule = DiscourseChat::Rule.find(params[:id].to_i)
|
||||||
hash = params.require(:rule).permit(:filter, :category_id, tags:[])
|
hash = params.require(:rule).permit(:type, :filter, :group_id, :category_id, tags:[])
|
||||||
|
|
||||||
if not rule.update(hash)
|
if not rule.update(hash)
|
||||||
raise Discourse::InvalidParameters, 'Rule is not valid'
|
raise Discourse::InvalidParameters, 'Rule is not valid'
|
||||||
|
@ -82,14 +82,25 @@ module DiscourseChat
|
|||||||
i = 1
|
i = 1
|
||||||
rules.each do |rule|
|
rules.each do |rule|
|
||||||
category_id = rule.category_id
|
category_id = rule.category_id
|
||||||
if category_id.nil?
|
|
||||||
category_name = I18n.t("chat_integration.all_categories")
|
case rule.type
|
||||||
else
|
when "normal"
|
||||||
category = Category.find_by(id: category_id)
|
if category_id.nil?
|
||||||
if category
|
category_name = I18n.t("chat_integration.all_categories")
|
||||||
category_name = category.slug
|
|
||||||
else
|
else
|
||||||
category_name = I18n.t("chat_integration.deleted_category")
|
category = Category.find_by(id: category_id)
|
||||||
|
if category
|
||||||
|
category_name = category.slug
|
||||||
|
else
|
||||||
|
category_name = I18n.t("chat_integration.deleted_category")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when "group_mention", "group_message"
|
||||||
|
group = Group.find_by(id: rule.group_id)
|
||||||
|
if group
|
||||||
|
category_name = I18n.t("chat_integration.#{rule.type}_template", name: group.name)
|
||||||
|
else
|
||||||
|
category_name = I18n.t("chat_integration.deleted_group")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,3 +48,5 @@ require_relative "../services/manager"
|
|||||||
require_relative "../jobs/regular/notify_chats"
|
require_relative "../jobs/regular/notify_chats"
|
||||||
|
|
||||||
require_relative "../../lib/discourse_chat/provider"
|
require_relative "../../lib/discourse_chat/provider"
|
||||||
|
|
||||||
|
require_relative "../jobs/onceoff/add_type_field"
|
||||||
|
9
app/jobs/onceoff/add_type_field.rb
Normal file
9
app/jobs/onceoff/add_type_field.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module Jobs
|
||||||
|
class DiscourseChatAddTypeField < Jobs::Onceoff
|
||||||
|
def execute_onceoff(args)
|
||||||
|
DiscourseChat::Rule.find_each do |rule|
|
||||||
|
rule.save(validate: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -59,7 +59,7 @@ class DiscourseChat::Channel < DiscourseChat::PluginModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def rules
|
def rules
|
||||||
DiscourseChat::Rule.with_channel_id(id)
|
DiscourseChat::Rule.with_channel_id(id).order_by_precedence
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :with_provider, ->(provider) { where("value::json->>'provider'=?", provider)}
|
scope :with_provider, ->(provider) { where("value::json->>'provider'=?", provider)}
|
||||||
|
@ -2,33 +2,56 @@ 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: [ :channel_id, :category_id, :tags, :filter ], coder: JSON
|
store :value, accessors: [ :channel_id, :type, :group_id, :category_id, :tags, :filter ], coder: JSON
|
||||||
|
|
||||||
after_initialize :init_filter
|
after_initialize :init_filter
|
||||||
|
|
||||||
def init_filter
|
def init_filter
|
||||||
self.filter ||= 'watch'
|
self.filter ||= 'watch'
|
||||||
|
self.type ||= 'normal'
|
||||||
end
|
end
|
||||||
|
|
||||||
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 :channel_valid?, :category_valid?, :tags_valid?
|
validates :type, :inclusion => { :in => %w(normal group_message group_mention),
|
||||||
|
:message => "%{value} is not a valid filter" }
|
||||||
|
|
||||||
|
validate :channel_valid?, :category_valid?, :group_valid?, :tags_valid?
|
||||||
|
|
||||||
def channel_valid?
|
def channel_valid?
|
||||||
# Validate category
|
# Validate channel
|
||||||
if not (DiscourseChat::Channel.where(id: channel_id).exists?)
|
if not (DiscourseChat::Channel.where(id: channel_id).exists?)
|
||||||
errors.add(:channel_id, "#{channel_id} is not a valid channel id")
|
errors.add(:channel_id, "#{channel_id} is not a valid channel id")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_valid?
|
def category_valid?
|
||||||
|
if type != 'normal' && !category_id.nil?
|
||||||
|
errors.add(:category_id, "cannot be specified for that type of rule")
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless type == 'normal'
|
||||||
|
|
||||||
# Validate category
|
# Validate category
|
||||||
if not (category_id.nil? or Category.where(id: category_id).exists?)
|
if not (category_id.nil? or Category.where(id: category_id).exists?)
|
||||||
errors.add(:category_id, "#{category_id} is not a valid category id")
|
errors.add(:category_id, "#{category_id} is not a valid category id")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def group_valid?
|
||||||
|
if type == 'normal' && !group_id.nil?
|
||||||
|
errors.add(:group_id, "cannot be specified for that type of rule")
|
||||||
|
end
|
||||||
|
|
||||||
|
return if type == 'normal'
|
||||||
|
|
||||||
|
# Validate group
|
||||||
|
if not Group.where(id: group_id).exists?
|
||||||
|
errors.add(:group_id, "#{group_id} is not a valid group id")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def tags_valid?
|
def tags_valid?
|
||||||
# Validate tags
|
# Validate tags
|
||||||
return if tags.nil?
|
return if tags.nil?
|
||||||
@ -48,22 +71,16 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Don't want this to end up as anything other than an integer
|
# These are only allowed to be integers
|
||||||
def category_id=(val)
|
%w(channel_id category_id group_id).each do |name|
|
||||||
if val.nil? or val.blank?
|
define_method "#{name}=" do |val|
|
||||||
super(nil)
|
if val.nil? or val.blank?
|
||||||
else
|
super(nil)
|
||||||
super(val.to_i)
|
else
|
||||||
|
super(val.to_i)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Don't want this to end up as anything other than an integer
|
|
||||||
def channel_id=(val)
|
|
||||||
if val.nil? or val.blank?
|
|
||||||
super(nil)
|
|
||||||
else
|
|
||||||
super(val.to_i)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Mock foreign key
|
# Mock foreign key
|
||||||
@ -75,12 +92,20 @@ class DiscourseChat::Rule < DiscourseChat::PluginModel
|
|||||||
self.channel_id = val.id
|
self.channel_id = val.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope :with_type, ->(type) { where("value::json->>'type'=?", type.to_s)}
|
||||||
|
|
||||||
scope :with_channel, ->(channel) { with_channel_id(channel.id) }
|
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_channel_id, ->(channel_id) { where("value::json->>'channel_id'=?", channel_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)}
|
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 :with_group_ids, ->(group_id) { where("value::json->>'group_id' IN (?)", group_id.map(&:to_s))}
|
||||||
|
|
||||||
scope :order_by_precedence, ->{ order("CASE
|
scope :order_by_precedence, ->{ order("CASE
|
||||||
|
WHEN value::json->>'type' = 'group_mention' THEN 1
|
||||||
|
WHEN value::json->>'type' = 'group_message' THEN 2
|
||||||
|
ELSE 3
|
||||||
|
END",
|
||||||
|
"CASE
|
||||||
WHEN value::json->>'filter' = 'mute' THEN 1
|
WHEN value::json->>'filter' = 'mute' THEN 1
|
||||||
WHEN value::json->>'filter' = 'watch' THEN 2
|
WHEN value::json->>'filter' = 'watch' THEN 2
|
||||||
WHEN value::json->>'filter' = 'follow' THEN 3
|
WHEN value::json->>'filter' = 'follow' THEN 3
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
class DiscourseChat::RuleSerializer < ApplicationSerializer
|
class DiscourseChat::RuleSerializer < ApplicationSerializer
|
||||||
attributes :id, :channel_id, :category_id, :tags, :filter
|
attributes :id, :channel_id, :type, :group_id, :group_name, :category_id, :tags, :filter
|
||||||
|
|
||||||
|
def group_name
|
||||||
|
if object.group_id
|
||||||
|
groups = Group.where(id:object.group_id)
|
||||||
|
if groups.exists?
|
||||||
|
return groups.first.name
|
||||||
|
else
|
||||||
|
return I18n.t("chat_integration.deleted_group")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
@ -18,14 +18,28 @@ module DiscourseChat
|
|||||||
|
|
||||||
topic = post.topic
|
topic = post.topic
|
||||||
|
|
||||||
# Abort if a private message (possible TODO: Add support for notifying about group PMs)
|
# Abort if topic is blank... this should never be the case
|
||||||
return if topic.blank? || topic.archetype == Archetype.private_message
|
return if topic.blank?
|
||||||
|
|
||||||
# Load all the rules that apply to this topic's category
|
# If it's a private message, filter rules by groups, otherwise filter rules by category
|
||||||
matching_rules = DiscourseChat::Rule.with_category_id(topic.category_id)
|
if topic.archetype == Archetype.private_message
|
||||||
|
group_ids_with_access = topic.topic_allowed_groups.pluck(:group_id)
|
||||||
|
return if group_ids_with_access.empty?
|
||||||
|
matching_rules = DiscourseChat::Rule.with_type('group_message').with_group_ids(group_ids_with_access)
|
||||||
|
else
|
||||||
|
matching_rules = DiscourseChat::Rule.with_type('normal').with_category_id(topic.category_id)
|
||||||
|
if topic.category # Also load the rules for the wildcard category
|
||||||
|
matching_rules += DiscourseChat::Rule.with_type('normal').with_category_id(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if topic.category # Also load the rules for the wildcard category
|
# If groups are mentioned, check for any matching rules and append them
|
||||||
matching_rules += DiscourseChat::Rule.with_category_id(nil)
|
mentions = post.raw_mentions
|
||||||
|
if mentions && mentions.length > 0
|
||||||
|
groups = Group.where('LOWER(name) IN (?)', mentions)
|
||||||
|
if groups.exists?
|
||||||
|
matching_rules += DiscourseChat::Rule.with_type('group_mention').with_group_ids(groups.map(&:id))
|
||||||
|
end
|
||||||
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
|
||||||
|
3
assets/javascripts/admin/components/channel-data.js.es6
Normal file
3
assets/javascripts/admin/components/channel-data.js.es6
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['channel-info'],
|
||||||
|
});
|
@ -26,8 +26,11 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
createRule(channel){
|
createRule(channel){
|
||||||
var newRule = this.get('store').createRecord('rule',{channel_id: channel.id});
|
this.sendAction('createRule', channel)
|
||||||
channel.rules.pushObject(newRule)
|
},
|
||||||
|
|
||||||
|
editRule(rule){
|
||||||
|
this.sendAction('editRule', rule, this.get('channel'))
|
||||||
},
|
},
|
||||||
|
|
||||||
showError(error_key){
|
showError(error_key){
|
||||||
|
@ -2,37 +2,33 @@ import { popupAjaxError } from 'discourse/lib/ajax-error';
|
|||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
tagName: 'tr',
|
tagName: 'tr',
|
||||||
editing: false,
|
|
||||||
|
|
||||||
autoEdit: function(){
|
isCategory: function(){
|
||||||
if(!this.get('rule').id){
|
return this.get('rule.type') == 'normal'
|
||||||
this.set('editing', true);
|
}.property('rule.type'),
|
||||||
}
|
|
||||||
}.on('init'),
|
isMessage: function(){
|
||||||
|
return this.get('rule.type') == 'group_message'
|
||||||
|
}.property('rule.type'),
|
||||||
|
|
||||||
|
isMention: function(){
|
||||||
|
return this.get('rule.type') == 'group_mention'
|
||||||
|
}.property('rule.type'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
edit: function(){
|
edit: function(){
|
||||||
this.set('editing', true);
|
this.sendAction('edit', this.get('rule'))
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function(){
|
|
||||||
this.send('refresh');
|
|
||||||
},
|
|
||||||
|
|
||||||
save: function(){
|
|
||||||
this.get('rule').save().then(result => {
|
|
||||||
this.send('refresh');
|
|
||||||
}).catch(popupAjaxError);
|
|
||||||
},
|
|
||||||
|
|
||||||
delete(rule){
|
delete(rule){
|
||||||
rule.destroyRecord().then(() => {
|
rule.destroyRecord().then(() => {
|
||||||
this.send('refresh');
|
this.send('refresh');
|
||||||
}).catch(popupAjaxError)
|
}).catch(popupAjaxError)
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(){
|
refresh: function(){
|
||||||
this.sendAction('refresh');
|
this.sendAction('refresh');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -35,6 +35,17 @@ export default Ember.Controller.extend({
|
|||||||
showModal('admin-plugins-chat-test', { model: model, admin: true });
|
showModal('admin-plugins-chat-test', { model: model, admin: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createRule(channel){
|
||||||
|
this.set('modalShowing', true);
|
||||||
|
var model = {rule: this.store.createRecord('rule',{channel_id: channel.id}), channel:channel, provider:this.get('model.provider'), groups:this.get('model.groups')};
|
||||||
|
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
|
||||||
|
},
|
||||||
|
editRule(rule, channel){
|
||||||
|
this.set('modalShowing', true);
|
||||||
|
var model = {rule: rule, channel:channel, provider:this.get('model.provider'), groups:this.get('model.groups')};
|
||||||
|
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
@ -0,0 +1,46 @@
|
|||||||
|
import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule'
|
||||||
|
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||||
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
import { extractError } from 'discourse/lib/ajax-error';
|
||||||
|
import InputValidation from 'discourse/models/input-validation';
|
||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
|
setupKeydown: function() {
|
||||||
|
Ember.run.schedule('afterRender', () => {
|
||||||
|
$('#chat_integration_edit_channel_modal').keydown(e => {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
this.send('save');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}.on('init'),
|
||||||
|
|
||||||
|
saveDisabled: function(){
|
||||||
|
return false;
|
||||||
|
}.property(),
|
||||||
|
|
||||||
|
@computed('model.rule.type')
|
||||||
|
showCategory: function(type){
|
||||||
|
return (type == "normal")
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
cancel: function(){
|
||||||
|
this.send('closeModal');
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function(){
|
||||||
|
if(this.get('saveDisabled')){return};
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
this.get('model.rule').save().then(function(result) {
|
||||||
|
self.send('closeModal');
|
||||||
|
}).catch(function(error) {
|
||||||
|
self.flash(extractError(error), 'error');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -9,12 +9,29 @@ export default RestModel.extend({
|
|||||||
{ id: 'mute', name: I18n.t('chat_integration.filter.mute'), icon: 'times-circle' }
|
{ id: 'mute', name: I18n.t('chat_integration.filter.mute'), icon: 'times-circle' }
|
||||||
],
|
],
|
||||||
|
|
||||||
|
available_types: [
|
||||||
|
{ id: 'normal', name: I18n.t('chat_integration.type.normal')},
|
||||||
|
{ id: 'group_message', name: I18n.t('chat_integration.type.group_message')},
|
||||||
|
{ id: 'group_mention', name: I18n.t('chat_integration.type.group_mention')}
|
||||||
|
],
|
||||||
|
|
||||||
category_id: null,
|
category_id: null,
|
||||||
tags: null,
|
tags: null,
|
||||||
channel_id: null,
|
channel_id: null,
|
||||||
filter: 'watch',
|
filter: 'watch',
|
||||||
|
type: 'normal',
|
||||||
error_key: null,
|
error_key: null,
|
||||||
|
|
||||||
|
|
||||||
|
removeUnneededInfo: function(){
|
||||||
|
const type=this.get('type');
|
||||||
|
if(type=='normal'){
|
||||||
|
this.set('group_id', null);
|
||||||
|
}else{
|
||||||
|
this.set('category_id', null);
|
||||||
|
}
|
||||||
|
}.observes('type'),
|
||||||
|
|
||||||
@computed('category_id')
|
@computed('category_id')
|
||||||
category(categoryId) {
|
category(categoryId) {
|
||||||
if (categoryId){
|
if (categoryId){
|
||||||
@ -30,12 +47,12 @@ export default RestModel.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateProperties() {
|
updateProperties() {
|
||||||
var prop_names = ['category_id','tags','filter'];
|
var prop_names = ['type','category_id','group_id','tags','filter'];
|
||||||
return this.getProperties(prop_names);
|
return this.getProperties(prop_names);
|
||||||
},
|
},
|
||||||
|
|
||||||
createProperties() {
|
createProperties() {
|
||||||
var prop_names = ['channel_id', 'category_id','tags','filter'];
|
var prop_names = ['type','channel_id', 'category_id','group_id','tags','filter'];
|
||||||
return this.getProperties(prop_names);
|
return this.getProperties(prop_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
import Group from 'discourse/models/group';
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
|
|
||||||
model(params, transition) {
|
model(params, transition) {
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
channels: this.store.findAll('channel', {provider: params.provider}),
|
channels: this.store.findAll('channel', {provider: params.provider}),
|
||||||
provider: this.modelFor("admin-plugins-chat").findBy('id',params.provider)
|
provider: this.modelFor("admin-plugins-chat").findBy('id',params.provider),
|
||||||
|
groups: Group.findAll().then(groups => {
|
||||||
|
return groups.filter(g => !g.get('automatic'));
|
||||||
|
})
|
||||||
}).then(value => {
|
}).then(value => {
|
||||||
value.channels.forEach(channel => {
|
value.channels.forEach(channel => {
|
||||||
channel.set('rules', channel.rules.map(rule => {
|
channel.set('rules', channel.rules.map(rule => {
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
{{#d-modal-body id="chat_integration_edit_rule_modal" title="chat_integration.edit_rule_modal.title"}}
|
||||||
|
<div>
|
||||||
|
<form {{action "save" on="submit"}}>
|
||||||
|
<table>
|
||||||
|
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='provider'>{{i18n "chat_integration.edit_rule_modal.provider"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{i18n (concat 'chat_integration.provider.' model.channel.provider '.title')}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='channel'>{{i18n "chat_integration.edit_rule_modal.channel"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{channel-data provider=model.provider channel=model.channel}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='filter'>{{i18n "chat_integration.edit_rule_modal.type"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{combo-box name="type" content=model.rule.available_types value=model.rule.type}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.type'}}</label></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='filter'>{{i18n "chat_integration.edit_rule_modal.filter"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{combo-box name="filter" content=model.rule.available_filters value=model.rule.filter}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.filter'}}</label></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{{#if showCategory}}
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='category'>{{i18n "chat_integration.edit_rule_modal.category"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{category-chooser
|
||||||
|
name="category"
|
||||||
|
value=model.rule.category_id
|
||||||
|
rootNoneLabel="chat_integration.all_categories"
|
||||||
|
rootNone=true
|
||||||
|
overrideWidths=false
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.category'}}</label></td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='group'>{{i18n "chat_integration.edit_rule_modal.group"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{combo-box content=model.groups valueAttribute="id" value=model.rule.group_id none="chat_integration.choose_group"}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.group'}}</label></td>
|
||||||
|
</tr>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{{#if siteSettings.tagging_enabled}}
|
||||||
|
<tr class="input">
|
||||||
|
<td class="label"><label for='tags'>{{i18n "chat_integration.edit_rule_modal.tags"}}</label></td>
|
||||||
|
<td>
|
||||||
|
{{tag-chooser placeholderKey="chat_integration.all_tags" name="tags" tags=model.rule.tags}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="instructions">
|
||||||
|
<td></td>
|
||||||
|
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.tags'}}</label></td>
|
||||||
|
</tr>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{/d-modal-body}}
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
|
||||||
|
{{d-button id="save_channel" class='btn-primary btn-large' action="save" title="chat_integration.edit_rule_modal.save" label="chat_integration.edit_rule_modal.save" disabled=saveDisabled}}
|
||||||
|
|
||||||
|
{{d-button class="btn-large" action="cancel" title="chat_integration.edit_rule_modal.cancel" label="chat_integration.edit_rule_modal.cancel"}}
|
||||||
|
|
||||||
|
</div>
|
@ -14,6 +14,8 @@
|
|||||||
refresh='refresh'
|
refresh='refresh'
|
||||||
edit='editChannel'
|
edit='editChannel'
|
||||||
test='testChannel'
|
test='testChannel'
|
||||||
|
createRule='createRule'
|
||||||
|
editRule='editRule'
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
{{# each provider.channel_parameters as |param|}}
|
||||||
|
{{#if param.hidden}}{{else}}
|
||||||
|
<span class='field-name'>{{i18n (concat 'chat_integration.provider.' channel.provider '.param.' param.key '.title')}}:</span>
|
||||||
|
<span class='field-value'>{{get channel.data param.key}}</span>
|
||||||
|
<br/>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
@ -12,14 +12,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
{{# each provider.channel_parameters as |param|}}
|
{{channel-data provider=provider channel=channel}}
|
||||||
|
|
||||||
{{#if param.hidden}}{{else}}
|
|
||||||
<span class='field-name'>{{i18n (concat 'chat_integration.provider.' channel.provider '.param.' param.key '.title')}}:</span>
|
|
||||||
<span class='field-value'>{{get channel.data param.key}}</span>
|
|
||||||
<br/>
|
|
||||||
{{/if}}
|
|
||||||
{{/each}}
|
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -43,7 +36,7 @@
|
|||||||
|
|
||||||
|
|
||||||
{{#each channel.rules as |rule|}}
|
{{#each channel.rules as |rule|}}
|
||||||
{{rule-row rule=rule refresh=refresh}}
|
{{rule-row rule=rule edit='editRule' refresh='refresh'}}
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
@ -1,53 +1,35 @@
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
{{#if editing}}
|
{{rule.filterName}}
|
||||||
{{combo-box name="filter" content=rule.available_filters value=rule.filter}}
|
|
||||||
{{else}}
|
|
||||||
{{rule.filterName}}
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
{{#if editing}}
|
{{#if isCategory}}
|
||||||
{{category-chooser
|
|
||||||
name="category"
|
|
||||||
value=rule.category_id
|
|
||||||
rootNoneLabel="chat_integration.all_categories"
|
|
||||||
rootNone=true
|
|
||||||
overrideWidths=false
|
|
||||||
}}
|
|
||||||
{{else}}
|
|
||||||
{{#if rule.category}}
|
{{#if rule.category}}
|
||||||
{{category-link rule.category allowUncategorized="true" link="false"}}
|
{{category-link rule.category allowUncategorized="true" link="false"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{i18n "chat_integration.all_categories"}}
|
{{i18n "chat_integration.all_categories"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{else if isMention}}
|
||||||
|
{{i18n "chat_integration.group_mention_template" name=rule.group_name}}
|
||||||
|
{{else if isMessage}}
|
||||||
|
{{i18n "chat_integration.group_message_template" name=rule.group_name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
{{#if siteSettings.tagging_enabled}}
|
{{#if siteSettings.tagging_enabled}}
|
||||||
<td>
|
<td>
|
||||||
{{#if editing}}
|
{{#if rule.tags}}
|
||||||
{{tag-chooser placeholderKey="chat_integration.all_tags" name="tags" tags=rule.tags}}
|
{{rule.tags}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if rule.tags}}
|
{{i18n "chat_integration.all_tags"}}
|
||||||
{{rule.tags}}
|
|
||||||
{{else}}
|
|
||||||
{{i18n "chat_integration.all_tags"}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
{{#if editing}}
|
{{d-button action="edit" actionParam=rule icon="pencil" class="edit" title="chat_integration.rule_table.edit_rule"}}
|
||||||
{{d-button action="save" actionParam=rule icon="check" class="ok" title="chat_integration.rule_table.save_rule"}}
|
{{d-button action="delete" actionParam=rule icon="trash-o" class="delete" title="chat_integration.rule_table.delete_rule"}}
|
||||||
{{d-button action="cancel" actionParam=rule icon="times" class="cancel" title="chat_integration.rule_table.cancel_edit"}}
|
|
||||||
{{else}}
|
|
||||||
{{d-button action="edit" actionParam=rule icon="pencil" class="edit" title="chat_integration.rule_table.edit_rule"}}
|
|
||||||
{{d-button action="delete" actionParam=rule icon="trash-o" class="delete" title="chat_integration.rule_table.delete_rule"}}
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat_integration_edit_channel_modal, #chat_integration_test_modal{
|
#chat_integration_edit_channel_modal, #chat_integration_test_modal, #chat_integration_edit_rule_modal{
|
||||||
table{
|
table{
|
||||||
width:100%;
|
width:100%;
|
||||||
|
|
||||||
@ -90,5 +90,8 @@
|
|||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-name{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@ en:
|
|||||||
no_providers: "You need to enable some providers in the plugin settings"
|
no_providers: "You need to enable some providers in the plugin settings"
|
||||||
channels_with_errors: "Some channels for this provider failed last time messages were sent. Click the error icon(s) to learn more."
|
channels_with_errors: "Some channels for this provider failed last time messages were sent. Click the error icon(s) to learn more."
|
||||||
channel_exception: "An unknown error occured when a message was last sent to this channel. Check the site logs for more information."
|
channel_exception: "An unknown error occured when a message was last sent to this channel. Check the site logs for more information."
|
||||||
|
group_mention_template: "Mentions of: @{{name}}"
|
||||||
|
group_message_template: "Messages to: @{{name}}"
|
||||||
|
choose_group: "(choose a group)"
|
||||||
all_categories: "(all categories)"
|
all_categories: "(all categories)"
|
||||||
all_tags: "(all tags)"
|
all_tags: "(all tags)"
|
||||||
create_rule: "Create Rule"
|
create_rule: "Create Rule"
|
||||||
@ -21,6 +24,10 @@ en:
|
|||||||
close: "Close"
|
close: "Close"
|
||||||
error: "An unknown error occured while sending the message. Check the site logs for more information."
|
error: "An unknown error occured while sending the message. Check the site logs for more information."
|
||||||
success: "Message sent successfully"
|
success: "Message sent successfully"
|
||||||
|
type:
|
||||||
|
normal: Normal
|
||||||
|
group_message: Group Message
|
||||||
|
group_mention: Group Mention
|
||||||
filter:
|
filter:
|
||||||
mute: 'Mute'
|
mute: 'Mute'
|
||||||
follow: 'First post only'
|
follow: 'First post only'
|
||||||
@ -39,6 +46,23 @@ en:
|
|||||||
channel_validation:
|
channel_validation:
|
||||||
ok: "Valid"
|
ok: "Valid"
|
||||||
fail: "Invalid format"
|
fail: "Invalid format"
|
||||||
|
edit_rule_modal:
|
||||||
|
title: Edit Rule
|
||||||
|
save: Save Rule
|
||||||
|
cancel: Cancel
|
||||||
|
provider: Provider
|
||||||
|
type: Type
|
||||||
|
channel: Channel
|
||||||
|
filter: Filter
|
||||||
|
category: Category
|
||||||
|
group: Group
|
||||||
|
tags: Tags
|
||||||
|
instructions:
|
||||||
|
type: "Change the type to trigger notifications for group messages or mentions"
|
||||||
|
filter: "Notification level. Mute overrides other matching rules"
|
||||||
|
category: "This rule will only apply to topics in the specified category"
|
||||||
|
group: "This rule will apply to posts referencing this group"
|
||||||
|
tags: "If specified, this rule will only apply to topics which have at least one of these tags"
|
||||||
|
|
||||||
provider:
|
provider:
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@ en:
|
|||||||
|
|
||||||
all_categories: "(all categories)"
|
all_categories: "(all categories)"
|
||||||
deleted_category: "(deleted category)"
|
deleted_category: "(deleted category)"
|
||||||
|
deleted_group: "(deleted group)"
|
||||||
|
|
||||||
|
group_mention_template: "mentions of: @%{name}"
|
||||||
|
group_message_template: "messages to: @%{name}"
|
||||||
|
|
||||||
provider:
|
provider:
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ describe 'Chat Controller', type: :request do
|
|||||||
"provider" => 'dummy',
|
"provider" => 'dummy',
|
||||||
"data" => {},
|
"data" => {},
|
||||||
"error_key" => nil,
|
"error_key" => nil,
|
||||||
"rules" => [{"id" => rule.id, "filter" => "follow", "channel_id" => channel.id, "category_id" => category.id, "tags" => [tag.name]}]
|
"rules" => [{"id" => rule.id, "type" => 'normal', "group_name" => nil, "group_id" => nil, "filter" => "follow", "channel_id" => channel.id, "category_id" => category.id, "tags" => [tag.name]}]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -152,16 +152,18 @@ RSpec.describe DiscourseChat::Manager do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'with some rules' do
|
context 'with some rules' do
|
||||||
|
let(:group){Fabricate(:group)}
|
||||||
before do
|
before do
|
||||||
DiscourseChat::Rule.create!(channel: chan1, filter:'watch', category_id:category.id, tags:nil)
|
DiscourseChat::Rule.create!(channel: chan1, filter:'watch', category_id:category.id, tags:nil)
|
||||||
DiscourseChat::Rule.create!(channel: chan1, filter:'mute', category_id:nil, tags:nil)
|
DiscourseChat::Rule.create!(channel: chan1, filter:'mute', category_id:nil, tags:nil)
|
||||||
DiscourseChat::Rule.create!(channel: chan1, filter:'follow', category_id:nil, tags:[tag1.name])
|
DiscourseChat::Rule.create!(channel: chan1, filter:'follow', category_id:nil, tags:[tag1.name])
|
||||||
|
DiscourseChat::Rule.create!(channel: chan1, filter:'watch', type: 'group_message', group_id:group.id)
|
||||||
DiscourseChat::Rule.create!(channel: chan2, filter:'watch', category_id:1, tags:nil)
|
DiscourseChat::Rule.create!(channel: chan2, filter:'watch', category_id:1, tags:nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'displays the correct rules' do
|
it 'displays the correct rules' do
|
||||||
string = DiscourseChat::Helper.status_for_channel(chan1)
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
||||||
expect(string.scan('status.rule_string').size).to eq(3)
|
expect(string.scan('status.rule_string').size).to eq(4)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'only displays tags for rules with tags' do
|
it 'only displays tags for rules with tags' do
|
||||||
|
@ -8,6 +8,8 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
let(:tag2){Fabricate(:tag)}
|
let(:tag2){Fabricate(:tag)}
|
||||||
|
|
||||||
let(:channel){DiscourseChat::Channel.create(provider:'dummy')}
|
let(:channel){DiscourseChat::Channel.create(provider:'dummy')}
|
||||||
|
let(:category) {Fabricate(:category)}
|
||||||
|
let(:group) {Fabricate(:group)}
|
||||||
|
|
||||||
describe '.alloc_key' do
|
describe '.alloc_key' do
|
||||||
it 'should return sequential numbers' do
|
it 'should return sequential numbers' do
|
||||||
@ -28,7 +30,7 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
|
|
||||||
rule = DiscourseChat::Rule.create({
|
rule = DiscourseChat::Rule.create({
|
||||||
channel: channel,
|
channel: channel,
|
||||||
category_id: 1,
|
category_id: category.id,
|
||||||
tags: [tag1.name, tag2.name],
|
tags: [tag1.name, tag2.name],
|
||||||
filter: 'watch'
|
filter: 'watch'
|
||||||
})
|
})
|
||||||
@ -38,7 +40,7 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
loadedRule = DiscourseChat::Rule.find(rule.id)
|
loadedRule = DiscourseChat::Rule.find(rule.id)
|
||||||
|
|
||||||
expect(loadedRule.channel.id).to eq(channel.id)
|
expect(loadedRule.channel.id).to eq(channel.id)
|
||||||
expect(loadedRule.category_id).to eq(1)
|
expect(loadedRule.category_id).to eq(category.id)
|
||||||
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')
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
before do
|
before do
|
||||||
rule = DiscourseChat::Rule.create({
|
rule = DiscourseChat::Rule.create({
|
||||||
channel: channel,
|
channel: channel,
|
||||||
category_id: 1,
|
category_id: category.id,
|
||||||
tags: [tag1.name, tag2.name]
|
tags: [tag1.name, tag2.name]
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -102,15 +104,42 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'can be filtered by category' do
|
it 'can be filtered by category' do
|
||||||
rule2 = DiscourseChat::Rule.create(channel:channel, category_id: 1)
|
rule2 = DiscourseChat::Rule.create(channel:channel, category_id: category.id)
|
||||||
rule3 = DiscourseChat::Rule.create(channel:channel, category_id: nil)
|
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_id(1).length).to eq(2)
|
expect(DiscourseChat::Rule.with_category_id(category.id).length).to eq(2)
|
||||||
expect(DiscourseChat::Rule.with_category_id(nil).length).to eq(1)
|
expect(DiscourseChat::Rule.with_category_id(nil).length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'can be filtered by group' do
|
||||||
|
group1 = Fabricate(:group)
|
||||||
|
group2 = Fabricate(:group)
|
||||||
|
rule2 = DiscourseChat::Rule.create!(channel:channel, type:'group_message', group_id: group1.id)
|
||||||
|
rule3 = DiscourseChat::Rule.create!(channel:channel, type:'group_message', group_id: group2.id)
|
||||||
|
|
||||||
|
expect(DiscourseChat::Rule.all.length).to eq(3)
|
||||||
|
|
||||||
|
expect(DiscourseChat::Rule.with_category_id(category.id).length).to eq(1)
|
||||||
|
expect(DiscourseChat::Rule.with_group_ids([group1.id,group2.id]).length).to eq(2)
|
||||||
|
expect(DiscourseChat::Rule.with_group_ids([group1.id]).length).to eq(1)
|
||||||
|
expect(DiscourseChat::Rule.with_group_ids([group2.id]).length).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can be filtered by type' do
|
||||||
|
group1 = Fabricate(:group)
|
||||||
|
|
||||||
|
rule2 = DiscourseChat::Rule.create!(channel: channel, type: 'group_message', group_id: group1.id)
|
||||||
|
rule3 = DiscourseChat::Rule.create!(channel: channel, type: 'group_mention', group_id: group1.id)
|
||||||
|
|
||||||
|
expect(DiscourseChat::Rule.all.length).to eq(3)
|
||||||
|
|
||||||
|
expect(DiscourseChat::Rule.with_type('group_message').length).to eq(1)
|
||||||
|
expect(DiscourseChat::Rule.with_type('group_mention').length).to eq(1)
|
||||||
|
expect(DiscourseChat::Rule.with_type('normal').length).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
it 'can be sorted by precedence' do
|
it 'can be sorted by precedence' do
|
||||||
rule2 = DiscourseChat::Rule.create(channel:channel, filter:'mute')
|
rule2 = DiscourseChat::Rule.create(channel:channel, filter:'mute')
|
||||||
rule3 = DiscourseChat::Rule.create(channel:channel, filter:'follow')
|
rule3 = DiscourseChat::Rule.create(channel:channel, filter:'follow')
|
||||||
@ -128,7 +157,7 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
DiscourseChat::Rule.create({
|
DiscourseChat::Rule.create({
|
||||||
filter: 'watch',
|
filter: 'watch',
|
||||||
channel: channel,
|
channel: channel,
|
||||||
category_id: 1,
|
category_id: category.id,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -140,9 +169,27 @@ RSpec.describe DiscourseChat::Rule do
|
|||||||
expect(rule.valid?).to eq(false)
|
expect(rule.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "doesn't allow both category and group to be set" do
|
||||||
|
expect(rule.valid?).to eq(true)
|
||||||
|
rule.group_id = group.id
|
||||||
|
expect(rule.valid?).to eq(false)
|
||||||
|
rule.category_id = nil
|
||||||
|
rule.type = "group_message"
|
||||||
|
expect(rule.valid?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'validates group correctly' do
|
||||||
|
rule.category_id = nil
|
||||||
|
rule.group_id = group.id
|
||||||
|
rule.type = "group_message"
|
||||||
|
expect(rule.valid?).to eq(true)
|
||||||
|
rule.group_id = -99
|
||||||
|
expect(rule.valid?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
it 'validates category correctly' do
|
it 'validates category correctly' do
|
||||||
expect(rule.valid?).to eq(true)
|
expect(rule.valid?).to eq(true)
|
||||||
rule.category_id = 99
|
rule.category_id = -99
|
||||||
expect(rule.valid?).to eq(false)
|
expect(rule.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ RSpec.describe DiscourseChat::Manager do
|
|||||||
|
|
||||||
let(:manager) {::DiscourseChat::Manager}
|
let(:manager) {::DiscourseChat::Manager}
|
||||||
let(:category) {Fabricate(:category)}
|
let(:category) {Fabricate(:category)}
|
||||||
|
let(:group) {Fabricate(:group)}
|
||||||
let(:topic){Fabricate(:topic, category_id: category.id )}
|
let(:topic){Fabricate(:topic, category_id: category.id )}
|
||||||
let(:first_post) {Fabricate(:post, topic: topic)}
|
let(:first_post) {Fabricate(:post, topic: topic)}
|
||||||
let(:second_post) {Fabricate(:post, topic: topic, post_number:2)}
|
let(:second_post) {Fabricate(:post, topic: topic, post_number:2)}
|
||||||
@ -107,6 +108,43 @@ RSpec.describe DiscourseChat::Manager do
|
|||||||
expect(provider.sent_to_channel_ids).to contain_exactly()
|
expect(provider.sent_to_channel_ids).to contain_exactly()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should work for group pms" do
|
||||||
|
DiscourseChat::Rule.create!(channel: chan1, filter: 'watch' ) # Wildcard watch
|
||||||
|
DiscourseChat::Rule.create!(channel: chan2, type: 'group_message', filter: 'watch', group_id: group.id ) # Group watch
|
||||||
|
|
||||||
|
private_post = Fabricate(:private_message_post)
|
||||||
|
private_post.topic.invite_group(Fabricate(:user), group)
|
||||||
|
|
||||||
|
manager.trigger_notifications(private_post.id)
|
||||||
|
|
||||||
|
expect(provider.sent_to_channel_ids).to contain_exactly(chan2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work for pms with multiple groups" do
|
||||||
|
group2 = Fabricate(:group)
|
||||||
|
DiscourseChat::Rule.create!(channel: chan1, type: 'group_message', filter: 'watch', group_id: group.id )
|
||||||
|
DiscourseChat::Rule.create!(channel: chan2, type: 'group_message', filter: 'watch', group_id: group2.id )
|
||||||
|
|
||||||
|
private_post = Fabricate(:private_message_post)
|
||||||
|
private_post.topic.invite_group(Fabricate(:user), group)
|
||||||
|
private_post.topic.invite_group(Fabricate(:user), group2)
|
||||||
|
|
||||||
|
manager.trigger_notifications(private_post.id)
|
||||||
|
|
||||||
|
expect(provider.sent_to_channel_ids).to contain_exactly(chan1.id, chan2.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work for group mentions" do
|
||||||
|
third_post = Fabricate(:post, topic: topic, post_number: 3, raw: "let's mention @#{group.name}")
|
||||||
|
|
||||||
|
DiscourseChat::Rule.create!(channel: chan1, filter: 'watch') # Wildcard watch
|
||||||
|
DiscourseChat::Rule.create!(channel: chan2, type: 'group_message', filter: 'watch', group_id: group.id)
|
||||||
|
DiscourseChat::Rule.create!(channel: chan3, type: 'group_mention', filter: 'watch', group_id: group.id)
|
||||||
|
|
||||||
|
manager.trigger_notifications(third_post.id)
|
||||||
|
expect(provider.sent_to_channel_ids).to contain_exactly(chan1.id, chan3.id)
|
||||||
|
end
|
||||||
|
|
||||||
it "should not notify about posts the chat_user cannot see" do
|
it "should not notify about posts the chat_user cannot see" do
|
||||||
DiscourseChat::Rule.create!(channel: chan1, filter: 'follow', category_id: nil ) # Wildcard watch
|
DiscourseChat::Rule.create!(channel: chan1, filter: 'follow', category_id: nil ) # Wildcard watch
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ acceptance("Chat Integration", {
|
|||||||
server.post('/admin/plugins/chat/test', () => {
|
server.post('/admin/plugins/chat/test', () => {
|
||||||
return response({ });
|
return response({ });
|
||||||
});
|
});
|
||||||
|
server.get('/groups/search.json', () => {
|
||||||
|
return response([]);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user