Initial commit
This commit is contained in:
361
spec/api/v2/management/operations_spec.rb
Normal file
361
spec/api/v2/management/operations_spec.rb
Normal file
@@ -0,0 +1,361 @@
|
||||
# encoding: UTF-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::Management::Operations, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v1_security_configuration!
|
||||
management_api_v1_security_configuration.merge! \
|
||||
scopes: {
|
||||
read_operations: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
write_operations: { permitted_signers: %i[alex jeff james], mandatory_signers: %i[alex jeff] }
|
||||
}
|
||||
end
|
||||
|
||||
describe 'list operations' do
|
||||
def request(op_type)
|
||||
post_json "/api/v2/management/#{op_type}", multisig_jwt_management_api_v1({ data: data }, *signers)
|
||||
end
|
||||
|
||||
def optional_request(op_type, data)
|
||||
post_json "/api/v2/management/#{op_type}", multisig_jwt_management_api_v1({ data: data }, *signers)
|
||||
end
|
||||
Operations::Account::PLATFORM_TYPES.each do |op_type|
|
||||
context op_type do
|
||||
let(:data) { {} }
|
||||
let(:signers) { %i[alex] }
|
||||
let(:operations_number) { 15 }
|
||||
let!(:operations) { create_list(op_type, operations_number) }
|
||||
|
||||
before do
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
context 'filter by currency' do
|
||||
let(:data) { { currency: :btc } }
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
it 'returns operations by currency' do
|
||||
operations = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.where(currency_id: :btc)
|
||||
expect(JSON.parse(response.body).count).to eq operations.count
|
||||
expect(JSON.parse(response.body).map { |h| h['currency'] }).to\
|
||||
eq operations.pluck(:currency_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'pagination' do
|
||||
let(:data) { { page: 2, limit: 8 } }
|
||||
|
||||
it 'returns second page of operations' do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(JSON.parse(response.body).count).to eq 7
|
||||
credits = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.order(id: :desc)
|
||||
.pluck(:credit)
|
||||
|
||||
# Consider that credit sequence is unique.
|
||||
expect(JSON.parse(response.body).map { |h| h['credit'].to_d }).to eq credits[8..15]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Operations::Account::MEMBER_TYPES.each do |op_type|
|
||||
context op_type do
|
||||
let(:data) { {} }
|
||||
let(:signers) { %i[alex] }
|
||||
let(:operations_number) { 15 }
|
||||
let!(:operations) { create_list(op_type, operations_number, :with_member) }
|
||||
|
||||
before do
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
context 'filter by currency' do
|
||||
let(:data) { { currency: :btc } }
|
||||
|
||||
it 'returns operations by currency' do
|
||||
expect(response).to have_http_status(200)
|
||||
operations = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.where(currency_id: :btc)
|
||||
expect(JSON.parse(response.body).count).to eq operations.count
|
||||
expect(JSON.parse(response.body).map { |h| h['currency'] }).to\
|
||||
eq operations.pluck(:currency_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'filter by uid' do
|
||||
let(:member) { create(:member, :barong) }
|
||||
let!(:member_operations) do
|
||||
create_list(op_type, operations_number, member_id: member.id)
|
||||
end
|
||||
let(:data) { { uid: member.uid } }
|
||||
|
||||
it 'returns operations by member UID' do
|
||||
expect(response).to have_http_status(200)
|
||||
request(op_type.to_s.pluralize)
|
||||
operations = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.where(member: member)
|
||||
expect(JSON.parse(response.body).count).to eq operations.count
|
||||
expect(JSON.parse(response.body).map { |h| h['uid'] }).to\
|
||||
eq [member.uid] * operations_number
|
||||
end
|
||||
end
|
||||
|
||||
context 'filter by reference type' do
|
||||
let(:deposit_data) { { reference_type: 'deposit' } }
|
||||
let(:trade_data) { { reference_type: 'trade' } }
|
||||
let(:order_data) { { reference_type: 'order' } }
|
||||
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
def equal_amount!(response, optional_field, op_type)
|
||||
operations = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.where(optional_field)
|
||||
expect(JSON.parse(response.body).count).to eq operations.count
|
||||
end
|
||||
|
||||
it 'returns operations by reference type deposit' do
|
||||
optional_request(op_type.to_s.pluralize, deposit_data)
|
||||
equal_amount!(response, deposit_data, op_type)
|
||||
end
|
||||
|
||||
it 'returns operations by reference type trade' do
|
||||
optional_request(op_type.to_s.pluralize, trade_data)
|
||||
equal_amount!(response, trade_data, op_type)
|
||||
end
|
||||
|
||||
it 'returns operations by reference type order' do
|
||||
optional_request(op_type.to_s.pluralize, order_data)
|
||||
equal_amount!(response, order_data, op_type)
|
||||
end
|
||||
end
|
||||
|
||||
context 'time range' do
|
||||
let(:time_from) { 2.days.ago }
|
||||
let(:time_to) { 1.day.ago }
|
||||
|
||||
let(:data) { { time_from: time_from.to_i, time_to: time_to.to_i } }
|
||||
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
it 'returns operations between 48h and 24h ago' do
|
||||
request(op_type.to_s.pluralize)
|
||||
operations = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.where('created_at >= ?', time_from)
|
||||
.where('created_at < ?', time_to)
|
||||
expect(JSON.parse(response.body).count).to eq operations.count
|
||||
end
|
||||
end
|
||||
|
||||
context 'pagination' do
|
||||
let(:data) { { page: 2, limit: 8 } }
|
||||
|
||||
it { expect(response).to have_http_status(200) }
|
||||
|
||||
it 'returns second page of operations' do
|
||||
expect(JSON.parse(response.body).count).to eq 7
|
||||
credits = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
.order(id: :desc)
|
||||
.pluck(:credit)
|
||||
|
||||
# Consider that credit sequence is unique.
|
||||
expect(JSON.parse(response.body).map{ |h| h['credit'].to_d }).to eq credits[8..15]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'create operation' do
|
||||
def request(op_type)
|
||||
post_json "/api/v2/management/#{op_type}/new", multisig_jwt_management_api_v1({ data: data }, *signers)
|
||||
end
|
||||
|
||||
Operations::Account::PLATFORM_TYPES.each do |op_type|
|
||||
context op_type do
|
||||
let(:currency) { Currency.coins.sample }
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) do
|
||||
{ currency: currency.code,
|
||||
code: Operations::Account.find_by(type: op_type, currency_type: currency.type).code}
|
||||
end
|
||||
|
||||
context 'credit' do
|
||||
let(:amount) { '0.2515' }
|
||||
before do
|
||||
data[:credit] = amount
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it 'returns operation' do
|
||||
expect(response).to have_http_status 200
|
||||
expect(JSON.parse(response.body)['currency']).to eq currency.code.to_s
|
||||
expect(JSON.parse(response.body)['credit'].to_d).to eq amount.to_d
|
||||
expect(JSON.parse(response.body)['code']).to \
|
||||
eq Operations::Account.find_by(type: op_type,
|
||||
kind: :main,
|
||||
currency_type: currency.type).code
|
||||
end
|
||||
|
||||
it 'saves operation' do
|
||||
op_klass = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
expect { request(op_type.to_s.pluralize) }.to \
|
||||
change(op_klass, :count).by(1)
|
||||
end
|
||||
|
||||
context 'wrong account code' do
|
||||
before do
|
||||
data[:code] = (::Operations::Account.pluck(:code) - [data[:code]]).sample
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status 422 }
|
||||
end
|
||||
end
|
||||
|
||||
context 'debit' do
|
||||
let(:amount) { '0.1545' }
|
||||
before do
|
||||
# Create credit operation to avoid negative balance.
|
||||
create(op_type, credit: amount)
|
||||
data[:debit] = amount
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it 'returns operation' do
|
||||
expect(response).to have_http_status 200
|
||||
expect(JSON.parse(response.body)['currency']).to eq currency.code.to_s
|
||||
expect(JSON.parse(response.body)['debit'].to_d).to eq amount.to_d
|
||||
expect(JSON.parse(response.body)['code']).to \
|
||||
eq Operations::Account.find_by(type: op_type,
|
||||
kind: :main,
|
||||
currency_type: currency.type).code
|
||||
end
|
||||
|
||||
it 'saves operation' do
|
||||
op_klass = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
expect { request(op_type.to_s.pluralize) }.to \
|
||||
change(op_klass, :count).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Operations::Account::MEMBER_TYPES.each do |op_type|
|
||||
context op_type do
|
||||
let(:currency) { Currency.coins.sample }
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:member) { create(:member, :barong) }
|
||||
let(:data) do
|
||||
{ currency: currency.code,
|
||||
code: Operations::Account.find_by(type: op_type, currency_type: currency.type, kind: :main).code,
|
||||
uid: member.uid }
|
||||
end
|
||||
|
||||
context 'credit' do
|
||||
let(:amount) { '0.2515' }
|
||||
before do
|
||||
data[:credit] = amount
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it 'returns operation' do
|
||||
expect(response).to have_http_status 200
|
||||
expect(JSON.parse(response.body)['uid']).to eq member.uid
|
||||
expect(JSON.parse(response.body)['currency']).to eq currency.code.to_s
|
||||
expect(JSON.parse(response.body)['credit'].to_d).to eq amount.to_d
|
||||
expect(JSON.parse(response.body)['code']).to \
|
||||
eq Operations::Account.find_by(type: op_type,
|
||||
kind: :main,
|
||||
currency_type: currency.type).code
|
||||
end
|
||||
|
||||
it 'saves operation' do
|
||||
op_klass = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
expect { request(op_type.to_s.pluralize) }.to \
|
||||
change(op_klass, :count).by(1)
|
||||
end
|
||||
|
||||
it 'updates legacy balance' do
|
||||
currency_id = JSON.parse(response.body)['currency']
|
||||
expect(member.get_account(currency_id).balance).to \
|
||||
eq JSON.parse(response.body)['credit'].to_d
|
||||
end
|
||||
|
||||
context 'wrong account code' do
|
||||
before do
|
||||
data[:code] = 999
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it { expect(response).to have_http_status 422 }
|
||||
end
|
||||
end
|
||||
|
||||
context 'debit' do
|
||||
let(:amount) { '0.1545' }
|
||||
before do
|
||||
# Create credit operation to avoid negative balance.
|
||||
create(op_type, :with_member, credit: amount,
|
||||
member: member, currency: currency)
|
||||
data[:debit] = amount
|
||||
request(op_type.to_s.pluralize)
|
||||
end
|
||||
|
||||
it 'returns operation' do
|
||||
expect(response).to have_http_status 200
|
||||
expect(JSON.parse(response.body)['uid']).to eq member.uid
|
||||
expect(JSON.parse(response.body)['currency']).to eq currency.code.to_s
|
||||
expect(JSON.parse(response.body)['debit'].to_d).to eq amount.to_d
|
||||
expect(JSON.parse(response.body)['code']).to \
|
||||
eq Operations::Account.find_by(type: op_type,
|
||||
kind: :main,
|
||||
currency_type: currency.type).code
|
||||
end
|
||||
|
||||
it 'saves operation' do
|
||||
# Create one more credit operation to avoid negative balance.
|
||||
# So we can create one more debit operation.
|
||||
create(op_type, :with_member, credit: amount, member: member, currency: currency)
|
||||
op_klass = "operations/#{op_type}"
|
||||
.camelize
|
||||
.constantize
|
||||
expect { request(op_type.to_s.pluralize) }.to \
|
||||
change(op_klass, :count).by(1)
|
||||
end
|
||||
|
||||
it 'updates legacy balance' do
|
||||
currency_id = JSON.parse(response.body)['currency']
|
||||
expect(member.get_account(currency_id).balance).to \
|
||||
eq 0.to_d
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user