client cleanup. add user endpoint. initial specs.
This commit is contained in:
parent
938dc32747
commit
3a9d9cf6c7
32
Gemfile.lock
32
Gemfile.lock
|
@ -2,7 +2,9 @@ PATH
|
|||
remote: .
|
||||
specs:
|
||||
btcpay (0.1.0)
|
||||
flexirest (~> 1.9, < 2.0)
|
||||
activesupport (> 5)
|
||||
multi_json (~> 1.15)
|
||||
rest-client (~> 2.1)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
|
@ -22,16 +24,15 @@ GEM
|
|||
safe_yaml (~> 1.0.0)
|
||||
diff-lcs (1.4.4)
|
||||
docile (1.3.2)
|
||||
faraday (1.0.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
flexirest (1.9.16)
|
||||
activesupport
|
||||
crack
|
||||
faraday
|
||||
mime-types
|
||||
multi_json
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
factory_bot (6.1.0)
|
||||
activesupport (>= 5.0.0)
|
||||
hashdiff (1.0.1)
|
||||
i18n (1.8.3)
|
||||
http-accept (1.7.0)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (1.8.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (1.0.0)
|
||||
mime-types (3.3.1)
|
||||
|
@ -39,7 +40,7 @@ GEM
|
|||
mime-types-data (3.2020.0512)
|
||||
minitest (5.14.1)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.1.1)
|
||||
netrc (0.11.0)
|
||||
parallel (1.19.2)
|
||||
parser (2.7.1.4)
|
||||
ast (~> 2.4.1)
|
||||
|
@ -50,6 +51,11 @@ GEM
|
|||
rainbow (3.0.0)
|
||||
rake (12.3.3)
|
||||
regexp_parser (1.7.1)
|
||||
rest-client (2.1.0)
|
||||
http-accept (>= 1.7.0, < 2.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
rexml (3.2.4)
|
||||
rspec (3.9.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
|
@ -84,6 +90,9 @@ GEM
|
|||
thread_safe (0.3.6)
|
||||
tzinfo (1.2.7)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
vcr (6.0.0)
|
||||
webmock (3.8.3)
|
||||
|
@ -98,6 +107,7 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
btcpay!
|
||||
bundler (~> 2.0)
|
||||
factory_bot (~> 6.1)
|
||||
pry (> 0)
|
||||
rake (~> 12.0)
|
||||
rspec (~> 3.0)
|
||||
|
|
55
README.md
55
README.md
|
@ -22,7 +22,58 @@ Or install it yourself as:
|
|||
|
||||
## Usage
|
||||
|
||||
TODO: Write usage instructions here
|
||||
#### Required Params
|
||||
|
||||
##### Auth Token
|
||||
|
||||
At least one of the following auth tokens are required. Auth tokens can be created via the following:
|
||||
|
||||
1. `auth_token`
|
||||
- Scoped Api Tokens can be created via `/Manage/APIKeys`
|
||||
- `BTCPAY_AUTH_TOKEN` environment variable can also be used
|
||||
1. `basic_auth_token`
|
||||
- Legacy Api Key can be created per store via `/stores/{store-id}/Tokens`
|
||||
- `BTCPAY_BASIC_AUTH_TOKEN` environment variable can also be used
|
||||
|
||||
##### Base Url
|
||||
|
||||
A `base_url` is required to interact with the server.
|
||||
- `BTCPAY_BASE_URL` environment variable can also be used
|
||||
|
||||
```ruby
|
||||
client = BtcPay.new(auth_token: 'foobar', base_url: 'http://localhost:49392')
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
A response consists of the following accessible attributes:
|
||||
|
||||
1. `#body` - rubified response body
|
||||
1. `#code` - response status code
|
||||
1. `#headers` - response headers
|
||||
1. `#raw` - unaltered response body
|
||||
1. `#status` - `:success`/`:failure`
|
||||
|
||||
### Request object types
|
||||
|
||||
All endpoints are accessed via namespaced Api resource. Example: `client.users.create({ email: 'foo@bar.com', password: 'password', isAdministrator: false })`
|
||||
|
||||
#### Users:
|
||||
|
||||
1. `#me(**opts)`
|
||||
- alias: `get`, `show`
|
||||
1. `#create(payload, **opts)`
|
||||
|
||||
|
||||
### Environment Variables
|
||||
|
||||
`btcpay` can be initialized with either arguments or ENV:
|
||||
|
||||
| Variable | Description | Default |
|
||||
| --------------------------|:------------------------|:--------:|
|
||||
| `BTCPAY_AUTH_TOKEN` | BtcPay Auth Token | - |
|
||||
| `BTCPAY_BASIC_AUTH_TOKEN` | BtcPay Basic Auth Token | - |
|
||||
| `BTCPAY_BASE_URL` | BtcPay Base Url | - |
|
||||
|
||||
### BtcPay Docker Compose
|
||||
|
||||
|
@ -42,7 +93,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|||
|
||||
## Contributing
|
||||
|
||||
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/btcpay.
|
||||
Bug reports and pull requests are welcome on Gitlab at https://gitlab.com/snogrammer/btcpay.
|
||||
|
||||
|
||||
## License
|
||||
|
|
|
@ -28,9 +28,12 @@ Gem::Specification.new do |spec|
|
|||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_dependency 'flexirest', '~> 1.9', '< 2.0'
|
||||
spec.add_dependency 'activesupport', '> 5'
|
||||
spec.add_dependency 'multi_json', '~> 1.15'
|
||||
spec.add_dependency 'rest-client', '~> 2.1'
|
||||
|
||||
spec.add_development_dependency 'bundler', '~> 2.0'
|
||||
spec.add_development_dependency 'factory_bot', '~> 6.1'
|
||||
spec.add_development_dependency 'pry', '> 0'
|
||||
spec.add_development_dependency 'rubocop', '> 0'
|
||||
spec.add_development_dependency 'simplecov', '> 0'
|
||||
|
|
|
@ -2,7 +2,16 @@
|
|||
|
||||
require 'btcpay/version'
|
||||
|
||||
require 'btcpay/client/config'
|
||||
require 'btcpay/client/base'
|
||||
|
||||
module BtcPay
|
||||
class Error < StandardError; end
|
||||
# Your code goes here...
|
||||
|
||||
module_function
|
||||
|
||||
def new(**args)
|
||||
config = BtcPay::Client::Config.new(**args)
|
||||
BtcPay::Client::Base.new(config: config, **args)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
module Api
|
||||
class Base
|
||||
def initialize(client:, logger:)
|
||||
@client = client
|
||||
@logger = logger
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_path
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
def path(*args)
|
||||
request_path = args.prepend(base_path.presence).compact.join('/')
|
||||
request_path[0].eql?('/') ? request_path : '/' + request_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :client, :logger
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require_relative './users'
|
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
module Api
|
||||
class Users < Base
|
||||
PATH = '/users'
|
||||
|
||||
# @see https://docs.btcpayserver.org/API/Greenfield/v1/#operation/Users_GetCurrentUser
|
||||
def me(**opts)
|
||||
client.get(path('me'), options: opts)
|
||||
end
|
||||
|
||||
alias get me
|
||||
alias show me
|
||||
|
||||
# @see https://docs.btcpayserver.org/API/Greenfield/v1/#tag/Users/paths/~1api~1v1~1users/post
|
||||
def create(payload, **opts)
|
||||
client.post(path, payload: payload, options: opts)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_path
|
||||
PATH
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,129 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support'
|
||||
require 'active_support/core_ext/object'
|
||||
require 'rest_client'
|
||||
|
||||
require_relative './result'
|
||||
require_relative './api/base'
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
class Error < RuntimeError
|
||||
def initialize(message)
|
||||
super(message)
|
||||
end
|
||||
end
|
||||
|
||||
class Base
|
||||
API_PATH = '/api/v1'
|
||||
DEFAULT_TIMEOUT = 10
|
||||
|
||||
# @param config [BtcPay::Client::Config]
|
||||
# @param logger [Logger]
|
||||
# @param timeout [Integer] Defaults to DEFAULT_TIMEOUT
|
||||
def initialize(config:, logger: Logger.new(STDOUT), timeout: DEFAULT_TIMEOUT, **_kwargs)
|
||||
@config = config
|
||||
@logger = logger
|
||||
@timeout = timeout
|
||||
end
|
||||
|
||||
# GET request
|
||||
#
|
||||
# @param uri [String]
|
||||
# @param options [Hash]
|
||||
# @param headers [Hash]
|
||||
# @return [Result]
|
||||
def get(uri, options: {}, headers: {})
|
||||
request(uri, method: :get, options: options, headers: headers)
|
||||
end
|
||||
|
||||
# POST request
|
||||
#
|
||||
# @param uri [String]
|
||||
# @param payload [Hash]
|
||||
# @param options [Hash]
|
||||
# @param headers [Hash]
|
||||
# @return [Result]
|
||||
def post(uri, payload:, options: {}, headers: {})
|
||||
data = payload.is_a?(Hash) ? payload.to_json : payload
|
||||
request(uri, method: :post, payload: data, options: options, headers: headers)
|
||||
end
|
||||
|
||||
def users
|
||||
@users ||= Api::Users.new(client: self, logger: logger)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :config, :logger
|
||||
|
||||
# @return [Hash]
|
||||
def default_headers
|
||||
{
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
'User-Agent' => config.user_agent,
|
||||
'Accept-Encoding' => 'deflate, gzip',
|
||||
'Authorization' => config.authorization
|
||||
}
|
||||
end
|
||||
|
||||
# @yield [Result]
|
||||
def request(uri, method:, payload: nil, options: {}, headers: {})
|
||||
options ||= {}
|
||||
headers ||= {}
|
||||
|
||||
url = URI(config.base_url)
|
||||
url.path = API_PATH + uri
|
||||
url.query = CGI.unescape(options.to_query).presence
|
||||
|
||||
params = {
|
||||
method: method,
|
||||
url: url.to_s,
|
||||
payload: payload,
|
||||
headers: default_headers.merge(headers),
|
||||
open_timeout: open_timeout,
|
||||
timeout: timeout
|
||||
}.compact
|
||||
|
||||
response = RestClient::Request.execute(params)
|
||||
|
||||
logger.debug(message: 'GET Request', url: url, options: options, status: response.code)
|
||||
result = success?(response.code) ? Result.success(response) : Result.failed(response)
|
||||
|
||||
logger.warn(error: 'Request Error', code: result.code, body: result.raw) if result.failure?
|
||||
result
|
||||
rescue ::RestClient::GatewayTimeout
|
||||
raise Error.new('Gateway timeout')
|
||||
rescue ::RestClient::RequestTimeout
|
||||
raise Error.new('Request timeout')
|
||||
rescue ::RestClient::Exception => e
|
||||
handle_error(e)
|
||||
end
|
||||
|
||||
# Handle errors
|
||||
# @param error [Error]
|
||||
# @return [Result]
|
||||
def handle_error(error)
|
||||
logger.error(error: 'Request Exception', code: error.response.code, message: error.message)
|
||||
|
||||
Result.failed(response)
|
||||
end
|
||||
|
||||
# @return [Integer]
|
||||
def open_timeout
|
||||
@open_timeout || DEFAULT_TIMEOUT
|
||||
end
|
||||
|
||||
# @return [Integer]
|
||||
def timeout
|
||||
@timeout || DEFAULT_TIMEOUT
|
||||
end
|
||||
|
||||
def success?(response_code)
|
||||
response_code.in?(200..299)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
class Config
|
||||
AUTH_TOKEN_TYPE = 'token'
|
||||
BASIC_TOKEN_TYPE = 'Basic'
|
||||
|
||||
attr_reader :authorization, :auth_token, :basic_auth_token, :base_url, :user_agent
|
||||
|
||||
def initialize(**kwargs)
|
||||
@base_url = load_url(kwargs[:base_url])
|
||||
@user_agent = kwargs[:user_agent] || "btcpay_ruby/#{BtcPay::VERSION}"
|
||||
|
||||
load_auth_token(kwargs)
|
||||
set_authorization
|
||||
end
|
||||
|
||||
def to_h
|
||||
{
|
||||
auth_token: auth_token,
|
||||
basic_auth_token: basic_auth_token,
|
||||
base_url: base_url,
|
||||
user_agent: user_agent
|
||||
}.compact
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_url(url)
|
||||
base_url = url || ENV['BTCPAY_BASE_URL'].to_s
|
||||
uri = URI(base_url)
|
||||
return uri.to_s if uri.scheme && uri.host
|
||||
|
||||
raise ArgumentError.new('invalid base_url')
|
||||
end
|
||||
|
||||
def load_auth_token(kwargs)
|
||||
@auth_token = kwargs[:auth_token] || ENV['BTCPAY_AUTH_TOKEN']
|
||||
@basic_auth_token = kwargs[:basic_auth_token] || ENV['BTCPAY_BASIC_AUTH_TOKEN']
|
||||
|
||||
raise ArgumentError.new('auth_token or basic_auth_token required') unless @auth_token || @basic_auth_token
|
||||
end
|
||||
|
||||
def set_authorization
|
||||
@authorization = if @auth_token
|
||||
"#{AUTH_TOKEN_TYPE} #{@auth_token}"
|
||||
elsif @basic_auth_token
|
||||
"#{BASIC_TOKEN_TYPE} #{@basic_auth_token}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/core_ext/hash/indifferent_access'
|
||||
require 'multi_json'
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
##
|
||||
# Status object to capture result from an HTTP request
|
||||
#
|
||||
# Gives callers context of the result and allows them to
|
||||
# implement successful strategies to handle success/failure
|
||||
class Result
|
||||
def self.success(response)
|
||||
new(:success, response)
|
||||
end
|
||||
|
||||
def self.failed(response)
|
||||
new(:failed, response)
|
||||
end
|
||||
|
||||
attr_reader :body, :code, :headers, :raw, :status
|
||||
|
||||
def initialize(status, response)
|
||||
@raw = raw_parse(response.body)
|
||||
|
||||
@body = rubify_body
|
||||
@code = response.code
|
||||
@headers = response.headers # e.g. "Content-Type" will become :content_type.
|
||||
@status = status
|
||||
end
|
||||
|
||||
def success?
|
||||
status == :success
|
||||
end
|
||||
|
||||
def failure?
|
||||
!success?
|
||||
end
|
||||
|
||||
def to_h
|
||||
{
|
||||
status: status,
|
||||
headers: headers,
|
||||
code: code,
|
||||
body: body
|
||||
}
|
||||
end
|
||||
|
||||
alias to_hash to_h
|
||||
|
||||
private
|
||||
|
||||
def method_missing(method, *args, &blk)
|
||||
to_h.send(method, *args, &blk) || super
|
||||
end
|
||||
|
||||
def respond_to_missing?(method, include_private = false)
|
||||
to_h.respond_to?(method) || super
|
||||
end
|
||||
|
||||
# @param body [JSON] Raw JSON body
|
||||
def raw_parse(body)
|
||||
MultiJson.load(body).with_indifferent_access
|
||||
rescue StandardError => e
|
||||
raise ResponseBodyParseError.new(error: 'JSON parse error', message: e.message, body: body)
|
||||
end
|
||||
|
||||
def rubify_body
|
||||
raw.deep_transform_keys { |key| key.to_s.underscore }.with_indifferent_access
|
||||
end
|
||||
|
||||
class ResponseBodyParseError < StandardError; end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,4 +4,11 @@ RSpec.describe BtcPay do
|
|||
it 'has a version number' do
|
||||
expect(BtcPay::VERSION).to eq('0.1.0')
|
||||
end
|
||||
|
||||
describe '.new' do
|
||||
it do
|
||||
expect(described_class.new(auth_token: '123', base_url: 'http://localhost'))
|
||||
.to be_a(BtcPay::Client::Base)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe BtcPay::Client::Base do
|
||||
let(:config) { create(:config) }
|
||||
let(:subject) { described_class.new(config: config) }
|
||||
|
||||
describe '.configuration' do
|
||||
it 'returns host' do
|
||||
expect(subject.host).to eq(host)
|
||||
end
|
||||
|
||||
it 'returns api_key' do
|
||||
expect(subject.api_key).to eq(api_key)
|
||||
end
|
||||
|
||||
it 'returns sandbox' do
|
||||
expect(subject.sandbox).to eq(false)
|
||||
end
|
||||
|
||||
# skipped due to logger being mocked
|
||||
xit 'returns default logger' do
|
||||
expect(subject.logger).to be_a(Logger)
|
||||
end
|
||||
|
||||
it 'raises error when api_key missing' do
|
||||
expect { described_class.new }.to raise_error(KeyError, 'key not found: "CMC_PRO_API_KEY"')
|
||||
end
|
||||
|
||||
context 'host' do
|
||||
it 'defaults to production environment' do
|
||||
subject = described_class.new(api_key: api_key)
|
||||
expect(subject.sandbox).to eq(false)
|
||||
expect(subject.host).to eq('https://pro-api.coinmarketcap.com/v1')
|
||||
end
|
||||
|
||||
it 'defaults to production environment' do
|
||||
subject = described_class.new(api_key: api_key, sandbox: true)
|
||||
expect(subject.sandbox).to eq(true)
|
||||
expect(subject.host).to eq('https://sandbox.coinmarketcap.com/v1')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'services' do
|
||||
it '.cryptocurrency' do
|
||||
expect(subject.cryptocurrency).to be_a(CoinMarketPro::Endpoint::Cryptocurrency)
|
||||
end
|
||||
|
||||
it '.exchange' do
|
||||
expect(subject.exchange).to be_a(CoinMarketPro::Endpoint::Exchange)
|
||||
end
|
||||
|
||||
it '.global_metrics' do
|
||||
expect(subject.global_metrics).to be_a(CoinMarketPro::Endpoint::GlobalMetrics)
|
||||
end
|
||||
|
||||
it '.tools' do
|
||||
expect(subject.tools).to be_a(CoinMarketPro::Endpoint::Tools)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.default_headers' do
|
||||
it do
|
||||
expect(subject.default_headers).to eq(
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
'User-Agent' => "coin_market_pro/#{CoinMarketPro::VERSION}",
|
||||
'Accept-Encoding' => 'deflate, gzip',
|
||||
'X-CMC_PRO_API_KEY' => api_key
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.open_timeout' do
|
||||
it { expect(subject.open_timeout).to eq(10) }
|
||||
end
|
||||
|
||||
describe '.timeout' do
|
||||
it { expect(subject.timeout).to eq(10) }
|
||||
end
|
||||
|
||||
describe '.handle_error' do
|
||||
let(:response) { double('response') }
|
||||
let(:error) { double('error') }
|
||||
let(:code) { 400 }
|
||||
let(:body) do
|
||||
{
|
||||
data: { id: 1 },
|
||||
status: { code: code }
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns failure status response' do
|
||||
allow(response).to receive(:headers)
|
||||
allow(response).to receive(:body).and_return(body.to_json)
|
||||
expect(response).to receive(:code).at_least(:once).and_return(code)
|
||||
|
||||
expect(error).to receive(:message).and_return('message')
|
||||
expect(error).to receive(:response).and_return(response)
|
||||
|
||||
status = subject.handle_error(error)
|
||||
|
||||
expect(status.failure?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.get' do
|
||||
let(:response) { double('response') }
|
||||
let(:body) do
|
||||
{
|
||||
data: { id: 1 },
|
||||
status: { code: 200 }
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(RestClient::Request).to receive(:execute).and_return(response)
|
||||
allow(response).to receive(:body).and_return(body.to_json)
|
||||
allow(response).to receive(:headers)
|
||||
end
|
||||
|
||||
it 'returns successful status response' do
|
||||
expect(response).to receive(:code).at_least(:once).and_return(200)
|
||||
|
||||
status = subject.get(path)
|
||||
expect(status.success?).to eq(true)
|
||||
end
|
||||
|
||||
context 'error' do
|
||||
it 'returns failure status response' do
|
||||
expect(response).to receive(:code).at_least(:once).and_return(400)
|
||||
|
||||
status = subject.get(path)
|
||||
expect(status.failure?).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe BtcPay::Client::Config do
|
||||
let(:config) { build(:config) }
|
||||
|
||||
describe '#initialize' do
|
||||
context '#base_url' do
|
||||
it do
|
||||
subject = described_class.new(**config.to_h)
|
||||
expect(subject.base_url).to eq(config.base_url)
|
||||
end
|
||||
|
||||
it { expect { described_class.new(auth_token: 123) }.to raise_error(ArgumentError, 'invalid base_url') }
|
||||
end
|
||||
|
||||
context '#authorization' do
|
||||
it do
|
||||
expect { described_class.new(base_url: config.base_url) }
|
||||
.to raise_error(ArgumentError, 'auth_token or basic_auth_token required')
|
||||
end
|
||||
|
||||
context 'auth_token' do
|
||||
it do
|
||||
subject = described_class.new(**config.to_h)
|
||||
expect(subject.auth_token).to eq(config.auth_token)
|
||||
expect(subject.authorization).to eq("token #{config.auth_token}")
|
||||
end
|
||||
end
|
||||
|
||||
context 'basic_auth_token' do
|
||||
let(:config) { build(:config, :basic_auth_token) }
|
||||
|
||||
it do
|
||||
subject = described_class.new(**config.to_h)
|
||||
expect(subject.basic_auth_token).to eq(config.basic_auth_token)
|
||||
expect(subject.authorization).to eq("Basic #{config.basic_auth_token}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_h' do
|
||||
subject { described_class.new(**config.to_h) }
|
||||
|
||||
it 'returns hash' do
|
||||
expect(subject.to_h).to eq({
|
||||
auth_token: config.auth_token,
|
||||
basic_auth_token: config.basic_auth_token,
|
||||
base_url: config.base_url,
|
||||
user_agent: config.user_agent
|
||||
}.compact)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,90 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe CoinMarketPro::Client::Result do # rubocop:disable Metrics/BlockLength
|
||||
let(:response) { double('response') }
|
||||
let(:code) { double('code') }
|
||||
let(:body) do
|
||||
{
|
||||
data: {
|
||||
test: 'test'
|
||||
},
|
||||
status: {
|
||||
code: 0
|
||||
}
|
||||
}
|
||||
end
|
||||
let(:headers) do
|
||||
{
|
||||
content_type: 'application/json'
|
||||
}
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
allow(response).to receive(:body).and_return(body.to_json)
|
||||
allow(response).to receive(:code).and_return(code)
|
||||
allow(response).to receive(:headers).and_return(headers)
|
||||
end
|
||||
|
||||
describe '.success' do
|
||||
it 'captures response and sets status to success' do
|
||||
result = described_class.success(response)
|
||||
|
||||
expect(result).to be_a(CoinMarketPro::Client::Result)
|
||||
expect(result.success?).to eq(true)
|
||||
expect(result.failure?).to eq(false)
|
||||
expect(result.body).to eq(body[:data])
|
||||
expect(result.code).to eq(code)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.failed' do
|
||||
it 'captures response and sets status to failed' do
|
||||
result = described_class.failed(response)
|
||||
|
||||
expect(result).to be_a(CoinMarketPro::Client::Result)
|
||||
expect(result.success?).to eq(false)
|
||||
expect(result.failure?).to eq(true)
|
||||
expect(result.body).to eq(body[:data])
|
||||
expect(result.code).to eq(code)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#success?' do
|
||||
let(:result) { described_class.success(response) }
|
||||
|
||||
it 'returns true if success' do
|
||||
expect(result.success?).to eq(true)
|
||||
expect(result.failure?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#failure?' do
|
||||
let(:result) { described_class.failed(response) }
|
||||
|
||||
it 'returns true if failed' do
|
||||
expect(result.failure?).to eq(true)
|
||||
expect(result.success?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_h' do
|
||||
it 'returns a hash of values' do
|
||||
result = described_class.success(response)
|
||||
expect(result.to_h).to eq(code: code, headers: headers, body: body[:data], status: body[:status].merge(result: :success))
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_hash' do
|
||||
it 'returns a hash of values' do
|
||||
result = described_class.success(response)
|
||||
expect(result.to_hash).to eq(code: code, headers: headers, body: body[:data], status: body[:status].merge(result: :success))
|
||||
end
|
||||
|
||||
it 'can be called implicitly' do
|
||||
result = described_class.success(response)
|
||||
expect(result[:code]).to eq code
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :users_payload, class: Hash do
|
||||
email { 'foo@bar.com' }
|
||||
password { 'password' }
|
||||
isAdministrator { false }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :config, class: BtcPay::Client::Config do
|
||||
base_url { 'http://localhost:49392' }
|
||||
|
||||
auth_token # default trait
|
||||
|
||||
initialize_with { new(**attributes) }
|
||||
|
||||
trait :auth_token do
|
||||
auth_token { '9133b8ef3ae9a4b7f2d9a6efef1d5cf738067c68' }
|
||||
basic_auth_token { nil }
|
||||
end
|
||||
|
||||
trait :basic_auth_token do
|
||||
auth_token { nil }
|
||||
basic_auth_token { 'TODO' }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,9 @@ require 'bundler/setup'
|
|||
require 'btcpay'
|
||||
|
||||
require 'webmock/rspec'
|
||||
require 'pry'
|
||||
|
||||
Dir[File.join(__dir__, 'support', '**', '*.rb')].sort.each { |f| require f }
|
||||
|
||||
RSpec.configure do |config|
|
||||
# Enable flags like --only-failures and --next-failure
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'factory_bot'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.include FactoryBot::Syntax::Methods
|
||||
|
||||
config.before(:suite) do
|
||||
FactoryBot.find_definitions
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue