Skip to content

Commit f80b73d

Browse files
committed
Introduce Client#call_adyen_api_url method
This method allows passing in a full URL for users that do not want to use the whole concept of services and actions.
1 parent b08262d commit f80b73d

File tree

2 files changed

+162
-44
lines changed

2 files changed

+162
-44
lines changed

lib/adyen/client.rb

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,18 @@ def service_url(service, action, version)
144144
def call_adyen_api(service, action, request_data, headers, version, _with_application_info: false)
145145
# get URL for requested endpoint
146146
url = service_url(service, action.is_a?(String) ? action : action.fetch(:url), version)
147-
148-
auth_type = auth_type(service, request_data)
147+
148+
# make sure valid authentication has been provided
149+
validate_auth_type(service, request_data)
150+
151+
method = action.is_a?(String) ? 'post' : action.fetch(:method)
152+
153+
call_adyen_api_url(url, method, request_data, headers, version, _with_application_info: _with_application_info)
154+
end
155+
156+
# send request to adyen API with a given full URL
157+
def call_adyen_api_url(url, method, request_data, headers, version, _with_application_info: false)
158+
auth_type = auth_type(request_data)
149159

150160
# initialize Faraday connection object
151161
conn = Faraday.new(url, @connection_options) do |faraday|
@@ -173,49 +183,27 @@ def call_adyen_api(service, action, request_data, headers, version, _with_applic
173183
# convert to json
174184
request_data = request_data.to_json
175185

176-
if action.is_a?(::Hash)
177-
if action.fetch(:method) == 'get'
178-
begin
179-
response = conn.get
180-
rescue Faraday::ConnectionFailed => e
181-
raise e, "Connection to #{url} failed"
182-
end
183-
end
184-
if action.fetch(:method) == 'delete'
185-
begin
186-
response = conn.delete
187-
rescue Faraday::ConnectionFailed => e
188-
raise e, "Connection to #{url} failed"
189-
end
190-
end
191-
if action.fetch(:method) == 'patch'
192-
begin
193-
response = conn.patch do |req|
194-
req.body = request_data
195-
end
196-
rescue Faraday::ConnectionFailed => e
197-
raise e, "Connection to #{url} failed"
198-
end
199-
end
200-
if action.fetch(:method) == 'post'
201-
# post request to Adyen
202-
begin
203-
response = conn.post do |req|
204-
req.body = request_data
205-
end
206-
rescue Faraday::ConnectionFailed => e
207-
raise e, "Connection to #{url} failed"
186+
begin
187+
response = case method
188+
when 'get'
189+
conn.get
190+
when 'delete'
191+
conn.delete
192+
when 'patch'
193+
conn.patch do |req|
194+
req.body = request_data
208195
end
209-
end
210-
else
211-
begin
212-
response = conn.post do |req|
196+
when 'post'
197+
conn.post do |req|
213198
req.body = request_data
214199
end
215-
rescue Faraday::ConnectionFailed => e
216-
raise e, "Connection to #{url} failed"
200+
else
201+
raise ArgumentError, "Invalid HTTP method: #{method}"
217202
end
203+
rescue Faraday::ConnectionFailed => e
204+
raise e, "Connection to #{url} failed"
218205
end
206+
219207
# check for API errors
220208
case response.status
221209
when 400
@@ -326,7 +314,7 @@ def balance_control
326314
@balance_control ||= Adyen::BalanceControl.new(self)
327315
end
328316

329-
317+
330318
private
331319

332320
def auth_header(auth_type, faraday)
@@ -346,9 +334,7 @@ def auth_header(auth_type, faraday)
346334
end
347335
end
348336

349-
def auth_type(service, request_data)
350-
# make sure valid authentication has been provided
351-
validate_auth_type(service, request_data)
337+
def auth_type(request_data)
352338
# Will prioritize authentication methods in this order:
353339
# api-key, oauth, basic
354340
return "api-key" unless @api_key.nil?

spec/client_spec.rb

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,4 +543,136 @@
543543
expect(request_body_sent).to eq(hash_data.to_json)
544544
end
545545
end
546+
547+
describe '#call_adyen_api_url' do
548+
it 'successfully makes a POST request with full URL' do
549+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
550+
mock_faraday_connection = double(Faraday::Connection)
551+
response_body = { pspReference: '987654321', resultCode: 'Authorised' }.to_json
552+
mock_response = Faraday::Response.new(
553+
status: 200,
554+
body: response_body,
555+
response_headers: { 'content-type' => 'application/json' }
556+
)
557+
558+
expect(Faraday).to receive(:new)
559+
.with('https://checkout-test.adyen.com/v71/payments', anything)
560+
.and_return(mock_faraday_connection)
561+
.and_yield(mock_faraday_connection)
562+
allow(mock_faraday_connection).to receive(:adapter)
563+
allow(mock_faraday_connection).to receive_message_chain(:headers, :[]=)
564+
allow(mock_faraday_connection).to receive(:post).and_return(mock_response)
565+
566+
result = client.call_adyen_api_url(
567+
'https://checkout-test.adyen.com/v71/payments',
568+
'post',
569+
{ amount: { value: 2000 } },
570+
{},
571+
'71'
572+
)
573+
574+
expect(result).to be_a(Adyen::AdyenResult)
575+
expect(result.status).to eq(200)
576+
expect(result.response["pspReference"]).to eq('987654321')
577+
end
578+
579+
it 'successfully makes a GET request' do
580+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
581+
mock_faraday_connection = double(Faraday::Connection)
582+
response_body = { data: [{ id: 'comp-1' }] }.to_json
583+
mock_response = Faraday::Response.new(status: 200, body: response_body, response_headers: {})
584+
585+
expect(Faraday).to receive(:new)
586+
.with('https://management-test.adyen.com/v1/companies/123', anything)
587+
.and_return(mock_faraday_connection)
588+
.and_yield(mock_faraday_connection)
589+
allow(mock_faraday_connection).to receive(:adapter)
590+
allow(mock_faraday_connection).to receive_message_chain(:headers, :[]=)
591+
allow(mock_faraday_connection).to receive(:get).and_return(mock_response)
592+
593+
result = client.call_adyen_api_url(
594+
'https://management-test.adyen.com/v1/companies/123',
595+
'get',
596+
{},
597+
{},
598+
'1'
599+
)
600+
601+
expect(result).to be_a(Adyen::AdyenResult)
602+
expect(result.status).to eq(200)
603+
end
604+
605+
it 'sets correct headers' do
606+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
607+
mock_faraday_connection = double(Faraday::Connection)
608+
mock_response = Faraday::Response.new(status: 200, body: '{}', response_headers: {})
609+
610+
headers_spy = {}
611+
expect(Faraday).to receive(:new)
612+
.with('https://custom.adyen.com/api/endpoint', anything)
613+
.and_return(mock_faraday_connection)
614+
.and_yield(mock_faraday_connection)
615+
allow(mock_faraday_connection).to receive(:adapter)
616+
allow(mock_faraday_connection).to receive_message_chain(:headers, :[]=) do |key, value|
617+
headers_spy[key] = value
618+
end
619+
allow(mock_faraday_connection).to receive(:post).and_return(mock_response)
620+
621+
custom_headers = { 'X-Custom-Header' => 'custom-value' }
622+
client.call_adyen_api_url('https://custom.adyen.com/api/endpoint', 'post', {}, custom_headers, '1')
623+
624+
expect(headers_spy['Content-Type']).to eq('application/json')
625+
expect(headers_spy['x-api-key']).to eq('test_key')
626+
expect(headers_spy['X-Custom-Header']).to eq('custom-value')
627+
end
628+
629+
it 'handles connection failures' do
630+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
631+
mock_faraday_connection = double(Faraday::Connection)
632+
633+
expect(Faraday).to receive(:new)
634+
.with('https://checkout-test.adyen.com/v71/payments', anything)
635+
.and_return(mock_faraday_connection)
636+
.and_yield(mock_faraday_connection)
637+
allow(mock_faraday_connection).to receive(:adapter)
638+
allow(mock_faraday_connection).to receive_message_chain(:headers, :[]=)
639+
allow(mock_faraday_connection).to receive(:post).and_raise(Faraday::ConnectionFailed.new('Connection failed'))
640+
641+
expect {
642+
client.call_adyen_api_url('https://checkout-test.adyen.com/v71/payments', 'post', {}, {}, '71')
643+
}.to raise_error(Faraday::ConnectionFailed, /Connection to .* failed/)
644+
end
645+
646+
it 'supports different HTTP methods' do
647+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
648+
mock_faraday_connection = double(Faraday::Connection)
649+
mock_response = Faraday::Response.new(status: 200, body: '{"status":"updated"}', response_headers: {})
650+
651+
expect(Faraday).to receive(:new)
652+
.with('https://management-test.adyen.com/v1/companies/123', anything)
653+
.and_return(mock_faraday_connection)
654+
.and_yield(mock_faraday_connection)
655+
allow(mock_faraday_connection).to receive(:adapter)
656+
allow(mock_faraday_connection).to receive_message_chain(:headers, :[]=)
657+
allow(mock_faraday_connection).to receive(:patch).and_return(mock_response)
658+
659+
result = client.call_adyen_api_url(
660+
'https://management-test.adyen.com/v1/companies/123',
661+
'patch',
662+
{ status: 'active' },
663+
{},
664+
'1'
665+
)
666+
667+
expect(result).to be_a(Adyen::AdyenResult)
668+
expect(result.status).to eq(200)
669+
end
670+
671+
it 'raises for invalid HTTP method' do
672+
client = Adyen::Client.new(api_key: 'test_key', env: :test)
673+
expect {
674+
client.call_adyen_api_url('https://management-test.adyen.com/v1/companies/123', 'invalid', {}, {}, '1')
675+
}.to raise_error(ArgumentError, "Invalid HTTP method: invalid")
676+
end
677+
end
546678
end

0 commit comments

Comments
 (0)