Initial commit
This commit is contained in:
113
spec/api/v2/coin_market_cap/assets_spec.rb
Normal file
113
spec/api/v2/coin_market_cap/assets_spec.rb
Normal file
@@ -0,0 +1,113 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::CoinMarketCap::Assets, type: :request do
|
||||
describe 'GET /api/v2/coinmarketcap/assets' do
|
||||
before(:each) { clear_redis }
|
||||
|
||||
context 'There are currencies' do
|
||||
context 'with unified id' do
|
||||
before do
|
||||
Currency.coins.each do |currency|
|
||||
stub_request(:get, "https://pro-api.coinmarketcap.com/v1/cryptocurrency/map?CMC_PRO_API_KEY=UNIFIED-CRYPTOASSET-INDEX&"\
|
||||
"listing_status=active&"\
|
||||
"symbol=#{currency.id}")
|
||||
.to_return(body:
|
||||
{
|
||||
'status'=>
|
||||
{
|
||||
'error_code'=>0,
|
||||
'error_message'=>nil,
|
||||
'elapsed'=>12,
|
||||
'credit_count'=>1,
|
||||
'notice'=>nil
|
||||
},
|
||||
'data'=>
|
||||
[
|
||||
{
|
||||
'id'=>1
|
||||
}
|
||||
]
|
||||
}.to_json)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return crypto assets' do
|
||||
get '/api/v2/coinmarketcap/assets'
|
||||
expect(response).to be_successful
|
||||
expect(response_body['BTC'].keys).to match_array %w[name unified_cryptoasset_id can_withdraw can_deposit min_withdraw]
|
||||
expect(response_body['BTC']['name']).to eq 'Bitcoin'
|
||||
expect(response_body['BTC']['unified_cryptoasset_id']).to eq 1
|
||||
expect(response_body['BTC']['can_withdraw']).to eq true
|
||||
expect(response_body['BTC']['can_deposit']).to eq true
|
||||
expect(response_body['BTC']['min_withdraw']).to eq '0.0'
|
||||
end
|
||||
end
|
||||
|
||||
context 'without unified id' do
|
||||
before do
|
||||
Currency.coins.each do |currency|
|
||||
stub_request(:get, "https://pro-api.coinmarketcap.com/v1/cryptocurrency/map?CMC_PRO_API_KEY=UNIFIED-CRYPTOASSET-INDEX&"\
|
||||
"listing_status=active&"\
|
||||
"symbol=#{currency.id}")
|
||||
.to_return(status: 400, body:
|
||||
{
|
||||
'status'=>
|
||||
{
|
||||
'timestamp'=>'2020-09-25T08:43:56.778Z',
|
||||
'error_code'=>400,
|
||||
'error_message'=>'Invalid value for \'symbol\': \'TESTTEST\'',
|
||||
'elapsed'=>0,
|
||||
'credit_count'=>0,
|
||||
'notice'=>nil
|
||||
}
|
||||
}.to_json)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return crypto assets' do
|
||||
get '/api/v2/coinmarketcap/assets'
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(response_body['BTC'].keys).to match_array %w[name can_withdraw can_deposit min_withdraw]
|
||||
expect(response_body['BTC']['name']).to eq 'Bitcoin'
|
||||
expect(response_body['BTC']['can_withdraw']).to eq true
|
||||
expect(response_body['BTC']['can_deposit']).to eq true
|
||||
expect(response_body['BTC']['min_withdraw']).to eq '0.0'
|
||||
end
|
||||
|
||||
context 'with 500 error from Faraday' do
|
||||
before do
|
||||
Currency.coins.each do |currency|
|
||||
stub_request(:get, "https://pro-api.coinmarketcap.com/v1/cryptocurrency/map?CMC_PRO_API_KEY=UNIFIED-CRYPTOASSET-INDEX&"\
|
||||
"listing_status=active&"\
|
||||
"symbol=#{currency.id}")
|
||||
.to_raise(Faraday::Error)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return crypto assets' do
|
||||
get '/api/v2/coinmarketcap/assets'
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(response_body['BTC'].keys).to match_array %w[name can_withdraw can_deposit min_withdraw]
|
||||
expect(response_body['BTC']['name']).to eq 'Bitcoin'
|
||||
expect(response_body['BTC']['can_withdraw']).to eq true
|
||||
expect(response_body['BTC']['can_deposit']).to eq true
|
||||
expect(response_body['BTC']['min_withdraw']).to eq '0.0'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'There is no currencies' do
|
||||
before { DatabaseCleaner.clean }
|
||||
|
||||
it 'should return assets' do
|
||||
get '/api/v2/coinmarketcap/assets'
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(response_body).to eq({})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
98
spec/api/v2/coin_market_cap/orderbook_spec.rb
Normal file
98
spec/api/v2/coin_market_cap/orderbook_spec.rb
Normal file
@@ -0,0 +1,98 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::CoinMarketCap::Orderbook, type: :request do
|
||||
describe 'GET /api/v2/coinmarketcap/orderbook/:market_pair' do
|
||||
before do
|
||||
create_list(:order_bid, 5, :btcusd)
|
||||
create_list(:order_bid, 5, :btcusd, price: 2)
|
||||
create_list(:order_ask, 5, :btcusd)
|
||||
create_list(:order_ask, 5, :btcusd, price: 3)
|
||||
end
|
||||
|
||||
let(:asks) { [["1.0", "5.0"], ["3.0", "5.0"]] }
|
||||
let(:bids) { [["2.0", "5.0"], ["1.0", "5.0"]] }
|
||||
|
||||
context 'valid market param' do
|
||||
it 'sorts asks and bids from highest to lowest' do
|
||||
get "/api/v2/coinmarketcap/orderbook/BTC_USD"
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 2
|
||||
expect(result['bids'].size).to eq 2
|
||||
expect(result['asks']).to eq asks
|
||||
expect(result['bids']).to eq bids
|
||||
end
|
||||
|
||||
context 'with depth param' do
|
||||
before do
|
||||
create_list(:order_bid, 5, :btcusd)
|
||||
create_list(:order_bid, 5, :btcusd, price: 4.1)
|
||||
create_list(:order_ask, 5, :btcusd)
|
||||
create_list(:order_ask, 5, :btcusd, price: 12.2)
|
||||
end
|
||||
|
||||
it 'get asks and bids with depth param' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 2 }
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 1
|
||||
expect(result['bids'].size).to eq 1
|
||||
end
|
||||
|
||||
it 'get asks and bids with depth param' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 4 }
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 2
|
||||
expect(result['bids'].size).to eq 2
|
||||
end
|
||||
|
||||
it 'get asks and bids with depth param' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 1 }
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 0
|
||||
expect(result['bids'].size).to eq 0
|
||||
end
|
||||
|
||||
it 'get asks and bids with depth param' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 3 }
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 1
|
||||
expect(result['bids'].size).to eq 1
|
||||
end
|
||||
|
||||
it 'get asks and bids with depth param for all orderbook' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 0 }
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['asks'].size).to eq 3
|
||||
expect(result['bids'].size).to eq 3
|
||||
end
|
||||
|
||||
context 'invalid depth params' do
|
||||
it 'shoud return error' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 'test' }
|
||||
expect(response).to have_http_status 422
|
||||
expect(response).to include_api_error('coinmarketcap.market_depth.non_integer_depth')
|
||||
end
|
||||
|
||||
it 'shoud return error' do
|
||||
get '/api/v2/coinmarketcap/orderbook/BTC_USD', params: { depth: 2000 }
|
||||
expect(response).to have_http_status 422
|
||||
expect(response).to include_api_error('coinmarketcap.market_depth.invalid_depth')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid market param' do
|
||||
it 'validates market param' do
|
||||
api_get "/api/v2/coinmarketcap/orderbook/usdusd"
|
||||
expect(response).to have_http_status 404
|
||||
expect(response).to include_api_error('record.not_found')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
70
spec/api/v2/coin_market_cap/summary_spec.rb
Normal file
70
spec/api/v2/coin_market_cap/summary_spec.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::CoinMarketCap::Summary, type: :request do
|
||||
describe 'GET /api/v2/coinmarketcap/summary' do
|
||||
before(:each) { clear_redis }
|
||||
after(:each) { delete_measurments('trades') }
|
||||
|
||||
context 'There is no trades in influx' do
|
||||
it 'should return summary' do
|
||||
get '/api/v2/coinmarketcap/summary'
|
||||
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.count).to eq Market.all.count
|
||||
expect(result.first['trading_pairs']).to eq 'BTC_USD'
|
||||
expect(result.first['base_currency']).to eq 'BTC'
|
||||
expect(result.first['quote_currency']).to eq 'USD'
|
||||
expect(result.first['last_price']).to eq '0.0'
|
||||
expect(result.first['lowest_ask']).to eq '0.0'
|
||||
expect(result.first['highest_bid']).to eq '0.0'
|
||||
expect(result.first['base_volume']).to eq '0.0'
|
||||
expect(result.first['quote_volume']).to eq '0.0'
|
||||
expect(result.first['price_change_percent_24h']).to eq '0.0'
|
||||
expect(result.first['highest_price_24h']).to eq '0.0'
|
||||
expect(result.first['lowest_price_24h']).to eq '0.0'
|
||||
end
|
||||
end
|
||||
|
||||
context 'There are trades in influx' do
|
||||
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
||||
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d)}
|
||||
|
||||
before do
|
||||
trade1.write_to_influx
|
||||
trade2.write_to_influx
|
||||
end
|
||||
|
||||
it 'should return summary' do
|
||||
get '/api/v2/coinmarketcap/summary'
|
||||
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.count).to eq Market.all.count
|
||||
expect(result.first['trading_pairs']).to eq 'BTC_USD'
|
||||
expect(result.first['base_currency']).to eq 'BTC'
|
||||
expect(result.first['quote_currency']).to eq 'USD'
|
||||
expect(result.first['last_price']).to eq '6.0'
|
||||
expect(result.first['lowest_ask']).to eq '1.0'
|
||||
expect(result.first['highest_bid']).to eq '1.0'
|
||||
expect(result.first['base_volume']).to eq '2.0'
|
||||
expect(result.first['quote_volume']).to eq '10.9'
|
||||
expect(result.first['price_change_percent_24h']).to eq '0.2'
|
||||
expect(result.first['highest_price_24h']).to eq '6.0'
|
||||
expect(result.first['lowest_price_24h']).to eq '5.0'
|
||||
end
|
||||
end
|
||||
|
||||
context 'There is no markets' do
|
||||
before { DatabaseCleaner.clean }
|
||||
|
||||
it 'should return summary' do
|
||||
get '/api/v2/coinmarketcap/summary'
|
||||
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result).to eq []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
127
spec/api/v2/coin_market_cap/ticker_spec.rb
Normal file
127
spec/api/v2/coin_market_cap/ticker_spec.rb
Normal file
@@ -0,0 +1,127 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::CoinMarketCap::Ticker, type: :request do
|
||||
describe 'GET /api/v2/coinmarketcap/ticker' do
|
||||
before do
|
||||
create_list(:order_bid, 5, :btcusd)
|
||||
create_list(:order_ask, 5, :btcusd)
|
||||
end
|
||||
|
||||
before(:each) { clear_redis }
|
||||
|
||||
context 'with unified id' do
|
||||
before(:each) { delete_measurments('trades') }
|
||||
after(:each) { delete_measurments('trades') }
|
||||
|
||||
before do
|
||||
Currency.ordered.coins.each.with_index(1) do |currency, index|
|
||||
stub_request(:get, "https://pro-api.coinmarketcap.com/v1/cryptocurrency/map?CMC_PRO_API_KEY=UNIFIED-CRYPTOASSET-INDEX&"\
|
||||
"listing_status=active&"\
|
||||
"symbol=#{currency.id}")
|
||||
.to_return(body:
|
||||
{
|
||||
'status'=>
|
||||
{
|
||||
'error_code'=>0,
|
||||
'error_message'=>nil,
|
||||
'elapsed'=>12,
|
||||
'credit_count'=>1,
|
||||
'notice'=>nil
|
||||
},
|
||||
'data'=>
|
||||
[
|
||||
{
|
||||
'id'=>index
|
||||
}
|
||||
]
|
||||
}.to_json)
|
||||
end
|
||||
end
|
||||
|
||||
context 'no trades executed yet' do
|
||||
let(:expected_btc_usd_ticker) do
|
||||
{
|
||||
'base_id' => 1, 'last_price' => '0.0',
|
||||
'quote_volume' => '0.0', 'base_volume' => '0.0',
|
||||
'isFrozen' => 0 }
|
||||
end
|
||||
|
||||
let(:expected_btc_eth_ticker) do
|
||||
{
|
||||
'base_id' => 1, 'quote_id' => 2, 'last_price' => '0.0',
|
||||
'quote_volume' => '0.0', 'base_volume' => '0.0',
|
||||
'isFrozen' => 0 }
|
||||
end
|
||||
|
||||
it 'returns ticker of all markets' do
|
||||
get '/api/v2/coinmarketcap/ticker'
|
||||
expect(response).to be_successful
|
||||
|
||||
# crypto/fiat market
|
||||
expect(response_body['BTC_USD'].keys).to match_array %w[base_id last_price base_volume quote_volume isFrozen]
|
||||
expect(response_body['BTC_USD']).to include(expected_btc_usd_ticker)
|
||||
# crypto/crypto market
|
||||
expect(response_body['BTC_ETH'].keys).to match_array %w[base_id quote_id last_price base_volume quote_volume isFrozen]
|
||||
expect(response_body['BTC_ETH']).to include(expected_btc_eth_ticker)
|
||||
end
|
||||
end
|
||||
|
||||
context 'single trade was executed' do
|
||||
let!(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
||||
|
||||
let(:expected_btc_usd_ticker) do
|
||||
{
|
||||
'base_id' => 1,
|
||||
'last_price' => '5.0', 'quote_volume' => '5.5',
|
||||
'base_volume' => '1.1', 'isFrozen' => 0
|
||||
}
|
||||
end
|
||||
|
||||
let(:expected_btc_usd_frozen_ticker) do
|
||||
{
|
||||
'base_id' => 1, 'last_price' => '5.0',
|
||||
'quote_volume' => '5.5', 'base_volume' => '1.1', 'isFrozen' => 1
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
trade.write_to_influx
|
||||
end
|
||||
|
||||
it 'returns market tickers' do
|
||||
get '/api/v2/coinmarketcap/ticker'
|
||||
|
||||
expect(response).to be_successful
|
||||
# crypto/fiat market
|
||||
expect(response_body['BTC_USD'].keys).to match_array %w[base_id last_price base_volume quote_volume isFrozen]
|
||||
expect(response_body['BTC_USD']).to include(expected_btc_usd_ticker)
|
||||
end
|
||||
end
|
||||
|
||||
context 'multiple trades were executed' do
|
||||
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
||||
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d)}
|
||||
|
||||
let(:expected_btc_usd_ticker) do
|
||||
{ 'base_id' => 1, 'last_price' => '6.0',
|
||||
'quote_volume' => '10.9', 'base_volume' => '2.0',
|
||||
'isFrozen' => 0 }
|
||||
end
|
||||
|
||||
before do
|
||||
trade1.write_to_influx
|
||||
trade2.write_to_influx
|
||||
end
|
||||
|
||||
it 'returns market tickers' do
|
||||
get '/api/v2/coinmarketcap/ticker'
|
||||
expect(response).to be_successful
|
||||
|
||||
# crypto/fiat market
|
||||
expect(response_body['BTC_USD'].keys).to match_array %w[base_id last_price base_volume quote_volume isFrozen]
|
||||
expect(response_body['BTC_USD']).to include(expected_btc_usd_ticker)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
51
spec/api/v2/coin_market_cap/trades_spec.rb
Normal file
51
spec/api/v2/coin_market_cap/trades_spec.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::CoinMarketCap::Trades, type: :request do
|
||||
describe 'GET /api/v2/coinmarketcap/trades/:market_pair' do
|
||||
before(:each) { delete_measurments('trades') }
|
||||
after(:each) { delete_measurments('trades') }
|
||||
|
||||
context 'there is no market pair' do
|
||||
it 'should return error' do
|
||||
get '/api/v2/coinmarketcap/trades/TEST_TEST'
|
||||
|
||||
expect(response).to have_http_status 404
|
||||
expect(response).to include_api_error('record.not_found')
|
||||
end
|
||||
end
|
||||
|
||||
context 'there is no trades in influx' do
|
||||
it 'should return recent trades' do
|
||||
get '/api/v2/coinmarketcap/trades/BTC_USD'
|
||||
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
context 'there are trades in influx' do
|
||||
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
||||
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d)}
|
||||
|
||||
before do
|
||||
trade1.write_to_influx
|
||||
trade2.write_to_influx
|
||||
end
|
||||
|
||||
it 'should return recent trades' do
|
||||
get '/api/v2/coinmarketcap/trades/BTC_USD'
|
||||
|
||||
expect(response).to be_successful
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.count).to eq 2
|
||||
expect(result.first.keys).to match_array %w[trade_id price base_volume quote_volume timestamp type]
|
||||
expect(result.first['trade_id']).to eq trade2.id
|
||||
expect(result.first['price']).to eq trade2.price
|
||||
expect(result.first['base_volume']).to eq trade2.amount
|
||||
expect(result.first['quote_volume']).to eq trade2.total
|
||||
expect(result.first['type']).to eq trade2.taker_type
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user