From f7043405775008979319623b109853357881d46d Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Wed, 8 Feb 2023 21:41:29 +1100 Subject: [PATCH] Refactor syndication clients for testability --- config/providers/clients.rb | 5 ++ lib/adamantium/micropub_request_parser.rb | 4 +- lib/adamantium/syndication/mastodon.rb | 61 +++-------------------- spec/syndication/mastodon_spec.rb | 6 ++- 4 files changed, 17 insertions(+), 59 deletions(-) create mode 100644 config/providers/clients.rb diff --git a/config/providers/clients.rb b/config/providers/clients.rb new file mode 100644 index 0000000..561e0f7 --- /dev/null +++ b/config/providers/clients.rb @@ -0,0 +1,5 @@ +Hanami.app.register_provider :clients, namespace: true do + start do + register "mastodon", Adamantium::Client::Mastodon.new + end +end diff --git a/lib/adamantium/micropub_request_parser.rb b/lib/adamantium/micropub_request_parser.rb index d24454a..a36f868 100644 --- a/lib/adamantium/micropub_request_parser.rb +++ b/lib/adamantium/micropub_request_parser.rb @@ -2,7 +2,7 @@ require "securerandom" module Adamantium class MicropubRequestParser - include Deps["logger", "post_utilities.slugify", "repos.post_repo"] + include Deps["post_utilities.slugify", "repos.post_repo"] def call(params:) return nil if params.key?(:action) @@ -83,8 +83,6 @@ module Adamantium new_params[:url] = params[:"bookmark-of"] new_params[:slug] = slug(name: new_params[:name], default_slug: params[:slug]) - logger.info(new_params) - new_params end end diff --git a/lib/adamantium/syndication/mastodon.rb b/lib/adamantium/syndication/mastodon.rb index 7dea972..ab9fda3 100644 --- a/lib/adamantium/syndication/mastodon.rb +++ b/lib/adamantium/syndication/mastodon.rb @@ -1,72 +1,23 @@ -require "digest" require "dry/monads" require "httparty" -require "tempfile" -require "open-uri" module Adamantium module Syndication class Mastodon include Dry::Monads[:result] - include Deps["settings", "logger"] + include Deps[mastodon_client: "clients.mastodon"] def call(post:) - unless settings.mastodon_token && settings.mastodon_server - logger.info("No Mastodon credentials") - return Failure(:no_mastodon_credentials) - end - - content = if post[:name] - "#{post[:name]} — #{settings.micropub_site_url}/post/#{post[:slug]}" - else - post[:content] - end - - tags = post[:category].map { |tag| "##{tag}" }.join(" ") - text_with_tags = "#{content} #{tags}" - - key = Digest::MD5.hexdigest text_with_tags - mastodon_token = settings.mastodon_token - mastodon_server = settings.mastodon_server.split("@").first - logger.info("Photos: #{post[:photos].inspect}") media_ids = post[:photos]&.map do |photo| - file = Tempfile.new(SecureRandom.uuid) - file.write(URI.open(photo[:value]).read) - file.rewind - response = HTTParty.post("#{mastodon_server}api/v2/media", { - headers: { - Authorization: "Bearer #{mastodon_token}" - }, - multipart: true, - body: { - file: file, - description: photo[:alt] - } - }) - file.close - file.unlink - logger.info(response.code) - - JSON.parse(response.body, symbolize_names: true).fetch(:id, nil) + mastodon_client.upload_media(photo: photo) end&.compact - response = HTTParty.post("#{mastodon_server}api/v1/statuses", { - headers: { - "Idempotency-Key": key, - Authorization: "Bearer #{mastodon_token}" - }, - body: { - status: text_with_tags, - media_ids: media_ids - } - }) + response = mastodon_client.create_post(post: post, media_ids: media_ids) - if response.code >= 200 && response.code < 300 - status = JSON.parse(response.body, symbolize_names: true) - Success("#{mastodon_server}/#{status[:id]}") + if response.success? + Success(response.value!) else - logger.info("Failed to syndicate to Mastodon: #{response.message}") - Failure(response.message) + Failure(:failed_to_syndicate) end end end diff --git a/spec/syndication/mastodon_spec.rb b/spec/syndication/mastodon_spec.rb index 8000587..266f78c 100644 --- a/spec/syndication/mastodon_spec.rb +++ b/spec/syndication/mastodon_spec.rb @@ -1,7 +1,11 @@ require "spec_helper" +require "dry/monads" RSpec.describe Adamantium::Syndication::Mastodon do - subject { described_class.new } + include Dry::Monads[:result] + + let(:client) { double("mastodon client", create_post: Success(), upload_media: Success()) } + subject { described_class.new(mastodon_client: client) } describe "syndication to mastodon" do let(:post) {