1
0
зеркало из https://github.com/glebtv/yookassa.git synced 2026-09-08 11:55:50 +03:00

Merge pull request #8 from PaymentInstruments/Replace-evil-client-with-http

Completely replace evil client with http. Ruby 3 still doesn't work
Этот коммит содержится в:
Ivan Shamatov
2021-10-30 22:55:26 +03:00
коммит произвёл GitHub
родитель 98b9eb2667 495bd54fdf
Коммит 508430d1c7
14 изменённых файлов: 171 добавлений и 187 удалений

7
.github/workflows/main.yml поставляемый
Просмотреть файл

@@ -16,6 +16,7 @@ jobs:
ruby: ruby:
- 2.6 - 2.6
- 2.7 - 2.7
- 3.0
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -24,5 +25,7 @@ jobs:
with: with:
ruby-version: ${{ matrix.ruby }} ruby-version: ${{ matrix.ruby }}
bundler-cache: true bundler-cache: true
- name: Cops & Specs - name: Cops
run: bin/rake run: bundle exec rubocop
- name: Specs
run: bundle exec rspec

Просмотреть файл

@@ -9,10 +9,12 @@ gemspec
group :development, :test do group :development, :test do
gem "pry" gem "pry"
gem "pry-byebug" gem "pry-byebug", "~> 3.8.0"
gem "rake", "~> 13.0" gem "rake", "~> 13.0"
gem "rspec", "~> 3.0" gem "rspec", "~> 3.5"
gem "rubocop", "~> 1.21" gem "rubocop", "~> 1.22"
gem "rubocop-rake", "~> 0.6.0" gem "rubocop-rake", "~> 0.6.0"
gem "rubocop-rspec", "~> 2.5" gem "rubocop-rspec", "~> 2.5"
gem "simplecov", "~> 0.16"
gem "webmock", "~> 3.14"
end end

Просмотреть файл

@@ -2,63 +2,68 @@ PATH
remote: . remote: .
specs: specs:
yookassa (0.1.0) yookassa (0.1.0)
evil-client (~> 3.0) dry-initializer
http (~> 5.0.1)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
addressable (2.6.0) addressable (2.8.0)
public_suffix (>= 2.0.2, < 4.0) public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2) ast (2.4.2)
byebug (11.0.1) byebug (11.1.3)
coderay (1.1.2) coderay (1.1.3)
concurrent-ruby (1.1.7) crack (0.4.5)
crack (0.4.3) rexml
safe_yaml (~> 1.0.0) diff-lcs (1.4.4)
diff-lcs (1.3) docile (1.4.0)
docile (1.3.1) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dry-initializer (3.0.4) dry-initializer (3.0.4)
evil-client (3.0.4) ffi (1.15.4)
dry-initializer (>= 2.1, < 4) ffi-compiler (1.0.1)
mime-types (~> 3.1) ffi (>= 1.0.0)
rack (~> 2) rake
tram-policy (>= 0.3.1, < 3) hashdiff (1.0.1)
hashdiff (0.4.0) http (5.0.4)
i18n (1.8.5) addressable (~> 2.8)
concurrent-ruby (~> 1.0) http-cookie (~> 1.0)
json (2.2.0) http-form_data (~> 2.2)
method_source (0.9.2) llhttp-ffi (~> 0.4.0)
mime-types (3.3.1) http-cookie (1.0.4)
mime-types-data (~> 3.2015) domain_name (~> 0.5)
mime-types-data (3.2020.1104) http-form_data (2.3.0)
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
method_source (1.0.0)
parallel (1.21.0) parallel (1.21.0)
parser (3.0.2.0) parser (3.0.2.0)
ast (~> 2.4.1) ast (~> 2.4.1)
pry (0.12.2) pry (0.14.1)
coderay (~> 1.1.0) coderay (~> 1.1)
method_source (~> 0.9.0) method_source (~> 1.0)
pry-byebug (3.7.0) pry-byebug (3.8.0)
byebug (~> 11.0) byebug (~> 11.0)
pry (~> 0.10) pry (~> 0.10)
public_suffix (3.1.0) public_suffix (4.0.6)
rack (2.2.3)
rainbow (3.0.0) rainbow (3.0.0)
rake (13.0.6) rake (13.0.6)
regexp_parser (2.1.1) regexp_parser (2.1.1)
rexml (3.2.5) rexml (3.2.5)
rspec (3.8.0) rspec (3.10.0)
rspec-core (~> 3.8.0) rspec-core (~> 3.10.0)
rspec-expectations (~> 3.8.0) rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.8.0) rspec-mocks (~> 3.10.0)
rspec-core (3.8.0) rspec-core (3.10.1)
rspec-support (~> 3.8.0) rspec-support (~> 3.10.0)
rspec-expectations (3.8.3) rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0) rspec-support (~> 3.10.0)
rspec-mocks (3.8.0) rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0) rspec-support (~> 3.10.0)
rspec-support (3.8.0) rspec-support (3.10.2)
rubocop (1.22.3) rubocop (1.22.3)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.0.0.0) parser (>= 3.0.0.0)
@@ -75,34 +80,34 @@ GEM
rubocop-rspec (2.5.0) rubocop-rspec (2.5.0)
rubocop (~> 1.19) rubocop (~> 1.19)
ruby-progressbar (1.11.0) ruby-progressbar (1.11.0)
safe_yaml (1.0.5) simplecov (0.21.2)
simplecov (0.16.1)
docile (~> 1.1) docile (~> 1.1)
json (>= 1.8, < 3) simplecov-html (~> 0.11)
simplecov-html (~> 0.10.0) simplecov_json_formatter (~> 0.1)
simplecov-html (0.10.2) simplecov-html (0.12.3)
tram-policy (2.0.1) simplecov_json_formatter (0.1.3)
dry-initializer (> 2, < 4) unf (0.1.4)
i18n (~> 1.0) unf_ext
unf_ext (0.0.8)
unicode-display_width (2.1.0) unicode-display_width (2.1.0)
webmock (3.5.1) webmock (3.14.0)
addressable (>= 2.3.6) addressable (>= 2.8.0)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff (>= 0.4.0, < 2.0.0)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
pry pry
pry-byebug pry-byebug (~> 3.8.0)
rake (~> 13.0) rake (~> 13.0)
rspec (~> 3.0) rspec (~> 3.5)
rubocop (~> 1.21) rubocop (~> 1.22)
rubocop-rake (~> 0.6.0) rubocop-rake (~> 0.6.0)
rubocop-rspec (~> 2.5) rubocop-rspec (~> 2.5)
simplecov (~> 0.16) simplecov (~> 0.16)
webmock (~> 3.5) webmock (~> 3.14)
yookassa! yookassa!
BUNDLED WITH BUNDLED WITH

