epics 2.10.0 → 3.0.0.rc1
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/.gitignore +2 -1
- data/.semaphore/semaphore.yml +17 -8
- data/CHANGELOG.md +97 -0
- data/EBICS_REFERENCES.md +169 -0
- data/README.md +219 -50
- data/lib/epics/azv.rb +3 -10
- data/lib/epics/b2b.rb +3 -10
- data/lib/epics/bka.rb +3 -14
- data/lib/epics/builders/body_builder/base.rb +26 -0
- data/lib/epics/builders/body_builder/v2.rb +9 -0
- data/lib/epics/builders/body_builder/v3.rb +9 -0
- data/lib/epics/builders/body_builder.rb +6 -0
- data/lib/epics/builders/data_encryption_info_builder.rb +29 -0
- data/lib/epics/builders/data_transfer_builder/base.rb +52 -0
- data/lib/epics/builders/data_transfer_builder/v2.rb +9 -0
- data/lib/epics/builders/data_transfer_builder/v3.rb +12 -0
- data/lib/epics/builders/data_transfer_builder.rb +6 -0
- data/lib/epics/builders/header_builder/base.rb +26 -0
- data/lib/epics/builders/header_builder/v2.rb +9 -0
- data/lib/epics/builders/header_builder/v3.rb +9 -0
- data/lib/epics/builders/header_builder.rb +6 -0
- data/lib/epics/builders/mutable_builder.rb +28 -0
- data/lib/epics/builders/order_details_builder/base.rb +100 -0
- data/lib/epics/builders/order_details_builder/v2.rb +21 -0
- data/lib/epics/builders/order_details_builder/v3.rb +51 -0
- data/lib/epics/builders/order_details_builder.rb +10 -0
- data/lib/epics/builders/request_builder.rb +25 -0
- data/lib/epics/builders/static_builder/base.rb +75 -0
- data/lib/epics/builders/static_builder/v2.rb +9 -0
- data/lib/epics/builders/static_builder/v3.rb +9 -0
- data/lib/epics/builders/static_builder.rb +9 -0
- data/lib/epics/builders/transfer_receipt_builder.rb +19 -0
- data/lib/epics/builders/xml_builder/base.rb +92 -0
- data/lib/epics/builders/xml_builder/v24.rb +31 -0
- data/lib/epics/builders/xml_builder/v25.rb +31 -0
- data/lib/epics/builders/xml_builder/v3.rb +31 -0
- data/lib/epics/builders/xml_builder.rb +7 -0
- data/lib/epics/builders.rb +13 -0
- data/lib/epics/c2s.rb +3 -10
- data/lib/epics/c52.rb +2 -14
- data/lib/epics/c53.rb +2 -14
- data/lib/epics/c54.rb +2 -14
- data/lib/epics/c5n.rb +3 -14
- data/lib/epics/ccs.rb +3 -10
- data/lib/epics/cct.rb +3 -10
- data/lib/epics/cd1.rb +3 -10
- data/lib/epics/cdb.rb +3 -10
- data/lib/epics/cdd.rb +3 -10
- data/lib/epics/cds.rb +3 -10
- data/lib/epics/cdz.rb +3 -14
- data/lib/epics/cip.rb +3 -10
- data/lib/epics/client.rb +491 -123
- data/lib/epics/crypt/aes.rb +56 -0
- data/lib/epics/crypt/x_509.rb +52 -0
- data/lib/epics/crypt.rb +5 -0
- data/lib/epics/crz.rb +3 -14
- data/lib/epics/factories/crypt/aes_factory.rb +5 -0
- data/lib/epics/factories/crypt.rb +4 -0
- data/lib/epics/factories/request_factory/base.rb +236 -0
- data/lib/epics/factories/request_factory/v2.rb +194 -0
- data/lib/epics/factories/request_factory/v24.rb +32 -0
- data/lib/epics/factories/request_factory/v25.rb +31 -0
- data/lib/epics/factories/request_factory/v3.rb +305 -0
- data/lib/epics/factories/request_factory.rb +8 -0
- data/lib/epics/factories.rb +5 -0
- data/lib/epics/fdl.rb +3 -18
- data/lib/epics/ful.rb +6 -0
- data/lib/epics/generic_request.rb +31 -92
- data/lib/epics/generic_upload_request.rb +14 -67
- data/lib/epics/haa.rb +3 -9
- data/lib/epics/hac.rb +3 -14
- data/lib/epics/handlers/auth_signature_handler.rb +102 -0
- data/lib/epics/handlers/order_data_handler/base.rb +98 -0
- data/lib/epics/handlers/order_data_handler/v2.rb +39 -0
- data/lib/epics/handlers/order_data_handler/v24.rb +11 -0
- data/lib/epics/handlers/order_data_handler/v25.rb +11 -0
- data/lib/epics/handlers/order_data_handler/v3.rb +41 -0
- data/lib/epics/handlers/order_data_handler.rb +8 -0
- data/lib/epics/handlers/user_signature_handler/base.rb +10 -0
- data/lib/epics/handlers/user_signature_handler/v2.rb +17 -0
- data/lib/epics/handlers/user_signature_handler/v3.rb +17 -0
- data/lib/epics/handlers/user_signature_handler.rb +6 -0
- data/lib/epics/handlers.rb +6 -0
- data/lib/epics/hev.rb +2 -15
- data/lib/epics/hia.rb +4 -55
- data/lib/epics/hkd.rb +3 -9
- data/lib/epics/hpb.rb +3 -13
- data/lib/epics/hpd.rb +3 -9
- data/lib/epics/htd.rb +3 -9
- data/lib/epics/ini.rb +4 -46
- data/lib/epics/keyring.rb +17 -0
- data/lib/epics/letter_renderer.rb +17 -22
- data/lib/epics/ptk.rb +3 -14
- data/lib/epics/response.rb +34 -29
- data/lib/epics/services/crypt_service.rb +62 -0
- data/lib/epics/services/digest_resolver/base.rb +30 -0
- data/lib/epics/services/digest_resolver/v2.rb +13 -0
- data/lib/epics/services/digest_resolver/v3.rb +19 -0
- data/lib/epics/services/digest_resolver.rb +6 -0
- data/lib/epics/services.rb +5 -0
- data/lib/epics/signature.rb +50 -0
- data/lib/epics/{key.rb → signature_algorithm/base.rb} +14 -21
- data/lib/epics/signature_algorithm/rsa.rb +50 -0
- data/lib/epics/signature_algorithm/rsapkcs1.rb +16 -0
- data/lib/epics/signature_algorithm/rsapss.rb +20 -0
- data/lib/epics/signature_algorithm.rb +2 -0
- data/lib/epics/sta.rb +3 -14
- data/lib/epics/version.rb +1 -1
- data/lib/epics/vmk.rb +3 -14
- data/lib/epics/wss.rb +3 -9
- data/lib/epics/xct.rb +3 -10
- data/lib/epics/xds.rb +3 -10
- data/lib/epics/xe2.rb +3 -10
- data/lib/epics/xe3.rb +3 -10
- data/lib/epics/xek.rb +5 -0
- data/lib/epics/yct.rb +6 -0
- data/lib/epics/z01.rb +2 -14
- data/lib/epics/z52.rb +2 -14
- data/lib/epics/z53.rb +2 -14
- data/lib/epics/z54.rb +2 -14
- data/lib/epics/zsr.rb +5 -0
- data/lib/epics.rb +69 -5
- data/lib/letter/ini.erb +27 -6
- data/spec/aes_spec.rb +46 -0
- data/spec/auth_signature_handler_spec.rb +58 -0
- data/spec/builders_spec.rb +616 -0
- data/spec/certificate_handling_spec.rb +189 -0
- data/spec/client_setup_block_spec.rb +41 -0
- data/spec/client_spec.rb +143 -91
- data/spec/crypt_service_spec.rb +132 -0
- data/spec/date_range_spec.rb +46 -0
- data/spec/digest_resolver_spec.rb +164 -0
- data/spec/fixtures/bank_x509.pem +3 -0
- data/spec/fixtures/xml/haa.xml +40 -1
- data/spec/fixtures/xml/haa_receipt.xml +33 -30
- data/spec/fixtures/xml/haa_response_h004.xml +4 -0
- data/spec/fixtures/xml/haa_response_h005.xml +38 -0
- data/spec/fixtures/xml/hia_request_order_data.xml +24 -1
- data/spec/fixtures/xml/hpb_request.xml +1 -1
- data/spec/fixtures/xml/hpb_response_x509.xml +16 -0
- data/spec/fixtures/xml/htd_order_data_h005.xml +55 -0
- data/spec/fixtures/xml/jruby/hia.xml +20 -22
- data/spec/fixtures/xml/jruby/ini.xml +1 -3
- data/spec/fixtures/xml/ruby/hia.xml +21 -1
- data/spec/fixtures/xml/ruby/ini.xml +21 -1
- data/spec/handlers_spec.rb +267 -0
- data/spec/hpb_malformed_certificate_spec.rb +36 -0
- data/spec/key_file_decryption_spec.rb +27 -0
- data/spec/key_file_preservation_spec.rb +78 -0
- data/spec/keyring_spec.rb +349 -0
- data/spec/middleware/parse_ebics_spec.rb +2 -1
- data/spec/order_id_spec.rb +65 -0
- data/spec/orders/azv_spec.rb +63 -7
- data/spec/orders/b2b_spec.rb +68 -3
- data/spec/orders/bka_spec.rb +34 -4
- data/spec/orders/c2s_spec.rb +62 -9
- data/spec/orders/c52_spec.rb +34 -4
- data/spec/orders/c53_spec.rb +34 -4
- data/spec/orders/c54_spec.rb +36 -4
- data/spec/orders/c5n_spec.rb +36 -4
- data/spec/orders/camt_parity_spec.rb +80 -0
- data/spec/orders/ccs_spec.rb +62 -9
- data/spec/orders/cct_spec.rb +83 -9
- data/spec/orders/cd1_spec.rb +50 -7
- data/spec/orders/cdb_spec.rb +64 -7
- data/spec/orders/cdd_spec.rb +64 -7
- data/spec/orders/cds_spec.rb +74 -0
- data/spec/orders/cdz_spec.rb +67 -4
- data/spec/orders/cip_spec.rb +61 -9
- data/spec/orders/crz_spec.rb +67 -4
- data/spec/orders/fdl_spec.rb +143 -13
- data/spec/orders/ful_spec.rb +63 -0
- data/spec/orders/haa_spec.rb +115 -9
- data/spec/orders/hac_spec.rb +89 -10
- data/spec/orders/hev_spec.rb +1 -6
- data/spec/orders/hia_spec.rb +25 -22
- data/spec/orders/hkd_spec.rb +23 -4
- data/spec/orders/hpb_spec.rb +7 -4
- data/spec/orders/hpd_spec.rb +23 -4
- data/spec/orders/htd_spec.rb +23 -4
- data/spec/orders/ini_spec.rb +23 -18
- data/spec/orders/ptk_spec.rb +27 -4
- data/spec/orders/sta_spec.rb +129 -11
- data/spec/orders/vmk_spec.rb +36 -4
- data/spec/orders/wss_spec.rb +29 -3
- data/spec/orders/x_509_certificate_spec.rb +9 -1
- data/spec/orders/xct_spec.rb +63 -0
- data/spec/orders/xds_spec.rb +13 -6
- data/spec/orders/xe2_spec.rb +64 -7
- data/spec/orders/xe3_spec.rb +64 -7
- data/spec/orders/xek_spec.rb +31 -0
- data/spec/orders/yct_spec.rb +43 -0
- data/spec/orders/z01_spec.rb +34 -4
- data/spec/orders/z52_spec.rb +34 -4
- data/spec/orders/z53_spec.rb +34 -4
- data/spec/orders/z54_spec.rb +36 -4
- data/spec/orders/zsr_spec.rb +31 -0
- data/spec/request_factory_spec.rb +444 -0
- data/spec/response_business_error_spec.rb +45 -0
- data/spec/response_validation_spec.rb +23 -0
- data/spec/{key_spec.rb → signature_algorithm/rsa_pss_spec.rb} +4 -13
- data/spec/support/ebics_matcher.rb +17 -9
- data/spec/support/ebics_shared_examples.rb +642 -0
- data/spec/support/h005_client_helper.rb +23 -0
- data/spec/upload_digest_spec.rb +69 -0
- data/spec/user_signature_handler_spec.rb +25 -0
- data/spec/version_support_error_spec.rb +76 -0
- data/spec/xsd/{ebics_hev.xsd → H000/ebics_hev.xsd} +0 -0
- data/spec/xsd/H003/ebics.xsd +11 -0
- data/spec/xsd/H003/ebics_keymgmt_request.xsd +555 -0
- data/spec/xsd/H003/ebics_keymgmt_response.xsd +131 -0
- data/spec/xsd/H003/ebics_orders.xsd +1811 -0
- data/spec/xsd/H003/ebics_request.xsd +354 -0
- data/spec/xsd/H003/ebics_response.xsd +161 -0
- data/spec/xsd/{ebics_signature.xsd → H003/ebics_signature.xsd} +0 -0
- data/spec/xsd/H003/ebics_types.xsd +2361 -0
- data/spec/xsd/H003/xmldsig-core-schema.xsd +318 -0
- data/spec/xsd/H004/ebics_signature.xsd +217 -0
- data/spec/xsd/H005/ebics_H005.xsd +11 -0
- data/spec/xsd/H005/ebics_keymgmt_request_H005.xsd +523 -0
- data/spec/xsd/H005/ebics_keymgmt_response_H005.xsd +137 -0
- data/spec/xsd/H005/ebics_orders_H005.xsd +2094 -0
- data/spec/xsd/H005/ebics_request_H005.xsd +349 -0
- data/spec/xsd/H005/ebics_response_H005.xsd +167 -0
- data/spec/xsd/H005/ebics_signature_S002.xsd +177 -0
- data/spec/xsd/H005/ebics_types_H005.xsd +1885 -0
- data/spec/xsd/H005/xmldsig-core-schema.xsd +318 -0
- metadata +200 -36
- data/lib/epics/header_request.rb +0 -58
- data/lib/epics/middleware/xmlsig.rb +0 -16
- data/lib/epics/signer.rb +0 -40
- data/lib/epics/x_509_certificate.rb +0 -15
- data/lib/letter/ini_with_certs.erb +0 -335
- data/spec/generic_upload_spec.rb +0 -58
- data/spec/hpb_spec.rb +0 -15
- data/spec/signer_spec.rb +0 -34
- /data/spec/xsd/{ebics_H004.xsd → H004/ebics_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_keymgmt_request_H004.xsd → H004/ebics_keymgmt_request_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_keymgmt_response_H004.xsd → H004/ebics_keymgmt_response_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_orders_H004.xsd → H004/ebics_orders_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_request_H004.xsd → H004/ebics_request_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_response_H004.xsd → H004/ebics_response_H004.xsd} +0 -0
- /data/spec/xsd/{ebics_types_H004.xsd → H004/ebics_types_H004.xsd} +0 -0
- /data/spec/xsd/{xmldsig-core-schema.xsd → H004/xmldsig-core-schema.xsd} +0 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
RSpec.describe 'RequestFactory' do
|
|
2
|
+
let(:client) { Epics::Client.new(File.open(File.join(File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS', version:) }
|
|
3
|
+
let(:start_date) { Date.new(2024, 1, 1) }
|
|
4
|
+
let(:end_date) { Date.new(2024, 1, 31) }
|
|
5
|
+
let(:digest) { OpenSSL::Digest::SHA256.digest('test document') }
|
|
6
|
+
let(:transaction_key) { OpenSSL::Cipher::AES.new(128, :CBC).random_key }
|
|
7
|
+
let(:transaction_id) { SecureRandom.hex(16) }
|
|
8
|
+
|
|
9
|
+
def parse(builder)
|
|
10
|
+
Nokogiri::XML(builder.to_xml).tap(&:remove_namespaces!)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# ─── Shared examples ───────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
shared_examples 'a base factory' do |factory_class|
|
|
16
|
+
subject(:factory) { factory_class.new(client) }
|
|
17
|
+
|
|
18
|
+
describe '#create_hev' do
|
|
19
|
+
it 'creates ebicsHEVRequest with HostID' do
|
|
20
|
+
xml = parse(factory.create_hev)
|
|
21
|
+
expect(xml.root.name).to eq('ebicsHEVRequest')
|
|
22
|
+
expect(xml.at('//HostID').text).to eq('SIZBN001')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#create_ini' do
|
|
27
|
+
it 'creates ebicsUnsecuredRequest with INI order details' do
|
|
28
|
+
xml = parse(factory.create_ini('<order_data/>'))
|
|
29
|
+
expect(xml.root.name).to eq('ebicsUnsecuredRequest')
|
|
30
|
+
expect(xml.at('//HostID').text).to eq('SIZBN001')
|
|
31
|
+
expect(xml.at('//PartnerID').text).to eq(client.partner_id)
|
|
32
|
+
expect(xml.at('//UserID').text).to eq(client.user_id)
|
|
33
|
+
expect(xml.at('//SecurityMedium').text).to eq('0000')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#create_hia' do
|
|
38
|
+
it 'creates ebicsUnsecuredRequest with HIA order details' do
|
|
39
|
+
xml = parse(factory.create_hia('<order_data/>'))
|
|
40
|
+
expect(xml.root.name).to eq('ebicsUnsecuredRequest')
|
|
41
|
+
expect(xml.at('//HostID').text).to eq('SIZBN001')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#create_hpb' do
|
|
46
|
+
it 'creates ebicsNoPubKeyDigestsRequest with AuthSignature' do
|
|
47
|
+
xml = parse(factory.create_hpb)
|
|
48
|
+
expect(xml.root.name).to eq('ebicsNoPubKeyDigestsRequest')
|
|
49
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
50
|
+
expect(xml.at('//SecurityMedium').text).to eq('0000')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe '#create_transfer_receipt' do
|
|
55
|
+
it 'creates receipt with TransactionID and ReceiptCode' do
|
|
56
|
+
xml = parse(factory.create_transfer_receipt(transaction_id, 0))
|
|
57
|
+
expect(xml.root.name).to eq('ebicsRequest')
|
|
58
|
+
expect(xml.at('//TransactionID').text).to eq(transaction_id)
|
|
59
|
+
expect(xml.at('//TransactionPhase').text).to eq('Receipt')
|
|
60
|
+
expect(xml.at('//ReceiptCode').text).to eq('0')
|
|
61
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe '#create_transfer_upload' do
|
|
66
|
+
it 'creates transfer with segment data' do
|
|
67
|
+
xml = parse(factory.create_transfer_upload(transaction_id, transaction_key, 'order_data', 1, true))
|
|
68
|
+
expect(xml.at('//TransactionID').text).to eq(transaction_id)
|
|
69
|
+
expect(xml.at('//TransactionPhase').text).to eq('Transfer')
|
|
70
|
+
node = xml.at('//SegmentNumber')
|
|
71
|
+
expect(node.text).to eq('1')
|
|
72
|
+
expect(node['lastSegment']).to eq('true')
|
|
73
|
+
expect(xml.at('//OrderData')).not_to be_nil
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe '#create_transfer_download' do
|
|
78
|
+
it 'creates transfer without order data' do
|
|
79
|
+
xml = parse(factory.create_transfer_download(transaction_id, 2, false))
|
|
80
|
+
expect(xml.at('//TransactionID').text).to eq(transaction_id)
|
|
81
|
+
expect(xml.at('//TransactionPhase').text).to eq('Transfer')
|
|
82
|
+
expect(xml.at('//SegmentNumber').text).to eq('2')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe 'admin order types' do
|
|
87
|
+
%w[hpd hkd htd haa].each do |order_type|
|
|
88
|
+
it "creates #{order_type.upcase} request with AuthSignature" do
|
|
89
|
+
xml = parse(factory.send("create_#{order_type}"))
|
|
90
|
+
expect(xml.root.name).to eq('ebicsRequest')
|
|
91
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
92
|
+
expect(xml.at('//TransactionPhase').text).to eq('Initialisation')
|
|
93
|
+
expect(xml.at('//BankPubKeyDigests')).not_to be_nil
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
%w[hac ptk].each do |order_type|
|
|
98
|
+
it "creates #{order_type.upcase} request with date range" do
|
|
99
|
+
xml = parse(factory.send("create_#{order_type}", start_date, end_date))
|
|
100
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
101
|
+
expect(xml.at('//DateRange/Start').text).to eq('2024-01-01')
|
|
102
|
+
expect(xml.at('//DateRange/End').text).to eq('2024-01-31')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# ─── V2 shared examples ────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
shared_examples 'a V2 download factory' do |factory_class, namespace|
|
|
111
|
+
subject(:factory) { factory_class.new(client) }
|
|
112
|
+
|
|
113
|
+
describe 'download requests' do
|
|
114
|
+
download_types = {
|
|
115
|
+
'c52' => {}, 'c53' => {}, 'c54' => {}, 'sta' => {},
|
|
116
|
+
'vmk' => {}, 'z52' => {}, 'z53' => {}, 'z54' => {},
|
|
117
|
+
'bka' => {}, 'c5n' => {}, 'cdz' => {}, 'crz' => {}, 'z01' => {}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
download_types.each do |order_type, _|
|
|
121
|
+
it "creates #{order_type.upcase} download request" do
|
|
122
|
+
xml = parse(factory.send("create_#{order_type}", start_date, end_date))
|
|
123
|
+
expect(xml.root.name).to eq('ebicsRequest')
|
|
124
|
+
expect(xml.at('//OrderType').text).to eq(order_type.upcase)
|
|
125
|
+
expect(xml.at('//OrderAttribute').text).to eq('DZHNN')
|
|
126
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
127
|
+
expect(xml.at('//BankPubKeyDigests')).not_to be_nil
|
|
128
|
+
expect(xml.at('//DateRange/Start').text).to eq('2024-01-01')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe 'WSS download (no date range)' do
|
|
134
|
+
it 'creates WSS request without date range' do
|
|
135
|
+
xml = parse(factory.create_wss)
|
|
136
|
+
expect(xml.at('//OrderType').text).to eq('WSS')
|
|
137
|
+
expect(xml.at('//DateRange')).to be_nil
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe 'FDL download with file format' do
|
|
142
|
+
it 'creates FDL request with FDLOrderParams' do
|
|
143
|
+
xml = parse(factory.create_fdl('camt.053', start_date, end_date))
|
|
144
|
+
expect(xml.at('//OrderType').text).to eq('FDL')
|
|
145
|
+
expect(xml.at('//FDLOrderParams/FileFormat').text).to eq('camt.053')
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
shared_examples 'a V2 upload factory' do |factory_class|
|
|
151
|
+
subject(:factory) { factory_class.new(client) }
|
|
152
|
+
|
|
153
|
+
describe 'upload requests' do
|
|
154
|
+
upload_types_with_es = {
|
|
155
|
+
'cct' => true, 'cdd' => true, 'cdb' => true, 'cip' => true,
|
|
156
|
+
'cd1' => true, 'b2b' => true, 'xds' => true, 'xe2' => true, 'xe3' => true
|
|
157
|
+
}
|
|
158
|
+
upload_types_without_es = {
|
|
159
|
+
'ccs' => false, 'cds' => false, 'c2s' => false
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
(upload_types_with_es.merge(upload_types_without_es)).each do |order_type, with_es|
|
|
163
|
+
expected_attr = with_es ? 'OZHNN' : 'DZHNN'
|
|
164
|
+
it "creates #{order_type.upcase} upload with OrderAttribute=#{expected_attr}" do
|
|
165
|
+
xml = parse(factory.send("create_#{order_type}", digest, transaction_key))
|
|
166
|
+
expect(xml.root.name).to eq('ebicsRequest')
|
|
167
|
+
expect(xml.at('//OrderType').text).to eq(order_type.upcase)
|
|
168
|
+
expect(xml.at('//OrderAttribute').text).to eq(expected_attr)
|
|
169
|
+
expect(xml.at('//NumSegments').text).to eq('1')
|
|
170
|
+
expect(xml.at('//SignatureData')).not_to be_nil
|
|
171
|
+
expect(xml.at('//DataEncryptionInfo')).not_to be_nil
|
|
172
|
+
expect(xml.at('//TransactionKey')).not_to be_nil
|
|
173
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe 'FUL upload with file format' do
|
|
179
|
+
it 'creates FUL request with FULOrderParams' do
|
|
180
|
+
xml = parse(factory.send(:create_ful, digest, transaction_key, file_format: 'pain.001.001.02'))
|
|
181
|
+
expect(xml.at('//OrderType').text).to eq('FUL')
|
|
182
|
+
expect(xml.at('//FULOrderParams/FileFormat').text).to eq('pain.001.001.02')
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
describe 'VersionSupportError for V3-only types' do
|
|
187
|
+
it 'raises for create_btd' do
|
|
188
|
+
expect { factory.create_btd }.to raise_error(Epics::VersionSupportError)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it 'raises for create_btu' do
|
|
192
|
+
expect { factory.create_btu }.to raise_error(Epics::VersionSupportError)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# ─── V24 (H003) ────────────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
describe Epics::Factories::RequestFactory::V24 do
|
|
200
|
+
let(:version) { Epics::Keyring::VERSION_24 }
|
|
201
|
+
|
|
202
|
+
include_examples 'a base factory', Epics::Factories::RequestFactory::V24
|
|
203
|
+
include_examples 'a V2 download factory', Epics::Factories::RequestFactory::V24, 'http://www.ebics.org/H003'
|
|
204
|
+
include_examples 'a V2 upload factory', Epics::Factories::RequestFactory::V24
|
|
205
|
+
|
|
206
|
+
subject(:factory) { described_class.new(client) }
|
|
207
|
+
|
|
208
|
+
describe 'V24-specific: OrderID present' do
|
|
209
|
+
it 'includes OrderID in download requests' do
|
|
210
|
+
xml = parse(factory.create_c52(start_date, end_date))
|
|
211
|
+
expect(xml.at('//OrderID')).not_to be_nil
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it 'includes OrderID in upload requests' do
|
|
215
|
+
xml = parse(factory.create_cct(digest, transaction_key))
|
|
216
|
+
expect(xml.at('//OrderID')).not_to be_nil
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe 'INI uses DZNNN attribute' do
|
|
221
|
+
it 'sets OrderAttribute to DZNNN for INI' do
|
|
222
|
+
xml = parse(factory.create_ini('<data/>'))
|
|
223
|
+
expect(xml.at('//OrderAttribute').text).to eq('DZNNN')
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
describe 'H005-only order types' do
|
|
228
|
+
%w[xek yct zsr].each do |type|
|
|
229
|
+
it "raises VersionSupportError for #{type}" do
|
|
230
|
+
expect { factory.send("create_#{type}", start_date, end_date) }
|
|
231
|
+
.to raise_error(Epics::VersionSupportError, 'Supported from version 3.0')
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
describe 'XML namespace' do
|
|
237
|
+
it 'uses H003 namespace' do
|
|
238
|
+
builder = factory.create_hev
|
|
239
|
+
xml = Nokogiri::XML(builder.to_xml)
|
|
240
|
+
# HEV uses H000, so check a standard request
|
|
241
|
+
builder2 = factory.create_hpb
|
|
242
|
+
xml2 = Nokogiri::XML(builder2.to_xml)
|
|
243
|
+
expect(xml2.root.namespace.href).to eq('http://www.ebics.org/H003')
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# ─── V25 (H004) ────────────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
describe Epics::Factories::RequestFactory::V25 do
|
|
251
|
+
let(:version) { Epics::Keyring::VERSION_25 }
|
|
252
|
+
|
|
253
|
+
include_examples 'a base factory', Epics::Factories::RequestFactory::V25
|
|
254
|
+
include_examples 'a V2 download factory', Epics::Factories::RequestFactory::V25, 'urn:org:ebics:H004'
|
|
255
|
+
include_examples 'a V2 upload factory', Epics::Factories::RequestFactory::V25
|
|
256
|
+
|
|
257
|
+
subject(:factory) { described_class.new(client) }
|
|
258
|
+
|
|
259
|
+
describe 'V25-specific: no OrderID' do
|
|
260
|
+
it 'does not include OrderID in download requests' do
|
|
261
|
+
xml = parse(factory.create_c52(start_date, end_date))
|
|
262
|
+
expect(xml.at('//OrderID')).to be_nil
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe 'XML namespace' do
|
|
267
|
+
it 'uses H004 namespace' do
|
|
268
|
+
builder = factory.create_hpb
|
|
269
|
+
xml = Nokogiri::XML(builder.to_xml)
|
|
270
|
+
expect(xml.root.namespace.href).to eq('urn:org:ebics:H004')
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# ─── V3 (H005) ────────────────────────────────────────────
|
|
276
|
+
|
|
277
|
+
describe Epics::Factories::RequestFactory::V3 do
|
|
278
|
+
let(:version) { Epics::Keyring::VERSION_30 }
|
|
279
|
+
|
|
280
|
+
include_examples 'a base factory', Epics::Factories::RequestFactory::V3
|
|
281
|
+
|
|
282
|
+
subject(:factory) { described_class.new(client) }
|
|
283
|
+
|
|
284
|
+
describe 'XML namespace' do
|
|
285
|
+
it 'uses H005 namespace' do
|
|
286
|
+
builder = factory.create_hpb
|
|
287
|
+
xml = Nokogiri::XML(builder.to_xml)
|
|
288
|
+
expect(xml.root.namespace.href).to eq('urn:org:ebics:H005')
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
describe 'uses AdminOrderType instead of OrderType' do
|
|
293
|
+
it 'generates AdminOrderType for admin requests' do
|
|
294
|
+
xml = parse(factory.create_hpd)
|
|
295
|
+
expect(xml.at('//AdminOrderType').text).to eq('HPD')
|
|
296
|
+
expect(xml.at('//OrderType')).to be_nil
|
|
297
|
+
expect(xml.at('//OrderAttribute')).to be_nil
|
|
298
|
+
expect(xml.at('//OrderID')).to be_nil
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
describe 'BTD download requests' do
|
|
303
|
+
btd_downloads = {
|
|
304
|
+
'c52' => { service_name: 'STM', msg_name: 'camt.052' },
|
|
305
|
+
'c53' => { service_name: 'EOP', msg_name: 'camt.053', container_type: 'ZIP' },
|
|
306
|
+
'c54' => { service_name: 'REP', msg_name: 'camt.054', container_type: 'ZIP' },
|
|
307
|
+
'sta' => { service_name: 'EOP', msg_name: 'mt940' },
|
|
308
|
+
'vmk' => { service_name: 'STM', msg_name: 'mt942' },
|
|
309
|
+
'z52' => { service_name: 'STM', msg_name: 'camt.052', container_type: 'ZIP' },
|
|
310
|
+
'z53' => { service_name: 'EOP', msg_name: 'camt.053', container_type: 'ZIP' },
|
|
311
|
+
'z54' => { service_name: 'EOP', msg_name: 'camt.054', service_option: 'XQRR' },
|
|
312
|
+
'xek' => { service_name: 'EOP', msg_name: 'pdf', container_type: 'ZIP' },
|
|
313
|
+
'z01' => { service_name: 'PSR', msg_name: 'pain.002', service_option: 'CH003GEN' },
|
|
314
|
+
'bka' => { service_name: 'EOP', msg_name: 'camt.053', scope: 'DE' },
|
|
315
|
+
'c5n' => { service_name: 'STM', msg_name: 'camt.054', scope: 'DE', service_option: 'SCI' },
|
|
316
|
+
'cdz' => { service_name: 'REP', msg_name: 'pain.002', scope: 'DE', service_option: 'SDD' },
|
|
317
|
+
'crz' => { service_name: 'REP', msg_name: 'pain.002', scope: 'DE', service_option: 'SCT' },
|
|
318
|
+
'zsr' => { service_name: 'PSR', msg_name: 'pain.002', scope: 'BIL' },
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
btd_downloads.each do |order_type, expected|
|
|
322
|
+
it "creates #{order_type.upcase} as BTD with correct service params" do
|
|
323
|
+
xml = parse(factory.send("create_#{order_type}", start_date, end_date))
|
|
324
|
+
expect(xml.at('//AdminOrderType').text).to eq('BTD')
|
|
325
|
+
expect(xml.at('//BTDOrderParams/Service/ServiceName').text).to eq(expected[:service_name])
|
|
326
|
+
expect(xml.at('//BTDOrderParams/Service/MsgName').text).to eq(expected[:msg_name])
|
|
327
|
+
|
|
328
|
+
if expected[:scope]
|
|
329
|
+
expect(xml.at('//BTDOrderParams/Service/Scope').text).to eq(expected[:scope])
|
|
330
|
+
else
|
|
331
|
+
expect(xml.at('//BTDOrderParams/Service/Scope')).to be_nil
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
if expected[:service_option]
|
|
335
|
+
expect(xml.at('//BTDOrderParams/Service/ServiceOption').text).to eq(expected[:service_option])
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
if expected[:container_type]
|
|
339
|
+
expect(xml.at('//BTDOrderParams/Service/Container')['containerType']).to eq(expected[:container_type])
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
343
|
+
expect(xml.at('//BankPubKeyDigests')).not_to be_nil
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
describe 'BTU upload requests' do
|
|
349
|
+
btu_uploads = {
|
|
350
|
+
'cct' => { service_name: 'SCT', msg_name: 'pain.001', scope: 'DE', filename: 'cct.pain.001.xxx.xml' },
|
|
351
|
+
'cdd' => { service_name: 'SDD', msg_name: 'pain.008', scope: 'DE', service_option: 'COR', filename: 'cdd.pain.008.xxx.xml' },
|
|
352
|
+
'cdb' => { service_name: 'SDD', msg_name: 'pain.008', service_option: 'B2B', filename: 'cdb.pain.008.xxx.xml' },
|
|
353
|
+
'cip' => { service_name: 'SCI', msg_name: 'pain.001', filename: 'cip.pain.001.xxx.xml' },
|
|
354
|
+
'xe2' => { service_name: 'MCT', msg_name: 'pain.001', filename: 'xe2.pain.001.xxx.xml' },
|
|
355
|
+
'xe3' => { service_name: 'SDD', msg_name: 'pain.008', filename: 'xe3.pain.008.xxx.xml' },
|
|
356
|
+
'yct' => { service_name: 'MCT', msg_name: 'pain.001', scope: 'BIL', filename: 'yct.pain.001.xxx.xml' },
|
|
357
|
+
'azv' => { service_name: 'XCT', msg_name: 'dtazv', scope: 'DE', filename: 'azv.dtazv.xxx.xml' },
|
|
358
|
+
'b2b' => { service_name: 'SDD', msg_name: 'pain.008', scope: 'BIL', service_option: 'B2B', filename: 'b2b.pain.008.xxx.xml' },
|
|
359
|
+
'ccs' => { service_name: 'SCT', msg_name: 'pain.001', scope: 'DE', filename: 'ccs.pain.001.xxx.xml' },
|
|
360
|
+
'cds' => { service_name: 'SDD', msg_name: 'pain.008', scope: 'BIL', filename: 'cds.pain.008.xxx.xml' },
|
|
361
|
+
'c2s' => { service_name: 'SDD', msg_name: 'pain.008', scope: 'BIL', filename: 'c2s.pain.008.xxx.xml' },
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
btu_uploads.each do |order_type, expected|
|
|
365
|
+
it "creates #{order_type.upcase} as BTU with correct service params" do
|
|
366
|
+
xml = parse(factory.send("create_#{order_type}", digest, transaction_key))
|
|
367
|
+
expect(xml.at('//AdminOrderType').text).to eq('BTU')
|
|
368
|
+
params = xml.at('//BTUOrderParams')
|
|
369
|
+
expect(params['fileName']).to eq(expected[:filename])
|
|
370
|
+
expect(params.at('Service/ServiceName').text).to eq(expected[:service_name])
|
|
371
|
+
expect(params.at('Service/MsgName').text).to eq(expected[:msg_name])
|
|
372
|
+
|
|
373
|
+
if expected[:scope]
|
|
374
|
+
expect(params.at('Service/Scope').text).to eq(expected[:scope])
|
|
375
|
+
else
|
|
376
|
+
expect(params.at('Service/Scope')).to be_nil
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
if expected[:service_option]
|
|
380
|
+
expect(params.at('Service/ServiceOption').text).to eq(expected[:service_option])
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
# V3-specific upload elements
|
|
384
|
+
expect(xml.at('//DataDigest')).not_to be_nil
|
|
385
|
+
expect(xml.at('//AdditionalOrderInfo')).not_to be_nil
|
|
386
|
+
expect(xml.at('//SignatureData')).not_to be_nil
|
|
387
|
+
expect(xml.at('//DataEncryptionInfo')).not_to be_nil
|
|
388
|
+
expect(xml.at('//AuthSignature')).not_to be_nil
|
|
389
|
+
expect(xml.at('//NumSegments').text).to eq('1')
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
describe 'VersionSupportError for V2-only types' do
|
|
395
|
+
%w[ful fdl cd1 wss xds].each do |type|
|
|
396
|
+
it "raises VersionSupportError for #{type}" do
|
|
397
|
+
expect { factory.send("create_#{type}", digest, transaction_key) }.to raise_error(Epics::VersionSupportError)
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
describe 'V3 upload includes DataDigest with correct SignatureVersion' do
|
|
403
|
+
it 'DataDigest has SignatureVersion matching user signature' do
|
|
404
|
+
xml = parse(factory.create_cct(digest, transaction_key))
|
|
405
|
+
data_digest = xml.at('//DataDigest')
|
|
406
|
+
expect(data_digest['SignatureVersion']).to eq(client.keyring.user_signature.version)
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
describe 'BTU upload override passthrough' do
|
|
411
|
+
it 'create_cct accepts service_option override' do
|
|
412
|
+
xml = parse(factory.create_cct(digest, transaction_key, service_option: 'VOO'))
|
|
413
|
+
params = xml.at('//BTUOrderParams')
|
|
414
|
+
expect(params.at('Service/ServiceName').text).to eq('SCT')
|
|
415
|
+
expect(params.at('Service/ServiceOption').text).to eq('VOO')
|
|
416
|
+
expect(params.at('Service/Scope').text).to eq('DE')
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it 'create_cct without override has no ServiceOption' do
|
|
420
|
+
xml = parse(factory.create_cct(digest, transaction_key))
|
|
421
|
+
params = xml.at('//BTUOrderParams')
|
|
422
|
+
expect(params.at('Service/ServiceOption')).to be_nil
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it 'create_cdd override replaces default service_option' do
|
|
426
|
+
xml = parse(factory.create_cdd(digest, transaction_key, service_option: 'NEW'))
|
|
427
|
+
params = xml.at('//BTUOrderParams')
|
|
428
|
+
expect(params.at('Service/ServiceOption').text).to eq('NEW')
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it 'create_cdb override can change scope' do
|
|
432
|
+
xml = parse(factory.create_cdb(digest, transaction_key, scope: 'CH'))
|
|
433
|
+
params = xml.at('//BTUOrderParams')
|
|
434
|
+
expect(params.at('Service/Scope').text).to eq('CH')
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it 'override can change filename' do
|
|
438
|
+
xml = parse(factory.create_cct(digest, transaction_key, filename: 'custom.xml'))
|
|
439
|
+
params = xml.at('//BTUOrderParams')
|
|
440
|
+
expect(params['fileName']).to eq('custom.xml')
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
RSpec.describe Epics::Response do
|
|
2
|
+
let(:client) do
|
|
3
|
+
Epics::Client.new(File.open(File.join(File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')),
|
|
4
|
+
'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS')
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def response_with(code)
|
|
8
|
+
xml = <<~XML
|
|
9
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
10
|
+
<ebicsResponse xmlns="urn:org:ebics:H004">
|
|
11
|
+
<body><ReturnCode>#{code}</ReturnCode></body>
|
|
12
|
+
</ebicsResponse>
|
|
13
|
+
XML
|
|
14
|
+
described_class.new(client, xml)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#business_error?' do
|
|
18
|
+
{ '000000' => false,
|
|
19
|
+
'011000' => false, # positive acknowledgement
|
|
20
|
+
'011301' => false } # bank does not support prevalidation
|
|
21
|
+
.each do |code, expected|
|
|
22
|
+
it "treats #{code} as #{expected ? 'an error' : 'informational'}" do
|
|
23
|
+
expect(response_with(code).business_error?).to eq(expected)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Both are defined as failures in Epics::Error and share the 01 prefix with the
|
|
28
|
+
# informational codes above.
|
|
29
|
+
{ '011001' => 'negative acknowledgement received',
|
|
30
|
+
'011101' => 'segment number not reached' }.each do |code, description|
|
|
31
|
+
it "treats #{code} (#{description}) as an error" do
|
|
32
|
+
expect(response_with(code).business_error?).to be(true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'treats an absent return code as informational' do
|
|
37
|
+
xml = '<?xml version="1.0"?><ebicsResponse xmlns="urn:org:ebics:H004"><body/></ebicsResponse>'
|
|
38
|
+
expect(described_class.new(client, xml).business_error?).to be(false)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'treats an unrelated failure code as an error' do
|
|
42
|
+
expect(response_with('091010').business_error?).to be(true)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
RSpec.describe 'Epics::Response validity checks without keys' do
|
|
2
|
+
let(:client) { Epics::Client.new(nil, 'secret', 'https://example.com/ebics', 'HOST01', 'USER01', 'PARTNER01') }
|
|
3
|
+
let(:xml) { File.read(File.join(File.dirname(__FILE__), 'fixtures', 'xml', 'upload_init_response.xml')) }
|
|
4
|
+
|
|
5
|
+
subject(:response) { Epics::Response.new(client, xml) }
|
|
6
|
+
|
|
7
|
+
# A response can arrive before HPB has run, so these must say what is missing rather
|
|
8
|
+
# than fail on nil.
|
|
9
|
+
it 'reports the missing bank key when verifying a signature' do
|
|
10
|
+
expect { response.signature_valid? }
|
|
11
|
+
.to raise_error(Epics::MissingKeyError, /bank's authentication key/)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'reports the missing encryption key when comparing the public digest' do
|
|
15
|
+
expect { response.public_digest_valid? }
|
|
16
|
+
.to raise_error(Epics::MissingKeyError, /encryption key/)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The digest is a plain SHA-256 over the authenticated nodes and needs no key at all.
|
|
20
|
+
it 'checks the digest without any key loaded' do
|
|
21
|
+
expect { response.digest_valid? }.not_to raise_error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
RSpec.describe Epics::
|
|
1
|
+
RSpec.describe Epics::SignatureAlgorithm::RsaPss do
|
|
2
2
|
|
|
3
|
-
subject { described_class.new( File.read(File.join( File.dirname(__FILE__), 'fixtures', 'e002.pem'))) }
|
|
3
|
+
subject { described_class.new( File.read(File.join( File.dirname(__FILE__), '..', 'fixtures', 'e002.pem'))) }
|
|
4
4
|
|
|
5
5
|
describe '#public_digest' do
|
|
6
6
|
|
|
@@ -14,17 +14,8 @@ RSpec.describe Epics::Key do
|
|
|
14
14
|
let(:dsi) { OpenSSL::Digest::SHA256.new.digest("ruby is great") }
|
|
15
15
|
|
|
16
16
|
it 'will generated a digest that can be verified with openssl key.verify_pss' do
|
|
17
|
-
signed_digest = subject.sign(dsi)
|
|
18
|
-
|
|
19
|
-
key = subject.key
|
|
20
|
-
|
|
21
|
-
verification_result = key.verify_pss(
|
|
22
|
-
'SHA256',
|
|
23
|
-
Base64.decode64(signed_digest),
|
|
24
|
-
dsi,
|
|
25
|
-
salt_length: :digest,
|
|
26
|
-
mgf1_hash: 'SHA256',
|
|
27
|
-
)
|
|
17
|
+
signed_digest = Base64.encode64(subject.sign(dsi)).strip
|
|
18
|
+
verification_result = subject.verify(signed_digest, dsi)
|
|
28
19
|
|
|
29
20
|
expect(verification_result).to eq(true)
|
|
30
21
|
end
|
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
RSpec::Matchers.define :be_a_valid_ebics_doc do
|
|
2
|
-
|
|
1
|
+
RSpec::Matchers.define :be_a_valid_ebics_doc do |version|
|
|
3
2
|
##
|
|
4
3
|
# use #open instead of #read to have the includes working
|
|
5
4
|
# http://stackoverflow.com/questions/11996326/nokogirixmlschema-syntaxerror-on-schema-load/22971456#22971456
|
|
6
|
-
def xsd
|
|
7
|
-
@xsd ||=
|
|
5
|
+
def xsd(version)
|
|
6
|
+
@xsd ||= {}
|
|
7
|
+
@xsd[version] ||= Nokogiri::XML::Schema(case version
|
|
8
|
+
when Epics::Keyring::VERSION_30
|
|
9
|
+
File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'H005', 'ebics_H005.xsd') )
|
|
10
|
+
when Epics::Keyring::VERSION_25
|
|
11
|
+
File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'H004', 'ebics_H004.xsd') )
|
|
12
|
+
when Epics::Keyring::VERSION_24
|
|
13
|
+
File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'H003', 'ebics.xsd') )
|
|
14
|
+
when 'H000'
|
|
15
|
+
File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'H000', 'ebics_hev.xsd') )
|
|
16
|
+
end)
|
|
8
17
|
end
|
|
9
18
|
|
|
10
19
|
match do |actual|
|
|
11
|
-
xsd.valid?(Nokogiri::XML(actual))
|
|
20
|
+
xsd(version).valid?(Nokogiri::XML(actual))
|
|
12
21
|
end
|
|
13
22
|
|
|
14
23
|
failure_message do |actual|
|
|
15
|
-
"expected that #{actual} would be a valid EBICS doc:\n\n #{xsd.validate(Nokogiri::XML(actual))}"
|
|
24
|
+
"expected that #{actual} would be a valid EBICS doc:\n\n #{xsd(version).validate(Nokogiri::XML(actual))}"
|
|
16
25
|
end
|
|
17
26
|
|
|
18
27
|
description do
|
|
19
|
-
|
|
28
|
+
'be a valid EBICS document'
|
|
20
29
|
end
|
|
21
|
-
|
|
22
|
-
end
|
|
30
|
+
end
|