# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Packages::Rpm::RepositoryMetadata::UpdateXmlService do
describe '#execute' do
subject { described_class.new(filename: filename, xml: xml, data: data).execute }
let(:xml) { nil }
let(:data) { nil }
shared_examples 'handling not implemented xml filename' do
let(:filename) { :not_implemented_yet }
let(:empty_xml) { '' }
it 'raise error' do
expect { subject }.to raise_error(ArgumentError)
end
end
shared_context 'with primary xml file data' do
let(:filename) { :primary }
let(:empty_xml) do
<<~XML
XML
end
end
shared_context 'with other xml file data' do
let(:filename) { :other }
let(:empty_xml) do
<<~XML
XML
end
end
shared_context 'with filelist xml file data' do
let(:filename) { :filelist }
let(:empty_xml) do
<<~XML
XML
end
end
context 'when building empty xml' do
shared_examples 'generating empty xml' do
it 'generate expected xml' do
expect(subject).to eq(empty_xml)
end
end
it_behaves_like 'handling not implemented xml filename'
context "for 'primary' xml file" do
include_context 'with primary xml file data'
it_behaves_like 'generating empty xml'
end
context "for 'other' xml file" do
include_context 'with other xml file data'
it_behaves_like 'generating empty xml'
end
context "for 'filelist' xml file" do
include_context 'with filelist xml file data'
it_behaves_like 'generating empty xml'
end
end
context 'when updating xml file' do
include_context 'with rpm package data'
let(:xml) { empty_xml }
let(:data) { xml_update_params }
let(:builder_class) { described_class::BUILDERS[filename] }
shared_examples 'updating rpm xml file' do
context 'when updating existing xml' do
shared_examples 'changing root tag attribute' do
it "increment previous 'packages' value by 1" do
previous_value = Nokogiri::XML(xml).at(builder_class::ROOT_TAG).attributes["packages"].value.to_i
new_value = Nokogiri::XML(subject).at(builder_class::ROOT_TAG).attributes["packages"].value.to_i
expect(previous_value + 1).to eq(new_value)
end
end
it 'generate valid xml add expected xml node to existing xml' do
# Have one root attribute
result = Nokogiri::XML::Document.parse(subject).remove_namespaces!
expect(result.children.count).to eq(1)
# Root node has 1 child with generated node
expect(result.xpath("//#{builder_class::ROOT_TAG}/package").count).to eq(1)
end
context 'when empty xml' do
it_behaves_like 'changing root tag attribute'
end
context 'when xml has children' do
context "when node with given 'pkgid' does not exist yet" do
let(:uniq_node_data) do
xml_update_params.tap do |data|
data[:pkgid] = SecureRandom.uuid
end
end
let(:xml) { build_xml_from(uniq_node_data) }
it 'has children nodes' do
existing_xml = Nokogiri::XML::Document.parse(xml).remove_namespaces!
expect(existing_xml.xpath('//package').count).to eq(1)
end
it_behaves_like 'changing root tag attribute'
end
context "when node with given 'pkgid' already exist" do
let(:existing_node_data) do
existing_data = data.dup
existing_data[:name] = FFaker::Lorem.word
existing_data
end
let(:xml) { build_xml_from(existing_node_data) }
it 'has children nodes' do
existing_xml = Nokogiri::XML::Document.parse(xml).remove_namespaces!
expect(existing_xml.xpath('//package').count).to eq(1)
end
it 'replace existing node with new data' do
existing_xml = Nokogiri::XML::Document.parse(xml).remove_namespaces!
result = Nokogiri::XML::Document.parse(subject).remove_namespaces!
expect(result.xpath('//package').count).to eq(1)
expect(result.xpath('//package').first.to_xml).not_to eq(existing_xml.xpath('//package').first.to_xml)
end
end
def build_xml_from(data)
described_class.new(filename: filename, xml: empty_xml, data: data).execute
end
end
end
end
it_behaves_like 'handling not implemented xml filename'
context "for 'primary' xml file" do
include_context 'with primary xml file data'
it_behaves_like 'updating rpm xml file'
end
context "for 'other' xml file" do
include_context 'with other xml file data'
it_behaves_like 'updating rpm xml file'
end
context "for 'filelist' xml file" do
include_context 'with filelist xml file data'
it_behaves_like 'updating rpm xml file'
end
end
end
end