DEV: Move array type custom fields to JSON type in automation (#26939)

The automation plugin has 4 custom field types that are array typed. However, array typed custom fields are deprecated and should be migrated to JSON type.

This commit does a couple of things:

1. Migrate all four custom fields to JSON
2. Fix a couple of small bugs that have been discovered while migrating the custom fields to JSON (see the comments on this commit's PR for details https://github.com/discourse/discourse/pull/26939)
This commit is contained in:
Osama Sayegh 2024-05-10 18:47:12 +03:00 committed by GitHub
parent 4e22b505c5
commit 3be4924b99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 264 additions and 103 deletions

View File

@ -19,11 +19,10 @@ end
# #
# Indexes # Indexes
# #
# idx_post_custom_fields_discourse_automation_unique_id_partial (post_id,value) UNIQUE WHERE ((name)::text = 'discourse_automation_ids'::text) # index_post_custom_fields_on_name_and_value (name, "left"(value, 200))
# index_post_custom_fields_on_name_and_value (name, "left"(value, 200)) # index_post_custom_fields_on_notice (post_id) UNIQUE WHERE ((name)::text = 'notice'::text)
# index_post_custom_fields_on_notice (post_id) UNIQUE WHERE ((name)::text = 'notice'::text) # index_post_custom_fields_on_post_id (post_id) UNIQUE WHERE ((name)::text = 'missing uploads'::text)
# index_post_custom_fields_on_post_id (post_id) UNIQUE WHERE ((name)::text = 'missing uploads'::text) # index_post_custom_fields_on_post_id_and_name (post_id,name)
# index_post_custom_fields_on_post_id_and_name (post_id,name) # index_post_custom_fields_on_stalled_wiki_triggered_at (post_id) UNIQUE WHERE ((name)::text = 'stalled_wiki_triggered_at'::text)
# index_post_custom_fields_on_stalled_wiki_triggered_at (post_id) UNIQUE WHERE ((name)::text = 'stalled_wiki_triggered_at'::text) # index_post_id_where_missing_uploads_ignored (post_id) UNIQUE WHERE ((name)::text = 'missing uploads ignored'::text)
# index_post_id_where_missing_uploads_ignored (post_id) UNIQUE WHERE ((name)::text = 'missing uploads ignored'::text)
# #

View File

@ -19,8 +19,7 @@ end
# #
# Indexes # Indexes
# #
# idx_topic_custom_fields_auto_responder_triggered_ids_partial (topic_id,value) UNIQUE WHERE ((name)::text = 'auto_responder_triggered_ids'::text) # idx_topic_custom_fields_auto_responder_triggered_ids_partial (topic_id,value) UNIQUE WHERE ((name)::text = 'auto_responder_triggered_ids'::text)
# idx_topic_custom_fields_discourse_automation_unique_id_partial (topic_id,value) UNIQUE WHERE ((name)::text = 'discourse_automation_ids'::text) # index_topic_custom_fields_on_topic_id_and_name (topic_id,name)
# index_topic_custom_fields_on_topic_id_and_name (topic_id,name) # topic_custom_fields_value_key_idx (value,name) WHERE ((value IS NOT NULL) AND (char_length(value) < 400))
# topic_custom_fields_value_key_idx (value,name) WHERE ((value IS NOT NULL) AND (char_length(value) < 400))
# #

View File

@ -26,6 +26,5 @@ end
# #
# Indexes # Indexes
# #
# idx_user_custom_fields_discourse_automation_unique_id_partial (user_id,value) UNIQUE WHERE ((name)::text = 'discourse_automation_ids'::text) # index_user_custom_fields_on_user_id_and_name (user_id,name)
# index_user_custom_fields_on_user_id_and_name (user_id,name)
# #

View File

@ -34,41 +34,38 @@ module DiscourseAutomation
MAX_NAME_LENGTH = 30 MAX_NAME_LENGTH = 30
validates :name, length: { in: MIN_NAME_LENGTH..MAX_NAME_LENGTH } validates :name, length: { in: MIN_NAME_LENGTH..MAX_NAME_LENGTH }
def attach_custom_field(target) def add_id_to_custom_field(target, custom_field_key)
if ![Topic, Post, User].any? { |m| target.is_a?(m) } if ![Topic, Post, User].any? { |m| target.is_a?(m) }
raise "Expected an instance of Topic/Post/User." raise "Expected an instance of Topic/Post/User."
end end
now = Time.now change_automation_ids_custom_field_in_mutex(target, custom_field_key) do
fk = target.custom_fields_fk target.reload
row = { ids = Array(target.custom_fields[custom_field_key])
fk => target.id, if !ids.include?(self.id)
:name => DiscourseAutomation::CUSTOM_FIELD, ids << self.id
:value => id, ids = ids.compact.uniq
:created_at => now, target.custom_fields[custom_field_key] = ids
:updated_at => now, target.save_custom_fields
} end
end
relation = "#{target.class.name}CustomField".constantize
relation.upsert(
row,
unique_by:
"idx_#{target.class.name.downcase}_custom_fields_discourse_automation_unique_id_partial",
)
end end
def detach_custom_field(target) def remove_id_from_custom_field(target, custom_field_key)
if ![Topic, Post, User].any? { |m| target.is_a?(m) } if ![Topic, Post, User].any? { |m| target.is_a?(m) }
raise "Expected an instance of Topic/Post/User." raise "Expected an instance of Topic/Post/User."
end end
fk = target.custom_fields_fk change_automation_ids_custom_field_in_mutex(target, custom_field_key) do
relation = "#{target.class.name}CustomField".constantize target.reload
relation.where( ids = Array(target.custom_fields[custom_field_key])
fk => target.id, if ids.include?(self.id)
:name => DiscourseAutomation::CUSTOM_FIELD, ids = ids.compact.uniq
:value => id, ids.delete(self.id)
).delete_all target.custom_fields[custom_field_key] = ids
target.save_custom_fields
end
end
end end
def trigger_field(name) def trigger_field(name)
@ -187,5 +184,12 @@ module DiscourseAutomation
def validate_trigger_fields def validate_trigger_fields
!triggerable || triggerable.valid?(self) !triggerable || triggerable.valid?(self)
end end
def change_automation_ids_custom_field_in_mutex(target, key)
DistributedMutex.synchronize(
"automation_custom_field_#{key}_#{target.class.table_name}_#{target.id}",
validity: 5.seconds,
) { yield }
end
end end
end end

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
class SwitchTopicAutomationCustomFieldsToJson < ActiveRecord::Migration[7.0]
def up
results = DB.query(<<~SQL)
SELECT topic_id, ARRAY_AGG(value) AS values
FROM topic_custom_fields
WHERE name = 'discourse_automation_ids'
GROUP BY topic_id
SQL
execute(<<~SQL)
DELETE FROM topic_custom_fields
WHERE name = 'discourse_automation_ids'
SQL
results.each do |row|
parsed = row.values.map(&:to_i).uniq
DB.exec(<<~SQL, topic_id: row.topic_id, value: parsed.to_json)
INSERT INTO topic_custom_fields
(topic_id, name, value, created_at, updated_at)
VALUES
(:topic_id, 'discourse_automation_ids_json', :value, NOW(), NOW())
SQL
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
class SwitchUserAutomationCustomFieldsToJson < ActiveRecord::Migration[7.0]
def up
results = DB.query(<<~SQL)
SELECT user_id, ARRAY_AGG(value) AS values
FROM user_custom_fields
WHERE name = 'discourse_automation_ids'
GROUP BY user_id
SQL
execute(<<~SQL)
DELETE FROM user_custom_fields
WHERE name = 'discourse_automation_ids'
SQL
results.each do |row|
parsed = row.values.map(&:to_i).uniq
DB.exec(<<~SQL, user_id: row.user_id, value: parsed.to_json)
INSERT INTO user_custom_fields
(user_id, name, value, created_at, updated_at)
VALUES
(:user_id, 'discourse_automation_ids_json', :value, NOW(), NOW())
SQL
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
class SwitchTopicAutomationTriggeredIdsCustomFieldsToJson < ActiveRecord::Migration[7.0]
def up
results = DB.query(<<~SQL)
SELECT topic_id, ARRAY_AGG(value) AS values
FROM topic_custom_fields
WHERE name = 'auto_responder_triggered_ids'
GROUP BY topic_id
SQL
execute(<<~SQL)
DELETE FROM topic_custom_fields
WHERE name = 'auto_responder_triggered_ids'
SQL
results.each do |row|
parsed = row.values.map(&:to_i).uniq
DB.exec(<<~SQL, topic_id: row.topic_id, value: parsed.to_json)
INSERT INTO topic_custom_fields
(topic_id, name, value, created_at, updated_at)
VALUES
(:topic_id, 'auto_responder_triggered_ids_json', :value, NOW(), NOW())
SQL
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class DropAutomationIdsCustomFieldIndexes < ActiveRecord::Migration[7.0]
def change
remove_index :topic_custom_fields,
name: :idx_topic_custom_fields_discourse_automation_unique_id_partial,
if_exists: true
remove_index :user_custom_fields,
name: :idx_user_custom_fields_discourse_automation_unique_id_partial,
if_exists: true
remove_index :post_custom_fields,
name: :idx_post_custom_fields_discourse_automation_unique_id_partial,
if_exists: true
end
end

View File

@ -75,7 +75,9 @@ module DiscourseAutomation
.find_each do |automation| .find_each do |automation|
once_per_user = automation.trigger_field("once_per_user")["value"] once_per_user = automation.trigger_field("once_per_user")["value"]
if once_per_user && if once_per_user &&
UserCustomField.exists?(name: DiscourseAutomation::CUSTOM_FIELD, user_id: user.id) user.custom_fields[
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD
].presence&.include?(automation.id)
next next
end end
@ -135,7 +137,8 @@ module DiscourseAutomation
user.save_custom_fields user.save_custom_fields
end end
automation.attach_custom_field(user) automation.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation.trigger!("kind" => name, "user" => user, "user_data" => user_data) automation.trigger!("kind" => name, "user" => user, "user_data" => user_data)
end end
end end

View File

@ -10,9 +10,9 @@ module DiscourseAutomation
return if !SiteSetting.discourse_automation_enabled return if !SiteSetting.discourse_automation_enabled
return if self.post_type == Post.types[:small_action] return if self.post_type == Post.types[:small_action]
return if !topic return if !topic
return if topic.custom_fields[DiscourseAutomation::CUSTOM_FIELD].blank? return if topic.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD].blank?
topic.custom_fields[DiscourseAutomation::CUSTOM_FIELD].each do |automation_id| topic.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD].each do |automation_id|
automation = DiscourseAutomation::Automation.find_by(id: automation_id) automation = DiscourseAutomation::Automation.find_by(id: automation_id)
next if automation&.script != DiscourseAutomation::Scripts::TOPIC_REQUIRED_WORDS next if automation&.script != DiscourseAutomation::Scripts::TOPIC_REQUIRED_WORDS

