FEATURE: Added trigger for topic tags changed (#28176)
* FEATURE: Added trigger for topic tags changed * DEV: register new file in plugin.rb * DEV: update to use already existing `:topic_tags_changed` event * DEV: Add tests to topic_tags_changed trigger remove `watching_user` field * DEV: add more tests to topic_tags_changed_spec.rb * DEV: update tests and implementation for topic tags changed automation trigger * DEV: update checking for tags changed automation * DEV: Update argument application for `handle_topic_tags_changed`
This commit is contained in:
parent
7977ae61f7
commit
ec46487870
|
@ -203,6 +203,14 @@ en:
|
|||
valid_trust_levels:
|
||||
label: Valid trust levels
|
||||
description: Will trigger only if post is created by user in these trust levels, defaults to any trust level
|
||||
topic_tags_changed:
|
||||
fields:
|
||||
watching_categories:
|
||||
label: Watching categories
|
||||
description: Will trigger only if the topic is in one of these categories
|
||||
watching_tags:
|
||||
label: Watching tags
|
||||
description: Will trigger only if the topic has any of these tags
|
||||
after_post_cook:
|
||||
fields:
|
||||
valid_trust_levels:
|
||||
|
|
|
@ -50,6 +50,9 @@ en:
|
|||
pm_created:
|
||||
title: Personal message created
|
||||
description: When a valid PM is created the automation will be triggered
|
||||
topic_tags_changed:
|
||||
title: Topic tags changed
|
||||
description: When the tags of a topic are changed the automation will be triggered
|
||||
topic:
|
||||
title: Topic
|
||||
description: The associated script will only be used on the specified topic, this is usefull for scripts doing validation for example
|
||||
|
|
|
@ -195,6 +195,36 @@ module DiscourseAutomation
|
|||
end
|
||||
end
|
||||
|
||||
def self.handle_topic_tags_changed(topic, old_tag_names, new_tag_names)
|
||||
name = DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED
|
||||
|
||||
DiscourseAutomation::Automation
|
||||
.where(trigger: name, enabled: true)
|
||||
.find_each do |automation|
|
||||
watching_categories = automation.trigger_field("watching_categories")
|
||||
if watching_categories["value"]
|
||||
next if !watching_categories["value"].include?(topic.category_id)
|
||||
end
|
||||
|
||||
watching_tags = automation.trigger_field("watching_tags")
|
||||
if watching_tags["value"]
|
||||
should_skip = false
|
||||
watching_tags["value"].each do |tag|
|
||||
should_skip = true if !old_tag_names.empty? && !old_tag_names.include?(tag)
|
||||
should_skip = true if !new_tag_names.empty? && !new_tag_names.include?(tag)
|
||||
end
|
||||
next if should_skip
|
||||
end
|
||||
|
||||
automation.trigger!(
|
||||
"kind" => name,
|
||||
"topic" => topic,
|
||||
"removed_tags" => old_tag_names,
|
||||
"added_tags" => new_tag_names,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.handle_after_post_cook(post, cooked)
|
||||
return cooked if post.post_type != Post.types[:regular] || post.post_number > 1
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ module DiscourseAutomation
|
|||
API_CALL = "api_call"
|
||||
CATEGORY_CREATED_EDITED = "category_created_edited"
|
||||
PM_CREATED = "pm_created"
|
||||
TOPIC_TAGS_CHANGED = "topic_tags_changed"
|
||||
POINT_IN_TIME = "point_in_time"
|
||||
POST_CREATED_EDITED = "post_created_edited"
|
||||
RECURRING = "recurring"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED) do
|
||||
field :watching_categories, component: :categories
|
||||
field :watching_tags, component: :tags
|
||||
end
|
|
@ -72,6 +72,7 @@ after_initialize do
|
|||
lib/discourse_automation/triggers/recurring
|
||||
lib/discourse_automation/triggers/stalled_topic
|
||||
lib/discourse_automation/triggers/stalled_wiki
|
||||
lib/discourse_automation/triggers/topic_tags_changed
|
||||
lib/discourse_automation/triggers/topic
|
||||
lib/discourse_automation/triggers/user_added_to_group
|
||||
lib/discourse_automation/triggers/user_badge_granted
|
||||
|
@ -181,6 +182,14 @@ after_initialize do
|
|||
DiscourseAutomation::EventHandlers.handle_pm_created(topic) if topic.private_message?
|
||||
end
|
||||
|
||||
on(:topic_tags_changed) do |topic, tags|
|
||||
DiscourseAutomation::EventHandlers.handle_topic_tags_changed(
|
||||
topic,
|
||||
tags[:old_tag_names],
|
||||
tags[:new_tag_names],
|
||||
)
|
||||
end
|
||||
|
||||
on(:post_created) do |post|
|
||||
DiscourseAutomation::EventHandlers.handle_post_created_edited(post, :create)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED do
|
||||
before { SiteSetting.discourse_automation_enabled = true }
|
||||
|
||||
fab!(:cool_tag) { Fabricate(:tag) }
|
||||
fab!(:bad_tag) { Fabricate(:tag) }
|
||||
fab!(:category)
|
||||
|
||||
fab!(:user)
|
||||
|
||||
fab!(:automation) do
|
||||
Fabricate(:automation, trigger: DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
before do
|
||||
SiteSetting.tagging_enabled = true
|
||||
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
end
|
||||
|
||||
context "when watching a cool tag" do
|
||||
before do
|
||||
automation.upsert_field!(
|
||||
"watching_tags",
|
||||
"tags",
|
||||
{ value: [cool_tag.name] },
|
||||
target: "trigger",
|
||||
)
|
||||
automation.reload
|
||||
end
|
||||
|
||||
it "should fire the trigger if the tag is added" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts do
|
||||
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [cool_tag.name])
|
||||
end
|
||||
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
it "should fire the trigger if the tag is removed" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [cool_tag], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts { DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), []) }
|
||||
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
it "should not fire if the tag is not present" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts do
|
||||
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [bad_tag.name])
|
||||
end
|
||||
|
||||
expect(list.length).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when watching a category" do
|
||||
before do
|
||||
automation.upsert_field!(
|
||||
"watching_categories",
|
||||
"categories",
|
||||
{ value: [category.id] },
|
||||
target: "trigger",
|
||||
)
|
||||
automation.reload
|
||||
end
|
||||
|
||||
it "should fire the trigger if the tag is added" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [], category: category)
|
||||
topic_1 = Fabricate(:topic, user: user, tags: [], category: Fabricate(:category))
|
||||
|
||||
list =
|
||||
capture_contexts do
|
||||
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [bad_tag.name])
|
||||
DiscourseTagging.tag_topic_by_names(topic_1, Guardian.new(user), [bad_tag.name])
|
||||
end
|
||||
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
it "should fire the trigger if the tag is removed" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [cool_tag], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts { DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), []) }
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
it "should not fire if not the watching category" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [], category: Fabricate(:category))
|
||||
|
||||
list =
|
||||
capture_contexts do
|
||||
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [cool_tag.name])
|
||||
end
|
||||
|
||||
expect(list.length).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when without any watching tags or categories" do
|
||||
it "should fire the trigger if the tag is added" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts do
|
||||
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [cool_tag.name])
|
||||
end
|
||||
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
|
||||
it "should fire the trigger if the tag is removed" do
|
||||
topic_0 = Fabricate(:topic, user: user, tags: [cool_tag], category: category)
|
||||
|
||||
list =
|
||||
capture_contexts { DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), []) }
|
||||
|
||||
expect(list.length).to eq(1)
|
||||
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue