diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index c3ac091..8f2d68d 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -198,17 +198,21 @@ module DiasporaFederation end end - add_parent(entity_data) + fetch_parent(entity_data) new(entity_data, xml_order, additional_xml_elements).tap(&:verify_signatures) end - def add_parent(data) - data[:parent] = fetch_parent(data) - end - def fetch_parent(data) type = data[:parent_type] || self::PARENT_TYPE - DiasporaFederation.callbacks.trigger(:fetch_related_entity, type, data[:parent_guid]) + guid = data[:parent_guid] + + data[:parent] = DiasporaFederation.callbacks.trigger(:fetch_related_entity, type, guid) + + unless data[:parent] + # fetch and receive parent from remote, if not available locally + Federation::Fetcher.fetch_public(data[:author], type, guid) + data[:parent] = DiasporaFederation.callbacks.trigger(:fetch_related_entity, type, guid) + end end end diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index 83be123..339ee33 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -294,5 +294,34 @@ XML end end end + + context "fetch parent" do + before do + expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key) + expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key) + expect_callback(:fetch_private_key, author).and_return(author_pkey) + expect_callback(:fetch_private_key, remote_parent.author).and_return(parent_pkey) + end + + let(:xml) { SomeRelayable.new(hash).to_xml } + + it "fetches the parent from the backend" do + expect_callback(:fetch_related_entity, "Parent", parent_guid).and_return(remote_parent) + expect(Federation::Fetcher).not_to receive(:fetch_public) + + entity = SomeRelayable.from_xml(xml) + + expect(entity.parent).to eq(remote_parent) + end + + it "fetches the parent from remote if not found on backend" do + expect_callback(:fetch_related_entity, "Parent", parent_guid).and_return(nil, remote_parent) + expect(Federation::Fetcher).to receive(:fetch_public).with(author, "Parent", parent_guid) + + entity = SomeRelayable.from_xml(xml) + + expect(entity.parent).to eq(remote_parent) + end + end end end