Merge branch 'preload-data' into 'develop'

Preload data into index.html

Closes #1660

See merge request pleroma/pleroma!2381
This commit is contained in:
feld 2020-06-25 21:35:39 +00:00
commit 8288419686
20 changed files with 608 additions and 161 deletions

View file

@ -434,6 +434,14 @@
],
unfurl_nsfw: false
config :pleroma, Pleroma.Web.Preload,
providers: [
Pleroma.Web.Preload.Providers.Instance,
Pleroma.Web.Preload.Providers.User,
Pleroma.Web.Preload.Providers.Timelines,
Pleroma.Web.Preload.Providers.StatusNet
]
config :pleroma, :http_security,
enabled: true,
sts: false,

View file

@ -9,6 +9,7 @@ defmodule Fallback.RedirectController do
alias Pleroma.User
alias Pleroma.Web.Metadata
alias Pleroma.Web.Preload
def api_not_implemented(conn, _params) do
conn
@ -16,16 +17,7 @@ def api_not_implemented(conn, _params) do
|> json(%{error: "Not implemented"})
end
def redirector(conn, _params, code \\ 200)
# redirect to admin section
# /pleroma/admin -> /pleroma/admin/
#
def redirector(conn, %{"path" => ["pleroma", "admin"]} = _, _code) do
redirect(conn, to: "/pleroma/admin/")
end
def redirector(conn, _params, code) do
def redirector(conn, _params, code \\ 200) do
conn
|> put_resp_content_type("text/html")
|> send_file(code, index_file_path())
@ -43,28 +35,33 @@ def redirector_with_meta(conn, %{"maybe_nickname_or_id" => maybe_nickname_or_id}
def redirector_with_meta(conn, params) do
{:ok, index_content} = File.read(index_file_path())
tags =
try do
Metadata.build_tags(params)
rescue
e ->
Logger.error(
"Metadata rendering for #{conn.request_path} failed.\n" <>
Exception.format(:error, e, __STACKTRACE__)
)
tags = build_tags(conn, params)
preloads = preload_data(conn, params)
""
end
response = String.replace(index_content, "<!--server-generated-meta-->", tags)
response =
index_content
|> String.replace("<!--server-generated-meta-->", tags <> preloads)
conn
|> put_resp_content_type("text/html")
|> send_resp(200, response)
end
def index_file_path do
Pleroma.Plugs.InstanceStatic.file_path("index.html")
def redirector_with_preload(conn, %{"path" => ["pleroma", "admin"]}) do
redirect(conn, to: "/pleroma/admin/")
end
def redirector_with_preload(conn, params) do
{:ok, index_content} = File.read(index_file_path())
preloads = preload_data(conn, params)
response =
index_content
|> String.replace("<!--server-generated-meta-->", preloads)
conn
|> put_resp_content_type("text/html")
|> send_resp(200, response)
end
def registration_page(conn, params) do
@ -76,4 +73,36 @@ def empty(conn, _params) do
|> put_status(204)
|> text("")
end
defp index_file_path do
Pleroma.Plugs.InstanceStatic.file_path("index.html")
end
defp build_tags(conn, params) do
try do
Metadata.build_tags(params)
rescue
e ->
Logger.error(
"Metadata rendering for #{conn.request_path} failed.\n" <>
Exception.format(:error, e, __STACKTRACE__)
)
""
end
end
defp preload_data(conn, params) do
try do
Preload.build_tags(conn, params)
rescue
e ->
Logger.error(
"Preloading for #{conn.request_path} failed.\n" <>
Exception.format(:error, e, __STACKTRACE__)
)
""
end
end
end

View file

@ -0,0 +1,130 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
alias Pleroma.Config
alias Pleroma.Stats
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.Federator.Publisher
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
# under software.
def get_nodeinfo("2.0") do
stats = Stats.get_stats()
quarantined = Config.get([:instance, :quarantined_instances], [])
staff_accounts =
User.all_superusers()
|> Enum.map(fn u -> u.ap_id end)
federation_response =
if Config.get([:instance, :mrf_transparency]) do
{:ok, data} = MRF.describe()
data
|> Map.merge(%{quarantined_instances: quarantined})
else
%{}
end
|> Map.put(:enabled, Config.get([:instance, :federating]))
features =
[
"pleroma_api",
"mastodon_api",
"mastodon_api_streaming",
"polls",
"pleroma_explicit_addressing",
"shareable_emoji_packs",
"multifetch",
"pleroma:api/v1/notifications:include_types_filter",
if Config.get([:media_proxy, :enabled]) do
"media_proxy"
end,
if Config.get([:gopher, :enabled]) do
"gopher"
end,
if Config.get([:chat, :enabled]) do
"chat"
end,
if Config.get([:instance, :allow_relay]) do
"relay"
end,
if Config.get([:instance, :safe_dm_mentions]) do
"safe_dm_mentions"
end,
"pleroma_emoji_reactions"
]
|> Enum.filter(& &1)
%{
version: "2.0",
software: %{
name: Pleroma.Application.name() |> String.downcase(),
version: Pleroma.Application.version()
},
protocols: Publisher.gather_nodeinfo_protocol_names(),
services: %{
inbound: [],
outbound: []
},
openRegistrations: Config.get([:instance, :registrations_open]),
usage: %{
users: %{
total: Map.get(stats, :user_count, 0)
},
localPosts: Map.get(stats, :status_count, 0)
},
metadata: %{
nodeName: Config.get([:instance, :name]),
nodeDescription: Config.get([:instance, :description]),
private: !Config.get([:instance, :public], true),
suggestions: %{
enabled: false
},
staffAccounts: staff_accounts,
federation: federation_response,
pollLimits: Config.get([:instance, :poll_limits]),
postFormats: Config.get([:instance, :allowed_post_formats]),
uploadLimits: %{
general: Config.get([:instance, :upload_limit]),
avatar: Config.get([:instance, :avatar_upload_limit]),
banner: Config.get([:instance, :banner_upload_limit]),
background: Config.get([:instance, :background_upload_limit])
},
fieldsLimits: %{
maxFields: Config.get([:instance, :max_account_fields]),
maxRemoteFields: Config.get([:instance, :max_remote_account_fields]),
nameLength: Config.get([:instance, :account_field_name_length]),
valueLength: Config.get([:instance, :account_field_value_length])
},
accountActivationRequired: Config.get([:instance, :account_activation_required], false),
invitesEnabled: Config.get([:instance, :invites_enabled], false),
mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false),
features: features,
restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
skipThreadContainment: Config.get([:instance, :skip_thread_containment], false)
}
}
end
def get_nodeinfo("2.1") do
raw_response = get_nodeinfo("2.0")
updated_software =
raw_response
|> Map.get(:software)
|> Map.put(:repository, Pleroma.Application.repository())
raw_response
|> Map.put(:software, updated_software)
|> Map.put(:version, "2.1")
end
def get_nodeinfo(_version) do
{:error, :missing}
end
end

