summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-01-28 16:14:23 +0000
committerlain <lain@soykaf.club>2020-01-28 16:14:23 +0000
commit10762ea2ac98cd27898af1d66bd5775bfeb15c5c (patch)
treed37b214ff074084c747cf7a7fa962cbf14e86f3c
parent271935953a384eb97606fb48d1b5c7befaf588e4 (diff)
parentd385789a450d455019c8aa6b6ee6abd28d5648e8 (diff)
Merge branch 'feature/tag_feed' into 'develop'
[#1452] Atom feeds for hashtags See merge request pleroma/pleroma!2040
-rw-r--r--CHANGELOG.md2
-rw-r--r--lib/pleroma/emails/admin_email.ex2
-rw-r--r--lib/pleroma/web/controller_helper.ex7
-rw-r--r--lib/pleroma/web/feed/feed_view.ex40
-rw-r--r--lib/pleroma/web/feed/tag_controller.ex41
-rw-r--r--lib/pleroma/web/feed/user_controller.ex (renamed from lib/pleroma/web/feed/feed_controller.ex)12
-rw-r--r--lib/pleroma/web/metadata/feed.ex2
-rw-r--r--lib/pleroma/web/metadata/utils.ex13
-rw-r--r--lib/pleroma/web/router.ex6
-rw-r--r--lib/pleroma/web/templates/feed/feed/_activity.xml.eex2
-rw-r--r--lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex51
-rw-r--r--lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex15
-rw-r--r--lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex18
-rw-r--r--lib/pleroma/web/templates/feed/feed/tag.atom.eex22
-rw-r--r--lib/pleroma/web/templates/feed/feed/tag.rss.eex15
-rw-r--r--lib/pleroma/web/templates/feed/feed/user.xml.eex (renamed from lib/pleroma/web/templates/feed/feed/feed.xml.eex)6
-rw-r--r--test/emails/admin_email_test.exs4
-rw-r--r--test/user_test.exs4
-rw-r--r--test/web/feed/tag_controller_test.exs154
-rw-r--r--test/web/feed/user_controller_test.exs (renamed from test/web/feed/feed_controller_test.exs)8
20 files changed, 397 insertions, 27 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d9f7d1b5..da211a1a1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -101,6 +101,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: Change emoji reaction reply format
- Notifications: Added `pleroma:emoji_reaction` notification type
- Mastodon API: Change emoji reaction reply format once more
+- Configuration: `feed.logo` option for tag feed.
+- Tag feed: `/tags/:tag.rss` - list public statuses by hashtag.
</details>
### Fixed
diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
index b15e4041b..d7dd4b2e0 100644
--- a/lib/pleroma/emails/admin_email.ex
+++ b/lib/pleroma/emails/admin_email.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.Emails.AdminEmail do
end
defp user_url(user) do
- Helpers.feed_url(Pleroma.Web.Endpoint, :feed_redirect, user.id)
+ Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, user.id)
end
def report(to, reporter, account, statuses, comment) do
diff --git a/lib/pleroma/web/controller_helper.ex b/lib/pleroma/web/controller_helper.ex
index 9a4e322c9..e3d7a465b 100644
--- a/lib/pleroma/web/controller_helper.ex
+++ b/lib/pleroma/web/controller_helper.ex
@@ -76,8 +76,7 @@ defmodule Pleroma.Web.ControllerHelper do
end
end
- def try_render(conn, target, params)
- when is_binary(target) do
+ def try_render(conn, target, params) when is_binary(target) do
case render(conn, target, params) do
nil -> render_error(conn, :not_implemented, "Can't display this activity")
res -> res
@@ -87,4 +86,8 @@ defmodule Pleroma.Web.ControllerHelper do
def try_render(conn, _, _) do
render_error(conn, :not_implemented, "Can't display this activity")
end
+
+ @spec put_in_if_exist(map(), atom() | String.t(), any) :: map()
+ def put_in_if_exist(map, _key, nil), do: map
+ def put_in_if_exist(map, key, value), do: put_in(map, key, value)
end
diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex
index bb1332fd3..334802e0a 100644
--- a/lib/pleroma/web/feed/feed_view.ex
+++ b/lib/pleroma/web/feed/feed_view.ex
@@ -13,21 +13,53 @@ defmodule Pleroma.Web.Feed.FeedView do
require Pleroma.Constants
- def prepare_activity(activity) do
+ @spec pub_date(String.t() | DateTime.t()) :: String.t()
+ def pub_date(date) when is_binary(date) do
+ date
+ |> Timex.parse!("{ISO:Extended}")
+ |> pub_date
+ end
+
+ def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}")
+
+ def prepare_activity(activity, opts \\ []) do
object = activity_object(activity)
+ actor =
+ if opts[:actor] do
+ Pleroma.User.get_cached_by_ap_id(activity.actor)
+ end
+
%{
activity: activity,
data: Map.get(object, :data),
- object: object
+ object: object,
+ actor: actor
}
end
+ def most_recent_update(activities) do
+ with %{updated_at: updated_at} <- List.first(activities) do
+ NaiveDateTime.to_iso8601(updated_at)
+ end
+ end
+
def most_recent_update(activities, user) do
(List.first(activities) || user).updated_at
|> NaiveDateTime.to_iso8601()
end
+ def feed_logo do
+ case Pleroma.Config.get([:feed, :logo]) do
+ nil ->
+ "#{Pleroma.Web.base_url()}/static/logo.png"
+
+ logo ->
+ "#{Pleroma.Web.base_url()}#{logo}"
+ end
+ |> MediaProxy.url()
+ end
+
def logo(user) do
user
|> User.avatar_url()
@@ -40,6 +72,8 @@ defmodule Pleroma.Web.Feed.FeedView do
def activity_title(%{data: %{"content" => content}}, opts \\ %{}) do
content
+ |> Pleroma.Web.Metadata.Utils.scrub_html()
+ |> Pleroma.Emoji.Formatter.demojify()
|> Formatter.truncate(opts[:max_length], opts[:omission])
|> escape()
end
@@ -50,6 +84,8 @@ defmodule Pleroma.Web.Feed.FeedView do
|> escape()
end
+ def activity_content(_), do: ""
+
def activity_context(activity), do: activity.data["context"]
def attachment_href(attachment) do
diff --git a/lib/pleroma/web/feed/tag_controller.ex b/lib/pleroma/web/feed/tag_controller.ex
new file mode 100644
index 000000000..9accd0872
--- /dev/null
+++ b/lib/pleroma/web/feed/tag_controller.ex
@@ -0,0 +1,41 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Feed.TagController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.Config
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.Feed.FeedView
+
+ import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3]
+
+ def feed(conn, %{"tag" => raw_tag} = params) do
+ {format, tag} = parse_tag(raw_tag)
+
+ activities =
+ %{"type" => ["Create"], "tag" => tag}
+ |> put_in_if_exist("max_id", params["max_id"])
+ |> ActivityPub.fetch_public_activities()
+
+ conn
+ |> put_resp_content_type("application/atom+xml")
+ |> put_view(FeedView)
+ |> render("tag.#{format}",
+ activities: activities,
+ tag: tag,
+ feed_config: Config.get([:feed])
+ )
+ end
+
+ @spec parse_tag(binary() | any()) :: {format :: String.t(), tag :: String.t()}
+ defp parse_tag(raw_tag) when is_binary(raw_tag) do
+ case Enum.reverse(String.split(raw_tag, ".")) do
+ [format | tag] when format in ["atom", "rss"] -> {format, Enum.join(tag, ".")}
+ _ -> {"rss", raw_tag}
+ end
+ end
+
+ defp parse_tag(raw_tag), do: {"rss", raw_tag}
+end
diff --git a/lib/pleroma/web/feed/feed_controller.ex b/lib/pleroma/web/feed/user_controller.ex
index acc0c3e6c..f5096834b 100644
--- a/lib/pleroma/web/feed/feed_controller.ex
+++ b/lib/pleroma/web/feed/user_controller.ex
@@ -2,13 +2,16 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
-defmodule Pleroma.Web.Feed.FeedController do
+defmodule Pleroma.Web.Feed.UserController do
use Pleroma.Web, :controller
alias Fallback.RedirectController
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.ActivityPubController
+ alias Pleroma.Web.Feed.FeedView
+
+ import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3]
plug(Pleroma.Plugs.SetFormatPlug when action in [:feed_redirect])
@@ -27,7 +30,7 @@ defmodule Pleroma.Web.Feed.FeedController do
def feed_redirect(conn, %{"nickname" => nickname}) do
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
- redirect(conn, external: "#{feed_url(conn, :feed, user.nickname)}.atom")
+ redirect(conn, external: "#{user_feed_url(conn, :feed, user.nickname)}.atom")
end
end
@@ -38,12 +41,13 @@ defmodule Pleroma.Web.Feed.FeedController do
"type" => ["Create"],
"actor_id" => user.ap_id
}
- |> Map.merge(Map.take(params, ["max_id"]))
+ |> put_in_if_exist("max_id", params["max_id"])
|> ActivityPub.fetch_public_activities()
conn
|> put_resp_content_type("application/atom+xml")
- |> render("feed.xml",
+ |> put_view(FeedView)
+ |> render("user.xml",
user: user,
activities: activities,
feed_config: Pleroma.Config.get([:feed])
diff --git a/lib/pleroma/web/metadata/feed.ex b/lib/pleroma/web/metadata/feed.ex
index 8043e6c54..ee48913a7 100644
--- a/lib/pleroma/web/metadata/feed.ex
+++ b/lib/pleroma/web/metadata/feed.ex
@@ -16,7 +16,7 @@ defmodule Pleroma.Web.Metadata.Providers.Feed do
[
rel: "alternate",
type: "application/atom+xml",
- href: Helpers.feed_path(Endpoint, :feed, user.nickname) <> ".atom"
+ href: Helpers.user_feed_path(Endpoint, :feed, user.nickname) <> ".atom"
], []}
]
end
diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex
index 589d11901..000bd9f66 100644
--- a/lib/pleroma/web/metadata/utils.ex
+++ b/lib/pleroma/web/metadata/utils.ex
@@ -21,15 +21,22 @@ defmodule Pleroma.Web.Metadata.Utils do
def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
content
+ |> scrub_html
+ |> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
+ |> Formatter.truncate(max_length)
+ end
+
+ def scrub_html(content) when is_binary(content) do
+ content
# html content comes from DB already encoded, decode first and scrub after
|> HtmlEntities.decode()
|> String.replace(~r/<br\s?\/?>/, " ")
|> HTML.strip_tags()
- |> Emoji.Formatter.demojify()
- |> HtmlEntities.decode()
- |> Formatter.truncate(max_length)
end
+ def scrub_html(content), do: content
+
def attachment_url(url) do
MediaProxy.url(url)
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index ef6e5a565..b5c1d85c7 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -527,8 +527,10 @@ defmodule Pleroma.Web.Router do
get("/notice/:id", OStatus.OStatusController, :notice)
get("/notice/:id/embed_player", OStatus.OStatusController, :notice_player)
- get("/users/:nickname/feed", Feed.FeedController, :feed)
- get("/users/:nickname", Feed.FeedController, :feed_redirect)
+ get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed)
+ get("/users/:nickname", Feed.UserController, :feed_redirect, as: :user_feed)
+
+ get("/tags/:tag", Feed.TagController, :feed, as: :tag_feed)
end
scope "/", Pleroma.Web do
diff --git a/lib/pleroma/web/templates/feed/feed/_activity.xml.eex b/lib/pleroma/web/templates/feed/feed/_activity.xml.eex
index 514eacaed..ac8a75009 100644
--- a/lib/pleroma/web/templates/feed/feed/_activity.xml.eex
+++ b/lib/pleroma/web/templates/feed/feed/_activity.xml.eex
@@ -9,7 +9,7 @@
<ostatus:conversation ref="<%= activity_context(@activity) %>">
<%= activity_context(@activity) %>
</ostatus:conversation>
- <link ref="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
+ <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
<%= if @data["summary"] do %>
<summary><%= @data["summary"] %></summary>
diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex
new file mode 100644
index 000000000..da4fa6d6c
--- /dev/null
+++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex
@@ -0,0 +1,51 @@
+<entry>
+ <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
+ <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+
+ <%= render @view_module, "_tag_author.atom", assigns %>
+
+ <id><%= @data["id"] %></id>
+ <title><%= activity_title(@object, Keyword.get(@feed_config, :post_title, %{})) %></title>
+ <content type="html"><%= activity_content(@object) %></content>
+
+ <%= if @activity.local do %>
+ <link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/>
+ <link type="text/html" href='<%= @data["id"] %>' rel="alternate"/>
+ <% else %>
+ <link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
+ <% end %>
+
+ <published><%= @data["published"] %></published>
+ <updated><%= @data["published"] %></updated>
+
+ <ostatus:conversation ref="<%= activity_context(@activity) %>">
+ <%= activity_context(@activity) %>
+ </ostatus:conversation>
+ <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
+
+ <%= if @data["summary"] do %>
+ <summary><%= @data["summary"] %></summary>
+ <% end %>
+
+ <%= for id <- @activity.recipients do %>
+ <%= if id == Pleroma.Constants.as_public() do %>
+ <link rel="mentioned"
+ ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"
+ href="http://activityschema.org/collection/public"/>
+ <% else %>
+ <%= unless Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) do %>
+ <link rel="mentioned"
+ ostatus:object-type="http://activitystrea.ms/schema/1.0/person"
+ href="<%= id %>" />
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <%= for tag <- @data["tag"] || [] do %>
+ <category term="<%= tag %>"></category>
+ <% end %>
+
+ <%= for {emoji, file} <- @data["emoji"] || %{} do %>
+ <link name="<%= emoji %>" rel="emoji" href="<%= file %>"/>
+ <% end %>
+</entry>
diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex
new file mode 100644
index 000000000..295574df1
--- /dev/null
+++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex
@@ -0,0 +1,15 @@
+<item>
+ <title><%= activity_title(@object, Keyword.get(@feed_config, :post_title, %{})) %></title>
+
+
+ <guid isPermalink="true"><%= activity_context(@activity) %></guid>
+ <link><%= activity_context(@activity) %></link>
+ <pubDate><%= pub_date(@data["published"]) %></pubDate>
+
+ <description><%= activity_content(@object) %></description>
+ <%= for attachment <- @data["attachment"] || [] do %>
+ <enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>
+ <% end %>
+
+</item>
+
diff --git a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex
new file mode 100644
index 000000000..997c4936e
--- /dev/null
+++ b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex
@@ -0,0 +1,18 @@
+<author>
+ <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
+ <id><%= @actor.ap_id %></id>
+ <uri><%= @actor.ap_id %></uri>
+ <name><%= @actor.nickname %></name>
+ <summary><%= escape(@actor.bio) %></summary>
+ <link rel="avatar" href="<%= User.avatar_url(@actor) %>"/>
+ <%= if User.banner_url(@actor) do %>
+ <link rel="header" href="<%= User.banner_url(@actor) %>"/>
+ <% end %>
+ <%= if @actor.local do %>
+ <ap_enabled>true</ap_enabled>
+ <% end %>
+
+ <poco:preferredUsername><%= @actor.nickname %></poco:preferredUsername>
+ <poco:displayName><%= @actor.name %></poco:displayName>
+ <poco:note><%= escape(@actor.bio) %></poco:note>
+</author>
diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex
new file mode 100644
index 000000000..a288539ed
--- /dev/null
+++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"
+ xmlns:thr="http://purl.org/syndication/thread/1.0"
+ xmlns:georss="http://www.georss.org/georss"
+ xmlns:activity="http://activitystrea.ms/spec/1.0/"
+ xmlns:media="http://purl.org/syndication/atommedia"
+ xmlns:poco="http://portablecontacts.net/spec/1.0"
+ xmlns:ostatus="http://ostatus.org/schema/1.0"
+ xmlns:statusnet="http://status.net/schema/api/1/">
+
+ <id><%= '#{tag_feed_url(@conn, :feed, @tag)}.rss' %></id>
+ <title>#<%= @tag %></title>
+
+ <subtitle>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</subtitle>
+ <logo><%= feed_logo() %></logo>
+ <updated><%= most_recent_update(@activities) %></updated>
+ <link rel="self" href="<%= '#{tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>
+ <%= for activity <- @activities do %>
+ <%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
+ <% end %>
+</feed>
diff --git a/lib/pleroma/web/templates/feed/feed/tag.rss.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex
new file mode 100644
index 000000000..eeda01a04
--- /dev/null
+++ b/lib/pleroma/web/templates/feed/feed/tag.rss.eex
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0" xmlns:webfeeds="http://webfeeds.org/rss/1.0">
+ <channel>
+
+
+ <title>#<%= @tag %></title>
+ <description>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</description>
+ <link><%= '#{tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
+ <webfeeds:logo><%= feed_logo() %></webfeeds:logo>
+ <webfeeds:accentColor>2b90d9</webfeeds:accentColor>
+ <%= for activity <- @activities do %>
+ <%= render @view_module, "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %>
+ <% end %>
+ </channel>
+</rss>
diff --git a/lib/pleroma/web/templates/feed/feed/feed.xml.eex b/lib/pleroma/web/templates/feed/feed/user.xml.eex
index 5ae36d345..d274c08ae 100644
--- a/lib/pleroma/web/templates/feed/feed/feed.xml.eex
+++ b/lib/pleroma/web/templates/feed/feed/user.xml.eex
@@ -6,16 +6,16 @@
xmlns:poco="http://portablecontacts.net/spec/1.0"
xmlns:ostatus="http://ostatus.org/schema/1.0">
- <id><%= feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
+ <id><%= user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
<title><%= @user.nickname <> "'s timeline" %></title>
<updated><%= most_recent_update(@activities, @user) %></updated>
<logo><%= logo(@user) %></logo>
- <link rel="self" href="<%= '#{feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
+ <link rel="self" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
<%= render @view_module, "_author.xml", assigns %>
<%= if last_activity(@activities) do %>
- <link rel="next" href="<%= '#{feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
+ <link rel="next" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
<% end %>
<%= for activity <- @activities do %>
diff --git a/test/emails/admin_email_test.exs b/test/emails/admin_email_test.exs
index ad89f9213..383cc3459 100644
--- a/test/emails/admin_email_test.exs
+++ b/test/emails/admin_email_test.exs
@@ -19,8 +19,8 @@ defmodule Pleroma.Emails.AdminEmailTest do
AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12")
- reporter_url = Helpers.feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id)
- account_url = Helpers.feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
+ reporter_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id)
+ account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}
diff --git a/test/user_test.exs b/test/user_test.exs
index 158f98e66..1b5e63bd4 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -585,7 +585,7 @@ defmodule Pleroma.UserTest do
user = insert(:user)
assert User.ap_id(user) ==
- Pleroma.Web.Router.Helpers.feed_url(
+ Pleroma.Web.Router.Helpers.user_feed_url(
Pleroma.Web.Endpoint,
:feed_redirect,
user.nickname
@@ -596,7 +596,7 @@ defmodule Pleroma.UserTest do
user = insert(:user)
assert User.ap_followers(user) ==
- Pleroma.Web.Router.Helpers.feed_url(
+ Pleroma.Web.Router.Helpers.user_feed_url(
Pleroma.Web.Endpoint,
:feed_redirect,
user.nickname
diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs
new file mode 100644
index 000000000..2aa1b9587
--- /dev/null
+++ b/test/web/feed/tag_controller_test.exs
@@ -0,0 +1,154 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Feed.TagControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+ import SweetXml
+
+ alias Pleroma.Web.Feed.FeedView
+
+ clear_config([:feed])
+
+ test "gets a feed (ATOM)", %{conn: conn} do
+ Pleroma.Config.put(
+ [:feed, :post_title],
+ %{max_length: 25, omission: "..."}
+ )
+
+ user = insert(:user)
+ {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
+
+ object = Pleroma.Object.normalize(activity1)
+
+ object_data =
+ Map.put(object.data, "attachment", [
+ %{
+ "url" => [
+ %{
+ "href" =>
+ "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
+ ]
+ }
+ ])
+
+ object
+ |> Ecto.Changeset.change(data: object_data)
+ |> Pleroma.Repo.update()
+
+ {:ok, _activity2} =
+ Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
+
+ {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"})
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/atom+xml")
+ |> get(tag_feed_path(conn, :feed, "pleromaart.atom"))
+ |> response(200)
+
+ xml = parse(response)
+
+ assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
+
+ assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
+ '42 This is :moominmamm...',
+ 'yeah #PleromaArt'
+ ]
+
+ assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
+ assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id]
+ end
+
+ test "gets a feed (RSS)", %{conn: conn} do
+ Pleroma.Config.put(
+ [:feed, :post_title],
+ %{max_length: 25, omission: "..."}
+ )
+
+ user = insert(:user)
+ {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
+
+ object = Pleroma.Object.normalize(activity1)
+
+ object_data =
+ Map.put(object.data, "attachment", [
+ %{
+ "url" => [
+ %{
+ "href" =>
+ "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
+ ]
+ }
+ ])
+
+ object
+ |> Ecto.Changeset.change(data: object_data)
+ |> Pleroma.Repo.update()
+
+ {:ok, activity2} =
+ Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
+
+ {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"})
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/rss+xml")
+ |> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
+ |> response(200)
+
+ xml = parse(response)
+ assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
+
+ assert xpath(xml, ~x"//channel/description/text()"s) ==
+ "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
+
+ assert xpath(xml, ~x"//channel/link/text()") ==
+ '#{Pleroma.Web.base_url()}/tags/pleromaart.rss'
+
+ assert xpath(xml, ~x"//channel/webfeeds:logo/text()") ==
+ '#{Pleroma.Web.base_url()}/static/logo.png'
+
+ assert xpath(xml, ~x"//channel/item/title/text()"l) == [
+ '42 This is :moominmamm...',
+ 'yeah #PleromaArt'
+ ]
+
+ assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
+ FeedView.pub_date(activity1.data["published"]),
+ FeedView.pub_date(activity2.data["published"])
+ ]
+
+ assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
+ "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
+ ]
+
+ obj1 = Pleroma.Object.normalize(activity1)
+ obj2 = Pleroma.Object.normalize(activity2)
+
+ assert xpath(xml, ~x"//channel/item/description/text()"sl) == [
+ HtmlEntities.decode(FeedView.activity_content(obj2)),
+ HtmlEntities.decode(FeedView.activity_content(obj1))
+ ]
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/atom+xml")
+ |> get(tag_feed_path(conn, :feed, "pleromaart"))
+ |> response(200)
+
+ xml = parse(response)
+ assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
+
+ assert xpath(xml, ~x"//channel/description/text()"s) ==
+ "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
+ end
+end
diff --git a/test/web/feed/feed_controller_test.exs b/test/web/feed/user_controller_test.exs
index 6f61acf43..41cc9e07e 100644
--- a/test/web/feed/feed_controller_test.exs
+++ b/test/web/feed/user_controller_test.exs
@@ -2,7 +2,7 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
-defmodule Pleroma.Web.Feed.FeedControllerTest do
+defmodule Pleroma.Web.Feed.UserControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
@@ -49,7 +49,7 @@ defmodule Pleroma.Web.Feed.FeedControllerTest do
resp =
conn
|> put_req_header("content-type", "application/atom+xml")
- |> get("/users/#{user.nickname}/feed.atom")
+ |> get(user_feed_path(conn, :feed, user.nickname))
|> response(200)
activity_titles =
@@ -65,7 +65,7 @@ defmodule Pleroma.Web.Feed.FeedControllerTest do
conn =
conn
|> put_req_header("content-type", "application/atom+xml")
- |> get("/users/nonexisting/feed.atom")
+ |> get(user_feed_path(conn, :feed, "nonexisting"))
assert response(conn, 404)
end
@@ -91,7 +91,7 @@ defmodule Pleroma.Web.Feed.FeedControllerTest do
response =
conn
|> put_req_header("accept", "application/xml")
- |> get("/users/jimm")
+ |> get(user_feed_path(conn, :feed, "jimm"))
|> response(404)
assert response == ~S({"error":"Not found"})