@@ -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/). | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | ||||
## [Unreleased] | ## [Unreleased] | ||||
### Added | |||||
- Refreshing poll results for remote polls | |||||
### Changed | ### Changed | ||||
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7) | - **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) | - 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 | - Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler | ||||
- Admin API: Return `total` when querying for reports | - 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-??-?? | ## [1.1.0] - 2019-??-?? | ||||
### Security | ### 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: 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:** 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/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: 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 | - 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 `skipThreadContainment` in `metadata` for the `skip_thread_containment` option | ||||
- NodeInfo: Return `mailerEnabled` in `metadata` | - 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: 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: /api/v1/accounts/:id/statuses now supports nicknames or user id | ||||
- Mastodon API: Improve support for the user profile custom fields | - 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 users' tags when querying reports | ||||
- Admin API: Return avatar and display name when querying users | - Admin API: Return avatar and display name when querying users | ||||
- Admin API: Allow querying user by ID | - 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` | ## `/api/pleroma/admin/users/invite_token` | ||||
### Get an account registration invite token | |||||
### Create an account registration invite token | |||||
- Methods: `GET` | |||||
- Methods: `POST` | |||||
- Params: | - 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` | ## `/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: | Has these additional fields under the `pleroma` object: | ||||
- `local`: true if the post was made on the local instance | - `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) | - `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` | - `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` | - `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 | - `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_followers`: boolean, true when the user has follower hiding enabled | ||||
- `hide_follows`: boolean, true when the user has follow 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` | - `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` | - `chat_token`: The token needed for Pleroma chat. Only returned in `verify_credentials` | ||||
- `deactivated`: boolean, true when the user is deactivated | - `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 | - `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_followers` - if true, user's followers will be hidden | ||||
- `hide_follows` - if true, user's follows 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 | - `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 | - `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 | - `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 | ### 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/) | - 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) | - Contact: [@lin@pleroma.gdgd.jp.net](https://pleroma.gdgd.jp.net/users/lin) | ||||
- Platforms: Android | - Platforms: Android | ||||
- Features: Streaming Ready | - Features: Streaming Ready | ||||
@@ -67,7 +67,7 @@ Feel free to contact us to be added to this list! | |||||
## Alternative Web Interfaces | ## Alternative Web Interfaces | ||||
### Brutaldon | ### Brutaldon | ||||
- Homepage: <https://jfm.carcosa.net/projects/software/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) | - Contact: [@gcupc@glitch.social](https://glitch.social/users/gcupc) | ||||
- Features: No Streaming | - 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 | %% If TLS is compiled in and you installed a SSL | ||||
@@ -246,7 +248,9 @@ | |||||
%% {max_stanza_size, 65536} | %% {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}, | {shaper, s2s_shaper}, | ||||
{max_stanza_size, 131072}, | {max_stanza_size, 131072}, | ||||
{protocol_options, ["no_sslv3"]} | {protocol_options, ["no_sslv3"]} | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Pleroma do | defmodule Mix.Pleroma do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.Database do | defmodule Mix.Tasks.Pleroma.Database do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-onl | ||||
defmodule Mix.Tasks.Pleroma.Ecto do | defmodule Mix.Tasks.Pleroma.Ecto do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-onl | ||||
defmodule Mix.Tasks.Pleroma.Ecto.Migrate do | defmodule Mix.Tasks.Pleroma.Ecto.Migrate do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-onl | ||||
defmodule Mix.Tasks.Pleroma.Ecto.Rollback do | defmodule Mix.Tasks.Pleroma.Ecto.Rollback do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.Emoji do | defmodule Mix.Tasks.Pleroma.Emoji do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.Instance do | defmodule Mix.Tasks.Pleroma.Instance do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.Relay do | defmodule Mix.Tasks.Pleroma.Relay do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.Uploads do | defmodule Mix.Tasks.Pleroma.Uploads do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.User do | defmodule Mix.Tasks.Pleroma.User do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Activity.Queries do | defmodule Pleroma.Activity.Queries do | ||||
@@ -6,4 +6,16 @@ defmodule Pleroma.Constants do | |||||
use Const | use Const | ||||
const(as_public, do: "https://www.w3.org/ns/activitystreams#Public") | 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 | end |
@@ -23,7 +23,7 @@ defmodule Pleroma.Docs.Markdown do | |||||
IO.write(file, "#{group[:description]}\n") | IO.write(file, "#{group[:description]}\n") | ||||
for child <- group[:children] do | |||||
for child <- group[:children] || [] do | |||||
print_child_header(file, child) | print_child_header(file, child) | ||||
print_suggestions(file, child[:suggestions]) | print_suggestions(file, child[:suggestions]) | ||||
@@ -44,6 +44,17 @@ defmodule Pleroma.Docs.Markdown do | |||||
{:ok, config_path} | {:ok, config_path} | ||||
end | 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 | defp print_suggestion(file, suggestion) when is_list(suggestion) do | ||||
IO.write(file, " `#{inspect(suggestion)}`\n") | IO.write(file, " `#{inspect(suggestion)}`\n") | ||||
end | end | ||||
@@ -59,20 +70,19 @@ defmodule Pleroma.Docs.Markdown do | |||||
defp print_suggestions(_file, nil), do: nil | 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 | if length(suggestions) > 1 do | ||||
IO.write(file, "Suggestions:\n") | |||||
for suggestion <- suggestions do | for suggestion <- suggestions do | ||||
print_suggestion(file, suggestion, true) | print_suggestion(file, suggestion, true) | ||||
end | end | ||||
else | else | ||||
IO.write(file, " Suggestion: ") | |||||
print_suggestion(file, List.first(suggestions)) | print_suggestion(file, List.first(suggestions)) | ||||
end | end | ||||
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 | end |
@@ -38,6 +38,24 @@ defmodule Pleroma.Object do | |||||
def get_by_id(nil), do: nil | def get_by_id(nil), do: nil | ||||
def get_by_id(id), do: Repo.get(Object, id) | 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(nil), do: nil | ||||
def get_by_ap_id(ap_id) do | def get_by_ap_id(ap_id) do | ||||
@@ -6,18 +6,39 @@ defmodule Pleroma.Object.Fetcher do | |||||
alias Pleroma.HTTP | alias Pleroma.HTTP | ||||
alias Pleroma.Object | alias Pleroma.Object | ||||
alias Pleroma.Object.Containment | alias Pleroma.Object.Containment | ||||
alias Pleroma.Repo | |||||
alias Pleroma.Signature | alias Pleroma.Signature | ||||
alias Pleroma.Web.ActivityPub.InternalFetchActor | alias Pleroma.Web.ActivityPub.InternalFetchActor | ||||
alias Pleroma.Web.ActivityPub.Transmogrifier | alias Pleroma.Web.ActivityPub.Transmogrifier | ||||
alias Pleroma.Web.OStatus | alias Pleroma.Web.OStatus | ||||
require Logger | 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"]}") | Logger.debug("Reinjecting object #{data["id"]}") | ||||
with data <- Transmogrifier.fix_object(data), | 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} | {:ok, object} | ||||
else | else | ||||
e -> | e -> | ||||
@@ -26,6 +47,17 @@ defmodule Pleroma.Object.Fetcher do | |||||
end | end | ||||
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: | # TODO: | ||||
# This will create a Create activity, which we need internally at the moment. | # This will create a Create activity, which we need internally at the moment. | ||||
def fetch_object_from_id(id, options \\ []) do | def fetch_object_from_id(id, options \\ []) do | ||||
@@ -57,7 +89,7 @@ defmodule Pleroma.Object.Fetcher do | |||||
{:reject, nil} | {:reject, nil} | ||||
{:object, data, nil} -> | {:object, data, nil} -> | ||||
reinject_object(data) | |||||
reinject_object(%Object{}, data) | |||||
{:normalize, object = %Object{}} -> | {:normalize, object = %Object{}} -> | ||||
{:ok, object} | {:ok, object} | ||||
@@ -41,6 +41,8 @@ defmodule Pleroma.User.Info do | |||||
field(:topic, :string, default: nil) | field(:topic, :string, default: nil) | ||||
field(:hub, :string, default: nil) | field(:hub, :string, default: nil) | ||||
field(:salmon, :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_followers, :boolean, default: false) | ||||
field(:hide_follows, :boolean, default: false) | field(:hide_follows, :boolean, default: false) | ||||
field(:hide_favorites, :boolean, default: true) | field(:hide_favorites, :boolean, default: true) | ||||
@@ -262,6 +264,8 @@ defmodule Pleroma.User.Info do | |||||
:salmon, | :salmon, | ||||
:hide_followers, | :hide_followers, | ||||
:hide_follows, | :hide_follows, | ||||
:hide_followers_count, | |||||
:hide_follows_count, | |||||
:follower_count, | :follower_count, | ||||
:fields, | :fields, | ||||
:following_count | :following_count | ||||
@@ -281,7 +285,9 @@ defmodule Pleroma.User.Info do | |||||
:following_count, | :following_count, | ||||
:hide_follows, | :hide_follows, | ||||
:fields, | :fields, | ||||
:hide_followers | |||||
:hide_followers, | |||||
:hide_followers_count, | |||||
:hide_follows_count | |||||
]) | ]) | ||||
|> validate_fields(remote?) | |> validate_fields(remote?) | ||||
end | end | ||||
@@ -295,6 +301,8 @@ defmodule Pleroma.User.Info do | |||||
:banner, | :banner, | ||||
:hide_follows, | :hide_follows, | ||||
:hide_followers, | :hide_followers, | ||||
:hide_followers_count, | |||||
:hide_follows_count, | |||||
:hide_favorites, | :hide_favorites, | ||||
:background, | :background, | ||||
:show_role, | :show_role, | ||||
@@ -458,7 +466,9 @@ defmodule Pleroma.User.Info do | |||||
:hide_followers, | :hide_followers, | ||||
:hide_follows, | :hide_follows, | ||||
:follower_count, | :follower_count, | ||||
:following_count | |||||
:following_count, | |||||
:hide_followers_count, | |||||
:hide_follows_count | |||||
]) | ]) | ||||
end | end | ||||
end | end |
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.User.Query do | defmodule Pleroma.User.Query do | ||||
@@ -979,15 +979,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||||
defp strip_internal_fields(object) do | defp strip_internal_fields(object) do | ||||
object | object | ||||
|> Map.drop([ | |||||
"likes", | |||||
"like_count", | |||||
"announcements", | |||||
"announcement_count", | |||||
"emoji", | |||||
"context_id", | |||||
"deleted_activity_id" | |||||
]) | |||||
|> Map.drop(Pleroma.Constants.object_internal_fields()) | |||||
end | end | ||||
defp strip_internal_tags(%{"tag" => tags} = object) do | 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), | 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), | {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id), | ||||
already_ap <- User.ap_enabled?(user), | 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}) | TransmogrifierWorker.enqueue("user_upgrade", %{"user_id" => user.id}) | ||||
end | end | ||||
@@ -1062,6 +1054,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||||
end | end | ||||
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 | def maybe_retire_websub(ap_id) do | ||||
# some sanity checks | # some sanity checks | ||||
if is_binary(ap_id) && String.length(ap_id) > 8 do | if is_binary(ap_id) && String.length(ap_id) > 8 do | ||||
@@ -118,30 +118,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||||
end | end | ||||
def render("following.json", %{user: user, page: page} = opts) do | 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 = User.get_friends_query(user) | ||||
query = from(user in query, select: [:ap_id]) | query = from(user in query, select: [:ap_id]) | ||||
following = Repo.all(query) | following = Repo.all(query) | ||||
total = | total = | ||||
if showing do | |||||
if showing_count do | |||||
length(following) | length(following) | ||||
else | else | ||||
0 | 0 | ||||
end | 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()) | |> Map.merge(Utils.make_json_ld_header()) | ||||
end | end | ||||
def render("following.json", %{user: user} = opts) do | 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 = User.get_friends_query(user) | ||||
query = from(user in query, select: [:ap_id]) | query = from(user in query, select: [:ap_id]) | ||||
following = Repo.all(query) | following = Repo.all(query) | ||||
total = | total = | ||||
if showing do | |||||
if showing_count do | |||||
length(following) | length(following) | ||||
else | else | ||||
0 | 0 | ||||
@@ -152,7 +156,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||||
"type" => "OrderedCollection", | "type" => "OrderedCollection", | ||||
"totalItems" => total, | "totalItems" => total, | ||||
"first" => | "first" => | ||||
if showing do | |||||
if showing_items do | |||||
collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows) | collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows) | ||||
else | else | ||||
"#{user.ap_id}/following?page=1" | "#{user.ap_id}/following?page=1" | ||||
@@ -162,32 +166,34 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||||
end | end | ||||
def render("followers.json", %{user: user, page: page} = opts) do | 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 = User.get_followers_query(user) | ||||
query = from(user in query, select: [:ap_id]) | query = from(user in query, select: [:ap_id]) | ||||
followers = Repo.all(query) | followers = Repo.all(query) | ||||
total = | total = | ||||
if showing do | |||||
if showing_count do | |||||
length(followers) | length(followers) | ||||
else | else | ||||
0 | 0 | ||||
end | 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()) | |> Map.merge(Utils.make_json_ld_header()) | ||||
end | end | ||||
def render("followers.json", %{user: user} = opts) do | 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 = User.get_followers_query(user) | ||||
query = from(user in query, select: [:ap_id]) | query = from(user in query, select: [:ap_id]) | ||||
followers = Repo.all(query) | followers = Repo.all(query) | ||||
total = | total = | ||||
if showing do | |||||
if showing_count do | |||||
length(followers) | length(followers) | ||||
else | else | ||||
0 | 0 | ||||
@@ -198,8 +204,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||||
"type" => "OrderedCollection", | "type" => "OrderedCollection", | ||||
"totalItems" => total, | "totalItems" => total, | ||||
"first" => | "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 | else | ||||
"#{user.ap_id}/followers?page=1" | "#{user.ap_id}/followers?page=1" | ||||
end | end | ||||
@@ -221,11 +227,12 @@ defmodule Pleroma.Web.ActivityPub.UserView do | |||||
activities = ActivityPub.fetch_user_activities(user, nil, params) | activities = ActivityPub.fetch_user_activities(user, nil, params) | ||||
# this is sorted chronologically, so first activity is the newest (max) | |||||
{max_id, min_id, collection} = | {max_id, min_id, collection} = | ||||
if length(activities) > 0 do | if length(activities) > 0 do | ||||
{ | { | ||||
Enum.at(Enum.reverse(activities), 0).id, | |||||
Enum.at(activities, 0).id, | Enum.at(activities, 0).id, | ||||
Enum.at(Enum.reverse(activities), 0).id, | |||||
Enum.map(activities, fn act -> | Enum.map(activities, fn act -> | ||||
{:ok, data} = Transmogrifier.prepare_outgoing(act.data) | {:ok, data} = Transmogrifier.prepare_outgoing(act.data) | ||||
data | data | ||||
@@ -402,13 +402,23 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
end | end | ||||
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 | end | ||||
@doc "Get list of created invites" | @doc "Get list of created invites" | ||||
@@ -147,6 +147,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||||
[ | [ | ||||
:no_rich_text, | :no_rich_text, | ||||
:locked, | :locked, | ||||
:hide_followers_count, | |||||
:hide_follows_count, | |||||
:hide_followers, | :hide_followers, | ||||
:hide_follows, | :hide_follows, | ||||
:hide_favorites, | :hide_favorites, | ||||
@@ -485,7 +487,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||||
end | end | ||||
def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do | 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"]), | %Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]), | ||||
true <- Visibility.visible_for_user?(activity, user) do | true <- Visibility.visible_for_user?(activity, user) do | ||||
conn | conn | ||||
@@ -609,7 +611,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||||
{:ok, activity} -> | {:ok, activity} -> | ||||
conn | conn | ||||
|> put_view(StatusView) | |> 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 | end | ||||
end | end | ||||
@@ -74,10 +74,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||||
user_info = User.get_cached_user_info(user) | user_info = User.get_cached_user_info(user) | ||||
following_count = | 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 = | 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"] | bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"] | ||||
@@ -138,6 +146,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||||
pleroma: %{ | pleroma: %{ | ||||
confirmation_pending: user_info.confirmation_pending, | confirmation_pending: user_info.confirmation_pending, | ||||
tags: user.tags, | 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_followers: user.info.hide_followers, | ||||
hide_follows: user.info.hide_follows, | hide_follows: user.info.hide_follows, | ||||
hide_favorites: user.info.hide_favorites, | hide_favorites: user.info.hide_favorites, | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.OAuth.Token.CleanWorker do | defmodule Pleroma.Web.OAuth.Token.CleanWorker do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.OAuth.Token.Query do | defmodule Pleroma.Web.OAuth.Token.Query do | ||||
@@ -3,14 +3,12 @@ | |||||
# SPDX-License-Identifier: AGPL-3.0-only | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.OStatus do | defmodule Pleroma.Web.OStatus do | ||||
import Ecto.Query | |||||
import Pleroma.Web.XML | import Pleroma.Web.XML | ||||
require Logger | require Logger | ||||
alias Pleroma.Activity | alias Pleroma.Activity | ||||
alias Pleroma.HTTP | alias Pleroma.HTTP | ||||
alias Pleroma.Object | alias Pleroma.Object | ||||
alias Pleroma.Repo | |||||
alias Pleroma.User | alias Pleroma.User | ||||
alias Pleroma.Web | alias Pleroma.Web | ||||
alias Pleroma.Web.ActivityPub.ActivityPub | alias Pleroma.Web.ActivityPub.ActivityPub | ||||
@@ -38,21 +36,13 @@ defmodule Pleroma.Web.OStatus do | |||||
end | end | ||||
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 | def handle_incoming(xml_string, options \\ []) do | ||||
with doc when doc != :error <- parse_document(xml_string) 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. | Get the cw that mastodon uses. | ||||
""" | """ | ||||
def get_cw(entry) do | 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 | ||||
end | end | ||||
@@ -232,19 +221,17 @@ defmodule Pleroma.Web.OStatus do | |||||
end | end | ||||
def maybe_update(doc, user) do | 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 | ||||
end | end | ||||
def maybe_update_ostatus(doc, user) do | 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, | with false <- user.local, | ||||
avatar <- make_avatar_object(doc), | avatar <- make_avatar_object(doc), | ||||
@@ -279,38 +266,37 @@ defmodule Pleroma.Web.OStatus do | |||||
end | end | ||||
end | end | ||||
@spec find_or_make_user(String.t()) :: {:ok, User.t()} | |||||
def find_or_make_user(uri) do | 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 | ||||
end | end | ||||
@spec make_user(String.t(), boolean()) :: {:ok, User.t()} | {:error, any()} | |||||
def make_user(uri, update \\ false) do | def make_user(uri, update \\ false) do | ||||
with {:ok, info} <- gather_user_info(uri) 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, | 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} | {:ok, user} | ||||
else | else | ||||
_e -> User.insert_or_update_user(data) | |||||
_e -> User.insert_or_update_user(build_user_data(info)) | |||||
end | end | ||||
end | 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. | # TODO: Just takes the first one for now. | ||||
def make_avatar_object(author_doc, rel \\ "avatar") do | def make_avatar_object(author_doc, rel \\ "avatar") do | ||||
href = string_from_xpath("//author[1]/link[@rel=\"#{rel}\"]/@href", author_doc) | href = string_from_xpath("//author[1]/link[@rel=\"#{rel}\"]/@href", author_doc) | ||||
@@ -319,23 +305,23 @@ defmodule Pleroma.Web.OStatus do | |||||
if href do | if href do | ||||
%{ | %{ | ||||
"type" => "Image", | "type" => "Image", | ||||
"url" => [ | |||||
%{ | |||||
"type" => "Link", | |||||
"mediaType" => type, | |||||
"href" => href | |||||
} | |||||
] | |||||
"url" => [%{"type" => "Link", "mediaType" => type, "href" => href}] | |||||
} | } | ||||
else | else | ||||
nil | nil | ||||
end | end | ||||
end | end | ||||
@spec gather_user_info(String.t()) :: {:ok, map()} | {:error, any()} | |||||
def gather_user_info(username) do | def gather_user_info(username) do | ||||
with {:ok, webfinger_data} <- WebFinger.finger(username), | with {:ok, webfinger_data} <- WebFinger.finger(username), | ||||
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do | {: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 | else | ||||
e -> | e -> | ||||
Logger.debug(fn -> "Couldn't gather info for #{username}" end) | 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 | def fetch_activity_from_atom_url(url, options \\ []) do | ||||
with true <- String.starts_with?(url, "http"), | with true <- String.starts_with?(url, "http"), | ||||
{:ok, %{body: body, status: code}} when code in 200..299 <- | {: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...") | Logger.debug("Got document from #{url}, handling...") | ||||
handle_incoming(body, options) | handle_incoming(body, options) | ||||
else | else | ||||
@@ -55,12 +55,11 @@ defmodule Pleroma.Web.OStatus.OStatusController do | |||||
def feed(conn, %{"nickname" => nickname} = params) do | def feed(conn, %{"nickname" => nickname} = params) do | ||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} 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 = | 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() | |> Enum.reverse() | ||||
response = | response = | ||||
@@ -98,8 +97,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do | |||||
Federator.incoming_doc(doc) | Federator.incoming_doc(doc) | ||||
conn | |||||
|> send_resp(200, "") | |||||
send_resp(conn, 200, "") | |||||
end | end | ||||
def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid}) | def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid}) | ||||
@@ -180,7 +180,7 @@ defmodule Pleroma.Web.Router do | |||||
post("/relay", AdminAPIController, :relay_follow) | post("/relay", AdminAPIController, :relay_follow) | ||||
delete("/relay", AdminAPIController, :relay_unfollow) | 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) | get("/users/invites", AdminAPIController, :invites) | ||||
post("/users/revoke_invite", AdminAPIController, :revoke_invite) | post("/users/revoke_invite", AdminAPIController, :revoke_invite) | ||||
post("/users/email_invite", AdminAPIController, :email_invite) | post("/users/email_invite", AdminAPIController, :email_invite) | ||||
@@ -174,7 +174,8 @@ defmodule Pleroma.Mixfile do | |||||
"ecto.rollback": ["pleroma.ecto.rollback"], | "ecto.rollback": ["pleroma.ecto.rollback"], | ||||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], | "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], | ||||
"ecto.reset": ["ecto.drop", "ecto.setup"], | "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 | end | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ActivityTest do | defmodule Pleroma.ActivityTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.CaptchaTest do | defmodule Pleroma.CaptchaTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ConfigTest do | defmodule Pleroma.ConfigTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ActivityExpirationWorkerTest do | defmodule Pleroma.ActivityExpirationWorkerTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ScheduledActivityDaemonTest do | defmodule Pleroma.ScheduledActivityDaemonTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Emails.AdminEmailTest do | defmodule Pleroma.Emails.AdminEmailTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Emails.MailerTest do | defmodule Pleroma.Emails.MailerTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Emails.UserEmailTest do | 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 | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.FormatterTest do | defmodule Pleroma.FormatterTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.HTMLTest do | defmodule Pleroma.HTMLTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Integration.MastodonWebsocketTest do | defmodule Pleroma.Integration.MastodonWebsocketTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ListTest do | defmodule Pleroma.ListTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.NotificationTest do | defmodule Pleroma.NotificationTest do | ||||
@@ -1,13 +1,16 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ObjectTest do | defmodule Pleroma.ObjectTest do | ||||
use Pleroma.DataCase | use Pleroma.DataCase | ||||
import ExUnit.CaptureLog | |||||
import Pleroma.Factory | import Pleroma.Factory | ||||
import Tesla.Mock | import Tesla.Mock | ||||
alias Pleroma.Activity | |||||
alias Pleroma.Object | alias Pleroma.Object | ||||
alias Pleroma.Repo | alias Pleroma.Repo | ||||
alias Pleroma.Web.CommonAPI | |||||
setup do | setup do | ||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end) | mock(fn env -> apply(HttpRequestMock, :request, [env]) end) | ||||
@@ -89,4 +92,110 @@ defmodule Pleroma.ObjectTest do | |||||
) | ) | ||||
end | end | ||||
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 | end |
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.AuthenticationPlugTest do | defmodule Pleroma.Plugs.AuthenticationPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.CacheControlTest do | defmodule Pleroma.Web.CacheControlTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do | defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do | defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do | defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.RuntimeStaticPlugTest do | defmodule Pleroma.Web.RuntimeStaticPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do | defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do | defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.OAuthPlugTest do | defmodule Pleroma.Plugs.OAuthPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.OAuthScopesPlugTest do | defmodule Pleroma.Plugs.OAuthScopesPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.SetFormatPlugTest do | defmodule Pleroma.Plugs.SetFormatPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Plugs.SetLocalePlugTest do | defmodule Pleroma.Plugs.SetLocalePlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.UploadedMediaPlugTest do | defmodule Pleroma.Web.UploadedMediaPlugTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.ScheduledActivityTest do | defmodule Pleroma.ScheduledActivityTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Captcha.Mock do | defmodule Pleroma.Captcha.Mock do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.ConnCase do | defmodule Pleroma.Web.ConnCase do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.DataCase do | defmodule Pleroma.DataCase do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Tests.Helpers do | defmodule Pleroma.Tests.Helpers do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule HttpRequestMock do | defmodule HttpRequestMock do | ||||
@@ -1004,6 +1004,10 @@ defmodule HttpRequestMock do | |||||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}} | {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}} | ||||
end | 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 | def get(url, query, body, headers) do | ||||
{:error, | {:error, | ||||
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ | "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule MRFModuleMock do | defmodule MRFModuleMock do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Tests.ObanHelpers do | defmodule Pleroma.Tests.ObanHelpers do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.WebPushHttpClientMock do | defmodule Pleroma.Web.WebPushHttpClientMock do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-onl | ||||
defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do | defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.RelayTest do | defmodule Mix.Tasks.Pleroma.RelayTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Mix.Tasks.Pleroma.UserTest do | defmodule Mix.Tasks.Pleroma.UserTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: [] | 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) | Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual) | ||||
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client) | Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client) | ||||
{:ok, _} = Application.ensure_all_started(:ex_machina) | {: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 | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.UploadTest do | defmodule Pleroma.UploadTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.UserSearchTest do | defmodule Pleroma.UserSearchTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.UserTest do | defmodule Pleroma.UserTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.ActivityPub.RelayTest do | defmodule Pleroma.Web.ActivityPub.RelayTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do | defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do | defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do | ||||
@@ -105,10 +105,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do | |||||
other_user = insert(:user) | other_user = insert(:user) | ||||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | ||||
assert %{"totalItems" => 1} = UserView.render("followers.json", %{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) | user = Map.put(user, :info, info) | ||||
assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user}) | assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user}) | ||||
end | 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 | end | ||||
describe "following" do | describe "following" do | ||||
@@ -117,9 +127,42 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do | |||||
other_user = insert(:user) | other_user = insert(:user) | ||||
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user) | {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user) | ||||
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: 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) | user = Map.put(user, :info, info) | ||||
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user}) | assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user}) | ||||
end | 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 | ||||
end | end |
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | ||||
@@ -574,18 +574,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
end | end | ||||
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 | test "/api/pleroma/admin/users/:nickname/password_reset" do | ||||
admin = insert(:user, info: %{is_admin: true}) | admin = insert(:user, info: %{is_admin: true}) | ||||
user = insert(:user) | user = insert(:user) | ||||
@@ -1066,7 +1054,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
"@#{admin.nickname} deactivated user @#{user.nickname}" | "@#{admin.nickname} deactivated user @#{user.nickname}" | ||||
end | end | ||||
describe "GET /api/pleroma/admin/users/invite_token" do | |||||
describe "POST /api/pleroma/admin/users/invite_token" do | |||||
setup do | setup do | ||||
admin = insert(:user, info: %{is_admin: true}) | admin = insert(:user, info: %{is_admin: true}) | ||||
@@ -1078,10 +1066,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
end | end | ||||
test "without options", %{conn: conn} do | 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.used | ||||
refute invite.expires_at | refute invite.expires_at | ||||
refute invite.max_use | refute invite.max_use | ||||
@@ -1090,12 +1078,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
test "with expires_at", %{conn: conn} do | test "with expires_at", %{conn: conn} do | ||||
conn = | 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 | refute invite.used | ||||
assert invite.expires_at == Date.utc_today() | assert invite.expires_at == Date.utc_today() | ||||
@@ -1104,13 +1092,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
end | end | ||||
test "with max_use", %{conn: conn} do | 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.used | ||||
refute invite.expires_at | refute invite.expires_at | ||||
assert invite.max_use == 150 | 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 | test "with max use and expires_at", %{conn: conn} do | ||||
conn = | 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 | refute invite.used | ||||
assert invite.expires_at == Date.utc_today() | assert invite.expires_at == Date.utc_today() | ||||
assert invite.max_use == 150 | assert invite.max_use == 150 | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.AdminAPI.SearchTest do | defmodule Pleroma.Web.AdminAPI.SearchTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.CommonAPI.UtilsTest do | defmodule Pleroma.Web.CommonAPI.UtilsTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.FederatorTest do | defmodule Pleroma.Web.FederatorTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Instances.InstanceTest do | defmodule Pleroma.Instances.InstanceTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.InstancesTest do | defmodule Pleroma.InstancesTest do | ||||
@@ -128,6 +128,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do | |||||
assert user["pleroma"]["hide_followers"] == true | assert user["pleroma"]["hide_followers"] == true | ||||
end | 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 | test "updates the user's skip_thread_containment option", %{conn: conn} do | ||||
user = insert(:user) | user = insert(:user) | ||||
@@ -296,7 +296,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||||
conn | conn | ||||
|> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"}) | |> 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 = Activity.get_by_id(id) | ||||
assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id] | assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id] | ||||
assert activity.data["to"] == [user2.ap_id] | assert activity.data["to"] == [user2.ap_id] | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | ||||
@@ -79,6 +79,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
hide_favorites: true, | hide_favorites: true, | ||||
hide_followers: false, | hide_followers: false, | ||||
hide_follows: false, | hide_follows: false, | ||||
hide_followers_count: false, | |||||
hide_follows_count: false, | |||||
relationship: %{}, | relationship: %{}, | ||||
skip_thread_containment: false | skip_thread_containment: false | ||||
} | } | ||||
@@ -147,6 +149,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
hide_favorites: true, | hide_favorites: true, | ||||
hide_followers: false, | hide_followers: false, | ||||
hide_follows: false, | hide_follows: false, | ||||
hide_followers_count: false, | |||||
hide_follows_count: false, | |||||
relationship: %{}, | relationship: %{}, | ||||
skip_thread_containment: false | skip_thread_containment: false | ||||
} | } | ||||
@@ -318,6 +322,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
hide_favorites: true, | hide_favorites: true, | ||||
hide_followers: false, | hide_followers: false, | ||||
hide_follows: false, | hide_follows: false, | ||||
hide_followers_count: false, | |||||
hide_follows_count: false, | |||||
relationship: %{ | relationship: %{ | ||||
id: to_string(user.id), | id: to_string(user.id), | ||||
following: false, | following: false, | ||||
@@ -361,8 +367,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
end | end | ||||
describe "hiding follows/following" do | 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) | other_user = insert(:user) | ||||
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) | {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) | ||||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) | ||||
@@ -370,6 +384,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
assert %{ | assert %{ | ||||
followers_count: 0, | followers_count: 0, | ||||
following_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} | pleroma: %{hide_follows: true, hide_followers: true} | ||||
} = AccountView.render("account.json", %{user: user}) | } = AccountView.render("account.json", %{user: user}) | ||||
end | end | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.ListViewTest do | defmodule Pleroma.Web.MastodonAPI.ListViewTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do | defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do | defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do | defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MastodonAPI.StatusViewTest do | defmodule Pleroma.Web.MastodonAPI.StatusViewTest do | ||||
@@ -1,5 +1,5 @@ | |||||
# Pleroma: A lightweight social networking server | # 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 | # SPDX-License-Identifier: AGPL-3.0-only | ||||
defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do | defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do | ||||