solidus_six_saferpay 0.1.3 → 0.1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +18 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +2 -0
  8. data/.travis.yml +12 -0
  9. data/Gemfile +33 -0
  10. data/LICENSE +26 -0
  11. data/README.md +33 -20
  12. data/Rakefile +4 -54
  13. data/app/assets/config/solidus_six_saferpay_manifest.js +1 -0
  14. data/app/assets/images/solidus_six_saferpay/.keep +0 -0
  15. data/app/assets/javascripts/spree/backend/solidus_six_saferpay.js +2 -0
  16. data/app/assets/javascripts/spree/frontend/solidus_six_saferpay.js +2 -0
  17. data/app/assets/stylesheets/solidus_six_saferpay/loading_animation.scss +0 -27
  18. data/app/assets/stylesheets/solidus_six_saferpay/payments.scss +4 -1
  19. data/app/assets/stylesheets/spree/backend/solidus_six_saferpay.css +4 -0
  20. data/app/assets/stylesheets/spree/frontend/solidus_six_saferpay.css +4 -0
  21. data/app/controllers/spree/solidus_six_saferpay/checkout_controller.rb +56 -10
  22. data/app/views/spree/checkout/payment/_saferpay_payment.html.erb +1 -1
  23. data/app/views/spree/six_saferpay_payments/_six_saferpay_payment.html.erb +2 -2
  24. data/bin/console +17 -0
  25. data/bin/rails +18 -0
  26. data/bin/rake +7 -0
  27. data/bin/setup +8 -0
  28. data/config/initializers/assets.rb +3 -0
  29. data/config/locales/de.yml +1 -1
  30. data/config/locales/en.yml +1 -1
  31. data/config/locales/fr.yml +1 -1
  32. data/config/routes.rb +2 -2
  33. data/lib/generators/solidus_six_saferpay/install/install_generator.rb +15 -3
  34. data/lib/solidus_six_saferpay.rb +6 -3
  35. data/lib/solidus_six_saferpay/configuration.rb +4 -7
  36. data/lib/solidus_six_saferpay/engine.rb +19 -10
  37. data/lib/solidus_six_saferpay/gateway.rb +13 -12
  38. data/lib/solidus_six_saferpay/version.rb +3 -1
  39. data/solidus_six_saferpay.gemspec +42 -0
  40. data/spec/controllers/spree/solidus_six_saferpay/checkout_controller_spec.rb +41 -0
  41. data/spec/controllers/spree/solidus_six_saferpay/payment_page/checkout_controller_spec.rb +205 -0
  42. data/spec/controllers/spree/solidus_six_saferpay/transaction/checkout_controller_spec.rb +228 -0
  43. data/spec/factories/payment_methods.rb +23 -0
  44. data/spec/factories/payments.rb +11 -0
  45. data/spec/factories/spree/six_saferpay_payments.rb +118 -0
  46. data/spec/models/spree/six_saferpay_payment_spec.rb +203 -0
  47. data/spec/rails_helper.rb +73 -0
  48. data/spec/services/spree/solidus_six_saferpay/assert_payment_page_spec.rb +148 -0
  49. data/spec/services/spree/solidus_six_saferpay/authorize_payment_spec.rb +39 -0
  50. data/spec/services/spree/solidus_six_saferpay/authorize_transaction_spec.rb +148 -0
  51. data/spec/services/spree/solidus_six_saferpay/initialize_payment_page_spec.rb +83 -0
  52. data/spec/services/spree/solidus_six_saferpay/initialize_payment_spec.rb +40 -0
  53. data/spec/services/spree/solidus_six_saferpay/initialize_transaction_spec.rb +85 -0
  54. data/spec/services/spree/solidus_six_saferpay/inquire_payment_page_payment_spec.rb +116 -0
  55. data/spec/services/spree/solidus_six_saferpay/inquire_payment_spec.rb +39 -0
  56. data/spec/services/spree/solidus_six_saferpay/inquire_transaction_payment_spec.rb +117 -0
  57. data/spec/services/spree/solidus_six_saferpay/payment_validator_spec.rb +100 -0
  58. data/spec/services/spree/solidus_six_saferpay/process_authorized_payment_spec.rb +39 -0
  59. data/spec/services/spree/solidus_six_saferpay/process_payment_page_payment_spec.rb +225 -0
  60. data/spec/services/spree/solidus_six_saferpay/process_transaction_payment_spec.rb +219 -0
  61. data/spec/solidus_six_saferpay/configuration_spec.rb +15 -0
  62. data/spec/solidus_six_saferpay/error_handler_spec.rb +65 -0
  63. data/spec/solidus_six_saferpay/gateway_response_spec.rb +70 -0
  64. data/spec/solidus_six_saferpay/gateway_spec.rb +378 -0
  65. data/spec/solidus_six_saferpay/payment_page_gateway_spec.rb +390 -0
  66. data/spec/solidus_six_saferpay/transaction_gateway_spec.rb +387 -0
  67. data/spec/spec_helper.rb +21 -0
  68. data/spec/support/route_access.rb +6 -0
  69. data/spec/support/uses_payment_page_gateway.rb +29 -0
  70. data/spec/support/uses_transaction_gateway.rb +28 -0
  71. metadata +241 -101
