ideal 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,766 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../helper', __FILE__)
4
+
5
+ module IdealTestCases
6
+ # This method is called at the end of the file when all fixture data has been loaded.
7
+ def self.setup_ideal_gateway!
8
+ Ideal::Gateway.class_eval do
9
+ self.acquirer = :ing
10
+
11
+ self.merchant_id = '123456789'
12
+
13
+ self.passphrase = 'passphrase'
14
+ self.private_key = PRIVATE_KEY
15
+ self.private_certificate = PRIVATE_CERTIFICATE
16
+ self.ideal_certificate = IDEAL_CERTIFICATE
17
+ end
18
+ end
19
+
20
+ VALID_PURCHASE_OPTIONS = {
21
+ :issuer_id => '0001',
22
+ :expiration_period => 'PT10M',
23
+ :return_url => 'http://return_to.example.com',
24
+ :order_id => '12345678901',
25
+ :description => 'A classic Dutch windmill',
26
+ :entrance_code => '1234'
27
+ }
28
+
29
+ class ClassMethodsTest < Test::Unit::TestCase
30
+ def test_merchant_id
31
+ assert_equal Ideal::Gateway.merchant_id, '123456789'
32
+ end
33
+
34
+ def test_verify_live_url_for_ing
35
+ Ideal::Gateway.acquirer = :ing
36
+ assert_equal 'https://ideal.secure-ing.com/ideal/iDeal', Ideal::Gateway.live_url
37
+ end
38
+
39
+ def test_verify_live_url_for_rabobank
40
+ Ideal::Gateway.acquirer = :rabobank
41
+ assert_equal 'https://ideal.rabobank.nl/ideal/iDeal', Ideal::Gateway.live_url
42
+ end
43
+
44
+ def test_verify_live_urls_for_abnamro
45
+ Ideal::Gateway.acquirer = :abnamro
46
+ assert_equal 'https://idealm.abnamro.nl/nl/issuerInformation/getIssuerInformation.xml', Ideal::Gateway.live_directory_url
47
+ assert_equal 'https://idealm.abnamro.nl/nl/acquirerTrxRegistration/getAcquirerTrxRegistration.xml', Ideal::Gateway.live_transaction_url
48
+ assert_equal 'https://idealm.abnamro.nl/nl/acquirerStatusInquiry/getAcquirerStatusInquiry.xml', Ideal::Gateway.live_status_url
49
+ end
50
+
51
+ def test_does_not_allow_configuration_of_unknown_acquirers
52
+ assert_raise(ArgumentError) do
53
+ Ideal::Gateway.acquirer = :unknown
54
+ end
55
+ end
56
+
57
+ def test_acquirers
58
+ assert_equal 'https://ideal.rabobank.nl/ideal/iDeal', Ideal::Gateway.acquirers['rabobank']['live_url']
59
+ assert_equal 'https://ideal.secure-ing.com/ideal/iDeal', Ideal::Gateway.acquirers['ing']['live_url']
60
+ assert_equal 'https://idealm.abnamro.nl/nl/acquirerTrxRegistration/getAcquirerTrxRegistration.xml', Ideal::Gateway.acquirers['abnamro']['live_transaction_url']
61
+ end
62
+
63
+ def test_private_certificate_returns_a_loaded_Certificate_instance
64
+ assert_equal Ideal::Gateway.private_certificate.to_text,
65
+ OpenSSL::X509::Certificate.new(PRIVATE_CERTIFICATE).to_text
66
+ end
67
+
68
+ def test_private_key_returns_a_loaded_PKey_RSA_instance
69
+ assert_equal Ideal::Gateway.private_key.to_text,
70
+ OpenSSL::PKey::RSA.new(PRIVATE_KEY, Ideal::Gateway.passphrase).to_text
71
+ end
72
+
73
+ def test_ideal_certificate_returns_a_loaded_Certificate_instance
74
+ assert_equal Ideal::Gateway.ideal_certificate.to_text,
75
+ OpenSSL::X509::Certificate.new(IDEAL_CERTIFICATE).to_text
76
+ end
77
+ end
78
+
79
+ class GeneralTest < Test::Unit::TestCase
80
+ def setup
81
+ @gateway = Ideal::Gateway.new
82
+ end
83
+
84
+ def test_optional_initialization_options
85
+ assert_equal 0, Ideal::Gateway.new.sub_id
86
+ assert_equal 1, Ideal::Gateway.new(:sub_id => 1).sub_id
87
+ end
88
+
89
+ def test_returns_the_test_url_when_in_the_test_env
90
+ Ideal::Gateway.acquirer = :ing
91
+ Ideal::Gateway.environment = :test
92
+ assert_equal Ideal::Gateway.test_url, @gateway.send(:request_url, :directory)
93
+ end
94
+
95
+ def test_returns_the_live_url_when_not_in_the_test_env
96
+ Ideal::Gateway.acquirer = :ing
97
+ Ideal::Gateway.environment = :live
98
+ assert_equal Ideal::Gateway.live_url, @gateway.send(:request_url, :directory)
99
+ end
100
+
101
+ def test_returns_the_special_urls_for_abnamro_when_in_the_test_env
102
+ Ideal::Gateway.acquirer = :abnamro
103
+ Ideal::Gateway.environment = :test
104
+ assert_equal Ideal::Gateway.test_directory_url, @gateway.send(:request_url, :directory)
105
+ assert_equal Ideal::Gateway.test_transaction_url, @gateway.send(:request_url, :transaction)
106
+ assert_equal Ideal::Gateway.test_status_url, @gateway.send(:request_url, :status)
107
+ end
108
+
109
+ def test_returns_created_at_timestamp
110
+ timestamp = '2001-12-17T09:30:47.000Z'
111
+ Time.any_instance.stubs(:gmtime).returns(DateTime.parse(timestamp))
112
+
113
+ assert_equal timestamp, @gateway.send(:created_at_timestamp)
114
+ end
115
+
116
+ def test_ruby_to_java_keys_conversion
117
+ keys = [
118
+ [:acquirer_transaction_request, 'AcquirerTrxReq'],
119
+ [:acquirer_status_request, 'AcquirerStatusReq'],
120
+ [:directory_request, 'DirectoryReq'],
121
+ [:created_at, 'createDateTimeStamp'],
122
+ [:issuer, 'Issuer'],
123
+ [:merchant, 'Merchant'],
124
+ [:transaction, 'Transaction'],
125
+ [:issuer_id, 'issuerID'],
126
+ [:merchant_id, 'merchantID'],
127
+ [:sub_id, 'subID'],
128
+ [:token_code, 'tokenCode'],
129
+ [:merchant_return_url, 'merchantReturnURL'],
130
+ [:purchase_id, 'purchaseID'],
131
+ [:expiration_period, 'expirationPeriod'],
132
+ [:entrance_code, 'entranceCode']
133
+ ]
134
+
135
+ keys.each do |key, expected_key|
136
+ assert_equal expected_key, @gateway.send(:javaize_key, key)
137
+ end
138
+ end
139
+
140
+ def test_does_not_convert_unknown_key_to_java_key
141
+ assert_equal 'not_a_registered_key', @gateway.send(:javaize_key, :not_a_registered_key)
142
+ end
143
+
144
+ def test_token_generation
145
+ expected_token = Digest::SHA1.hexdigest(OpenSSL::X509::Certificate.new(PRIVATE_CERTIFICATE).to_der).upcase
146
+ assert_equal expected_token, @gateway.send(:token)
147
+ end
148
+
149
+ def test_token_code_generation
150
+ Ideal::Gateway.acquirer = :ing
151
+ message = "Top\tsecret\tman.\nI could tell you, but then I'd have to kill you…"
152
+ stripped_message = message.gsub(/\s/m, '')
153
+
154
+ sha1 = OpenSSL::Digest::SHA1.new
155
+ OpenSSL::Digest::SHA1.stubs(:new).returns(sha1)
156
+
157
+ signature = Ideal::Gateway.private_key.sign(sha1, stripped_message)
158
+ encoded_signature = Base64.encode64(signature).strip.gsub(/\n/, '')
159
+
160
+ assert_equal encoded_signature, @gateway.send(:token_code, message)
161
+ end
162
+
163
+ def test_token_code_generation_on_abn_amro
164
+ Ideal::Gateway.acquirer = :abnamro
165
+ message = "Top\tsecret\tman.\nI could tell you, but\r then I'd have to kill you…"
166
+ stripped_message = message.gsub(/(\f|\n|\r|\t|\v)/m, '')
167
+
168
+ sha1 = OpenSSL::Digest::SHA1.new
169
+ OpenSSL::Digest::SHA1.stubs(:new).returns(sha1)
170
+
171
+ signature = Ideal::Gateway.private_key.sign(sha1, stripped_message)
172
+ encoded_signature = Base64.encode64(signature).strip.gsub(/\n/, '')
173
+
174
+ assert_equal encoded_signature, @gateway.send(:token_code, message)
175
+ end
176
+
177
+ def test_posts_data_with_ssl_to_request_url_and_return_the_correct_response_for_test
178
+ Ideal::Gateway.environment = :test
179
+ Ideal::Response.expects(:new).with('response', :test => true)
180
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'data').returns('response')
181
+ @gateway.send(:post_data, @gateway.request_url(:directory), 'data', Ideal::Response)
182
+ end
183
+
184
+ def test_posts_data_with_ssl_to_request_url_and_return_the_correct_response_for_live
185
+ Ideal::Gateway.environment = :live
186
+ Ideal::Response.expects(:new).with('response', :test => false)
187
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'data').returns('response')
188
+ @gateway.send(:post_data, @gateway.request_url(:directory), 'data', Ideal::Response)
189
+ end
190
+ end
191
+
192
+ class XMLBuildingTest < Test::Unit::TestCase
193
+ def setup
194
+ @gateway = Ideal::Gateway.new
195
+ end
196
+
197
+ def test_contains_correct_info_in_root_node
198
+ expected_xml = Builder::XmlMarkup.new
199
+ expected_xml.instruct!
200
+ expected_xml.tag!('AcquirerTrxReq', 'xmlns' => Ideal::Gateway::XML_NAMESPACE, 'version' => Ideal::Gateway::API_VERSION) {}
201
+
202
+ assert_equal expected_xml.target!, @gateway.send(:xml_for, :acquirer_transaction_request, [])
203
+ end
204
+
205
+ def test_creates_correct_xml_with_java_keys_from_array_with_ruby_keys
206
+ expected_xml = Builder::XmlMarkup.new
207
+ expected_xml.instruct!
208
+ expected_xml.tag!('AcquirerTrxReq', 'xmlns' => Ideal::Gateway::XML_NAMESPACE, 'version' => Ideal::Gateway::API_VERSION) do
209
+ expected_xml.tag!('a_parent') do
210
+ expected_xml.tag!('createDateTimeStamp', '2009-01-26')
211
+ end
212
+ end
213
+
214
+ assert_equal expected_xml.target!, @gateway.send(:xml_for, :acquirer_transaction_request, [[:a_parent, [[:created_at, '2009-01-26']]]])
215
+ end
216
+ end
217
+
218
+ class RequestBodyBuildingTest < Test::Unit::TestCase
219
+ def setup
220
+ @gateway = Ideal::Gateway.new
221
+
222
+ @gateway.stubs(:created_at_timestamp).returns('created_at_timestamp')
223
+ @gateway.stubs(:token).returns('the_token')
224
+ @gateway.stubs(:token_code)
225
+
226
+ @transaction_id = '0001023456789112'
227
+ end
228
+
229
+ def test_build_transaction_request_body_raises_ArgumentError_with_missing_required_options
230
+ options = VALID_PURCHASE_OPTIONS.dup
231
+ options.keys.each do |key|
232
+ options.delete(key)
233
+
234
+ assert_raise(ArgumentError) do
235
+ @gateway.send(:build_transaction_request_body, 100, options)
236
+ end
237
+ end
238
+ end
239
+
240
+ def test_valid_with_valid_options
241
+ assert_not_nil @gateway.send(:build_transaction_request_body, 4321, VALID_PURCHASE_OPTIONS)
242
+ end
243
+
244
+ def test_checks_that_fields_are_not_too_long
245
+ assert_raise ArgumentError do
246
+ @gateway.send(:build_transaction_request_body, 1234567890123, VALID_PURCHASE_OPTIONS) # 13 chars
247
+ end
248
+
249
+ [
250
+ [:order_id, '12345678901234567'], # 17 chars,
251
+ [:description, '123456789012345678901234567890123'], # 33 chars
252
+ [:entrance_code, '12345678901234567890123456789012345678901'] # 41
253
+ ].each do |key, value|
254
+ options = VALID_PURCHASE_OPTIONS.dup
255
+ options[key] = value
256
+
257
+ assert_raise ArgumentError do
258
+ @gateway.send(:build_transaction_request_body, 4321, options)
259
+ end
260
+ end
261
+ end
262
+
263
+ def test_checks_that_fields_do_not_contain_diacritical_characters
264
+ assert_raise ArgumentError do
265
+ @gateway.send(:build_transaction_request_body, 'graphème', VALID_PURCHASE_OPTIONS)
266
+ end
267
+
268
+ [:order_id, :description, :entrance_code].each do |key, value|
269
+ options = VALID_PURCHASE_OPTIONS.dup
270
+ options[key] = 'graphème'
271
+
272
+ assert_raise ArgumentError do
273
+ @gateway.send(:build_transaction_request_body, 4321, options)
274
+ end
275
+ end
276
+ end
277
+
278
+ def test_builds_a_transaction_request_body
279
+ money = 4321
280
+
281
+ message = 'created_at_timestamp' +
282
+ VALID_PURCHASE_OPTIONS[:issuer_id] +
283
+ Ideal::Gateway.merchant_id +
284
+ @gateway.sub_id.to_s +
285
+ VALID_PURCHASE_OPTIONS[:return_url] +
286
+ VALID_PURCHASE_OPTIONS[:order_id] +
287
+ money.to_s +
288
+ Ideal::Gateway::CURRENCY +
289
+ Ideal::Gateway::LANGUAGE +
290
+ VALID_PURCHASE_OPTIONS[:description] +
291
+ VALID_PURCHASE_OPTIONS[:entrance_code]
292
+
293
+ @gateway.expects(:token_code).with(message).returns('the_token_code')
294
+
295
+ @gateway.expects(:xml_for).with(:acquirer_transaction_request, [
296
+ [:created_at, 'created_at_timestamp'],
297
+ [:issuer, [[:issuer_id, VALID_PURCHASE_OPTIONS[:issuer_id]]]],
298
+
299
+ [:merchant, [
300
+ [:merchant_id, Ideal::Gateway.merchant_id],
301
+ [:sub_id, @gateway.sub_id],
302
+ [:authentication, Ideal::Gateway::AUTHENTICATION_TYPE],
303
+ [:token, 'the_token'],
304
+ [:token_code, 'the_token_code'],
305
+ [:merchant_return_url, VALID_PURCHASE_OPTIONS[:return_url]]
306
+ ]],
307
+
308
+ [:transaction, [
309
+ [:purchase_id, VALID_PURCHASE_OPTIONS[:order_id]],
310
+ [:amount, money],
311
+ [:currency, Ideal::Gateway::CURRENCY],
312
+ [:expiration_period, VALID_PURCHASE_OPTIONS[:expiration_period]],
313
+ [:language, Ideal::Gateway::LANGUAGE],
314
+ [:description, VALID_PURCHASE_OPTIONS[:description]],
315
+ [:entrance_code, VALID_PURCHASE_OPTIONS[:entrance_code]]
316
+ ]]
317
+ ])
318
+
319
+ @gateway.send(:build_transaction_request_body, money, VALID_PURCHASE_OPTIONS)
320
+ end
321
+
322
+ def test_builds_a_directory_request_body
323
+ message = 'created_at_timestamp' + Ideal::Gateway.merchant_id + @gateway.sub_id.to_s
324
+ @gateway.expects(:token_code).with(message).returns('the_token_code')
325
+
326
+ @gateway.expects(:xml_for).with(:directory_request, [
327
+ [:created_at, 'created_at_timestamp'],
328
+ [:merchant, [
329
+ [:merchant_id, Ideal::Gateway.merchant_id],
330
+ [:sub_id, @gateway.sub_id],
331
+ [:authentication, Ideal::Gateway::AUTHENTICATION_TYPE],
332
+ [:token, 'the_token'],
333
+ [:token_code, 'the_token_code']
334
+ ]]
335
+ ])
336
+
337
+ @gateway.send(:build_directory_request_body)
338
+ end
339
+
340
+ def test_builds_a_status_request_body_raises_ArgumentError_with_missing_required_options
341
+ assert_raise(ArgumentError) do
342
+ @gateway.send(:build_status_request_body, {})
343
+ end
344
+ end
345
+
346
+ def test_builds_a_status_request_body
347
+ options = { :transaction_id => @transaction_id }
348
+
349
+ message = 'created_at_timestamp' + Ideal::Gateway.merchant_id + @gateway.sub_id.to_s + options[:transaction_id]
350
+ @gateway.expects(:token_code).with(message).returns('the_token_code')
351
+
352
+ @gateway.expects(:xml_for).with(:acquirer_status_request, [
353
+ [:created_at, 'created_at_timestamp'],
354
+ [:merchant, [
355
+ [:merchant_id, Ideal::Gateway.merchant_id],
356
+ [:sub_id, @gateway.sub_id],
357
+ [:authentication, Ideal::Gateway::AUTHENTICATION_TYPE],
358
+ [:token, 'the_token'],
359
+ [:token_code, 'the_token_code']
360
+ ]],
361
+
362
+ [:transaction, [
363
+ [:transaction_id, options[:transaction_id]]
364
+ ]],
365
+ ])
366
+
367
+ @gateway.send(:build_status_request_body, options)
368
+ end
369
+ end
370
+
371
+ class GeneralResponseTest < Test::Unit::TestCase
372
+ def test_resturns_if_it_is_a_test_request
373
+ assert Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS, :test => true).test?
374
+
375
+ assert !Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS, :test => false).test?
376
+ assert !Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS).test?
377
+ end
378
+ end
379
+
380
+ class SuccessfulResponseTest < Test::Unit::TestCase
381
+ def setup
382
+ @response = Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS)
383
+ end
384
+
385
+ def test_initializes_with_only_response_body
386
+ assert_equal REXML::Document.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS).root.to_s,
387
+ @response.instance_variable_get(:@response).to_s
388
+ end
389
+
390
+ def test_successful
391
+ assert @response.success?
392
+ end
393
+
394
+ def test_returns_no_error_messages
395
+ assert_nil @response.error_message
396
+ end
397
+
398
+ def test_returns_no_error_code
399
+ assert_nil @response.error_code
400
+ end
401
+ end
402
+
403
+ class ErrorResponseTest < Test::Unit::TestCase
404
+ def setup
405
+ @response = Ideal::Response.new(ERROR_RESPONSE)
406
+ end
407
+
408
+ def test_unsuccessful
409
+ assert !@response.success?
410
+ end
411
+
412
+ def test_returns_error_messages
413
+ assert_equal 'Failure in system', @response.error_message
414
+ assert_equal 'System generating error: issuer', @response.error_details
415
+ assert_equal 'Betalen met iDEAL is nu niet mogelijk.', @response.consumer_error_message
416
+ end
417
+
418
+ def test_returns_error_code
419
+ assert_equal 'SO1000', @response.error_code
420
+ end
421
+
422
+ def test_returns_error_type
423
+ [
424
+ ['IX1000', :xml],
425
+ ['SO1000', :system],
426
+ ['SE2000', :security],
427
+ ['BR1200', :value],
428
+ ['AP1000', :application]
429
+ ].each do |code, type|
430
+ @response.stubs(:error_code).returns(code)
431
+ assert_equal type, @response.error_type
432
+ end
433
+ end
434
+ end
435
+
436
+ class DirectoryTest < Test::Unit::TestCase
437
+ def setup
438
+ @gateway = Ideal::Gateway.new
439
+ end
440
+
441
+ def test_returns_a_list_with_only_one_issuer
442
+ @gateway.stubs(:build_directory_request_body).returns('the request body')
443
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'the request body').returns(DIRECTORY_RESPONSE_WITH_ONE_ISSUER)
444
+
445
+ expected_issuers = [{ :id => '1006', :name => 'ABN AMRO Bank' }]
446
+
447
+ directory_response = @gateway.issuers
448
+ assert_instance_of Ideal::DirectoryResponse, directory_response
449
+ assert_equal expected_issuers, directory_response.list
450
+ end
451
+
452
+ def test_returns_list_of_issuers_from_response
453
+ @gateway.stubs(:build_directory_request_body).returns('the request body')
454
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'the request body').returns(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS)
455
+
456
+ expected_issuers = [
457
+ { :id => '1006', :name => 'ABN AMRO Bank' },
458
+ { :id => '1003', :name => 'Postbank' },
459
+ { :id => '1005', :name => 'Rabobank' },
460
+ { :id => '1017', :name => 'Asr bank' },
461
+ { :id => '1023', :name => 'Van Lanschot' }
462
+ ]
463
+
464
+ directory_response = @gateway.issuers
465
+ assert_instance_of Ideal::DirectoryResponse, directory_response
466
+ assert_equal expected_issuers, directory_response.list
467
+ end
468
+ end
469
+
470
+ class SetupPurchaseTest < Test::Unit::TestCase
471
+ def setup
472
+ @gateway = Ideal::Gateway.new
473
+
474
+ @gateway.stubs(:build_transaction_request_body).with(4321, VALID_PURCHASE_OPTIONS).returns('the request body')
475
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:transaction), 'the request body').returns(ACQUIRER_TRANSACTION_RESPONSE)
476
+
477
+ @setup_purchase_response = @gateway.setup_purchase(4321, VALID_PURCHASE_OPTIONS)
478
+ end
479
+
480
+ def test_setup_purchase_returns_IdealTransactionResponse
481
+ assert_instance_of Ideal::TransactionResponse, @setup_purchase_response
482
+ end
483
+
484
+ def test_setup_purchase_returns_response_with_service_url
485
+ assert_equal 'https://ideal.example.com/long_service_url?X009=BETAAL&X010=20', @setup_purchase_response.service_url
486
+ end
487
+
488
+ def test_setup_purchase_returns_response_with_transaction_and_order_ids
489
+ assert_equal '0001023456789112', @setup_purchase_response.transaction_id
490
+ assert_equal 'iDEAL-aankoop 21', @setup_purchase_response.order_id
491
+ end
492
+ end
493
+
494
+ class CapturePurchaseTest < Test::Unit::TestCase
495
+ def setup
496
+ @gateway = Ideal::Gateway.new
497
+
498
+ @gateway.stubs(:build_status_request_body).
499
+ with(:transaction_id => '0001023456789112').returns('the request body')
500
+ end
501
+
502
+ def test_setup_purchase_returns_IdealStatusResponse
503
+ expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
504
+ assert_instance_of Ideal::StatusResponse, @gateway.capture('0001023456789112')
505
+ end
506
+
507
+ # Because we don't have a real private key and certificate we stub
508
+ # verified? to return true. However, this is properly tested in the remote
509
+ # tests.
510
+ def test_capture_of_successful_payment
511
+ Ideal::StatusResponse.any_instance.stubs(:verified?).returns(true)
512
+
513
+ expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
514
+ capture_response = @gateway.capture('0001023456789112')
515
+
516
+ assert capture_response.success?
517
+ end
518
+
519
+ def test_capture_of_failed_payment
520
+ expects_request_and_returns ACQUIRER_FAILED_STATUS_RESPONSE
521
+ capture_response = @gateway.capture('0001023456789112')
522
+
523
+ assert !capture_response.success?
524
+ end
525
+
526
+ def test_capture_of_successful_payment_but_message_does_not_match_signature
527
+ expects_request_and_returns ACQUIRER_SUCCEEDED_BUT_WRONG_SIGNATURE_STATUS_RESPONSE
528
+ capture_response = @gateway.capture('0001023456789112')
529
+
530
+ assert !capture_response.success?
531
+ end
532
+
533
+ def test_capture_of_consumer_fields
534
+ expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
535
+ capture_response = @gateway.capture('0001023456789112')
536
+
537
+ assert_equal '0949298989', capture_response.consumer_account_number
538
+ assert_equal 'Onderheuvel', capture_response.consumer_name
539
+ assert_equal 'DEN HAAG', capture_response.consumer_city
540
+ end
541
+
542
+ def test_returns_status
543
+ response = Ideal::StatusResponse.new(ACQUIRER_SUCCEEDED_STATUS_RESPONSE)
544
+ [
545
+ ['Success', :success],
546
+ ['Cancelled', :cancelled],
547
+ ['Expired', :expired],
548
+ ['Open', :open],
549
+ ['Failure', :failure]
550
+ ].each do |raw_status, expected_status|
551
+ response.stubs(:text).with("//status").returns(raw_status)
552
+ assert_equal expected_status, response.status
553
+ end
554
+ end
555
+
556
+ private
557
+
558
+ def expects_request_and_returns(str)
559
+ @gateway.expects(:ssl_post).with(@gateway.request_url(:status), 'the request body').returns(str)
560
+ end
561
+ end
562
+
563
+ ###
564
+ #
565
+ # Fixture data
566
+ #
567
+
568
+ PRIVATE_CERTIFICATE = %{-----BEGIN CERTIFICATE-----
569
+ MIIC+zCCAmSgAwIBAgIJALVAygHjnd8ZMA0GCSqGSIb3DQEBBQUAMF0xCzAJBgNV
570
+ BAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHEwlBbXN0ZXJk
571
+ YW0xIjAgBgNVBAoTGWlERUFMIEFjdGl2ZU1lcmNoYW50IFRlc3QwHhcNMDkwMTMw
572
+ MTMxNzQ5WhcNMjQxMjExMDM1MjI5WjBdMQswCQYDVQQGEwJOTDEWMBQGA1UECBMN
573
+ Tm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJQW1zdGVyZGFtMSIwIAYDVQQKExlpREVB
574
+ TCBBY3RpdmVNZXJjaGFudCBUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
575
+ gQDmBpi+RVvZBA01kdP5lV5bDzu6Jp1zy78qhxxwlG8WMdUh0Qtg0kkYmeThFPoh
576
+ 2c3BYuFQ+AA6f1R0Spb+hTNrBxkZaRnHCfMMD9LXquFjJ/lvSGnwkjvBmGzyTPZ1
577
+ LIunpejm8hH0MJPqpp5AIeXjp1mv7BXA9y0FqObrrLAPaQIDAQABo4HCMIG/MB0G
578
+ A1UdDgQWBBTLqGWJt5+Ri6vrOpqGZhINbRtXczCBjwYDVR0jBIGHMIGEgBTLqGWJ
579
+ t5+Ri6vrOpqGZhINbRtXc6FhpF8wXTELMAkGA1UEBhMCTkwxFjAUBgNVBAgTDU5v
580
+ b3JkLUhvbGxhbmQxEjAQBgNVBAcTCUFtc3RlcmRhbTEiMCAGA1UEChMZaURFQUwg
581
+ QWN0aXZlTWVyY2hhbnQgVGVzdIIJALVAygHjnd8ZMAwGA1UdEwQFMAMBAf8wDQYJ
582
+ KoZIhvcNAQEFBQADgYEAGtgkmME9tgaxJIU3T7v1/xbKr6A/iwmt3sCmfJEl4Pty
583
+ aUGaHFy1KB7xmkna8gomxMWL2zZkdv4t1iGeuVCl9n77SL3MzapotdeNNqahblcN
584
+ RBshYCpWpsQQPF45/R5Xp7rXWWsjxgip7qTBNpgTx+Z/VKQpuQsFjYCYq4UCf2Y=
585
+ -----END CERTIFICATE-----}
586
+
587
+ PRIVATE_KEY = %{-----BEGIN RSA PRIVATE KEY-----
588
+ MIICXAIBAAKBgQDmBpi+RVvZBA01kdP5lV5bDzu6Jp1zy78qhxxwlG8WMdUh0Qtg
589
+ 0kkYmeThFPoh2c3BYuFQ+AA6f1R0Spb+hTNrBxkZaRnHCfMMD9LXquFjJ/lvSGnw
590
+ kjvBmGzyTPZ1LIunpejm8hH0MJPqpp5AIeXjp1mv7BXA9y0FqObrrLAPaQIDAQAB
591
+ AoGAfkccz0ewVoDc5424+wk/FWpVdaoBQjKWLbiiqkMygNK2mKv0PSD0M+c4OUCU
592
+ 2MSDKikoXJTpOzPvny/bmLpzMMGn9YJiWEQ5WdaTdppffdylfGPBZXZkt5M9nxJA
593
+ NL3fPT79R79mkCF8cgNUbLtNL4woSoFKwRHDU2CGvtTbxqkCQQD+TY1sGJv1VTQi
594
+ MYYx3FlEOqw3jp/2q7QluTDDGmvmVOSFnAPfmX0rKEtnBmG4ID7IaG+IQFthDudL
595
+ 3trqGQdTAkEA54+RxyCZiXDfkh23cD0QaApZaBuk6cKkx6qeFxeg1T+/idGgtWJI
596
+ Qg3i9fHzOIFUXwk51R3xh5IimvMJZ9Ii0wJAb7yrsx9tB3MUoSGZkTb8kholqZOl
597
+ fcEcOqcQYemuF1qdvoc6vHi4osnlt7L6JOkmLPCWcQu2GwNtZczZ65pruQJBAJ3p
598
+ vbtzUuF01TKbC18Cda7N5/zkZUl5ENCNXTRYS7lBuQhuqc8okChjufSJpJlTMUuC
599
+ Sis5OV5/3ROYTEC+ADsCQCwq6VQ1kXRrM+3tkMwi2rZi73dsFVuFx8crlBOmvhkD
600
+ U7Ar9bW13qhBeH9px8RCRDMWTGQcxY/C/TEQc/qvhkI=
601
+ -----END RSA PRIVATE KEY-----}
602
+
603
+ IDEAL_CERTIFICATE = %{-----BEGIN CERTIFICATE-----
604
+ MIIEAzCCA3CgAwIBAgIQMIEnzk1UPrPDLOY9dc2cUjANBgkqhkiG9w0BAQUFADBf
605
+ MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXUlNBIERhdGEgU2VjdXJpdHksIEluYy4x
606
+ LjAsBgNVBAsTJVNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
607
+ HhcNMDQwNjA4MDAwMDAwWhcNMDUwNjA4MjM1OTU5WjCBvDELMAkGA1UEBhMCTkwx
608
+ FjAUBgNVBAgTDU5vb3JkLUhvbGxhbmQxEjAQBgNVBAcUCUFtc3RlcmRhbTEbMBkG
609
+ A1UEChQSQUJOIEFNUk8gQmFuayBOLlYuMRYwFAYDVQQLFA1JTi9OUy9FLUlORlJB
610
+ MTMwMQYDVQQLFCpUZXJtcyBvZiB1c2UgYXQgd3d3LnZlcmlzaWduLmNvbS9ycGEg
611
+ KGMpMDAxFzAVBgNVBAMUDnd3dy5hYm5hbXJvLm5sMIGfMA0GCSqGSIb3DQEBAQUA
612
+ A4GNADCBiQKBgQD1hPZlFD01ZdQu0GVLkUQ7tOwtVw/jmZ1Axu8v+3bxrjKX9Qi1
613
+ 0w6EIadCXScDMmhCstExVptaTEQ5hG3DedV2IpMcwe93B1lfyviNYlmc/XIol1B7
614
+ PM70mI9XUTYAoJpquEv8AaupRO+hgxQlz3FACHINJxEIMgdxa1iyoJfCKwIDAQAB
615
+ o4IBZDCCAWAwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwPAYDVR0fBDUwMzAxoC+g
616
+ LYYraHR0cDovL2NybC52ZXJpc2lnbi5jb20vUlNBU2VjdXJlU2VydmVyLmNybDBE
617
+ BgNVHSAEPTA7MDkGC2CGSAGG+EUBBxcDMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
618
+ d3d3LnZlcmlzaWduLmNvbS9ycGEwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
619
+ BwMCMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AudmVy
620
+ aXNpZ24uY29tMG0GCCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAh
621
+ MB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dv
622
+ LnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMA0GCSqGSIb3DQEBBQUAA34AY7BYsNvj
623
+ i5fjnEHPlGOd2yxseCHU54HDPPCZOoP9a9kVWGX8tuj2b1oeiOsIbI1viIo+O4eQ
624
+ ilZjTJIlLOkXk6uE8vQGjZy0BUnjNPkXOQGkTyj4jDxZ2z+z9Vy8BwfothdcYbZK
625
+ 48ZOp3u74DdEfQejNxBeqLODzrxQTV4=
626
+ -----END CERTIFICATE-----}
627
+
628
+ DIRECTORY_RESPONSE_WITH_ONE_ISSUER = %{<?xml version="1.0" encoding="UTF-8"?>
629
+ <DirectoryRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
630
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
631
+ <Acquirer>
632
+ <acquirerID>0245</acquirerID>
633
+ </Acquirer>
634
+ <Directory>
635
+ <directoryDateTimeStamp>2004-11-10T10:15:12.145Z</directoryDateTimeStamp>
636
+ <Issuer>
637
+ <issuerID>1006</issuerID>
638
+ <issuerName>ABN AMRO Bank</issuerName>
639
+ <issuerList>Short</issuerList>
640
+ </Issuer>
641
+ </Directory>
642
+ </DirectoryRes>}
643
+
644
+ DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS = %{<?xml version="1.0" encoding="UTF-8"?>
645
+ <DirectoryRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
646
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
647
+ <Acquirer>
648
+ <acquirerID>0245</acquirerID>
649
+ </Acquirer>
650
+ <Directory>
651
+ <directoryDateTimeStamp>2004-11-10T10:15:12.145Z</directoryDateTimeStamp>
652
+ <Issuer>
653
+ <issuerID>1006</issuerID>
654
+ <issuerName>ABN AMRO Bank</issuerName>
655
+ <issuerList>Short</issuerList>
656
+ </Issuer>
657
+ <Issuer>
658
+ <issuerID>1003</issuerID>
659
+ <issuerName>Postbank</issuerName>
660
+ <issuerList>Short</issuerList>
661
+ </Issuer>
662
+ <Issuer>
663
+ <issuerID>1005</issuerID>
664
+ <issuerName>Rabobank</issuerName>
665
+ <issuerList>Short</issuerList>
666
+ </Issuer>
667
+ <Issuer>
668
+ <issuerID>1017</issuerID>
669
+ <issuerName>Asr bank</issuerName>
670
+ <issuerList>Long</issuerList>
671
+ </Issuer>
672
+ <Issuer>
673
+ <issuerID>1023</issuerID>
674
+ <issuerName>Van Lanschot</issuerName>
675
+ <issuerList>Long</issuerList>
676
+ </Issuer>
677
+ </Directory>
678
+ </DirectoryRes>}
679
+
680
+ ACQUIRER_TRANSACTION_RESPONSE = %{<?xml version="1.0" encoding="UTF-8"?>
681
+ <AcquirerTrxRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
682
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
683
+ <Acquirer>
684
+ <acquirerID>1545</acquirerID>
685
+ </Acquirer>
686
+ <Issuer>
687
+ <issuerAuthenticationURL>https://ideal.example.com/long_service_url?X009=BETAAL&amp;X010=20</issuerAuthenticationURL>
688
+ </Issuer>
689
+ <Transaction>
690
+ <transactionID>0001023456789112</transactionID>
691
+ <purchaseID>iDEAL-aankoop 21</purchaseID>
692
+ </Transaction>
693
+ </AcquirerTrxRes>}
694
+
695
+ ACQUIRER_SUCCEEDED_STATUS_RESPONSE = %{<?xml version="1.0" encoding="UTF-8"?>
696
+ <AcquirerStatusRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
697
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
698
+ <Acquirer>
699
+ <acquirerID>1234</acquirerID>
700
+ </Acquirer>
701
+ <Transaction>
702
+ <transactionID>0001023456789112</transactionID>
703
+ <status>Success</status>
704
+ <consumerName>Onderheuvel</consumerName>
705
+ <consumerAccountNumber>0949298989</consumerAccountNumber>
706
+ <consumerCity>DEN HAAG</consumerCity>
707
+ </Transaction>
708
+ <Signature>
709
+ <signatureValue>db82/jpJRvKQKoiDvu33X0yoDAQpayJOaW2Y8zbR1qk1i3epvTXi+6g+QVBY93YzGv4w+Va+vL3uNmzyRjYsm2309d1CWFVsn5Mk24NLSvhYfwVHEpznyMqizALEVUNSoiSHRkZUDfXowBAyLT/tQVGbuUuBj+TKblY826nRa7U=</signatureValue>
710
+ <fingerprint>1E15A00E3D7DF085768749D4ABBA3284794D8AE9</fingerprint>
711
+ </Signature>
712
+ </AcquirerStatusRes>}
713
+
714
+ ACQUIRER_SUCCEEDED_BUT_WRONG_SIGNATURE_STATUS_RESPONSE = %{<?xml version="1.0" encoding="UTF-8"?>
715
+ <AcquirerStatusRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
716
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
717
+ <Acquirer>
718
+ <acquirerID>1234</acquirerID>
719
+ </Acquirer>
720
+ <Transaction>
721
+ <transactionID>0001023456789112</transactionID>
722
+ <status>Success</status>
723
+ <consumerName>Onderheuvel</consumerName>
724
+ <consumerAccountNumber>0949298989</consumerAccountNumber>
725
+ <consumerCity>DEN HAAG</consumerCity>
726
+ </Transaction>
727
+ <Signature>
728
+ <signatureValue>WRONG</signatureValue>
729
+ <fingerprint>1E15A00E3D7DF085768749D4ABBA3284794D8AE9</fingerprint>
730
+ </Signature>
731
+ </AcquirerStatusRes>}
732
+
733
+ ACQUIRER_FAILED_STATUS_RESPONSE = %{<?xml version="1.0" encoding="UTF-8"?>
734
+ <AcquirerStatusRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
735
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
736
+ <Acquirer>
737
+ <acquirerID>1234</acquirerID>
738
+ </Acquirer>
739
+ <Transaction>
740
+ <transactionID>0001023456789112</transactionID>
741
+ <status>Failed</status>
742
+ <consumerName>Onderheuvel</consumerName>
743
+ <consumerAccountNumber>0949298989</consumerAccountNumber>
744
+ <consumerCity>DEN HAAG</consumerCity>
745
+ </Transaction>
746
+ <Signature>
747
+ <signatureValue>db82/jpJRvKQKoiDvu33X0yoDAQpayJOaW2Y8zbR1qk1i3epvTXi+6g+QVBY93YzGv4w+Va+vL3uNmzyRjYsm2309d1CWFVsn5Mk24NLSvhYfwVHEpznyMqizALEVUNSoiSHRkZUDfXowBAyLT/tQVGbuUuBj+TKblY826nRa7U=</signatureValue>
748
+ <fingerprint>1E15A00E3D7DF085768749D4ABBA3284794D8AE9</fingerprint>
749
+ </Signature>
750
+ </AcquirerStatusRes>}
751
+
752
+ ERROR_RESPONSE = %{<?xml version="1.0" encoding="UTF-8"?>
753
+ <ErrorRes xmlns="http://www.idealdesk.com/Message" version="1.1.0">
754
+ <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
755
+ <Error>
756
+ <errorCode>SO1000</errorCode>
757
+ <errorMessage>Failure in system</errorMessage>
758
+ <errorDetail>System generating error: issuer</errorDetail>
759
+ <suggestedAction></suggestedAction>
760
+ <suggestedExpirationPeriod></suggestedExpirationPeriod>
761
+ <consumerMessage>Betalen met iDEAL is nu niet mogelijk.</consumerMessage>
762
+ </Error>
763
+ </ErrorRes>}
764
+
765
+ setup_ideal_gateway!
766
+ end