diff --git a/README.md b/README.md index 9a92719..3346a9d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# This gem is under development, don't use in production - # Blnk Easy way to use the blnkfinance.com API in ruby @@ -24,10 +22,10 @@ If bundler is not being used to manage dependencies, install the gem by executin - [x] Find Balance - [x] Search Balances - [x] Create Transaction -- [ ] Multiple sources / destinations Transaction -- [ ] Refund Transaction -- [ ] Commit inflight Transaction -- [ ] Void inflight Transaction +- [x] Multiple sources / destinations Transaction +- [x] Refund Transaction +- [x] Commit inflight Transaction +- [x] Void inflight Transaction - [x] Find Transaction - [x] Search Transactions - [ ] Handler notifications diff --git a/lib/blnk/transaction.rb b/lib/blnk/transaction.rb index d8d3991..9004e56 100644 --- a/lib/blnk/transaction.rb +++ b/lib/blnk/transaction.rb @@ -9,14 +9,40 @@ class CreateContract < Dry::Validation::Contract required(:precision).value(:integer) required(:currency).value(:string) required(:reference).value(:string) - required(:source).value(:string) - required(:destination).value(:string) + optional(:source).value(:string) + optional(:sources).array(:hash) do + required(:identifier).value(:string) + required(:distribution).value(:string) + required(:narration).value(:string) + end + optional(:destination).value(:string) + optional(:destinations).array(:hash) do + required(:identifier).value(:string) + required(:distribution).value(:string) + required(:narration).value(:string) + end required(:description).value(:string) required(:allow_overdraft).value(:bool) optional(:inflight).value(:bool) optional(:rate).value(:integer) optional(:scheduled_for).value(:string) end + + rule do + base.failure('must only contain one of source, sources') if key?(:source) && key?(:sources) + + if key?(:destination) && key?(:destinations) + base.failure('must only contain one of destination, destinations') + end + + if values[:source].to_s.empty? && values[:sources].to_s.empty? + key(:source).failure('missing source') + end + + if values[:destination].to_s.empty? && values[:destinations].to_s.empty? + key(:destination).failure('missing destination') + end + end end self.resource_name = :transactions diff --git a/test/blnk/test_transaction.rb b/test/blnk/test_transaction.rb index 4741ccf..ea31a84 100644 --- a/test/blnk/test_transaction.rb +++ b/test/blnk/test_transaction.rb @@ -70,6 +70,18 @@ def stub_refund_transaction_request_with_error .to_return_json(body: { error: 'failed_refund_transaction' }, status: 400) end +def stub_inflight_status_change_transaction_request_with_error(body: { status: 'commit' }) + stub_request(:put, %r{/transactions/inflight/(.*)}) + .with(body:) + .to_return_json(body: { error: 'failed' }, status: 400) +end + +def stub_inflight_status_change_transaction_request_with_success(body: { status: 'commit' }) + stub_request(:put, %r{/transactions/inflight/(.*)}) + .with(body:) + .to_return_json(body: transaction_response_body, status: 200) +end + def stub_find_transaction_request_with_success stub_request(:get, %r{/transactions/(.*)}) .to_return_json(body: transaction_response_body, status: 200) @@ -96,7 +108,7 @@ def stub_all_transaction_request_with_success .to_return_json(body: [transaction_response_body], status: 200) end -class TestTransaction < Minitest::Test +class TestTransaction < Minitest::Test # rubocop:disable Metrics/ClassLength def test_that_transaction_not_found stub_find_transaction_request_with_error find = Blnk::Transaction.find 'transaction_id' @@ -140,7 +152,7 @@ def test_that_transaction_create_errosr assert create.failure? end - def test_that_transaction_create_success # rubocop:disable Metric/AbcSize, Metrics/MethodLength + def test_that_transaction_create_success # rubocop:disable Metrics/AbcSize, Metrics/MethodLength stub_create_transaction_request_with_success create = Blnk::Transaction.create( @@ -160,7 +172,7 @@ def test_that_transaction_create_success # rubocop:disable Metric/AbcSize, Metri assert create.value!.name.eql?(transaction_response_body[:name]) end - def test_that_transaction_refund_error # rubocop:disable Metric/Metrics/MethodLength + def test_that_transaction_refund_error # rubocop:disable Metrics/MethodLength stub_find_transaction_request_with_success stub_create_transaction_request_with_success stub_refund_transaction_request_with_error @@ -181,7 +193,7 @@ def test_that_transaction_refund_error # rubocop:disable Metric/Metrics/MethodLe assert refund_txn.failure? end - def test_that_transaction_refund_success # rubocop:disable Metric/Metrics/MethodLength + def test_that_transaction_refund_success # rubocop:disable Metrics/MethodLength stub_find_transaction_request_with_success stub_create_transaction_request_with_success stub_refund_transaction_request_with_success @@ -202,4 +214,70 @@ def test_that_transaction_refund_success # rubocop:disable Metric/Metrics/Method assert refund_txn.success? assert txn.value!.transaction_id != refund_txn.value!.transaction_id end + + def test_that_transaction_void_error # rubocop:disable Metrics/MethodLength + stub_find_transaction_request_with_success + stub_create_transaction_request_with_success + stub_inflight_status_change_transaction_request_with_error(body: { status: 'void' }) + + txn = Blnk::Transaction.create( + amount: 75, + reference: 'ref_005', + currency: 'BRLX', + precision: 100, + source: '@world', + destination: 'bln_469f93bc-40e9-4e0e-b6ab-d11c3638c15d', + description: 'For fees', + allow_overdraft: true, + inflight: true + ) + + void_txn = txn.value!.void + + assert void_txn.failure? + end + + def test_that_transaction_void_success # rubocop:disable Metrics/MethodLength + stub_find_transaction_request_with_success + stub_create_transaction_request_with_success + stub_inflight_status_change_transaction_request_with_success(body: { status: 'void' }) + + txn = Blnk::Transaction.create( + amount: 75, + reference: 'ref_005', + currency: 'BRLX', + precision: 100, + source: '@world', + destination: 'bln_469f93bc-40e9-4e0e-b6ab-d11c3638c15d', + description: 'For fees', + allow_overdraft: true, + inflight: true + ) + + void_txn = txn.value!.void + + assert void_txn.success? + end + + def test_that_transaction_commit_error # rubocop:disable Metrics/MethodLength + stub_find_transaction_request_with_success + stub_create_transaction_request_with_success + stub_inflight_status_change_transaction_request_with_error(body: { status: 'commit' }) + + txn = Blnk::Transaction.create( + amount: 75, + reference: 'ref_005', + currency: 'BRLX', + precision: 100, + source: '@world', + destination: 'bln_469f93bc-40e9-4e0e-b6ab-d11c3638c15d', + description: 'For fees', + allow_overdraft: true, + inflight: true + ) + + commit_txn = txn.value!.commit + + assert commit_txn.failure? + end end