diff options
author | rinpatch <rinpatch@sdf.org> | 2019-01-18 18:31:25 +0300 |
---|---|---|
committer | rinpatch <rinpatch@sdf.org> | 2019-01-18 18:31:25 +0300 |
commit | 74346a7035d950ede143d65f8364194cb116aaf5 (patch) | |
tree | f058b3fc2edd6868511bc6f832f75374bdbd117e | |
parent | a38f21f51dc810221cbf910556910a10f6104956 (diff) | |
parent | 98d9dcd509ab6823e38b3ddbce1f5fc4f3d5a82c (diff) | |
download | pleroma-74346a7035d950ede143d65f8364194cb116aaf5.tar.gz |
Fix merge conflict
39 files changed, 559 insertions, 81 deletions
diff --git a/config/config.exs b/config/config.exs index 9c4d73465..e8cf2ed3a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -139,7 +139,8 @@ config :pleroma, :instance, finmoji_enabled: true, mrf_transparency: true, autofollowed_nicknames: [], - max_pinned_statuses: 1 + max_pinned_statuses: 1, + no_attachment_links: false config :pleroma, :markup, # XXX - unfortunately, inline images must be enabled by default right now, because diff --git a/docs/config.md b/docs/config.md index b9ad2aef7..5464fa90d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -95,6 +95,7 @@ config :pleroma, Pleroma.Mailer, older software for theses nicknames. * `max_pinned_statuses`: The maximum number of pinned statuses. `0` will disable the feature. * `autofollowed_nicknames`: Set to nicknames of (local) users that every new user should automatically follow. +* `no_attachment_links`: Set to true to disable automatically adding attachment link text to statuses ## :logger * `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index 46b84fb50..a24bb0e61 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -79,8 +79,10 @@ server { proxy_cache_valid 200 206 301 304 1h; proxy_cache_lock on; proxy_ignore_client_abort on; - proxy_buffering off; + proxy_buffering on; chunked_transfer_encoding on; + proxy_ignore_headers Cache-Control; + proxy_hide_header Cache-Control; proxy_pass http://localhost:4000; } } diff --git a/installation/pleroma.service b/installation/pleroma.service index f1ed56cb3..72090bbc7 100644 --- a/installation/pleroma.service +++ b/installation/pleroma.service @@ -3,15 +3,23 @@ Description=Pleroma social network After=network.target postgresql.service [Service] -User=pleroma -WorkingDirectory=/home/pleroma/pleroma -Environment="HOME=/home/pleroma" -Environment="MIX_ENV=prod" -ExecStart=/usr/local/bin/mix phx.server ExecReload=/bin/kill $MAINPID KillMode=process Restart=on-failure +; Name of the user that runs the Pleroma service. +User=pleroma +; Declares that Pleroma runs in production mode. +Environment="MIX_ENV=prod" + +; Make sure that all paths fit your installation. +; Path to the home directory of the user running the Pleroma service. +Environment="HOME=/home/pleroma" +; Path to the folder containing the Pleroma installation. +WorkingDirectory=/home/pleroma/pleroma +; Path to the Mix binary. +ExecStart=/usr/bin/mix phx.server + ; Some security directives. ; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops. PrivateTmp=true diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 2696f41c0..9e50ea3f4 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -155,7 +155,9 @@ defmodule Pleroma.Formatter do short_match = String.split(match, "@") |> tl() |> hd() {uuid, - "<span><a data-user='#{id}' class='mention' href='#{ap_id}'>@<span>#{short_match}</span></a></span>"} + "<span class='h-card'><a data-user='#{id}' class='u-url mention' href='#{ap_id}'>@<span>#{ + short_match + }</span></a></span>"} end) {subs, uuid_text} @@ -178,7 +180,7 @@ defmodule Pleroma.Formatter do subs ++ Enum.map(tags, fn {tag_text, tag, uuid} -> url = - "<a data-tag='#{tag}' href='#{Pleroma.Web.base_url()}/tag/#{tag}' rel='tag'>#{ + "<a class='hashtag' data-tag='#{tag}' href='#{Pleroma.Web.base_url()}/tag/#{tag}' rel='tag'>#{ tag_text }</a>" diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 0c5b0f03f..f5c6e5033 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -78,14 +78,14 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do # links Meta.allow_tag_with_uri_attributes("a", ["href", "data-user", "data-tag"], @valid_schemes) - Meta.allow_tag_with_these_attributes("a", ["name", "title"]) + Meta.allow_tag_with_these_attributes("a", ["name", "title", "class"]) # paragraphs and linebreaks Meta.allow_tag_with_these_attributes("br", []) Meta.allow_tag_with_these_attributes("p", []) # microformats - Meta.allow_tag_with_these_attributes("span", []) + Meta.allow_tag_with_these_attributes("span", ["class"]) # allow inline images for custom emoji @allow_inline_images Keyword.get(@markup, :allow_inline_images) @@ -119,7 +119,7 @@ defmodule Pleroma.HTML.Scrubber.Default do Meta.strip_comments() Meta.allow_tag_with_uri_attributes("a", ["href", "data-user", "data-tag"], @valid_schemes) - Meta.allow_tag_with_these_attributes("a", ["name", "title"]) + Meta.allow_tag_with_these_attributes("a", ["name", "title", "class"]) Meta.allow_tag_with_these_attributes("abbr", ["title"]) @@ -134,7 +134,7 @@ defmodule Pleroma.HTML.Scrubber.Default do Meta.allow_tag_with_these_attributes("ol", []) Meta.allow_tag_with_these_attributes("p", []) Meta.allow_tag_with_these_attributes("pre", []) - Meta.allow_tag_with_these_attributes("span", []) + Meta.allow_tag_with_these_attributes("span", ["class"]) Meta.allow_tag_with_these_attributes("strong", []) Meta.allow_tag_with_these_attributes("u", []) Meta.allow_tag_with_these_attributes("ul", []) diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex index b8103cef6..75c58e6c9 100644 --- a/lib/pleroma/http/http.ex +++ b/lib/pleroma/http/http.ex @@ -31,12 +31,15 @@ defmodule Pleroma.HTTP do process_request_options(options) |> process_sni_options(url) + params = Keyword.get(options, :params, []) + %{} |> Builder.method(method) |> Builder.headers(headers) |> Builder.opts(options) |> Builder.url(url) |> Builder.add_param(:body, :body, body) + |> Builder.add_param(:query, :query, params) |> Enum.into([]) |> (&Tesla.request(Connection.new(), &1)).() end diff --git a/lib/pleroma/http/request_builder.ex b/lib/pleroma/http/request_builder.ex index bffc7c6fe..5f2cff2c0 100644 --- a/lib/pleroma/http/request_builder.ex +++ b/lib/pleroma/http/request_builder.ex @@ -100,6 +100,8 @@ defmodule Pleroma.HTTP.RequestBuilder do Map """ @spec add_param(map(), atom, atom, any()) :: map() + def add_param(request, :query, :query, values), do: Map.put(request, :query, values) + def add_param(request, :body, :body, value), do: Map.put(request, :body, value) def add_param(request, :body, key, value) do @@ -107,7 +109,10 @@ defmodule Pleroma.HTTP.RequestBuilder do |> Map.put_new_lazy(:body, &Tesla.Multipart.new/0) |> Map.update!( :body, - &Tesla.Multipart.add_field(&1, key, Poison.encode!(value), + &Tesla.Multipart.add_field( + &1, + key, + Jason.encode!(value), headers: [{:"Content-Type", "application/json"}] ) ) diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index 8a030ecd0..b3566ceb6 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -34,10 +34,11 @@ defmodule Pleroma.Stats do peers = from( u in Pleroma.User, - select: fragment("distinct ?->'host'", u.info), + select: fragment("distinct split_part(?, '@', 2)", u.nickname), where: u.local != ^true ) |> Repo.all() + |> Enum.filter(& &1) domain_count = Enum.count(peers) @@ -45,7 +46,7 @@ defmodule Pleroma.Stats do from(u in User.local_user_query(), select: fragment("sum((?->>'note_count')::int)", u.info)) status_count = Repo.one(status_query) - user_count = Repo.aggregate(User.local_user_query(), :count, :id) + user_count = Repo.aggregate(User.active_local_user_query(), :count, :id) Agent.update(__MODULE__, fn _ -> {peers, %{domain_count: domain_count, status_count: status_count, user_count: user_count}} diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 0b1bdeec4..0a19e737b 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -34,8 +34,9 @@ defmodule Pleroma.Upload do require Logger @type source :: - Plug.Upload.t() | data_uri_string :: - String.t() | {:from_local, name :: String.t(), id :: String.t(), path :: String.t()} + Plug.Upload.t() + | (data_uri_string :: String.t()) + | {:from_local, name :: String.t(), id :: String.t(), path :: String.t()} @type option :: {:type, :avatar | :banner | :background} @@ -215,6 +216,12 @@ defmodule Pleroma.Upload do end defp url_from_spec(base_url, {:file, path}) do + path = + path + |> URI.encode() + |> String.replace("?", "%3F") + |> String.replace(":", "%3A") + [base_url, "media", path] |> Path.join() end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 13a476fd2..5137af917 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -822,7 +822,7 @@ defmodule Pleroma.User do update_and_set_cache(cng) end - def local_user_query() do + def local_user_query do from( u in User, where: u.local == true, @@ -830,7 +830,14 @@ defmodule Pleroma.User do ) end - def moderator_user_query() do + def active_local_user_query do + from( + u in local_user_query(), + where: fragment("?->'deactivated' @> 'false'", u.info) + ) + end + + def moderator_user_query do from( u in User, where: u.local == true, @@ -1066,4 +1073,14 @@ defmodule Pleroma.User do @strict_local_nickname_regex end end + + def error_user(ap_id) do + %User{ + name: ap_id, + ap_id: ap_id, + info: %User.Info{}, + nickname: "erroruser@example.com", + inserted_at: NaiveDateTime.utc_now() + } + end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 9c1eb377f..5b87f7462 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -515,15 +515,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_reblogs(query, _), do: query - # Only search through last 100_000 activities by default - defp restrict_recent(query, %{"whole_db" => true}), do: query - - defp restrict_recent(query, _) do - since = (Repo.aggregate(Activity, :max, :id) || 0) - 100_000 - - from(activity in query, where: activity.id > ^since) - end - defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do blocks = info.blocks || [] domain_blocks = info.domain_blocks || [] @@ -574,7 +565,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_actor(opts) |> restrict_type(opts) |> restrict_favorited_by(opts) - |> restrict_recent(opts) |> restrict_blocked(opts) |> restrict_media(opts) |> restrict_visibility(opts) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 73ca07e84..7eed0a600 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -54,6 +54,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def object_likes(conn, %{"uuid" => uuid, "page" => page}) do + with ap_id <- o_status_url(conn, :object, uuid), + %Object{} = object <- Object.get_cached_by_ap_id(ap_id), + {_, true} <- {:public?, ActivityPub.is_public?(object)}, + likes <- Utils.get_object_likes(object) do + {page, _} = Integer.parse(page) + + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(ObjectView.render("likes.json", ap_id, likes, page)) + else + {:public?, false} -> + {:error, :not_found} + end + end + + def object_likes(conn, %{"uuid" => uuid}) do + with ap_id <- o_status_url(conn, :object, uuid), + %Object{} = object <- Object.get_cached_by_ap_id(ap_id), + {_, true} <- {:public?, ActivityPub.is_public?(object)}, + likes <- Utils.get_object_likes(object) do + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(ObjectView.render("likes.json", ap_id, likes)) + else + {:public?, false} -> + {:error, :not_found} + end + end + def activity(conn, %{"uuid" => uuid}) do with ap_id <- o_status_url(conn, :activity, uuid), %Activity{} = activity <- Activity.normalize(ap_id), @@ -204,6 +234,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def handle_user_activity(user, %{"type" => "Like"} = params) do + with %Object{} = object <- Object.normalize(params["object"]), + {:ok, activity, _object} <- ActivityPub.like(user, object) do + {:ok, activity} + else + _ -> {:error, "Can't like object"} + end + end + def handle_user_activity(_, _) do {:error, "Unhandled activity type"} end diff --git a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex new file mode 100644 index 000000000..081456046 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex @@ -0,0 +1,29 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do + @behaviour Pleroma.Web.ActivityPub.MRF + + @impl true + def filter( + %{ + "type" => "Create", + "object" => %{"content" => content, "attachment" => _attachment} = child_object + } = object + ) + when content in [".", "<p>.</p>"] do + child_object = + child_object + |> Map.put("content", "") + + object = + object + |> Map.put("object", child_object) + + {:ok, object} + end + + @impl true + def filter(object), do: {:ok, object} +end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 87b7fc07f..86d11c874 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -629,6 +629,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> add_mention_tags |> add_emoji_tags |> add_attributed_to + |> add_likes |> prepare_attachments |> set_conversation |> set_reply_to_uri @@ -641,7 +642,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # internal -> Mastodon # """ - def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do + def prepare_outgoing(%{"type" => "Create", "object" => object} = data) do object = object |> prepare_object @@ -788,6 +789,22 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> Map.put("attributedTo", attributedTo) end + def add_likes(%{"id" => id, "like_count" => likes} = object) do + likes = %{ + "id" => "#{id}/likes", + "first" => "#{id}/likes?page=1", + "type" => "OrderedCollection", + "totalItems" => likes + } + + object + |> Map.put("likes", likes) + end + + def add_likes(object) do + object + end + def prepare_attachments(object) do attachments = (object["attachment"] || []) @@ -803,7 +820,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do defp strip_internal_fields(object) do object |> Map.drop([ - "likes", "like_count", "announcements", "announcement_count", diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index b313996db..6ecab773c 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -231,6 +231,27 @@ defmodule Pleroma.Web.ActivityPub.Utils do Repo.one(query) end + @doc """ + Returns like activities targeting an object + """ + def get_object_likes(%{data: %{"id" => id}}) do + query = + from( + activity in Activity, + # this is to use the index + where: + fragment( + "coalesce((?)->'object'->>'id', (?)->>'object') = ?", + activity.data, + activity.data, + ^id + ), + where: fragment("(?)->>'type' = 'Like'", activity.data) + ) + + Repo.all(query) + end + def make_like_data(%User{ap_id: ap_id} = actor, %{data: %{"id" => id}} = object, activity_id) do data = %{ "type" => "Like", diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index b5c9bf8d0..394d82fbc 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -35,4 +35,38 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do Map.merge(base, additional) end + + def render("likes.json", ap_id, likes, page) do + collection(likes, "#{ap_id}/likes", page) + |> Map.merge(Pleroma.Web.ActivityPub.Utils.make_json_ld_header()) + end + + def render("likes.json", ap_id, likes) do + %{ + "id" => "#{ap_id}/likes", + "type" => "OrderedCollection", + "totalItems" => length(likes), + "first" => collection(likes, "#{ap_id}/likes", 1) + } + |> Map.merge(Pleroma.Web.ActivityPub.Utils.make_json_ld_header()) + end + + def collection(collection, iri, page) do + offset = (page - 1) * 10 + items = Enum.slice(collection, offset, 10) + items = Enum.map(items, fn object -> Transmogrifier.prepare_object(object.data) end) + total = length(collection) + + map = %{ + "id" => "#{iri}?page=#{page}", + "type" => "OrderedCollectionPage", + "partOf" => iri, + "totalItems" => total, + "orderedItems" => items + } + + if offset < total do + Map.put(map, "next", "#{iri}?page=#{page + 1}") + end + end end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 9a748d65e..504670439 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -103,7 +103,14 @@ defmodule Pleroma.Web.CommonAPI do attachments, tags, get_content_type(data["content_type"]), - true + Enum.member?( + [true, "true"], + Map.get( + data, + "no_attachment_links", + Pleroma.Config.get([:instance, :no_attachment_links], false) + ) + ) ), context <- make_context(inReplyTo), cw <- data["spoiler_text"], diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e00a3fb87..daad89185 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -341,7 +341,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do params = params |> Map.put("in_reply_to_status_id", params["in_reply_to_id"]) - |> Map.put("no_attachment_links", true) idempotency_key = case get_req_header(conn, "idempotency-key") do @@ -824,9 +823,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, res) end - def favourites(%{assigns: %{user: user}} = conn, _) do + def favourites(%{assigns: %{user: user}} = conn, params) do params = - %{} + params |> Map.put("type", "Create") |> Map.put("favorited_by", user.ap_id) |> Map.put("blocking_user", user) @@ -836,6 +835,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> Enum.reverse() conn + |> add_link_headers(:favourites, activities) |> put_view(StatusView) |> render("index.json", %{activities: activities, for: user, as: :activity}) end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index db543ffe5..7f5a52ea3 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -32,6 +32,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end) end + defp get_user(ap_id) do + cond do + user = User.get_cached_by_ap_id(ap_id) -> + user + + user = User.get_by_guessed_nickname(ap_id) -> + user + + true -> + User.error_user(ap_id) + end + end + def render("index.json", opts) do replied_to_activities = get_replied_to_activities(opts.activities) @@ -48,7 +61,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do "status.json", %{activity: %{data: %{"type" => "Announce", "object" => object}} = activity} = opts ) do - user = User.get_cached_by_ap_id(activity.data["actor"]) + user = get_user(activity.data["actor"]) created_at = Utils.to_masto_date(activity.data["published"]) reblogged = Activity.get_create_activity_by_object_ap_id(object) @@ -93,7 +106,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end def render("status.json", %{activity: %{data: %{"object" => object}} = activity} = opts) do - user = User.get_cached_by_ap_id(activity.data["actor"]) + user = get_user(activity.data["actor"]) like_count = object["like_count"] || 0 announcement_count = object["announcement_count"] || 0 @@ -116,7 +129,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do created_at = Utils.to_masto_date(object["published"]) reply_to = get_reply_to(activity, opts) - reply_to_user = reply_to && User.get_cached_by_ap_id(reply_to.data["actor"]) + reply_to_user = reply_to && get_user(reply_to.data["actor"]) content = object diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index fe092bf19..6da83c6e4 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -1,5 +1,9 @@ defmodule Pleroma.Web.RichMedia.Parser do - @parsers [Pleroma.Web.RichMedia.Parsers.OGP, Pleroma.Web.RichMedia.Parsers.TwitterCard] + @parsers [ + Pleroma.Web.RichMedia.Parsers.OGP, + Pleroma.Web.RichMedia.Parsers.TwitterCard, + Pleroma.Web.RichMedia.Parsers.OEmbed + ] if Mix.env() == :test do def parse(url), do: parse_url(url) diff --git a/lib/pleroma/web/rich_media/parsers/oembed_parser.ex b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex new file mode 100644 index 000000000..ca7226faf --- /dev/null +++ b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex @@ -0,0 +1,27 @@ +defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do + def parse(html, _data) do + with elements = [_ | _] <- get_discovery_data(html), + {:ok, oembed_url} <- get_oembed_url(elements), + {:ok, oembed_data} <- get_oembed_data(oembed_url) do + {:ok, oembed_data} + else + _e -> {:error, "No OEmbed data found"} + end + end + + defp get_discovery_data(html) do + html |> Floki.find("link[type='application/json+oembed']") + end + + defp get_oembed_url(nodes) do + {"link", attributes, _children} = nodes |> hd() + + {:ok, Enum.into(attributes, %{})["href"]} + end + + defp get_oembed_data(url) do + {:ok, %Tesla.Env{body: json}} = Pleroma.HTTP.get(url) + + {:ok, Poison.decode!(json)} + end +end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 25e866c48..68b02d8ca 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -431,6 +431,7 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/followers", ActivityPubController, :followers) get("/users/:nickname/following", ActivityPubController, :following) get("/users/:nickname/outbox", ActivityPubController, :outbox) + get("/objects/:uuid/likes", ActivityPubController, :object_likes) end pipeline :activitypub_client do diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 108e7bfc5..03708d84c 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -101,20 +101,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do user true -> - error_user(ap_id) + User.error_user(ap_id) end end - defp error_user(ap_id) do - %User{ - name: ap_id, - ap_id: ap_id, - info: %User.Info{}, - nickname: "erroruser@example.com", - inserted_at: NaiveDateTime.utc_now() - } - end - def render("index.json", opts) do context_ids = collect_context_ids(opts.activities) users = collect_users(opts.activities) diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index 3a287edd9..7ca62c83b 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -121,6 +121,12 @@ defmodule Pleroma.Web.Websub do end end + def incoming_subscription_request(user, params) do + Logger.info("Unhandled WebSub request for #{user.nickname}: #{inspect(params)}") + + {:error, "Invalid WebSub request"} + end + defp get_subscription(topic, callback) do Repo.get_by(WebsubServerSubscription, topic: topic, callback: callback) || %WebsubServerSubscription{} diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex index 27304d988..e58f144e5 100644 --- a/lib/pleroma/web/websub/websub_controller.ex +++ b/lib/pleroma/web/websub/websub_controller.ex @@ -67,6 +67,13 @@ defmodule Pleroma.Web.Websub.WebsubController do end end + def websub_subscription_confirmation(conn, params) do + Logger.info("Invalid WebSub confirmation request: #{inspect(params)}") + + conn + |> send_resp(500, "Invalid parameters") + end + def websub_incoming(conn, %{"id" => id}) do with "sha1=" <> signature <- hd(get_req_header(conn, "x-hub-signature")), signature <- String.downcase(signature), diff --git a/test/fixtures/rich_media/oembed.html b/test/fixtures/rich_media/oembed.html new file mode 100644 index 000000000..55f17004b --- /dev/null +++ b/test/fixtures/rich_media/oembed.html @@ -0,0 +1,3 @@ +<link rel="alternate" type="application/json+oembed" + href="http://example.com/oembed.json" + title="Bacon Lollys oEmbed Profile" /> diff --git a/test/fixtures/rich_media/oembed.json b/test/fixtures/rich_media/oembed.json new file mode 100644 index 000000000..2a5f7a771 --- /dev/null +++ b/test/fixtures/rich_media/oembed.json @@ -0,0 +1 @@ +{"type":"photo","flickr_type":"photo","title":"Bacon Lollys","author_name":"\u202e\u202d\u202cbees\u202c","author_url":"https:\/\/www.flickr.com\/photos\/bees\/","width":"1024","height":"768","url":"https:\/\/farm4.staticflickr.com\/3040\/2362225867_4a87ab8baf_b.jpg","web_page":"https:\/\/www.flickr.com\/photos\/bees\/2362225867\/","thumbnail_url":"https:\/\/farm4.staticflickr.com\/3040\/2362225867_4a87ab8baf_q.jpg","thumbnail_width":150,"thumbnail_height":150,"web_page_short_url":"https:\/\/flic.kr\/p\/4AK2sc","license":"All Rights Reserved","license_id":0,"html":"<a data-flickr-embed=\"true\" href=\"https:\/\/www.flickr.com\/photos\/bees\/2362225867\/\" title=\"Bacon Lollys by \u202e\u202d\u202cbees\u202c, on Flickr\"><img src=\"https:\/\/farm4.staticflickr.com\/3040\/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"><\/a><script async src=\"https:\/\/embedr.flickr.com\/assets\/client-code.js\" charset=\"utf-8\"><\/script>","version":"1.0","cache_age":3600,"provider_name":"Flickr","provider_url":"https:\/\/www.flickr.com\/"} diff --git a/test/formatter_test.exs b/test/formatter_test.exs index c76149e38..bd8844458 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -19,7 +19,7 @@ defmodule Pleroma.FormatterTest do text = "I love #cofe and #2hu" expected_text = - "I love <a data-tag='cofe' href='http://localhost:4001/tag/cofe' rel='tag'>#cofe</a> and <a data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a>" + "I love <a class='hashtag' data-tag='cofe' href='http://localhost:4001/tag/cofe' rel='tag'>#cofe</a> and <a class='hashtag' data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a>" tags = Formatter.parse_tags(text) @@ -31,7 +31,7 @@ defmodule Pleroma.FormatterTest do text = "Fact #3: pleroma does what mastodon't" expected_text = - "Fact <a data-tag='3' href='http://localhost:4001/tag/3' rel='tag'>#3</a>: pleroma does what mastodon't" + "Fact <a class='hashtag' data-tag='3' href='http://localhost:4001/tag/3' rel='tag'>#3</a>: pleroma does what mastodon't" tags = Formatter.parse_tags(text) @@ -144,11 +144,13 @@ defmodule Pleroma.FormatterTest do Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end) expected_text = - "<span><a data-user='#{gsimg.id}' class='mention' href='#{gsimg.ap_id}'>@<span>gsimg</span></a></span> According to <span><a data-user='#{ + "<span class='h-card'><a data-user='#{gsimg.id}' class='u-url mention' href='#{ + gsimg.ap_id + }'>@<span>gsimg</span></a></span> According to <span class='h-card'><a data-user='#{ archaeme.id - }' class='mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span><a data-user='#{ + }' class='u-url mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class='h-card'><a data-user='#{ archaeme_remote.id - }' class='mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme</span></a></span>" + }' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme</span></a></span>" assert expected_text == Formatter.finalize({subs, text}) end @@ -166,7 +168,7 @@ defmodule Pleroma.FormatterTest do Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end) expected_text = - "<span><a data-user='#{mike.id}' class='mention' href='#{mike.ap_id}'>@<span>mike</span></a></span> test" + "<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike</span></a></span> test" assert expected_text == Formatter.finalize({subs, text}) end @@ -183,7 +185,7 @@ defmodule Pleroma.FormatterTest do Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end) expected_text = - "<span><a data-user='#{o.id}' class='mention' href='#{o.ap_id}'>@<span>o</span></a></span> hi" + "<span class='h-card'><a data-user='#{o.id}' class='u-url mention' href='#{o.ap_id}'>@<span>o</span></a></span> hi" assert expected_text == Formatter.finalize({subs, text}) end diff --git a/test/support/factory.ex b/test/support/factory.ex index 57fa4a79d..4ac77981a 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -57,6 +57,11 @@ defmodule Pleroma.Factory do %Pleroma.Object{data: Map.merge(data, %{"to" => [user2.ap_id]})} end + def article_factory do + note_factory() + |> Map.put("type", "Article") + end + def tombstone_factory do data = %{ "type" => "Tombstone", @@ -110,6 +115,26 @@ defmodule Pleroma.Factory do } end + def article_activity_factory do + article = insert(:article) + + data = %{ + "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), + "type" => "Create", + "actor" => article.data["actor"], + "to" => article.data["to"], + "object" => article.data, + "published" => DateTime.utc_now() |> DateTime.to_iso8601(), + "context" => article.data["context"] + } + + %Pleroma.Activity{ + data: data, + actor: data["actor"], + recipients: data["to"] + } + end + def announce_activity_factory do note_activity = insert(:note_activity) user = insert(:user) diff --git a/test/upload_test.exs b/test/upload_test.exs index d4ea3a573..b2d9eca38 100644 --- a/test/upload_test.exs +++ b/test/upload_test.exs @@ -137,5 +137,35 @@ defmodule Pleroma.UploadTest do refute data["name"] == "an [image.jpg" end + + test "escapes invalid characters in url" do + File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") + + file = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image_tmp.jpg"), + filename: "an… image.jpg" + } + + {:ok, data} = Upload.store(file) + [attachment_url | _] = data["url"] + + assert Path.basename(attachment_url["href"]) == "an%E2%80%A6%20image.jpg" + end + + test "replaces : (colon) and ? (question-mark) to %3A and %3F (respectively)" do + File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") + + file = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image_tmp.jpg"), + filename: "is:an?image.jpg" + } + + {:ok, data} = Upload.store(file) + [attachment_url | _] = data["url"] + + assert Path.basename(attachment_url["href"]) == "is%3Aan%3Fimage.jpg" + end end end diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 7aed8c71d..52e67f046 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -89,6 +89,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end end + describe "/object/:uuid/likes" do + test "it returns the like activities in a collection", %{conn: conn} do + like = insert(:like_activity) + uuid = String.split(like.data["object"], "/") |> List.last() + + result = + conn + |> put_req_header("accept", "application/activity+json") + |> get("/objects/#{uuid}/likes") + |> json_response(200) + + assert List.first(result["first"]["orderedItems"])["id"] == like.data["id"] + end + end + describe "/activities/:uuid" do test "it returns a json representation of the activity", %{conn: conn} do activity = insert(:note_activity) @@ -292,6 +307,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert json_response(conn, 400) end + + test "it increases like count when receiving a like action", %{conn: conn} do + note_activity = insert(:note_activity) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + data = %{ + type: "Like", + object: %{ + id: note_activity.data["object"]["id"] + } + } + + conn = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/outbox", data) + + result = json_response(conn, 201) + assert Activity.get_by_ap_id(result["id"]) + + object = Object.get_by_ap_id(note_activity.data["object"]["id"]) + assert object + assert object.data["like_count"] == 1 + end end describe "/users/:nickname/followers" do diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index a5fd87ed4..87d0ab559 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -829,12 +829,33 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert length(modified["object"]["tag"]) == 2 assert is_nil(modified["object"]["emoji"]) - assert is_nil(modified["object"]["likes"]) assert is_nil(modified["object"]["like_count"]) assert is_nil(modified["object"]["announcements"]) assert is_nil(modified["object"]["announcement_count"]) assert is_nil(modified["object"]["context_id"]) end + + test "it strips internal fields of article" do + activity = insert(:article_activity) + + {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + + assert length(modified["object"]["tag"]) == 2 + + assert is_nil(modified["object"]["emoji"]) + assert is_nil(modified["object"]["like_count"]) + assert is_nil(modified["object"]["announcements"]) + assert is_nil(modified["object"]["announcement_count"]) + assert is_nil(modified["object"]["context_id"]) + end + + test "it adds like collection to object" do + activity = insert(:note_activity) + {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + + assert modified["object"]["likes"]["type"] == "OrderedCollection" + assert modified["object"]["likes"]["totalItems"] == 0 + end end describe "user upgrade" do diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index b448d13f5..dd84052a3 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -386,7 +386,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do |> assign(:user, user) |> get("/api/v1/filters/#{filter.filter_id}") - assert response = json_response(conn, 200) + assert _response = json_response(conn, 200) end test "update a filter", %{conn: conn} do @@ -600,7 +600,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do |> get("/api/v1/notifications") expected_response = - "hi <span><a data-user=\"#{user.id}\" href=\"#{user.ap_id}\">@<span>#{user.nickname}</span></a></span>" + "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{ + user.ap_id + }\">@<span>#{user.nickname}</span></a></span>" assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200) assert response == expected_response @@ -621,7 +623,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do |> get("/api/v1/notifications/#{notification.id}") expected_response = - "hi <span><a data-user=\"#{user.id}\" href=\"#{user.ap_id}\">@<span>#{user.nickname}</span></a></span>" + "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{ + user.ap_id + }\">@<span>#{user.nickname}</span></a></span>" assert %{"status" => %{"content" => response}} = json_response(conn, 200) assert response == expected_response @@ -1349,13 +1353,42 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do {:ok, _, _} = CommonAPI.favorite(activity.id, user) - conn = + first_conn = conn |> assign(:user, user) |> get("/api/v1/favourites") - assert [status] = json_response(conn, 200) + assert [status] = json_response(first_conn, 200) assert status["id"] == to_string(activity.id) + + assert [{"link", _link_header}] = + Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end) + + # Honours query params + {:ok, second_activity} = + CommonAPI.post(other_user, %{ + "status" => + "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful." + }) + + {:ok, _, _} = CommonAPI.favorite(second_activity.id, user) + + last_like = status["id"] + + second_conn = + conn + |> assign(:user, user) + |> get("/api/v1/favourites?since_id=#{last_like}") + + assert [second_status] = json_response(second_conn, 200) + assert second_status["id"] == to_string(second_activity.id) + + third_conn = + conn + |> assign(:user, user) + |> get("/api/v1/favourites?limit=0") + + assert [] = json_response(third_conn, 200) end describe "updating credentials" do @@ -1373,9 +1406,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert user = json_response(conn, 200) assert user["note"] == - "I drink <a data-tag=\"cofe\" href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span><a data-user=\"#{ + "I drink <a class=\"hashtag\" data-tag=\"cofe\" href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span class=\"h-card\"><a data-user=\"#{ user2.id - }\" href=\"#{user2.ap_id}\">@<span>#{user2.nickname}</span></a></span>" + }\" class=\"u-url mention\" href=\"#{user2.ap_id}\">@<span>#{user2.nickname}</span></a></span>" end test "updates the user's locking status", %{conn: conn} do @@ -1440,22 +1473,41 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do end test "get instance information", %{conn: conn} do - insert(:user, %{local: true}) user = insert(:user, %{local: true}) - insert(:user, %{local: false}) + + user2 = insert(:user, %{local: true}) + {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated) + + insert(:user, %{local: false, nickname: "u@peer1.com"}) + insert(:user, %{local: false, nickname: "u@peer2.com"}) {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"}) Pleroma.Stats.update_stats() - conn = - conn - |> get("/api/v1/instance") + conn = get(conn, "/api/v1/instance") + + assert result = json_response(conn, 200) + + stats = result["stats"] + + assert stats + assert stats["user_count"] == 1 + assert stats["status_count"] == 1 + assert stats["domain_count"] == 2 + end + + test "get peers", %{conn: conn} do + insert(:user, %{local: false, nickname: "u@peer1.com"}) + insert(:user, %{local: false, nickname: "u@peer2.com"}) + + Pleroma.Stats.update_stats() + + conn = get(conn, "/api/v1/instance/peers") assert result = json_response(conn, 200) - assert result["stats"]["user_count"] == 2 - assert result["stats"]["status_count"] == 1 + assert ["peer1.com", "peer2.com"] == Enum.sort(result) end test "put settings", %{conn: conn} do @@ -1466,7 +1518,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do |> assign(:user, user) |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) - assert result = json_response(conn, 200) + assert _result = json_response(conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert user.info.settings == %{"programming" => "socks"} diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index 1076b5002..d30ae6149 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -19,6 +19,36 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do :ok end + test "returns a temporary ap_id based user for activities missing db users" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + Repo.delete(user) + Cachex.clear(:user_cache) + + %{account: ms_user} = StatusView.render("status.json", activity: activity) + + assert ms_user.acct == "erroruser@example.com" + end + + test "tries to get a user by nickname if fetching by ap_id doesn't work" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + {:ok, user} = + user + |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"}) + |> Repo.update() + + Cachex.clear(:user_cache) + + result = StatusView.render("status.json", activity: activity) + + assert result[:account][:id] == to_string(user.id) + end + test "a note with null content" do note = insert(:note_activity) diff --git a/test/web/rich_media/parser_test.exs b/test/web/rich_media/parser_test.exs index ff3486a6d..e14b5061a 100644 --- a/test/web/rich_media/parser_test.exs +++ b/test/web/rich_media/parser_test.exs @@ -15,6 +15,18 @@ defmodule Pleroma.Web.RichMedia.ParserTest do } -> %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")} + %{ + method: :get, + url: "http://example.com/oembed" + } -> + %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.html")} + + %{ + method: :get, + url: "http://example.com/oembed.json" + } -> + %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.json")} + %{method: :get, url: "http://example.com/empty"} -> %Tesla.Env{status: 200, body: "hello"} end) @@ -48,4 +60,33 @@ defmodule Pleroma.Web.RichMedia.ParserTest do description: "View the album on Flickr." }} end + + test "parses OEmbed" do + assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/oembed") == + {:ok, + %{ + "author_name" => "bees", + "author_url" => "https://www.flickr.com/photos/bees/", + "cache_age" => 3600, + "flickr_type" => "photo", + "height" => "768", + "html" => + "<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by bees, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>", + "license" => "All Rights Reserved", + "license_id" => 0, + "provider_name" => "Flickr", + "provider_url" => "https://www.flickr.com/", + "thumbnail_height" => 150, + "thumbnail_url" => + "https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg", + "thumbnail_width" => 150, + "title" => "Bacon Lollys", + "type" => "photo", + "url" => "https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg", + "version" => "1.0", + "web_page" => "https://www.flickr.com/photos/bees/2362225867/", + "web_page_short_url" => "https://flic.kr/p/4AK2sc", + "width" => "1024" + }} + end end diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 5f13e7959..e08edc525 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -1357,9 +1357,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do assert user.name == "new name" assert user.bio == - "hi <span><a data-user='#{user2.id}' class='mention' href='#{user2.ap_id}'>@<span>#{ - user2.nickname - }</span></a></span>" + "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{ + user2.ap_id + }'>@<span>#{user2.nickname}</span></a></span>" assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) end diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index b9feb23d4..547592ff2 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -38,7 +38,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do {:ok, activity = %Activity{}} = TwitterAPI.create_status(user, input) expected_text = - "Hello again, <span><a data-user='#{mentioned_user.id}' class='mention' href='shp'>@<span>shp</span></a></span>.<script></script><br>This is on another :moominmamma: line. <a data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a> <a data-tag='epic' href='http://localhost:4001/tag/epic' rel='tag'>#epic</a> <a data-tag='phantasmagoric' href='http://localhost:4001/tag/phantasmagoric' rel='tag'>#phantasmagoric</a><br><a href=\"http://example.org/image.jpg\" class='attachment'>image.jpg</a>" + "Hello again, <span class='h-card'><a data-user='#{mentioned_user.id}' class='u-url mention' href='shp'>@<span>shp</span></a></span>.<script></script><br>This is on another :moominmamma: line. <a class='hashtag' data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a> <a class='hashtag' data-tag='epic' href='http://localhost:4001/tag/epic' rel='tag'>#epic</a> <a class='hashtag' data-tag='phantasmagoric' href='http://localhost:4001/tag/phantasmagoric' rel='tag'>#phantasmagoric</a><br><a href=\"http://example.org/image.jpg\" class='attachment'>image.jpg</a>" assert get_in(activity.data, ["object", "content"]) == expected_text assert get_in(activity.data, ["object", "type"]) == "Note" @@ -328,7 +328,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do {:ok, user2} = TwitterAPI.register_user(data2) expected_text = - "<span><a data-user='#{user1.id}' class='mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test" + "<span class='h-card'><a data-user='#{user1.id}' class='u-url mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test" assert user2.bio == expected_text end diff --git a/test/web/twitter_api/views/activity_view_test.exs b/test/web/twitter_api/views/activity_view_test.exs index 8b5a16add..3d6b264b1 100644 --- a/test/web/twitter_api/views/activity_view_test.exs +++ b/test/web/twitter_api/views/activity_view_test.exs @@ -66,7 +66,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do result = ActivityView.render("activity.json", activity: activity) assert result["statusnet_html"] == - "<a data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\">#cycling</a> <a data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\">#CHScycling</a> <a data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\">#commute</a><br />MVIMG_20181211_054020.jpg" + "<a class=\"hashtag\" data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a class=\"hashtag\" data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\">#cycling</a> <a class=\"hashtag\" data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\">#CHScycling</a> <a class=\"hashtag\" data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\">#commute</a><br />MVIMG_20181211_054020.jpg" assert result["text"] == "#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg" @@ -141,7 +141,9 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do "summary" => "", "summary_html" => "", "statusnet_html" => - "Hey <span><a data-user=\"#{other_user.id}\" href=\"#{other_user.ap_id}\">@<span>shp</span></a></span>!", + "Hey <span class=\"h-card\"><a data-user=\"#{other_user.id}\" class=\"u-url mention\" href=\"#{ + other_user.ap_id + }\">@<span>shp</span></a></span>!", "tags" => [], "text" => "Hey @shp!", "uri" => activity.data["object"]["id"], |