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

197 lines
6.8 KiB
Ruby

# frozen_string_literal: true
describe API::V2::Account::InternalTransfers, type: :request do
let(:endpoint) { '/api/v2/account/internal_transfers' }
let(:member) { create(:member, :level_3, email: 'example@gmail.com', uid: 'ID73BF61C8H0', username: 'membertest') }
let(:member_receiver) { create(:member, :level_3, email: 'receiver@gmail.com', uid: 'ID84BF61C8H0', username: 'test1') }
let(:token) { jwt_for(member) }
describe 'GET /api/v2/account/internal_transfers' do
let!(:internal_transfer_btc) { create_list(:internal_transfer_btc, 4, :with_deposit_liability, sender: member) }
let!(:internal_transfer_usd) { create_list(:internal_transfer_usd, 6, :with_deposit_liability, sender: member_receiver) }
let!(:internal_transfer_usd) { create_list(:internal_transfer_usd, 3, :with_deposit_liability, receiver: member) }
context 'unauthorized' do
before do
Ability.stubs(:user_permissions).returns([])
end
it 'renders unauthorized error' do
api_get endpoint, token: token, params: { limit: 100 }
expect(response).to have_http_status 403
expect(response).to include_api_error('user.ability.not_permitted')
end
end
it 'requires authentication' do
get endpoint
expect(response.code).to eq '401'
end
it 'validates currency param' do
api_get endpoint, params: { currency: 'FOO' }, token: token
expect(response.code).to eq '422'
expect(response).to include_api_error('account.currency.doesnt_exist')
end
it 'returns internal transfers for all currencies by default' do
api_get endpoint, params: { limit: 100 }, token: token
result = JSON.parse(response.body)
expect(response).to be_successful
expect(response.headers.fetch('Total')).to eq '7'
expect(result.map { |x| x['currency'] }.uniq.sort).to eq %w[ btc usd ]
end
it 'returns all internal transfers' do
api_get endpoint, token: token
result = JSON.parse(response.body)
expect(result.size).to eq 7
expect(response.headers.fetch('Total')).to eq '7'
end
it 'returns internal transfers of BTC currency' do
api_get endpoint, params: { currency: 'btc' }, token: token
result = JSON.parse(response.body)
expect(result.count).to eq 4
end
it 'returns internal transfers of USD currency' do
api_get endpoint, params: { currency: 'usd' }, token: token
result = JSON.parse(response.body)
expect(result.count).to eq 3
end
end
describe "create internal transfer" do
let(:currency) { Currency.visible.sample; Currency.find(:eth) }
let(:amount) { 0.15 }
let :data do
{ username_or_uid: member_receiver.uid,
currency: currency.code,
amount: amount,
otp: 123456 }
end
let(:account) { member.get_account(currency) }
let(:balance) { 1.2 }
before { account.plus_funds(balance) }
before { Vault::TOTP.stubs(:validate?).returns(true) }
it 'validates missing params' do
data.except!(:otp, :amount, :currency, :username_or_uid)
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internaltransfer.missing_otp')
expect(response).to include_api_error('account.internaltransfer.missing_amount')
expect(response).to include_api_error('account.internaltransfer.missing_currency')
expect(response).to include_api_error('account.internaltransfer.empty_username_or_uid')
end
it 'requires otp' do
data[:otp] = nil
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internaltransfer.empty_otp')
end
it 'validates otp code' do
Vault::TOTP.stubs(:validate?).returns(false)
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.invalid_otp')
end
it 'requires amount' do
data[:amount] = nil
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.non_positive_amount')
end
it 'validates negative amount' do
data[:amount] = -1
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.non_positive_amount')
end
it 'validates enough balance' do
data[:amount] = 100
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.insufficient_balance')
end
it 'validates amount type' do
data[:amount] = 'one'
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.non_decimal_amount')
end
it 'requires currency' do
data[:currency] = nil
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.currency.doesnt_exist')
end
it 'creates new internal_transfer' do
api_post endpoint, params: data, token: token
expect(response).to have_http_status(201)
record = InternalTransfer.last
expect(record.sender_id).to eq member.id
expect(record.receiver_id).to eq member_receiver.id
expect(record.amount).to eq amount
expect(record.currency).to eq currency
end
it 'creates new internal_transfer using username' do
data[:username_or_uid] = member_receiver.username
api_post endpoint, params: data, token: token
expect(response).to have_http_status(201)
record = InternalTransfer.last
expect(record.sender_id).to eq member.id
expect(record.receiver_id).to eq member_receiver.id
expect(record.amount).to eq amount
expect(record.currency).to eq currency
end
it 'should change balance for receiver and sender after transfer' do
api_post endpoint, params: data, token: token
account.reload.balance
expect(response).to have_http_status(201)
record = InternalTransfer.last
expect(account.balance).to eq (balance - amount)
expect(member_receiver.get_account(currency.code).balance).to eq amount
end
it 'not allow create new internal_transfer to yourself' do
data[:username_or_uid] = member.uid
api_post endpoint, params: data, token: token
expect(response).to have_http_status(422)
expect(response).to include_api_error('account.internal_transfer.can_not_tranfer_to_yourself')
end
end
end