View File

@ -70,9 +70,7 @@ DiscourseAutomation::Scriptable.add(DiscourseAutomation::Scripts::AUTO_RESPONDER
end end
.join("\n\n") .join("\n\n")
value = (Array(post.topic.custom_fields[key]) << automation.id).compact.uniq automation.add_id_to_custom_field(post.topic, key)
post.topic.custom_fields[key] = value
post.topic.save_custom_fields
PostCreator.create!( PostCreator.create!(
answering_user, answering_user,

View File

@ -12,17 +12,19 @@ DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::TOPIC) do
previous_topic = Topic.find_by(id: previous_topic_id) previous_topic = Topic.find_by(id: previous_topic_id)
if previous_topic if previous_topic
TopicCustomField.where( automation.remove_id_from_custom_field(
topic_id: previous_topic_id, previous_topic,
name: DiscourseAutomation::CUSTOM_FIELD, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
value: automation.id, )
).delete_all
end end
end end
if topic_id if topic_id
topic = Topic.find_by(id: topic_id) topic = Topic.find_by(id: topic_id)
topic&.upsert_custom_fields(DiscourseAutomation::CUSTOM_FIELD => automation.id)
next if !topic
automation.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
end end
end end
end end

View File

@ -14,7 +14,7 @@ register_asset "stylesheets/common/discourse-automation.scss"
module ::DiscourseAutomation module ::DiscourseAutomation
PLUGIN_NAME = "automation" PLUGIN_NAME = "automation"
CUSTOM_FIELD = "discourse_automation_ids" AUTOMATION_IDS_CUSTOM_FIELD = "discourse_automation_ids_json"
TOPIC_LAST_CHECKED_BY = "discourse_automation_last_checked_by" TOPIC_LAST_CHECKED_BY = "discourse_automation_last_checked_by"
TOPIC_LAST_CHECKED_AT = "discourse_automation_last_checked_at" TOPIC_LAST_CHECKED_AT = "discourse_automation_last_checked_at"
@ -26,7 +26,7 @@ module ::DiscourseAutomation
{ id: "TL34", name: "discourse_automation.triggerables.user_promoted.trust_levels.TL34" }, { id: "TL34", name: "discourse_automation.triggerables.user_promoted.trust_levels.TL34" },
] ]
AUTO_RESPONDER_TRIGGERED_IDS = "auto_responder_triggered_ids" AUTO_RESPONDER_TRIGGERED_IDS = "auto_responder_triggered_ids_json"
USER_GROUP_MEMBERSHIP_THROUGH_BADGE_BULK_MODIFY_START_COUNT = 1000 USER_GROUP_MEMBERSHIP_THROUGH_BADGE_BULK_MODIFY_START_COUNT = 1000
def self.set_active_automation(id) def self.set_active_automation(id)
@ -203,15 +203,15 @@ after_initialize do
on(:post_created) { |post| DiscourseAutomation::EventHandlers.handle_stalled_topic(post) } on(:post_created) { |post| DiscourseAutomation::EventHandlers.handle_stalled_topic(post) }
register_topic_custom_field_type(DiscourseAutomation::CUSTOM_FIELD, [:integer]) register_topic_custom_field_type(DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD, :json)
register_topic_custom_field_type(DiscourseAutomation::AUTO_RESPONDER_TRIGGERED_IDS, [:integer]) register_topic_custom_field_type(DiscourseAutomation::AUTO_RESPONDER_TRIGGERED_IDS, :json)
on(:user_updated) { |user| DiscourseAutomation::EventHandlers.handle_user_updated(user) } on(:user_updated) { |user| DiscourseAutomation::EventHandlers.handle_user_updated(user) }
on(:user_created) do |user| on(:user_created) do |user|
DiscourseAutomation::EventHandlers.handle_user_updated(user, new_user: true) DiscourseAutomation::EventHandlers.handle_user_updated(user, new_user: true)
end end
register_user_custom_field_type(DiscourseAutomation::CUSTOM_FIELD, [:integer]) register_user_custom_field_type(DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD, :json)
register_post_custom_field_type(DiscourseAutomation::CUSTOM_FIELD, [:integer]) register_post_custom_field_type(DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD, :json)
register_post_custom_field_type("stalled_wiki_triggered_at", :string) register_post_custom_field_type("stalled_wiki_triggered_at", :string)
end end

