diff --git a/Gemfile.lock b/Gemfile.lock index 94f6472..79e803c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: yookassa (0.1.0) - dry-initializer + dry-struct http (~> 5.0.1) GEM @@ -13,13 +13,35 @@ GEM ast (2.4.2) byebug (11.1.3) coderay (1.1.3) + concurrent-ruby (1.1.9) crack (0.4.5) rexml diff-lcs (1.4.4) docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dry-initializer (3.0.4) + dry-configurable (0.13.0) + concurrent-ruby (~> 1.0) + dry-core (~> 0.6) + dry-container (0.9.0) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.13, >= 0.13.0) + dry-core (0.7.1) + concurrent-ruby (~> 1.0) + dry-inflector (0.2.1) + dry-logic (1.2.0) + concurrent-ruby (~> 1.0) + dry-core (~> 0.5, >= 0.5) + dry-struct (1.4.0) + dry-core (~> 0.5, >= 0.5) + dry-types (~> 1.5) + ice_nine (~> 0.11) + dry-types (1.5.1) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.5, >= 0.5) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) ffi (1.15.4) ffi-compiler (1.0.1) ffi (>= 1.0.0) @@ -33,6 +55,7 @@ GEM http-cookie (1.0.4) domain_name (~> 0.5) http-form_data (2.3.0) + ice_nine (0.11.2) llhttp-ffi (0.4.0) ffi-compiler (~> 1.0) rake (~> 13.0) diff --git a/lib/yookassa.rb b/lib/yookassa.rb index b70d279..aaebd55 100644 --- a/lib/yookassa.rb +++ b/lib/yookassa.rb @@ -1,16 +1,13 @@ # frozen_string_literal: true require "http" -require "dry-initializer" +require "dry-struct" require "yookassa/version" require "yookassa/payment" require "yookassa/refund" -require "yookassa/response" -require "yookassa/callable" -require "yookassa/optional" require "yookassa/entity/payment" require "yookassa/entity/refund" -require "yookassa/error" +require "yookassa/entity/error" require "yookassa/config" require "yookassa/http_helpers" diff --git a/lib/yookassa/callable.rb b/lib/yookassa/callable.rb deleted file mode 100644 index fa08026..0000000 --- a/lib/yookassa/callable.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Yookassa - module Callable - def call(*args) - new(*args) - end - alias [] call - end -end diff --git a/lib/yookassa/entity/amount.rb b/lib/yookassa/entity/amount.rb index 4182e04..2db9abf 100644 --- a/lib/yookassa/entity/amount.rb +++ b/lib/yookassa/entity/amount.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true +require_relative "./types" + module Yookassa module Entity - class Amount - extend Dry::Initializer - extend Yookassa::Callable - include Yookassa::Optional - - option :value, proc(&:to_f), optional: true - option :currency, proc(&:to_s), optional: true + class Amount < Dry::Struct + attribute :value, Types::Coercible::Float + attribute :currency, Types::String end end end diff --git a/lib/yookassa/entity/card.rb b/lib/yookassa/entity/card.rb index 26b23a7..599220e 100644 --- a/lib/yookassa/entity/card.rb +++ b/lib/yookassa/entity/card.rb @@ -1,18 +1,16 @@ # frozen_string_literal: true +require_relative "./types" + module Yookassa module Entity - class Card - extend Dry::Initializer - extend Yookassa::Callable - include Yookassa::Optional - - option :first6 - option :last4 - option :expiry_month - option :expiry_year - option :card_type, proc(&:to_s) - option :source, proc(&:to_s), optional: true + class Card < Dry::Struct + attribute :first6, Types::Integer + attribute :last4, Types::Integer + attribute :expiry_month, Types::Integer + attribute :expiry_year, Types::Integer + attribute :card_type, Types::String + attribute :source, Types::String end end end diff --git a/lib/yookassa/entity/confirmation.rb b/lib/yookassa/entity/confirmation.rb index cab9f3a..3454dd7 100644 --- a/lib/yookassa/entity/confirmation.rb +++ b/lib/yookassa/entity/confirmation.rb @@ -1,16 +1,14 @@ # frozen_string_literal: true +require_relative "./types" + module Yookassa module Entity - class Confirmation - extend Dry::Initializer - extend Yookassa::Callable - include Yookassa::Optional - - option :type, proc(&:to_s), optional: true - option :confirmation_url, proc(&:to_s), optional: true - option :enforce, optional: true - option :return_url, proc(&:to_s), optional: true + class Confirmation < Dry::Struct + attribute :type, Types::String + attribute :confirmation_url, Types::String + attribute? :enforce, Types::Bool + attribute? :return_url, Types::String end end end diff --git a/lib/yookassa/entity/error.rb b/lib/yookassa/entity/error.rb new file mode 100644 index 0000000..6d225e4 --- /dev/null +++ b/lib/yookassa/entity/error.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Yookassa + module Entity + class Error < Dry::Struct + attribute :type, Types::String + attribute? :id, Types::String + attribute? :code, Types::String + attribute? :description, Types::String + attribute? :parameter, Types::String + + def error? + type == "error" + end + end + end +end diff --git a/lib/yookassa/entity/payment.rb b/lib/yookassa/entity/payment.rb index 7fb4133..1e4667b 100644 --- a/lib/yookassa/entity/payment.rb +++ b/lib/yookassa/entity/payment.rb @@ -1,22 +1,26 @@ # frozen_string_literal: true +require_relative "./types" require_relative "./amount" require_relative "./payment_method" require_relative "./confirmation" module Yookassa module Entity - class Payment < Yookassa::Response - option :paid - option :amount, Entity::Amount - option :created_at - option :captured_at, proc(&:to_s), optional: true - option :expires_at, optional: true - option :description, proc(&:to_s), optional: true - option :metadata, optional: true - option :payment_method, Entity::PaymentMethod, optional: true - option :confirmation, Entity::Confirmation, optional: true - option :test + class Payment < Dry::Struct + attribute :id, Types::String + attribute :status, Types::String.enum("pending", "waiting_for_capture", "succeeded", "canceled") + attribute :paid, Types::Bool + attribute :amount, Entity::Amount + attribute? :income_amount, Entity::Amount + attribute :created_at, Types::String + attribute? :captured_at, Types::String + attribute? :expires_at, Types::String + attribute? :description, Types::String + attribute :metadata, Types::Hash + attribute :payment_method, Entity::PaymentMethod + attribute :confirmation, Entity::Confirmation + attribute :test, Types::Bool end end end diff --git a/lib/yookassa/entity/payment_method.rb b/lib/yookassa/entity/payment_method.rb index a7a93ea..47358cc 100644 --- a/lib/yookassa/entity/payment_method.rb +++ b/lib/yookassa/entity/payment_method.rb @@ -1,19 +1,16 @@ # frozen_string_literal: true +require_relative "./types" require_relative "./card" module Yookassa module Entity - class PaymentMethod - extend Dry::Initializer - extend Yookassa::Callable - include Yookassa::Optional - - option :type, proc(&:to_s) - option :id, proc(&:to_s) - option :saved - option :card, Entity::Card, optional: true - option :title, proc(&:to_s), optional: true + class PaymentMethod < Dry::Struct + attribute :type, Types::String + attribute :id, Types::String + attribute :saved, Types::Bool + attribute? :card, Entity::Card + attribute? :title, Types::String end end end diff --git a/lib/yookassa/entity/refund.rb b/lib/yookassa/entity/refund.rb index a5da761..03613cb 100644 --- a/lib/yookassa/entity/refund.rb +++ b/lib/yookassa/entity/refund.rb @@ -1,15 +1,18 @@ # frozen_string_literal: true +require_relative "./types" require_relative "./amount" module Yookassa module Entity - class Refund < Yookassa::Response - option :payment_id - option :created_at, proc(&:to_s) - option :amount, Entity::Amount - option :receipt_registration, proc(&:to_s), optional: true - option :description, proc(&:to_s), optional: true + class Refund < Dry::Struct + attribute :id, Types::String + attribute :status, Types::String + attribute :payment_id, Types::String + attribute :created_at, Types::String + attribute :amount, Entity::Amount + attribute? :receipt_registration, Types::String + attribute :description, Types::String end end end diff --git a/lib/yookassa/entity/types.rb b/lib/yookassa/entity/types.rb new file mode 100644 index 0000000..4306115 --- /dev/null +++ b/lib/yookassa/entity/types.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Yookassa + module Entity + module Types + include Dry.Types() + end + end +end diff --git a/lib/yookassa/error.rb b/lib/yookassa/error.rb deleted file mode 100644 index e4d9974..0000000 --- a/lib/yookassa/error.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Yookassa - class Error - extend Dry::Initializer - extend Yookassa::Callable - include Yookassa::Optional - - option :type, proc(&:to_s) - option :id, proc(&:to_s), optional: true - option :code, proc(&:to_s), optional: true - option :description, proc(&:to_s), optional: true - option :parameter, proc(&:to_s), optional: true - - def error? - type == "error" - end - - class << self - def build(*res) - body = res.last - new JSON.parse(body.first) - end - - def new(opts) - super opts.transform_keys(&:to_sym) - end - end - end -end diff --git a/lib/yookassa/http_helpers.rb b/lib/yookassa/http_helpers.rb index 94b1039..26e80d6 100644 --- a/lib/yookassa/http_helpers.rb +++ b/lib/yookassa/http_helpers.rb @@ -8,7 +8,7 @@ module Yookassa response = client.get("#{API_URL}#{endpoint}", params: query) body = JSON.parse(response.body.to_s, symbolize_names: true) - return Error.new(body) if response.status.client_error? + return Entity::Error.new(**body) if response.status.client_error? yield(body) if block_given? end @@ -17,7 +17,7 @@ module Yookassa response = client.headers("Idempotence-Key" => idempotency_key).post("#{API_URL}#{endpoint}", json: payload) body = JSON.parse(response.body.to_s, symbolize_names: true) - return Error.new(body) if response.status.client_error? + return Entity::Error.new(**body) if response.status.client_error? yield(body) if block_given? end diff --git a/lib/yookassa/optional.rb b/lib/yookassa/optional.rb deleted file mode 100644 index 026c9eb..0000000 --- a/lib/yookassa/optional.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Yookassa - module Optional - private - - def initialize(opts) - super opts.transform_keys(&:to_sym) - end - - def __options__ - @__options__ ||= self.class.dry_initializer.attributes(self) - end - - def respond_to_missing?(name, *) - __options__.respond_to? name - end - - def method_missing(*args, &block) - respond_to_missing?(*args) ? __options__.send(*args, &block) : super - end - end -end diff --git a/lib/yookassa/response.rb b/lib/yookassa/response.rb deleted file mode 100644 index e6ddd84..0000000 --- a/lib/yookassa/response.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Yookassa - class Response - extend Dry::Initializer - option :id, proc(&:to_s) - option :status, proc(&:to_s), default: proc {} - end -end diff --git a/spec/yookassa/payment_spec.rb b/spec/yookassa/payment_spec.rb index 1ae3228..36c802e 100644 --- a/spec/yookassa/payment_spec.rb +++ b/spec/yookassa/payment_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Yookassa::Payment do shared_examples "returns_payment_object" do it "returns success" do - expect(subject).to be_kind_of Yookassa::Response + expect(subject).to be_a Yookassa::Entity::Payment expect(subject.id).to eq "2490ded1-000f-5000-8000-1f64111bc63e" expect(subject.test).to eq true expect(subject.paid).to eq false @@ -21,17 +21,17 @@ RSpec.describe Yookassa::Payment do expect(subject.expires_at).to eq nil expect(subject.metadata).to eq({}) - expect(subject.amount).to be_kind_of Yookassa::Entity::Amount + expect(subject.amount).to be_a Yookassa::Entity::Amount expect(subject.amount.currency).to eq "RUB" expect(subject.amount.value).to eq 10.0 - expect(subject.confirmation).to be_kind_of Yookassa::Entity::Confirmation + expect(subject.confirmation).to be_a Yookassa::Entity::Confirmation expect(subject.confirmation.confirmation_url).to eq "https://money.yookassa.ru/payments/external/confirmation?orderId=2490ded1-000f-5000-8000-1f64111bc63e" expect(subject.confirmation.type).to eq "redirect" expect(subject.confirmation.return_url).to eq "https://url.test" expect(subject.confirmation.enforce).to eq nil - expect(subject.payment_method).to be_kind_of Yookassa::Entity::PaymentMethod + expect(subject.payment_method).to be_a Yookassa::Entity::PaymentMethod expect(subject.payment_method.card).to eq nil expect(subject.payment_method.id).to eq "2490ded1-000f-5000-8000-1f64111bc63e" expect(subject.payment_method.saved).to eq false diff --git a/spec/yookassa/refund_spec.rb b/spec/yookassa/refund_spec.rb index 935a6db..526d3d9 100644 --- a/spec/yookassa/refund_spec.rb +++ b/spec/yookassa/refund_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Yookassa::Refund do shared_examples "returns_refund_object" do it "returns success" do - expect(subject).to be_kind_of Yookassa::Response + expect(subject).to be_a Yookassa::Entity::Refund expect(subject.id).to eq "2491ab0c-0015-5000-9000-1640c7f1a6f0" expect(subject.payment_id).to eq "2491a6e2-000f-5000-9000-1480e820ae17" expect(subject.status).to eq "succeeded" diff --git a/yookassa.gemspec b/yookassa.gemspec index 403656f..d938ed0 100644 --- a/yookassa.gemspec +++ b/yookassa.gemspec @@ -22,6 +22,6 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 2.6" - spec.add_runtime_dependency "dry-initializer" + spec.add_runtime_dependency "dry-struct" spec.add_runtime_dependency "http", "~> 5.0.1" end