diff --git a/lib/epics/client.rb b/lib/epics/client.rb index f9b03ca..ef1b01a 100644 --- a/lib/epics/client.rb +++ b/lib/epics/client.rb @@ -1,3 +1,10 @@ +require_relative 'h004' +require_relative './hvu' +require_relative './hvz' +require_relative './hvd' +require_relative './hve' +require_relative './hvs' + class Epics::Client extend Forwardable @@ -151,6 +158,7 @@ def HAA Nokogiri::XML(download(Epics::HAA)).at_xpath("//xmlns:OrderTypes", xmlns: "urn:org:ebics:H004").content.split(/\s/) end + # fetch client and subscriber data def HTD Nokogiri::XML(download(Epics::HTD)).tap do |htd| @iban ||= htd.at_xpath("//xmlns:AccountNumber[@international='true']", xmlns: "urn:org:ebics:H004").text @@ -159,34 +167,67 @@ def HTD end.to_xml end + # fetch bank parameters def HPD download(Epics::HPD) end + # fetch client and subscriber data def HKD download(Epics::HKD) end + # fetch text protocol def PTK(from, to) download(Epics::PTK, from, to) end + # XML Protokolldatei abholen def HAC(from = nil, to = nil) download(Epics::HAC, from, to) end + # VEU related actions + + # Fetch overview of all orders which need to be signed + def HVU + Epics::H004.from_xml(download(Epics::HVU)).to_h + end + + # Fetch detailed overview of all orders which need to be signed + def HVZ + Epics::H004.from_xml(download(Epics::HVZ)).to_h + end + + # Fetch details for an order + def HVD(order_id, order_type) + Epics::H004.from_xml(download(Epics::HVD, order_id, order_type)).to_h + end + + # sign an order + def HVE(order_id, order_type, digest) + upload(Epics::HVE, order_id, order_type, digest) + end + + # reject an order + def HVS(order_id, order_type, digest) + upload(Epics::HVS, order_id, order_type, digest) + end + def save_keys(path) File.write(path, dump_keys) end private - def upload(order_type, document) - order = order_type.new(self, document) + def upload(order_type, *args) + order = order_type.new(self, *args) res = post(url, order.to_xml).body order.transaction_id = res.transaction_id - res = post(url, order.to_transfer_xml).body + if order.segmented? + res = post(url, order.to_transfer_xml).body + end return res.transaction_id, res.order_id end diff --git a/lib/epics/generic_upload_request.rb b/lib/epics/generic_upload_request.rb index 74fdd88..733c222 100644 --- a/lib/epics/generic_upload_request.rb +++ b/lib/epics/generic_upload_request.rb @@ -3,12 +3,16 @@ class Epics::GenericUploadRequest < Epics::GenericRequest attr_accessor :key attr_accessor :document - def initialize(client, document) + def initialize(client, document = nil) super(client) self.document = document self.key ||= cipher.random_key end + def segmented? + true + end + def cipher @cipher ||= OpenSSL::Cipher.new("aes-128-cbc") end @@ -83,4 +87,4 @@ def pad(d) end end -end \ No newline at end of file +end diff --git a/lib/epics/h004.rb b/lib/epics/h004.rb new file mode 100644 index 0000000..34cc888 --- /dev/null +++ b/lib/epics/h004.rb @@ -0,0 +1,30 @@ +require 'nokogiri' + +require_relative './h004/hvu' +require_relative './h004/hvz' +require_relative './h004/hvd' + +module Epics + module H004 + UnknownInput = Class.new(ArgumentError) + + def self.from_xml(raw_xml) + doc = Nokogiri::XML(raw_xml).at_xpath('/*') + + unless doc.namespace.href == "urn:org:ebics:H004" + fail UnknownInput, "Unknown xml file contents" + end + + case doc.name + when "HVZResponseOrderData" + Epics::H004::HVZ.new(doc) + when "HVUResponseOrderData" + Epics::H004::HVU.new(doc) + when "HVDResponseOrderData" + Epics::H004::HVD.new(doc) + end + rescue Nokogiri::XML::XPath::SyntaxError => ex + fail UnknownInput, "Invalid XML input data: #{ex.message}" + end + end +end diff --git a/lib/epics/h004/hvd.rb b/lib/epics/h004/hvd.rb new file mode 100644 index 0000000..cadfd72 --- /dev/null +++ b/lib/epics/h004/hvd.rb @@ -0,0 +1,46 @@ +module Epics + module H004 + class HVD + attr_accessor :doc + + def initialize(xml_doc) + self.doc = xml_doc + end + + def to_h + order = doc.at_xpath("/h004:HVDResponseOrderData") + { + signers: signers(order.xpath('./h004:SignerInfo')), + order_details_available: order.at_xpath('./h004:OrderDetailsAvailable').content == 'true', + order_data_available: order.at_xpath('./h004:OrderDataAvailable').content == 'true', + digest: order.at_xpath('./h004:DataDigest').content, + digest_signature_version: order.at_xpath('./h004:DataDigest')['SignatureVersion'], + display_file: Base64.decode64(order.at_xpath('./h004:DisplayFile').content).encode("UTF-8", "ISO-8859-15"), + } + end + + private + + def originator(node) + { + name: node.at_xpath('./h004:Name').content.strip, + partner_id: node.at_xpath('./h004:PartnerID').content.strip, + user_id: node.at_xpath('./h004:UserID').content.strip, + timestamp: Time.parse(node.at_xpath('./h004:Timestamp').content), + } + end + + def signers(nodes) + nodes.map do |signer| + { + name: signer.at_xpath('./h004:Name').content.strip, + partner_id: signer.at_xpath('./h004:PartnerID').content.strip, + user_id: signer.at_xpath('./h004:UserID').content.strip, + signature_class: signer.at_xpath('./h004:Permission')['AuthorisationLevel'] + } + end + end + + end + end +end diff --git a/lib/epics/h004/hvu.rb b/lib/epics/h004/hvu.rb new file mode 100644 index 0000000..4f9616a --- /dev/null +++ b/lib/epics/h004/hvu.rb @@ -0,0 +1,48 @@ +module Epics + module H004 + class HVU + attr_accessor :doc + + def initialize(xml_doc) + self.doc = xml_doc + end + + def to_h + doc.xpath("/h004:HVUResponseOrderData/h004:OrderDetails").map do |order| + { + order_id: order.at_xpath('./h004:OrderID').content, + order_type: order.at_xpath('./h004:OrderType').content, + originator: originator(order.at_xpath('./h004:OriginatorInfo')), + signers: signers(order.xpath('./h004:SignerInfo')), + required_signatures: order.at_xpath('./h004:SigningInfo')['NumSigRequired'].to_i, + applied_signatures: order.at_xpath('./h004:SigningInfo')['NumSigDone'].to_i, + ready_for_signature: order.at_xpath('./h004:SigningInfo')['readyToBeSigned'].to_s.downcase == 'true', + } + end + end + + private + + def originator(node) + { + name: node.at_xpath('./h004:Name').content.strip, + partner_id: node.at_xpath('./h004:PartnerID').content.strip, + user_id: node.at_xpath('./h004:UserID').content.strip, + timestamp: Time.parse(node.at_xpath('./h004:Timestamp').content), + } + end + + def signers(nodes) + nodes.map do |signer| + { + name: signer.at_xpath('./h004:Name').content.strip, + partner_id: signer.at_xpath('./h004:PartnerID').content.strip, + user_id: signer.at_xpath('./h004:UserID').content.strip, + signature_class: signer.at_xpath('./h004:Permission')['AuthorisationLevel'] + } + end + end + + end + end +end diff --git a/lib/epics/h004/hvz.rb b/lib/epics/h004/hvz.rb new file mode 100644 index 0000000..0d53993 --- /dev/null +++ b/lib/epics/h004/hvz.rb @@ -0,0 +1,58 @@ +require 'bigdecimal' + +module Epics + module H004 + class HVZ + attr_accessor :doc + + def initialize(xml_doc) + self.doc = xml_doc + end + + def to_h + doc.xpath("/h004:HVZResponseOrderData/h004:OrderDetails").map do |order| + { + order_id: order.at_xpath('./h004:OrderID').content, + order_type: order.at_xpath('./h004:OrderType').content, + originator: originator(order.at_xpath('./h004:OriginatorInfo')), + signers: signers(order.xpath('./h004:SignerInfo')), + required_signatures: order.at_xpath('./h004:SigningInfo')['NumSigRequired'].to_i, + applied_signatures: order.at_xpath('./h004:SigningInfo')['NumSigDone'].to_i, + ready_for_signature: as_boolean(order.at_xpath('./h004:SigningInfo')['readyToBeSigned']), + total_amount: BigDecimal.new(order.at_xpath('./h004:TotalAmount').content), + total_amount_type: as_boolean(order.at_xpath('./h004:TotalAmount')['isCredit']) ? 'credit' : 'debit', + total_orders: order.at_xpath('./h004:TotalOrders').content.to_i, + digest: order.at_xpath('./h004:DataDigest').content, + digest_signature_version: order.at_xpath('./h004:DataDigest')['SignatureVersion'], + } + end + end + + private + + def originator(node) + { + name: node.at_xpath('./h004:Name').content.strip, + partner_id: node.at_xpath('./h004:PartnerID').content.strip, + user_id: node.at_xpath('./h004:UserID').content.strip, + timestamp: Time.parse(node.at_xpath('./h004:Timestamp').content), + } + end + + def signers(nodes) + nodes.map do |signer| + { + name: signer.at_xpath('./h004:Name').content.strip, + partner_id: signer.at_xpath('./h004:PartnerID').content.strip, + user_id: signer.at_xpath('./h004:UserID').content.strip, + signature_class: signer.at_xpath('./h004:Permission')['AuthorisationLevel'] + } + end + end + + def as_boolean(input) + input.to_s.downcase == 'true' + end + end + end +end diff --git a/lib/epics/hvd.rb b/lib/epics/hvd.rb new file mode 100644 index 0000000..345578f --- /dev/null +++ b/lib/epics/hvd.rb @@ -0,0 +1,53 @@ +module Epics + class HVD < Epics::GenericRequest + attr_accessor :order_id, :order_type + + def initialize(client, order_id, order_type) + super(client) + self.order_id = order_id + self.order_type = order_type + end + + def header + { + :@authenticate => true, + static: { + "HostID" => host_id, + "Nonce" => nonce, + "Timestamp" => timestamp, + "PartnerID" => partner_id, + "UserID" => user_id, + "Product" => { + :@Language => "de", + :content! => "EPICS - a ruby ebics kernel" + }, + "OrderDetails" => { + "OrderType" => "HVD", + "OrderAttribute" => "DZHNN", + "HVDOrderParams" => { + "PartnerID" => partner_id, + "OrderType" => order_type, + "OrderID" => order_id, + } + }, + "BankPubKeyDigests" => { + "Authentication" => { + :@Version => "X002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_x.public_digest + }, + "Encryption" => { + :@Version => "E002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_e.public_digest + } + }, + "SecurityMedium" => "0000" + }, + "mutable" => { + "TransactionPhase" => "Initialisation" + } + } + end + end +end diff --git a/lib/epics/hve.rb b/lib/epics/hve.rb new file mode 100644 index 0000000..42d82ab --- /dev/null +++ b/lib/epics/hve.rb @@ -0,0 +1,64 @@ +module Epics + class HVE < Epics::GenericUploadRequest + + attr_accessor :order_id, :order_type, :digest + + def initialize(client, order_id, order_type, digest) + super(client) + self.order_id = order_id + self.order_type = order_type + self.digest = digest + end + + def segmented? + false + end + + def header + { + :@authenticate => true, + static: { + "HostID" => host_id, + "Nonce" => nonce, + "Timestamp" => timestamp, + "PartnerID" => partner_id, + "UserID" => user_id, + "Product" => { + :@Language => "de", + :content! => "EPICS - a ruby ebics kernel" + }, + "OrderDetails" => { + "OrderType" => "HVE", + "OrderAttribute" => "UZHNN", + "HVEOrderParams" => { + "PartnerID" => partner_id, + "OrderType" => order_type, + "OrderID" => order_id, + } + }, + "BankPubKeyDigests" => { + "Authentication" => { + :@Version => "X002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_x.public_digest + }, + "Encryption" => { + :@Version => "E002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_e.public_digest + } + }, + "SecurityMedium" => "0000", + "NumSegments" => 0, + }, + "mutable" => { + "TransactionPhase" => "Initialisation" + } + } + end + + def signature_value + client.a.sign(Base64.strict_decode64(digest)) + end + end +end diff --git a/lib/epics/hvs.rb b/lib/epics/hvs.rb new file mode 100644 index 0000000..447df95 --- /dev/null +++ b/lib/epics/hvs.rb @@ -0,0 +1,64 @@ +module Epics + class HVS < Epics::GenericUploadRequest + + attr_accessor :order_id, :order_type, :digest + + def initialize(client, order_id, order_type, digest) + super(client) + self.order_id = order_id + self.order_type = order_type + self.digest = digest + end + + def segmented? + false + end + + def header + { + :@authenticate => true, + static: { + "HostID" => host_id, + "Nonce" => nonce, + "Timestamp" => timestamp, + "PartnerID" => partner_id, + "UserID" => user_id, + "Product" => { + :@Language => "de", + :content! => "EPICS - a ruby ebics kernel" + }, + "OrderDetails" => { + "OrderType" => "HVS", + "OrderAttribute" => "UZHNN", + "HVSOrderParams" => { + "PartnerID" => partner_id, + "OrderType" => order_type, + "OrderID" => order_id, + } + }, + "BankPubKeyDigests" => { + "Authentication" => { + :@Version => "X002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_x.public_digest + }, + "Encryption" => { + :@Version => "E002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_e.public_digest + } + }, + "SecurityMedium" => "0000", + "NumSegments" => 0, + }, + "mutable" => { + "TransactionPhase" => "Initialisation" + } + } + end + + def signature_value + client.a.sign(Base64.strict_decode64(digest)) + end + end +end diff --git a/lib/epics/hvu.rb b/lib/epics/hvu.rb new file mode 100644 index 0000000..7f72124 --- /dev/null +++ b/lib/epics/hvu.rb @@ -0,0 +1,41 @@ +module Epics + class HVU < Epics::GenericRequest + def header + { + :@authenticate => true, + static: { + "HostID" => host_id, + "Nonce" => nonce, + "Timestamp" => timestamp, + "PartnerID" => partner_id, + "UserID" => user_id, + "Product" => { + :@Language => "de", + :content! => "EPICS - a ruby ebics kernel" + }, + "OrderDetails" => { + "OrderType" => "HVU", + "OrderAttribute" => "DZHNN", + "HVUOrderParams" => {} + }, + "BankPubKeyDigests" => { + "Authentication" => { + :@Version => "X002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_x.public_digest + }, + "Encryption" => { + :@Version => "E002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_e.public_digest + } + }, + "SecurityMedium" => "0000" + }, + "mutable" => { + "TransactionPhase" => "Initialisation" + } + } + end + end +end diff --git a/lib/epics/hvz.rb b/lib/epics/hvz.rb new file mode 100644 index 0000000..d8a57c5 --- /dev/null +++ b/lib/epics/hvz.rb @@ -0,0 +1,41 @@ +module Epics + class HVZ < Epics::GenericRequest + def header + { + :@authenticate => true, + static: { + "HostID" => host_id, + "Nonce" => nonce, + "Timestamp" => timestamp, + "PartnerID" => partner_id, + "UserID" => user_id, + "Product" => { + :@Language => "de", + :content! => "EPICS - a ruby ebics kernel" + }, + "OrderDetails" => { + "OrderType" => "HVZ", + "OrderAttribute" => "DZHNN", + "HVZOrderParams" => {} + }, + "BankPubKeyDigests" => { + "Authentication" => { + :@Version => "X002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_x.public_digest + }, + "Encryption" => { + :@Version => "E002", + :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256", + :content! => client.bank_e.public_digest + } + }, + "SecurityMedium" => "0000" + }, + "mutable" => { + "TransactionPhase" => "Initialisation" + } + } + end + end +end diff --git a/spec/fixtures/xml/hvd_response.xml b/spec/fixtures/xml/hvd_response.xml new file mode 100644 index 0000000..23325bb --- /dev/null +++ b/spec/fixtures/xml/hvd_response.xml @@ -0,0 +1,24 @@ + + + Ej9Q5zvpef87V9Ef5vdEY/aiPvEiVYupcZHir51G94g= + DQogICAgICAgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAgICAgIEcgVSBUIFMgQyBIIFIgSSBGIFQgRSBOCiAgICAgICAgIERhdGVpLUlEICAgOiBFQklDUy1CT1gvQTk2MDI5ODg1MTQ4MzY2QUU5NTA4MgogICAgICAgICBEYXR1bS9aZWl0IDogMjMuMDMuMjAxNi8xMDo1NjozNgogICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgIFNhbW1sZXJyZWZlcmVueiAgICAgICAgICAgICAgOiBFQklDUy1CT1gvQTk2MDI5ODg1MTQ4MzY2QUU5NTA4Mi8xCiAgICAgICAgIEJhbmstQ29kZSAgICAgICAgICAgICAgICAgICAgOiBYQkFOREVDRwogICAgICAgICBLb250b251bW1lciAgICAgICAgICAgICAgICAgIDogREUzNjI1MDQwMDkwMDAwMTIzNDU1NQogICAgICAgICBBdWZ0cmFnZ2ViZXJkYXRlbiAgICAgICAgICAgIDogUUEgS29udG8gQlYKICAgICAgICAgQW56YWhsIGRlciBaYWhsdW5nc3PkdHplICAgICA6IDEKICAgICAgICAgU3VtbWUgZGVyIEJldHLkZ2UgKCBFVVIgKSAgICA6IDEuMDAwLDEzCiAgICAgICAgIEF1c2b8aHJ1bmdzdGVybWluICAgICAgICAgICAgOiAyMy4wMy4yMDE2CiAgICAgICAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0= + true + 1776 + false + + RS + RST + + RS T + 2016-03-23T08:56:39.000000Z + + + + RS + RSA + + RS A + 2016-03-23T09:26:33.000000Z + + + diff --git a/spec/fixtures/xml/hvu_response.xml b/spec/fixtures/xml/hvu_response.xml new file mode 100644 index 0000000..ea1f999 --- /dev/null +++ b/spec/fixtures/xml/hvu_response.xml @@ -0,0 +1,53 @@ + + + + CCT + B03N + 1776 + + + RS + RST + + RS T + 2016-03-23T08:56:39.000000Z + + + + RS + RSA + + RS A + 2016-03-23T09:26:33.000000Z + + + + RS + RST + + RS T + 2016-03-23T08:56:39.000000Z + + + + CCT + B03P + 1776 + + + RS + RST + + RS T + 2016-03-29T10:57:12.000000Z + + + + RS + RST + + RS T + 2016-03-29T10:57:11.000000Z + + + diff --git a/spec/fixtures/xml/hvz_response.xml b/spec/fixtures/xml/hvz_response.xml new file mode 100644 index 0000000..a50599b --- /dev/null +++ b/spec/fixtures/xml/hvz_response.xml @@ -0,0 +1,65 @@ + + + + CCT + B03N + Ej9Q5zvpef87V9Ef5vdEY/aiPvEiVYupcZHir51G94g= + true + 1776 + false + 1 + 1000.13 + EUR + + + RS + RST + + RS T + 2016-03-23T08:56:39.000000Z + + + + RS + RSA + + RS A + 2016-03-23T09:26:33.000000Z + + + + RS + RST + + RS T + 2016-03-23T08:56:39.000000Z + + + + CCT + B03P + INN6KG5EHVovPLsbzdnNbfL7GGneYztgIYxXlRQwwI4= + true + 1776 + false + 1 + 1000.13 + EUR + + + RS + RST + + RS T + 2016-03-29T10:57:12.000000Z + + + + RS + RST + + RS T + 2016-03-29T10:57:11.000000Z + + + diff --git a/spec/generic_upload_spec.rb b/spec/generic_upload_spec.rb index 156623f..074040d 100644 --- a/spec/generic_upload_spec.rb +++ b/spec/generic_upload_spec.rb @@ -2,6 +2,12 @@ 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') } subject { described_class.new(client, "\x01" * 12) } + describe '#segmented?' do + it 'returns true by default' do + expect(subject.segmented?).to eq(true) + end + end + describe '#pad' do it 'will complete the block to the next 16byte' do @@ -35,4 +41,4 @@ end end -end \ No newline at end of file +end diff --git a/spec/orders/hvd_spec.rb b/spec/orders/hvd_spec.rb new file mode 100644 index 0000000..f2be648 --- /dev/null +++ b/spec/orders/hvd_spec.rb @@ -0,0 +1,85 @@ +# encoding: utf-8 + +require 'spec_helper' + +RSpec.describe Epics::HVD do + 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') } + + describe 'No data available' do + it 'returns nil' + end + + describe 'data is available' do + let(:xml_response) { File.read(File.join(File.dirname(__FILE__), '../fixtures/xml/hvd_response.xml')) } + + before { allow(client).to receive(:download).with(described_class, 'B03N', 'CCT').and_return(xml_response) } + + describe 'attributes' do + subject { client.HVD('B03N', 'CCT') } + + it 'lists all signers' do + expect(subject[:signers]).to be_instance_of(Array) + end + + it 'indicates if detailed order data is available' do + expect(subject[:order_details_available]).to eq(false) + end + + it 'indicates if order data is available' do + expect(subject[:order_data_available]).to eq(true) + end + + it 'sets correct string encoding' do + expect(subject[:display_file]).to include("Ausführungstermin") + end + + it 'indicates if order data is available' do + expect(subject[:display_file]).to include("Datei-ID") + end + + it 'sets digest' do + expect(subject[:digest]).to eq('Ej9Q5zvpef87V9Ef5vdEY/aiPvEiVYupcZHir51G94g=') + end + + it 'sets digest_signature_version' do + expect(subject[:digest_signature_version]).to eq('A006') + end + + it 'does not include an order id' do + expect(subject).to_not have_key(:order_id) + end + + it 'does not include an order type' do + expect(subject).to_not have_key(:order_type) + end + + it 'does not include an originator' do + expect(subject).to_not have_key(:originator) + end + + it 'does not include flag if ready to be signed' do + expect(subject).to_not have_key(:ready_for_signature) + end + + it 'does not include number of already applied signatures' do + expect(subject).to_not have_key(:applied_signatures) + end + + it 'does not include number of required signatures' do + expect(subject).to_not have_key(:required_signatures) + end + + it 'does not include not have total_amount' do + expect(subject).to_not have_key(:total_amount) + end + + it 'does not have total_amount_type' do + expect(subject).to_not have_key(:total_amount_type) + end + + it 'does not have total_orders' do + expect(subject).to_not have_key(:total_orders) + end + end + end +end diff --git a/spec/orders/hve_spec.rb b/spec/orders/hve_spec.rb new file mode 100644 index 0000000..c6248ef --- /dev/null +++ b/spec/orders/hve_spec.rb @@ -0,0 +1,42 @@ +RSpec.describe Epics::HVE do + 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') } + let(:digest) { Base64.strict_encode64("supersecretdigest") } + + subject { described_class.new(client, "myid", "mytype", digest) } + + describe '#segmented?' do + it 'returns false' do + expect(subject.segmented?).to eq(false) + end + end + + describe '#to_xml' do + describe 'message header' do + it 'sets order type' do + expect(subject.to_xml).to include("HVE") + end + + it 'uploads as order without segments' do + expect(subject.to_xml).to include("UZHNN") + end + + it 'sets order params' do + expect(subject.to_xml).to include("") + end + + it 'sets number of segments to zero' do + expect(subject.to_xml).to include("0") + end + end + + describe 'message body' do + it 'includes a signature' do + expect(subject.to_xml).to include("") + end + + it 'does not have any order data' do + expect(subject.to_xml).to_not include("") + end + end + end +end diff --git a/spec/orders/hvs_spec.rb b/spec/orders/hvs_spec.rb new file mode 100644 index 0000000..538a352 --- /dev/null +++ b/spec/orders/hvs_spec.rb @@ -0,0 +1,42 @@ +RSpec.describe Epics::HVS do + 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') } + let(:digest) { Base64.strict_encode64("supersecretdigest") } + + subject { described_class.new(client, "myid", "mytype", digest) } + + describe '#segmented?' do + it 'returns false' do + expect(subject.segmented?).to eq(false) + end + end + + describe '#to_xml' do + describe 'message header' do + it 'sets order type' do + expect(subject.to_xml).to include("HVS") + end + + it 'uploads as order without segments' do + expect(subject.to_xml).to include("UZHNN") + end + + it 'sets order params' do + expect(subject.to_xml).to include("") + end + + it 'sets number of segments to zero' do + expect(subject.to_xml).to include("0") + end + end + + describe 'message body' do + it 'includes a signature' do + expect(subject.to_xml).to include("") + end + + it 'does not have any order data' do + expect(subject.to_xml).to_not include("") + end + end + end +end diff --git a/spec/orders/hvu_spec.rb b/spec/orders/hvu_spec.rb new file mode 100644 index 0000000..f5e0f6b --- /dev/null +++ b/spec/orders/hvu_spec.rb @@ -0,0 +1,84 @@ +require 'spec_helper' + +RSpec.describe Epics::HVU do + 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') } + + describe 'No data available' do + before { allow(client).to receive(:download).with(described_class).and_raise(Epics::Error::BusinessError, "090005") } + + it 'returns an empty array' + end + + describe 'data is available' do + let(:xml_response) { File.read(File.join(File.dirname(__FILE__), '../fixtures/xml/hvu_response.xml')) } + + before { allow(client).to receive(:download).with(described_class).and_return(xml_response) } + + it 'parses and returns an array' do + expect(client.HVU).to be_instance_of(Array) + end + + it 'parses and returns each order' do + expect(client.HVU.size).to eq(2) + end + + describe 'attributes' do + subject { client.HVU.first } + + it 'sets the order id' do + expect(subject[:order_id]).to eq('B03N') + end + + it 'sets order type' do + expect(subject[:order_type]).to eq('CCT') + end + + it 'lists all signers' do + expect(subject[:signers]).to be_instance_of(Array) + end + + it 'sets the originator' do + expect(subject[:originator]).to match(hash_including( + :name => "RS T", + :partner_id => "RS", + :timestamp => Time.new(2016, 3, 23, 8, 56, 39, "+00:00"), + :user_id => "RST", + )) + end + + it 'sets flag if ready to be signed' do + expect(subject[:ready_for_signature]).to eq(true) + end + + it 'sets number of already applied signatures' do + expect(subject[:applied_signatures]).to eq(1) + end + + it 'sets number of required signatures' do + expect(subject[:required_signatures]).to eq(1) + end + + it 'does not have total_amount' do + expect(subject).to_not have_key(:total_amount) + end + + it 'does not have total_amount_type' do + expect(subject).to_not have_key(:total_amount_type) + end + + it 'does not have total_orders' do + expect(subject).to_not have_key(:total_orders) + end + + it 'does not have digest' do + expect(subject).to_not have_key(:digest) + end + + it 'does not have digest_signature_version' do + expect(subject).to_not have_key(:digest_signature_version) + end + end + + end + +end diff --git a/spec/orders/hvz_spec.rb b/spec/orders/hvz_spec.rb new file mode 100644 index 0000000..7bf00a9 --- /dev/null +++ b/spec/orders/hvz_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +RSpec.describe Epics::HVZ do + 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') } + + describe 'No data available' do + before { allow(client).to receive(:download).with(Epics::HVZ).and_raise(Epics::Error::BusinessError, "090005") } + + it 'returns an empty array' + end + + describe 'data is available' do + let(:xml_response) { File.read(File.join(File.dirname(__FILE__), '../fixtures/xml/hvz_response.xml')) } + + before { allow(client).to receive(:download).with(Epics::HVZ).and_return(xml_response) } + + it 'parses and returns an array' do + expect(client.HVZ).to be_instance_of(Array) + end + + it 'parses and returns each order' do + expect(client.HVZ.size).to eq(2) + end + + describe 'attributes' do + subject { client.HVZ.first } + + it 'sets the order id' do + expect(subject[:order_id]).to eq('B03N') + end + + it 'sets order type' do + expect(subject[:order_type]).to eq('CCT') + end + + it 'lists all signers' do + expect(subject[:signers]).to be_instance_of(Array) + end + + it 'sets the originator' do + expect(subject[:originator]).to match(hash_including( + :name => "RS T", + :partner_id => "RS", + :timestamp => Time.new(2016, 3, 23, 8, 56, 39, "+00:00"), + :user_id => "RST", + )) + end + + it 'sets flag if ready to be signed' do + expect(subject[:ready_for_signature]).to eq(true) + end + + it 'sets number of already applied signatures' do + expect(subject[:applied_signatures]).to eq(1) + end + + it 'sets number of required signatures' do + expect(subject[:required_signatures]).to eq(1) + end + + it 'sets total_amount' do + expect(subject[:total_amount]).to eq(1000.13) + end + it 'sets total_amount_type' do + expect(subject[:total_amount_type]).to eq('credit') + end + + it 'sets total_orders' do + expect(subject[:total_orders]).to eq(1) + end + + it 'sets digest' do + expect(subject[:digest]).to eq('Ej9Q5zvpef87V9Ef5vdEY/aiPvEiVYupcZHir51G94g=') + end + + it 'sets digest_signature_version' do + expect(subject[:digest_signature_version]).to eq('A006') + end + end + + end + +end