View file

@ -5,12 +5,8 @@
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
use Pleroma.Web, :controller
alias Pleroma.Config
alias Pleroma.Stats
alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.Federator.Publisher
alias Pleroma.Web.MastodonAPI.InstanceView
alias Pleroma.Web.Nodeinfo.Nodeinfo
def schemas(conn, _params) do
response = %{
@ -29,102 +25,20 @@ def schemas(conn, _params) do
json(conn, response)
end
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
# under software.
def raw_nodeinfo do
stats = Stats.get_stats()
staff_accounts =
User.all_superusers()
|> Enum.map(fn u -> u.ap_id end)
features = InstanceView.features()
federation = InstanceView.federation()
%{
version: "2.0",
software: %{
name: Pleroma.Application.name() |> String.downcase(),
version: Pleroma.Application.version()
},
protocols: Publisher.gather_nodeinfo_protocol_names(),
services: %{
inbound: [],
outbound: []
},
openRegistrations: Config.get([:instance, :registrations_open]),
usage: %{
users: %{
total: Map.get(stats, :user_count, 0)
},
localPosts: Map.get(stats, :status_count, 0)
},
metadata: %{
nodeName: Config.get([:instance, :name]),
nodeDescription: Config.get([:instance, :description]),
private: !Config.get([:instance, :public], true),
suggestions: %{
enabled: false
},
staffAccounts: staff_accounts,
federation: federation,
pollLimits: Config.get([:instance, :poll_limits]),
postFormats: Config.get([:instance, :allowed_post_formats]),
uploadLimits: %{
general: Config.get([:instance, :upload_limit]),
avatar: Config.get([:instance, :avatar_upload_limit]),
banner: Config.get([:instance, :banner_upload_limit]),
background: Config.get([:instance, :background_upload_limit])
},
fieldsLimits: %{
maxFields: Config.get([:instance, :max_account_fields]),
maxRemoteFields: Config.get([:instance, :max_remote_account_fields]),
nameLength: Config.get([:instance, :account_field_name_length]),
valueLength: Config.get([:instance, :account_field_value_length])
},
accountActivationRequired: Config.get([:instance, :account_activation_required], false),
invitesEnabled: Config.get([:instance, :invites_enabled], false),
mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false),
features: features,
restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
skipThreadContainment: Config.get([:instance, :skip_thread_containment], false)
}
}
end
# Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json
# and https://github.com/jhass/nodeinfo/blob/master/schemas/2.1/schema.json
def nodeinfo(conn, %{"version" => "2.0"}) do
conn
|> put_resp_header(
"content-type",
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8"
)
|> json(raw_nodeinfo())
end
def nodeinfo(conn, %{"version" => version}) do
case Nodeinfo.get_nodeinfo(version) do
{:error, :missing} ->
render_error(conn, :not_found, "Nodeinfo schema version not handled")
def nodeinfo(conn, %{"version" => "2.1"}) do
raw_response = raw_nodeinfo()
updated_software =
raw_response
|> Map.get(:software)
|> Map.put(:repository, Pleroma.Application.repository())
response =
raw_response
|> Map.put(:software, updated_software)
|> Map.put(:version, "2.1")
conn
|> put_resp_header(
"content-type",
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.1#; charset=utf-8"
)
|> json(response)
end
def nodeinfo(conn, _) do
render_error(conn, :not_found, "Nodeinfo schema version not handled")
node_info ->
conn
|> put_resp_header(
"content-type",
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8"
)
|> json(node_info)
end
end
end

