diff --git a/lib/diaspora_federation/federation/fetcher.rb b/lib/diaspora_federation/federation/fetcher.rb index 824e2a0..ea36891 100644 --- a/lib/diaspora_federation/federation/fetcher.rb +++ b/lib/diaspora_federation/federation/fetcher.rb @@ -7,7 +7,9 @@ module DiasporaFederation # @param [Symbol, String] entity_type snake_case version of the entity class # @param [String] guid guid of the entity to fetch def self.fetch_public(author, entity_type, guid) - url = DiasporaFederation.callbacks.trigger(:fetch_person_url_to, author, "/fetch/#{entity_type}/#{guid}") + url = DiasporaFederation.callbacks.trigger( + :fetch_person_url_to, author, "/fetch/#{entity_name(entity_type)}/#{guid}" + ) response = HttpClient.get(url) raise "Failed to fetch #{url}: #{response.status}" unless response.success? @@ -18,6 +20,15 @@ module DiasporaFederation raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}" end + def self.entity_name(class_name) + return class_name if class_name =~ /^[a-z]*(_[a-z]*)*$/ + + raise DiasporaFederation::Entity::UnknownEntity, class_name unless Entities.const_defined?(class_name) + + class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase + end + private_class_method :entity_name + # Raised, if the entity is not fetchable class NotFetchable < RuntimeError end diff --git a/spec/lib/diaspora_federation/federation/fetcher_spec.rb b/spec/lib/diaspora_federation/federation/fetcher_spec.rb index 1dcdddf..bbcdcbe 100644 --- a/spec/lib/diaspora_federation/federation/fetcher_spec.rb +++ b/spec/lib/diaspora_federation/federation/fetcher_spec.rb @@ -4,7 +4,7 @@ module DiasporaFederation let(:post_magic_env) { Salmon::MagicEnvelope.new(post, post.author).envelop(alice.private_key).to_xml } describe ".fetch_public" do - it "fetches a public post" do + it "fetches a public post with symbol as type param" do stub_request(:get, "https://example.org/fetch/post/#{post.guid}") .to_return(status: 200, body: post_magic_env) @@ -27,6 +27,29 @@ module DiasporaFederation Federation::Fetcher.fetch_public(post.author, :post, post.guid) end + it "fetches a public post with class name as type param" do + stub_request(:get, "https://example.org/fetch/post/#{post.guid}") + .to_return(status: 200, body: post_magic_env) + + expect_callback(:fetch_person_url_to, post.author, "/fetch/post/#{post.guid}") + .and_return("https://example.org/fetch/post/#{post.guid}") + expect_callback(:fetch_public_key, post.author).and_return(alice.public_key) + + receiver = double + expect(Federation::Receiver::Public).to receive(:new).with( + kind_of(Salmon::MagicEnvelope) + ) do |magic_env| + expect(magic_env.payload.guid).to eq(post.guid) + expect(magic_env.payload.author).to eq(post.author) + expect(magic_env.payload.raw_message).to eq(post.raw_message) + expect(magic_env.payload.public).to eq("true") + receiver + end + expect(receiver).to receive(:receive) + + Federation::Fetcher.fetch_public(post.author, "Post", post.guid) + end + it "follows redirects" do stub_request(:get, "https://example.org/fetch/post/#{post.guid}") .to_return(status: 302, headers: {"Location" => "https://example.com/fetch/post/#{post.guid}"})