main
  1# frozen_string_literal: true
  2
  3RSpec.describe ::Xml::Kit::Templatable do
  4  class Item
  5    include ::Xml::Kit::Templatable
  6  end
  7  subject { Item.new }
  8
  9  describe '#encrypt_data_for' do
 10    context 'when encrypting xml' do
 11      before do
 12        subject.encrypt = true
 13        subject.encryption_certificate = ::Xml::Kit::KeyPair.generate(use: :encryption).certificate
 14      end
 15
 16      let(:result) do
 17        subject.encrypt_data_for(xml: ::Builder::XmlMarkup.new) do |xml|
 18          xml.HelloWorld Time.now.iso8601
 19        end
 20      end
 21      let(:xml_hash) { Hash.from_xml(result) }
 22
 23      specify { expect(result).to include('EncryptedData') }
 24      specify { expect(xml_hash['EncryptedData']).to be_present }
 25      specify { expect(xml_hash['EncryptedData']['EncryptionMethod']).to be_present }
 26    end
 27
 28    context 'when disabled' do
 29      before do
 30        subject.encrypt = false
 31        subject.encryption_certificate = ::Xml::Kit::KeyPair.generate(use: :encryption).certificate
 32      end
 33
 34      let(:result) do
 35        subject.encrypt_data_for(xml: ::Builder::XmlMarkup.new) do |xml|
 36          xml.HelloWorld Time.now.iso8601
 37        end
 38      end
 39
 40      specify { expect(result).to include('HelloWorld') }
 41      specify { expect(result).not_to include('EncryptedData') }
 42      specify { expect(Hash.from_xml(result)['HelloWorld']).to be_present }
 43    end
 44
 45    context 'when a cert is missing' do
 46      before do
 47        subject.encrypt = true
 48        subject.encryption_certificate = nil
 49      end
 50
 51      let(:result) do
 52        subject.encrypt_data_for(xml: ::Builder::XmlMarkup.new) do |xml|
 53          xml.HelloWorld Time.now.iso8601
 54        end
 55      end
 56
 57      specify { expect(result).to include('HelloWorld') }
 58      specify { expect(result).not_to include('EncryptedData') }
 59      specify { expect(Hash.from_xml(result)['HelloWorld']).to be_present }
 60    end
 61  end
 62
 63  describe '#encrypt_with' do
 64    before do
 65      subject.encrypt_with(key_pair.certificate)
 66    end
 67
 68    let(:key_pair) { ::Xml::Kit::KeyPair.generate(use: :encryption) }
 69    let(:result) do
 70      subject.encrypt_data_for(xml: ::Builder::XmlMarkup.new) do |xml|
 71        xml.HelloWorld Time.now.iso8601
 72      end
 73    end
 74
 75    specify { expect(result).to include('EncryptedData') }
 76    specify { expect(Hash.from_xml(result)['EncryptedData']).to be_present }
 77    specify { expect(Hash.from_xml(result)['EncryptedData']['EncryptionMethod']).to be_present }
 78  end
 79
 80  describe '#to_xml' do
 81    context 'when generating a signed document' do
 82      let(:key_pair) { ::Xml::Kit::KeyPair.generate(use: :signing) }
 83
 84      before do
 85        subject.sign_with(key_pair)
 86      end
 87
 88      it 'produces a valid signature' do
 89        result = subject.to_xml
 90        node = Nokogiri::XML(result).at_xpath('//ds:Signature', ds: ::Xml::Kit::Namespaces::XMLDSIG)
 91        dsignature = Xmldsig::Signature.new(node, 'ID=$uri or @Id')
 92        expect(dsignature).to be_valid(key_pair.certificate.x509)
 93        expect(dsignature.errors).to be_empty
 94      end
 95    end
 96
 97    specify { expect(subject.to_xml).to match_xsd('item') }
 98
 99    context 'with the key extracted to the header' do
100      let(:xml_hash) { Hash.from_xml(subject.to_xml) }
101
102      before do
103        subject.template_path = './spec/fixtures/item-extracted-key.builder'
104      end
105
106      specify { expect(subject.to_xml).to match_xsd('item-extracted-key') }
107      specify { expect(xml_hash['Item']['Encrypted']['EncryptedData']['KeyInfo']['RetrievalMethod']).to be_present }
108      specify { expect(xml_hash['Item']['Encrypted']['EncryptedData']['KeyInfo']['RetrievalMethod']['xmlns']).to eql(::Xml::Kit::Namespaces::XMLDSIG) }
109      specify { expect(xml_hash['Item']['Encrypted']['EncryptedData']['KeyInfo']['RetrievalMethod']['URI']).to eql('#EK') }
110      specify { expect(xml_hash['Item']['Encrypted']['EncryptedData']['KeyInfo']['RetrievalMethod']['Type']).to eql('http://www.w3.org/2001/04/xmlenc#EncryptedKey') }
111      specify { expect(xml_hash['Item']['Encrypted']['EncryptedData']['KeyInfo']['EncryptedKey']).to be_nil }
112    end
113  end
114end