discourse/plugins/automation/spec/triggers/post_created_edited_spec.rb
Joffrey JAFFEUX ad7d5426d8
FIX: supports groups field in post_created_edited (#28783)
⚠️ This commit is a revert of a revert due to a migration which was causing `{}` metadata to be transformed into `{"value": [null]}`. The new migration shouldn't cause this and will also clean the existing errors, there shouldn't  be any data loss given the affected fields where not containing actual data. We might want to stop storing these empty fields in the future.

To achieve it, this commit does the following:
- create a new `groups field`, ideally we would have reused the existing group field, but many automations now have the expectation that this field will return a group id and not an array of group ids, which makes it a dangerous change
- alter the code in `post_created_edited` to use this new groups field and change the logic to use an array
- migrate the existing group fields post_created_edited automations to change name from `restricted_group` to `restricted_groups`, the component from `group` to `groups` and the metadata from `{"value": integer}` to `{"value": [integer]}`

<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
2024-09-06 17:22:42 +02:00

523 lines
15 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
describe "PostCreatedEdited" do
before { SiteSetting.discourse_automation_enabled = true }
let(:basic_topic_params) do
{ title: "hello world topic", raw: "my name is fred", archetype: Archetype.default }
end
let(:parent_category) { Fabricate(:category_with_definition) }
let(:subcategory) { Fabricate(:category_with_definition, parent_category_id: parent_category.id) }
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:automation) { Fabricate(:automation, trigger: "post_created_edited") }
context "when filtering on first post only" do
before do
automation.upsert_field!("first_post_only", "boolean", { value: true }, target: "trigger")
end
it "fires on first post, but not on second" do
post = create_post(title: "hello world topic", raw: "my name is fred")
topic = post.topic
list =
capture_contexts do
PostCreator.create!(user, raw: "this is a test reply", topic_id: topic.id)
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("create")
list =
capture_contexts do
PostCreator.create!(user, raw: "this is another test reply", topic_id: topic.id)
end
expect(list.length).to eq(0)
end
end
context "when filtering on first topic only" do
before do
automation.upsert_field!("first_topic_only", "boolean", { value: true }, target: "trigger")
end
it "does not fire if it is not a topic" do
post = create_post(title: "hello world topic", raw: "my name is fred")
topic = post.topic
list =
capture_contexts do
PostCreator.create!(user, raw: "this is a test reply", topic_id: topic.id)
end
expect(list.length).to eq(0)
end
it "fires if it is a first topic (and not on second)" do
list =
capture_contexts do
PostCreator.create!(user, raw: "this is a test reply", title: "hello there mister")
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("create")
list =
capture_contexts do
PostCreator.create!(user, raw: "this is a test reply 2", title: "hello there mister 2")
end
expect(list.length).to eq(0)
end
end
context "when skipping posts created via email" do
before do
automation.upsert_field!("skip_via_email", "boolean", { value: true }, target: "trigger")
end
let(:parent_post) { create_post(title: "hello world topic", raw: "my name is fred") }
it "fires if the post didn't come via email" do
topic = parent_post.topic
list =
capture_contexts do
PostCreator.create!(user, raw: "this is a test reply", topic_id: topic.id)
end
expect(list.length).to eq(1)
end
it "skips the trigger if the post came via email" do
topic = parent_post.topic
list =
capture_contexts do
PostCreator.create!(
user,
raw: "this is a test reply",
topic_id: topic.id,
via_email: true,
)
end
expect(list.length).to eq(0)
end
end
context "when editing/creating a post" do
it "fires the trigger" do
post = nil
list = capture_contexts { post = PostCreator.create(user, basic_topic_params) }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("create")
list = capture_contexts { post.revise(post.user, raw: "this is another cool topic") }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("edit")
end
context "when trust_levels are restricted" do
before do
automation.upsert_field!(
"valid_trust_levels",
"trust-levels",
{ value: [0] },
target: "trigger",
)
end
context "when trust level is allowed" do
it "fires the trigger" do
list =
capture_contexts do
user.trust_level = TrustLevel[0]
PostCreator.create(user, basic_topic_params)
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
end
context "when trust level is not allowed" do
it "doesnt fire the trigger" do
list =
capture_contexts do
user.trust_level = TrustLevel[1]
PostCreator.create(user, basic_topic_params)
end
expect(list).to be_blank
end
end
end
context "when group is restricted" do
fab!(:target_group) { Fabricate(:group, messageable_level: Group::ALIAS_LEVELS[:everyone]) }
fab!(:another_group) { Fabricate(:group, messageable_level: Group::ALIAS_LEVELS[:everyone]) }
before do
automation.upsert_field!(
"restricted_groups",
"groups",
{ value: [target_group.id, another_group.id] },
target: "trigger",
)
end
context "when PM is not sent to the group" do
it "doesnt fire the trigger" do
list =
capture_contexts do
PostCreator.create(
user,
basic_topic_params.merge(
target_group_names: [Fabricate(:group).name],
archetype: Archetype.private_message,
),
)
end
expect(list.length).to eq(0)
end
end
context "when PM is sent to the group" do
it "fires the trigger" do
list =
capture_contexts do
PostCreator.create(
user,
basic_topic_params.merge(
target_group_names: [target_group.name],
archetype: Archetype.private_message,
),
)
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
end
context "when the topic is not a PM" do
it "doesnt fire the trigger" do
list =
capture_contexts do
user.groups << target_group
PostCreator.create(user, basic_topic_params)
end
expect(list).to be_blank
end
end
context "when members of the group are ignored" do
before do
automation.upsert_field!(
"ignore_group_members",
"boolean",
{ value: true },
target: "trigger",
)
end
it "doesnt fire the trigger" do
list =
capture_contexts do
user.groups << target_group
PostCreator.create(
user,
basic_topic_params.merge(
target_group_names: [target_group.name],
archetype: Archetype.private_message,
),
)
end
expect(list).to be_blank
end
end
context "when a different group is used" do
it "does not fire the trigger" do
list =
capture_contexts do
PostCreator.create(
user,
basic_topic_params.merge(
target_group_names: [Fabricate(:group).name],
archetype: Archetype.private_message,
),
)
end
expect(list).to be_blank
end
end
end
context "when the post is being created from an incoming email" do
let(:reply_key) { "4f97315cc828096c9cb34c6f1a0d6fe8" }
fab!(:user) { Fabricate(:user, email: "discourse@bar.com", refresh_auto_groups: true) }
fab!(:topic) { create_topic(user: user) }
fab!(:post) { create_post(topic: topic) }
let!(:post_reply_key) do
Fabricate(:post_reply_key, reply_key: reply_key, user: user, post: post)
end
before do
SiteSetting.email_in = true
SiteSetting.reply_by_email_address = "reply+%{reply_key}@bar.com"
SiteSetting.alternative_reply_by_email_addresses = "alt+%{reply_key}@bar.com"
end
it "fires the trigger" do
list = capture_contexts { Email::Receiver.new(email("html_reply")).process! }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("create")
end
context "when the incoming email is automated" do
before { SiteSetting.block_auto_generated_emails = false }
it "fires the trigger" do
list =
capture_contexts { Email::Receiver.new(email("auto_generated_unblocked")).process! }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
context "when ignore_automated is true" do
before do
automation.upsert_field!(
"ignore_automated",
"boolean",
{ value: true },
target: "trigger",
)
end
it "doesn't fire the trigger" do
list =
capture_contexts { Email::Receiver.new(email("auto_generated_unblocked")).process! }
expect(list).to be_blank
end
end
end
end
context "with original_post_only" do
before do
automation.upsert_field!(
"original_post_only",
"boolean",
{ value: true },
target: "trigger",
)
end
it "fires the trigger only for OP" do
list = capture_contexts { PostCreator.create(user, basic_topic_params) }
expect(list.length).to eq(1)
list =
capture_contexts do
PostCreator.create(
user,
basic_topic_params.merge({ topic_id: list[0]["post"].topic_id }),
)
end
expect(list.length).to eq(0)
end
end
context "when tags is restricted" do
fab!(:tag_1) { Fabricate(:tag) }
before do
automation.upsert_field!(
"restricted_tags",
"tags",
{ value: [tag_1.name] },
target: "trigger",
)
end
context "when tag is allowed" do
it "fires the trigger" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ tags: [tag_1.name] }))
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
end
context "when tag is not allowed" do
it "fires the trigger" do
list = capture_contexts { PostCreator.create(user, basic_topic_params.merge()) }
expect(list.length).to eq(0)
end
end
end
context "when category is restricted" do
before do
automation.upsert_field!(
"restricted_category",
"category",
{ value: Category.first.id },
target: "trigger",
)
end
context "when category is allowed" do
it "fires the trigger" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: Category.first.id }))
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
end
context "when restricted to a subcategory" do
before do
automation.upsert_field!(
"restricted_category",
"category",
{ value: subcategory.id },
target: "trigger",
)
end
it "fires the trigger" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: subcategory.id }))
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
it "does not fire the trigger for the parent" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: parent_category.id }))
end
expect(list.length).to eq(0)
end
end
context "when restricted to a parent category" do
before do
automation.upsert_field!(
"restricted_category",
"category",
{ value: parent_category.id },
target: "trigger",
)
end
it "fires the trigger for a subcategory" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: subcategory.id }))
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
it "fires the trigger for the parent" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: parent_category.id }))
end
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
end
end
context "when category is not allowed" do
fab!(:category)
it "doesnt fire the trigger" do
list =
capture_contexts do
PostCreator.create(user, basic_topic_params.merge({ category: category.id }))
end
expect(list).to be_blank
end
end
end
context "when action_type is set to create" do
before do
automation.upsert_field!("action_type", "choices", { value: "created" }, target: "trigger")
end
it "fires the trigger only for create" do
post = nil
list = capture_contexts { post = PostCreator.create(user, basic_topic_params) }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("create")
list = capture_contexts { post.revise(post.user, raw: "this is another cool topic") }
expect(list.length).to eq(0)
end
end
context "when action_type is set to edit" do
before do
automation.upsert_field!("action_type", "choices", { value: "edited" }, target: "trigger")
end
it "fires the trigger only for edit" do
post = nil
list = capture_contexts { post = PostCreator.create(user, basic_topic_params) }
expect(list.length).to eq(0)
list = capture_contexts { post.revise(post.user, raw: "this is another cool topic") }
expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("post_created_edited")
expect(list[0]["action"].to_s).to eq("edit")
end
end
end
end