Skip to content

Commit

Permalink
refactor(has_j_send_status_and_attributes): respect entity classes
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Apr 30, 2023
1 parent 4e4b790 commit 6365baa
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,73 @@ module Plugins
module HasJSendStatusAndAttributes
module Commands
class CastJSendAttributes < Support::Command
attr_reader :attributes
##
# @!attribute [r] result
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
#
attr_reader :result

def initialize(attributes:)
@attributes = attributes
##
# @!attribute [r] kwargs
# @return [Hash{Symbol => Object}]
#
attr_reader :kwargs

##
# @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
# @param kwargs [Hash{Symbol => Object}]
# @return [void]
#
def initialize(result:, kwargs:)
@result = result
@kwargs = kwargs
end

##
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Structs::JSendAttributes]
# @raise [ConvenientService::Support::Castable::Errors::FailedToCast]
#
def call
Structs::JSendAttributes.new(
service: attributes[:service],
status: Entities::Status.cast!(attributes[:status]),
data: Entities::Data.cast!(attributes[:data]),
message: Entities::Message.cast!(attributes[:message]),
code: Entities::Code.cast!(attributes[:code])
)
Structs::JSendAttributes.new(service: service, status: status, data: data, message: message, code: code)
end

##
# @return [Object]
#
def service
kwargs[:service]
end

##
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status]
# @raise [ConvenientService::Support::Castable::Errors::FailedToCast]
#
def status
@status ||= result.class.status_class.cast!(kwargs[:status])
end

##
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Data]
# @raise [ConvenientService::Support::Castable::Errors::FailedToCast]
#
def data
@data ||= result.class.data_class.cast!(kwargs[:data])
end

##
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Message]
# @raise [ConvenientService::Support::Castable::Errors::FailedToCast]
#
def message
@message ||= result.class.message_class.cast!(kwargs[:message])
end

##
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Code]
# @raise [ConvenientService::Support::Castable::Errors::FailedToCast]
#
def code
@code ||= result.class.code_class.cast!(kwargs[:code])
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Middleware < MethodChainMiddleware
# @return [void]
#
def next(*args, **kwargs, &block)
entity.internals.cache[:jsend_attributes] = Commands::CastJSendAttributes.call(attributes: kwargs)
entity.internals.cache[:jsend_attributes] = Commands::CastJSendAttributes.call(result: entity, kwargs: kwargs)

chain.next(*args, **kwargs, &block)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,40 @@

require "convenient_service"

# rubocop:disable RSpec/NestedGroups
# rubocop:disable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
RSpec.describe ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Commands::CastJSendAttributes do
example_group "class methods" do
describe ".call" do
let(:service_class) { Class.new }
let(:service_class) do
Class.new do
include ConvenientService::Configs::Minimal

def result
success
end
end
end

let(:service_instance) { service_class.new }
let(:result) { service_instance.result }

let(:command_result) { described_class.call(attributes: attributes) }
let(:attributes) { {service: service_instance, status: :foo, data: {foo: :bar}, message: "foo", code: :foo} }
let(:command_result) { described_class.call(result: result, kwargs: kwargs) }
let(:kwargs) { {service: service_instance, status: :foo, data: {foo: :bar}, message: "foo", code: :foo} }

it "returns `struct` with `attributes[:service]` as `service`" do
expect(command_result.service).to eq(attributes[:service])
it "returns `struct` with `kwargs[:service]` as `service`" do
expect(command_result.service).to eq(kwargs[:service])
end

it "returns `struct` with `attributes[:status]` casted to `ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status` as `status`" do
expect(command_result.status).to eq(ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status.cast(attributes[:status]))
it "returns `struct` with `kwargs[:status]` casted to `result.class.status_class` as `status`" do
expect(command_result.status).to eq(result.class.status_class.cast(kwargs[:status]))
end

context "when `attributes[:status]` is NOT castable" do
let(:command_result) { described_class.call(attributes: attributes.merge(status: 42)) }
context "when `kwargs[:status]` is NOT castable" do
let(:command_result) { described_class.call(result: result, kwargs: kwargs.merge(status: 42)) }

let(:error_message) do
<<~TEXT
Failed to cast `42` into `#{ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status}`.
Failed to cast `42` into `#{result.class.status_class}`.
TEXT
end

