diff --git a/lib/diaspora_federation/salmon/xml_payload.rb b/lib/diaspora_federation/salmon/xml_payload.rb index 48f8653..81d65db 100644 --- a/lib/diaspora_federation/salmon/xml_payload.rb +++ b/lib/diaspora_federation/salmon/xml_payload.rb @@ -91,7 +91,7 @@ module DiasporaFederation type = prop_def[:type] if type == String - data[name] = parse_string_from_node(name, node) + data[name] = parse_string_from_node(prop_def[:xml_name], node) elsif type.instance_of?(Array) data[name] = parse_array_from_node(type, node) elsif type.ancestors.include?(Entity) diff --git a/spec/lib/diaspora_federation/discovery/h_card_spec.rb b/spec/lib/diaspora_federation/discovery/h_card_spec.rb index 0f4375c..827e0a6 100644 --- a/spec/lib/diaspora_federation/discovery/h_card_spec.rb +++ b/spec/lib/diaspora_federation/discovery/h_card_spec.rb @@ -20,7 +20,6 @@ module DiasporaFederation last_name: person.last_name } } - let(:klass) { Discovery::HCard } let(:html) { <<-HTML @@ -109,9 +108,7 @@ module DiasporaFederation HTML } - it_behaves_like "an Entity subclass" do - let(:xml) { nil } # disable to_xml test - end + it_behaves_like "an Entity subclass" context "generation" do it "creates an instance from a data hash" do diff --git a/spec/lib/diaspora_federation/discovery/web_finger_spec.rb b/spec/lib/diaspora_federation/discovery/web_finger_spec.rb index 9613f92..8e6eace 100644 --- a/spec/lib/diaspora_federation/discovery/web_finger_spec.rb +++ b/spec/lib/diaspora_federation/discovery/web_finger_spec.rb @@ -17,7 +17,6 @@ module DiasporaFederation public_key: person.serialized_public_key } } - let(:klass) { Discovery::WebFinger } let(:xml) { <<-XML diff --git a/spec/lib/diaspora_federation/entities/location_spec.rb b/spec/lib/diaspora_federation/entities/location_spec.rb index e8cd263..9cf56c3 100644 --- a/spec/lib/diaspora_federation/entities/location_spec.rb +++ b/spec/lib/diaspora_federation/entities/location_spec.rb @@ -9,11 +9,11 @@ module DiasporaFederation #{data[:lat]} #{data[:lng]} - XML +XML } - it_behaves_like "an Entity subclass" do - let(:klass) { Entities::Location } - end + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/entities/person_spec.rb b/spec/lib/diaspora_federation/entities/person_spec.rb index d8cdb51..a245543 100644 --- a/spec/lib/diaspora_federation/entities/person_spec.rb +++ b/spec/lib/diaspora_federation/entities/person_spec.rb @@ -1,7 +1,6 @@ module DiasporaFederation describe Entities::Person do let(:data) { FactoryGirl.attributes_for(:person_entity) } - let(:klass) { Entities::Person } let(:xml) { <<-XML @@ -30,5 +29,7 @@ XML } it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/entities/photo_spec.rb b/spec/lib/diaspora_federation/entities/photo_spec.rb index e07d5a3..c4c853a 100644 --- a/spec/lib/diaspora_federation/entities/photo_spec.rb +++ b/spec/lib/diaspora_federation/entities/photo_spec.rb @@ -16,11 +16,11 @@ module DiasporaFederation #{data[:height]} #{data[:width]} - XML +XML } - it_behaves_like "an Entity subclass" do - let(:klass) { Entities::Photo } - end + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/entities/profile_spec.rb b/spec/lib/diaspora_federation/entities/profile_spec.rb index 0bc15fc..d299d76 100644 --- a/spec/lib/diaspora_federation/entities/profile_spec.rb +++ b/spec/lib/diaspora_federation/entities/profile_spec.rb @@ -1,7 +1,6 @@ module DiasporaFederation describe Entities::Profile do let(:data) { FactoryGirl.attributes_for(:profile_entity) } - let(:klass) { Entities::Profile } let(:xml) { <<-XML @@ -24,5 +23,7 @@ XML } it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/entities/request_spec.rb b/spec/lib/diaspora_federation/entities/request_spec.rb index f142ed6..62592fb 100644 --- a/spec/lib/diaspora_federation/entities/request_spec.rb +++ b/spec/lib/diaspora_federation/entities/request_spec.rb @@ -11,11 +11,11 @@ module DiasporaFederation alice@somepod.org bob@otherpod.net - XML +XML } - it_behaves_like "an Entity subclass" do - let(:klass) { Entities::Request } - end + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/entities/status_message_spec.rb b/spec/lib/diaspora_federation/entities/status_message_spec.rb index 08bfa74..dccb5e1 100644 --- a/spec/lib/diaspora_federation/entities/status_message_spec.rb +++ b/spec/lib/diaspora_federation/entities/status_message_spec.rb @@ -58,8 +58,8 @@ module DiasporaFederation XML } - it_behaves_like "an Entity subclass" do - let(:klass) { Entities::StatusMessage } - end + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" end end diff --git a/spec/lib/diaspora_federation/salmon/xml_payload_spec.rb b/spec/lib/diaspora_federation/salmon/xml_payload_spec.rb index 2235041..90ee287 100644 --- a/spec/lib/diaspora_federation/salmon/xml_payload_spec.rb +++ b/spec/lib/diaspora_federation/salmon/xml_payload_spec.rb @@ -35,7 +35,7 @@ module DiasporaFederation end it "produces the expected XML" do - xml_str = <<-XML.strip + xml = <<-XML.strip @@ -44,7 +44,7 @@ module DiasporaFederation XML - expect(subject.to_xml).to eq(xml_str) + expect(subject.to_xml).to eq(xml) end end end @@ -103,6 +103,24 @@ XML expect(subject).to be_an_instance_of Entities::TestEntity expect(subject.test).to eq("asdf") end + + it "uses xml_name for parsing" do + xml = <<-XML.strip + + + + asdf + qwer + + + +XML + entity = Salmon::XmlPayload.unpack(Nokogiri::XML::Document.parse(xml).root) + + expect(entity).to be_an_instance_of Entities::TestEntityWithXmlName + expect(entity.test).to eq("asdf") + expect(entity.qwer).to eq("qwer") + end end context "nested entities" do diff --git a/spec/support/shared_entity_specs.rb b/spec/support/shared_entity_specs.rb index ce8fb61..bb0b884 100644 --- a/spec/support/shared_entity_specs.rb +++ b/spec/support/shared_entity_specs.rb @@ -1,22 +1,22 @@ shared_examples "an Entity subclass" do it "should be an Entity" do - expect(klass).to be < DiasporaFederation::Entity + expect(described_class).to be < DiasporaFederation::Entity end it "has its properties set" do - expect(klass.class_prop_names).to include(*data.keys) + expect(described_class.class_prop_names).to include(*data.keys) end context "behaviour" do - let(:instance) { klass.new(data) } + let(:instance) { described_class.new(data) } describe "initialize" do it "must not create blank instances" do - expect { klass.new({}) }.to raise_error ArgumentError + expect { described_class.new({}) }.to raise_error ArgumentError end it "fails if nil was given" do - expect { klass.new(nil) }.to raise_error ArgumentError, "expected a Hash" + expect { described_class.new(nil) }.to raise_error ArgumentError, "expected a Hash" end it "should be frozen" do @@ -29,11 +29,50 @@ shared_examples "an Entity subclass" do expect(instance.to_h).to eq(data) end end + end +end - describe "#to_xml" do - it "produces correct XML" do - expect(instance.to_xml.to_s.strip).to eq(xml.strip) unless xml.nil? - end +shared_examples "an XML Entity" do + let(:instance) { described_class.new(data) } + + describe "#to_xml" do + it "produces correct XML" do + expect(instance.to_xml.to_s.strip).to eq(xml.strip) + end + end + + context "parsing" do + it "reads its own output" do + packed_xml = DiasporaFederation::Salmon::XmlPayload.pack(instance).to_s + xml_root = Nokogiri::XML::Document.parse(packed_xml).root + parsed_instance = DiasporaFederation::Salmon::XmlPayload.unpack(xml_root) + + check_entity(instance, parsed_instance) + end + end + + def check_entity(entity, parsed_entity) + entity.class.class_props.each do |prop_def| + name = prop_def[:name] + type = prop_def[:type] + + value = entity.send(name) + parsed_value = parsed_entity.send(name) + + validate_values(parsed_value, type, value) + end + end + + def validate_values(parsed_value, type, value) + if value.nil? + expect(parsed_value).to be_nil + elsif type == String + expect(parsed_value).to eq(value.to_s) + elsif type.instance_of?(Array) + parsed_entities = parsed_value + value.each_with_index { |entity, index| check_entity(entity, parsed_entities[index]) } + elsif type.ancestors.include?(DiasporaFederation::Entity) + check_entity(value, parsed_value) end end end