Files
Dena/spec/api/v2/management/deposits_spec.rb
2026-08-13 19:50:53 +03:30

270 lines
8.5 KiB
Ruby

# encoding: UTF-8
# frozen_string_literal: true
describe API::V2::Management::Deposits, type: :request do
before do
defaults_for_management_api_v1_security_configuration!
management_api_v1_security_configuration.merge! \
scopes: {
read_deposits: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
write_deposits: { permitted_signers: %i[alex jeff james], mandatory_signers: %i[alex jeff] }
}
end
describe 'list deposits' do
def request
post_json '/api/v2/management/deposits', multisig_jwt_management_api_v1({ data: data }, *signers)
end
let(:data) { {} }
let(:signers) { %i[alex jeff] }
let(:members) { create_list(:member, 2, :barong) }
before do
Deposit::STATES.tap do |states|
(states.count * 2).times do
create(:deposit_btc, member: members.sample, aasm_state: states.sample)
create(:deposit_usd, member: members.sample, aasm_state: states.sample)
end
end
end
it 'returns deposits' do
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).map { |x| x.fetch('tid') }).to eq Deposit.order(id: :desc).pluck(:tid)
end
it 'paginates' do
ids = Deposit.order(id: :desc).pluck(:tid)
data.merge!(page: 1, limit: 4)
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).map { |x| x.fetch('tid') }).to eq ids[0...4]
data.merge!(page: 3, limit: 4)
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).map { |x| x.fetch('tid') }).to eq ids[8...12]
end
it 'filters by state' do
Deposit::STATES.each do |state|
data.merge!(state: state)
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).count).to eq Deposit.where(aasm_state: state).count
end
end
it 'filters by member' do
member = members.last
data.merge!(uid: member.uid)
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).count).to eq member.deposits.count
end
it 'filters by currency' do
data.merge!(currency: :usd)
request
expect(response).to have_http_status(200)
expect(JSON.parse(response.body).count).to eq Deposit.where(currency_id: :usd).count
end
end
describe 'create deposits' do
let(:member) { create(:member, :barong) }
let(:currency) { Currency.find(:usd) }
let!(:account) { member.get_account(:usd) }
let(:amount) { 750.77 }
let :data do
{ uid: member.uid,
currency: currency.code,
amount: amount.to_s }
end
let(:signers) { %i[alex jeff] }
def request
post_json '/api/v2/management/deposits/new', multisig_jwt_management_api_v1({ data: data }, *signers)
end
it 'creates new fiat deposit with state «submitted»' do
request
expect(response.status).to eq 201
record = Deposit.find_by_tid!(JSON.parse(response.body).fetch('tid'))
expect(record.amount).to eq 750.77
expect(record.aasm_state).to eq 'submitted'
expect(record.account).to eq member.get_account(currency)
expect(response_body['transfer_type']).to eq 'fiat'
end
it 'can create fiat deposit and immediately accept it' do
data.merge!(state: :accepted)
expect { request }.to change { member.get_account(currency).balance }.by amount
end
it 'denies access unless enough signatures are supplied' do
data.merge!(state: :accepted)
signers.clear.concat %i[james jeff]
expect { request }.not_to(change { member.get_account(currency).balance })
expect(response.status).to eq 401
end
it 'validates member' do
data.delete(:uid)
request
expect(response.body).to match(/uid is missing/i)
data[:uid] = '1234567890'
request
expect(response.body).to match(/member must exist/i)
end
it 'validates currency' do
data.delete(:currency)
request
expect(response.body).to match(/currency is missing/i)
data[:currency] = 'btc'
request
expect(response.body).to match(/currency does not have a valid value/i)
end
it 'validates amount' do
data.delete(:amount)
request
expect(response.body).to match(/amount is missing/i)
data[:amount] = '-340.50'
request
expect(response.body).to match(/amount must be greater than 0/i)
end
it 'validates state' do
data[:state] = 'submitted'
request
expect(response.body).to match(/state does not have a valid value/i)
end
context 'when coin instead of fiat is supplied' do
let(:currency) { Currency.find(:btc) }
it 'doesn\'t work' do
request
expect(response.body).to match(/currency does not have a valid value/i)
end
end
context 'extremely precise values' do
it 'keeps precision for amount' do
data.merge!(amount: '0.0000000123456789')
request
expect(response).to have_http_status(201)
expect(Deposit.last.amount.to_s).to eq data[:amount]
end
end
context 'disabled currency' do
before do
currency.update(deposit_enabled: false)
end
it 'returns error for enabled disabled deposit' do
request
expect(response).to have_http_status(422)
expect(response).to include_api_error('management.currency.deposit_disabled')
end
end
end
describe 'get deposit' do
def request
post_json '/api/v2/management/deposits/get', multisig_jwt_management_api_v1({ data: data }, *signers)
end
let(:signers) { %i[alex jeff] }
let(:data) { { tid: record.tid } }
let(:record) { create(:deposit_btc, member: member) }
let(:member) { create(:member, :barong) }
it 'returns deposit by TID' do
request
expect(JSON.parse(response.body).fetch('tid')).to eq record.tid
end
end
describe 'update deposit' do
def request
put_json '/api/v2/management/deposits/state', multisig_jwt_management_api_v1({ data: data }, *signers)
end
let(:currency) { Currency.find(:usd) }
let(:member) { create(:member, :barong) }
let(:amount) { '500.90' }
let(:signers) { %i[alex jeff] }
let(:data) { { tid: record.tid } }
let(:account) { member.get_account(currency) }
let(:record) { Deposits::Fiat.create!(member: member, amount: amount, currency: currency) }
context 'coin deposit' do
let(:record) { create(:deposit_btc) }
it 'works only with fiat deposits' do
data.merge!(state: :accepted)
request
expect(response).to have_http_status(404)
end
end
it 'cancels deposit' do
data.merge!(state: :canceled)
request
expect(response).to have_http_status(200)
expect(Deposit.find_by_tid!(JSON.parse(response.body).fetch('tid')).aasm_state).to eq 'canceled'
account.reload
expect(account.balance).to eq 0
expect(account.locked).to eq 0
end
it 'accepts deposit' do
data.merge!(state: :accepted)
request
expect(response).to have_http_status(200)
expect(Deposit.find_by_tid!(JSON.parse(response.body).fetch('tid')).aasm_state).to eq 'accepted'
account.reload
expect(account.balance).to eq amount.to_d
expect(account.locked).to eq 0
end
it 'doesn\'t cancel deposit twice' do
record.cancel!
expect(record.aasm_state).to eq 'canceled'
data.merge!(state: :canceled)
expect { request }.not_to(change { record.reload.aasm_state })
expect(response).to have_http_status(422)
expect(record.account.balance).to eq 0
expect(record.account.locked).to eq 0
end
it 'doesn\'t accept deposit twice' do
record.accept!
expect(record.aasm_state).to eq 'accepted'
data.merge!(state: :accepted)
expect { request }.not_to(change { record.reload.aasm_state })
expect(response).to have_http_status(422)
expect(record.account.balance).to eq amount.to_d
expect(record.account.locked).to eq 0
end
it 'validates state' do
data.merge!(state: :rejected)
request
expect(response).to have_http_status(422)
expect(response.body).to match(/state does not have a valid value/i)
end
it 'denies access unless enough signatures are supplied' do
data.merge!(state: :accepted)
signers.clear.concat %i[james]
expect { request }.not_to(change { member.get_account(:usd).balance })
expect(response.status).to eq 401
end
end
end