@@ -0,0 +1,15 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe Configuration do
5
+
6
+ describe '.config' do
7
+ it 'exposes a configurable payment success handler' do
8
+ expect(described_class).to respond_to(:payment_processing_success_handler)
9
+ end
10
+ it 'exposes a configurable list of error handlers' do
11
+ expect(described_class).to respond_to(:error_handlers)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,65 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe ErrorHandler do
5
+
6
+ let(:error) { StandardError.new }
7
+ let(:error_handlers) { [] }
8
+
9
+ before do
10
+ allow(Configuration).to receive(:error_handlers).and_return(error_handlers)
11
+ end
12
+
13
+ describe '.handle' do
14
+
15
+ it 'defaults to level :error' do
16
+ expect(Rails.logger).to receive(:error).with(error)
17
+ described_class.handle(error)
18
+ end
19
+
20
+ it 'allows for configuring the error level' do
21
+ expect(Rails.logger).to receive(:info).with(error)
22
+ described_class.handle(error, level: :info)
23
+ end
24
+
25
+ context 'when any attached handler can not receive our error messages' do
26
+ let(:error_handler1) { double("Handler1", to_s: 'handler1', call: true) }
27
+ let(:error_handler2) { double("Handler2", to_s: 'handler2') }
28
+ let(:error_handler3) { double("Handler3", to_s: 'handler3', call: true) }
29
+
30
+ let(:error_handlers) { [error_handler1, error_handler2, error_handler3] }
31
+
32
+ before do
33
+ allow(error_handler1).to receive(:respond_to?).with(:call).and_return(true)
34
+ allow(error_handler2).to receive(:respond_to?).with(:call).and_return(false)
35
+ allow(error_handler3).to receive(:respond_to?).with(:call).and_return(true)
36
+ end
37
+
38
+ it 'informs about the misconfiguration via Rails logger' do
39
+ expect(Rails.logger).to receive(:warn).with(/ERROR:.*handler2.*/)
40
+
41
+ described_class.handle(error)
42
+ end
43
+
44
+ it 'skips to the next error handler' do
45
+ expect(error_handler1).to receive(:call).with(error, level: :error)
46
+ expect(error_handler2).not_to receive(:call)
47
+ expect(error_handler3).to receive(:call).with(error, level: :error)
48
+
49
+ described_class.handle(error)
50
+ end
51
+ end
52
+
53
+ context 'when an attached handler can receive our error messages' do
54
+ let(:error_handler) { double("CustomErrorHandler", call: true) }
55
+ let(:error_handlers) { [error_handler] }
56
+
57
+ it 'forwards the error to the error handler' do
58
+ expect(error_handler).to receive(:call).with(error, level: :error)
59
+
60
+ described_class.handle(error)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,70 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe GatewayResponse do
5
+ let(:success) { true }
6
+ let(:message) { double('message') }
7
+ let(:api_response) { double('API response') }
8
+ let(:options) { {} }
9
+
10
+ subject { described_class.new(success, message, api_response, options) }
11
+
12
+ describe '#initialize' do
13
+ let(:error_name) { double("error_name") }
14
+ let(:authorization) { double("authorization") }
15
+
16
+ describe 'when given option :error_name' do
17
+ let(:options) { { error_name: error_name } }
18
+
19
+ it 'sets the error name' do
20
+ expect(subject.error_name).to eq(error_name)
21
+ end
22
+ end
23
+
24
+ describe 'when given option :authorization' do
25
+ let(:options) { { authorization: authorization } }
26
+
27
+ it 'sets the authorization' do
28
+ expect(subject.authorization).to eq(authorization)
29
+ end
30
+
31
+ end
32
+ end
33
+
34
+ describe '#success?' do
35
+ context 'when initialized as a success' do
36
+ let(:success) { true }
37
+
38
+ it 'is true' do
39
+ expect(subject).to be_success
40
+ end
41
+ end
42
+
43
+ context 'when initialized as failure' do
44
+ let(:success) { false }
45
+
46
+ it 'is false' do
47
+ expect(subject).not_to be_success
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#to_s' do
53
+ it 'returns the message' do
54
+ expect(subject.to_s).to eq(message)
55
+ end
56
+ end
57
+
58
+ describe '#avs_result' do
59
+ it 'should be an empty hash' do
60
+ expect(subject.avs_result).to eq({})
61
+ end
62
+ end
63
+
64
+ describe '#cvv_result' do
65
+ it 'should be nil' do
66
+ expect(subject.cvv_result).to be_nil
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,378 @@
1
+ require 'rails_helper'
2
+
3
+ module SolidusSixSaferpay
4
+ RSpec.describe Gateway do
5
+ # config options
6
+ let(:customer_id) { 'CUSTOMER_ID' }
7
+ let(:terminal_id) { 'TERMINAL_ID' }
8
+ let(:username) { 'USERNAME' }
9
+ let(:password) { 'PASSWORD' }
10
+ let(:success_url) { '/api/endpoints/success' }
11
+ let(:fail_url) { '/api/endpoints/fail' }
12
+ let(:base_url) { 'https://test.saferpay-api-host.test' }
13
+ let(:css_url) { '/custom/css/url' }
14
+
15
+ let(:gateway) do
16
+ described_class.new(
17
+ success_url: success_url,
18
+ fail_url: fail_url,
19
+ customer_id: customer_id,
20
+ terminal_id: terminal_id,
21
+ username: username,
22
+ password: password,
23
+ base_url: base_url,
24
+ css_url: css_url
25
+ )
26
+ end
27
+
28
+ describe '#new' do
29
+
30
+ it 'configures the API client' do
31
+ gateway = described_class.new(
32
+ success_url: success_url,
33
+ fail_url: fail_url,
34
+ customer_id: customer_id,
35
+ terminal_id: terminal_id,
36
+ username: username,
37
+ password: password,
38
+ base_url: base_url,
39
+ css_url: css_url
40
+ )
41
+
42
+ config = SixSaferpay.config
43
+
44
+ expect(config.customer_id).to eq(customer_id)
45
+ expect(config.terminal_id).to eq(terminal_id)
46
+ expect(config.username).to eq(username)
47
+ expect(config.password).to eq(password)
48
+ expect(config.success_url).to eq(success_url)
49
+ expect(config.fail_url).to eq(fail_url)
50
+ expect(config.base_url).to eq(base_url)
51
+ expect(config.css_url).to eq(css_url)
52
+ end
53
+
54
+ context 'when global options are not passed' do
55
+
56
+ before do
57
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CUSTOMER_ID').and_return(customer_id)
58
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_TERMINAL_ID').and_return(terminal_id)
59
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_USERNAME').and_return(username)
60
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_PASSWORD').and_return(password)
61
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_BASE_URL').and_return(base_url)
62
+ allow(ENV).to receive(:fetch).with('SIX_SAFERPAY_CSS_URL').and_return(css_url)
63
+ end
64
+
65
+ it 'falls back to ENV vars' do
66
+ gateway = described_class.new(
67
+ success_url: success_url,
68
+ fail_url: fail_url
69
+ )
70
+
71
+ config = SixSaferpay.config
72
+
73
+ expect(config.customer_id).to eq(customer_id)
74
+ expect(config.terminal_id).to eq(terminal_id)
75
+ expect(config.username).to eq(username)
76
+ expect(config.password).to eq(password)
77
+ expect(config.success_url).to eq(success_url)
78
+ expect(config.fail_url).to eq(fail_url)
79
+ expect(config.base_url).to eq(base_url)
80
+ expect(config.css_url).to eq(css_url)
81
+ end
82
+ end
83
+ end
84
+
85
+ describe '#initialize_payment' do
86
+
87
+ let(:order) { create(:order) }
88
+ let(:payment_method) { create(:saferpay_payment_method) }
89
+
90
+ it 'fails because it does not know which interface to use' do
91
+ expect { gateway.initialize_payment(order, payment_method) }.to raise_error(NotImplementedError)
92
+ end
93
+ end
94
+
95
+ describe '#authorize' do
96
+
97
+ let(:payment) { create(:six_saferpay_payment) }
98
+ let(:amount) { payment.order.total }
99
+
100
+ it 'fails because authorize must be defined in a subclass' do
101
+ expect { gateway.authorize(amount, payment) }.to raise_error(NotImplementedError)
102
+ end
103
+ end
104
+
105
+ describe '#inquire' do
106
+
107
+ let(:payment) { create(:six_saferpay_payment) }
108
+
109
+ it 'fails because inquire must be defined in a subclass' do
110
+ expect { gateway.inquire(payment) }.to raise_error(NotImplementedError)
111
+ end
112
+ end
113
+
114
+ describe '#purchase' do
115
+ let(:payment) { create(:six_saferpay_payment) }
116
+ let(:amount) { payment.order.total }
117
+
118
+ it 'delegates to capture (with a different signature)' do
119
+ expect(gateway).to receive(:capture).with(amount, payment.transaction_id, {})
120
+
121
+ gateway.purchase(amount, payment)
122
+ end
123
+
124
+ end
125
+
126
+ describe '#capture' do
127
+ let(:amount) { 500 }
128
+ let(:transaction_id) { "TRANSACTION_ID" }
129
+
130
+ let(:api_capture_response) do
131
+ SixSaferpay::SixTransaction::CaptureResponse.new(
132
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
133
+ capture_id: 'CAPTURE_ID',
134
+ status: 'CAPTURED',
135
+ date: '2015-01-30T12:45:22.258+01:00'
136
+ )
137
+ end
138
+
139
+ let(:transaction_reference) { instance_double("SixSaferpay::TransactionReference", transaction_id: transaction_id) }
140
+ let(:saferpay_capture) { instance_double("SixSaferpay::SixTransaction::Capture") }
141
+
142
+ it 'captures the given transaction via the Saferpay API' do
143
+ expect(SixSaferpay::TransactionReference).to receive(:new).with(transaction_id: transaction_id).and_return(transaction_reference)
144
+ expect(SixSaferpay::SixTransaction::Capture).to receive(:new).with(transaction_reference: transaction_reference).and_return(saferpay_capture)
145
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_capture).and_return(api_capture_response)
146
+
147
+ gateway.capture(amount, transaction_id)
148
+ end
149
+
150
+ context 'when the capture is successful' do
151
+ before do
152
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_return(api_capture_response)
153
+ end
154
+
155
+ it 'returns a success gateway response' do
156
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_capture_response, { authorization: api_capture_response.capture_id } )
157
+
158
+ gateway.capture(amount, transaction_id)
159
+ end
160
+ end
161
+
162
+ context 'when the API raises an error' do
163
+ let(:six_saferpay_error) do
164
+ SixSaferpay::Error.new(
165
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
166
+ behavior: 'ABORT',
167
+ error_name: 'INVALID_TRANSACTION',
168
+ error_message: 'error_message'
169
+ )
170
+ end
171
+
172
+ before do
173
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_raise(six_saferpay_error)
174
+ end
175
+
176
+ it 'handles the error gracefully' do
177
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
178
+
179
+ gateway.capture(amount, transaction_id)
180
+ end
181
+ end
182
+ end
183
+
184
+ describe '#void' do
185
+ let(:transaction_id) { 'TRANSACTION_ID' }
186
+
187
+ let(:transaction_reference) { instance_double("SixSaferpay::TransactionReference") }
188
+ let(:saferpay_cancel) { instance_double("SixSaferpay::SixTransaction::Cancel") }
189
+
190
+ let(:api_cancel_response) do
191
+ SixSaferpay::SixTransaction::CancelResponse.new(
192
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
193
+ transaction_id: transaction_id,
194
+ )
195
+ end
196
+
197
+ it 'cancels the payment' do
198
+ expect(SixSaferpay::TransactionReference).to receive(:new).with(transaction_id: transaction_id).and_return(transaction_reference)
199
+ expect(SixSaferpay::SixTransaction::Cancel).to receive(:new).with(transaction_reference: transaction_reference).and_return(saferpay_cancel)
200
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_cancel).and_return(api_cancel_response)
201
+
202
+ gateway.void(transaction_id)
203
+ end
204
+
205
+ context 'when the cancellation is successful' do
206
+ before do
207
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Cancel)).and_return(api_cancel_response)
208
+ end
209
+
210
+ it 'returns a success gateway response' do
211
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_cancel_response, {})
212
+
213
+ gateway.void(transaction_id)
214
+ end
215
+ end
216
+
217
+ context 'when the API raises an error' do
218
+ let(:six_saferpay_error) do
219
+ SixSaferpay::Error.new(
220
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
221
+ behavior: 'ABORT',
222
+ error_name: 'INVALID_TRANSACTION',
223
+ error_message: 'error_message'
224
+ )
225
+ end
226
+
227
+ before do
228
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Cancel)).and_raise(six_saferpay_error)
229
+ end
230
+
231
+ it 'handles the error gracefully' do
232
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
233
+
234
+ gateway.void(transaction_id)
235
+ end
236
+ end
237
+ end
238
+
239
+ describe '#try_void' do
240
+ let(:transaction_id) { "TRANSACTION_ID" }
241
+ let(:payment) { create(:payment, response_code: transaction_id) }
242
+
243
+ context 'if payment is in checkout state and has transaction_id' do
244
+ it 'voids the payment' do
245
+ expect(gateway).to receive(:void).with(transaction_id, originator: gateway)
246
+
247
+ gateway.try_void(payment)
248
+ end
249
+ end
250
+ end
251
+
252
+ describe '#credit' do
253
+ let(:amount) { 400 }
254
+ let(:transaction_id) { 'TRANSACTION_ID' }
255
+ let(:options) { {a: 'a', b: 'b'} }
256
+
257
+ it 'is aliased to #refund' do
258
+ expect(gateway).to receive(:refund).with(amount, transaction_id, options)
259
+
260
+ gateway.credit(amount, transaction_id, options)
261
+ end
262
+ end
263
+
264
+ describe '#refund' do
265
+ let(:transaction_amount) { 400 }
266
+ let(:refund_amount) { 300 }
267
+ let(:transaction_id) { 'TRANSACTION_ID' }
268
+ let(:refund_id) { 'REFUND_ID' }
269
+
270
+ let!(:payment) { create(:payment_using_saferpay, response_code: transaction_id, amount: transaction_amount) }
271
+
272
+ let(:saferpay_refund) do
273
+ amount = SixSaferpay::Amount.new(value: (refund_amount * 100), currency_code: payment.order.currency)
274
+ refund = SixSaferpay::Refund.new(amount: amount, order_id: payment.order.number)
275
+ capture_reference = SixSaferpay::CaptureReference.new(capture_id: transaction_id)
276
+
277
+ SixSaferpay::SixTransaction::Refund.new(
278
+ refund: refund,
279
+ capture_reference: capture_reference
280
+ )
281
+ end
282
+
283
+ let(:api_refund_response) do
284
+ transaction = SixSaferpay::Transaction.new(
285
+ type: 'REFUND',
286
+ status: 'AUTHORIZED',
287
+ id: refund_id,
288
+ date: '2015-01-30T12:45:22.258+01:00',
289
+ amount: SixSaferpay::Amount.new(
290
+ value: refund_amount,
291
+ currency_code: payment.order.currency
292
+ ),
293
+ six_transaction_reference: 'SIX_TRANSACTION_REFERENCE'
294
+ )
295
+
296
+ payment_means = SixSaferpay::ResponsePaymentMeans.new(
297
+ brand: SixSaferpay::Brand.new(name: 'BrandName'),
298
+ display_text: 'xxxxxxxxxxxx1234'
299
+ )
300
+
301
+ SixSaferpay::SixTransaction::RefundResponse.new(
302
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
303
+ transaction: transaction,
304
+ payment_means: payment_means
305
+ )
306
+ end
307
+
308
+ it 'refunds and directly captures the payment' do
309
+ expect(SixSaferpay::SixTransaction::Refund).to receive(:new).with(refund: instance_of(SixSaferpay::Refund), capture_reference: instance_of(SixSaferpay::CaptureReference)).and_return(saferpay_refund)
310
+
311
+ expect(SixSaferpay::Client).to receive(:post).with(saferpay_refund).and_return(api_refund_response)
312
+
313
+ expect(gateway).to receive(:capture).with(refund_amount, refund_id, {})
314
+
315
+ gateway.refund(refund_amount, transaction_id)
316
+ end
317
+
318
+ context 'when the refund is successful' do
319
+ let(:api_capture_response) do
320
+ SixSaferpay::SixTransaction::CaptureResponse.new(
321
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
322
+ capture_id: 'CAPTURE_ID',
323
+ status: 'CAPTURED',
324
+ date: '2015-01-30T12:45:22.258+01:00'
325
+ )
326
+ end
327
+
328
+ before do
329
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_return(api_refund_response)
330
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_return(api_capture_response)
331
+ end
332
+
333
+ it 'returns a success gateway response' do
334
+ expect(GatewayResponse).to receive(:new).with(true, instance_of(String), api_capture_response, { authorization: 'CAPTURE_ID' })
335
+
336
+ gateway.refund(refund_amount, transaction_id)
337
+ end
338
+ end
339
+
340
+ context 'when the API raises an error' do
341
+ let(:six_saferpay_error) do
342
+ SixSaferpay::Error.new(
343
+ response_header: SixSaferpay::ResponseHeader.new(request_id: 'request_id', spec_version: 'test'),
344
+ behavior: 'ABORT',
345
+ error_name: 'INVALID_TRANSACTION',
346
+ error_message: 'error_message'
347
+ )
348
+ end
349
+
350
+ context 'during refunding' do
351
+ before do
352
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_raise(six_saferpay_error)
353
+ end
354
+
355
+ it 'handles the error gracefully' do
356
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
357
+
358
+ gateway.refund(refund_amount, transaction_id)
359
+ end
360
+ end
361
+
362
+ context 'during capture' do
363
+ before do
364
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Refund)).and_return(api_refund_response)
365
+ allow(SixSaferpay::Client).to receive(:post).with(instance_of(SixSaferpay::SixTransaction::Capture)).and_raise(six_saferpay_error)
366
+ end
367
+
368
+ it 'handles the error gracefully' do
369
+ expect(GatewayResponse).to receive(:new).with(false, six_saferpay_error.error_message, nil, error_name: six_saferpay_error.error_name)
370
+
371
+ gateway.refund(refund_amount, transaction_id)
372
+ end
373
+ end
374
+
375
+ end
376
+ end
377
+ end
378
+ end