Initial commit

This commit is contained in:
Yaser
2026-08-13 19:50:53 +03:30
commit 38084458fe
879 changed files with 95198 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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