FEATURE: Filter topic and post web hook events by tags (#6726)
* FEATURE: Filter topic and post web hook events by tags * Add a spec test with unmatched tags
This commit is contained in:
parent
1a71f98d28
commit
d33d031742
|
@ -9,6 +9,11 @@ export default Ember.Controller.extend({
|
|||
defaultEventTypes: Ember.computed.alias("adminWebHooks.defaultEventTypes"),
|
||||
contentTypes: Ember.computed.alias("adminWebHooks.contentTypes"),
|
||||
|
||||
@computed
|
||||
showTagsFilter() {
|
||||
return this.siteSettings.tagging_enabled;
|
||||
},
|
||||
|
||||
@computed("model.isSaving", "saved", "saveButtonDisabled")
|
||||
savingStatus(isSaving, saved, saveButtonDisabled) {
|
||||
if (isSaving) {
|
||||
|
|
|
@ -63,6 +63,7 @@ export default RestModel.extend({
|
|||
createProperties() {
|
||||
const types = this.get("web_hook_event_types");
|
||||
const categoryIds = this.get("categories").map(c => c.id);
|
||||
const tagNames = this.get("tag_names");
|
||||
|
||||
// Hack as {{group-selector}} accepts a comma-separated string as data source, but
|
||||
// we use an array to populate the datasource above.
|
||||
|
@ -81,6 +82,7 @@ export default RestModel.extend({
|
|||
? [null]
|
||||
: types.map(type => type.id),
|
||||
category_ids: Ember.isEmpty(categoryIds) ? [null] : categoryIds,
|
||||
tag_names: Ember.isEmpty(tagNames) ? [null] : tagNames,
|
||||
group_ids:
|
||||
Ember.isEmpty(groupNames) || Ember.isEmpty(groupNames[0])
|
||||
? [null]
|
||||
|
|
|
@ -19,6 +19,7 @@ export default Discourse.Route.extend({
|
|||
}
|
||||
|
||||
model.set("category_ids", model.get("category_ids"));
|
||||
model.set("tag_names", model.get("tag_names"));
|
||||
model.set("group_ids", model.get("group_ids"));
|
||||
controller.setProperties({ model, saved: false });
|
||||
},
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
{{category-selector categories=model.categories}}
|
||||
<div class="instructions">{{i18n 'admin.web_hooks.categories_filter_instructions'}}</div>
|
||||
</div>
|
||||
{{#if showTagsFilter}}
|
||||
<div class="filter">
|
||||
<label>{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.tags_filter'}}</label>
|
||||
{{tag-chooser tags=model.tag_names everyTag=true}}
|
||||
<div class="instructions">{{i18n 'admin.web_hooks.tags_filter_instructions'}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="filter">
|
||||
<label>{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.groups_filter'}}</label>
|
||||
{{group-selector groupNames=model.groupsFilterInName groupFinder=model.groupFinder}}
|
||||
|
|
|
@ -111,6 +111,7 @@ class Admin::WebHooksController < Admin::AdminController
|
|||
:wildcard_web_hook, :active, :verify_certificate,
|
||||
web_hook_event_type_ids: [],
|
||||
group_ids: [],
|
||||
tag_names: [],
|
||||
category_ids: [])
|
||||
end
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ module Jobs
|
|||
return if web_hook.category_ids.present? && (!args[:category_id].present? ||
|
||||
!web_hook.category_ids.include?(args[:category_id]))
|
||||
|
||||
return if web_hook.tag_ids.present? && (args[:tag_ids].blank? ||
|
||||
(web_hook.tag_ids & args[:tag_ids]).blank?)
|
||||
|
||||
raise Discourse::InvalidParameters.new(:payload) unless args[:payload].present?
|
||||
args[:payload] = JSON.parse(args[:payload])
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ class WebHook < ActiveRecord::Base
|
|||
has_and_belongs_to_many :web_hook_event_types
|
||||
has_and_belongs_to_many :groups
|
||||
has_and_belongs_to_many :categories
|
||||
has_and_belongs_to_many :tags
|
||||
|
||||
has_many :web_hook_events, dependent: :destroy
|
||||
|
||||
|
@ -15,6 +16,10 @@ class WebHook < ActiveRecord::Base
|
|||
|
||||
before_save :strip_url
|
||||
|
||||
def tag_names=(tag_names_arg)
|
||||
DiscourseTagging.add_or_create_tags_by_name(self, tag_names_arg, unlimited: true)
|
||||
end
|
||||
|
||||
def self.content_types
|
||||
@content_types ||= Enum.new('application/json' => 1,
|
||||
'application/x-www-form-urlencoded' => 2)
|
||||
|
@ -68,6 +73,7 @@ class WebHook < ActiveRecord::Base
|
|||
WebHook.enqueue_hooks(:topic, event,
|
||||
id: topic.id,
|
||||
category_id: topic&.category_id,
|
||||
tag_ids: topic&.tags.pluck(:id),
|
||||
payload: payload
|
||||
)
|
||||
end
|
||||
|
@ -80,6 +86,7 @@ class WebHook < ActiveRecord::Base
|
|||
WebHook.enqueue_hooks(:post, event,
|
||||
id: post.id,
|
||||
category_id: post&.topic&.category_id,
|
||||
tag_ids: post&.topic&.tags.pluck(:id),
|
||||
payload: payload
|
||||
)
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ class AdminWebHookSerializer < ApplicationSerializer
|
|||
:web_hook_event_types
|
||||
|
||||
has_many :categories, serializer: BasicCategorySerializer, embed: :ids, include: false
|
||||
has_many :tags, key: :tag_names, serializer: TagSerializer, embed: :ids, embed_key: :name, include: false
|
||||
has_many :groups, serializer: BasicGroupSerializer, embed: :ids, include: false
|
||||
|
||||
def web_hook_event_types
|
||||
|
|
|
@ -3082,6 +3082,8 @@ en:
|
|||
active_notice: "We will deliver event details when it happens."
|
||||
categories_filter_instructions: "Relevant webhooks will only be triggered if the event is related with specified categories. Leave blank to trigger webhooks for all categories."
|
||||
categories_filter: "Triggered Categories"
|
||||
tags_filter_instructions: "Relevant webhooks will only be triggered if the event is related with specified tags. Leave blank to trigger webhooks for all tags."
|
||||
tags_filter: "Triggered Tags"
|
||||
groups_filter_instructions: "Relevant webhooks will only be triggered if the event is related with specified groups. Leave blank to trigger webhooks for all groups."
|
||||
groups_filter: "Triggered Groups"
|
||||
delete_confirm: "Delete this webhook?"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
class CreateJoinTableWebHooksTags < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_join_table :web_hooks, :tags do |t|
|
||||
t.index [:web_hook_id, :tag_id], name: 'web_hooks_tags', unique: true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -125,6 +125,42 @@ describe Jobs::EmitWebHookEvent do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with tag filters' do
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
let(:topic) { Fabricate(:topic, tags: [tag]) }
|
||||
let(:topic_hook) { Fabricate(:topic_web_hook, tags: [tag]) }
|
||||
|
||||
it "doesn't emit when event is not included any tags" do
|
||||
subject.execute(
|
||||
web_hook_id: topic_hook.id,
|
||||
event_type: 'topic',
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
|
||||
it "doesn't emit when event is not related with defined tags" do
|
||||
subject.execute(
|
||||
web_hook_id: topic_hook.id,
|
||||
event_type: 'topic',
|
||||
tag_ids: [Fabricate(:tag).id],
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
|
||||
it 'emit when event is related with defined tags' do
|
||||
stub_request(:post, "https://meta.discourse.org/webhook_listener")
|
||||
.with(body: "{\"topic\":{\"test\":\"some payload\"}}")
|
||||
.to_return(body: 'OK', status: 200)
|
||||
|
||||
subject.execute(
|
||||
web_hook_id: topic_hook.id,
|
||||
event_type: 'topic',
|
||||
tag_ids: topic.tags.pluck(:id),
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#web_hook_request' do
|
||||
it 'creates delivery event record' do
|
||||
stub_request(:post, "https://meta.discourse.org/webhook_listener")
|
||||
|
|
Loading…
Reference in New Issue