View File

@ -38,90 +38,122 @@ describe "Core extensions" do
describe "post custom fields" do describe "post custom fields" do
it "supports discourse_automation_ids" do it "supports discourse_automation_ids" do
post = create_post post = create_post
automation_1.attach_custom_field(post) automation_1.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(post.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(post.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_2.attach_custom_field(post) automation_2.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(post.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq( expect(post.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id, automation_2.id], [automation_1.id, automation_2.id],
) )
PostCustomField.where(post_id: post.id, name: DiscourseAutomation::CUSTOM_FIELD).delete_all PostCustomField.where(
post_id: post.id,
name: DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
).delete_all
expect(post.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(post.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to be(nil)
automation_1.attach_custom_field(post) automation_1.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(post) automation_1.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(post) automation_1.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(post) automation_1.add_id_to_custom_field(post, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(post.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(post.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_1.detach_custom_field(post) automation_1.remove_id_from_custom_field(
post,
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
)
expect(post.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(post.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq([])
end end
end end
describe "topic custom fields" do describe "topic custom fields" do
it "supports discourse_automation_ids" do it "supports discourse_automation_ids" do
topic = create_topic topic = create_topic
automation_1.attach_custom_field(topic) automation_1.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(topic.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(topic.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_2.attach_custom_field(topic) automation_2.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(topic.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq( expect(topic.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id, automation_2.id], [automation_1.id, automation_2.id],
) )
TopicCustomField.where(topic_id: topic.id, name: DiscourseAutomation::CUSTOM_FIELD).delete_all TopicCustomField.where(
topic_id: topic.id,
name: DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
).delete_all
expect(topic.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(topic.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
nil,
)
automation_1.attach_custom_field(topic) automation_1.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(topic) automation_1.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(topic) automation_1.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(topic) automation_1.add_id_to_custom_field(topic, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(topic.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(topic.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_1.detach_custom_field(topic) automation_1.remove_id_from_custom_field(
topic,
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
)
expect(topic.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(topic.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq([])
end end
end end
describe "user custom fields" do describe "user custom fields" do
it "supports discourse_automation_ids" do it "supports discourse_automation_ids" do
user = create_user user = create_user
automation_1.attach_custom_field(user) automation_1.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(user.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(user.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_2.attach_custom_field(user) automation_2.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(user.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq( expect(user.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id, automation_2.id], [automation_1.id, automation_2.id],
) )
UserCustomField.where(user_id: user.id, name: DiscourseAutomation::CUSTOM_FIELD).delete_all UserCustomField.where(
user_id: user.id,
name: DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
).delete_all
expect(user.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(user.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(nil)
automation_1.attach_custom_field(user) automation_1.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(user) automation_1.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(user) automation_1.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
automation_1.attach_custom_field(user) automation_1.add_id_to_custom_field(user, DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD)
expect(user.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to eq([automation_1.id]) expect(user.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation_1.id],
)
automation_1.detach_custom_field(user) automation_1.remove_id_from_custom_field(
user,
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
)
expect(user.reload.custom_fields[DiscourseAutomation::CUSTOM_FIELD]).to be(nil) expect(user.reload.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq([])
end end
end end
end end

View File

@ -46,19 +46,29 @@ describe DiscourseAutomation::Automation do
end end
end end
describe "#detach_custom_field" do describe "#remove_id_from_custom_field" do
fab!(:automation) fab!(:automation)
it "expects a User/Topic/Post instance" do it "expects a User/Topic/Post instance" do
expect { automation.detach_custom_field(Invite.new) }.to raise_error(RuntimeError) expect {
automation.remove_id_from_custom_field(
Invite.new,
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
)
}.to raise_error(RuntimeError)
end end
end end
describe "#attach_custom_field" do describe "#add_id_to_custom_field" do
fab!(:automation) fab!(:automation)
it "expects a User/Topic/Post instance" do it "expects a User/Topic/Post instance" do
expect { automation.attach_custom_field(Invite.new) }.to raise_error(RuntimeError) expect {
automation.add_id_to_custom_field(
Invite.new,
DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD,
)
}.to raise_error(RuntimeError)
end end
end end

View File

@ -14,7 +14,9 @@ describe "TopicRequiredWords" do
context "when updating trigger" do context "when updating trigger" do
it "updates the custom field" do it "updates the custom field" do
automation.upsert_field!("restricted_topic", "text", { value: topic.id }, target: "trigger") automation.upsert_field!("restricted_topic", "text", { value: topic.id }, target: "trigger")
expect(topic.custom_fields["discourse_automation_ids"]).to eq([automation.id]) expect(topic.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation.id],
)
new_topic = create_topic new_topic = create_topic
automation.upsert_field!( automation.upsert_field!(
@ -23,7 +25,9 @@ describe "TopicRequiredWords" do
{ value: new_topic.id }, { value: new_topic.id },
target: "trigger", target: "trigger",
) )
expect(new_topic.custom_fields["discourse_automation_ids"]).to eq([automation.id]) expect(new_topic.custom_fields[DiscourseAutomation::AUTOMATION_IDS_CUSTOM_FIELD]).to eq(
[automation.id],
)
end end
end end
end end

View File

@ -70,7 +70,7 @@ describe "UserUpdated" do
end end
it "doesnt trigger if automation already triggered" do it "doesnt trigger if automation already triggered" do
automation.attach_custom_field(user) UserUpdater.new(user, user).update(location: "Korea", bio_raw: "good")
output = output =
capture_contexts { UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine") } capture_contexts { UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine") }