Просмотреть файл

@@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require "evil/client" require "http"
require "dry-initializer"
require "yookassa/version" require "yookassa/version"
require "yookassa/payment" require "yookassa/payment"
require "yookassa/refund" require "yookassa/refund"
@@ -12,6 +12,7 @@ require "yookassa/entity/payment"
require "yookassa/entity/refund" require "yookassa/entity/refund"
require "yookassa/error" require "yookassa/error"
require "yookassa/config" require "yookassa/config"
require "yookassa/http_helpers"
module Yookassa module Yookassa
def self.configure def self.configure

29
lib/yookassa/http_helpers.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,29 @@
# frozen_string_literal: true
module Yookassa
module HttpHelpers
API_URL = "https://api.yookassa.ru/v3/"
def get(endpoint, query: {})
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?
yield(body) if block_given?
end
def post(endpoint, idempotency_key:, payload: {})
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?
yield(body) if block_given?
end
def client
HTTP.basic_auth(user: shop_id, pass: api_key).headers(accept: "application/json")
end
end
end

Просмотреть файл

@@ -1,65 +1,46 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "http_helpers"
module Yookassa module Yookassa
class Payment < Evil::Client class Payment
option :shop_id, proc(&:to_s), default: proc { Yookassa.config.shop_id } include HttpHelpers
option :api_key, proc(&:to_s), default: proc { Yookassa.config.api_key }
path { "https://api.yookassa.ru/v3/payments" } attr_reader :shop_id, :api_key
security { basic_auth shop_id, api_key }
operation :get_payment_info do def initialize(shop_id: Yookassa.config.shop_id, api_key: Yookassa.config.api_key)
option :payment_id, proc(&:to_s) @shop_id = shop_id
@api_key = api_key
http_method :get
path { "/#{payment_id}" }
response(200) { |*res| Entity::Payment.build(*res) }
response(400, 404) { |*res| Error.build(*res) }
end end
operation :create do def get_payment_info(payment_id:)
option :payment get("payments/#{payment_id}") do |response|
option :idempotency_key, proc(&:to_s) Entity::Payment.new(**response)
http_method :post
format "json"
headers { { "Idempotence-Key" => idempotency_key } }
body { payment }
response(200) { |*res| Entity::Payment.build(*res) }
response(400) { |*res| Error.build(*res) }
end
operation :capture do
option :payment_id, proc(&:to_s)
option :idempotency_key, optional: true
http_method :post
path { "/#{payment_id}/capture" }
format "json"
headers { { "Idempotence-Key" => idempotency_key } }
response(200) { |*res| Entity::Payment.build(*res) }
response(400) { |*res| Error.build(*res) }
end
operation :cancel do
option :payment_id, proc(&:to_s)
option :idempotency_key, optional: true
http_method :post
path { "/#{payment_id}/cancel" }
format "json"
headers { { "Idempotence-Key" => idempotency_key } }
response(200) { |*res| Entity::Payment.build(*res) }
response(400) { |*res| Error.build(*res) }
end end
end end
def create(payment:, idempotency_key: SecureRandom.hex(10))
post("payments", payload: payment, idempotency_key: idempotency_key) do |response|
Entity::Payment.new(**response)
end
end
def capture(payment_id:, idempotency_key: SecureRandom.hex(10))
post("payments/#{payment_id}/capture", idempotency_key: idempotency_key) do |response|
Entity::Payment.new(**response)
end
end
def cancel(payment_id:, idempotency_key: SecureRandom.hex(10))
post("payments/#{payment_id}/cancel", idempotency_key: idempotency_key) do |response|
Entity::Payment.new(**response)
end
end
# def self.list(shop_id: Yookassa.config.shop_id, api_key: Yookassa.config.api_key)
# get("payments", shop_id: shop_id, api_key: api_key) do |resp|
# resp['items'].map { Entity::Payment.new(_1) }
# end
# end
end
end end