Expand All @@ -38,16 +48,16 @@
end
end

it "returns `struct` with `attributes[:data]` casted to `ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Data` as `data`" do
expect(command_result.data).to eq(ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Data.cast(attributes[:data]))
it "returns `struct` with `kwargs[:data]` casted to `result.class.data_class` as `data`" do
expect(command_result.data).to eq(result.class.data_class.cast(kwargs[:data]))
end

context "when `attributes[:data]` is NOT castable" do
let(:command_result) { described_class.call(attributes: attributes.merge(data: 42)) }
context "when `kwargs[:data]` is NOT castable" do
let(:command_result) { described_class.call(result: result, kwargs: kwargs.merge(data: 42)) }

let(:error_message) do
<<~TEXT
Failed to cast `42` into `#{ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Data}`.
Failed to cast `42` into `#{result.class.data_class}`.
TEXT
end

Expand All @@ -58,16 +68,16 @@
end
end

it "returns `struct` with `attributes[:message]` casted to `ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Message` as `message`" do
expect(command_result.message).to eq(ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Message.cast(attributes[:message]))
it "returns `struct` with `kwargs[:message]` casted to `result.class.message_class` as `message`" do
expect(command_result.message).to eq(result.class.message_class.cast(kwargs[:message]))
end

context "when `attributes[:message]` is NOT castable" do
let(:command_result) { described_class.call(attributes: attributes.merge(message: 42)) }
context "when `kwargs[:message]` is NOT castable" do
let(:command_result) { described_class.call(result: result, kwargs: kwargs.merge(message: 42)) }

let(:error_message) do
<<~TEXT
Failed to cast `42` into `#{ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Message}`.
Failed to cast `42` into `#{result.class.message_class}`.
TEXT
end

Expand All @@ -78,16 +88,16 @@
end
end

it "returns `struct` with `attributes[:code]` casted to `ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Code` as `code`" do
expect(command_result.code).to eq(ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Code.cast(attributes[:code]))
it "returns `struct` with `kwargs[:code]` casted to `result.class.code_class` as `code`" do
expect(command_result.code).to eq(result.class.code_class.cast(kwargs[:code]))
end

context "when `attributes[:code]` is NOT castable" do
let(:command_result) { described_class.call(attributes: attributes.merge(code: 42)) }
context "when `kwargs[:code]` is NOT castable" do
let(:command_result) { described_class.call(result: result, kwargs: kwargs.merge(code: 42)) }

let(:error_message) do
<<~TEXT
Failed to cast `42` into `#{ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Code}`.
Failed to cast `42` into `#{result.class.code_class}`.
TEXT
end

Expand All @@ -100,4 +110,4 @@
end
end
end
# rubocop:enable RSpec/NestedGroups
# rubocop:enable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
include ConvenientService::RSpec::Matchers::CallChainNext
include ConvenientService::RSpec::Matchers::DelegateTo

subject(:method_value) { method.call(**attributes) }
subject(:method_value) { method.call(**kwargs) }

let(:method) { wrap_method(result_instance, :initialize, middlewares: described_class) }
let(:method) { wrap_method(result, :initialize, middlewares: described_class) }

let(:attributes) do
let(:kwargs) do
{
service: double,
status: :foo,
Expand All @@ -48,26 +48,22 @@
}
end

# rubocop:disable RSpec/LeakyConstantDeclaration, Lint/ConstantDefinitionInBlock
let(:result_class) do
let(:service) do
Class.new do
include ConvenientService::Common::Plugins::HasInternals::Concern
include ConvenientService::Common::Plugins::HasConstructor::Concern
include ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Concern
include ConvenientService::Configs::Minimal

class self::Internals
include ConvenientService::Common::Plugins::HasInternals::Entities::Internals::Plugins::HasCache::Concern
def result
success
end
end
end
# rubocop:enable RSpec/LeakyConstantDeclaration, Lint/ConstantDefinitionInBlock

let(:result_instance) { result_class.allocate }
let(:result) { service.result }

specify do
expect { method_value }
.to delegate_to(ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Commands::CastJSendAttributes, :call)
.with_arguments(attributes: attributes)
.with_arguments(result: result, kwargs: kwargs)
end

specify do
Expand Down

0 comments on commit 6365baa

Please sign in to comment.