View file

@ -0,0 +1,36 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload do
alias Phoenix.HTML
require Logger
def build_tags(_conn, params) do
preload_data =
Enum.reduce(Pleroma.Config.get([__MODULE__, :providers], []), %{}, fn parser, acc ->
terms =
params
|> parser.generate_terms()
|> Enum.map(fn {k, v} -> {k, Base.encode64(Jason.encode!(v))} end)
|> Enum.into(%{})
Map.merge(acc, terms)
end)
rendered_html =
preload_data
|> Jason.encode!()
|> build_script_tag()
|> HTML.safe_to_string()
rendered_html
end
def build_script_tag(content) do
HTML.Tag.content_tag(:script, HTML.raw(content),
id: "initial-results",
type: "application/json"
)
end
end

View file

@ -0,0 +1,49 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.Instance do
alias Pleroma.Web.MastodonAPI.InstanceView
alias Pleroma.Web.Nodeinfo.Nodeinfo
alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider
@instance_url :"/api/v1/instance"
@panel_url :"/instance/panel.html"
@nodeinfo_url :"/nodeinfo/2.0"
@impl Provider
def generate_terms(_params) do
%{}
|> build_info_tag()
|> build_panel_tag()
|> build_nodeinfo_tag()
end
defp build_info_tag(acc) do
info_data = InstanceView.render("show.json", %{})
Map.put(acc, @instance_url, info_data)
end
defp build_panel_tag(acc) do
instance_path = Path.join(:code.priv_dir(:pleroma), "static/instance/panel.html")
if File.exists?(instance_path) do
panel_data = File.read!(instance_path)
Map.put(acc, @panel_url, panel_data)
else
acc
end
end
defp build_nodeinfo_tag(acc) do
case Nodeinfo.get_nodeinfo("2.0") do
{:error, _} ->
acc
nodeinfo_data ->
Map.put(acc, @nodeinfo_url, nodeinfo_data)
end
end
end

View file

@ -0,0 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.Provider do
@callback generate_terms(map()) :: map()
end

View file

