FIX: `TopicTagsChanged` trigger not working with multiple tags (#29961)

* FIX: `TopicTagsChanged` trigger not working with multiple tags

The check for when had multiple tags was being exclusive, you had to have all tags to trigger the automation, now it's inclusive, you can trigger the automation if you have any of the tags.

* DEV: add specs for when having multiple categories

* DEV: changed to use unions and intersections for tags

added more tests to check for multiple tags
This commit is contained in:
Gabriel Grubba 2024-11-27 14:16:29 -03:00 committed by GitHub
parent fac6147039
commit 43414abf83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 111 additions and 6 deletions

View File

@ -239,12 +239,8 @@ module DiscourseAutomation
watching_tags = automation.trigger_field("watching_tags")
if watching_tags["value"]
should_skip = false
watching_tags["value"].each do |tag|
should_skip = true if !removed_tags.empty? && !removed_tags.include?(tag)
should_skip = true if !added_tags.empty? && !added_tags.include?(tag)
end
next if should_skip
changed_tags = (removed_tags | added_tags)
next if (changed_tags & watching_tags["value"]).empty?
end
automation.trigger!(

View File

@ -82,6 +82,66 @@ describe DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED do
end
end
context "when watching a few cool tags" do
fab!(:cool_tag_2) { Fabricate(:tag) }
fab!(:cool_tag_3) { Fabricate(:tag) }
before do
automation.upsert_field!(
"watching_tags",
"tags",
{ value: [cool_tag.name, cool_tag_2.name, cool_tag_3.name] },
target: "trigger",
)
automation.reload
end
it "should fire the trigger if any 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 any 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
it "should fire the trigger if a tag is add and one is removed" do
topic_0 = Fabricate(:topic, user: user, tags: [cool_tag], category: category)
list =
capture_contexts do
DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), [cool_tag_2.name])
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
end
end
context "when watching a category" do
before do
automation.upsert_field!(
@ -128,6 +188,55 @@ describe DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED do
end
end
context "when watching a few categories" do
fab!(:category_2) { Fabricate(:category) }
fab!(:category_3) { Fabricate(:category) }
before do
automation.upsert_field!(
"watching_categories",
"categories",
{ value: [category.id, category_2.id, category_3.id] },
target: "trigger",
)
automation.reload
end
it "should fire the trigger if any tag is added" do
topic_0 = Fabricate(:topic, user: user, tags: [], category: category)
topic_1 = Fabricate(:topic, user: user, tags: [], category: category_2)
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(2)
expect(list[0]["kind"]).to eq(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED)
end
it "should fire the trigger if any 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)