diff options
| -rw-r--r-- | config/config.exs | 25 | ||||
| -rw-r--r-- | lib/pleroma/web/fallback_redirect_controller.ex | 82 | ||||
| -rw-r--r-- | lib/pleroma/web/nodeinfo/nodeinfo.ex | 130 | ||||
| -rw-r--r-- | lib/pleroma/web/nodeinfo/nodeinfo_controller.ex | 114 | ||||
| -rw-r--r-- | lib/pleroma/web/preload.ex | 30 | ||||
| -rw-r--r-- | lib/pleroma/web/preload/instance.ex | 49 | ||||
| -rw-r--r-- | lib/pleroma/web/preload/provider.ex | 7 | ||||
| -rw-r--r-- | lib/pleroma/web/preload/timelines.ex | 42 | ||||
| -rw-r--r-- | lib/pleroma/web/preload/user.ex | 25 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 2 | ||||
| -rw-r--r-- | test/plugs/instance_static_test.exs | 2 | ||||
| -rw-r--r-- | test/web/fallback_test.exs | 38 | ||||
| -rw-r--r-- | test/web/preload/instance_test.exs | 37 | ||||
| -rw-r--r-- | test/web/preload/timeline_test.exs | 74 | ||||
| -rw-r--r-- | test/web/preload/user_test.exs | 33 | 
15 files changed, 533 insertions, 157 deletions
| diff --git a/config/config.exs b/config/config.exs index 9508ae077..ee81eb899 100644 --- a/config/config.exs +++ b/config/config.exs @@ -241,18 +241,7 @@ config :pleroma, :instance,    account_field_value_length: 2048,    external_user_synchronization: true,    extended_nickname_format: true, -  cleanup_attachments: false, -  multi_factor_authentication: [ -    totp: [ -      # digits 6 or 8 -      digits: 6, -      period: 30 -    ], -    backup_codes: [ -      number: 5, -      length: 16 -    ] -  ] +  cleanup_attachments: false  config :pleroma, :feed,    post_title: %{ @@ -361,8 +350,7 @@ config :pleroma, :mrf_simple,    reject: [],    accept: [],    avatar_removal: [], -  banner_removal: [], -  reject_deletes: [] +  banner_removal: []  config :pleroma, :mrf_keyword,    reject: [], @@ -428,6 +416,13 @@ config :pleroma, Pleroma.Web.Metadata,    ],    unfurl_nsfw: false +config :pleroma, Pleroma.Web.Preload, +  providers: [ +    Pleroma.Web.Preload.Providers.Instance, +    Pleroma.Web.Preload.Providers.User, +    Pleroma.Web.Preload.Providers.Timelines +  ] +  config :pleroma, :http_security,    enabled: true,    sts: false, @@ -682,8 +677,6 @@ config :pleroma, :restrict_unauthenticated,    profiles: %{local: false, remote: false},    activities: %{local: false, remote: false} -config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false -  # Import environment specific config. This must remain at the bottom  # of this file so it overrides the configuration defined above.  import_config "#{Mix.env()}.exs" diff --git a/lib/pleroma/web/fallback_redirect_controller.ex b/lib/pleroma/web/fallback_redirect_controller.ex index 0d9d578fc..932fb8d7e 100644 --- a/lib/pleroma/web/fallback_redirect_controller.ex +++ b/lib/pleroma/web/fallback_redirect_controller.ex @@ -4,11 +4,10 @@  defmodule Fallback.RedirectController do    use Pleroma.Web, :controller -    require Logger -    alias Pleroma.User    alias Pleroma.Web.Metadata +  alias Pleroma.Web.Preload    def api_not_implemented(conn, _params) do      conn @@ -16,16 +15,7 @@ defmodule Fallback.RedirectController 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 +33,34 @@ defmodule Fallback.RedirectController do    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__) -          ) - -          "" -      end +    tags = build_tags(conn, params) +    preloads = preload_data(conn, params) -    response = String.replace(index_content, "<!--server-generated-meta-->", tags) +    response = +      index_content +      |> String.replace("<!--server-generated-meta-->", tags) +      |> String.replace("<!--server-generated-initial-data-->", 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-initial-data-->", preloads) + +    conn +    |> put_resp_content_type("text/html") +    |> send_resp(200, response)    end    def registration_page(conn, params) do @@ -76,4 +72,36 @@ defmodule Fallback.RedirectController 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 diff --git a/lib/pleroma/web/nodeinfo/nodeinfo.ex b/lib/pleroma/web/nodeinfo/nodeinfo.ex new file mode 100644 index 000000000..d26b7c938 --- /dev/null +++ b/lib/pleroma/web/nodeinfo/nodeinfo.ex @@ -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 diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 721b599d4..8c7a9e565 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -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 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController 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" => "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") +  def nodeinfo(conn, %{"version" => version}) do +    case Nodeinfo.get_nodeinfo(version) do +      {:error, :missing} -> +        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 diff --git a/lib/pleroma/web/preload.ex b/lib/pleroma/web/preload.ex new file mode 100644 index 000000000..c2211c597 --- /dev/null +++ b/lib/pleroma/web/preload.ex @@ -0,0 +1,30 @@ +# 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 -> +        Map.merge(acc, parser.generate_terms(params)) +      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 diff --git a/lib/pleroma/web/preload/instance.ex b/lib/pleroma/web/preload/instance.ex new file mode 100644 index 000000000..0b6fd3313 --- /dev/null +++ b/lib/pleroma/web/preload/instance.ex @@ -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 diff --git a/lib/pleroma/web/preload/provider.ex b/lib/pleroma/web/preload/provider.ex new file mode 100644 index 000000000..7ef595a34 --- /dev/null +++ b/lib/pleroma/web/preload/provider.ex @@ -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 diff --git a/lib/pleroma/web/preload/timelines.ex b/lib/pleroma/web/preload/timelines.ex new file mode 100644 index 000000000..dbd7db407 --- /dev/null +++ b/lib/pleroma/web/preload/timelines.ex @@ -0,0 +1,42 @@ +# 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(%{}) +  end + +  def build_public_tag(acc) do +    if Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated], true) do +      acc +    else +      Map.put(acc, @public_url, public_timeline(nil)) +    end +  end + +  defp public_timeline(user) do +    activities = +      create_timeline_params(user) +      |> Map.put("local_only", false) +      |> ActivityPub.fetch_public_activities() + +    StatusView.render("index.json", activities: activities, for: user, as: :activity) +  end + +  defp create_timeline_params(user) do +    %{} +    |> Map.put("type", ["Create", "Announce"]) +    |> Map.put("blocking_user", user) +    |> Map.put("muting_user", user) +    |> Map.put("user", user) +  end +end diff --git a/lib/pleroma/web/preload/user.ex b/lib/pleroma/web/preload/user.ex new file mode 100644 index 000000000..3a244845b --- /dev/null +++ b/lib/pleroma/web/preload/user.ex @@ -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 diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 80ea28364..3b55afede 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -718,7 +718,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 diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs index b8f070d6a..be2613ad0 100644 --- a/test/plugs/instance_static_test.exs +++ b/test/plugs/instance_static_test.exs @@ -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") diff --git a/test/web/fallback_test.exs b/test/web/fallback_test.exs index 3919ef93a..3b7a51d5e 100644 --- a/test/web/fallback_test.exs +++ b/test/web/fallback_test.exs @@ -6,22 +6,36 @@ 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-->" +      assert html_response(response, 200) =~ "<!--server-generated-initial-data-->" +    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-->" -    refute conn -           |> get("/" <> user.nickname) -           |> html_response(200) =~ "<!--server-generated-meta-->" +      assert html_response(user_missing, 200) =~ "<!--server-generated-initial-data-->" +      refute html_response(user_present, 200) =~ "<!--server-generated-initial-data-->" +    end +  end + +  describe "preloaded data only attached to" do +    test "GET /*path", %{conn: conn} do +      public_page = get(conn, "/main/public") + +      assert html_response(public_page, 200) =~ "<!--server-generated-meta-->" +      refute html_response(public_page, 200) =~ "<!--server-generated-initial-data-->" +    end    end    test "GET /api*path", %{conn: conn} do diff --git a/test/web/preload/instance_test.exs b/test/web/preload/instance_test.exs new file mode 100644 index 000000000..52f9bab3b --- /dev/null +++ b/test/web/preload/instance_test.exs @@ -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, "A Pleroma instance, an alternative 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 diff --git a/test/web/preload/timeline_test.exs b/test/web/preload/timeline_test.exs new file mode 100644 index 000000000..00b10d0ab --- /dev/null +++ b/test/web/preload/timeline_test.exs @@ -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 diff --git a/test/web/preload/user_test.exs b/test/web/preload/user_test.exs new file mode 100644 index 000000000..99232cdfa --- /dev/null +++ b/test/web/preload/user_test.exs @@ -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 | 