@ -0,0 +1,24 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.StatusNet do
alias Pleroma.Web.Preload.Providers.Provider
alias Pleroma.Web.TwitterAPI.UtilView
@behaviour Provider
@config_url :"/api/statusnet/config.json"
@impl Provider
def generate_terms(_params) do
%{}
|> build_config_tag()
end
defp build_config_tag(acc) do
instance = Pleroma.Config.get(:instance)
info_data = UtilView.status_net_config(instance)
Map.put(acc, @config_url, info_data)
end
end

View file

@ -0,0 +1,39 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.Timelines do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider
@public_url :"/api/v1/timelines/public"
@impl Provider
def generate_terms(params) do
build_public_tag(%{}, params)
end
def build_public_tag(acc, params) do
if Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated], true) do
acc
else
Map.put(acc, @public_url, public_timeline(params))
end
end
defp public_timeline(%{"path" => ["main", "all"]}), do: get_public_timeline(false)
defp public_timeline(_params), do: get_public_timeline(true)
defp get_public_timeline(local_only) do
activities =
ActivityPub.fetch_public_activities(%{
type: ["Create"],
local_only: local_only
})
StatusView.render("index.json", activities: activities, for: nil, as: :activity)
end
end

View file

@ -0,0 +1,25 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.User do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider
@account_url :"/api/v1/accounts"
@impl Provider
def generate_terms(%{user: user}) do
build_accounts_tag(%{}, user)
end
def generate_terms(_params), do: %{}
def build_accounts_tag(acc, nil), do: acc
def build_accounts_tag(acc, user) do
account_data = AccountView.render("show.json", %{user: user, for: user})
Map.put(acc, @account_url, account_data)
end
end

View file

@ -726,7 +726,7 @@ defmodule Pleroma.Web.Router do
get("/registration/:token", RedirectController, :registration_page)
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
get("/api*path", RedirectController, :api_not_implemented)
get("/*path", RedirectController, :redirector)
get("/*path", RedirectController, :redirector_with_preload)
options("/*path", RedirectController, :empty)
end

View file

@ -15,6 +15,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.TwitterAPI.UtilView
alias Pleroma.Web.WebFinger
plug(Pleroma.Web.FederatingPlug when action == :remote_subscribe)
@ -90,17 +91,7 @@ def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_
def config(%{assigns: %{format: "xml"}} = conn, _params) do
instance = Pleroma.Config.get(:instance)
response = """
<config>
<site>
<name>#{Keyword.get(instance, :name)}</name>
<site>#{Web.base_url()}</site>
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
</site>
</config>
"""
response = UtilView.status_net_config(instance)
conn
|> put_resp_content_type("application/xml")

View file

@ -5,4 +5,18 @@
defmodule Pleroma.Web.TwitterAPI.UtilView do
use Pleroma.Web, :view
import Phoenix.HTML.Form
alias Pleroma.Web
def status_net_config(instance) do
"""
<config>
<site>
<name>#{Keyword.get(instance, :name)}</name>
<site>#{Web.base_url()}</site>
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
</site>
</config>
"""
end
end

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.RuntimeStaticPlugTest do
test "overrides index" do
bundled_index = get(build_conn(), "/")
assert html_response(bundled_index, 200) == File.read!("priv/static/index.html")
refute html_response(bundled_index, 200) == "hello world"
File.write!(@dir <> "/index.html", "hello world")

View file

