trolley 0.2.14 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trolley/Balance.rb +4 -0
- data/lib/trolley/Batch.rb +20 -0
- data/lib/trolley/BatchSummary.rb +21 -0
- data/lib/trolley/Client.rb +117 -0
- data/lib/trolley/Configuration.rb +30 -0
- data/lib/trolley/Exceptions.rb +26 -0
- data/lib/trolley/Gateway.rb +18 -0
- data/lib/trolley/Invoice.rb +22 -0
- data/lib/trolley/InvoicePayment.rb +13 -0
- data/lib/trolley/OfflinePayment.rb +23 -0
- data/lib/trolley/Payment.rb +52 -0
- data/lib/trolley/Recipient.rb +44 -0
- data/lib/trolley/RecipientAccount.rb +30 -0
- data/lib/trolley/gateways/BalanceGateway.rb +15 -0
- data/lib/trolley/gateways/BatchGateway.rb +74 -0
- data/lib/trolley/gateways/InvoiceGateway.rb +57 -0
- data/lib/trolley/gateways/InvoicePaymentGateway.rb +37 -0
- data/lib/trolley/gateways/OfflinePaymentGateway.rb +44 -0
- data/lib/trolley/gateways/PaymentGateway.rb +42 -0
- data/lib/trolley/gateways/RecipientAccountGateway.rb +42 -0
- data/lib/trolley/gateways/RecipientGateway.rb +82 -0
- data/lib/trolley/utils/PaginatedArray.rb +25 -0
- data/lib/trolley/utils/ResponseMapper.rb +80 -0
- data/lib/trolley.rb +33 -5
- data/spec/integration/BatchTest.rb +126 -0
- data/spec/integration/InvoicePaymentTest.rb +92 -0
- data/spec/integration/InvoiceTest.rb +128 -0
- data/spec/integration/RecipientAccountTest.rb +48 -0
- data/spec/integration/RecipientTest.rb +159 -0
- data/spec/integration/helper.rb +19 -0
- data/spec/unit/ConfigurationTest.rb +47 -0
- data/spec/unit/PaginatedArrayTest.rb +23 -0
- data/spec/unit/ResponseMapperTest.rb +26 -0
- data/spec/unit/TrolleyTest.rb +15 -0
- data/trolley.gemspec +22 -12
- metadata +103 -8
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../Client'
|
2
|
+
|
3
|
+
module Trolley
|
4
|
+
class PaymentGateway
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def find(batch_id, payment_id)
|
10
|
+
response = @client.get("/v1/batches/#{batch_id}/payments/#{payment_id}")
|
11
|
+
payment_builder(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create(batch_id, body)
|
15
|
+
response = @client.post("/v1/batches/#{batch_id}/payments", body)
|
16
|
+
payment_builder(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(batch_id, payment_id, body)
|
20
|
+
@client.patch("/v1/batches/#{batch_id}/payments/#{payment_id}", body)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(batch_id, payment_id)
|
25
|
+
@client.delete("/v1/batches/#{batch_id}/payments/#{payment_id}")
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def search(batch_id, page = 1, page_size = 10, term = '')
|
30
|
+
response = @client.get("/v1/batches/#{batch_id}/payments?page=#{page}&pageSize=#{page_size}&search=#{term}")
|
31
|
+
payments_list_builder(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
def payment_builder(response)
|
35
|
+
Utils::ResponseMapper.build(response, Payment)
|
36
|
+
end
|
37
|
+
|
38
|
+
def payments_list_builder(response)
|
39
|
+
Utils::PaginatedArray.from_response(response, Payment)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../Client'
|
2
|
+
|
3
|
+
module Trolley
|
4
|
+
class RecipientAccountGateway
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def find(recipient_id, recipient_account_id)
|
10
|
+
response = @client.get("/v1/recipients/#{recipient_id}/accounts/#{recipient_account_id}")
|
11
|
+
recipient_account_builder(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def all(recipient_id)
|
15
|
+
response = @client.get("/v1/recipients/#{recipient_id}/accounts/")
|
16
|
+
recipient_account_list_builder(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create(recipient_id, body)
|
20
|
+
response = @client.post("/v1/recipients/#{recipient_id}/accounts", body)
|
21
|
+
recipient_account_builder(response)
|
22
|
+
end
|
23
|
+
|
24
|
+
def update(recipient_id, recipient_account_id, body)
|
25
|
+
response = @client.patch("/v1/recipients/#{recipient_id}/accounts/#{recipient_account_id}", body)
|
26
|
+
recipient_account_builder(response)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete(recipient_id, recipient_account_id)
|
30
|
+
@client.delete("/v1/recipients/#{recipient_id}/accounts/#{recipient_account_id}")
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def recipient_account_builder(response)
|
35
|
+
Utils::ResponseMapper.build(response, RecipientAccount)
|
36
|
+
end
|
37
|
+
|
38
|
+
def recipient_account_list_builder(response)
|
39
|
+
Utils::PaginatedArray.from_response(response, RecipientAccount)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative '../Client'
|
2
|
+
|
3
|
+
module Trolley
|
4
|
+
class RecipientGateway
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def find(recipient_id)
|
10
|
+
response = @client.get("/v1/recipients/#{recipient_id}")
|
11
|
+
recipient_builder(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create(body)
|
15
|
+
response = @client.post('/v1/recipients/', body)
|
16
|
+
recipient_builder(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(recipient_id, body)
|
20
|
+
@client.patch("/v1/recipients/#{recipient_id}", body)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param recipient_id [String] or [Array] The id (or array of ids) of the recipient to delete
|
25
|
+
def delete(recipient_id)
|
26
|
+
path = '/v1/recipients/'
|
27
|
+
body = ''
|
28
|
+
|
29
|
+
if recipient_id.is_a?(String)
|
30
|
+
path += recipient_id
|
31
|
+
elsif recipient_id.is_a?(Array)
|
32
|
+
body = { ids: recipient_id }
|
33
|
+
else
|
34
|
+
raise 'Invalid recipient_id type'
|
35
|
+
end
|
36
|
+
|
37
|
+
@client.delete(path, body)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
# @note This method retrieves a list of activity logs for a recipient
|
42
|
+
def find_logs(recipient_id)
|
43
|
+
response = @client.get("/v1/recipients/#{recipient_id}/logs")
|
44
|
+
JSON.parse(response, object_class: OpenStruct)
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_payments(recipient_id, page = 1, page_size = 10)
|
48
|
+
query_string = URI.encode_www_form(
|
49
|
+
page: page.to_s,
|
50
|
+
pageSize: page_size.to_s
|
51
|
+
)
|
52
|
+
response = @client.get("/v1/recipients/#{recipient_id}/payments?#{query_string}")
|
53
|
+
payments_list_builder(response)
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO: if we can afford a breaking change ideally these should be kwargs
|
57
|
+
# rubocop:disable Metrics/ParameterLists
|
58
|
+
def search(page = 1, page_size = 10, prefix_search = '', filters = {})
|
59
|
+
query_string = URI.encode_www_form(
|
60
|
+
page: page.to_s,
|
61
|
+
pageSize: page_size.to_s,
|
62
|
+
search: prefix_search,
|
63
|
+
**filters
|
64
|
+
)
|
65
|
+
response = @client.get("/v1/recipients?#{query_string}")
|
66
|
+
recipient_list_builder(response)
|
67
|
+
end
|
68
|
+
# rubocop:enable Metrics/ParameterLists
|
69
|
+
|
70
|
+
def recipient_builder(response)
|
71
|
+
Utils::ResponseMapper.build(response, Recipient)
|
72
|
+
end
|
73
|
+
|
74
|
+
def recipient_list_builder(response)
|
75
|
+
Utils::PaginatedArray.from_response(response, Recipient)
|
76
|
+
end
|
77
|
+
|
78
|
+
def payments_list_builder(response)
|
79
|
+
Utils::PaginatedArray.from_response(response, Payment)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Trolley
|
2
|
+
module Utils
|
3
|
+
class PaginatedArray < Array
|
4
|
+
attr_accessor :page, :pages, :records
|
5
|
+
|
6
|
+
def self.from_response(response, klass)
|
7
|
+
data = JSON.parse(response)
|
8
|
+
|
9
|
+
enum = Utils::ResponseMapper.new(response, klass).build
|
10
|
+
page = data.dig('meta', 'page')
|
11
|
+
pages = data.dig('meta', 'pages')
|
12
|
+
records = data.dig('meta', 'records')
|
13
|
+
|
14
|
+
new(enum, page, pages, records)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(enum, page, pages, records)
|
18
|
+
super(enum)
|
19
|
+
@page = page
|
20
|
+
@pages = pages
|
21
|
+
@records = records
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trolley
|
4
|
+
module Utils
|
5
|
+
class ResponseMapper
|
6
|
+
KLASS_TO_RESOURCE_KEY_MAPPERS = {
|
7
|
+
'Trolley::Batch' => { resource: 'batch', collection: 'batches' },
|
8
|
+
'Trolley::Invoice' => { resource: 'invoice', collection: 'invoices' },
|
9
|
+
'Trolley::InvoicePayment' => { resource: 'invoicePayment', collection: 'invoicePayments' },
|
10
|
+
'Trolley::OfflinePayment' => { resource: 'offlinePayment', collection: 'offlinePayments' },
|
11
|
+
'Trolley::Payment' => { resource: 'payment', collection: 'payments' },
|
12
|
+
'Trolley::RecipientAccount' => { resource: 'account', collection: 'accounts' },
|
13
|
+
'Trolley::Recipient' => { resource: 'recipient', collection: 'recipients' },
|
14
|
+
'Trolley::BatchSummary' => { resource: 'batchSummary' }
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def self.build(response, klass)
|
18
|
+
new(response, klass).build
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(response, klass)
|
22
|
+
@response = response
|
23
|
+
@klass = klass
|
24
|
+
@data = JSON.parse(response)
|
25
|
+
end
|
26
|
+
|
27
|
+
def build
|
28
|
+
if collection?
|
29
|
+
build_collection
|
30
|
+
else
|
31
|
+
build_resource
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :response, :klass, :data
|
38
|
+
|
39
|
+
def build_collection
|
40
|
+
data[applicable_collection_key].map do |resource_data|
|
41
|
+
build_resource(resource_data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_resource(resource_data = nil)
|
46
|
+
resource_data ||= data[applicable_resource_key]
|
47
|
+
loosely_hydrate_model(resource_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def loosely_hydrate_model(resource_data)
|
51
|
+
instance = klass.new
|
52
|
+
|
53
|
+
resource_data.each do |k, v|
|
54
|
+
instance.send("#{k}=", v)
|
55
|
+
rescue NoMethodError
|
56
|
+
# TODO: The API is showing non-public attributes, once we remove them from the API response we can re-add this warning.
|
57
|
+
# warn "[PaymentRails] Unknown attribute #{k} for class #{klass_instance.class.name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
instance
|
61
|
+
end
|
62
|
+
|
63
|
+
def collection?
|
64
|
+
data[applicable_collection_key].is_a?(Array)
|
65
|
+
end
|
66
|
+
|
67
|
+
def applicable_collection_key
|
68
|
+
applicable_mapper[:collection]
|
69
|
+
end
|
70
|
+
|
71
|
+
def applicable_resource_key
|
72
|
+
applicable_mapper[:resource]
|
73
|
+
end
|
74
|
+
|
75
|
+
def applicable_mapper
|
76
|
+
KLASS_TO_RESOURCE_KEY_MAPPERS.fetch(klass.to_s)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/trolley.rb
CHANGED
@@ -1,5 +1,33 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require 'trolley/Configuration'
|
2
|
+
require 'trolley/Gateway'
|
3
|
+
|
4
|
+
require 'trolley/gateways/BalanceGateway'
|
5
|
+
require 'trolley/gateways/BatchGateway'
|
6
|
+
require 'trolley/gateways/PaymentGateway'
|
7
|
+
require 'trolley/gateways/RecipientGateway'
|
8
|
+
require 'trolley/gateways/RecipientAccountGateway'
|
9
|
+
require 'trolley/gateways/OfflinePaymentGateway'
|
10
|
+
require 'trolley/gateways/InvoiceGateway'
|
11
|
+
require 'trolley/gateways/InvoicePaymentGateway'
|
12
|
+
|
13
|
+
require 'trolley/utils/PaginatedArray'
|
14
|
+
require 'trolley/utils/ResponseMapper'
|
15
|
+
|
16
|
+
require 'trolley/Balance'
|
17
|
+
require 'trolley/Batch'
|
18
|
+
require 'trolley/BatchSummary'
|
19
|
+
require 'trolley/Exceptions'
|
20
|
+
require 'trolley/Payment'
|
21
|
+
require 'trolley/Recipient'
|
22
|
+
require 'trolley/RecipientAccount'
|
23
|
+
require 'trolley/OfflinePayment'
|
24
|
+
require 'trolley/Invoice'
|
25
|
+
require 'trolley/InvoicePayment'
|
26
|
+
|
27
|
+
module Trolley
|
28
|
+
VERSION = '1.0.2'.freeze
|
29
|
+
|
30
|
+
def self.client(key, secret, **optionals)
|
31
|
+
Gateway.new(Configuration.new(key, secret, **optionals))
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
class BatchTest < Test::Unit::TestCase
|
3
|
+
include ApiClientHelper
|
4
|
+
|
5
|
+
def create_recipient
|
6
|
+
uuid = SecureRandom.uuid.to_s
|
7
|
+
recipient = @client.recipient.create(
|
8
|
+
type: 'individual',
|
9
|
+
firstName: 'Tom',
|
10
|
+
lastName: 'Jones',
|
11
|
+
email: "test.batch#{uuid}@example.com",
|
12
|
+
address: {
|
13
|
+
street1: '123 Wolfstrasse',
|
14
|
+
city: 'Berlin',
|
15
|
+
country: 'DE',
|
16
|
+
postalCode: '123123'
|
17
|
+
}
|
18
|
+
)
|
19
|
+
@client.recipient_account.create(recipient.id, type: 'bank-transfer', currency: 'EUR', country: 'DE', iban: 'DE89 3704 0044 0532 0130 00')
|
20
|
+
recipient
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_create
|
24
|
+
batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
|
25
|
+
assert_not_nil(batch)
|
26
|
+
assert_not_nil(batch.id)
|
27
|
+
|
28
|
+
batch = @client.batch.all
|
29
|
+
assert_true(batch.count > 0)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_update
|
33
|
+
batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
|
34
|
+
assert_not_nil(batch)
|
35
|
+
assert_not_nil(batch.id)
|
36
|
+
|
37
|
+
all = @client.batch.all
|
38
|
+
assert_true(all.count > 0)
|
39
|
+
|
40
|
+
response = @client.batch.update(batch.id, description: 'Integration Update')
|
41
|
+
assert_true(response)
|
42
|
+
findBatch = @client.batch.find(batch.id)
|
43
|
+
assert_equal('Integration Update', findBatch.description)
|
44
|
+
assert_equal('open', batch.status)
|
45
|
+
|
46
|
+
response = @client.batch.delete(batch.id)
|
47
|
+
assert_true(response)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_create_with_payments
|
51
|
+
recipientAlpha = create_recipient
|
52
|
+
recipientBeta = create_recipient
|
53
|
+
|
54
|
+
batch = @client.batch.create(
|
55
|
+
sourceCurrency: 'USD', description: 'Integration Test Payments', payments: [
|
56
|
+
{ targetAmount: '10.00', targetCurrency: 'EUR', recipient: { id: recipientAlpha.id } },
|
57
|
+
{ sourceAmount: '10.00', recipient: { id: recipientBeta.id } }
|
58
|
+
]
|
59
|
+
)
|
60
|
+
|
61
|
+
assert_not_nil(batch)
|
62
|
+
assert_not_nil(batch.id)
|
63
|
+
|
64
|
+
findBatch = @client.batch.find(batch.id)
|
65
|
+
assert_not_nil(findBatch)
|
66
|
+
assert_equal(2, findBatch.totalPayments)
|
67
|
+
|
68
|
+
payments = @client.payment.search(batch.id)
|
69
|
+
payments.each { |item| assert_equal('pending', item.status) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_payments
|
73
|
+
batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Payments')
|
74
|
+
assert_not_nil(batch)
|
75
|
+
assert_not_nil(batch.id)
|
76
|
+
|
77
|
+
recipient = create_recipient
|
78
|
+
|
79
|
+
payment = @client.payment.create(batch.id, sourceAmount: '10.00', recipient: { id: recipient.id })
|
80
|
+
|
81
|
+
assert_not_nil(payment)
|
82
|
+
assert_not_nil(payment.id)
|
83
|
+
|
84
|
+
response = @client.payment.update(batch.id, payment.id, sourceAmount: '20.00')
|
85
|
+
assert_true(response)
|
86
|
+
|
87
|
+
response = @client.payment.delete(batch.id, payment.id)
|
88
|
+
assert_true(response)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_processing
|
92
|
+
recipientAlpha = create_recipient
|
93
|
+
recipientBeta = create_recipient
|
94
|
+
|
95
|
+
batch = @client.batch.create(
|
96
|
+
sourceCurrency: 'USD', description: 'Integration Test Payments', payments: [
|
97
|
+
{ targetAmount: '10.00', targetCurrency: 'EUR', recipient: { id: recipientAlpha.id } },
|
98
|
+
{ sourceAmount: '10.00', recipient: { id: recipientBeta.id } }
|
99
|
+
]
|
100
|
+
)
|
101
|
+
assert_not_nil(batch)
|
102
|
+
assert_not_nil(batch.id)
|
103
|
+
|
104
|
+
summary = @client.batch.summary(batch.id)
|
105
|
+
assert_equal(2, summary.detail['bank-transfer']['count'])
|
106
|
+
|
107
|
+
quote = @client.batch.generate_quote(batch.id)
|
108
|
+
assert_not_nil(quote)
|
109
|
+
|
110
|
+
start = @client.batch.start_processing(batch.id)
|
111
|
+
assert_not_nil(start)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_delete_multiple
|
115
|
+
batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
|
116
|
+
assert_not_nil(batch)
|
117
|
+
assert_not_nil(batch.id)
|
118
|
+
|
119
|
+
batch2 = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
|
120
|
+
assert_not_nil(batch2)
|
121
|
+
assert_not_nil(batch2.id)
|
122
|
+
|
123
|
+
response = @client.batch.delete([batch.id, batch2.id])
|
124
|
+
assert_true(response)
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class InvoicePaymentTest < Test::Unit::TestCase
|
4
|
+
include ApiClientHelper
|
5
|
+
|
6
|
+
def create_recipient
|
7
|
+
uuid = SecureRandom.uuid.to_s
|
8
|
+
recipient = @client.recipient.create(
|
9
|
+
type: 'individual',
|
10
|
+
firstName: 'Tom',
|
11
|
+
lastName: 'Jones',
|
12
|
+
email: "test.batch#{uuid}@example.com",
|
13
|
+
address: {
|
14
|
+
street1: '123 Wolfstrasse',
|
15
|
+
city: 'Berlin',
|
16
|
+
country: 'DE',
|
17
|
+
postalCode: '123123'
|
18
|
+
}
|
19
|
+
)
|
20
|
+
@client.recipient_account.create(recipient.id, type: 'bank-transfer', currency: 'EUR', country: 'DE', iban: 'DE89 3704 0044 0532 0130 00')
|
21
|
+
recipient
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_create
|
25
|
+
recipient = create_recipient
|
26
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
27
|
+
assert_not_nil(invoice)
|
28
|
+
assert_not_nil(invoice.id)
|
29
|
+
assert_equal('open', invoice.status)
|
30
|
+
|
31
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
32
|
+
assert_not_nil(invoice_line.lines)
|
33
|
+
assert_not_nil(invoice_line.lines.first['id'])
|
34
|
+
|
35
|
+
@client.invoice_payment.create(ids: [invoiceId: invoice.id])
|
36
|
+
invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
|
37
|
+
assert_true(invoice_payments.count > 0)
|
38
|
+
|
39
|
+
findInvoice = @client.invoice.find(invoiceId: invoice.id)
|
40
|
+
assert_equal('paid', findInvoice.status)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_update
|
44
|
+
recipient = create_recipient
|
45
|
+
|
46
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
47
|
+
assert_not_nil(invoice)
|
48
|
+
assert_not_nil(invoice.id)
|
49
|
+
|
50
|
+
invoices = @client.invoice.search({})
|
51
|
+
assert_true(invoices.count > 0)
|
52
|
+
|
53
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
54
|
+
assert_not_nil(invoice_line.lines)
|
55
|
+
assert_not_nil(invoice_line.lines.first['id'])
|
56
|
+
|
57
|
+
invoice_payment = @client.invoice_payment.create(ids: [invoiceId: invoice.id])
|
58
|
+
invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
|
59
|
+
assert_true(invoice_payments.count > 0)
|
60
|
+
assert_equal('2000.00', invoice_payments.first.amount['value'])
|
61
|
+
|
62
|
+
response = @client.invoice_payment.update(paymentId: invoice_payment.paymentId, invoiceLineId: invoice_payment.invoicePayments.first['invoiceLineId'], amount: { value: '5000', currency: 'USD' })
|
63
|
+
assert_true(response)
|
64
|
+
invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
|
65
|
+
assert_true(invoice_payments.count > 0)
|
66
|
+
assert_equal('5000.00', invoice_payments.first.amount['value'])
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_delete
|
70
|
+
recipient = create_recipient
|
71
|
+
|
72
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
73
|
+
assert_not_nil(invoice)
|
74
|
+
assert_not_nil(invoice.id)
|
75
|
+
|
76
|
+
invoices = @client.invoice.search({})
|
77
|
+
assert_true(invoices.count > 0)
|
78
|
+
|
79
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
80
|
+
assert_not_nil(invoice_line.lines)
|
81
|
+
assert_not_nil(invoice_line.lines.first['id'])
|
82
|
+
|
83
|
+
invoice_payment = @client.invoice_payment.create(ids: [invoiceId: invoice.id])
|
84
|
+
invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
|
85
|
+
assert_true(invoice_payments.count > 0)
|
86
|
+
|
87
|
+
response = @client.invoice_payment.delete(paymentId: invoice_payment.paymentId, invoiceLineIds: [invoice_payment.invoicePayments.first['invoiceLineId']])
|
88
|
+
assert_true(response)
|
89
|
+
invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
|
90
|
+
assert_true(invoice_payments.count == 0)
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
class InvoiceTest < Test::Unit::TestCase
|
5
|
+
include ApiClientHelper
|
6
|
+
|
7
|
+
def create_recipient
|
8
|
+
uuid = SecureRandom.uuid.to_s
|
9
|
+
recipient = @client.recipient.create(
|
10
|
+
type: 'individual',
|
11
|
+
firstName: 'Tom',
|
12
|
+
lastName: 'Jones',
|
13
|
+
email: "test.batch#{uuid}@example.com",
|
14
|
+
address: {
|
15
|
+
street1: '123 Wolfstrasse',
|
16
|
+
city: 'Berlin',
|
17
|
+
country: 'DE',
|
18
|
+
postalCode: '123123'
|
19
|
+
}
|
20
|
+
)
|
21
|
+
@client.recipient_account.create(recipient.id, type: 'bank-transfer', currency: 'EUR', country: 'DE', iban: 'DE89 3704 0044 0532 0130 00')
|
22
|
+
recipient
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_create
|
26
|
+
recipient = create_recipient
|
27
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
28
|
+
assert_not_nil(invoice)
|
29
|
+
assert_not_nil(invoice.id)
|
30
|
+
|
31
|
+
invoice = @client.invoice.search({})
|
32
|
+
assert_true(invoice.count > 0)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_create_line
|
36
|
+
recipient = create_recipient
|
37
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
38
|
+
assert_not_nil(invoice)
|
39
|
+
assert_not_nil(invoice.id)
|
40
|
+
assert_equal([], invoice.lines)
|
41
|
+
|
42
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
43
|
+
assert_not_nil(invoice_line.lines)
|
44
|
+
assert_not_nil(invoice_line.lines.first['id'])
|
45
|
+
|
46
|
+
findInvoice = @client.invoice.find(invoiceId: invoice.id)
|
47
|
+
assert_true(findInvoice.lines.count > 0)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_update
|
51
|
+
recipient = create_recipient
|
52
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
53
|
+
assert_not_nil(invoice)
|
54
|
+
assert_not_nil(invoice.id)
|
55
|
+
|
56
|
+
invoices = @client.invoice.search({})
|
57
|
+
assert_true(invoices.count > 0)
|
58
|
+
|
59
|
+
response = @client.invoice.update(invoiceId: invoice.id, description: 'Integration Test Invoice Update')
|
60
|
+
assert_true(response)
|
61
|
+
findInvoice = @client.invoice.find(invoiceId: invoice.id)
|
62
|
+
assert_equal('Integration Test Invoice Update', findInvoice.description)
|
63
|
+
assert_equal('open', findInvoice.status)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_update_line
|
67
|
+
recipient = create_recipient
|
68
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
69
|
+
assert_not_nil(invoice)
|
70
|
+
assert_not_nil(invoice.id)
|
71
|
+
assert_equal([], invoice.lines)
|
72
|
+
|
73
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
74
|
+
assert_not_nil(invoice_line.lines)
|
75
|
+
assert_not_nil(invoice_line.lines.first['id'])
|
76
|
+
|
77
|
+
response = @client.invoice.update_line(
|
78
|
+
invoiceId: invoice.id,
|
79
|
+
lines: [{
|
80
|
+
invoiceLineId: invoice_line.lines.first['id'],
|
81
|
+
unitAmount: { value: '3000', currency: 'USD' }
|
82
|
+
}]
|
83
|
+
)
|
84
|
+
assert_true(response)
|
85
|
+
|
86
|
+
findInvoice = @client.invoice.find(invoiceId: invoice.id)
|
87
|
+
assert_equal('3000.00', findInvoice.lines.first['unitAmount']['value'])
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_delete
|
91
|
+
recipient = create_recipient
|
92
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
93
|
+
assert_not_nil(invoice)
|
94
|
+
assert_not_nil(invoice.id)
|
95
|
+
|
96
|
+
invoices = @client.invoice.search({})
|
97
|
+
assert_true(invoices.count > 0)
|
98
|
+
|
99
|
+
response = @client.invoice.delete(invoiceIds: invoices.map(&:id))
|
100
|
+
assert_true(response)
|
101
|
+
|
102
|
+
final_invoices = @client.invoice.search({})
|
103
|
+
assert_true(final_invoices.count == 0)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_delete_line
|
107
|
+
recipient = create_recipient
|
108
|
+
invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
|
109
|
+
assert_not_nil(invoice)
|
110
|
+
assert_not_nil(invoice.id)
|
111
|
+
assert_equal([], invoice.lines)
|
112
|
+
|
113
|
+
invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
|
114
|
+
|
115
|
+
response = @client.invoice.delete_line(invoiceId: invoice.id, invoiceLineIds: [invoice_line.lines.first['id']])
|
116
|
+
assert_true(response)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_support_error_arrays
|
120
|
+
@client.invoice.create(recipientId: 'invalid', description: 'Integration Test Invoice Create')
|
121
|
+
rescue ::Trolley::TrolleyError => e
|
122
|
+
assert_equal(1, e.validation_errors.count)
|
123
|
+
assert_equal('recipientId', e.validation_errors.first['field'])
|
124
|
+
assert_equal('Value is invalid', e.validation_errors.first['message'])
|
125
|
+
assert_equal('invalid_field', e.validation_errors.first['code'])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
# rubocop:enable Metrics/ClassLength
|