Просмотреть файл

@@ -1,35 +1,28 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "http_helpers"
module Yookassa module Yookassa
class Refund < Evil::Client class Refund
option :shop_id, proc(&:to_s), default: proc { Yookassa.config.shop_id } include HttpHelpers
option :api_key, proc(&:to_s), default: proc { Yookassa.config.api_key }
path { "https://api.yookassa.ru/v3/refunds" } attr_reader :shop_id, :api_key
security { basic_auth shop_id, api_key }
operation :get_refund_info do def initialize(shop_id: Yookassa.config.shop_id, api_key: Yookassa.config.api_key)
option :payment_id, proc(&:to_s) @shop_id = shop_id
@api_key = api_key
http_method :get
path { "/#{payment_id}" }
response(200) { |*res| Entity::Refund.build(*res) }
response(400, 404) { |*res| Error.build(*res) }
end end
operation :create do def get_refund_info(payment_id:)
option :payload get("refunds/#{payment_id}") do |response|
option :idempotency_key, proc(&:to_s) Entity::Refund.new(**response)
end
end
http_method :post def create(payload:, idempotency_key: SecureRandom.hex(10))
post("refunds", payload: payload, idempotency_key: idempotency_key) do |response|
format "json" Entity::Refund.new(**response)
headers { { "Idempotence-Key" => idempotency_key } } end
body { payload }
response(200) { |*res| Entity::Refund.build(*res) }
response(400, 404) { |*res| Error.build(*res) }
end end
end end
end end

Просмотреть файл

@@ -5,16 +5,5 @@ module Yookassa
extend Dry::Initializer extend Dry::Initializer
option :id, proc(&:to_s) option :id, proc(&:to_s)
option :status, proc(&:to_s), default: proc {} option :status, proc(&:to_s), default: proc {}
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
end end

Просмотреть файл

