From 0d6286395153e714f739ee462a658094ccf90405 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba <70247653+Grubba27@users.noreply.github.com> Date: Mon, 6 Jan 2025 09:22:39 -0500 Subject: [PATCH] FEATURE: Add trigger_on option to topic_tags_changed automation (#30391) * FEATURE: default value to fields in automation This PR adds the property `extra.default_value` to the fields in automation. This property is used to set the default value of the field. Reducing the nil checks we have to do in automation fields. I've added only testing in the `da-choices-field-test.js` file, but we could add tests to all the fields. * FEATURE: Add trigger_on option to `topic_tags_changed` automation This new field will allow users to specify when the trigger should be fired. The options are: - `tags_added_or_removed`: The trigger will be fired when tags are added or removed from the topic. - `tags_added`: The trigger will be fired when tags are added to the topic. - `tags_removed`: The trigger will be fired when tags are removed from the topic. This PR also brings a migration to set the `trigger_on` field to `tags_added_or_removed` for all existing `topic_tags_changed` automations. * DEV: reorganize the specs in context blocks * DEV: migration to add trigger_on field default value to topic_tags_changed_trigger * DEV: `down` migration for `add_trigger_on_field_default_value_to_topic_tags_changed_trigger` migration * Update plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb Co-authored-by: Joffrey JAFFEUX * Update plugins/automation/config/locales/client.en.yml Co-authored-by: Joffrey JAFFEUX * DEV: lint files and update topic_tags_changed trigger to use `default_value` * Revert "FEATURE: default value to fields in automation" This reverts commit 4d32635c695b1da36dbe3343bb55c223a720106a. * DEV: remove migration file --------- Co-authored-by: Joffrey JAFFEUX --- .../automation/config/locales/client.en.yml | 6 ++ .../discourse_automation/event_handlers.rb | 11 +++ .../triggers/topic_tags_changed.rb | 38 ++++++++++ .../spec/triggers/topic_tags_changed_spec.rb | 74 +++++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/plugins/automation/config/locales/client.en.yml b/plugins/automation/config/locales/client.en.yml index 91109ef8ea4..22e12b7f07f 100644 --- a/plugins/automation/config/locales/client.en.yml +++ b/plugins/automation/config/locales/client.en.yml @@ -222,6 +222,10 @@ en: 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: + trigger_on_modes: + tags_added_or_removed: Tags added or removed + tags_added: Tags added + tags_removed: Tags removed fields: watching_categories: label: Watching categories @@ -229,6 +233,8 @@ en: watching_tags: label: Watching tags description: Will trigger only if the topic has any of these tags + trigger_on: + label: Trigger on trigger_with_pms: label: Trigger with PMs description: Will trigger even if the tags were changed in a PM diff --git a/plugins/automation/lib/discourse_automation/event_handlers.rb b/plugins/automation/lib/discourse_automation/event_handlers.rb index 0ce2903efa5..031bd65a444 100644 --- a/plugins/automation/lib/discourse_automation/event_handlers.rb +++ b/plugins/automation/lib/discourse_automation/event_handlers.rb @@ -243,6 +243,17 @@ module DiscourseAutomation next if (changed_tags & watching_tags["value"]).empty? end + trigger_on = automation.trigger_field("trigger_on")["value"] + + if trigger_on == Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED && added_tags.empty? + next + end + + if trigger_on == Triggers::TopicTagsChanged::TriggerOn::TAGS_REMOVED && + removed_tags.empty? + next + end + automation.trigger!( "kind" => name, "topic" => topic, diff --git a/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb b/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb index 092d4bd20a7..9cbd5ce119b 100644 --- a/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb +++ b/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb @@ -1,8 +1,46 @@ # frozen_string_literal: true +module DiscourseAutomation + module Triggers + module TopicTagsChanged + module TriggerOn + TAGS_ADDED_OR_REMOVED = "tags_added_or_removed" + TAGS_ADDED = "tags_added" + TAGS_REMOVED = "tags_removed" + + MODES = [ + { + id: TAGS_ADDED_OR_REMOVED, + name: + "discourse_automation.triggerables.topic_tags_changed.trigger_on_modes.tags_added_or_removed", + }, + { + id: TAGS_ADDED, + name: + "discourse_automation.triggerables.topic_tags_changed.trigger_on_modes.tags_added", + }, + { + id: TAGS_REMOVED, + name: + "discourse_automation.triggerables.topic_tags_changed.trigger_on_modes.tags_removed", + }, + ] + end + end + end +end + DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED) do field :watching_categories, component: :categories field :watching_tags, component: :tags + field :trigger_on, + component: :choices, + extra: { + content: DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::MODES, + }, + default_value: + DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED_OR_REMOVED, + required: true field :trigger_with_pms, component: :boolean placeholder :topic_url diff --git a/plugins/automation/spec/triggers/topic_tags_changed_spec.rb b/plugins/automation/spec/triggers/topic_tags_changed_spec.rb index a0474ea4cc8..75e80cc0d7a 100644 --- a/plugins/automation/spec/triggers/topic_tags_changed_spec.rb +++ b/plugins/automation/spec/triggers/topic_tags_changed_spec.rb @@ -328,5 +328,79 @@ describe DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED do end expect(list.length).to eq(1) end + + context "with TAGS_ADDED set in trigger_on field" do + it "should fire if tag is added" do + automation.upsert_field!( + "trigger_on", + "choices", + { value: DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED }, + target: "trigger", + ) + + topic_0 = Fabricate(:topic, user: user, tags: []) + + 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 not fire if tag is removed" do + automation.upsert_field!( + "trigger_on", + "choices", + { value: DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED }, + target: "trigger", + ) + + topic_0 = Fabricate(:topic, user: user, tags: [cool_tag]) + + list = + capture_contexts { DiscourseTagging.tag_topic_by_names(topic_0, Guardian.new(user), []) } + + expect(list.length).to eq(0) + end + end + + context "with TAGS_REMOVED set in trigger_on field" do + it "should fire if tag is removed" do + automation.upsert_field!( + "trigger_on", + "choices", + { value: DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_REMOVED }, + target: "trigger", + ) + + topic_0 = Fabricate(:topic, user: user, tags: [cool_tag]) + + 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 tag is added" do + automation.upsert_field!( + "trigger_on", + "choices", + { value: DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_REMOVED }, + target: "trigger", + ) + + topic_0 = Fabricate(:topic, user: user, tags: []) + + 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 end end