@@ -4,11 +4,14 @@ All notable changes to this project will be documented in this file. | |||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
## [Unreleased] | |||
### Added | |||
- Refreshing poll results for remote polls | |||
### Changed | |||
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7) | |||
- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings) | |||
- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler | |||
- Admin API: Return `total` when querying for reports | |||
- Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`) | |||
## [1.1.0] - 2019-??-?? | |||
### Security | |||
@@ -23,7 +26,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- **Breaking:** Configuration: A setting to explicitly disable the mailer was added, defaulting to true, if you are using a mailer add `config :pleroma, Pleroma.Emails.Mailer, enabled: true` to your config | |||
- **Breaking:** Configuration: `/media/` is now removed when `base_url` is configured, append `/media/` to your `base_url` config to keep the old behaviour if desired | |||
- **Breaking:** `/api/pleroma/notifications/read` is moved to `/api/v1/pleroma/notifications/read` and now supports `max_id` and responds with Mastodon API entities. | |||
- **Breaking:** `/api/pleroma/admin/users/invite_token` now uses `POST`, changed accepted params and returns full invite in json instead of only token string. | |||
- Configuration: added `config/description.exs`, from which `docs/config.md` is generated | |||
- Configuration: OpenGraph and TwitterCard providers enabled by default | |||
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text | |||
- Mastodon API: `pleroma.thread_muted` key in the Status entity | |||
- Federation: Return 403 errors when trying to request pages from a user's follower/following collections if they have `hide_followers`/`hide_follows` set | |||
- NodeInfo: Return `skipThreadContainment` in `metadata` for the `skip_thread_containment` option | |||
- NodeInfo: Return `mailerEnabled` in `metadata` | |||
@@ -79,6 +86,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Mastodon API: added `/auth/password` endpoint for password reset with rate limit. | |||
- Mastodon API: /api/v1/accounts/:id/statuses now supports nicknames or user id | |||
- Mastodon API: Improve support for the user profile custom fields | |||
- Mastodon API: follower/following counters are nullified when `hide_follows`/`hide_followers` and `hide_follows_count`/`hide_followers_count` are set | |||
- Admin API: Return users' tags when querying reports | |||
- Admin API: Return avatar and display name when querying users | |||
- Admin API: Allow querying user by ID | |||
@@ -224,15 +224,25 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret | |||
## `/api/pleroma/admin/users/invite_token` | |||
### Get an account registration invite token | |||
### Create an account registration invite token | |||
- Methods: `GET` | |||
- Methods: `POST` | |||
- Params: | |||
- *optional* `invite` => [ | |||
- *optional* `max_use` (integer) | |||
- *optional* `expires_at` (date string e.g. "2019-04-07") | |||
] | |||
- Response: invite token (base64 string) | |||
- *optional* `max_use` (integer) | |||
- *optional* `expires_at` (date string e.g. "2019-04-07") | |||
- Response: | |||
```json | |||
{ | |||
"id": integer, | |||
"token": string, | |||
"used": boolean, | |||
"expires_at": date, | |||
"uses": integer, | |||
"max_use": integer, | |||
"invite_type": string (possible values: `one_time`, `reusable`, `date_limited`, `reusable_date_limited`) | |||
} | |||
``` | |||
## `/api/pleroma/admin/users/invites` | |||
@@ -21,7 +21,8 @@ Adding the parameter `with_muted=true` to the timeline queries will also return | |||
Has these additional fields under the `pleroma` object: | |||
- `local`: true if the post was made on the local instance | |||
- `conversation_id`: the ID of the conversation the status is associated with (if any) | |||
- `conversation_id`: the ID of the AP context the status is associated with (if any) | |||
- `direct_conversation_id`: the ID of the Mastodon direct message conversation the status is associated with (if any) | |||
- `in_reply_to_account_acct`: the `acct` property of User entity for replied user (if any) | |||
- `content`: a map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain` | |||
- `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain` | |||
@@ -50,6 +51,8 @@ Has these additional fields under the `pleroma` object: | |||
- `confirmation_pending`: boolean, true if a new user account is waiting on email confirmation to be activated | |||
- `hide_followers`: boolean, true when the user has follower hiding enabled | |||
- `hide_follows`: boolean, true when the user has follow hiding enabled | |||
- `hide_followers_count`: boolean, true when the user has follower stat hiding enabled | |||
- `hide_follows_count`: boolean, true when the user has follow stat hiding enabled | |||
- `settings_store`: A generic map of settings for frontends. Opaque to the backend. Only returned in `verify_credentials` and `update_credentials` | |||
- `chat_token`: The token needed for Pleroma chat. Only returned in `verify_credentials` | |||
- `deactivated`: boolean, true when the user is deactivated | |||
@@ -112,6 +115,8 @@ Additional parameters can be added to the JSON body/Form data: | |||
- `no_rich_text` - if true, html tags are stripped from all statuses requested from the API | |||
- `hide_followers` - if true, user's followers will be hidden | |||
- `hide_follows` - if true, user's follows will be hidden | |||
- `hide_followers_count` - if true, user's follower count will be hidden | |||
- `hide_follows_count` - if true, user's follow count will be hidden | |||
- `hide_favorites` - if true, user's favorites timeline will be hidden | |||
- `show_role` - if true, user's role (e.g admin, moderator) will be exposed to anyone in the API | |||
- `default_scope` - the scope returned under `privacy` key in Source subentity | |||
@@ -39,7 +39,7 @@ Feel free to contact us to be added to this list! | |||
### Nekonium | |||
- Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/) | |||
- Source: <https://git.gdgd.jp.net/lin/nekonium/> | |||
- Source: <https://gogs.gdgd.jp.net/lin/nekonium> | |||
- Contact: [@lin@pleroma.gdgd.jp.net](https://pleroma.gdgd.jp.net/users/lin) | |||
- Platforms: Android | |||
- Features: Streaming Ready | |||
@@ -67,7 +67,7 @@ Feel free to contact us to be added to this list! | |||
## Alternative Web Interfaces | |||
### Brutaldon | |||
- Homepage: <https://jfm.carcosa.net/projects/software/brutaldon/> | |||
- Source Code: <https://github.com/jfmcbrayer/brutaldon> | |||
- Source Code: <https://git.carcosa.net/jmcbray/brutaldon> | |||
- Contact: [@gcupc@glitch.social](https://glitch.social/users/gcupc) | |||
- Features: No Streaming | |||
@@ -215,7 +215,9 @@ | |||
]} | |||
]}, | |||
{ 5222, ejabberd_c2s, [ | |||
%% If you want dual stack, you have to clone this entire config stanza | |||
%% and change the bind to "::" | |||
{ {5222, "0.0.0.0"}, ejabberd_c2s, [ | |||
%% | |||
%% If TLS is compiled in and you installed a SSL | |||
@@ -246,7 +248,9 @@ | |||
%% {max_stanza_size, 65536} | |||
%% ]}, | |||
{ 5269, ejabberd_s2s_in, [ | |||
%% If you want dual stack, you have to clone this entire config stanza | |||
%% and change the bind to "::" | |||
{ {5269, "0.0.0.0"}, ejabberd_s2s_in, [ | |||
{shaper, s2s_shaper}, | |||
{max_stanza_size, 131072}, | |||
{protocol_options, ["no_sslv3"]} | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Pleroma do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.Database do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-onl | |||
defmodule Mix.Tasks.Pleroma.Ecto do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-onl | |||
defmodule Mix.Tasks.Pleroma.Ecto.Migrate do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-onl | |||
defmodule Mix.Tasks.Pleroma.Ecto.Rollback do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.Emoji do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.Instance do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.Relay do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.Uploads do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.User do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Activity.Queries do | |||
@@ -6,4 +6,16 @@ defmodule Pleroma.Constants do | |||
use Const | |||
const(as_public, do: "https://www.w3.org/ns/activitystreams#Public") | |||
const(object_internal_fields, | |||
do: [ | |||
"likes", | |||
"like_count", | |||
"announcements", | |||
"announcement_count", | |||
"emoji", | |||
"context_id", | |||
"deleted_activity_id" | |||
] | |||
) | |||
end |
@@ -23,7 +23,7 @@ defmodule Pleroma.Docs.Markdown do | |||
IO.write(file, "#{group[:description]}\n") | |||
for child <- group[:children] do | |||
for child <- group[:children] || [] do | |||
print_child_header(file, child) | |||
print_suggestions(file, child[:suggestions]) | |||
@@ -44,6 +44,17 @@ defmodule Pleroma.Docs.Markdown do | |||
{:ok, config_path} | |||
end | |||
defp print_child_header(file, %{key: key, type: type, description: description} = _child) do | |||
IO.write( | |||
file, | |||
"- `#{inspect(key)}` (`#{inspect(type)}`): #{description} \n" | |||
) | |||
end | |||
defp print_child_header(file, %{key: key, type: type} = _child) do | |||
IO.write(file, "- `#{inspect(key)}` (`#{inspect(type)}`) \n") | |||
end | |||
defp print_suggestion(file, suggestion) when is_list(suggestion) do | |||
IO.write(file, " `#{inspect(suggestion)}`\n") | |||
end | |||
@@ -59,20 +70,19 @@ defmodule Pleroma.Docs.Markdown do | |||
defp print_suggestions(_file, nil), do: nil | |||
defp print_suggestions(file, suggestions) do | |||
IO.write(file, "Suggestions:\n") | |||
defp print_suggestions(_file, ""), do: nil | |||
defp print_suggestions(file, suggestions) do | |||
if length(suggestions) > 1 do | |||
IO.write(file, "Suggestions:\n") | |||
for suggestion <- suggestions do | |||
print_suggestion(file, suggestion, true) | |||
end | |||
else | |||
IO.write(file, " Suggestion: ") | |||
print_suggestion(file, List.first(suggestions)) | |||
end | |||
end | |||
defp print_child_header(file, child) do | |||
IO.write(file, "- `#{inspect(child[:key])}` -`#{inspect(child[:type])}` \n") | |||
IO.write(file, "#{child[:description]} \n") | |||
end | |||
end |
@@ -38,6 +38,24 @@ defmodule Pleroma.Object do | |||
def get_by_id(nil), do: nil | |||
def get_by_id(id), do: Repo.get(Object, id) | |||
def get_by_id_and_maybe_refetch(id, opts \\ []) do | |||
%{updated_at: updated_at} = object = get_by_id(id) | |||
if opts[:interval] && | |||
NaiveDateTime.diff(NaiveDateTime.utc_now(), updated_at) > opts[:interval] do | |||
case Fetcher.refetch_object(object) do | |||
{:ok, %Object{} = object} -> | |||
object | |||
e -> | |||
Logger.error("Couldn't refresh #{object.data["id"]}:\n#{inspect(e)}") | |||
object | |||
end | |||
else | |||
object | |||
end | |||
end | |||
def get_by_ap_id(nil), do: nil | |||
def get_by_ap_id(ap_id) do | |||
@@ -6,18 +6,39 @@ defmodule Pleroma.Object.Fetcher do | |||
alias Pleroma.HTTP | |||
alias Pleroma.Object | |||
alias Pleroma.Object.Containment | |||
alias Pleroma.Repo | |||
alias Pleroma.Signature | |||
alias Pleroma.Web.ActivityPub.InternalFetchActor | |||
alias Pleroma.Web.ActivityPub.Transmogrifier | |||
alias Pleroma.Web.OStatus | |||
require Logger | |||
require Pleroma.Constants | |||
defp reinject_object(data) do | |||
defp touch_changeset(changeset) do | |||
updated_at = | |||
NaiveDateTime.utc_now() | |||
|> NaiveDateTime.truncate(:second) | |||
Ecto.Changeset.put_change(changeset, :updated_at, updated_at) | |||
end | |||
defp maybe_reinject_internal_fields(data, %{data: %{} = old_data}) do | |||
internal_fields = Map.take(old_data, Pleroma.Constants.object_internal_fields()) | |||
Map.merge(data, internal_fields) | |||
end | |||
defp maybe_reinject_internal_fields(data, _), do: data | |||
defp reinject_object(struct, data) do | |||
Logger.debug("Reinjecting object #{data["id"]}") | |||
with data <- Transmogrifier.fix_object(data), | |||
{:ok, object} <- Object.create(data) do | |||
data <- maybe_reinject_internal_fields(data, struct), | |||
changeset <- Object.change(struct, %{data: data}), | |||
changeset <- touch_changeset(changeset), | |||
{:ok, object} <- Repo.insert_or_update(changeset) do | |||
{:ok, object} | |||
else | |||
e -> | |||
@@ -26,6 +47,17 @@ defmodule Pleroma.Object.Fetcher do | |||
end | |||
end | |||
def refetch_object(%Object{data: %{"id" => id}} = object) do | |||
with {:local, false} <- {:local, String.starts_with?(id, Pleroma.Web.base_url() <> "/")}, | |||
{:ok, data} <- fetch_and_contain_remote_object_from_id(id), | |||
{:ok, object} <- reinject_object(object, data) do | |||
{:ok, object} | |||
else | |||
{:local, true} -> object | |||
e -> {:error, e} | |||
end | |||
end | |||
# TODO: | |||
# This will create a Create activity, which we need internally at the moment. | |||
def fetch_object_from_id(id, options \\ []) do | |||
@@ -57,7 +89,7 @@ defmodule Pleroma.Object.Fetcher do | |||
{:reject, nil} | |||
{:object, data, nil} -> | |||
reinject_object(data) | |||
reinject_object(%Object{}, data) | |||
{:normalize, object = %Object{}} -> | |||
{:ok, object} | |||
@@ -41,6 +41,8 @@ defmodule Pleroma.User.Info do | |||
field(:topic, :string, default: nil) | |||
field(:hub, :string, default: nil) | |||
field(:salmon, :string, default: nil) | |||
field(:hide_followers_count, :boolean, default: false) | |||
field(:hide_follows_count, :boolean, default: false) | |||
field(:hide_followers, :boolean, default: false) | |||
field(:hide_follows, :boolean, default: false) | |||
field(:hide_favorites, :boolean, default: true) | |||
@@ -262,6 +264,8 @@ defmodule Pleroma.User.Info do | |||
:salmon, | |||
:hide_followers, | |||
:hide_follows, | |||
:hide_followers_count, | |||
:hide_follows_count, | |||
:follower_count, | |||
:fields, | |||
:following_count | |||
@@ -281,7 +285,9 @@ defmodule Pleroma.User.Info do | |||
:following_count, | |||
:hide_follows, | |||
:fields, | |||
:hide_followers | |||
:hide_followers, | |||
:hide_followers_count, | |||
:hide_follows_count | |||
]) | |||
|> validate_fields(remote?) | |||
end | |||
@@ -295,6 +301,8 @@ defmodule Pleroma.User.Info do | |||
:banner, | |||
:hide_follows, | |||
:hide_followers, | |||
:hide_followers_count, | |||
:hide_follows_count, | |||
:hide_favorites, | |||
:background, | |||
:show_role, | |||
@@ -458,7 +466,9 @@ defmodule Pleroma.User.Info do | |||
:hide_followers, | |||
:hide_follows, | |||
:follower_count, | |||
:following_count | |||
:following_count, | |||
:hide_followers_count, | |||
:hide_follows_count | |||
]) | |||
end | |||
end |
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.User.Query do | |||
@@ -979,15 +979,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||
defp strip_internal_fields(object) do | |||
object | |||
|> Map.drop([ | |||
"likes", | |||
"like_count", | |||
"announcements", | |||
"announcement_count", | |||
"emoji", | |||
"context_id", | |||
"deleted_activity_id" | |||
]) | |||
|> Map.drop(Pleroma.Constants.object_internal_fields()) | |||
end | |||
defp strip_internal_tags(%{"tag" => tags} = object) do | |||
@@ -1050,8 +1042,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||
with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id), | |||
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id), | |||
already_ap <- User.ap_enabled?(user), | |||
{:ok, user} <- user |> User.upgrade_changeset(data, true) |> User.update_and_set_cache() do | |||
unless already_ap do | |||
{:ok, user} <- upgrade_user(user, data) do | |||
if not already_ap do | |||
TransmogrifierWorker.enqueue("user_upgrade", %{"user_id" => user.id}) | |||
end | |||
@@ -1062,6 +1054,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||
end | |||
end | |||
defp upgrade_user(user, data) do | |||
user | |||
|> User.upgrade_changeset(data, true) | |||
|> User.update_and_set_cache() | |||
end | |||
def maybe_retire_websub(ap_id) do | |||
# some sanity checks | |||
if is_binary(ap_id) && String.length(ap_id) > 8 do | |||
@@ -118,30 +118,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||
end | |||
def render("following.json", %{user: user, page: page} = opts) do | |||
showing = (opts[:for] && opts[:for] == user) || !user.info.hide_follows | |||
showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_follows | |||
showing_count = showing_items || !user.info.hide_follows_count | |||
query = User.get_friends_query(user) | |||
query = from(user in query, select: [:ap_id]) | |||
following = Repo.all(query) | |||
total = | |||
if showing do | |||
if showing_count do | |||
length(following) | |||
else | |||
0 | |||
end | |||
collection(following, "#{user.ap_id}/following", page, showing, total) | |||
collection(following, "#{user.ap_id}/following", page, showing_items, total) | |||
|> Map.merge(Utils.make_json_ld_header()) | |||
end | |||
def render("following.json", %{user: user} = opts) do | |||
showing = (opts[:for] && opts[:for] == user) || !user.info.hide_follows | |||
showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_follows | |||
showing_count = showing_items || !user.info.hide_follows_count | |||
query = User.get_friends_query(user) | |||
query = from(user in query, select: [:ap_id]) | |||
following = Repo.all(query) | |||
total = | |||
if showing do | |||
if showing_count do | |||
length(following) | |||
else | |||
0 | |||
@@ -152,7 +156,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||
"type" => "OrderedCollection", | |||
"totalItems" => total, | |||
"first" => | |||
if showing do | |||
if showing_items do | |||
collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows) | |||
else | |||
"#{user.ap_id}/following?page=1" | |||
@@ -162,32 +166,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||
end | |||
def render("followers.json", %{user: user, page: page} = opts) do | |||
showing = (opts[:for] && opts[:for] == user) || !user.info.hide_followers | |||
showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_followers | |||
showing_count = showing_items || !user.info.hide_followers_count | |||
query = User.get_followers_query(user) | |||
query = from(user in query, select: [:ap_id]) | |||
followers = Repo.all(query) | |||
total = | |||
if showing do | |||
if showing_count do | |||
length(followers) | |||
else | |||
0 | |||
end | |||
collection(followers, "#{user.ap_id}/followers", page, showing, total) | |||
collection(followers, "#{user.ap_id}/followers", page, showing_items, total) | |||
|> Map.merge(Utils.make_json_ld_header()) | |||
end | |||
def render("followers.json", %{user: user} = opts) do | |||
showing = (opts[:for] && opts[:for] == user) || !user.info.hide_followers | |||
showing_items = (opts[:for] && opts[:for] == user) || !user.info.hide_followers | |||
showing_count = showing_items || !user.info.hide_followers_count | |||
query = User.get_followers_query(user) | |||
query = from(user in query, select: [:ap_id]) | |||
followers = Repo.all(query) | |||
total = | |||
if showing do | |||
if showing_count do | |||
length(followers) | |||
else | |||
0 | |||
@@ -198,8 +204,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||
"type" => "OrderedCollection", | |||
"totalItems" => total, | |||
"first" => | |||
if showing do | |||
collection(followers, "#{user.ap_id}/followers", 1, showing, total) | |||
if showing_items do | |||
collection(followers, "#{user.ap_id}/followers", 1, showing_items, total) | |||
else | |||
"#{user.ap_id}/followers?page=1" | |||
end | |||
@@ -221,11 +227,12 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||
activities = ActivityPub.fetch_user_activities(user, nil, params) | |||
# this is sorted chronologically, so first activity is the newest (max) | |||
{max_id, min_id, collection} = | |||
if length(activities) > 0 do | |||
{ | |||
Enum.at(Enum.reverse(activities), 0).id, | |||
Enum.at(activities, 0).id, | |||
Enum.at(Enum.reverse(activities), 0).id, | |||
Enum.map(activities, fn act -> | |||
{:ok, data} = Transmogrifier.prepare_outgoing(act.data) | |||
data | |||
@@ -402,13 +402,23 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||
end | |||
end | |||
@doc "Get a account registeration invite token (base64 string)" | |||
def get_invite_token(conn, params) do | |||
options = params["invite"] || %{} | |||
{:ok, invite} = UserInviteToken.create_invite(options) | |||
@doc "Create an account registration invite token" | |||
def create_invite_token(conn, params) do | |||
opts = %{} | |||
conn | |||
|> json(invite.token) | |||
opts = | |||
if params["max_use"], | |||
do: Map.put(opts, :max_use, params["max_use"]), | |||
else: opts | |||
opts = | |||
if params["expires_at"], | |||
do: Map.put(opts, :expires_at, params["expires_at"]), | |||
else: opts | |||
{:ok, invite} = UserInviteToken.create_invite(opts) | |||
json(conn, AccountView.render("invite.json", %{invite: invite})) | |||
end | |||
@doc "Get list of created invites" | |||
@@ -147,6 +147,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
[ | |||
:no_rich_text, | |||
:locked, | |||
:hide_followers_count, | |||
:hide_follows_count, | |||
:hide_followers, | |||
:hide_follows, | |||
:hide_favorites, | |||
@@ -485,7 +487,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
with %Object{} = object <- Object.get_by_id(id), | |||
with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60), | |||
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]), | |||
true <- Visibility.visible_for_user?(activity, user) do | |||
conn | |||
@@ -609,7 +611,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
{:ok, activity} -> | |||
conn | |||
|> put_view(StatusView) | |||
|> try_render("status.json", %{activity: activity, for: user, as: :activity}) | |||
|> try_render("status.json", %{ | |||
activity: activity, | |||
for: user, | |||
as: :activity, | |||
with_direct_conversation_id: true | |||
}) | |||
end | |||
end | |||
end | |||
@@ -74,10 +74,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||
user_info = User.get_cached_user_info(user) | |||
following_count = | |||
((!user.info.hide_follows or opts[:for] == user) && user_info.following_count) || 0 | |||
if !user.info.hide_follows_count or !user.info.hide_follows or opts[:for] == user do | |||
user_info.following_count | |||
else | |||
0 | |||
end | |||
followers_count = | |||
((!user.info.hide_followers or opts[:for] == user) && user_info.follower_count) || 0 | |||
if !user.info.hide_followers_count or !user.info.hide_followers or opts[:for] == user do | |||
user_info.follower_count | |||
else | |||
0 | |||
end | |||
bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"] | |||
@@ -138,6 +146,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||
pleroma: %{ | |||
confirmation_pending: user_info.confirmation_pending, | |||
tags: user.tags, | |||
hide_followers_count: user.info.hide_followers_count, | |||
hide_follows_count: user.info.hide_follows_count, | |||
hide_followers: user.info.hide_followers, | |||
hide_follows: user.info.hide_follows, | |||
hide_favorites: user.info.hide_favorites, | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.OAuth.Token.CleanWorker do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.OAuth.Token.Query do | |||
@@ -3,14 +3,12 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.OStatus do | |||
import Ecto.Query | |||
import Pleroma.Web.XML | |||
require Logger | |||
alias Pleroma.Activity | |||
alias Pleroma.HTTP | |||
alias Pleroma.Object | |||
alias Pleroma.Repo | |||
alias Pleroma.User | |||
alias Pleroma.Web | |||
alias Pleroma.Web.ActivityPub.ActivityPub | |||
@@ -38,21 +36,13 @@ defmodule Pleroma.Web.OStatus do | |||
end | |||
end | |||
def feed_path(user) do | |||
"#{user.ap_id}/feed.atom" | |||
end | |||
def feed_path(user), do: "#{user.ap_id}/feed.atom" | |||
def pubsub_path(user) do | |||
"#{Web.base_url()}/push/hub/#{user.nickname}" | |||
end | |||
def pubsub_path(user), do: "#{Web.base_url()}/push/hub/#{user.nickname}" | |||
def salmon_path(user) do | |||
"#{user.ap_id}/salmon" | |||
end | |||
def salmon_path(user), do: "#{user.ap_id}/salmon" | |||
def remote_follow_path do | |||
"#{Web.base_url()}/ostatus_subscribe?acct={uri}" | |||
end | |||
def remote_follow_path, do: "#{Web.base_url()}/ostatus_subscribe?acct={uri}" | |||
def handle_incoming(xml_string, options \\ []) do | |||
with doc when doc != :error <- parse_document(xml_string) do | |||
@@ -217,10 +207,9 @@ defmodule Pleroma.Web.OStatus do | |||
Get the cw that mastodon uses. | |||
""" | |||
def get_cw(entry) do | |||
with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do | |||
cw | |||
else | |||
_e -> nil | |||
case string_from_xpath("/*/summary", entry) do | |||
cw when not is_nil(cw) -> cw | |||
_ -> nil | |||
end | |||
end | |||
@@ -232,19 +221,17 @@ defmodule Pleroma.Web.OStatus do | |||
end | |||
def maybe_update(doc, user) do | |||
if "true" == string_from_xpath("//author[1]/ap_enabled", doc) do | |||
Transmogrifier.upgrade_user_from_ap_id(user.ap_id) | |||
else | |||
maybe_update_ostatus(doc, user) | |||
case string_from_xpath("//author[1]/ap_enabled", doc) do | |||
"true" -> | |||
Transmogrifier.upgrade_user_from_ap_id(user.ap_id) | |||
_ -> | |||
maybe_update_ostatus(doc, user) | |||
end | |||
end | |||
def maybe_update_ostatus(doc, user) do | |||
old_data = %{ | |||
avatar: user.avatar, | |||
bio: user.bio, | |||
name: user.name | |||
} | |||
old_data = Map.take(user, [:bio, :avatar, :name]) | |||
with false <- user.local, | |||
avatar <- make_avatar_object(doc), | |||
@@ -279,38 +266,37 @@ defmodule Pleroma.Web.OStatus do | |||
end | |||
end | |||
@spec find_or_make_user(String.t()) :: {:ok, User.t()} | |||
def find_or_make_user(uri) do | |||
query = from(user in User, where: user.ap_id == ^uri) | |||
user = Repo.one(query) | |||
if is_nil(user) do | |||
make_user(uri) | |||
else | |||
{:ok, user} | |||
case User.get_by_ap_id(uri) do | |||
%User{} = user -> {:ok, user} | |||
_ -> make_user(uri) | |||
end | |||
end | |||
@spec make_user(String.t(), boolean()) :: {:ok, User.t()} | {:error, any()} | |||
def make_user(uri, update \\ false) do | |||
with {:ok, info} <- gather_user_info(uri) do | |||
data = %{ | |||
name: info["name"], | |||
nickname: info["nickname"] <> "@" <> info["host"], | |||
ap_id: info["uri"], | |||
info: info, | |||
avatar: info["avatar"], | |||
bio: info["bio"] | |||
} | |||
with false <- update, | |||
%User{} = user <- User.get_cached_by_ap_id(data.ap_id) do | |||
%User{} = user <- User.get_cached_by_ap_id(info["uri"]) do | |||
{:ok, user} | |||
else | |||
_e -> User.insert_or_update_user(data) | |||
_e -> User.insert_or_update_user(build_user_data(info)) | |||
end | |||
end | |||
end | |||
defp build_user_data(info) do | |||
%{ | |||
name: info["name"], | |||
nickname: info["nickname"] <> "@" <> info["host"], | |||
ap_id: info["uri"], | |||
info: info, | |||
avatar: info["avatar"], | |||
bio: info["bio"] | |||
} | |||
end | |||
# TODO: Just takes the first one for now. | |||
def make_avatar_object(author_doc, rel \\ "avatar") do | |||
href = string_from_xpath("//author[1]/link[@rel=\"#{rel}\"]/@href", author_doc) | |||
@@ -319,23 +305,23 @@ defmodule Pleroma.Web.OStatus do | |||
if href do | |||
%{ | |||
"type" => "Image", | |||
"url" => [ | |||
%{ | |||
"type" => "Link", | |||
"mediaType" => type, | |||
"href" => href | |||
} | |||
] | |||
"url" => [%{"type" => "Link", "mediaType" => type, "href" => href}] | |||
} | |||
else | |||
nil | |||
end | |||
end | |||
@spec gather_user_info(String.t()) :: {:ok, map()} | {:error, any()} | |||
def gather_user_info(username) do | |||
with {:ok, webfinger_data} <- WebFinger.finger(username), | |||
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do | |||
{:ok, Map.merge(webfinger_data, feed_data) |> Map.put("fqn", username)} | |||
data = | |||
webfinger_data | |||
|> Map.merge(feed_data) | |||
|> Map.put("fqn", username) | |||
{:ok, data} | |||
else | |||
e -> | |||
Logger.debug(fn -> "Couldn't gather info for #{username}" end) | |||
@@ -371,10 +357,7 @@ defmodule Pleroma.Web.OStatus do | |||
def fetch_activity_from_atom_url(url, options \\ []) do | |||
with true <- String.starts_with?(url, "http"), | |||
{:ok, %{body: body, status: code}} when code in 200..299 <- | |||
HTTP.get( | |||
url, | |||
[{:Accept, "application/atom+xml"}] | |||
) do | |||
HTTP.get(url, [{:Accept, "application/atom+xml"}]) do | |||
Logger.debug("Got document from #{url}, handling...") | |||
handle_incoming(body, options) | |||
else | |||
@@ -55,12 +55,11 @@ defmodule Pleroma.Web.OStatus.OStatusController do | |||
def feed(conn, %{"nickname" => nickname} = params) do | |||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do | |||
query_params = | |||
Map.take(params, ["max_id"]) | |||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) | |||
activities = | |||
ActivityPub.fetch_public_activities(query_params) | |||
params | |||
|> Map.take(["max_id"]) | |||
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) | |||
|> ActivityPub.fetch_public_activities() | |||
|> Enum.reverse() | |||
response = | |||
@@ -98,8 +97,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do | |||
Federator.incoming_doc(doc) | |||
conn | |||
|> send_resp(200, "") | |||
send_resp(conn, 200, "") | |||
end | |||
def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid}) | |||
@@ -180,7 +180,7 @@ defmodule Pleroma.Web.Router do | |||
post("/relay", AdminAPIController, :relay_follow) | |||
delete("/relay", AdminAPIController, :relay_unfollow) | |||
get("/users/invite_token", AdminAPIController, :get_invite_token) | |||
post("/users/invite_token", AdminAPIController, :create_invite_token) | |||
get("/users/invites", AdminAPIController, :invites) | |||
post("/users/revoke_invite", AdminAPIController, :revoke_invite) | |||
post("/users/email_invite", AdminAPIController, :email_invite) | |||
@@ -174,7 +174,8 @@ defmodule Pleroma.Mixfile do | |||
"ecto.rollback": ["pleroma.ecto.rollback"], | |||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], | |||
"ecto.reset": ["ecto.drop", "ecto.setup"], | |||
test: ["ecto.create --quiet", "ecto.migrate", "test"] | |||
test: ["ecto.create --quiet", "ecto.migrate", "test"], | |||
docs: ["pleroma.docs", "docs"] | |||
] | |||
end | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ActivityTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.CaptchaTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ConfigTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ActivityExpirationWorkerTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ScheduledActivityDaemonTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Emails.AdminEmailTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Emails.MailerTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Emails.UserEmailTest do | |||
@@ -0,0 +1 @@ | |||
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":8,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":3,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"} |
@@ -0,0 +1 @@ | |||
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":4,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":0,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"} |
@@ -0,0 +1 @@ | |||
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"attachment":[],"endpoints":{"oauthAuthorizationEndpoint":"https://patch.cx/oauth/authorize","oauthRegistrationEndpoint":"https://patch.cx/api/v1/apps","oauthTokenEndpoint":"https://patch.cx/oauth/token","sharedInbox":"https://patch.cx/inbox"},"followers":"https://patch.cx/users/rin/followers","following":"https://patch.cx/users/rin/following","icon":{"type":"Image","url":"https://patch.cx/media/4e914f5b84e4a259a3f6c2d2edc9ab642f2ab05f3e3d9c52c81fc2d984b3d51e.jpg"},"id":"https://patch.cx/users/rin","image":{"type":"Image","url":"https://patch.cx/media/f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg?name=f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg"},"inbox":"https://patch.cx/users/rin/inbox","manuallyApprovesFollowers":false,"name":"rinpatch","outbox":"https://patch.cx/users/rin/outbox","preferredUsername":"rin","publicKey":{"id":"https://patch.cx/users/rin#main-key","owner":"https://patch.cx/users/rin","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"},"summary":"your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts","tag":[],"type":"Person","url":"https://patch.cx/users/rin"} |
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.FormatterTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.HTMLTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Integration.MastodonWebsocketTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ListTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.NotificationTest do | |||
@@ -1,13 +1,16 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ObjectTest do | |||
use Pleroma.DataCase | |||
import ExUnit.CaptureLog | |||
import Pleroma.Factory | |||
import Tesla.Mock | |||
alias Pleroma.Activity | |||
alias Pleroma.Object | |||
alias Pleroma.Repo | |||
alias Pleroma.Web.CommonAPI | |||
setup do | |||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end) | |||
@@ -89,4 +92,110 @@ defmodule Pleroma.ObjectTest do | |||
) | |||
end | |||
end | |||
describe "get_by_id_and_maybe_refetch" do | |||
setup do | |||
mock(fn | |||
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} -> | |||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/poll_original.json")} | |||
env -> | |||
apply(HttpRequestMock, :request, [env]) | |||
end) | |||
mock_modified = fn resp -> | |||
mock(fn | |||
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} -> | |||
resp | |||
env -> | |||
apply(HttpRequestMock, :request, [env]) | |||
end) | |||
end | |||
on_exit(fn -> mock(fn env -> apply(HttpRequestMock, :request, [env]) end) end) | |||
[mock_modified: mock_modified] | |||
end | |||
test "refetches if the time since the last refetch is greater than the interval", %{ | |||
mock_modified: mock_modified | |||
} do | |||
%Object{} = | |||
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d") | |||
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
mock_modified.(%Tesla.Env{ | |||
status: 200, | |||
body: File.read!("test/fixtures/tesla_mock/poll_modified.json") | |||
}) | |||
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1) | |||
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8 | |||
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3 | |||
end | |||
test "returns the old object if refetch fails", %{mock_modified: mock_modified} do | |||
%Object{} = | |||
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d") | |||
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
assert capture_log(fn -> | |||
mock_modified.(%Tesla.Env{status: 404, body: ""}) | |||
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1) | |||
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
end) =~ | |||
"[error] Couldn't refresh https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d" | |||
end | |||
test "does not refetch if the time since the last refetch is greater than the interval", %{ | |||
mock_modified: mock_modified | |||
} do | |||
%Object{} = | |||
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d") | |||
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
mock_modified.(%Tesla.Env{ | |||
status: 200, | |||
body: File.read!("test/fixtures/tesla_mock/poll_modified.json") | |||
}) | |||
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: 100) | |||
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
end | |||
test "preserves internal fields on refetch", %{mock_modified: mock_modified} do | |||
%Object{} = | |||
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d") | |||
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4 | |||
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0 | |||
user = insert(:user) | |||
activity = Activity.get_create_by_object_ap_id(object.data["id"]) | |||
{:ok, _activity, object} = CommonAPI.favorite(activity.id, user) | |||
assert object.data["like_count"] == 1 | |||
mock_modified.(%Tesla.Env{ | |||
status: 200, | |||
body: File.read!("test/fixtures/tesla_mock/poll_modified.json") | |||
}) | |||
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1) | |||
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8 | |||
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3 | |||
assert updated_object.data["like_count"] == 1 | |||
end | |||
end | |||
end |
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.CacheControlTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.RuntimeStaticPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.OAuthPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.OAuthScopesPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.SetFormatPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Plugs.SetLocalePlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.UploadedMediaPlugTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.ScheduledActivityTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Captcha.Mock do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ConnCase do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.DataCase do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Tests.Helpers do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule HttpRequestMock do | |||
@@ -1004,6 +1004,10 @@ defmodule HttpRequestMock do | |||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}} | |||
end | |||
def get("https://patch.cx/users/rin", _, _, _) do | |||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}} | |||
end | |||
def get(url, query, body, headers) do | |||
{:error, | |||
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule MRFModuleMock do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Tests.ObanHelpers do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.WebPushHttpClientMock do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-onl | |||
defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.RelayTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Mix.Tasks.Pleroma.UserTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: [] | |||
@@ -7,3 +7,8 @@ ExUnit.start(exclude: os_exclude) | |||
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual) | |||
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client) | |||
{:ok, _} = Application.ensure_all_started(:ex_machina) | |||
ExUnit.after_suite(fn _results -> | |||
uploads = Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads], "test/uploads") | |||
File.rm_rf!(uploads) | |||
end) |
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.UploadTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.UserSearchTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.UserTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ActivityPub.RelayTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do | |||
@@ -105,10 +105,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do | |||
other_user = insert(:user) | |||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | |||
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) | |||
info = Map.put(user.info, :hide_followers, true) | |||
info = Map.merge(user.info, %{hide_followers_count: true, hide_followers: true}) | |||
user = Map.put(user, :info, info) | |||
assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user}) | |||
end | |||
test "sets correct totalItems when followers are hidden but the follower counter is not" do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | |||
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) | |||
info = Map.merge(user.info, %{hide_followers_count: false, hide_followers: true}) | |||
user = Map.put(user, :info, info) | |||
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) | |||
end | |||
end | |||
describe "following" do | |||
@@ -117,9 +127,42 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do | |||
other_user = insert(:user) | |||
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user) | |||
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) | |||
info = Map.put(user.info, :hide_follows, true) | |||
info = Map.merge(user.info, %{hide_follows_count: true, hide_follows: true}) | |||
user = Map.put(user, :info, info) | |||
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user}) | |||
end | |||
test "sets correct totalItems when follows are hidden but the follow counter is not" do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user) | |||
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) | |||
info = Map.merge(user.info, %{hide_follows_count: false, hide_follows: true}) | |||
user = Map.put(user, :info, info) | |||
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) | |||
end | |||
end | |||
test "outbox paginates correctly" do | |||
user = insert(:user) | |||
posts = | |||
for i <- 0..25 do | |||
{:ok, activity} = CommonAPI.post(user, %{"status" => "post #{i}"}) | |||
activity | |||
end | |||
# outbox sorts chronologically, newest first, with ten per page | |||
posts = Enum.reverse(posts) | |||
%{"first" => %{"next" => next_url}} = | |||
UserView.render("outbox.json", %{user: user, max_id: nil}) | |||
next_id = Enum.at(posts, 9).id | |||
assert next_url =~ next_id | |||
%{"next" => next_url} = UserView.render("outbox.json", %{user: user, max_id: next_id}) | |||
next_id = Enum.at(posts, 19).id | |||
assert next_url =~ next_id | |||
end | |||
end |
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
@@ -574,18 +574,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
end | |||
end | |||
test "/api/pleroma/admin/users/invite_token" do | |||
admin = insert(:user, info: %{is_admin: true}) | |||
conn = | |||
build_conn() | |||
|> assign(:user, admin) | |||
|> put_req_header("accept", "application/json") | |||
|> get("/api/pleroma/admin/users/invite_token") | |||
assert conn.status == 200 | |||
end | |||
test "/api/pleroma/admin/users/:nickname/password_reset" do | |||
admin = insert(:user, info: %{is_admin: true}) | |||
user = insert(:user) | |||
@@ -1066,7 +1054,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
"@#{admin.nickname} deactivated user @#{user.nickname}" | |||
end | |||
describe "GET /api/pleroma/admin/users/invite_token" do | |||
describe "POST /api/pleroma/admin/users/invite_token" do | |||
setup do | |||
admin = insert(:user, info: %{is_admin: true}) | |||
@@ -1078,10 +1066,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
end | |||
test "without options", %{conn: conn} do | |||
conn = get(conn, "/api/pleroma/admin/users/invite_token") | |||
conn = post(conn, "/api/pleroma/admin/users/invite_token") | |||
token = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(token) | |||
invite_json = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(invite_json["token"]) | |||
refute invite.used | |||
refute invite.expires_at | |||
refute invite.max_use | |||
@@ -1090,12 +1078,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
test "with expires_at", %{conn: conn} do | |||
conn = | |||
get(conn, "/api/pleroma/admin/users/invite_token", %{ | |||
"invite" => %{"expires_at" => Date.to_string(Date.utc_today())} | |||
post(conn, "/api/pleroma/admin/users/invite_token", %{ | |||
"expires_at" => Date.to_string(Date.utc_today()) | |||
}) | |||
token = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(token) | |||
invite_json = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(invite_json["token"]) | |||
refute invite.used | |||
assert invite.expires_at == Date.utc_today() | |||
@@ -1104,13 +1092,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
end | |||
test "with max_use", %{conn: conn} do | |||
conn = | |||
get(conn, "/api/pleroma/admin/users/invite_token", %{ | |||
"invite" => %{"max_use" => 150} | |||
}) | |||
conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150}) | |||
token = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(token) | |||
invite_json = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(invite_json["token"]) | |||
refute invite.used | |||
refute invite.expires_at | |||
assert invite.max_use == 150 | |||
@@ -1119,12 +1104,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
test "with max use and expires_at", %{conn: conn} do | |||
conn = | |||
get(conn, "/api/pleroma/admin/users/invite_token", %{ | |||
"invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())} | |||
post(conn, "/api/pleroma/admin/users/invite_token", %{ | |||
"max_use" => 150, | |||
"expires_at" => Date.to_string(Date.utc_today()) | |||
}) | |||
token = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(token) | |||
invite_json = json_response(conn, 200) | |||
invite = UserInviteToken.find_by_token!(invite_json["token"]) | |||
refute invite.used | |||
assert invite.expires_at == Date.utc_today() | |||
assert invite.max_use == 150 | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.AdminAPI.SearchTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.CommonAPI.UtilsTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.FederatorTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Instances.InstanceTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.InstancesTest do | |||
@@ -128,6 +128,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do | |||
assert user["pleroma"]["hide_followers"] == true | |||
end | |||
test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> patch("/api/v1/accounts/update_credentials", %{ | |||
hide_followers_count: "true", | |||
hide_follows_count: "true" | |||
}) | |||
assert user = json_response(conn, 200) | |||
assert user["pleroma"]["hide_followers_count"] == true | |||
assert user["pleroma"]["hide_follows_count"] == true | |||
end | |||
test "updates the user's skip_thread_containment option", %{conn: conn} do | |||
user = insert(:user) | |||
@@ -296,7 +296,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
conn | |||
|> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"}) | |||
assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200) | |||
assert %{"id" => id} = response = json_response(conn, 200) | |||
assert response["visibility"] == "direct" | |||
assert response["pleroma"]["direct_conversation_id"] | |||
assert activity = Activity.get_by_id(id) | |||
assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id] | |||
assert activity.data["to"] == [user2.ap_id] | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
@@ -79,6 +79,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
hide_favorites: true, | |||
hide_followers: false, | |||
hide_follows: false, | |||
hide_followers_count: false, | |||
hide_follows_count: false, | |||
relationship: %{}, | |||
skip_thread_containment: false | |||
} | |||
@@ -147,6 +149,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
hide_favorites: true, | |||
hide_followers: false, | |||
hide_follows: false, | |||
hide_followers_count: false, | |||
hide_follows_count: false, | |||
relationship: %{}, | |||
skip_thread_containment: false | |||
} | |||
@@ -318,6 +322,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
hide_favorites: true, | |||
hide_followers: false, | |||
hide_follows: false, | |||
hide_followers_count: false, | |||
hide_follows_count: false, | |||
relationship: %{ | |||
id: to_string(user.id), | |||
following: false, | |||
@@ -361,8 +367,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
end | |||
describe "hiding follows/following" do | |||
test "shows when follows/following are hidden and sets follower/following count to 0" do | |||
user = insert(:user, info: %{hide_followers: true, hide_follows: true}) | |||
test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do | |||
info = %{ | |||
hide_followers: true, | |||
hide_followers_count: true, | |||
hide_follows: true, | |||
hide_follows_count: true | |||
} | |||
user = insert(:user, info: info) | |||
other_user = insert(:user) | |||
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) | |||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | |||
@@ -370,6 +384,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||
assert %{ | |||
followers_count: 0, | |||
following_count: 0, | |||
pleroma: %{hide_follows_count: true, hide_followers_count: true} | |||
} = AccountView.render("account.json", %{user: user}) | |||
end | |||
test "shows when follows/followers are hidden" do | |||
user = insert(:user, info: %{hide_followers: true, hide_follows: true}) | |||
other_user = insert(:user) | |||
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) | |||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | |||
assert %{ | |||
followers_count: 1, | |||
following_count: 1, | |||
pleroma: %{hide_follows: true, hide_followers: true} | |||
} = AccountView.render("account.json", %{user: user}) | |||
end | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.ListViewTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.StatusViewTest do | |||
@@ -1,5 +1,5 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do | |||