@@ -13,9 +13,4 @@ RSpec.configure do |config|
config.order = :random config.order = :random
config.filter_run focus: true config.filter_run focus: true
config.run_all_when_everything_filtered = true config.run_all_when_everything_filtered = true
config.around(:each) do |example|
stub_request(:any, //)
example.run
end
end end

Просмотреть файл

@@ -1,9 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module Yookassa RSpec.describe Yookassa::Config do
RSpec.describe Config do
subject { described_class.new } subject { described_class.new }
it { is_expected.to respond_to(:shop_id) } it { is_expected.to respond_to(:shop_id) }
it { is_expected.to respond_to(:api_key) } it { is_expected.to respond_to(:api_key) }
end end
end

Просмотреть файл

@@ -3,7 +3,10 @@
RSpec.describe Yookassa::Payment do RSpec.describe Yookassa::Payment do
let(:settings) { { shop_id: "SHOP_ID", api_key: "API_KEY" } } let(:settings) { { shop_id: "SHOP_ID", api_key: "API_KEY" } }
let(:idempotency_key) { 12_345 } let(:idempotency_key) { 12_345 }
let(:payment) { described_class.new(settings) } let(:payment) { described_class.new(**settings) }
let(:body) { File.read("spec/fixtures/payment_response.json") }
before { stub_request(:any, //).to_return(body: body, headers: { "Content-Type" => "application/json" }) }
shared_examples "returns_payment_object" do shared_examples "returns_payment_object" do
it "returns success" do it "returns success" do
@@ -38,11 +41,9 @@ RSpec.describe Yookassa::Payment do
end end
describe "#create" do describe "#create" do
let(:params) { { payment: File.read("spec/fixtures/payment.json") } } let(:params) { JSON.parse(File.read("spec/fixtures/payment.json")) }
let(:url) { "https://api.yookassa.ru/v3/payments" } let(:url) { "https://api.yookassa.ru/v3/payments" }
let(:body) { File.read("spec/fixtures/payment_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.create(payment: params, idempotency_key: idempotency_key) } subject { payment.create(payment: params, idempotency_key: idempotency_key) }
it "sends a request" do it "sends a request" do
@@ -56,9 +57,7 @@ RSpec.describe Yookassa::Payment do
describe "#get_payment_info" do describe "#get_payment_info" do
let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" } let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" }
let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}" } let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}" }
let(:body) { File.read("spec/fixtures/payment_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.get_payment_info(payment_id: payment_id) } subject { payment.get_payment_info(payment_id: payment_id) }
it "sends a request" do it "sends a request" do
@@ -71,11 +70,8 @@ RSpec.describe Yookassa::Payment do
describe "#capture" do describe "#capture" do
let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" } let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" }
let(:params) { { payment: File.read("spec/fixtures/payment.json") } }
let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}/capture" } let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}/capture" }
let(:body) { File.read("spec/fixtures/payment_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.capture(payment_id: payment_id, idempotency_key: idempotency_key) } subject { payment.capture(payment_id: payment_id, idempotency_key: idempotency_key) }
it "sends a request" do it "sends a request" do
@@ -89,9 +85,7 @@ RSpec.describe Yookassa::Payment do
describe "#cancel" do describe "#cancel" do
let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" } let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" }
let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}/cancel" } let(:url) { "https://api.yookassa.ru/v3/payments/#{payment_id}/cancel" }
let(:body) { File.read("spec/fixtures/payment_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.cancel(payment_id: payment_id, idempotency_key: idempotency_key) } subject { payment.cancel(payment_id: payment_id, idempotency_key: idempotency_key) }
it "sends a request" do it "sends a request" do

Просмотреть файл

@@ -3,7 +3,10 @@
RSpec.describe Yookassa::Refund do RSpec.describe Yookassa::Refund do
let(:settings) { { shop_id: "SHOP_ID", api_key: "API_KEY" } } let(:settings) { { shop_id: "SHOP_ID", api_key: "API_KEY" } }
let(:idempotency_key) { 12_345 } let(:idempotency_key) { 12_345 }
let(:payment) { described_class.new(settings) } let(:payment) { described_class.new(**settings) }
let(:body) { File.read("spec/fixtures/refund_response.json") }
before { stub_request(:any, //).to_return(body: body, headers: { "Content-Type" => "application/json" }) }
shared_examples "returns_refund_object" do shared_examples "returns_refund_object" do
it "returns success" do it "returns success" do
@@ -21,11 +24,9 @@ RSpec.describe Yookassa::Refund do
end end
describe "#create" do describe "#create" do
let(:payload) { File.read("spec/fixtures/refund.json") } let(:payload) { JSON.parse(File.read("spec/fixtures/refund.json")) }
let(:url) { "https://api.yookassa.ru/v3/refunds" } let(:url) { "https://api.yookassa.ru/v3/refunds" }
let(:body) { File.read("spec/fixtures/refund_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.create(payload: payload, idempotency_key: idempotency_key) } subject { payment.create(payload: payload, idempotency_key: idempotency_key) }
it "sends a request" do it "sends a request" do
@@ -39,9 +40,7 @@ RSpec.describe Yookassa::Refund do
describe "#get_refund_info" do describe "#get_refund_info" do
let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" } let(:payment_id) { "2490ded1-000f-5000-8000-1f64111bc63e" }
let(:url) { "https://api.yookassa.ru/v3/refunds/#{payment_id}" } let(:url) { "https://api.yookassa.ru/v3/refunds/#{payment_id}" }
let(:body) { File.read("spec/fixtures/refund_response.json") }
before { stub_request(:any, //).to_return(body: body) }
subject { payment.get_refund_info(payment_id: payment_id) } subject { payment.get_refund_info(payment_id: payment_id) }
it "sends a request" do it "sends a request" do

Просмотреть файл

@@ -22,11 +22,6 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 2.6" spec.required_ruby_version = ">= 2.6"
spec.add_runtime_dependency "evil-client", "~> 3.0" spec.add_runtime_dependency "dry-initializer"
spec.add_runtime_dependency "http", "~> 5.0.1"
spec.add_development_dependency "rake", ">= 10.0"
spec.add_development_dependency "rspec", "~> 3.5"
spec.add_development_dependency "rubocop", "~> 0.71"
spec.add_development_dependency "simplecov", "~> 0.16"
spec.add_development_dependency "webmock", "~> 3.5"
end end