DEV: Have `contract` take a block in services
Currently in services, the `contract` step is only used to define where the contract will be called in the execution flow. Then, a `Contract` class has to be defined with validations in it. This patch allows the `contract` step to take a block containing validations, attributes, etc. directly. No need to then open a `Contract` class later in the service. It also has a nice side effect, as it’s now easy to define multiples contracts inside the same service. Before, we had the `class_name:` option, but it wasn’t really useful as you had to redefine a complete new contract class. Now, when using a name for the contract other than `default`, a new contract will be created automatically using the provided name. Example: ```ruby contract(:user) do attribute :user_id, :integer validates :user_id, presence: true end ``` This will create a `UserContract` class and use it, also putting the resulting contract in `context[:user_contract]`.
This commit is contained in:
parent
76ad581f67
commit
fc1c5f6a8d
|
@ -3,28 +3,26 @@
|
||||||
class Flags::CreateFlag
|
class Flags::CreateFlag
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
policy :invalid_access
|
|
||||||
policy :unique_name
|
|
||||||
model :flag, :instantiate_flag
|
|
||||||
|
|
||||||
transaction do
|
|
||||||
step :create
|
|
||||||
step :log
|
|
||||||
end
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :name, :string
|
attribute :name, :string
|
||||||
attribute :description, :string
|
attribute :description, :string
|
||||||
attribute :require_message, :boolean
|
attribute :require_message, :boolean
|
||||||
attribute :enabled, :boolean
|
attribute :enabled, :boolean
|
||||||
attribute :applies_to
|
attribute :applies_to
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :description, presence: true
|
validates :description, presence: true
|
||||||
validates :name, length: { maximum: Flag::MAX_NAME_LENGTH }
|
validates :name, length: { maximum: Flag::MAX_NAME_LENGTH }
|
||||||
validates :description, length: { maximum: Flag::MAX_DESCRIPTION_LENGTH }
|
validates :description, length: { maximum: Flag::MAX_DESCRIPTION_LENGTH }
|
||||||
validates :applies_to, inclusion: { in: -> { Flag.valid_applies_to_types } }, allow_nil: false
|
validates :applies_to, inclusion: { in: -> { Flag.valid_applies_to_types } }, allow_nil: false
|
||||||
end
|
end
|
||||||
|
policy :invalid_access
|
||||||
|
policy :unique_name
|
||||||
|
model :flag, :instantiate_flag
|
||||||
|
transaction do
|
||||||
|
step :create
|
||||||
|
step :log
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -5,23 +5,21 @@ VALID_DIRECTIONS = %w[up down]
|
||||||
class Flags::ReorderFlag
|
class Flags::ReorderFlag
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :flag_id, :integer
|
||||||
|
attribute :direction, :string
|
||||||
|
|
||||||
|
validates :flag_id, presence: true
|
||||||
|
validates :direction, inclusion: { in: VALID_DIRECTIONS }
|
||||||
|
end
|
||||||
model :flag
|
model :flag
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
policy :invalid_move
|
policy :invalid_move
|
||||||
|
|
||||||
transaction do
|
transaction do
|
||||||
step :move
|
step :move
|
||||||
step :log
|
step :log
|
||||||
end
|
end
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :flag_id, :integer
|
|
||||||
attribute :direction, :string
|
|
||||||
validates :flag_id, presence: true
|
|
||||||
validates :direction, inclusion: { in: VALID_DIRECTIONS }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_flag(flag_id:)
|
def fetch_flag(flag_id:)
|
||||||
|
|
|
@ -3,20 +3,18 @@
|
||||||
class Flags::ToggleFlag
|
class Flags::ToggleFlag
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :flag_id, :integer
|
||||||
|
|
||||||
|
validates :flag_id, presence: true
|
||||||
|
end
|
||||||
model :flag
|
model :flag
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
|
|
||||||
transaction do
|
transaction do
|
||||||
step :toggle
|
step :toggle
|
||||||
step :log
|
step :log
|
||||||
end
|
end
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :flag_id, :integer
|
|
||||||
validates :flag_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_flag(flag_id:)
|
def fetch_flag(flag_id:)
|
||||||
|
|
|
@ -3,30 +3,28 @@
|
||||||
class Flags::UpdateFlag
|
class Flags::UpdateFlag
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :flag
|
|
||||||
policy :not_system
|
|
||||||
policy :not_used
|
|
||||||
policy :invalid_access
|
|
||||||
policy :unique_name
|
|
||||||
|
|
||||||
transaction do
|
|
||||||
step :update
|
|
||||||
step :log
|
|
||||||
end
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :name, :string
|
attribute :name, :string
|
||||||
attribute :description, :string
|
attribute :description, :string
|
||||||
attribute :require_message, :boolean
|
attribute :require_message, :boolean
|
||||||
attribute :enabled, :boolean
|
attribute :enabled, :boolean
|
||||||
attribute :applies_to
|
attribute :applies_to
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :description, presence: true
|
validates :description, presence: true
|
||||||
validates :name, length: { maximum: Flag::MAX_NAME_LENGTH }
|
validates :name, length: { maximum: Flag::MAX_NAME_LENGTH }
|
||||||
validates :description, length: { maximum: Flag::MAX_DESCRIPTION_LENGTH }
|
validates :description, length: { maximum: Flag::MAX_DESCRIPTION_LENGTH }
|
||||||
validates :applies_to, inclusion: { in: -> { Flag.valid_applies_to_types } }, allow_nil: false
|
validates :applies_to, inclusion: { in: -> { Flag.valid_applies_to_types } }, allow_nil: false
|
||||||
end
|
end
|
||||||
|
model :flag
|
||||||
|
policy :not_system
|
||||||
|
policy :not_used
|
||||||
|
policy :invalid_access
|
||||||
|
policy :unique_name
|
||||||
|
transaction do
|
||||||
|
step :update
|
||||||
|
step :log
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,18 @@ class UpdateSiteSetting
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
policy :current_user_is_admin
|
policy :current_user_is_admin
|
||||||
contract
|
contract do
|
||||||
step :convert_name_to_sym
|
|
||||||
policy :setting_is_visible
|
|
||||||
policy :setting_is_configurable
|
|
||||||
step :cleanup_value
|
|
||||||
step :save
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :setting_name
|
attribute :setting_name
|
||||||
attribute :new_value
|
attribute :new_value
|
||||||
attribute :allow_changing_hidden, :boolean, default: false
|
attribute :allow_changing_hidden, :boolean, default: false
|
||||||
|
|
||||||
validates :setting_name, presence: true
|
validates :setting_name, presence: true
|
||||||
end
|
end
|
||||||
|
step :convert_name_to_sym
|
||||||
|
policy :setting_is_visible
|
||||||
|
policy :setting_is_configurable
|
||||||
|
step :cleanup_value
|
||||||
|
step :save
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,7 @@
|
||||||
class User::Silence
|
class User::Silence
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :user
|
|
||||||
policy :not_silenced_already, class_name: User::Policy::NotAlreadySilenced
|
|
||||||
model :users
|
|
||||||
policy :can_silence_all_users
|
|
||||||
step :silence
|
|
||||||
model :post, optional: true
|
|
||||||
step :perform_post_action
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :user_id, :integer
|
attribute :user_id, :integer
|
||||||
attribute :reason, :string
|
attribute :reason, :string
|
||||||
attribute :message, :string
|
attribute :message, :string
|
||||||
|
@ -28,6 +19,13 @@ class User::Silence
|
||||||
validates :other_user_ids, length: { maximum: User::MAX_SIMILAR_USERS }
|
validates :other_user_ids, length: { maximum: User::MAX_SIMILAR_USERS }
|
||||||
validates :post_action, inclusion: { in: %w[delete delete_replies edit] }, allow_blank: true
|
validates :post_action, inclusion: { in: %w[delete delete_replies edit] }, allow_blank: true
|
||||||
end
|
end
|
||||||
|
model :user
|
||||||
|
policy :not_silenced_already, class_name: User::Policy::NotAlreadySilenced
|
||||||
|
model :users
|
||||||
|
policy :can_silence_all_users
|
||||||
|
step :silence
|
||||||
|
model :post, optional: true
|
||||||
|
step :perform_post_action
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,7 @@
|
||||||
class User::Suspend
|
class User::Suspend
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :user
|
|
||||||
policy :not_suspended_already, class_name: User::Policy::NotAlreadySuspended
|
|
||||||
model :users
|
|
||||||
policy :can_suspend_all_users
|
|
||||||
step :suspend
|
|
||||||
model :post, optional: true
|
|
||||||
step :perform_post_action
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :user_id, :integer
|
attribute :user_id, :integer
|
||||||
attribute :reason, :string
|
attribute :reason, :string
|
||||||
attribute :message, :string
|
attribute :message, :string
|
||||||
|
@ -28,6 +19,13 @@ class User::Suspend
|
||||||
validates :other_user_ids, length: { maximum: User::MAX_SIMILAR_USERS }
|
validates :other_user_ids, length: { maximum: User::MAX_SIMILAR_USERS }
|
||||||
validates :post_action, inclusion: { in: %w[delete delete_replies edit] }, allow_blank: true
|
validates :post_action, inclusion: { in: %w[delete delete_replies edit] }, allow_blank: true
|
||||||
end
|
end
|
||||||
|
model :user
|
||||||
|
policy :not_suspended_already, class_name: User::Policy::NotAlreadySuspended
|
||||||
|
model :users
|
||||||
|
policy :can_suspend_all_users
|
||||||
|
step :suspend
|
||||||
|
model :post, optional: true
|
||||||
|
step :perform_post_action
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,12 @@ module Service
|
||||||
# Currently, there are 5 types of steps:
|
# Currently, there are 5 types of steps:
|
||||||
#
|
#
|
||||||
# * +contract(name = :default)+: used to validate the input parameters,
|
# * +contract(name = :default)+: used to validate the input parameters,
|
||||||
# typically provided by a user calling an endpoint. A special embedded
|
# typically provided by a user calling an endpoint. A block has to be
|
||||||
# +Contract+ class has to be defined to holds the validations. If the
|
# defined to hold the validations. If the validations fail, the step will
|
||||||
# validations fail, the step will fail. Otherwise, the resulting contract
|
# fail. Otherwise, the resulting contract will be available in
|
||||||
# will be available in +context[:contract]+. When calling +step(name)+ or
|
# +context[:contract]+. When calling +step(name)+ or +model(name = :model)+
|
||||||
# +model(name = :model)+ methods after validating a contract, the contract
|
# methods after validating a contract, the contract should be used as an
|
||||||
# should be used as an argument instead of context attributes.
|
# argument instead of context attributes.
|
||||||
# * +model(name = :model)+: used to instantiate a model (either by building
|
# * +model(name = :model)+: used to instantiate a model (either by building
|
||||||
# it or fetching it from the DB). If a falsy value is returned, then the
|
# it or fetching it from the DB). If a falsy value is returned, then the
|
||||||
# step will fail. Otherwise the resulting object will be assigned in
|
# step will fail. Otherwise the resulting object will be assigned in
|
||||||
|
|
|
@ -78,10 +78,12 @@ module Service
|
||||||
steps << ModelStep.new(name, step_name, optional: optional)
|
steps << ModelStep.new(name, step_name, optional: optional)
|
||||||
end
|
end
|
||||||
|
|
||||||
def contract(name = :default, class_name: self::Contract, default_values_from: nil)
|
def contract(name = :default, default_values_from: nil, &block)
|
||||||
|
contract_class = Class.new(Service::ContractBase).tap { _1.class_eval(&block) }
|
||||||
|
const_set("#{name.to_s.classify.sub("Default", "")}Contract", contract_class)
|
||||||
steps << ContractStep.new(
|
steps << ContractStep.new(
|
||||||
name,
|
name,
|
||||||
class_name: class_name,
|
class_name: contract_class,
|
||||||
default_values_from: default_values_from,
|
default_values_from: default_values_from,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -214,20 +216,6 @@ module Service
|
||||||
included do
|
included do
|
||||||
# The global context which is available from any step.
|
# The global context which is available from any step.
|
||||||
attr_reader :context
|
attr_reader :context
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
# Internal class used to setup the base contract of the service.
|
|
||||||
self::Contract =
|
|
||||||
Class.new do
|
|
||||||
include ActiveModel::API
|
|
||||||
include ActiveModel::Attributes
|
|
||||||
include ActiveModel::AttributeMethods
|
|
||||||
include ActiveModel::Validations::Callbacks
|
|
||||||
|
|
||||||
def raw_attributes
|
|
||||||
@attributes.values_before_type_cast
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
|
@ -306,10 +294,10 @@ module Service
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# @!scope class
|
# @!scope class
|
||||||
# @!method contract(name = :default, class_name: self::Contract, default_values_from: nil)
|
# @!method contract(name = :default, default_values_from: nil, &block)
|
||||||
# @param name [Symbol] name for this contract
|
# @param name [Symbol] name for this contract
|
||||||
# @param class_name [Class] a class defining the contract
|
|
||||||
# @param default_values_from [Symbol] name of the model to get default values from
|
# @param default_values_from [Symbol] name of the model to get default values from
|
||||||
|
# @param block [Proc] a block containing validations
|
||||||
# Checks the validity of the input parameters.
|
# Checks the validity of the input parameters.
|
||||||
# Implements ActiveModel::Validations and ActiveModel::Attributes.
|
# Implements ActiveModel::Validations and ActiveModel::Attributes.
|
||||||
#
|
#
|
||||||
|
@ -317,9 +305,7 @@ module Service
|
||||||
# (can be customized by providing the +name+ argument).
|
# (can be customized by providing the +name+ argument).
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# contract
|
# contract do
|
||||||
#
|
|
||||||
# class Contract
|
|
||||||
# attribute :name
|
# attribute :name
|
||||||
# validates :name, presence: true
|
# validates :name, presence: true
|
||||||
# end
|
# end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Service::ContractBase
|
||||||
|
include ActiveModel::API
|
||||||
|
include ActiveModel::Attributes
|
||||||
|
include ActiveModel::AttributeMethods
|
||||||
|
include ActiveModel::Validations::Callbacks
|
||||||
|
|
||||||
|
def raw_attributes
|
||||||
|
@attributes.values_before_type_cast
|
||||||
|
end
|
||||||
|
end
|
|
@ -22,33 +22,28 @@ module Chat
|
||||||
# @option params_to_create [Array<String>] usernames
|
# @option params_to_create [Array<String>] usernames
|
||||||
# @option params_to_create [Array<String>] groups
|
# @option params_to_create [Array<String>] groups
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
model :channel
|
|
||||||
policy :can_add_users_to_channel
|
|
||||||
model :target_users, optional: true
|
|
||||||
policy :satisfies_dms_max_users_limit,
|
|
||||||
class_name: Chat::DirectMessageChannel::Policy::MaxUsersExcess
|
|
||||||
|
|
||||||
transaction do
|
|
||||||
step :upsert_memberships
|
|
||||||
step :recompute_users_count
|
|
||||||
step :notice_channel
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :usernames, :array
|
attribute :usernames, :array
|
||||||
attribute :groups, :array
|
attribute :groups, :array
|
||||||
|
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
validates :channel_id, presence: true
|
|
||||||
|
|
||||||
|
validates :channel_id, presence: true
|
||||||
validate :target_presence
|
validate :target_presence
|
||||||
|
|
||||||
def target_presence
|
def target_presence
|
||||||
usernames.present? || groups.present?
|
usernames.present? || groups.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
model :channel
|
||||||
|
policy :can_add_users_to_channel
|
||||||
|
model :target_users, optional: true
|
||||||
|
policy :satisfies_dms_max_users_limit,
|
||||||
|
class_name: Chat::DirectMessageChannel::Policy::MaxUsersExcess
|
||||||
|
transaction do
|
||||||
|
step :upsert_memberships
|
||||||
|
step :recompute_users_count
|
||||||
|
step :notice_channel
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -128,20 +123,17 @@ module Chat
|
||||||
|
|
||||||
return if added_users.blank?
|
return if added_users.blank?
|
||||||
|
|
||||||
result =
|
::Chat::CreateMessage.call(
|
||||||
::Chat::CreateMessage.call(
|
guardian: Discourse.system_user.guardian,
|
||||||
guardian: Discourse.system_user.guardian,
|
chat_channel_id: channel.id,
|
||||||
chat_channel_id: channel.id,
|
message:
|
||||||
message:
|
I18n.t(
|
||||||
I18n.t(
|
"chat.channel.users_invited_to_channel",
|
||||||
"chat.channel.users_invited_to_channel",
|
invited_users: added_users.map { |u| "@#{u.username}" }.join(", "),
|
||||||
invited_users: added_users.map { |u| "@#{u.username}" }.join(", "),
|
inviting_user: "@#{guardian.user.username}",
|
||||||
inviting_user: "@#{guardian.user.username}",
|
count: added_users.count,
|
||||||
count: added_users.count,
|
),
|
||||||
),
|
) { on_failure { fail!(failure: "Failed to notice the channel") } }
|
||||||
)
|
|
||||||
|
|
||||||
fail!(failure: "Failed to notice the channel") if result.failure?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,13 +14,7 @@ module Chat
|
||||||
class AutoJoinChannelBatch
|
class AutoJoinChannelBatch
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :channel
|
|
||||||
step :create_memberships
|
|
||||||
step :recalculate_user_count
|
|
||||||
step :publish_new_channel
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
# Backward-compatible attributes
|
# Backward-compatible attributes
|
||||||
attribute :chat_channel_id, :integer
|
attribute :chat_channel_id, :integer
|
||||||
attribute :starts_at, :integer
|
attribute :starts_at, :integer
|
||||||
|
@ -41,6 +35,10 @@ module Chat
|
||||||
self.end_user_id ||= ends_at
|
self.end_user_id ||= ends_at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
model :channel
|
||||||
|
step :create_memberships
|
||||||
|
step :recalculate_user_count
|
||||||
|
step :publish_new_channel
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@ module Chat
|
||||||
class HandleCategoryUpdated
|
class HandleCategoryUpdated
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :category_id, :integer
|
||||||
|
|
||||||
|
validates :category_id, presence: true
|
||||||
|
end
|
||||||
step :assign_defaults
|
step :assign_defaults
|
||||||
policy :chat_enabled
|
policy :chat_enabled
|
||||||
model :category
|
model :category
|
||||||
|
@ -23,12 +27,6 @@ module Chat
|
||||||
step :remove_users_without_channel_permission
|
step :remove_users_without_channel_permission
|
||||||
step :publish
|
step :publish
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :category_id, :integer
|
|
||||||
|
|
||||||
validates :category_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def assign_defaults
|
def assign_defaults
|
||||||
|
|
|
@ -21,7 +21,11 @@ module Chat
|
||||||
class HandleDestroyedGroup
|
class HandleDestroyedGroup
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :destroyed_group_user_ids
|
||||||
|
|
||||||
|
validates :destroyed_group_user_ids, presence: true
|
||||||
|
end
|
||||||
step :assign_defaults
|
step :assign_defaults
|
||||||
policy :chat_enabled
|
policy :chat_enabled
|
||||||
policy :not_everyone_allowed
|
policy :not_everyone_allowed
|
||||||
|
@ -30,12 +34,6 @@ module Chat
|
||||||
step :remove_users_without_channel_permission
|
step :remove_users_without_channel_permission
|
||||||
step :publish
|
step :publish
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :destroyed_group_user_ids
|
|
||||||
|
|
||||||
validates :destroyed_group_user_ids, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def assign_defaults
|
def assign_defaults
|
||||||
|
|
|
@ -20,7 +20,11 @@ module Chat
|
||||||
class HandleUserRemovedFromGroup
|
class HandleUserRemovedFromGroup
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :user_id, :integer
|
||||||
|
|
||||||
|
validates :user_id, presence: true
|
||||||
|
end
|
||||||
step :assign_defaults
|
step :assign_defaults
|
||||||
policy :chat_enabled
|
policy :chat_enabled
|
||||||
policy :not_everyone_allowed
|
policy :not_everyone_allowed
|
||||||
|
@ -30,12 +34,6 @@ module Chat
|
||||||
step :remove_from_private_channels
|
step :remove_from_private_channels
|
||||||
step :publish
|
step :publish
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :user_id, :integer
|
|
||||||
|
|
||||||
validates :user_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def assign_defaults
|
def assign_defaults
|
||||||
|
|
|
@ -29,17 +29,7 @@ module Chat
|
||||||
|
|
||||||
policy :public_channels_enabled
|
policy :public_channels_enabled
|
||||||
policy :can_create_channel
|
policy :can_create_channel
|
||||||
contract
|
contract do
|
||||||
model :category, :fetch_category
|
|
||||||
policy :category_channel_does_not_exist
|
|
||||||
transaction do
|
|
||||||
model :channel, :create_channel
|
|
||||||
model :membership, :create_membership
|
|
||||||
end
|
|
||||||
step :enforce_automatic_channel_memberships
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :name, :string
|
attribute :name, :string
|
||||||
attribute :description, :string
|
attribute :description, :string
|
||||||
attribute :slug, :string
|
attribute :slug, :string
|
||||||
|
@ -55,6 +45,13 @@ module Chat
|
||||||
validates :category_id, presence: true
|
validates :category_id, presence: true
|
||||||
validates :name, length: { maximum: SiteSetting.max_topic_title_length }
|
validates :name, length: { maximum: SiteSetting.max_topic_title_length }
|
||||||
end
|
end
|
||||||
|
model :category
|
||||||
|
policy :category_channel_does_not_exist
|
||||||
|
transaction do
|
||||||
|
model :channel, :create_channel
|
||||||
|
model :membership, :create_membership
|
||||||
|
end
|
||||||
|
step :enforce_automatic_channel_memberships
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,18 @@ module Chat
|
||||||
# @option params_to_create [Boolean] upsert
|
# @option params_to_create [Boolean] upsert
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :name, :string
|
||||||
|
attribute :target_usernames, :array
|
||||||
|
attribute :target_groups, :array
|
||||||
|
attribute :upsert, :boolean, default: false
|
||||||
|
|
||||||
|
validate :target_presence
|
||||||
|
|
||||||
|
def target_presence
|
||||||
|
target_usernames.present? || target_groups.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
model :target_users
|
model :target_users
|
||||||
policy :can_create_direct_message
|
policy :can_create_direct_message
|
||||||
policy :satisfies_dms_max_users_limit,
|
policy :satisfies_dms_max_users_limit,
|
||||||
|
@ -38,20 +49,6 @@ module Chat
|
||||||
step :update_memberships
|
step :update_memberships
|
||||||
step :recompute_users_count
|
step :recompute_users_count
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :name, :string
|
|
||||||
attribute :target_usernames, :array
|
|
||||||
attribute :target_groups, :array
|
|
||||||
attribute :upsert, :boolean, default: false
|
|
||||||
|
|
||||||
validate :target_presence
|
|
||||||
|
|
||||||
def target_presence
|
|
||||||
target_usernames.present? || target_groups.present?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def can_create_direct_message(guardian:, target_users:)
|
def can_create_direct_message(guardian:, target_users:)
|
||||||
|
|
|
@ -22,36 +22,7 @@ module Chat
|
||||||
# @param incoming_chat_webhook [Chat::IncomingWebhook]
|
# @param incoming_chat_webhook [Chat::IncomingWebhook]
|
||||||
|
|
||||||
policy :no_silenced_user
|
policy :no_silenced_user
|
||||||
contract
|
contract do
|
||||||
model :channel
|
|
||||||
step :enforce_membership
|
|
||||||
model :membership
|
|
||||||
policy :allowed_to_create_message_in_channel, class_name: Chat::Channel::Policy::MessageCreation
|
|
||||||
model :reply, optional: true
|
|
||||||
policy :ensure_reply_consistency
|
|
||||||
model :thread, optional: true
|
|
||||||
policy :ensure_valid_thread_for_channel
|
|
||||||
policy :ensure_thread_matches_parent
|
|
||||||
model :uploads, optional: true
|
|
||||||
step :clean_message
|
|
||||||
model :message_instance, :instantiate_message
|
|
||||||
|
|
||||||
transaction do
|
|
||||||
step :create_excerpt
|
|
||||||
step :update_created_by_sdk
|
|
||||||
step :save_message
|
|
||||||
step :delete_drafts
|
|
||||||
step :post_process_thread
|
|
||||||
step :create_webhook_event
|
|
||||||
step :update_channel_last_message
|
|
||||||
step :update_membership_last_read
|
|
||||||
step :process_direct_message_channel
|
|
||||||
end
|
|
||||||
step :publish_new_thread
|
|
||||||
step :process
|
|
||||||
step :publish_user_tracking_state
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :chat_channel_id, :string
|
attribute :chat_channel_id, :string
|
||||||
attribute :in_reply_to_id, :string
|
attribute :in_reply_to_id, :string
|
||||||
attribute :context_topic_id, :integer
|
attribute :context_topic_id, :integer
|
||||||
|
@ -71,6 +42,32 @@ module Chat
|
||||||
validates :chat_channel_id, presence: true
|
validates :chat_channel_id, presence: true
|
||||||
validates :message, presence: true, if: -> { upload_ids.blank? }
|
validates :message, presence: true, if: -> { upload_ids.blank? }
|
||||||
end
|
end
|
||||||
|
model :channel
|
||||||
|
step :enforce_membership
|
||||||
|
model :membership
|
||||||
|
policy :allowed_to_create_message_in_channel, class_name: Chat::Channel::Policy::MessageCreation
|
||||||
|
model :reply, optional: true
|
||||||
|
policy :ensure_reply_consistency
|
||||||
|
model :thread, optional: true
|
||||||
|
policy :ensure_valid_thread_for_channel
|
||||||
|
policy :ensure_thread_matches_parent
|
||||||
|
model :uploads, optional: true
|
||||||
|
step :clean_message
|
||||||
|
model :message_instance, :instantiate_message
|
||||||
|
transaction do
|
||||||
|
step :create_excerpt
|
||||||
|
step :update_created_by_sdk
|
||||||
|
step :save_message
|
||||||
|
step :delete_drafts
|
||||||
|
step :post_process_thread
|
||||||
|
step :create_webhook_event
|
||||||
|
step :update_channel_last_message
|
||||||
|
step :update_membership_last_read
|
||||||
|
step :process_direct_message_channel
|
||||||
|
end
|
||||||
|
step :publish_new_thread
|
||||||
|
step :process
|
||||||
|
step :publish_user_tracking_state
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,14 @@ module Chat
|
||||||
# @option params_to_create [String,nil] title
|
# @option params_to_create [String,nil] title
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :original_message_id, :integer
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :title, :string
|
||||||
|
|
||||||
|
validates :original_message_id, :channel_id, presence: true
|
||||||
|
validates :title, length: { maximum: Chat::Thread::MAX_TITLE_LENGTH }
|
||||||
|
end
|
||||||
model :channel
|
model :channel
|
||||||
policy :can_view_channel
|
policy :can_view_channel
|
||||||
policy :threading_enabled_for_channel
|
policy :threading_enabled_for_channel
|
||||||
|
@ -29,16 +36,6 @@ module Chat
|
||||||
step :trigger_chat_thread_created_event
|
step :trigger_chat_thread_created_event
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :original_message_id, :integer
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
attribute :title, :string
|
|
||||||
|
|
||||||
validates :original_message_id, :channel_id, presence: true
|
|
||||||
validates :title, length: { maximum: Chat::Thread::MAX_TITLE_LENGTH }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_channel(contract:)
|
def fetch_channel(contract:)
|
||||||
|
|
|
@ -26,27 +26,22 @@ module Chat
|
||||||
# the force_review option.
|
# the force_review option.
|
||||||
|
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
model :message
|
|
||||||
policy :can_flag_message_in_channel
|
|
||||||
step :flag_message
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :integer
|
attribute :message_id, :integer
|
||||||
validates :message_id, presence: true
|
|
||||||
|
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
validates :channel_id, presence: true
|
|
||||||
|
|
||||||
attribute :flag_type_id, :integer
|
attribute :flag_type_id, :integer
|
||||||
validates :flag_type_id, inclusion: { in: ->(_flag_type) { ::ReviewableScore.types.values } }
|
|
||||||
|
|
||||||
attribute :message, :string
|
attribute :message, :string
|
||||||
attribute :is_warning, :boolean
|
attribute :is_warning, :boolean
|
||||||
attribute :take_action, :boolean
|
attribute :take_action, :boolean
|
||||||
attribute :queue_for_review, :boolean
|
attribute :queue_for_review, :boolean
|
||||||
|
|
||||||
|
validates :message_id, presence: true
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
validates :flag_type_id, inclusion: { in: ->(_flag_type) { ::ReviewableScore.types.values } }
|
||||||
end
|
end
|
||||||
|
model :message
|
||||||
|
policy :can_flag_message_in_channel
|
||||||
|
step :flag_message
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -16,23 +16,19 @@ module Chat
|
||||||
# @option optional_params [Integer, nil] message_id
|
# @option optional_params [Integer, nil] message_id
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :user_ids, :array
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :message_id, :integer
|
||||||
|
|
||||||
|
validates :user_ids, presence: true
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
end
|
||||||
model :channel
|
model :channel
|
||||||
policy :can_view_channel
|
policy :can_view_channel
|
||||||
model :users, optional: true
|
model :users, optional: true
|
||||||
step :send_invite_notifications
|
step :send_invite_notifications
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :user_ids, :array
|
|
||||||
validates :user_ids, presence: true
|
|
||||||
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
|
|
||||||
attribute :message_id, :integer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_channel(contract:)
|
def fetch_channel(contract:)
|
||||||
|
|
|
@ -17,17 +17,15 @@ module Chat
|
||||||
# @param [Integer] channel_id of the channel
|
# @param [Integer] channel_id of the channel
|
||||||
|
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
end
|
||||||
model :channel
|
model :channel
|
||||||
step :leave
|
step :leave
|
||||||
step :recompute_users_count
|
step :recompute_users_count
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_channel(contract:)
|
def fetch_channel(contract:)
|
||||||
|
|
|
@ -15,11 +15,34 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :page_size, :integer
|
||||||
|
|
||||||
|
# If this is not present, then we just fetch messages with page_size
|
||||||
|
# and direction.
|
||||||
|
attribute :target_message_id, :integer # (optional)
|
||||||
|
attribute :direction, :string # (optional)
|
||||||
|
attribute :fetch_from_last_read, :boolean # (optional)
|
||||||
|
attribute :target_date, :string # (optional)
|
||||||
|
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
validates :page_size,
|
||||||
|
numericality: {
|
||||||
|
less_than_or_equal_to: ::Chat::MessagesQuery::MAX_PAGE_SIZE,
|
||||||
|
only_integer: true,
|
||||||
|
},
|
||||||
|
allow_nil: true
|
||||||
|
validates :direction,
|
||||||
|
inclusion: {
|
||||||
|
in: Chat::MessagesQuery::VALID_DIRECTIONS,
|
||||||
|
},
|
||||||
|
allow_nil: true
|
||||||
|
end
|
||||||
|
|
||||||
model :channel
|
model :channel
|
||||||
policy :can_view_channel
|
policy :can_view_channel
|
||||||
step :fetch_optional_membership
|
model :membership, optional: true
|
||||||
step :enabled_threads?
|
step :enabled_threads?
|
||||||
step :determine_target_message_id
|
step :determine_target_message_id
|
||||||
policy :target_message_exists
|
policy :target_message_exists
|
||||||
|
@ -31,40 +54,14 @@ module Chat
|
||||||
step :update_membership_last_viewed_at
|
step :update_membership_last_viewed_at
|
||||||
step :update_user_last_channel
|
step :update_user_last_channel
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
|
|
||||||
attribute :page_size, :integer
|
|
||||||
validates :page_size,
|
|
||||||
numericality: {
|
|
||||||
less_than_or_equal_to: ::Chat::MessagesQuery::MAX_PAGE_SIZE,
|
|
||||||
only_integer: true,
|
|
||||||
},
|
|
||||||
allow_nil: true
|
|
||||||
|
|
||||||
# If this is not present, then we just fetch messages with page_size
|
|
||||||
# and direction.
|
|
||||||
attribute :target_message_id, :integer # (optional)
|
|
||||||
attribute :direction, :string # (optional)
|
|
||||||
attribute :fetch_from_last_read, :boolean # (optional)
|
|
||||||
attribute :target_date, :string # (optional)
|
|
||||||
|
|
||||||
validates :direction,
|
|
||||||
inclusion: {
|
|
||||||
in: Chat::MessagesQuery::VALID_DIRECTIONS,
|
|
||||||
},
|
|
||||||
allow_nil: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_channel(contract:)
|
def fetch_channel(contract:)
|
||||||
::Chat::Channel.includes(:chatable).find_by(id: contract.channel_id)
|
::Chat::Channel.includes(:chatable).find_by(id: contract.channel_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_optional_membership(channel:, guardian:)
|
def fetch_membership(channel:, guardian:)
|
||||||
context.membership = channel.membership_for(guardian.user)
|
channel.membership_for(guardian.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enabled_threads?(channel:)
|
def enabled_threads?(channel:)
|
||||||
|
|
|
@ -15,19 +15,8 @@ module Chat
|
||||||
# @option optional_params [Integer] thread_id
|
# @option optional_params [Integer] thread_id
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
|
||||||
model :thread
|
|
||||||
policy :can_view_thread
|
|
||||||
step :fetch_optional_membership
|
|
||||||
step :determine_target_message_id
|
|
||||||
policy :target_message_exists
|
|
||||||
step :fetch_messages
|
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
validates :thread_id, presence: true
|
|
||||||
|
|
||||||
# If this is not present, then we just fetch messages with page_size
|
# If this is not present, then we just fetch messages with page_size
|
||||||
# and direction.
|
# and direction.
|
||||||
attribute :target_message_id, :integer # (optional)
|
attribute :target_message_id, :integer # (optional)
|
||||||
|
@ -38,6 +27,7 @@ module Chat
|
||||||
attribute :fetch_from_first_message, :boolean # (optional)
|
attribute :fetch_from_first_message, :boolean # (optional)
|
||||||
attribute :target_date, :string # (optional)
|
attribute :target_date, :string # (optional)
|
||||||
|
|
||||||
|
validates :thread_id, presence: true
|
||||||
validates :direction,
|
validates :direction,
|
||||||
inclusion: {
|
inclusion: {
|
||||||
in: Chat::MessagesQuery::VALID_DIRECTIONS,
|
in: Chat::MessagesQuery::VALID_DIRECTIONS,
|
||||||
|
@ -50,13 +40,15 @@ module Chat
|
||||||
},
|
},
|
||||||
allow_nil: true
|
allow_nil: true
|
||||||
end
|
end
|
||||||
|
model :thread
|
||||||
|
policy :can_view_thread
|
||||||
|
model :membership, optional: true
|
||||||
|
step :determine_target_message_id
|
||||||
|
policy :target_message_exists
|
||||||
|
model :messages, optional: true
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_optional_membership(thread:, guardian:)
|
|
||||||
context.membership = thread.membership_for(guardian.user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_thread(contract:)
|
def fetch_thread(contract:)
|
||||||
::Chat::Thread.strict_loading.includes(channel: :chatable).find_by(id: contract.thread_id)
|
::Chat::Thread.strict_loading.includes(channel: :chatable).find_by(id: contract.thread_id)
|
||||||
end
|
end
|
||||||
|
@ -65,6 +57,10 @@ module Chat
|
||||||
guardian.user == Discourse.system_user || guardian.can_preview_chat_channel?(thread.channel)
|
guardian.user == Discourse.system_user || guardian.can_preview_chat_channel?(thread.channel)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_membership(thread:, guardian:)
|
||||||
|
thread.membership_for(guardian.user)
|
||||||
|
end
|
||||||
|
|
||||||
def determine_target_message_id(contract:, membership:, guardian:, thread:)
|
def determine_target_message_id(contract:, membership:, guardian:, thread:)
|
||||||
if contract.fetch_from_last_message
|
if contract.fetch_from_last_message
|
||||||
context.target_message_id = thread.last_message_id
|
context.target_message_id = thread.last_message_id
|
||||||
|
@ -106,7 +102,7 @@ module Chat
|
||||||
context.can_load_more_past = messages_data[:can_load_more_past]
|
context.can_load_more_past = messages_data[:can_load_more_past]
|
||||||
context.can_load_more_future = messages_data[:can_load_more_future]
|
context.can_load_more_future = messages_data[:can_load_more_future]
|
||||||
|
|
||||||
context.messages = [
|
[
|
||||||
messages_data[:messages],
|
messages_data[:messages],
|
||||||
messages_data[:past_messages]&.reverse,
|
messages_data[:past_messages]&.reverse,
|
||||||
messages_data[:target_message],
|
messages_data[:target_message],
|
||||||
|
|
|
@ -24,7 +24,19 @@ module Chat
|
||||||
# @param [Integer] offset
|
# @param [Integer] offset
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :limit, :integer
|
||||||
|
attribute :offset, :integer
|
||||||
|
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
validates :limit,
|
||||||
|
numericality: {
|
||||||
|
less_than_or_equal_to: THREADS_LIMIT,
|
||||||
|
only_integer: true,
|
||||||
|
},
|
||||||
|
allow_nil: true
|
||||||
|
end
|
||||||
step :set_limit
|
step :set_limit
|
||||||
step :set_offset
|
step :set_offset
|
||||||
model :channel
|
model :channel
|
||||||
|
@ -36,22 +48,6 @@ module Chat
|
||||||
step :fetch_participants
|
step :fetch_participants
|
||||||
step :build_load_more_url
|
step :build_load_more_url
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
|
|
||||||
attribute :limit, :integer
|
|
||||||
validates :limit,
|
|
||||||
numericality: {
|
|
||||||
less_than_or_equal_to: THREADS_LIMIT,
|
|
||||||
only_integer: true,
|
|
||||||
},
|
|
||||||
allow_nil: true
|
|
||||||
|
|
||||||
attribute :offset, :integer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_limit(contract:)
|
def set_limit(contract:)
|
||||||
|
|
|
@ -16,20 +16,17 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :thread, :fetch_thread
|
|
||||||
policy :invalid_access
|
|
||||||
policy :threading_enabled_for_channel
|
|
||||||
step :fetch_membership
|
|
||||||
step :fetch_participants
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
validates :thread_id, :channel_id, presence: true
|
validates :thread_id, :channel_id, presence: true
|
||||||
end
|
end
|
||||||
|
model :thread
|
||||||
|
policy :invalid_access
|
||||||
|
policy :threading_enabled_for_channel
|
||||||
|
model :membership, optional: true
|
||||||
|
model :participants, optional: true
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -50,11 +47,11 @@ module Chat
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_membership(thread:, guardian:)
|
def fetch_membership(thread:, guardian:)
|
||||||
context.membership = thread.membership_for(guardian.user)
|
thread.membership_for(guardian.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_participants(thread:)
|
def fetch_participants(thread:)
|
||||||
context.participants = ::Chat::ThreadParticipantQuery.call(thread_ids: [thread.id])[thread.id]
|
::Chat::ThreadParticipantQuery.call(thread_ids: [thread.id])[thread.id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,10 @@ module Chat
|
||||||
# @param [Integer] offset
|
# @param [Integer] offset
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :limit, :integer
|
||||||
|
attribute :offset, :integer
|
||||||
|
end
|
||||||
step :set_limit
|
step :set_limit
|
||||||
step :set_offset
|
step :set_offset
|
||||||
model :threads
|
model :threads
|
||||||
|
@ -29,12 +32,6 @@ module Chat
|
||||||
step :fetch_participants
|
step :fetch_participants
|
||||||
step :build_load_more_url
|
step :build_load_more_url
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :limit, :integer
|
|
||||||
attribute :offset, :integer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_limit(contract:)
|
def set_limit(contract:)
|
||||||
|
|
|
@ -21,19 +21,16 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :thread
|
|
||||||
policy :threading_enabled_for_channel
|
|
||||||
policy :can_view_channel
|
|
||||||
transaction { step :create_or_update_membership }
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
validates :thread_id, :channel_id, presence: true
|
validates :thread_id, :channel_id, presence: true
|
||||||
end
|
end
|
||||||
|
model :thread
|
||||||
|
policy :threading_enabled_for_channel
|
||||||
|
policy :can_view_channel
|
||||||
|
transaction { step :create_or_update_membership }
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,13 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :message_id, :integer
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
|
validates :message_id, presence: true
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
end
|
||||||
model :message
|
model :message
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
transaction do
|
transaction do
|
||||||
|
@ -27,14 +33,6 @@ module Chat
|
||||||
end
|
end
|
||||||
step :publish_events
|
step :publish_events
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :integer
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :message_id, presence: true
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_message(contract:)
|
def fetch_message(contract:)
|
||||||
|
|
|
@ -16,16 +16,7 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
step :clean_term
|
|
||||||
model :memberships, optional: true
|
|
||||||
model :users, optional: true
|
|
||||||
model :groups, optional: true
|
|
||||||
model :category_channels, optional: true
|
|
||||||
model :direct_message_channels, optional: true
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :term, :string, default: ""
|
attribute :term, :string, default: ""
|
||||||
attribute :include_users, :boolean, default: true
|
attribute :include_users, :boolean, default: true
|
||||||
attribute :include_groups, :boolean, default: true
|
attribute :include_groups, :boolean, default: true
|
||||||
|
@ -33,6 +24,12 @@ module Chat
|
||||||
attribute :include_direct_message_channels, :boolean, default: true
|
attribute :include_direct_message_channels, :boolean, default: true
|
||||||
attribute :excluded_memberships_channel_id, :integer
|
attribute :excluded_memberships_channel_id, :integer
|
||||||
end
|
end
|
||||||
|
step :clean_term
|
||||||
|
model :memberships, optional: true
|
||||||
|
model :users, optional: true
|
||||||
|
model :groups, optional: true
|
||||||
|
model :category_channels, optional: true
|
||||||
|
model :direct_message_channels, optional: true
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,11 @@ module Chat
|
||||||
# @param [Integer] message_id
|
# @param [Integer] message_id
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
|
attribute :message_id, :integer
|
||||||
|
|
||||||
|
validates :message_id, presence: true
|
||||||
|
end
|
||||||
model :message
|
model :message
|
||||||
step :enforce_membership
|
step :enforce_membership
|
||||||
model :membership
|
model :membership
|
||||||
|
@ -21,13 +25,6 @@ module Chat
|
||||||
step :stop_message_streaming
|
step :stop_message_streaming
|
||||||
step :publish_message_streaming_state
|
step :publish_message_streaming_state
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :integer
|
|
||||||
|
|
||||||
validates :message_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_message(contract:)
|
def fetch_message(contract:)
|
||||||
|
|
|
@ -33,26 +33,17 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
step :cast_thread_and_channel_ids_to_integer
|
attribute :channel_ids, :array, default: []
|
||||||
model :report
|
attribute :thread_ids, :array, default: []
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_ids, default: []
|
|
||||||
attribute :thread_ids, default: []
|
|
||||||
attribute :include_missing_memberships, default: false
|
attribute :include_missing_memberships, default: false
|
||||||
attribute :include_threads, default: false
|
attribute :include_threads, default: false
|
||||||
attribute :include_read, default: true
|
attribute :include_read, default: true
|
||||||
end
|
end
|
||||||
|
model :report
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def cast_thread_and_channel_ids_to_integer(contract:)
|
|
||||||
contract.thread_ids = contract.thread_ids.map(&:to_i)
|
|
||||||
contract.channel_ids = contract.channel_ids.map(&:to_i)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_report(contract:, guardian:)
|
def fetch_report(contract:, guardian:)
|
||||||
::Chat::TrackingStateReportQuery.call(
|
::Chat::TrackingStateReportQuery.call(
|
||||||
guardian: guardian,
|
guardian: guardian,
|
||||||
|
|
|
@ -17,7 +17,13 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :message_id, :integer
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
|
validates :message_id, presence: true
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
end
|
||||||
model :message
|
model :message
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
transaction do
|
transaction do
|
||||||
|
@ -29,14 +35,6 @@ module Chat
|
||||||
end
|
end
|
||||||
step :publish_events
|
step :publish_events
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :integer
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
validates :message_id, presence: true
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_message(contract:)
|
def fetch_message(contract:)
|
||||||
|
|
|
@ -17,7 +17,13 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :message_ids, :array
|
||||||
|
|
||||||
|
validates :channel_id, presence: true
|
||||||
|
validates :message_ids, length: { minimum: 1, maximum: 50 }
|
||||||
|
end
|
||||||
model :messages
|
model :messages
|
||||||
policy :can_delete_all_chat_messages
|
policy :can_delete_all_chat_messages
|
||||||
transaction do
|
transaction do
|
||||||
|
@ -29,14 +35,6 @@ module Chat
|
||||||
end
|
end
|
||||||
step :publish_events
|
step :publish_events
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
attribute :message_ids, :array
|
|
||||||
validates :channel_id, presence: true
|
|
||||||
validates :message_ids, length: { minimum: 1, maximum: 50 }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_messages(contract:)
|
def fetch_messages(contract:)
|
||||||
|
|
|
@ -17,15 +17,13 @@ module Chat
|
||||||
# @param [Integer] channel_id of the channel
|
# @param [Integer] channel_id of the channel
|
||||||
|
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
model :channel
|
|
||||||
step :unfollow
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
validates :channel_id, presence: true
|
validates :channel_id, presence: true
|
||||||
end
|
end
|
||||||
|
model :channel
|
||||||
|
step :unfollow
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -32,17 +32,9 @@ module Chat
|
||||||
# @option params_to_edit [Boolean] allow_channel_wide_mentions Allow the use of @here and @all in the channel.
|
# @option params_to_edit [Boolean] allow_channel_wide_mentions Allow the use of @here and @all in the channel.
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
model :channel, :fetch_channel
|
model :channel
|
||||||
policy :check_channel_permission
|
policy :check_channel_permission
|
||||||
contract default_values_from: :channel
|
contract(default_values_from: :channel) do
|
||||||
step :update_channel
|
|
||||||
step :mark_all_threads_as_read_if_needed
|
|
||||||
step :update_site_settings_if_needed
|
|
||||||
step :publish_channel_update
|
|
||||||
step :auto_join_users_if_needed
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :name, :string
|
attribute :name, :string
|
||||||
attribute :description, :string
|
attribute :description, :string
|
||||||
attribute :slug, :string
|
attribute :slug, :string
|
||||||
|
@ -56,6 +48,11 @@ module Chat
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
step :update_channel
|
||||||
|
step :mark_all_threads_as_read_if_needed
|
||||||
|
step :update_site_settings_if_needed
|
||||||
|
step :publish_channel_update
|
||||||
|
step :auto_join_users_if_needed
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,13 @@ module Chat
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
model :channel, :fetch_channel
|
model :channel, :fetch_channel
|
||||||
contract
|
contract do
|
||||||
policy :check_channel_permission
|
|
||||||
step :change_status
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :status
|
attribute :status
|
||||||
|
|
||||||
validates :status, inclusion: { in: Chat::Channel.editable_statuses.keys }
|
validates :status, inclusion: { in: Chat::Channel.editable_statuses.keys }
|
||||||
end
|
end
|
||||||
|
policy :check_channel_permission
|
||||||
|
step :change_status
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,17 @@ module Chat
|
||||||
# @param message [String]
|
# @param message [String]
|
||||||
# @param upload_ids [Array<Integer>] IDs of uploaded documents
|
# @param upload_ids [Array<Integer>] IDs of uploaded documents
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :message_id, :string
|
||||||
|
attribute :message, :string
|
||||||
|
attribute :upload_ids, :array
|
||||||
|
attribute :streaming, :boolean, default: false
|
||||||
|
attribute :strip_whitespaces, :boolean, default: true
|
||||||
|
attribute :process_inline, :boolean, default: Rails.env.test?
|
||||||
|
|
||||||
|
validates :message_id, presence: true
|
||||||
|
validates :message, presence: true, if: -> { upload_ids.blank? }
|
||||||
|
end
|
||||||
model :message
|
model :message
|
||||||
model :uploads, optional: true
|
model :uploads, optional: true
|
||||||
step :enforce_membership
|
step :enforce_membership
|
||||||
|
@ -23,7 +33,6 @@ module Chat
|
||||||
policy :can_modify_channel_message
|
policy :can_modify_channel_message
|
||||||
policy :can_modify_message
|
policy :can_modify_message
|
||||||
step :clean_message
|
step :clean_message
|
||||||
|
|
||||||
transaction do
|
transaction do
|
||||||
step :modify_message
|
step :modify_message
|
||||||
step :update_excerpt
|
step :update_excerpt
|
||||||
|
@ -32,22 +41,6 @@ module Chat
|
||||||
step :publish
|
step :publish
|
||||||
end
|
end
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :string
|
|
||||||
validates :message_id, presence: true
|
|
||||||
|
|
||||||
attribute :message, :string
|
|
||||||
validates :message, presence: true, if: -> { upload_ids.blank? }
|
|
||||||
|
|
||||||
attribute :upload_ids, :array
|
|
||||||
|
|
||||||
attribute :streaming, :boolean, default: false
|
|
||||||
|
|
||||||
attribute :strip_whitespaces, :boolean, default: true
|
|
||||||
|
|
||||||
attribute :process_inline, :boolean, default: Rails.env.test?
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def enforce_membership(guardian:, message:)
|
def enforce_membership(guardian:, message:)
|
||||||
|
|
|
@ -19,22 +19,19 @@ module Chat
|
||||||
# @option params_to_edit [String,nil] title
|
# @option params_to_edit [String,nil] title
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :thread, :fetch_thread
|
|
||||||
policy :can_view_channel
|
|
||||||
policy :can_edit_thread
|
|
||||||
policy :threading_enabled_for_channel
|
|
||||||
step :update
|
|
||||||
step :publish_metadata
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
attribute :title, :string
|
attribute :title, :string
|
||||||
|
|
||||||
validates :thread_id, presence: true
|
validates :thread_id, presence: true
|
||||||
validates :title, length: { maximum: Chat::Thread::MAX_TITLE_LENGTH }
|
validates :title, length: { maximum: Chat::Thread::MAX_TITLE_LENGTH }
|
||||||
end
|
end
|
||||||
|
model :thread
|
||||||
|
policy :can_view_channel
|
||||||
|
policy :can_edit_thread
|
||||||
|
policy :threading_enabled_for_channel
|
||||||
|
step :update
|
||||||
|
step :publish_metadata
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -23,25 +23,21 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
model :thread, :fetch_thread
|
|
||||||
policy :can_view_channel
|
|
||||||
policy :threading_enabled_for_channel
|
|
||||||
transaction { step :create_or_update_membership }
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
attribute :notification_level, :integer
|
attribute :notification_level, :integer
|
||||||
|
|
||||||
validates :thread_id, :channel_id, :notification_level, presence: true
|
validates :thread_id, :channel_id, :notification_level, presence: true
|
||||||
|
|
||||||
validates :notification_level,
|
validates :notification_level,
|
||||||
inclusion: {
|
inclusion: {
|
||||||
in: Chat::UserChatThreadMembership.notification_levels.values,
|
in: Chat::UserChatThreadMembership.notification_levels.values,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
model :thread, :fetch_thread
|
||||||
|
policy :can_view_channel
|
||||||
|
policy :threading_enabled_for_channel
|
||||||
|
transaction { step :create_or_update_membership }
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,12 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :message_id, :integer
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
|
||||||
|
validates :message_id, :channel_id, presence: true
|
||||||
|
end
|
||||||
model :channel
|
model :channel
|
||||||
model :membership
|
model :membership
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
|
@ -27,14 +32,6 @@ module Chat
|
||||||
end
|
end
|
||||||
step :publish_new_last_read_to_clients
|
step :publish_new_last_read_to_clients
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :message_id, :integer
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
|
|
||||||
validates :message_id, :channel_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_channel(contract:)
|
def fetch_channel(contract:)
|
||||||
|
|
|
@ -17,7 +17,13 @@ module Chat
|
||||||
# @param [Guardian] guardian
|
# @param [Guardian] guardian
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
contract
|
contract do
|
||||||
|
attribute :channel_id, :integer
|
||||||
|
attribute :thread_id, :integer
|
||||||
|
attribute :message_id, :integer
|
||||||
|
|
||||||
|
validates :thread_id, :channel_id, presence: true
|
||||||
|
end
|
||||||
model :thread
|
model :thread
|
||||||
policy :invalid_access
|
policy :invalid_access
|
||||||
model :membership
|
model :membership
|
||||||
|
@ -27,15 +33,6 @@ module Chat
|
||||||
step :mark_thread_read
|
step :mark_thread_read
|
||||||
step :publish_new_last_read_to_clients
|
step :publish_new_last_read_to_clients
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
|
||||||
attribute :thread_id, :integer
|
|
||||||
attribute :message_id, :integer
|
|
||||||
|
|
||||||
validates :thread_id, :channel_id, presence: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_thread(contract:)
|
def fetch_thread(contract:)
|
||||||
|
|
|
@ -20,20 +20,17 @@ module Chat
|
||||||
# @param [String] json object as string containing the data of the draft (message, uploads, replyToMsg and editing keys)
|
# @param [String] json object as string containing the data of the draft (message, uploads, replyToMsg and editing keys)
|
||||||
# @option [Integer] thread_id of the channel
|
# @option [Integer] thread_id of the channel
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
contract
|
contract do
|
||||||
model :channel
|
|
||||||
policy :can_upsert_draft
|
|
||||||
step :check_thread_exists
|
|
||||||
step :upsert_draft
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
class Contract
|
|
||||||
attribute :channel_id, :integer
|
attribute :channel_id, :integer
|
||||||
validates :channel_id, presence: true
|
validates :channel_id, presence: true
|
||||||
|
|
||||||
attribute :thread_id, :integer
|
attribute :thread_id, :integer
|
||||||
attribute :data, :string
|
attribute :data, :string
|
||||||
end
|
end
|
||||||
|
model :channel
|
||||||
|
policy :can_upsert_draft
|
||||||
|
step :check_thread_exists
|
||||||
|
step :upsert_draft
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -38,18 +38,17 @@ RSpec.describe Service::Runner do
|
||||||
class FailedContractService
|
class FailedContractService
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
class Contract
|
contract do
|
||||||
attribute :test
|
attribute :test
|
||||||
|
|
||||||
validates :test, presence: true
|
validates :test, presence: true
|
||||||
end
|
end
|
||||||
|
|
||||||
contract
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class SuccessContractService
|
class SuccessContractService
|
||||||
include Service::Base
|
include Service::Base
|
||||||
|
|
||||||
contract
|
contract {}
|
||||||
end
|
end
|
||||||
|
|
||||||
class FailureWithModelService
|
class FailureWithModelService
|
||||||
|
|
|
@ -6,18 +6,16 @@ RSpec.describe StepsInspector do
|
||||||
|
|
||||||
model :model
|
model :model
|
||||||
policy :policy
|
policy :policy
|
||||||
contract
|
contract do
|
||||||
|
attribute :parameter
|
||||||
|
|
||||||
|
validates :parameter, presence: true
|
||||||
|
end
|
||||||
transaction do
|
transaction do
|
||||||
step :in_transaction_step_1
|
step :in_transaction_step_1
|
||||||
step :in_transaction_step_2
|
step :in_transaction_step_2
|
||||||
end
|
end
|
||||||
step :final_step
|
step :final_step
|
||||||
|
|
||||||
class Contract
|
|
||||||
attribute :parameter
|
|
||||||
|
|
||||||
validates :parameter, presence: true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:inspector) { described_class.new(result) }
|
subject(:inspector) { described_class.new(result) }
|
||||||
|
|
Loading…
Reference in New Issue