From 5fb9d5b761c4352ce59e484990bded29db1ec363 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 18 Dec 2020 02:07:26 +0100 Subject: [PATCH] Transmogrifier: Clean out unused functions --- lib/pleroma/object/fetcher.ex | 17 -- lib/pleroma/web/activity_pub/transmogrifier.ex | 290 ++------------------- .../transmogrifier/note_handling_test.exs | 164 ------------ .../web/activity_pub/transmogrifier_test.exs | 87 ------- 4 files changed, 21 insertions(+), 537 deletions(-) diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index 4ca67f0fd..4995271af 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -51,23 +51,6 @@ defmodule Pleroma.Object.Fetcher do end end - defp reinject_object(%Object{} = object, new_data) do - Logger.debug("Reinjecting object #{new_data["id"]}") - - with new_data <- Transmogrifier.fix_object(new_data), - data <- maybe_reinject_internal_fields(object, new_data), - changeset <- Object.change(object, %{data: data}), - changeset <- touch_changeset(changeset), - {:ok, object} <- Repo.insert_or_update(changeset), - {:ok, object} <- Object.set_cache(object) do - {:ok, object} - else - e -> - Logger.error("Error while processing object: #{inspect(e)}") - {:error, e} - end - end - def refetch_object(%Object{data: %{"id" => id}} = object) do with {:local, false} <- {:local, Object.local?(object)}, {:ok, new_data} <- fetch_and_contain_remote_object_from_id(id), diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index d1d5a3184..56c53bc82 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -10,7 +10,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.Maps alias Pleroma.Object - alias Pleroma.Object.Containment alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub @@ -27,73 +26,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do require Logger require Pleroma.Constants - @doc """ - Modifies an incoming AP object (mastodon format) to our internal format. - """ - def fix_object(object, options \\ []) do - object - |> strip_internal_fields() - |> fix_actor() - |> fix_url() - |> fix_attachments() - |> fix_context() - |> fix_in_reply_to(options) - |> fix_emoji() - |> fix_tag() - |> fix_content_map() - |> fix_addressing() - |> fix_summary() - end - - def fix_summary(%{"summary" => nil} = object) do - Map.put(object, "summary", "") - end - - def fix_summary(%{"summary" => _} = object) do - # summary is present, nothing to do - object - end - - def fix_summary(object), do: Map.put(object, "summary", "") - - def fix_addressing_list(map, field) do - addrs = map[field] - - cond do - is_list(addrs) -> - Map.put(map, field, Enum.filter(addrs, &is_binary/1)) - - is_binary(addrs) -> - Map.put(map, field, [addrs]) - - true -> - Map.put(map, field, []) - end - end - - # if directMessage flag is set to true, leave the addressing alone - def fix_explicit_addressing(%{"directMessage" => true} = object, _follower_collection), - do: object - - def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, follower_collection) do - explicit_mentions = - Utils.determine_explicit_mentions(object) ++ - [Pleroma.Constants.as_public(), follower_collection] - - explicit_to = Enum.filter(to, fn x -> x in explicit_mentions end) - explicit_cc = Enum.filter(to, fn x -> x not in explicit_mentions end) - - final_cc = - (cc ++ explicit_cc) - |> Enum.filter(& &1) - |> Enum.reject(fn x -> String.ends_with?(x, "/followers") and x != follower_collection end) - |> Enum.uniq() - - object - |> Map.put("to", explicit_to) - |> Map.put("cc", final_cc) - end - # if as:Public is addressed, then make sure the followers collection is also addressed # so that the activities will be delivered to local users. def fix_implicit_addressing(%{"to" => to, "cc" => cc} = object, followers_collection) do @@ -117,34 +49,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_addressing(object) do - {:ok, %User{follower_address: follower_collection}} = - object - |> Containment.get_actor() - |> User.get_or_fetch_by_ap_id() - - object - |> fix_addressing_list("to") - |> fix_addressing_list("cc") - |> fix_addressing_list("bto") - |> fix_addressing_list("bcc") - |> fix_explicit_addressing(follower_collection) - |> fix_implicit_addressing(follower_collection) - end - - def fix_actor(%{"attributedTo" => actor} = object) do - actor = Containment.get_actor(%{"actor" => actor}) - - # TODO: Remove actor field for Objects - object - |> Map.put("actor", actor) - |> Map.put("attributedTo", actor) - end - - def fix_in_reply_to(object, options \\ []) - - def fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object, options) - when not is_nil(in_reply_to) do + defp fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object, options) + when not is_nil(in_reply_to) do in_reply_to_id = prepare_in_reply_to(in_reply_to) depth = (options[:depth] || 0) + 1 @@ -165,7 +71,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_in_reply_to(object, _options), do: object + defp fix_in_reply_to(object, _options), do: object defp prepare_in_reply_to(in_reply_to) do cond do @@ -183,100 +89,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_context(object) do - context = object["context"] || object["conversation"] || Utils.generate_context_id() - - object - |> Map.put("context", context) - |> Map.drop(["conversation"]) - end - - def fix_attachments(%{"attachment" => attachment} = object) when is_list(attachment) do - attachments = - Enum.map(attachment, fn data -> - url = - cond do - is_list(data["url"]) -> List.first(data["url"]) - is_map(data["url"]) -> data["url"] - true -> nil - end - - media_type = - cond do - is_map(url) && MIME.extensions(url["mediaType"]) != [] -> - url["mediaType"] - - is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] -> - data["mediaType"] - - is_bitstring(data["mimeType"]) && MIME.extensions(data["mimeType"]) != [] -> - data["mimeType"] - - true -> - nil - end - - href = - cond do - is_map(url) && is_binary(url["href"]) -> url["href"] - is_binary(data["url"]) -> data["url"] - is_binary(data["href"]) -> data["href"] - true -> nil - end - - if href do - attachment_url = - %{ - "href" => href, - "type" => Map.get(url || %{}, "type", "Link") - } - |> Maps.put_if_present("mediaType", media_type) - |> Maps.put_if_present("width", (url || %{})["width"] || data["width"]) - |> Maps.put_if_present("height", (url || %{})["height"] || data["height"]) - - %{ - "url" => [attachment_url], - "type" => data["type"] || "Document" - } - |> Maps.put_if_present("mediaType", media_type) - |> Maps.put_if_present("name", data["name"]) - |> Maps.put_if_present("blurhash", data["blurhash"]) - else - nil - end - end) - |> Enum.filter(& &1) - - Map.put(object, "attachment", attachments) - end - - def fix_attachments(%{"attachment" => attachment} = object) when is_map(attachment) do - object - |> Map.put("attachment", [attachment]) - |> fix_attachments() - end - - def fix_attachments(object), do: object - - def fix_url(%{"url" => url} = object) when is_map(url) do - Map.put(object, "url", url["href"]) - end - - def fix_url(%{"url" => url} = object) when is_list(url) do - first_element = Enum.at(url, 0) - - url_string = - cond do - is_bitstring(first_element) -> first_element - is_map(first_element) -> first_element["href"] || "" - true -> "" - end - - Map.put(object, "url", url_string) - end - - def fix_url(object), do: object - def fix_emoji(%{"tag" => tags} = object) when is_list(tags) do emoji = tags @@ -299,26 +111,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def fix_emoji(object), do: object - def fix_tag(%{"tag" => tag} = object) when is_list(tag) do - tags = - tag - |> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end) - |> Enum.map(fn - %{"name" => "#" <> hashtag} -> String.downcase(hashtag) - %{"name" => hashtag} -> String.downcase(hashtag) - end) - - Map.put(object, "tag", tag ++ tags) - end - - def fix_tag(%{"tag" => %{} = tag} = object) do - object - |> Map.put("tag", [tag]) - |> fix_tag - end - - def fix_tag(object), do: object - # content map usually only has one language so this will do for now. def fix_content_map(%{"contentMap" => content_map} = object) do content_groups = Map.to_list(content_map) @@ -398,7 +190,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do "star" => "⭐" } - @doc "Rewrite misskey likes into EmojiReacts" + # Rewrite misskey likes into EmojiReacts def handle_incoming( %{ "type" => "Like", @@ -575,30 +367,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - @spec get_embedded_obj_helper(String.t() | Object.t(), User.t()) :: {:ok, Object.t()} | nil - def get_embedded_obj_helper(%{"attributedTo" => attributed_to, "id" => object_id} = data, %User{ - ap_id: ap_id - }) - when attributed_to == ap_id do - with {:ok, activity} <- - handle_incoming(%{ - "type" => "Create", - "to" => data["to"], - "cc" => data["cc"], - "actor" => attributed_to, - "object" => data - }) do - {:ok, Object.normalize(activity, fetch: false)} - else - _ -> get_obj_helper(object_id) - end - end - - def get_embedded_obj_helper(object_id, _) do - get_obj_helper(object_id) - end - - def set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_reply_to) do + defp set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_reply_to) do with false <- String.starts_with?(in_reply_to, "http"), {:ok, %{data: replied_to_object}} <- get_obj_helper(in_reply_to) do Map.put(object, "inReplyTo", replied_to_object["external_url"] || in_reply_to) @@ -607,13 +376,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def set_reply_to_uri(obj), do: obj + defp set_reply_to_uri(obj), do: obj - @doc """ - Serialized Mastodon-compatible `replies` collection containing _self-replies_. - Based on Mastodon's ActivityPub::NoteSerializer#replies. - """ - def set_replies(obj_data) do + # Serialized Mastodon-compatible `replies` collection containing _self-replies_. + # Based on Mastodon's ActivityPub::NoteSerializer#replies. + defp set_replies(obj_data) do replies_uris = with limit when limit > 0 <- Pleroma.Config.get([:activitypub, :note_replies_output_limit], 0), @@ -643,16 +410,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.merge(obj, %{"replies" => replies_collection}) end - def replies(%{"replies" => %{"first" => %{"items" => items}}}) when not is_nil(items) do - items - end - - def replies(%{"replies" => %{"items" => items}}) when not is_nil(items) do - items - end - - def replies(_), do: [] - # Prepares the object of an outgoing create activity. def prepare_object(object) do object @@ -669,11 +426,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> set_type end - # @doc - # """ - # internal -> Mastodon - # """ - def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data) when activity_type in ["Create", "Listen"] do object = @@ -778,7 +530,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def maybe_fix_object_url(data), do: data - def add_hashtags(object) do + defp add_hashtags(object) do tags = (object["tag"] || []) |> Enum.map(fn @@ -800,7 +552,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # TODO These should be added on our side on insertion, it doesn't make much # sense to regenerate these all the time - def add_mention_tags(object) do + defp add_mention_tags(object) do to = object["to"] || [] cc = object["cc"] || [] mentioned = User.get_users_from_set(to ++ cc, local_only: false) @@ -822,7 +574,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end # TODO: we should probably send mtime instead of unix epoch time for updated - def add_emoji_tags(%{"emoji" => emoji} = object) do + defp add_emoji_tags(%{"emoji" => emoji} = object) do tags = object["tag"] || [] out = Enum.map(emoji, &build_emoji_tag/1) @@ -830,7 +582,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.put(object, "tag", tags ++ out) end - def add_emoji_tags(object), do: object + defp add_emoji_tags(object), do: object defp build_emoji_tag({name, url}) do %{ @@ -842,25 +594,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do } end - def set_conversation(object) do + defp set_conversation(object) do Map.put(object, "conversation", object["context"]) end - def set_type(%{"type" => "Answer"} = object) do + defp set_type(%{"type" => "Answer"} = object) do Map.put(object, "type", "Note") end - def set_type(object), do: object + defp set_type(object), do: object - def add_attributed_to(object) do + defp add_attributed_to(object) do attributed_to = object["attributedTo"] || object["actor"] Map.put(object, "attributedTo", attributed_to) end # TODO: Revisit this - def prepare_attachments(%{"type" => "ChatMessage"} = object), do: object + defp prepare_attachments(%{"type" => "ChatMessage"} = object), do: object - def prepare_attachments(object) do + defp prepare_attachments(object) do attachments = object |> Map.get("attachment", []) @@ -934,11 +686,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> User.update_and_set_cache() end - def maybe_fix_user_url(%{"url" => url} = data) when is_map(url) do + defp maybe_fix_user_url(%{"url" => url} = data) when is_map(url) do Map.put(data, "url", url["href"]) end - def maybe_fix_user_url(data), do: data + defp maybe_fix_user_url(data), do: data def maybe_fix_user_object(data), do: maybe_fix_user_url(data) end diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index 1846b2291..0a7674049 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -499,128 +499,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do end end - describe "fix_in_reply_to/2" do - setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) - - setup do - data = Jason.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) - [data: data] - end - - test "returns not modified object when hasn't containts inReplyTo field", %{data: data} do - assert Transmogrifier.fix_in_reply_to(data) == data - end - - test "returns object with inReplyTo when denied incoming reply", %{data: data} do - clear_config([:instance, :federation_incoming_replies_max_depth], 0) - - object_with_reply = - Map.put(data["object"], "inReplyTo", "https://shitposter.club/notice/2827873") - - modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) - assert modified_object["inReplyTo"] == "https://shitposter.club/notice/2827873" - - object_with_reply = - Map.put(data["object"], "inReplyTo", %{"id" => "https://shitposter.club/notice/2827873"}) - - modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) - assert modified_object["inReplyTo"] == %{"id" => "https://shitposter.club/notice/2827873"} - - object_with_reply = - Map.put(data["object"], "inReplyTo", ["https://shitposter.club/notice/2827873"]) - - modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) - assert modified_object["inReplyTo"] == ["https://shitposter.club/notice/2827873"] - - object_with_reply = Map.put(data["object"], "inReplyTo", []) - modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) - assert modified_object["inReplyTo"] == [] - end - - @tag capture_log: true - test "returns modified object when allowed incoming reply", %{data: data} do - object_with_reply = - Map.put( - data["object"], - "inReplyTo", - "https://mstdn.io/users/mayuutann/statuses/99568293732299394" - ) - - clear_config([:instance, :federation_incoming_replies_max_depth], 5) - modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) - - assert modified_object["inReplyTo"] == - "https://mstdn.io/users/mayuutann/statuses/99568293732299394" - - assert modified_object["context"] == - "tag:shitposter.club,2018-02-22:objectType=thread:nonce=e5a7c72d60a9c0e4" - end - end - - describe "fix_attachments/1" do - test "returns not modified object" do - data = Jason.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) - assert Transmogrifier.fix_attachments(data) == data - end - - test "returns modified object when attachment is map" do - assert Transmogrifier.fix_attachments(%{ - "attachment" => %{ - "mediaType" => "video/mp4", - "url" => "https://peertube.moe/stat-480.mp4" - } - }) == %{ - "attachment" => [ - %{ - "mediaType" => "video/mp4", - "type" => "Document", - "url" => [ - %{ - "href" => "https://peertube.moe/stat-480.mp4", - "mediaType" => "video/mp4", - "type" => "Link" - } - ] - } - ] - } - end - - test "returns modified object when attachment is list" do - assert Transmogrifier.fix_attachments(%{ - "attachment" => [ - %{"mediaType" => "video/mp4", "url" => "https://pe.er/stat-480.mp4"}, - %{"mimeType" => "video/mp4", "href" => "https://pe.er/stat-480.mp4"} - ] - }) == %{ - "attachment" => [ - %{ - "mediaType" => "video/mp4", - "type" => "Document", - "url" => [ - %{ - "href" => "https://pe.er/stat-480.mp4", - "mediaType" => "video/mp4", - "type" => "Link" - } - ] - }, - %{ - "mediaType" => "video/mp4", - "type" => "Document", - "url" => [ - %{ - "href" => "https://pe.er/stat-480.mp4", - "mediaType" => "video/mp4", - "type" => "Link" - } - ] - } - ] - } - end - end - describe "fix_emoji/1" do test "returns not modified object when object not contains tags" do data = Jason.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) @@ -652,48 +530,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do end end - describe "set_replies/1" do - setup do: clear_config([:activitypub, :note_replies_output_limit], 2) - - test "returns unmodified object if activity doesn't have self-replies" do - data = Jason.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) - assert Transmogrifier.set_replies(data) == data - end - - test "sets `replies` collection with a limited number of self-replies" do - [user, another_user] = insert_list(2, :user) - - {:ok, %{id: id1} = activity} = CommonAPI.post(user, %{status: "1"}) - - {:ok, %{id: id2} = self_reply1} = - CommonAPI.post(user, %{status: "self-reply 1", in_reply_to_status_id: id1}) - - {:ok, self_reply2} = - CommonAPI.post(user, %{status: "self-reply 2", in_reply_to_status_id: id1}) - - # Assuming to _not_ be present in `replies` due to :note_replies_output_limit is set to 2 - {:ok, _} = CommonAPI.post(user, %{status: "self-reply 3", in_reply_to_status_id: id1}) - - {:ok, _} = - CommonAPI.post(user, %{ - status: "self-reply to self-reply", - in_reply_to_status_id: id2 - }) - - {:ok, _} = - CommonAPI.post(another_user, %{ - status: "another user's reply", - in_reply_to_status_id: id1 - }) - - object = Object.normalize(activity, fetch: false) - replies_uris = Enum.map([self_reply1, self_reply2], fn a -> a.object.data["id"] end) - - assert %{"type" => "Collection", "items" => ^replies_uris} = - Transmogrifier.set_replies(object.data)["replies"] - end - end - test "take_emoji_tags/1" do user = insert(:user, %{emoji: %{"firefox" => "https://example.org/firefox.png"}}) diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index b5974d8f6..2dff6da65 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -12,12 +12,10 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.ActivityPub.Transmogrifier - alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI import Mock - import Pleroma.Factory import ExUnit.CaptureLog setup_all do @@ -425,91 +423,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do end end - describe "fix_explicit_addressing" do - setup do - user = insert(:user) - [user: user] - end - - test "moves non-explicitly mentioned actors to cc", %{user: user} do - explicitly_mentioned_actors = [ - "https://pleroma.gold/users/user1", - "https://pleroma.gold/user2" - ] - - object = %{ - "actor" => user.ap_id, - "to" => explicitly_mentioned_actors ++ ["https://social.beepboop.ga/users/dirb"], - "cc" => [], - "tag" => - Enum.map(explicitly_mentioned_actors, fn href -> - %{"type" => "Mention", "href" => href} - end) - } - - fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) - assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"])) - refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"] - assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"] - end - - test "does not move actor's follower collection to cc", %{user: user} do - object = %{ - "actor" => user.ap_id, - "to" => [user.follower_address], - "cc" => [] - } - - fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) - assert user.follower_address in fixed_object["to"] - refute user.follower_address in fixed_object["cc"] - end - - test "removes recipient's follower collection from cc", %{user: user} do - recipient = insert(:user) - - object = %{ - "actor" => user.ap_id, - "to" => [recipient.ap_id, "https://www.w3.org/ns/activitystreams#Public"], - "cc" => [user.follower_address, recipient.follower_address] - } - - fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) - - assert user.follower_address in fixed_object["cc"] - refute recipient.follower_address in fixed_object["cc"] - refute recipient.follower_address in fixed_object["to"] - end - end - - describe "fix_summary/1" do - test "returns fixed object" do - assert Transmogrifier.fix_summary(%{"summary" => nil}) == %{"summary" => ""} - assert Transmogrifier.fix_summary(%{"summary" => "ok"}) == %{"summary" => "ok"} - assert Transmogrifier.fix_summary(%{}) == %{"summary" => ""} - end - end - - describe "fix_url/1" do - test "fixes data for object when url is map" do - object = %{ - "url" => %{ - "type" => "Link", - "mimeType" => "video/mp4", - "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4" - } - } - - assert Transmogrifier.fix_url(object) == %{ - "url" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4" - } - end - - test "returns non-modified object" do - assert Transmogrifier.fix_url(%{"type" => "Text"}) == %{"type" => "Text"} - end - end - describe "get_obj_helper/2" do test "returns nil when cannot normalize object" do assert capture_log(fn ->