@ -6,22 +6,56 @@ defmodule Pleroma.Web.FallbackTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
test "GET /registration/:token", %{conn: conn} do
assert conn
|> get("/registration/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
describe "neither preloaded data nor metadata attached to" do
test "GET /registration/:token", %{conn: conn} do
response = get(conn, "/registration/foo")
assert html_response(response, 200) =~ "<!--server-generated-meta-->"
end
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
end
test "GET /:maybe_nickname_or_id", %{conn: conn} do
user = insert(:user)
describe "preloaded data and metadata attached to" do
test "GET /:maybe_nickname_or_id", %{conn: conn} do
user = insert(:user)
user_missing = get(conn, "/foo")
user_present = get(conn, "/#{user.nickname}")
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
assert(html_response(user_missing, 200) =~ "<!--server-generated-meta-->")
refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
assert html_response(user_present, 200) =~ "initial-results"
end
refute conn
|> get("/" <> user.nickname)
|> html_response(200) =~ "<!--server-generated-meta-->"
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
refute conn
|> get("/foo/bar")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
end
describe "preloaded data is attached to" do
test "GET /main/public", %{conn: conn} do
public_page = get(conn, "/main/public")
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
assert html_response(public_page, 200) =~ "initial-results"
end
test "GET /main/all", %{conn: conn} do
public_page = get(conn, "/main/all")
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
assert html_response(public_page, 200) =~ "initial-results"
end
end
test "GET /api*path", %{conn: conn} do
@ -34,16 +68,6 @@ test "GET /pleroma/admin -> /pleroma/admin/", %{conn: conn} do
assert redirected_to(get(conn, "/pleroma/admin")) =~ "/pleroma/admin/"
end
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
assert conn
|> get("/foo/bar")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
test "OPTIONS /*path", %{conn: conn} do
assert conn
|> options("/foo")

View file

@ -142,8 +142,7 @@ test "it shows default features flags", %{conn: conn} do
"shareable_emoji_packs",
"multifetch",
"pleroma_emoji_reactions",
"pleroma:api/v1/notifications:include_types_filter",
"pleroma_chat_messages"
"pleroma:api/v1/notifications:include_types_filter"
]
assert MapSet.subset?(

View file

@ -0,0 +1,37 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.InstanceTest do
use Pleroma.DataCase
alias Pleroma.Web.Preload.Providers.Instance
setup do: {:ok, Instance.generate_terms(nil)}
test "it renders the info", %{"/api/v1/instance": info} do
assert %{
description: description,
email: "admin@example.com",
registrations: true
} = info
assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server")
end
test "it renders the panel", %{"/instance/panel.html": panel} do
assert String.contains?(
panel,
"<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>"
)
end
test "it renders the node_info", %{"/nodeinfo/2.0": nodeinfo} do
%{
metadata: metadata,
version: "2.0"
} = nodeinfo
assert metadata.private == false
assert metadata.suggestions == %{enabled: false}
end
end

View file

@ -0,0 +1,14 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.StatusNetTest do
use Pleroma.DataCase
alias Pleroma.Web.Preload.Providers.StatusNet
setup do: {:ok, StatusNet.generate_terms(nil)}
test "it renders the info", %{"/api/statusnet/config.json": info} do
assert info =~ "<name>Pleroma</name>"
end
end

View file

@ -0,0 +1,74 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.TimelineTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Preload.Providers.Timelines
@public_url :"/api/v1/timelines/public"
describe "unauthenticated timeliness when restricted" do
setup do
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true})
on_exit(fn ->
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
end)
:ok
end
test "return nothing" do
tl_data = Timelines.generate_terms(%{})
refute Map.has_key?(tl_data, "/api/v1/timelines/public")
end
end
describe "unauthenticated timeliness when unrestricted" do
setup do
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{
local: false,
federated: false
})
on_exit(fn ->
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
end)
{:ok, user: insert(:user)}
end
test "returns the timeline when not restricted" do
assert Timelines.generate_terms(%{})
|> Map.has_key?(@public_url)
end
test "returns public items", %{user: user} do
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
assert Timelines.generate_terms(%{})
|> Map.fetch!(@public_url)
|> Enum.count() == 3
end
test "does not return non-public items", %{user: user} do
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!", visibility: "unlisted"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
assert Timelines.generate_terms(%{})
|> Map.fetch!(@public_url)
|> Enum.count() == 1
end
end
end

View file

@ -0,0 +1,33 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.UserTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.Preload.Providers.User
describe "returns empty when user doesn't exist" do
test "nil user specified" do
refute User.generate_terms(%{user: nil})
|> Map.has_key?("/api/v1/accounts")
end
test "missing user specified" do
refute User.generate_terms(%{user: :not_a_user})
|> Map.has_key?("/api/v1/accounts")
end
end
describe "specified user exists" do
setup do
user = insert(:user)
{:ok, User.generate_terms(%{user: user})}
end
test "account is rendered", %{"/api/v1/accounts": accounts} do
assert %{acct: user, username: user} = accounts
end
end
end