forked from AkkomaGang/akkoma
Merge remote-tracking branch 'remotes/origin/develop' into 1364-notifications-sending-control
This commit is contained in:
commit
012d428e1f
122 changed files with 1476 additions and 520 deletions
|
@ -62,19 +62,21 @@ unit-testing:
|
||||||
- mix ecto.migrate
|
- mix ecto.migrate
|
||||||
- mix coveralls --preload-modules
|
- mix coveralls --preload-modules
|
||||||
|
|
||||||
federated-testing:
|
# Removed to fix CI issue. In this early state it wasn't adding much value anyway.
|
||||||
stage: test
|
# TODO Fix and reinstate federated testing
|
||||||
cache: *testing_cache_policy
|
# federated-testing:
|
||||||
services:
|
# stage: test
|
||||||
- name: minibikini/postgres-with-rum:12
|
# cache: *testing_cache_policy
|
||||||
alias: postgres
|
# services:
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
# - name: minibikini/postgres-with-rum:12
|
||||||
script:
|
# alias: postgres
|
||||||
- mix deps.get
|
# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- mix ecto.create
|
# script:
|
||||||
- mix ecto.migrate
|
# - mix deps.get
|
||||||
- epmd -daemon
|
# - mix ecto.create
|
||||||
- mix test --trace --only federated
|
# - mix ecto.migrate
|
||||||
|
# - epmd -daemon
|
||||||
|
# - mix test --trace --only federated
|
||||||
|
|
||||||
unit-testing-rum:
|
unit-testing-rum:
|
||||||
stage: test
|
stage: test
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -7,6 +7,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Changed
|
### Changed
|
||||||
- **Breaking:** BBCode and Markdown formatters will no longer return any `\n` and only use `<br/>` for newlines
|
- **Breaking:** BBCode and Markdown formatters will no longer return any `\n` and only use `<br/>` for newlines
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- **Breaking:** removed `with_move` parameter from notifications timeline.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
|
||||||
|
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
||||||
|
<details>
|
||||||
|
<summary>API Changes</summary>
|
||||||
|
- Mastodon API: Support for `include_types` in `/api/v1/notifications`.
|
||||||
|
</details>
|
||||||
|
|
||||||
## [2.0.0] - 2019-03-08
|
## [2.0.0] - 2019-03-08
|
||||||
### Security
|
### Security
|
||||||
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
||||||
|
@ -67,6 +78,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
||||||
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
||||||
- Mastodon API: Limit timeline requests to 3 per timeline per 500ms per user/ip by default.
|
- Mastodon API: Limit timeline requests to 3 per timeline per 500ms per user/ip by default.
|
||||||
|
- Admin API: `PATCH /api/pleroma/admin/users/:nickname/credentials` and `GET /api/pleroma/admin/users/:nickname/credentials`
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -624,6 +624,11 @@
|
||||||
parameters: [gin_fuzzy_search_limit: "500"],
|
parameters: [gin_fuzzy_search_limit: "500"],
|
||||||
prepare: :unnamed
|
prepare: :unnamed
|
||||||
|
|
||||||
|
config :pleroma, :restrict_unauthenticated,
|
||||||
|
timelines: %{local: false, federated: false},
|
||||||
|
profiles: %{local: false, remote: false},
|
||||||
|
activities: %{local: false, remote: false}
|
||||||
|
|
||||||
# Import environment specific config. This must remain at the bottom
|
# Import environment specific config. This must remain at the bottom
|
||||||
# of this file so it overrides the configuration defined above.
|
# of this file so it overrides the configuration defined above.
|
||||||
import_config "#{Mix.env()}.exs"
|
import_config "#{Mix.env()}.exs"
|
||||||
|
|
|
@ -2915,5 +2915,65 @@
|
||||||
suggestions: [2]
|
suggestions: [2]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
group: :pleroma,
|
||||||
|
key: :restrict_unauthenticated,
|
||||||
|
type: :group,
|
||||||
|
description:
|
||||||
|
"Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :timelines,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for public and federated timelines.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view public timeline."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :federated,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view federated timeline."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :profiles,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for user profiles.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view local user profiles."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :remote,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view remote user profiles."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :activities,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for statuses.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view local statuses."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :remote,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view remote statuses."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -414,6 +414,83 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
||||||
- `nicknames`
|
- `nicknames`
|
||||||
- Response: none (code `204`)
|
- Response: none (code `204`)
|
||||||
|
|
||||||
|
## `GET /api/pleroma/admin/users/:nickname/credentials`
|
||||||
|
|
||||||
|
### Get the user's email, password, display and settings-related fields
|
||||||
|
|
||||||
|
- Params:
|
||||||
|
- `nickname`
|
||||||
|
|
||||||
|
- Response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"actor_type": "Person",
|
||||||
|
"allow_following_move": true,
|
||||||
|
"avatar": "https://pleroma.social/media/7e8e7508fd545ef580549b6881d80ec0ff2c81ed9ad37b9bdbbdf0e0d030159d.jpg",
|
||||||
|
"background": "https://pleroma.social/media/4de34c0bd10970d02cbdef8972bef0ebbf55f43cadc449554d4396156162fe9a.jpg",
|
||||||
|
"banner": "https://pleroma.social/media/8d92ba2bd244b613520abf557dd448adcd30f5587022813ee9dd068945986946.jpg",
|
||||||
|
"bio": "bio",
|
||||||
|
"default_scope": "public",
|
||||||
|
"discoverable": false,
|
||||||
|
"email": "user@example.com",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "example",
|
||||||
|
"value": "<a href=\"https://example.com\" rel=\"ugc\">https://example.com</a>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hide_favorites": false,
|
||||||
|
"hide_followers": false,
|
||||||
|
"hide_followers_count": false,
|
||||||
|
"hide_follows": false,
|
||||||
|
"hide_follows_count": false,
|
||||||
|
"id": "9oouHaEEUR54hls968",
|
||||||
|
"locked": true,
|
||||||
|
"name": "user",
|
||||||
|
"no_rich_text": true,
|
||||||
|
"pleroma_settings_store": {},
|
||||||
|
"raw_fields": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "example",
|
||||||
|
"value": "https://example.com"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"show_role": true,
|
||||||
|
"skip_thread_containment": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## `PATCH /api/pleroma/admin/users/:nickname/credentials`
|
||||||
|
|
||||||
|
### Change the user's email, password, display and settings-related fields
|
||||||
|
|
||||||
|
- Params:
|
||||||
|
- `email`
|
||||||
|
- `password`
|
||||||
|
- `name`
|
||||||
|
- `bio`
|
||||||
|
- `avatar`
|
||||||
|
- `locked`
|
||||||
|
- `no_rich_text`
|
||||||
|
- `default_scope`
|
||||||
|
- `banner`
|
||||||
|
- `hide_follows`
|
||||||
|
- `hide_followers`
|
||||||
|
- `hide_followers_count`
|
||||||
|
- `hide_follows_count`
|
||||||
|
- `hide_favorites`
|
||||||
|
- `allow_following_move`
|
||||||
|
- `background`
|
||||||
|
- `show_role`
|
||||||
|
- `skip_thread_containment`
|
||||||
|
- `fields`
|
||||||
|
- `discoverable`
|
||||||
|
- `actor_type`
|
||||||
|
|
||||||
|
- Response: none (code `200`)
|
||||||
|
|
||||||
## `GET /api/pleroma/admin/reports`
|
## `GET /api/pleroma/admin/reports`
|
||||||
|
|
||||||
### Get a list of reports
|
### Get a list of reports
|
||||||
|
|
|
@ -117,7 +117,7 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields:
|
||||||
Accepts additional parameters:
|
Accepts additional parameters:
|
||||||
|
|
||||||
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
|
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
|
||||||
- `with_move`: boolean, when set to `true` will include Move notifications. `false` by default.
|
- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`.
|
||||||
|
|
||||||
## POST `/api/v1/statuses`
|
## POST `/api/v1/statuses`
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,8 @@ config :pleroma, :mrf_user_allowlist,
|
||||||
```
|
```
|
||||||
|
|
||||||
#### :mrf_object_age
|
#### :mrf_object_age
|
||||||
* `threshold`: Required age (in seconds) of a post before actions are taken.
|
* `threshold`: Required time offset (in seconds) compared to your server clock of an incoming post before actions are taken.
|
||||||
|
e.g., A value of 900 results in any post with a timestamp older than 15 minutes will be acted upon.
|
||||||
* `actions`: A list of actions to apply to the post:
|
* `actions`: A list of actions to apply to the post:
|
||||||
* `:delist` removes the post from public timelines
|
* `:delist` removes the post from public timelines
|
||||||
* `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines
|
* `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines
|
||||||
|
@ -871,3 +872,21 @@ config :auto_linker,
|
||||||
## :configurable_from_database
|
## :configurable_from_database
|
||||||
|
|
||||||
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Restrict entities access for unauthenticated users
|
||||||
|
|
||||||
|
### :restrict_unauthenticated
|
||||||
|
|
||||||
|
Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
||||||
|
|
||||||
|
* `timelines` - public and federated timelines
|
||||||
|
* `local` - public timeline
|
||||||
|
* `federated`
|
||||||
|
* `profiles` - user profiles
|
||||||
|
* `local`
|
||||||
|
* `remote`
|
||||||
|
* `activities` - statuses
|
||||||
|
* `local`
|
||||||
|
* `remote`
|
|
@ -605,6 +605,17 @@ def get_log_entry_message(%ModerationLog{
|
||||||
}"
|
}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "updated_users",
|
||||||
|
"subject" => subjects
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} updated users: #{users_to_nicknames_string(subjects)}"
|
||||||
|
end
|
||||||
|
|
||||||
defp nicknames_to_string(nicknames) do
|
defp nicknames_to_string(nicknames) do
|
||||||
nicknames
|
nicknames
|
||||||
|> Enum.map(&"@#{&1}")
|
|> Enum.map(&"@#{&1}")
|
||||||
|
|
|
@ -79,7 +79,6 @@ def for_user_query(user, opts \\ %{}) do
|
||||||
|> exclude_notification_muted(user, exclude_notification_muted_opts)
|
|> exclude_notification_muted(user, exclude_notification_muted_opts)
|
||||||
|> exclude_blocked(user, exclude_blocked_opts)
|
|> exclude_blocked(user, exclude_blocked_opts)
|
||||||
|> exclude_visibility(opts)
|
|> exclude_visibility(opts)
|
||||||
|> exclude_move(opts)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_blocked(query, user, opts) do
|
defp exclude_blocked(query, user, opts) do
|
||||||
|
@ -109,14 +108,6 @@ defp exclude_notification_muted(query, user, opts) do
|
||||||
|> where([n, a, o, tm], is_nil(tm.user_id))
|
|> where([n, a, o, tm], is_nil(tm.user_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_move(query, %{with_move: true}) do
|
|
||||||
query
|
|
||||||
end
|
|
||||||
|
|
||||||
defp exclude_move(query, _opts) do
|
|
||||||
where(query, [n, a], fragment("?->>'type' != 'Move'", a.data))
|
|
||||||
end
|
|
||||||
|
|
||||||
@valid_visibilities ~w[direct unlisted public private]
|
@valid_visibilities ~w[direct unlisted public private]
|
||||||
|
|
||||||
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
||||||
|
|
|
@ -245,7 +245,18 @@ def visible_for?(user, for_user \\ nil)
|
||||||
|
|
||||||
def visible_for?(%User{invisible: true}, _), do: false
|
def visible_for?(%User{invisible: true}, _), do: false
|
||||||
|
|
||||||
def visible_for?(%User{id: user_id}, %User{id: for_id}) when user_id == for_id, do: true
|
def visible_for?(%User{id: user_id}, %User{id: user_id}), do: true
|
||||||
|
|
||||||
|
def visible_for?(%User{local: local} = user, nil) do
|
||||||
|
cfg_key =
|
||||||
|
if local,
|
||||||
|
do: :local,
|
||||||
|
else: :remote
|
||||||
|
|
||||||
|
if Config.get([:restrict_unauthenticated, :profiles, cfg_key]),
|
||||||
|
do: false,
|
||||||
|
else: account_status(user) == :active
|
||||||
|
end
|
||||||
|
|
||||||
def visible_for?(%User{} = user, for_user) do
|
def visible_for?(%User{} = user, for_user) do
|
||||||
account_status(user) == :active || superuser?(for_user)
|
account_status(user) == :active || superuser?(for_user)
|
||||||
|
@ -289,24 +300,6 @@ def ap_followers(%User{} = user), do: "#{ap_id(user)}/followers"
|
||||||
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
||||||
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
||||||
|
|
||||||
def follow_state(%User{} = user, %User{} = target) do
|
|
||||||
case Utils.fetch_latest_follow(user, target) do
|
|
||||||
%{data: %{"state" => state}} -> state
|
|
||||||
# Ideally this would be nil, but then Cachex does not commit the value
|
|
||||||
_ -> false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_cached_follow_state(user, target) do
|
|
||||||
key = "follow_state:#{user.ap_id}|#{target.ap_id}"
|
|
||||||
Cachex.fetch!(:user_cache, key, fn _ -> {:commit, follow_state(user, target)} end)
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec set_follow_state_cache(String.t(), String.t(), String.t()) :: {:ok | :error, boolean()}
|
|
||||||
def set_follow_state_cache(user_ap_id, target_ap_id, state) do
|
|
||||||
Cachex.put(:user_cache, "follow_state:#{user_ap_id}|#{target_ap_id}", state)
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t()
|
@spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t()
|
||||||
def restrict_deactivated(query) do
|
def restrict_deactivated(query) do
|
||||||
from(u in query, where: u.deactivated != ^true)
|
from(u in query, where: u.deactivated != ^true)
|
||||||
|
@ -425,9 +418,55 @@ def update_changeset(struct, params \\ %{}) do
|
||||||
|> validate_format(:nickname, local_nickname_regex())
|
|> validate_format(:nickname, local_nickname_regex())
|
||||||
|> validate_length(:bio, max: bio_limit)
|
|> validate_length(:bio, max: bio_limit)
|
||||||
|> validate_length(:name, min: 1, max: name_limit)
|
|> validate_length(:name, min: 1, max: name_limit)
|
||||||
|
|> put_fields()
|
||||||
|
|> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)})
|
||||||
|
|> put_change_if_present(:avatar, &put_upload(&1, :avatar))
|
||||||
|
|> put_change_if_present(:banner, &put_upload(&1, :banner))
|
||||||
|
|> put_change_if_present(:background, &put_upload(&1, :background))
|
||||||
|
|> put_change_if_present(
|
||||||
|
:pleroma_settings_store,
|
||||||
|
&{:ok, Map.merge(struct.pleroma_settings_store, &1)}
|
||||||
|
)
|
||||||
|> validate_fields(false)
|
|> validate_fields(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp put_fields(changeset) do
|
||||||
|
if raw_fields = get_change(changeset, :raw_fields) do
|
||||||
|
raw_fields =
|
||||||
|
raw_fields
|
||||||
|
|> Enum.filter(fn %{"name" => n} -> n != "" end)
|
||||||
|
|
||||||
|
fields =
|
||||||
|
raw_fields
|
||||||
|
|> Enum.map(fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
|
||||||
|
|
||||||
|
changeset
|
||||||
|
|> put_change(:raw_fields, raw_fields)
|
||||||
|
|> put_change(:fields, fields)
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp put_change_if_present(changeset, map_field, value_function) do
|
||||||
|
if value = get_change(changeset, map_field) do
|
||||||
|
with {:ok, new_value} <- value_function.(value) do
|
||||||
|
put_change(changeset, map_field, new_value)
|
||||||
|
else
|
||||||
|
_ -> changeset
|
||||||
|
end
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp put_upload(value, type) do
|
||||||
|
with %Plug.Upload{} <- value,
|
||||||
|
{:ok, object} <- ActivityPub.upload(value, type: type) do
|
||||||
|
{:ok, object.data}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do
|
def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do
|
||||||
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
|
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
|
||||||
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
|
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
|
||||||
|
@ -471,6 +510,27 @@ def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do
|
||||||
|> validate_fields(remote?)
|
|> validate_fields(remote?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_as_admin_changeset(struct, params) do
|
||||||
|
struct
|
||||||
|
|> update_changeset(params)
|
||||||
|
|> cast(params, [:email])
|
||||||
|
|> delete_change(:also_known_as)
|
||||||
|
|> unique_constraint(:email)
|
||||||
|
|> validate_format(:email, @email_regex)
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec update_as_admin(%User{}, map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
|
||||||
|
def update_as_admin(user, params) do
|
||||||
|
params = Map.put(params, "password_confirmation", params["password"])
|
||||||
|
changeset = update_as_admin_changeset(user, params)
|
||||||
|
|
||||||
|
if params["password"] do
|
||||||
|
reset_password(user, changeset, params)
|
||||||
|
else
|
||||||
|
User.update_and_set_cache(changeset)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def password_update_changeset(struct, params) do
|
def password_update_changeset(struct, params) do
|
||||||
struct
|
struct
|
||||||
|> cast(params, [:password, :password_confirmation])
|
|> cast(params, [:password, :password_confirmation])
|
||||||
|
@ -481,10 +541,14 @@ def password_update_changeset(struct, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
|
@spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
|
||||||
def reset_password(%User{id: user_id} = user, data) do
|
def reset_password(%User{} = user, params) do
|
||||||
|
reset_password(user, user, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_password(%User{id: user_id} = user, struct, params) do
|
||||||
multi =
|
multi =
|
||||||
Multi.new()
|
Multi.new()
|
||||||
|> Multi.update(:user, password_update_changeset(user, data))
|
|> Multi.update(:user, password_update_changeset(struct, params))
|
||||||
|> Multi.delete_all(:tokens, OAuth.Token.Query.get_by_user(user_id))
|
|> Multi.delete_all(:tokens, OAuth.Token.Query.get_by_user(user_id))
|
||||||
|> Multi.delete_all(:auth, OAuth.Authorization.delete_by_user_query(user))
|
|> Multi.delete_all(:auth, OAuth.Authorization.delete_by_user_query(user))
|
||||||
|
|
||||||
|
@ -1890,6 +1954,17 @@ def fields(%{fields: nil}), do: []
|
||||||
|
|
||||||
def fields(%{fields: fields}), do: fields
|
def fields(%{fields: fields}), do: fields
|
||||||
|
|
||||||
|
def sanitized_fields(%User{} = user) do
|
||||||
|
user
|
||||||
|
|> User.fields()
|
||||||
|
|> Enum.map(fn %{"name" => name, "value" => value} ->
|
||||||
|
%{
|
||||||
|
"name" => name,
|
||||||
|
"value" => Pleroma.HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly)
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
def validate_fields(changeset, remote? \\ false) do
|
def validate_fields(changeset, remote? \\ false) do
|
||||||
limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields
|
limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields
|
||||||
limit = Pleroma.Config.get([:instance, limit_name], 0)
|
limit = Pleroma.Config.get([:instance, limit_name], 0)
|
||||||
|
|
|
@ -503,8 +503,7 @@ def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
defp do_follow(follower, followed, activity_id, local) do
|
defp do_follow(follower, followed, activity_id, local) do
|
||||||
with data <- make_follow_data(follower, followed, activity_id),
|
with data <- make_follow_data(follower, followed, activity_id),
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity),
|
:ok <- maybe_federate(activity) do
|
||||||
_ <- User.set_follow_state_cache(follower.ap_id, followed.ap_id, activity.data["state"]) do
|
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
{:error, error} -> Repo.rollback(error)
|
{:error, error} -> Repo.rollback(error)
|
||||||
|
@ -584,6 +583,16 @@ defp do_delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp do_delete(%Object{data: %{"type" => "Tombstone", "id" => ap_id}}, _) do
|
||||||
|
activity =
|
||||||
|
ap_id
|
||||||
|
|> Activity.Queries.by_object_id()
|
||||||
|
|> Activity.Queries.by_type("Delete")
|
||||||
|
|> Repo.one()
|
||||||
|
|
||||||
|
{:ok, activity}
|
||||||
|
end
|
||||||
|
|
||||||
@spec block(User.t(), User.t(), String.t() | nil, boolean()) ::
|
@spec block(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
{:ok, Activity.t()} | {:error, any()}
|
{:ok, Activity.t()} | {:error, any()}
|
||||||
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
|
|
|
@ -440,22 +440,19 @@ def update_follow_state_for_all(
|
||||||
|> update(set: [data: fragment("jsonb_set(data, '{state}', ?)", ^state)])
|
|> update(set: [data: fragment("jsonb_set(data, '{state}', ?)", ^state)])
|
||||||
|> Repo.update_all([])
|
|> Repo.update_all([])
|
||||||
|
|
||||||
User.set_follow_state_cache(actor, object, state)
|
|
||||||
|
|
||||||
activity = Activity.get_by_id(activity.id)
|
activity = Activity.get_by_id(activity.id)
|
||||||
|
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_follow_state(
|
def update_follow_state(
|
||||||
%Activity{data: %{"actor" => actor, "object" => object}} = activity,
|
%Activity{} = activity,
|
||||||
state
|
state
|
||||||
) do
|
) do
|
||||||
new_data = Map.put(activity.data, "state", state)
|
new_data = Map.put(activity.data, "state", state)
|
||||||
changeset = Changeset.change(activity, data: new_data)
|
changeset = Changeset.change(activity, data: new_data)
|
||||||
|
|
||||||
with {:ok, activity} <- Repo.update(changeset) do
|
with {:ok, activity} <- Repo.update(changeset) do
|
||||||
User.set_follow_state_cache(actor, object, state)
|
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -44,6 +44,7 @@ def is_direct?(activity) do
|
||||||
def is_list?(%{data: %{"listMessage" => _}}), do: true
|
def is_list?(%{data: %{"listMessage" => _}}), do: true
|
||||||
def is_list?(_), do: false
|
def is_list?(_), do: false
|
||||||
|
|
||||||
|
@spec visible_for_user?(Activity.t(), User.t() | nil) :: boolean()
|
||||||
def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true
|
def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true
|
||||||
|
|
||||||
def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do
|
def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do
|
||||||
|
@ -55,14 +56,21 @@ def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{
|
||||||
|
|
||||||
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
||||||
|
|
||||||
def visible_for_user?(activity, nil) do
|
def visible_for_user?(%{local: local} = activity, nil) do
|
||||||
is_public?(activity)
|
cfg_key =
|
||||||
|
if local,
|
||||||
|
do: :local,
|
||||||
|
else: :remote
|
||||||
|
|
||||||
|
if Pleroma.Config.get([:restrict_unauthenticated, :activities, cfg_key]),
|
||||||
|
do: false,
|
||||||
|
else: is_public?(activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_for_user?(activity, user) do
|
def visible_for_user?(activity, user) do
|
||||||
x = [user.ap_id | User.following(user)]
|
x = [user.ap_id | User.following(user)]
|
||||||
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || [])
|
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || [])
|
||||||
visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
|
is_public?(activity) || Enum.any?(x, &(&1 in y))
|
||||||
end
|
end
|
||||||
|
|
||||||
def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do
|
def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do
|
||||||
|
|
|
@ -38,7 +38,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:accounts"], admin: true}
|
%{scopes: ["read:accounts"], admin: true}
|
||||||
when action in [:list_users, :user_show, :right_get]
|
when action in [:list_users, :user_show, :right_get, :show_user_credentials]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
|
@ -54,7 +54,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
:tag_users,
|
:tag_users,
|
||||||
:untag_users,
|
:untag_users,
|
||||||
:right_add,
|
:right_add,
|
||||||
:right_delete
|
:right_delete,
|
||||||
|
:update_user_credentials
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -658,6 +659,52 @@ def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nic
|
||||||
json_response(conn, :no_content, "")
|
json_response(conn, :no_content, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc "Show a given user's credentials"
|
||||||
|
def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
||||||
|
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
|
||||||
|
conn
|
||||||
|
|> put_view(AccountView)
|
||||||
|
|> render("credentials.json", %{user: user, for: admin})
|
||||||
|
else
|
||||||
|
_ -> {:error, :not_found}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "Updates a given user"
|
||||||
|
def update_user_credentials(
|
||||||
|
%{assigns: %{user: admin}} = conn,
|
||||||
|
%{"nickname" => nickname} = params
|
||||||
|
) do
|
||||||
|
with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
|
||||||
|
{:ok, _user} <-
|
||||||
|
User.update_as_admin(user, params) do
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
subject: [user],
|
||||||
|
action: "updated_users"
|
||||||
|
})
|
||||||
|
|
||||||
|
if params["password"] do
|
||||||
|
User.force_password_reset_async(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
subject: [user],
|
||||||
|
action: "force_password_reset"
|
||||||
|
})
|
||||||
|
|
||||||
|
json(conn, %{status: "success"})
|
||||||
|
else
|
||||||
|
{:error, changeset} ->
|
||||||
|
{_, {error, _}} = Enum.at(changeset.errors, 0)
|
||||||
|
json(conn, %{error: "New password #{error}."})
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
json(conn, %{error: "Unable to change password."})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def list_reports(conn, params) do
|
def list_reports(conn, params) do
|
||||||
{page, page_size} = page_params(params)
|
{page, page_size} = page_params(params)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,43 @@ def render("index.json", %{users: users}) do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render("credentials.json", %{user: user, for: for_user}) do
|
||||||
|
user = User.sanitize_html(user, User.html_filter_policy(for_user))
|
||||||
|
avatar = User.avatar_url(user) |> MediaProxy.url()
|
||||||
|
banner = User.banner_url(user) |> MediaProxy.url()
|
||||||
|
background = image_url(user.background) |> MediaProxy.url()
|
||||||
|
|
||||||
|
user
|
||||||
|
|> Map.take([
|
||||||
|
:id,
|
||||||
|
:bio,
|
||||||
|
:email,
|
||||||
|
:fields,
|
||||||
|
:name,
|
||||||
|
:nickname,
|
||||||
|
:locked,
|
||||||
|
:no_rich_text,
|
||||||
|
:default_scope,
|
||||||
|
:hide_follows,
|
||||||
|
:hide_followers_count,
|
||||||
|
:hide_follows_count,
|
||||||
|
:hide_followers,
|
||||||
|
:hide_favorites,
|
||||||
|
:allow_following_move,
|
||||||
|
:show_role,
|
||||||
|
:skip_thread_containment,
|
||||||
|
:pleroma_settings_store,
|
||||||
|
:raw_fields,
|
||||||
|
:discoverable,
|
||||||
|
:actor_type
|
||||||
|
])
|
||||||
|
|> Map.merge(%{
|
||||||
|
"avatar" => avatar,
|
||||||
|
"banner" => banner,
|
||||||
|
"background" => background
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
def render("show.json", %{user: user}) do
|
def render("show.json", %{user: user}) do
|
||||||
avatar = User.avatar_url(user) |> MediaProxy.url()
|
avatar = User.avatar_url(user) |> MediaProxy.url()
|
||||||
display_name = Pleroma.HTML.strip_tags(user.name || user.nickname)
|
display_name = Pleroma.HTML.strip_tags(user.name || user.nickname)
|
||||||
|
@ -104,4 +141,7 @@ defp parse_error(errors) do
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
||||||
|
defp image_url(_), do: nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,7 +87,8 @@ def try_render(conn, _, _) do
|
||||||
render_error(conn, :not_implemented, "Can't display this activity")
|
render_error(conn, :not_implemented, "Can't display this activity")
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec put_in_if_exist(map(), atom() | String.t(), any) :: map()
|
@spec put_if_exist(map(), atom() | String.t(), any) :: map()
|
||||||
def put_in_if_exist(map, _key, nil), do: map
|
def put_if_exist(map, _key, nil), do: map
|
||||||
def put_in_if_exist(map, key, value), do: put_in(map, key, value)
|
|
||||||
|
def put_if_exist(map, key, value), do: Map.put(map, key, value)
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,18 +9,18 @@ defmodule Pleroma.Web.Feed.TagController do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.Feed.FeedView
|
alias Pleroma.Web.Feed.FeedView
|
||||||
|
|
||||||
import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3]
|
import Pleroma.Web.ControllerHelper, only: [put_if_exist: 3]
|
||||||
|
|
||||||
def feed(conn, %{"tag" => raw_tag} = params) do
|
def feed(conn, %{"tag" => raw_tag} = params) do
|
||||||
{format, tag} = parse_tag(raw_tag)
|
{format, tag} = parse_tag(raw_tag)
|
||||||
|
|
||||||
activities =
|
activities =
|
||||||
%{"type" => ["Create"], "tag" => tag}
|
%{"type" => ["Create"], "tag" => tag}
|
||||||
|> put_in_if_exist("max_id", params["max_id"])
|
|> put_if_exist("max_id", params["max_id"])
|
||||||
|> ActivityPub.fetch_public_activities()
|
|> ActivityPub.fetch_public_activities()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("application/atom+xml")
|
|> put_resp_content_type("application/#{format}+xml")
|
||||||
|> put_view(FeedView)
|
|> put_view(FeedView)
|
||||||
|> render("tag.#{format}",
|
|> render("tag.#{format}",
|
||||||
activities: activities,
|
activities: activities,
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.Feed.UserController do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPubController
|
alias Pleroma.Web.ActivityPub.ActivityPubController
|
||||||
alias Pleroma.Web.Feed.FeedView
|
alias Pleroma.Web.Feed.FeedView
|
||||||
|
|
||||||
import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3]
|
import Pleroma.Web.ControllerHelper, only: [put_if_exist: 3]
|
||||||
|
|
||||||
plug(Pleroma.Plugs.SetFormatPlug when action in [:feed_redirect])
|
plug(Pleroma.Plugs.SetFormatPlug when action in [:feed_redirect])
|
||||||
|
|
||||||
|
@ -40,19 +40,28 @@ def feed_redirect(conn, %{"nickname" => nickname}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def feed(conn, %{"nickname" => nickname} = params) do
|
def feed(conn, %{"nickname" => nickname} = params) do
|
||||||
|
format = get_format(conn)
|
||||||
|
|
||||||
|
format =
|
||||||
|
if format in ["rss", "atom"] do
|
||||||
|
format
|
||||||
|
else
|
||||||
|
"atom"
|
||||||
|
end
|
||||||
|
|
||||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
||||||
activities =
|
activities =
|
||||||
%{
|
%{
|
||||||
"type" => ["Create"],
|
"type" => ["Create"],
|
||||||
"actor_id" => user.ap_id
|
"actor_id" => user.ap_id
|
||||||
}
|
}
|
||||||
|> put_in_if_exist("max_id", params["max_id"])
|
|> put_if_exist("max_id", params["max_id"])
|
||||||
|> ActivityPub.fetch_public_activities()
|
|> ActivityPub.fetch_public_activities()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("application/atom+xml")
|
|> put_resp_content_type("application/#{format}+xml")
|
||||||
|> put_view(FeedView)
|
|> put_view(FeedView)
|
||||||
|> render("user.xml",
|
|> render("user.#{format}",
|
||||||
user: user,
|
user: user,
|
||||||
activities: activities,
|
activities: activities,
|
||||||
feed_config: Pleroma.Config.get([:feed])
|
feed_config: Pleroma.Config.get([:feed])
|
||||||
|
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
||||||
import Pleroma.Web.ControllerHelper,
|
import Pleroma.Web.ControllerHelper,
|
||||||
only: [add_link_headers: 2, truthy_param?: 1, assign_account_by_id: 2, json_response: 3]
|
only: [add_link_headers: 2, truthy_param?: 1, assign_account_by_id: 2, json_response: 3]
|
||||||
|
|
||||||
alias Pleroma.Emoji
|
|
||||||
alias Pleroma.Plugs.OAuthScopesPlug
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
alias Pleroma.Plugs.RateLimiter
|
alias Pleroma.Plugs.RateLimiter
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
@ -60,7 +59,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||||
when action != :create
|
when action not in [:create, :show, :statuses]
|
||||||
)
|
)
|
||||||
|
|
||||||
@relationship_actions [:follow, :unfollow]
|
@relationship_actions [:follow, :unfollow]
|
||||||
|
@ -144,17 +143,6 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _) do
|
||||||
def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
||||||
user = original_user
|
user = original_user
|
||||||
|
|
||||||
params =
|
|
||||||
if Map.has_key?(params, "fields_attributes") do
|
|
||||||
Map.update!(params, "fields_attributes", fn fields ->
|
|
||||||
fields
|
|
||||||
|> normalize_fields_attributes()
|
|
||||||
|> Enum.filter(fn %{"name" => n} -> n != "" end)
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
params
|
|
||||||
end
|
|
||||||
|
|
||||||
user_params =
|
user_params =
|
||||||
[
|
[
|
||||||
:no_rich_text,
|
:no_rich_text,
|
||||||
|
@ -173,46 +161,20 @@ def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
||||||
add_if_present(acc, params, to_string(key), key, &{:ok, truthy_param?(&1)})
|
add_if_present(acc, params, to_string(key), key, &{:ok, truthy_param?(&1)})
|
||||||
end)
|
end)
|
||||||
|> add_if_present(params, "display_name", :name)
|
|> add_if_present(params, "display_name", :name)
|
||||||
|> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value, user)} end)
|
|> add_if_present(params, "note", :bio)
|
||||||
|> add_if_present(params, "avatar", :avatar, fn value ->
|
|> add_if_present(params, "avatar", :avatar)
|
||||||
with %Plug.Upload{} <- value,
|
|> add_if_present(params, "header", :banner)
|
||||||
{:ok, object} <- ActivityPub.upload(value, type: :avatar) do
|
|> add_if_present(params, "pleroma_background_image", :background)
|
||||||
{:ok, object.data}
|
|> add_if_present(
|
||||||
end
|
params,
|
||||||
end)
|
"fields_attributes",
|
||||||
|> add_if_present(params, "header", :banner, fn value ->
|
:raw_fields,
|
||||||
with %Plug.Upload{} <- value,
|
&{:ok, normalize_fields_attributes(&1)}
|
||||||
{:ok, object} <- ActivityPub.upload(value, type: :banner) do
|
)
|
||||||
{:ok, object.data}
|
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store)
|
||||||
end
|
|
||||||
end)
|
|
||||||
|> add_if_present(params, "pleroma_background_image", :background, fn value ->
|
|
||||||
with %Plug.Upload{} <- value,
|
|
||||||
{:ok, object} <- ActivityPub.upload(value, type: :background) do
|
|
||||||
{:ok, object.data}
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|> add_if_present(params, "fields_attributes", :fields, fn fields ->
|
|
||||||
fields = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
|
|
||||||
|
|
||||||
{:ok, fields}
|
|
||||||
end)
|
|
||||||
|> add_if_present(params, "fields_attributes", :raw_fields)
|
|
||||||
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
|
|
||||||
{:ok, Map.merge(user.pleroma_settings_store, value)}
|
|
||||||
end)
|
|
||||||
|> add_if_present(params, "default_scope", :default_scope)
|
|> add_if_present(params, "default_scope", :default_scope)
|
||||||
|> add_if_present(params, "actor_type", :actor_type)
|
|> add_if_present(params, "actor_type", :actor_type)
|
||||||
|
|
||||||
emojis_text = (user_params["display_name"] || "") <> (user_params["note"] || "")
|
|
||||||
|
|
||||||
user_emojis =
|
|
||||||
user
|
|
||||||
|> Map.get(:emoji, [])
|
|
||||||
|> Enum.concat(Emoji.Formatter.get_emoji_map(emojis_text))
|
|
||||||
|> Enum.dedup()
|
|
||||||
|
|
||||||
user_params = Map.put(user_params, :emoji, user_emojis)
|
|
||||||
changeset = User.update_changeset(user, user_params)
|
changeset = User.update_changeset(user, user_params)
|
||||||
|
|
||||||
with {:ok, user} <- User.update_and_set_cache(changeset) do
|
with {:ok, user} <- User.update_and_set_cache(changeset) do
|
||||||
|
@ -263,7 +225,8 @@ def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
|
||||||
|
|
||||||
@doc "GET /api/v1/accounts/:id/statuses"
|
@doc "GET /api/v1/accounts/:id/statuses"
|
||||||
def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
|
with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user),
|
||||||
|
true <- User.visible_for?(user, reading_user) do
|
||||||
params =
|
params =
|
||||||
params
|
params
|
||||||
|> Map.put("tag", params["tagged"])
|
|> Map.put("tag", params["tagged"])
|
||||||
|
@ -275,6 +238,8 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
||||||
|> add_link_headers(activities)
|
|> add_link_headers(activities)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> render("index.json", activities: activities, for: reading_user, as: :activity)
|
|> render("index.json", activities: activities, for: reading_user, as: :activity)
|
||||||
|
else
|
||||||
|
_e -> render_error(conn, :not_found, "Can't find user")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
%{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark]
|
%{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action not in [:index, :show])
|
||||||
|
|
||||||
@rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a
|
@rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
||||||
|
|
||||||
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :public)
|
||||||
|
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
||||||
|
|
||||||
|
@ -75,17 +75,30 @@ def direct(%{assigns: %{user: user}} = conn, params) do
|
||||||
def public(%{assigns: %{user: user}} = conn, params) do
|
def public(%{assigns: %{user: user}} = conn, params) do
|
||||||
local_only = truthy_param?(params["local"])
|
local_only = truthy_param?(params["local"])
|
||||||
|
|
||||||
activities =
|
cfg_key =
|
||||||
params
|
if local_only do
|
||||||
|> Map.put("type", ["Create", "Announce"])
|
:local
|
||||||
|> Map.put("local_only", local_only)
|
else
|
||||||
|> Map.put("blocking_user", user)
|
:federated
|
||||||
|> Map.put("muting_user", user)
|
end
|
||||||
|> ActivityPub.fetch_public_activities()
|
|
||||||
|
|
||||||
conn
|
restrict? = Pleroma.Config.get([:restrict_unauthenticated, :timelines, cfg_key])
|
||||||
|> add_link_headers(activities, %{"local" => local_only})
|
|
||||||
|> render("index.json", activities: activities, for: user, as: :activity)
|
if not (restrict? and is_nil(user)) do
|
||||||
|
activities =
|
||||||
|
params
|
||||||
|
|> Map.put("type", ["Create", "Announce"])
|
||||||
|
|> Map.put("local_only", local_only)
|
||||||
|
|> Map.put("blocking_user", user)
|
||||||
|
|> Map.put("muting_user", user)
|
||||||
|
|> ActivityPub.fetch_public_activities()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> add_link_headers(activities, %{"local" => local_only})
|
||||||
|
|> render("index.json", activities: activities, for: user, as: :activity)
|
||||||
|
else
|
||||||
|
render_error(conn, :unauthorized, "authorization required for timeline view")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def hashtag_fetching(params, user, local_only) do
|
def hashtag_fetching(params, user, local_only) do
|
||||||
|
|
|
@ -55,6 +55,7 @@ def get_notifications(user, params \\ %{}) do
|
||||||
|
|
||||||
user
|
user
|
||||||
|> Notification.for_user_query(options)
|
|> Notification.for_user_query(options)
|
||||||
|
|> restrict(:include_types, options)
|
||||||
|> restrict(:exclude_types, options)
|
|> restrict(:exclude_types, options)
|
||||||
|> restrict(:account_ap_id, options)
|
|> restrict(:account_ap_id, options)
|
||||||
|> Pagination.fetch_paginated(params)
|
|> Pagination.fetch_paginated(params)
|
||||||
|
@ -69,10 +70,10 @@ def get_scheduled_activities(user, params \\ %{}) do
|
||||||
defp cast_params(params) do
|
defp cast_params(params) do
|
||||||
param_types = %{
|
param_types = %{
|
||||||
exclude_types: {:array, :string},
|
exclude_types: {:array, :string},
|
||||||
|
include_types: {:array, :string},
|
||||||
exclude_visibilities: {:array, :string},
|
exclude_visibilities: {:array, :string},
|
||||||
reblogs: :boolean,
|
reblogs: :boolean,
|
||||||
with_muted: :boolean,
|
with_muted: :boolean,
|
||||||
with_move: :boolean,
|
|
||||||
account_ap_id: :string
|
account_ap_id: :string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +81,16 @@ defp cast_params(params) do
|
||||||
changeset.changes
|
changeset.changes
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
defp restrict(query, :include_types, %{include_types: mastodon_types = [_ | _]}) do
|
||||||
ap_types =
|
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||||
mastodon_types
|
|
||||||
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
|
||||||
|> Enum.filter(& &1)
|
|
||||||
|
|
||||||
query
|
where(query, [q, a], fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||||
|> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
end
|
||||||
|
|
||||||
|
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
||||||
|
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||||
|
|
||||||
|
where(query, [q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
||||||
|
@ -95,4 +98,10 @@ defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, _, _), do: query
|
defp restrict(query, _, _), do: query
|
||||||
|
|
||||||
|
defp convert_and_filter_mastodon_types(types) do
|
||||||
|
types
|
||||||
|
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
||||||
|
|> Enum.filter(& &1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,25 +36,18 @@ def render("relationship.json", %{user: nil, target: _target}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("relationship.json", %{user: %User{} = user, target: %User{} = target}) do
|
def render("relationship.json", %{user: %User{} = user, target: %User{} = target}) do
|
||||||
follow_state = User.get_cached_follow_state(user, target)
|
follow_state = User.get_follow_state(user, target)
|
||||||
|
|
||||||
requested =
|
|
||||||
if follow_state && !User.following?(user, target) do
|
|
||||||
follow_state == "pending"
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
id: to_string(target.id),
|
id: to_string(target.id),
|
||||||
following: User.following?(user, target),
|
following: follow_state == "accept",
|
||||||
followed_by: User.following?(target, user),
|
followed_by: User.following?(target, user),
|
||||||
blocking: User.blocks_user?(user, target),
|
blocking: User.blocks_user?(user, target),
|
||||||
blocked_by: User.blocks_user?(target, user),
|
blocked_by: User.blocks_user?(target, user),
|
||||||
muting: User.mutes?(user, target),
|
muting: User.mutes?(user, target),
|
||||||
muting_notifications: User.muted_notifications?(user, target),
|
muting_notifications: User.muted_notifications?(user, target),
|
||||||
subscribing: User.subscribed_to?(user, target),
|
subscribing: User.subscribed_to?(user, target),
|
||||||
requested: requested,
|
requested: follow_state == "pending",
|
||||||
domain_blocking: User.blocks_domain?(user, target),
|
domain_blocking: User.blocks_domain?(user, target),
|
||||||
showing_reblogs: User.showing_reblogs?(user, target),
|
showing_reblogs: User.showing_reblogs?(user, target),
|
||||||
endorsed: false
|
endorsed: false
|
||||||
|
@ -122,7 +115,7 @@ defp do_render("show.json", %{user: user} = opts) do
|
||||||
fields: user.fields,
|
fields: user.fields,
|
||||||
bot: bot,
|
bot: bot,
|
||||||
source: %{
|
source: %{
|
||||||
note: Pleroma.HTML.strip_tags((user.bio || "") |> String.replace("<br>", "\n")),
|
note: (user.bio || "") |> String.replace(~r(<br */?>), "\n") |> Pleroma.HTML.strip_tags(),
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
fields: user.raw_fields,
|
fields: user.raw_fields,
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
|
|
|
@ -60,6 +60,7 @@ def raw_nodeinfo do
|
||||||
"pleroma_explicit_addressing",
|
"pleroma_explicit_addressing",
|
||||||
"shareable_emoji_packs",
|
"shareable_emoji_packs",
|
||||||
"multifetch",
|
"multifetch",
|
||||||
|
"pleroma:api/v1/notifications:include_types_filter",
|
||||||
if Config.get([:media_proxy, :enabled]) do
|
if Config.get([:media_proxy, :enabled]) do
|
||||||
"media_proxy"
|
"media_proxy"
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -173,6 +173,8 @@ defmodule Pleroma.Web.Router do
|
||||||
|
|
||||||
get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)
|
get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)
|
||||||
patch("/users/force_password_reset", AdminAPIController, :force_password_reset)
|
patch("/users/force_password_reset", AdminAPIController, :force_password_reset)
|
||||||
|
get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials)
|
||||||
|
patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials)
|
||||||
|
|
||||||
get("/users", AdminAPIController, :list_users)
|
get("/users", AdminAPIController, :list_users)
|
||||||
get("/users/:nickname", AdminAPIController, :user_show)
|
get("/users/:nickname", AdminAPIController, :user_show)
|
||||||
|
@ -513,7 +515,7 @@ defmodule Pleroma.Web.Router do
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :ostatus do
|
pipeline :ostatus do
|
||||||
plug(:accepts, ["html", "xml", "atom", "activity+json", "json"])
|
plug(:accepts, ["html", "xml", "rss", "atom", "activity+json", "json"])
|
||||||
plug(Pleroma.Plugs.StaticFEPlug)
|
plug(Pleroma.Plugs.StaticFEPlug)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,9 @@ defp represent(%Activity{object: %Object{data: data}} = activity, selected) do
|
||||||
|
|
||||||
content =
|
content =
|
||||||
if data["content"] do
|
if data["content"] do
|
||||||
Pleroma.HTML.filter_tags(data["content"])
|
data["content"]
|
||||||
|
|> Pleroma.HTML.filter_tags()
|
||||||
|
|> Pleroma.Emoji.Formatter.emojify(Map.get(data, "emoji", %{}))
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
49
lib/pleroma/web/templates/feed/feed/_activity.rss.eex
Normal file
49
lib/pleroma/web/templates/feed/feed/_activity.rss.eex
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<item>
|
||||||
|
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||||
|
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||||
|
<guid><%= @data["id"] %></guid>
|
||||||
|
<title><%= activity_title(@object, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
|
<description><%= activity_content(@object) %></description>
|
||||||
|
<pubDate><%= @data["published"] %></pubDate>
|
||||||
|
<updated><%= @data["published"] %></updated>
|
||||||
|
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||||
|
<%= activity_context(@activity) %>
|
||||||
|
</ostatus:conversation>
|
||||||
|
<link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
|
||||||
|
|
||||||
|
<%= if @data["summary"] do %>
|
||||||
|
<description><%= @data["summary"] %></description>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= if @activity.local do %>
|
||||||
|
<link><%= @data["id"] %></link>
|
||||||
|
<% else %>
|
||||||
|
<link><%= @data["external_url"] %></link>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= for tag <- @data["tag"] || [] do %>
|
||||||
|
<category term="<%= tag %>"></category>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= for attachment <- @data["attachment"] || [] do %>
|
||||||
|
<link type="<%= attachment_type(attachment) %>"><%= attachment_href(attachment) %></link>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= if @data["inReplyTo"] do %>
|
||||||
|
<thr:in-reply-to ref='<%= @data["inReplyTo"] %>' href='<%= get_href(@data["inReplyTo"]) %>'/>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= for id <- @activity.recipients do %>
|
||||||
|
<%= if id == Pleroma.Constants.as_public() do %>
|
||||||
|
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection">http://activityschema.org/collection/public</link>
|
||||||
|
<% else %>
|
||||||
|
<%= unless Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) do %>
|
||||||
|
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person"><%= id %></link>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= for {emoji, file} <- @data["emoji"] || %{} do %>
|
||||||
|
<link name="<%= emoji %>" rel="emoji"><%= file %></link>
|
||||||
|
<% end %>
|
||||||
|
</item>
|
17
lib/pleroma/web/templates/feed/feed/_author.rss.eex
Normal file
17
lib/pleroma/web/templates/feed/feed/_author.rss.eex
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<managingEditor>
|
||||||
|
<guid><%= @user.ap_id %></guid>
|
||||||
|
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
|
||||||
|
<uri><%= @user.ap_id %></uri>
|
||||||
|
<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>
|
||||||
|
<poco:displayName><%= @user.name %></poco:displayName>
|
||||||
|
<poco:note><%= escape(@user.bio) %></poco:note>
|
||||||
|
<description><%= escape(@user.bio) %></description>
|
||||||
|
<name><%= @user.nickname %></name>
|
||||||
|
<link rel="avatar"><%= User.avatar_url(@user) %></link>
|
||||||
|
<%= if User.banner_url(@user) do %>
|
||||||
|
<link rel="header"><%= User.banner_url(@user) %></link>
|
||||||
|
<% end %>
|
||||||
|
<%= if @user.local do %>
|
||||||
|
<ap_enabled>true</ap_enabled>
|
||||||
|
<% end %>
|
||||||
|
</managingEditor>
|
|
@ -12,13 +12,13 @@
|
||||||
<logo><%= logo(@user) %></logo>
|
<logo><%= logo(@user) %></logo>
|
||||||
<link rel="self" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
||||||
|
|
||||||
<%= render @view_module, "_author.xml", assigns %>
|
<%= render @view_module, "_author.atom", assigns %>
|
||||||
|
|
||||||
<%= if last_activity(@activities) do %>
|
<%= if last_activity(@activities) do %>
|
||||||
<link rel="next" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
|
<link rel="next" href="<%= '#{user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
<%= render @view_module, "_activity.xml", Map.merge(assigns, prepare_activity(activity)) %>
|
<%= render @view_module, "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</feed>
|
</feed>
|
20
lib/pleroma/web/templates/feed/feed/user.rss.eex
Normal file
20
lib/pleroma/web/templates/feed/feed/user.rss.eex
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<rss version="2.0">
|
||||||
|
<channel>
|
||||||
|
<guid><%= user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %></guid>
|
||||||
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
|
<updated><%= most_recent_update(@activities, @user) %></updated>
|
||||||
|
<image><%= logo(@user) %></image>
|
||||||
|
<link><%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
||||||
|
|
||||||
|
<%= render @view_module, "_author.rss", assigns %>
|
||||||
|
|
||||||
|
<%= if last_activity(@activities) do %>
|
||||||
|
<link rel="next"><%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %></link>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= for activity <- @activities do %>
|
||||||
|
<%= render @view_module, "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %>
|
||||||
|
<% end %>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
2
mix.exs
2
mix.exs
|
@ -63,7 +63,7 @@ def copy_nginx_config(%{path: target_path} = release) do
|
||||||
def application do
|
def application do
|
||||||
[
|
[
|
||||||
mod: {Pleroma.Application, []},
|
mod: {Pleroma.Application, []},
|
||||||
extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize],
|
extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize, :ssl],
|
||||||
included_applications: [:ex_syslogger]
|
included_applications: [:ex_syslogger]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -174,3 +174,10 @@ .alert-info {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.emoji {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.ActivityExpirationTest do
|
||||||
alias Pleroma.ActivityExpiration
|
alias Pleroma.ActivityExpiration
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config([ActivityExpiration, :enabled])
|
setup do: clear_config([ActivityExpiration, :enabled])
|
||||||
|
|
||||||
test "finds activities due to be deleted only" do
|
test "finds activities due to be deleted only" do
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
|
|
|
@ -138,7 +138,7 @@ test "when association is not loaded" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :limit_to_local_content])
|
setup do: clear_config([:instance, :limit_to_local_content])
|
||||||
|
|
||||||
test "finds utf8 text in statuses", %{
|
test "finds utf8 text in statuses", %{
|
||||||
japanese_activity: japanese_activity,
|
japanese_activity: japanese_activity,
|
||||||
|
|
|
@ -12,8 +12,7 @@ defmodule Pleroma.CaptchaTest do
|
||||||
alias Pleroma.Captcha.Native
|
alias Pleroma.Captcha.Native
|
||||||
|
|
||||||
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
||||||
|
setup do: clear_config([Pleroma.Captcha, :enabled])
|
||||||
clear_config([Pleroma.Captcha, :enabled])
|
|
||||||
|
|
||||||
describe "Kocaptcha" do
|
describe "Kocaptcha" do
|
||||||
setup do
|
setup do
|
||||||
|
|
|
@ -10,9 +10,7 @@ defmodule Pleroma.Config.TransferTaskTest do
|
||||||
alias Pleroma.Config.TransferTask
|
alias Pleroma.Config.TransferTask
|
||||||
alias Pleroma.ConfigDB
|
alias Pleroma.ConfigDB
|
||||||
|
|
||||||
clear_config(:configurable_from_database) do
|
setup do: clear_config(:configurable_from_database, true)
|
||||||
Pleroma.Config.put(:configurable_from_database, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "transfer config values from db to env" do
|
test "transfer config values from db to env" do
|
||||||
refute Application.get_env(:pleroma, :test_key)
|
refute Application.get_env(:pleroma, :test_key)
|
||||||
|
|
|
@ -11,9 +11,7 @@ defmodule Pleroma.ConversationTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config_all([:instance, :federating]) do
|
setup_all do: clear_config([:instance, :federating], true)
|
||||||
Pleroma.Config.put([:instance, :federating], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it goes through old direct conversations" do
|
test "it goes through old direct conversations" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -14,8 +14,7 @@ defmodule Pleroma.Emails.MailerTest do
|
||||||
subject: "Pleroma test email",
|
subject: "Pleroma test email",
|
||||||
to: [{"Test User", "user1@example.com"}]
|
to: [{"Test User", "user1@example.com"}]
|
||||||
}
|
}
|
||||||
|
setup do: clear_config([Pleroma.Emails.Mailer, :enabled])
|
||||||
clear_config([Pleroma.Emails.Mailer, :enabled])
|
|
||||||
|
|
||||||
test "not send email when mailer is disabled" do
|
test "not send email when mailer is disabled" do
|
||||||
Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
|
Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
|
||||||
|
|
|
@ -8,8 +8,8 @@ defmodule Pleroma.HTTP.RequestBuilderTest do
|
||||||
alias Pleroma.HTTP.RequestBuilder
|
alias Pleroma.HTTP.RequestBuilder
|
||||||
|
|
||||||
describe "headers/2" do
|
describe "headers/2" do
|
||||||
clear_config([:http, :send_user_agent])
|
setup do: clear_config([:http, :send_user_agent])
|
||||||
clear_config([:http, :user_agent])
|
setup do: clear_config([:http, :user_agent])
|
||||||
|
|
||||||
test "don't send pleroma user agent" do
|
test "don't send pleroma user agent" do
|
||||||
assert RequestBuilder.headers(%{}, []) == %{headers: []}
|
assert RequestBuilder.headers(%{}, []) == %{headers: []}
|
||||||
|
|
|
@ -802,7 +802,13 @@ test "move activity generates a notification" do
|
||||||
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
||||||
ObanHelpers.perform_all()
|
ObanHelpers.perform_all()
|
||||||
|
|
||||||
assert [] = Notification.for_user(follower)
|
assert [
|
||||||
|
%{
|
||||||
|
activity: %{
|
||||||
|
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
] = Notification.for_user(follower)
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
%{
|
%{
|
||||||
|
@ -810,17 +816,7 @@ test "move activity generates a notification" do
|
||||||
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
] = Notification.for_user(follower, %{with_move: true})
|
] = Notification.for_user(other_follower)
|
||||||
|
|
||||||
assert [] = Notification.for_user(other_follower)
|
|
||||||
|
|
||||||
assert [
|
|
||||||
%{
|
|
||||||
activity: %{
|
|
||||||
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
] = Notification.for_user(other_follower, %{with_move: true})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,7 @@ defmodule Pleroma.Object.FetcherTest do
|
||||||
|
|
||||||
describe "max thread distance restriction" do
|
describe "max thread distance restriction" do
|
||||||
@ap_id "http://mastodon.example.org/@admin/99541947525187367"
|
@ap_id "http://mastodon.example.org/@admin/99541947525187367"
|
||||||
|
setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
|
||||||
clear_config([:instance, :federation_incoming_replies_max_depth])
|
|
||||||
|
|
||||||
test "it returns thread depth exceeded error if thread depth is exceeded" do
|
test "it returns thread depth exceeded error if thread depth is exceeded" do
|
||||||
Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
|
Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
|
||||||
|
@ -160,7 +159,7 @@ test "it can refetch pruned objects" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "signed fetches" do
|
describe "signed fetches" do
|
||||||
clear_config([:activitypub, :sign_object_fetches])
|
setup do: clear_config([:activitypub, :sign_object_fetches])
|
||||||
|
|
||||||
test_with_mock "it signs fetches when configured to do so",
|
test_with_mock "it signs fetches when configured to do so",
|
||||||
Pleroma.Signature,
|
Pleroma.Signature,
|
||||||
|
|
|
@ -74,8 +74,8 @@ test "ensures cache is cleared for the object" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "delete attachments" do
|
describe "delete attachments" do
|
||||||
clear_config([Pleroma.Upload])
|
setup do: clear_config([Pleroma.Upload])
|
||||||
clear_config([:instance, :cleanup_attachments])
|
setup do: clear_config([:instance, :cleanup_attachments])
|
||||||
|
|
||||||
test "Disabled via config" do
|
test "Disabled via config" do
|
||||||
Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||||
|
|
|
@ -23,7 +23,7 @@ test "does nothing if a user is assigned", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when secret set it assigns an admin user" do
|
describe "when secret set it assigns an admin user" do
|
||||||
clear_config([:admin_token])
|
setup do: clear_config([:admin_token])
|
||||||
|
|
||||||
test "with `admin_token` query parameter", %{conn: conn} do
|
test "with `admin_token` query parameter", %{conn: conn} do
|
||||||
Pleroma.Config.put(:admin_token, "password123")
|
Pleroma.Config.put(:admin_token, "password123")
|
||||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do
|
||||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
clear_config([:instance, :public])
|
setup do: clear_config([:instance, :public])
|
||||||
|
|
||||||
test "it halts if not public and no user is assigned", %{conn: conn} do
|
test "it halts if not public and no user is assigned", %{conn: conn} do
|
||||||
Config.put([:instance, :public], false)
|
Config.put([:instance, :public], false)
|
||||||
|
|
|
@ -7,9 +7,9 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Plug.Conn
|
alias Plug.Conn
|
||||||
|
|
||||||
clear_config([:http_securiy, :enabled])
|
setup do: clear_config([:http_securiy, :enabled])
|
||||||
clear_config([:http_security, :sts])
|
setup do: clear_config([:http_security, :sts])
|
||||||
clear_config([:http_security, :referrer_policy])
|
setup do: clear_config([:http_security, :referrer_policy])
|
||||||
|
|
||||||
describe "http security enabled" do
|
describe "http security enabled" do
|
||||||
setup do
|
setup do
|
||||||
|
|
|
@ -12,9 +12,7 @@ defmodule Pleroma.Web.RuntimeStaticPlugTest do
|
||||||
on_exit(fn -> File.rm_rf(@dir) end)
|
on_exit(fn -> File.rm_rf(@dir) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :static_dir]) do
|
setup do: clear_config([:instance, :static_dir], @dir)
|
||||||
Pleroma.Config.put([:instance, :static_dir], @dir)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "overrides index" do
|
test "overrides index" do
|
||||||
bundled_index = get(build_conn(), "/")
|
bundled_index = get(build_conn(), "/")
|
||||||
|
|
|
@ -193,7 +193,7 @@ test "filters scopes which directly match or are ancestors of supported scopes"
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "transform_scopes/2" do
|
describe "transform_scopes/2" do
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage])
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage])
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
{:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
|
{:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
|
||||||
|
|
|
@ -12,14 +12,12 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
||||||
import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
|
import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
|
||||||
|
|
||||||
# Note: each example must work with separate buckets in order to prevent concurrency issues
|
# Note: each example must work with separate buckets in order to prevent concurrency issues
|
||||||
|
setup do: clear_config([Pleroma.Web.Endpoint, :http, :ip])
|
||||||
clear_config([Pleroma.Web.Endpoint, :http, :ip])
|
setup do: clear_config(:rate_limit)
|
||||||
clear_config(:rate_limit)
|
|
||||||
|
|
||||||
describe "config" do
|
describe "config" do
|
||||||
@limiter_name :test_init
|
@limiter_name :test_init
|
||||||
|
setup do: clear_config([Pleroma.Plugs.RemoteIp, :enabled])
|
||||||
clear_config([Pleroma.Plugs.RemoteIp, :enabled])
|
|
||||||
|
|
||||||
test "config is required for plug to work" do
|
test "config is required for plug to work" do
|
||||||
Config.put([:rate_limit, @limiter_name], {1, 1})
|
Config.put([:rate_limit, @limiter_name], {1, 1})
|
||||||
|
|
|
@ -9,8 +9,7 @@ defmodule Pleroma.Plugs.RemoteIpTest do
|
||||||
alias Pleroma.Plugs.RemoteIp
|
alias Pleroma.Plugs.RemoteIp
|
||||||
|
|
||||||
import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
|
import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
|
||||||
|
setup do: clear_config(RemoteIp)
|
||||||
clear_config(RemoteIp)
|
|
||||||
|
|
||||||
test "disabled" do
|
test "disabled" do
|
||||||
Pleroma.Config.put(RemoteIp, enabled: false)
|
Pleroma.Config.put(RemoteIp, enabled: false)
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do
|
||||||
alias Pleroma.Plugs.UserEnabledPlug
|
alias Pleroma.Plugs.UserEnabledPlug
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
test "doesn't do anything if the user isn't set", %{conn: conn} do
|
test "doesn't do anything if the user isn't set", %{conn: conn} do
|
||||||
ret_conn =
|
ret_conn =
|
||||||
|
|
|
@ -9,9 +9,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
||||||
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "accepts a user that is an admin" do
|
test "accepts a user that is an admin" do
|
||||||
user = insert(:user, is_admin: true)
|
user = insert(:user, is_admin: true)
|
||||||
|
@ -42,9 +40,7 @@ test "denies when a user isn't set" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
||||||
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
admin_user = insert(:user, is_admin: true)
|
admin_user = insert(:user, is_admin: true)
|
||||||
|
|
|
@ -67,7 +67,7 @@ test "return error if has not assoc " do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
|
setup do: clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
|
||||||
|
|
||||||
test "raises if it detects unapplied migrations" do
|
test "raises if it detects unapplied migrations" do
|
||||||
assert_raise Pleroma.Repo.UnappliedMigrationsError, fn ->
|
assert_raise Pleroma.Repo.UnappliedMigrationsError, fn ->
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.ScheduledActivityTest do
|
||||||
alias Pleroma.ScheduledActivity
|
alias Pleroma.ScheduledActivity
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config([ScheduledActivity, :enabled])
|
setup do: clear_config([ScheduledActivity, :enabled])
|
||||||
|
|
||||||
setup context do
|
setup context do
|
||||||
DataCase.ensure_local_uploader(context)
|
DataCase.ensure_local_uploader(context)
|
||||||
|
|
|
@ -17,35 +17,17 @@ defmacro clear_config(config_path) do
|
||||||
|
|
||||||
defmacro clear_config(config_path, do: yield) do
|
defmacro clear_config(config_path, do: yield) do
|
||||||
quote do
|
quote do
|
||||||
setup do
|
initial_setting = Config.get(unquote(config_path))
|
||||||
initial_setting = Config.get(unquote(config_path))
|
unquote(yield)
|
||||||
unquote(yield)
|
on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
|
||||||
on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
|
:ok
|
||||||
:ok
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Stores initial config value and restores it after *all* test examples are executed."
|
defmacro clear_config(config_path, temp_setting) do
|
||||||
defmacro clear_config_all(config_path) do
|
|
||||||
quote do
|
quote do
|
||||||
clear_config_all(unquote(config_path)) do
|
clear_config(unquote(config_path)) do
|
||||||
end
|
Config.put(unquote(config_path), unquote(temp_setting))
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Stores initial config value and restores it after *all* test examples are executed.
|
|
||||||
Only use if *all* test examples should work with the same stubbed value
|
|
||||||
(*no* examples set a different value).
|
|
||||||
"""
|
|
||||||
defmacro clear_config_all(config_path, do: yield) do
|
|
||||||
quote do
|
|
||||||
setup_all do
|
|
||||||
initial_setting = Config.get(unquote(config_path))
|
|
||||||
unquote(yield)
|
|
||||||
on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
|
|
||||||
:ok
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -55,9 +37,7 @@ defmacro __using__(_opts) do
|
||||||
import Pleroma.Tests.Helpers,
|
import Pleroma.Tests.Helpers,
|
||||||
only: [
|
only: [
|
||||||
clear_config: 1,
|
clear_config: 1,
|
||||||
clear_config: 2,
|
clear_config: 2
|
||||||
clear_config_all: 1,
|
|
||||||
clear_config_all: 2
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def to_datetime(naive_datetime) do
|
def to_datetime(naive_datetime) do
|
||||||
|
|
|
@ -20,9 +20,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config_all(:configurable_from_database) do
|
setup_all do: clear_config(:configurable_from_database, true)
|
||||||
Pleroma.Config.put(:configurable_from_database, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "error if file with custom settings doesn't exist" do
|
test "error if file with custom settings doesn't exist" do
|
||||||
Mix.Tasks.Pleroma.Config.migrate_to_db("config/not_existance_config_file.exs")
|
Mix.Tasks.Pleroma.Config.migrate_to_db("config/not_existance_config_file.exs")
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule Mix.Tasks.Pleroma.RobotsTxtTest do
|
||||||
use Pleroma.Tests.Helpers
|
use Pleroma.Tests.Helpers
|
||||||
alias Mix.Tasks.Pleroma.RobotsTxt
|
alias Mix.Tasks.Pleroma.RobotsTxt
|
||||||
|
|
||||||
clear_config([:instance, :static_dir])
|
setup do: clear_config([:instance, :static_dir])
|
||||||
|
|
||||||
test "creates new dir" do
|
test "creates new dir" do
|
||||||
path = "test/fixtures/new_dir/"
|
path = "test/fixtures/new_dir/"
|
||||||
|
|
|
@ -18,7 +18,7 @@ defmodule Pleroma.Upload.Filter.AnonymizeFilenameTest do
|
||||||
%{upload_file: upload_file}
|
%{upload_file: upload_file}
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text])
|
setup do: clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text])
|
||||||
|
|
||||||
test "it replaces filename on pre-defined text", %{upload_file: upload_file} do
|
test "it replaces filename on pre-defined text", %{upload_file: upload_file} do
|
||||||
Config.put([Upload.Filter.AnonymizeFilename, :text], "custom-file.png")
|
Config.put([Upload.Filter.AnonymizeFilename, :text], "custom-file.png")
|
||||||
|
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Upload.Filter.MogrifyTest do
|
||||||
alias Pleroma.Upload
|
alias Pleroma.Upload
|
||||||
alias Pleroma.Upload.Filter
|
alias Pleroma.Upload.Filter
|
||||||
|
|
||||||
clear_config([Filter.Mogrify, :args])
|
setup do: clear_config([Filter.Mogrify, :args])
|
||||||
|
|
||||||
test "apply mogrify filter" do
|
test "apply mogrify filter" do
|
||||||
Config.put([Filter.Mogrify, :args], [{"tint", "40"}])
|
Config.put([Filter.Mogrify, :args], [{"tint", "40"}])
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Upload.FilterTest do
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Upload.Filter
|
alias Pleroma.Upload.Filter
|
||||||
|
|
||||||
clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text])
|
setup do: clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text])
|
||||||
|
|
||||||
test "applies filters" do
|
test "applies filters" do
|
||||||
Config.put([Pleroma.Upload.Filter.AnonymizeFilename, :text], "custom-file.png")
|
Config.put([Pleroma.Upload.Filter.AnonymizeFilename, :text], "custom-file.png")
|
||||||
|
|
|
@ -250,9 +250,7 @@ test "escapes reserved uri characters" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Setting a custom base_url for uploaded media" do
|
describe "Setting a custom base_url for uploaded media" do
|
||||||
clear_config([Pleroma.Upload, :base_url]) do
|
setup do: clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social")
|
||||||
Pleroma.Config.put([Pleroma.Upload, :base_url], "https://cache.pleroma.social")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns a media url with configured base_url" do
|
test "returns a media url with configured base_url" do
|
||||||
base_url = Pleroma.Config.get([Pleroma.Upload, :base_url])
|
base_url = Pleroma.Config.get([Pleroma.Upload, :base_url])
|
||||||
|
|
|
@ -11,12 +11,11 @@ defmodule Pleroma.Uploaders.S3Test do
|
||||||
import Mock
|
import Mock
|
||||||
import ExUnit.CaptureLog
|
import ExUnit.CaptureLog
|
||||||
|
|
||||||
clear_config([Pleroma.Uploaders.S3]) do
|
setup do:
|
||||||
Config.put([Pleroma.Uploaders.S3],
|
clear_config(Pleroma.Uploaders.S3,
|
||||||
bucket: "test_bucket",
|
bucket: "test_bucket",
|
||||||
public_endpoint: "https://s3.amazonaws.com"
|
public_endpoint: "https://s3.amazonaws.com"
|
||||||
)
|
)
|
||||||
end
|
|
||||||
|
|
||||||
describe "get_file/1" do
|
describe "get_file/1" do
|
||||||
test "it returns path to local folder for files" do
|
test "it returns path to local folder for files" do
|
||||||
|
|
|
@ -15,7 +15,7 @@ defmodule Pleroma.UserSearchTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "User.search" do
|
describe "User.search" do
|
||||||
clear_config([:instance, :limit_to_local_content])
|
setup do: clear_config([:instance, :limit_to_local_content])
|
||||||
|
|
||||||
test "excluded invisible users from results" do
|
test "excluded invisible users from results" do
|
||||||
user = insert(:user, %{nickname: "john t1000"})
|
user = insert(:user, %{nickname: "john t1000"})
|
||||||
|
|
|
@ -24,7 +24,7 @@ defmodule Pleroma.UserTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
describe "service actors" do
|
describe "service actors" do
|
||||||
test "returns updated invisible actor" do
|
test "returns updated invisible actor" do
|
||||||
|
@ -297,7 +297,7 @@ test "local users do not automatically follow local locked accounts" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "unfollow/2" do
|
describe "unfollow/2" do
|
||||||
clear_config([:instance, :external_user_synchronization])
|
setup do: clear_config([:instance, :external_user_synchronization])
|
||||||
|
|
||||||
test "unfollow with syncronizes external user" do
|
test "unfollow with syncronizes external user" do
|
||||||
Pleroma.Config.put([:instance, :external_user_synchronization], true)
|
Pleroma.Config.put([:instance, :external_user_synchronization], true)
|
||||||
|
@ -375,10 +375,9 @@ test "fetches correct profile for nickname beginning with number" do
|
||||||
password_confirmation: "test",
|
password_confirmation: "test",
|
||||||
email: "email@example.com"
|
email: "email@example.com"
|
||||||
}
|
}
|
||||||
|
setup do: clear_config([:instance, :autofollowed_nicknames])
|
||||||
clear_config([:instance, :autofollowed_nicknames])
|
setup do: clear_config([:instance, :welcome_message])
|
||||||
clear_config([:instance, :welcome_message])
|
setup do: clear_config([:instance, :welcome_user_nickname])
|
||||||
clear_config([:instance, :welcome_user_nickname])
|
|
||||||
|
|
||||||
test "it autofollows accounts that are set for it" do
|
test "it autofollows accounts that are set for it" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -412,7 +411,7 @@ test "it sends a welcome message if it is set" do
|
||||||
assert activity.actor == welcome_user.ap_id
|
assert activity.actor == welcome_user.ap_id
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
|
test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
|
||||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||||
|
@ -475,10 +474,7 @@ test "it sets the password_hash and ap_id" do
|
||||||
password_confirmation: "test",
|
password_confirmation: "test",
|
||||||
email: "email@example.com"
|
email: "email@example.com"
|
||||||
}
|
}
|
||||||
|
setup do: clear_config([:instance, :account_activation_required], true)
|
||||||
clear_config([:instance, :account_activation_required]) do
|
|
||||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it creates unconfirmed user" do
|
test "it creates unconfirmed user" do
|
||||||
changeset = User.register_changeset(%User{}, @full_user_data)
|
changeset = User.register_changeset(%User{}, @full_user_data)
|
||||||
|
@ -621,9 +617,8 @@ test "returns an ap_followers link for a user" do
|
||||||
ap_id: "http...",
|
ap_id: "http...",
|
||||||
avatar: %{some: "avatar"}
|
avatar: %{some: "avatar"}
|
||||||
}
|
}
|
||||||
|
setup do: clear_config([:instance, :user_bio_length])
|
||||||
clear_config([:instance, :user_bio_length])
|
setup do: clear_config([:instance, :user_name_length])
|
||||||
clear_config([:instance, :user_name_length])
|
|
||||||
|
|
||||||
test "it confirms validity" do
|
test "it confirms validity" do
|
||||||
cs = User.remote_user_creation(@valid_remote)
|
cs = User.remote_user_creation(@valid_remote)
|
||||||
|
@ -1116,7 +1111,7 @@ test "hide a user's statuses from timelines and notifications" do
|
||||||
[user: user]
|
[user: user]
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :federating])
|
setup do: clear_config([:instance, :federating])
|
||||||
|
|
||||||
test ".delete_user_activities deletes all create activities", %{user: user} do
|
test ".delete_user_activities deletes all create activities", %{user: user} do
|
||||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
|
||||||
|
@ -1297,7 +1292,7 @@ test "User.delete() plugs any possible zombie objects" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "account_status/1" do
|
describe "account_status/1" do
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
test "return confirmation_pending for unconfirm user" do
|
test "return confirmation_pending for unconfirm user" do
|
||||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||||
|
@ -1665,7 +1660,7 @@ test "performs update cache if user updated" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "following/followers synchronization" do
|
describe "following/followers synchronization" do
|
||||||
clear_config([:instance, :external_user_synchronization])
|
setup do: clear_config([:instance, :external_user_synchronization])
|
||||||
|
|
||||||
test "updates the counters normally on following/getting a follow when disabled" do
|
test "updates the counters normally on following/getting a follow when disabled" do
|
||||||
Pleroma.Config.put([:instance, :external_user_synchronization], false)
|
Pleroma.Config.put([:instance, :external_user_synchronization], false)
|
||||||
|
@ -1770,7 +1765,7 @@ test "changes email", %{user: user} do
|
||||||
[local_user: local_user, remote_user: remote_user]
|
[local_user: local_user, remote_user: remote_user]
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :limit_to_local_content])
|
setup do: clear_config([:instance, :limit_to_local_content])
|
||||||
|
|
||||||
test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
|
test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
|
||||||
remote_user: remote_user
|
remote_user: remote_user
|
||||||
|
|
|
@ -26,12 +26,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :federating]) do
|
setup do: clear_config([:instance, :federating], true)
|
||||||
Config.put([:instance, :federating], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "/relay" do
|
describe "/relay" do
|
||||||
clear_config([:instance, :allow_relay])
|
setup do: clear_config([:instance, :allow_relay])
|
||||||
|
|
||||||
test "with the relay active, it returns the relay user", %{conn: conn} do
|
test "with the relay active, it returns the relay user", %{conn: conn} do
|
||||||
res =
|
res =
|
||||||
|
@ -1227,8 +1225,8 @@ test "GET /api/ap/whoami", %{conn: conn} do
|
||||||
|> json_response(403)
|
|> json_response(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:media_proxy])
|
setup do: clear_config([:media_proxy])
|
||||||
clear_config([Pleroma.Upload])
|
setup do: clear_config([Pleroma.Upload])
|
||||||
|
|
||||||
test "POST /api/ap/upload_media", %{conn: conn} do
|
test "POST /api/ap/upload_media", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -27,7 +27,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :federating])
|
setup do: clear_config([:instance, :federating])
|
||||||
|
|
||||||
describe "streaming out participations" do
|
describe "streaming out participations" do
|
||||||
test "it streams them out" do
|
test "it streams them out" do
|
||||||
|
@ -1396,7 +1396,7 @@ test "creates an undo activity for the last block" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "deletion" do
|
describe "deletion" do
|
||||||
clear_config([:instance, :rewrite_policy])
|
setup do: clear_config([:instance, :rewrite_policy])
|
||||||
|
|
||||||
test "it reverts deletion on error" do
|
test "it reverts deletion on error" do
|
||||||
note = insert(:note_activity)
|
note = insert(:note_activity)
|
||||||
|
@ -1425,6 +1425,12 @@ test "it creates a delete activity and deletes the original object" do
|
||||||
assert Repo.get(Object, object.id).data["type"] == "Tombstone"
|
assert Repo.get(Object, object.id).data["type"] == "Tombstone"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it doesn't fail when an activity was already deleted" do
|
||||||
|
{:ok, delete} = insert(:note_activity) |> Object.normalize() |> ActivityPub.delete()
|
||||||
|
|
||||||
|
assert {:ok, ^delete} = delete |> Object.normalize() |> ActivityPub.delete()
|
||||||
|
end
|
||||||
|
|
||||||
test "decrements user note count only for public activities" do
|
test "decrements user note count only for public activities" do
|
||||||
user = insert(:user, note_count: 10)
|
user = insert(:user, note_count: 10)
|
||||||
|
|
||||||
|
@ -1580,7 +1586,7 @@ test "it filters broken threads" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "update" do
|
describe "update" do
|
||||||
clear_config([:instance, :max_pinned_statuses])
|
setup do: clear_config([:instance, :max_pinned_statuses])
|
||||||
|
|
||||||
test "it creates an update activity with the new user data" do
|
test "it creates an update activity with the new user data" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -1955,11 +1961,9 @@ test "create" do
|
||||||
|
|
||||||
activity = %Activity{activity | object: nil}
|
activity = %Activity{activity | object: nil}
|
||||||
|
|
||||||
assert [%Notification{activity: ^activity}] =
|
assert [%Notification{activity: ^activity}] = Notification.for_user(follower)
|
||||||
Notification.for_user(follower, %{with_move: true})
|
|
||||||
|
|
||||||
assert [%Notification{activity: ^activity}] =
|
assert [%Notification{activity: ^activity}] = Notification.for_user(follower_move_opted_out)
|
||||||
Notification.for_user(follower_move_opted_out, %{with_move: true})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "old user must be in the new user's `also_known_as` list" do
|
test "old user must be in the new user's `also_known_as` list" do
|
||||||
|
|
|
@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
|
||||||
[user: user, message: message]
|
[user: user, message: message]
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config(:mrf_hellthread)
|
setup do: clear_config(:mrf_hellthread)
|
||||||
|
|
||||||
describe "reject" do
|
describe "reject" do
|
||||||
test "rejects the message if the recipient count is above reject_threshold", %{
|
test "rejects the message if the recipient count is above reject_threshold", %{
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy
|
alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy
|
||||||
|
|
||||||
clear_config(:mrf_keyword)
|
setup do: clear_config(:mrf_keyword)
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []})
|
Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []})
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.MRF.MentionPolicy
|
alias Pleroma.Web.ActivityPub.MRF.MentionPolicy
|
||||||
|
|
||||||
clear_config(:mrf_mention)
|
setup do: clear_config(:mrf_mention)
|
||||||
|
|
||||||
test "pass filter if allow list is empty" do
|
test "pass filter if allow list is empty" do
|
||||||
Pleroma.Config.delete([:mrf_mention])
|
Pleroma.Config.delete([:mrf_mention])
|
||||||
|
|
|
@ -60,7 +60,7 @@ test "matches are case-insensitive" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "describe/0" do
|
describe "describe/0" do
|
||||||
clear_config([:instance, :rewrite_policy])
|
setup do: clear_config([:instance, :rewrite_policy])
|
||||||
|
|
||||||
test "it works as expected with noop policy" do
|
test "it works as expected with noop policy" do
|
||||||
expected = %{
|
expected = %{
|
||||||
|
|
|
@ -9,12 +9,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
||||||
alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy
|
alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
|
|
||||||
clear_config([:mrf_object_age]) do
|
setup do:
|
||||||
Config.put(:mrf_object_age,
|
clear_config(:mrf_object_age,
|
||||||
threshold: 172_800,
|
threshold: 172_800,
|
||||||
actions: [:delist, :strip_followers]
|
actions: [:delist, :strip_followers]
|
||||||
)
|
)
|
||||||
end
|
|
||||||
|
|
||||||
setup_all do
|
setup_all do
|
||||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.MRF.RejectNonPublic
|
alias Pleroma.Web.ActivityPub.MRF.RejectNonPublic
|
||||||
|
|
||||||
clear_config([:mrf_rejectnonpublic])
|
setup do: clear_config([:mrf_rejectnonpublic])
|
||||||
|
|
||||||
describe "public message" do
|
describe "public message" do
|
||||||
test "it's allowed when address is public" do
|
test "it's allowed when address is public" do
|
||||||
|
|
|
@ -8,18 +8,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
|
alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
|
||||||
|
|
||||||
clear_config([:mrf_simple]) do
|
setup do:
|
||||||
Config.put(:mrf_simple,
|
clear_config(:mrf_simple,
|
||||||
media_removal: [],
|
media_removal: [],
|
||||||
media_nsfw: [],
|
media_nsfw: [],
|
||||||
federated_timeline_removal: [],
|
federated_timeline_removal: [],
|
||||||
report_removal: [],
|
report_removal: [],
|
||||||
reject: [],
|
reject: [],
|
||||||
accept: [],
|
accept: [],
|
||||||
avatar_removal: [],
|
avatar_removal: [],
|
||||||
banner_removal: []
|
banner_removal: []
|
||||||
)
|
)
|
||||||
end
|
|
||||||
|
|
||||||
describe "when :media_removal" do
|
describe "when :media_removal" do
|
||||||
test "is empty" do
|
test "is empty" do
|
||||||
|
|
|
@ -13,8 +13,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicyTest do
|
||||||
"type" => "Create",
|
"type" => "Create",
|
||||||
"object" => %{"content" => "hi"}
|
"object" => %{"content" => "hi"}
|
||||||
}
|
}
|
||||||
|
setup do: clear_config([:mrf_subchain, :match_actor])
|
||||||
clear_config([:mrf_subchain, :match_actor])
|
|
||||||
|
|
||||||
test "it matches and processes subchains when the actor matches a configured target" do
|
test "it matches and processes subchains when the actor matches a configured target" do
|
||||||
Pleroma.Config.put([:mrf_subchain, :match_actor], %{
|
Pleroma.Config.put([:mrf_subchain, :match_actor], %{
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy
|
alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy
|
||||||
|
|
||||||
clear_config([:mrf_user_allowlist, :localhost])
|
setup do: clear_config([:mrf_user_allowlist, :localhost])
|
||||||
|
|
||||||
test "pass filter if allow list is empty" do
|
test "pass filter if allow list is empty" do
|
||||||
actor = insert(:user)
|
actor = insert(:user)
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
|
||||||
alias Pleroma.Web.ActivityPub.MRF.VocabularyPolicy
|
alias Pleroma.Web.ActivityPub.MRF.VocabularyPolicy
|
||||||
|
|
||||||
describe "accept" do
|
describe "accept" do
|
||||||
clear_config([:mrf_vocabulary, :accept])
|
setup do: clear_config([:mrf_vocabulary, :accept])
|
||||||
|
|
||||||
test "it accepts based on parent activity type" do
|
test "it accepts based on parent activity type" do
|
||||||
Pleroma.Config.put([:mrf_vocabulary, :accept], ["Like"])
|
Pleroma.Config.put([:mrf_vocabulary, :accept], ["Like"])
|
||||||
|
@ -65,7 +65,7 @@ test "it does not accept disallowed parent types" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "reject" do
|
describe "reject" do
|
||||||
clear_config([:mrf_vocabulary, :reject])
|
setup do: clear_config([:mrf_vocabulary, :reject])
|
||||||
|
|
||||||
test "it rejects based on parent activity type" do
|
test "it rejects based on parent activity type" do
|
||||||
Pleroma.Config.put([:mrf_vocabulary, :reject], ["Like"])
|
Pleroma.Config.put([:mrf_vocabulary, :reject], ["Like"])
|
||||||
|
|
|
@ -23,9 +23,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config_all([:instance, :federating]) do
|
setup_all do: clear_config([:instance, :federating], true)
|
||||||
Pleroma.Config.put([:instance, :federating], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "gather_webfinger_links/1" do
|
describe "gather_webfinger_links/1" do
|
||||||
test "it returns links" do
|
test "it returns links" do
|
||||||
|
|
|
@ -68,7 +68,7 @@ test "returns activity" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "publish/1" do
|
describe "publish/1" do
|
||||||
clear_config([:instance, :federating])
|
setup do: clear_config([:instance, :federating])
|
||||||
|
|
||||||
test "returns error when activity not `Create` type" do
|
test "returns error when activity not `Create` type" do
|
||||||
activity = insert(:like_activity)
|
activity = insert(:like_activity)
|
||||||
|
|
|
@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "handle_incoming" do
|
describe "handle_incoming" do
|
||||||
clear_config([:user, :deny_follow_blocked])
|
setup do: clear_config([:user, :deny_follow_blocked])
|
||||||
|
|
||||||
test "it works for osada follow request" do
|
test "it works for osada follow request" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -25,7 +25,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :max_remote_account_fields])
|
setup do: clear_config([:instance, :max_remote_account_fields])
|
||||||
|
|
||||||
describe "handle_incoming" do
|
describe "handle_incoming" do
|
||||||
test "it ignores an incoming notice if we already have it" do
|
test "it ignores an incoming notice if we already have it" do
|
||||||
|
@ -1351,11 +1351,8 @@ test "it accepts Move activities" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "`handle_incoming/2`, Mastodon format `replies` handling" do
|
describe "`handle_incoming/2`, Mastodon format `replies` handling" do
|
||||||
clear_config([:activitypub, :note_replies_output_limit]) do
|
setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
|
||||||
Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5)
|
setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
|
||||||
end
|
|
||||||
|
|
||||||
clear_config([:instance, :federation_incoming_replies_max_depth])
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
data =
|
data =
|
||||||
|
@ -1394,11 +1391,8 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "`handle_incoming/2`, Pleroma format `replies` handling" do
|
describe "`handle_incoming/2`, Pleroma format `replies` handling" do
|
||||||
clear_config([:activitypub, :note_replies_output_limit]) do
|
setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
|
||||||
Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5)
|
setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
|
||||||
end
|
|
||||||
|
|
||||||
clear_config([:instance, :federation_incoming_replies_max_depth])
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -1882,7 +1876,7 @@ test "returns fixed object" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "fix_in_reply_to/2" do
|
describe "fix_in_reply_to/2" do
|
||||||
clear_config([:instance, :federation_incoming_replies_max_depth])
|
setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
|
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
|
||||||
|
@ -2145,9 +2139,7 @@ test "returns object with emoji when object contains map tag" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "set_replies/1" do
|
describe "set_replies/1" do
|
||||||
clear_config([:activitypub, :note_replies_output_limit]) do
|
setup do: clear_config([:activitypub, :note_replies_output_limit], 2)
|
||||||
Pleroma.Config.put([:activitypub, :note_replies_output_limit], 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns unmodified object if activity doesn't have self-replies" do
|
test "returns unmodified object if activity doesn't have self-replies" do
|
||||||
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
|
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
|
||||||
|
|
|
@ -37,9 +37,7 @@ test "renders a note activity" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "note activity's `replies` collection rendering" do
|
describe "note activity's `replies` collection rendering" do
|
||||||
clear_config([:activitypub, :note_replies_output_limit]) do
|
setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
|
||||||
Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "renders `replies` collection for a note activity" do
|
test "renders `replies` collection for a note activity" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -43,9 +43,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
||||||
Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
||||||
%{admin: admin} do
|
%{admin: admin} do
|
||||||
|
@ -93,9 +91,7 @@ test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or bro
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||||
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
||||||
Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/users/:nickname requires " <>
|
test "GET /api/pleroma/admin/users/:nickname requires " <>
|
||||||
"read:accounts or admin:read:accounts or broader scope",
|
"read:accounts or admin:read:accounts or broader scope",
|
||||||
|
@ -581,13 +577,8 @@ test "/:right DELETE, can remove from a permission group (multiple)", %{
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /api/pleroma/admin/email_invite, with valid config" do
|
describe "POST /api/pleroma/admin/email_invite, with valid config" do
|
||||||
clear_config([:instance, :registrations_open]) do
|
setup do: clear_config([:instance, :registrations_open], false)
|
||||||
Config.put([:instance, :registrations_open], false)
|
setup do: clear_config([:instance, :invites_enabled], true)
|
||||||
end
|
|
||||||
|
|
||||||
clear_config([:instance, :invites_enabled]) do
|
|
||||||
Config.put([:instance, :invites_enabled], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "sends invitation and returns 204", %{admin: admin, conn: conn} do
|
test "sends invitation and returns 204", %{admin: admin, conn: conn} do
|
||||||
recipient_email = "foo@bar.com"
|
recipient_email = "foo@bar.com"
|
||||||
|
@ -638,8 +629,8 @@ test "it returns 403 if requested by a non-admin" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
|
describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
|
||||||
clear_config([:instance, :registrations_open])
|
setup do: clear_config([:instance, :registrations_open])
|
||||||
clear_config([:instance, :invites_enabled])
|
setup do: clear_config([:instance, :invites_enabled])
|
||||||
|
|
||||||
test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
|
test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
|
||||||
Config.put([:instance, :registrations_open], false)
|
Config.put([:instance, :registrations_open], false)
|
||||||
|
@ -1888,9 +1879,7 @@ test "returns 404 when the status does not exist", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/config" do
|
describe "GET /api/pleroma/admin/config" do
|
||||||
clear_config(:configurable_from_database) do
|
setup do: clear_config(:configurable_from_database, true)
|
||||||
Config.put(:configurable_from_database, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "when configuration from database is off", %{conn: conn} do
|
test "when configuration from database is off", %{conn: conn} do
|
||||||
Config.put(:configurable_from_database, false)
|
Config.put(:configurable_from_database, false)
|
||||||
|
@ -2041,9 +2030,7 @@ test "POST /api/pleroma/admin/config error", %{conn: conn} do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config(:configurable_from_database) do
|
setup do: clear_config(:configurable_from_database, true)
|
||||||
Config.put(:configurable_from_database, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
@tag capture_log: true
|
@tag capture_log: true
|
||||||
test "create new config setting in db", %{conn: conn} do
|
test "create new config setting in db", %{conn: conn} do
|
||||||
|
@ -3052,9 +3039,7 @@ test "proxy tuple ip", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/restart" do
|
describe "GET /api/pleroma/admin/restart" do
|
||||||
clear_config(:configurable_from_database) do
|
setup do: clear_config(:configurable_from_database, true)
|
||||||
Config.put(:configurable_from_database, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "pleroma restarts", %{conn: conn} do
|
test "pleroma restarts", %{conn: conn} do
|
||||||
capture_log(fn ->
|
capture_log(fn ->
|
||||||
|
@ -3389,6 +3374,75 @@ test "returns log filtered by search", %{conn: conn, moderator: moderator} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "GET /users/:nickname/credentials" do
|
||||||
|
test "gets the user credentials", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
|
||||||
|
|
||||||
|
response = assert json_response(conn, 200)
|
||||||
|
assert response["email"] == user.email
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 403 if requested by a non-admin" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> get("/api/pleroma/admin/users/#{user.nickname}/credentials")
|
||||||
|
|
||||||
|
assert json_response(conn, :forbidden)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH /users/:nickname/credentials" do
|
||||||
|
test "changes password and email", %{conn: conn, admin: admin} do
|
||||||
|
user = insert(:user)
|
||||||
|
assert user.password_reset_pending == false
|
||||||
|
|
||||||
|
conn =
|
||||||
|
patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
|
||||||
|
"password" => "new_password",
|
||||||
|
"email" => "new_email@example.com",
|
||||||
|
"name" => "new_name"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{"status" => "success"}
|
||||||
|
|
||||||
|
ObanHelpers.perform_all()
|
||||||
|
|
||||||
|
updated_user = User.get_by_id(user.id)
|
||||||
|
|
||||||
|
assert updated_user.email == "new_email@example.com"
|
||||||
|
assert updated_user.name == "new_name"
|
||||||
|
assert updated_user.password_hash != user.password_hash
|
||||||
|
assert updated_user.password_reset_pending == true
|
||||||
|
|
||||||
|
[log_entry2, log_entry1] = ModerationLog |> Repo.all() |> Enum.sort()
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry1) ==
|
||||||
|
"@#{admin.nickname} updated users: @#{user.nickname}"
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry2) ==
|
||||||
|
"@#{admin.nickname} forced password reset for users: @#{user.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 403 if requested by a non-admin" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> patch("/api/pleroma/admin/users/#{user.nickname}/credentials", %{
|
||||||
|
"password" => "new_password",
|
||||||
|
"email" => "new_email@example.com",
|
||||||
|
"name" => "new_name"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert json_response(conn, :forbidden)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "PATCH /users/:nickname/force_password_reset" do
|
describe "PATCH /users/:nickname/force_password_reset" do
|
||||||
test "sets password_reset_pending to true", %{conn: conn} do
|
test "sets password_reset_pending to true", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -21,7 +21,7 @@ test "it broadcasts a message", %{socket: socket} do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "message lengths" do
|
describe "message lengths" do
|
||||||
clear_config([:instance, :chat_limit])
|
setup do: clear_config([:instance, :chat_limit])
|
||||||
|
|
||||||
test "it ignores messages of length zero", %{socket: socket} do
|
test "it ignores messages of length zero", %{socket: socket} do
|
||||||
push(socket, "new_msg", %{"text" => ""})
|
push(socket, "new_msg", %{"text" => ""})
|
||||||
|
|
|
@ -17,9 +17,9 @@ defmodule Pleroma.Web.CommonAPITest do
|
||||||
|
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
|
||||||
clear_config([:instance, :safe_dm_mentions])
|
setup do: clear_config([:instance, :safe_dm_mentions])
|
||||||
clear_config([:instance, :limit])
|
setup do: clear_config([:instance, :limit])
|
||||||
clear_config([:instance, :max_pinned_statuses])
|
setup do: clear_config([:instance, :max_pinned_statuses])
|
||||||
|
|
||||||
test "when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given" do
|
test "when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -21,13 +21,10 @@ defmodule Pleroma.Web.FederatorTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config_all([:instance, :federating]) do
|
setup_all do: clear_config([:instance, :federating], true)
|
||||||
Pleroma.Config.put([:instance, :federating], true)
|
setup do: clear_config([:instance, :allow_relay])
|
||||||
end
|
setup do: clear_config([:instance, :rewrite_policy])
|
||||||
|
setup do: clear_config([:mrf_keyword])
|
||||||
clear_config([:instance, :allow_relay])
|
|
||||||
clear_config([:instance, :rewrite_policy])
|
|
||||||
clear_config([:mrf_keyword])
|
|
||||||
|
|
||||||
describe "Publish an activity" do
|
describe "Publish an activity" do
|
||||||
setup do
|
setup do
|
||||||
|
|
|
@ -8,9 +8,11 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import SweetXml
|
import SweetXml
|
||||||
|
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.Feed.FeedView
|
alias Pleroma.Web.Feed.FeedView
|
||||||
|
|
||||||
clear_config([:feed])
|
setup do: clear_config([:feed])
|
||||||
|
|
||||||
test "gets a feed (ATOM)", %{conn: conn} do
|
test "gets a feed (ATOM)", %{conn: conn} do
|
||||||
Pleroma.Config.put(
|
Pleroma.Config.put(
|
||||||
|
@ -19,9 +21,9 @@ test "gets a feed (ATOM)", %{conn: conn} do
|
||||||
)
|
)
|
||||||
|
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
|
{:ok, activity1} = CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
|
||||||
|
|
||||||
object = Pleroma.Object.normalize(activity1)
|
object = Object.normalize(activity1)
|
||||||
|
|
||||||
object_data =
|
object_data =
|
||||||
Map.put(object.data, "attachment", [
|
Map.put(object.data, "attachment", [
|
||||||
|
@ -41,14 +43,13 @@ test "gets a feed (ATOM)", %{conn: conn} do
|
||||||
|> Ecto.Changeset.change(data: object_data)
|
|> Ecto.Changeset.change(data: object_data)
|
||||||
|> Pleroma.Repo.update()
|
|> Pleroma.Repo.update()
|
||||||
|
|
||||||
{:ok, _activity2} =
|
{:ok, activity2} = CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
|
||||||
Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
|
|
||||||
|
|
||||||
{:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"})
|
{:ok, _activity3} = CommonAPI.post(user, %{"status" => "This is :moominmamma"})
|
||||||
|
|
||||||
response =
|
response =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|> get(tag_feed_path(conn, :feed, "pleromaart.atom"))
|
|> get(tag_feed_path(conn, :feed, "pleromaart.atom"))
|
||||||
|> response(200)
|
|> response(200)
|
||||||
|
|
||||||
|
@ -63,6 +64,21 @@ test "gets a feed (ATOM)", %{conn: conn} do
|
||||||
|
|
||||||
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
|
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
|
||||||
assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id]
|
assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id]
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|
|> get("/tags/pleromaart.atom", %{"max_id" => activity2.id})
|
||||||
|
|
||||||
|
assert get_resp_header(conn, "content-type") == ["application/atom+xml; charset=utf-8"]
|
||||||
|
resp = response(conn, 200)
|
||||||
|
xml = parse(resp)
|
||||||
|
|
||||||
|
assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
|
||||||
|
|
||||||
|
assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
|
||||||
|
'yeah #PleromaArt'
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "gets a feed (RSS)", %{conn: conn} do
|
test "gets a feed (RSS)", %{conn: conn} do
|
||||||
|
@ -72,9 +88,9 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
)
|
)
|
||||||
|
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
|
{:ok, activity1} = CommonAPI.post(user, %{"status" => "yeah #PleromaArt"})
|
||||||
|
|
||||||
object = Pleroma.Object.normalize(activity1)
|
object = Object.normalize(activity1)
|
||||||
|
|
||||||
object_data =
|
object_data =
|
||||||
Map.put(object.data, "attachment", [
|
Map.put(object.data, "attachment", [
|
||||||
|
@ -94,14 +110,13 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
|> Ecto.Changeset.change(data: object_data)
|
|> Ecto.Changeset.change(data: object_data)
|
||||||
|> Pleroma.Repo.update()
|
|> Pleroma.Repo.update()
|
||||||
|
|
||||||
{:ok, activity2} =
|
{:ok, activity2} = CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
|
||||||
Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"})
|
|
||||||
|
|
||||||
{:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"})
|
{:ok, _activity3} = CommonAPI.post(user, %{"status" => "This is :moominmamma"})
|
||||||
|
|
||||||
response =
|
response =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/rss+xml")
|
|> put_req_header("accept", "application/rss+xml")
|
||||||
|> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
|
|> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
|
||||||
|> response(200)
|
|> response(200)
|
||||||
|
|
||||||
|
@ -131,8 +146,8 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
|
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
|
||||||
]
|
]
|
||||||
|
|
||||||
obj1 = Pleroma.Object.normalize(activity1)
|
obj1 = Object.normalize(activity1)
|
||||||
obj2 = Pleroma.Object.normalize(activity2)
|
obj2 = Object.normalize(activity2)
|
||||||
|
|
||||||
assert xpath(xml, ~x"//channel/item/description/text()"sl) == [
|
assert xpath(xml, ~x"//channel/item/description/text()"sl) == [
|
||||||
HtmlEntities.decode(FeedView.activity_content(obj2)),
|
HtmlEntities.decode(FeedView.activity_content(obj2)),
|
||||||
|
@ -141,7 +156,7 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
|
|
||||||
response =
|
response =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("accept", "application/rss+xml")
|
||||||
|> get(tag_feed_path(conn, :feed, "pleromaart"))
|
|> get(tag_feed_path(conn, :feed, "pleromaart"))
|
||||||
|> response(200)
|
|> response(200)
|
||||||
|
|
||||||
|
@ -150,5 +165,20 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
|
|
||||||
assert xpath(xml, ~x"//channel/description/text()"s) ==
|
assert xpath(xml, ~x"//channel/description/text()"s) ==
|
||||||
"These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
|
"These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/rss+xml")
|
||||||
|
|> get("/tags/pleromaart.rss", %{"max_id" => activity2.id})
|
||||||
|
|
||||||
|
assert get_resp_header(conn, "content-type") == ["application/rss+xml; charset=utf-8"]
|
||||||
|
resp = response(conn, 200)
|
||||||
|
xml = parse(resp)
|
||||||
|
|
||||||
|
assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
|
||||||
|
|
||||||
|
assert xpath(xml, ~x"//channel/item/title/text()"l) == [
|
||||||
|
'yeah #PleromaArt'
|
||||||
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,12 +12,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
clear_config([:instance, :federating]) do
|
setup do: clear_config([:instance, :federating], true)
|
||||||
Config.put([:instance, :federating], true)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "feed" do
|
describe "feed" do
|
||||||
clear_config([:feed])
|
setup do: clear_config([:feed])
|
||||||
|
|
||||||
test "gets a feed", %{conn: conn} do
|
test "gets a feed", %{conn: conn} do
|
||||||
Config.put(
|
Config.put(
|
||||||
|
@ -54,12 +52,12 @@ test "gets a feed", %{conn: conn} do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_note_activity2 = insert(:note_activity, note: note2)
|
note_activity2 = insert(:note_activity, note: note2)
|
||||||
object = Object.normalize(note_activity)
|
object = Object.normalize(note_activity)
|
||||||
|
|
||||||
resp =
|
resp =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|> get(user_feed_path(conn, :feed, user.nickname))
|
|> get(user_feed_path(conn, :feed, user.nickname))
|
||||||
|> response(200)
|
|> response(200)
|
||||||
|
|
||||||
|
@ -70,12 +68,91 @@ test "gets a feed", %{conn: conn} do
|
||||||
|
|
||||||
assert activity_titles == ['42 This...', 'This is...']
|
assert activity_titles == ['42 This...', 'This is...']
|
||||||
assert resp =~ object.data["content"]
|
assert resp =~ object.data["content"]
|
||||||
|
|
||||||
|
resp =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|
|> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
activity_titles =
|
||||||
|
resp
|
||||||
|
|> SweetXml.parse()
|
||||||
|
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||||
|
|
||||||
|
assert activity_titles == ['This is...']
|
||||||
|
end
|
||||||
|
|
||||||
|
test "gets a rss feed", %{conn: conn} do
|
||||||
|
Pleroma.Config.put(
|
||||||
|
[:feed, :post_title],
|
||||||
|
%{max_length: 10, omission: "..."}
|
||||||
|
)
|
||||||
|
|
||||||
|
activity = insert(:note_activity)
|
||||||
|
|
||||||
|
note =
|
||||||
|
insert(:note,
|
||||||
|
data: %{
|
||||||
|
"content" => "This is :moominmamma: note ",
|
||||||
|
"attachment" => [
|
||||||
|
%{
|
||||||
|
"url" => [
|
||||||
|
%{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inReplyTo" => activity.data["id"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
note_activity = insert(:note_activity, note: note)
|
||||||
|
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||||
|
|
||||||
|
note2 =
|
||||||
|
insert(:note,
|
||||||
|
user: user,
|
||||||
|
data: %{
|
||||||
|
"content" => "42 This is :moominmamma: note ",
|
||||||
|
"inReplyTo" => activity.data["id"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
note_activity2 = insert(:note_activity, note: note2)
|
||||||
|
object = Object.normalize(note_activity)
|
||||||
|
|
||||||
|
resp =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/rss+xml")
|
||||||
|
|> get("/users/#{user.nickname}/feed.rss")
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
activity_titles =
|
||||||
|
resp
|
||||||
|
|> SweetXml.parse()
|
||||||
|
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||||
|
|
||||||
|
assert activity_titles == ['42 This...', 'This is...']
|
||||||
|
assert resp =~ object.data["content"]
|
||||||
|
|
||||||
|
resp =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/rss+xml")
|
||||||
|
|> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
activity_titles =
|
||||||
|
resp
|
||||||
|
|> SweetXml.parse()
|
||||||
|
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||||
|
|
||||||
|
assert activity_titles == ['This is...']
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns 404 for a missing feed", %{conn: conn} do
|
test "returns 404 for a missing feed", %{conn: conn} do
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|> get(user_feed_path(conn, :feed, "nonexisting"))
|
|> get(user_feed_path(conn, :feed, "nonexisting"))
|
||||||
|
|
||||||
assert response(conn, 404)
|
assert response(conn, 404)
|
||||||
|
|
|
@ -10,9 +10,7 @@ defmodule Pleroma.Instances.InstanceTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config_all([:instance, :federation_reachability_timeout_days]) do
|
setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
|
||||||
Pleroma.Config.put([:instance, :federation_reachability_timeout_days], 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "set_reachable/1" do
|
describe "set_reachable/1" do
|
||||||
test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do
|
test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do
|
||||||
|
|
|
@ -7,9 +7,7 @@ defmodule Pleroma.InstancesTest do
|
||||||
|
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
|
|
||||||
clear_config_all([:instance, :federation_reachability_timeout_days]) do
|
setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
|
||||||
Pleroma.Config.put([:instance, :federation_reachability_timeout_days], 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "reachable?/1" do
|
describe "reachable?/1" do
|
||||||
test "returns `true` for host / url with unknown reachability status" do
|
test "returns `true` for host / url with unknown reachability status" do
|
||||||
|
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.MastoFEController do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config([:instance, :public])
|
setup do: clear_config([:instance, :public])
|
||||||
|
|
||||||
test "put settings", %{conn: conn} do
|
test "put settings", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -9,7 +9,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
clear_config([:instance, :max_account_fields])
|
|
||||||
|
setup do: clear_config([:instance, :max_account_fields])
|
||||||
|
|
||||||
describe "updating credentials" do
|
describe "updating credentials" do
|
||||||
setup do: oauth_access(["write:accounts"])
|
setup do: oauth_access(["write:accounts"])
|
||||||
|
@ -75,7 +76,7 @@ test "updates the user's bio", %{conn: conn} do
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||||
"note" => "I drink #cofe with @#{user2.nickname}"
|
"note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.."
|
||||||
})
|
})
|
||||||
|
|
||||||
assert user_data = json_response(conn, 200)
|
assert user_data = json_response(conn, 200)
|
||||||
|
@ -83,7 +84,7 @@ test "updates the user's bio", %{conn: conn} do
|
||||||
assert user_data["note"] ==
|
assert user_data["note"] ==
|
||||||
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a data-user="#{
|
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a data-user="#{
|
||||||
user2.id
|
user2.id
|
||||||
}" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span>)
|
}" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "updates the user's locking status", %{conn: conn} do
|
test "updates the user's locking status", %{conn: conn} do
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
|
alias Pleroma.Config
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
@ -15,7 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
describe "account fetching" do
|
describe "account fetching" do
|
||||||
clear_config([:instance, :limit_to_local_content])
|
setup do: clear_config([:instance, :limit_to_local_content])
|
||||||
|
|
||||||
test "works by id" do
|
test "works by id" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -46,7 +47,7 @@ test "works by nickname" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "works by nickname for remote users" do
|
test "works by nickname for remote users" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], false)
|
Config.put([:instance, :limit_to_local_content], false)
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -58,7 +59,7 @@ test "works by nickname for remote users" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "respects limit_to_local_content == :all for remote user nicknames" do
|
test "respects limit_to_local_content == :all for remote user nicknames" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], :all)
|
Config.put([:instance, :limit_to_local_content], :all)
|
||||||
|
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ test "respects limit_to_local_content == :all for remote user nicknames" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
|
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
|
Config.put([:instance, :limit_to_local_content], :unauthenticated)
|
||||||
|
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
reading_user = insert(:user)
|
reading_user = insert(:user)
|
||||||
|
@ -140,6 +141,98 @@ test "returns 404 for internal.fetch actor", %{conn: conn} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_users do
|
||||||
|
local = insert(:user)
|
||||||
|
remote = insert(:user, local: false)
|
||||||
|
{:ok, local: local, remote: remote}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for local and remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for local" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "user timelines" do
|
describe "user timelines" do
|
||||||
setup do: oauth_access(["read:statuses"])
|
setup do: oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
@ -293,6 +386,102 @@ test "the user views their own timelines and excludes direct messages", %{
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities(%{local: local, remote: remote}) do
|
||||||
|
insert(:note_activity, user: local)
|
||||||
|
insert(:note_activity, user: remote, local: false)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for local and remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for local" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "followers" do
|
describe "followers" do
|
||||||
setup do: oauth_access(["read:accounts"])
|
setup do: oauth_access(["read:accounts"])
|
||||||
|
|
||||||
|
@ -601,7 +790,7 @@ test "blocking / unblocking a user" do
|
||||||
[valid_params: valid_params]
|
[valid_params: valid_params]
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
test "Account registration via Application", %{conn: conn} do
|
test "Account registration via Application", %{conn: conn} do
|
||||||
conn =
|
conn =
|
||||||
|
@ -699,7 +888,7 @@ test "returns bad_request if missing required params", %{
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :account_activation_required])
|
setup do: clear_config([:instance, :account_activation_required])
|
||||||
|
|
||||||
test "returns bad_request if missing email params when :account_activation_required is enabled",
|
test "returns bad_request if missing email params when :account_activation_required is enabled",
|
||||||
%{conn: conn, valid_params: valid_params} do
|
%{conn: conn, valid_params: valid_params} do
|
||||||
|
@ -756,9 +945,7 @@ test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create account by app / rate limit" do
|
describe "create account by app / rate limit" do
|
||||||
clear_config([:rate_limit, :app_account_creation]) do
|
setup do: clear_config([:rate_limit, :app_account_creation], {10_000, 2})
|
||||||
Pleroma.Config.put([:rate_limit, :app_account_creation], {10_000, 2})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "respects rate limit setting", %{conn: conn} do
|
test "respects rate limit setting", %{conn: conn} do
|
||||||
app_token = insert(:oauth_token, user: nil)
|
app_token = insert(:oauth_token, user: nil)
|
||||||
|
|
|
@ -22,8 +22,8 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
||||||
[image: image]
|
[image: image]
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:media_proxy])
|
setup do: clear_config([:media_proxy])
|
||||||
clear_config([Pleroma.Upload])
|
setup do: clear_config([Pleroma.Upload])
|
||||||
|
|
||||||
test "returns uploaded image", %{conn: conn, image: image} do
|
test "returns uploaded image", %{conn: conn, image: image} do
|
||||||
desc = "Description of the image"
|
desc = "Description of the image"
|
||||||
|
|
|
@ -304,6 +304,51 @@ test "filters notifications using exclude_types" do
|
||||||
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "filters notifications using include_types" do
|
||||||
|
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
|
||||||
|
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
|
||||||
|
{:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user)
|
||||||
|
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
|
||||||
|
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
|
||||||
|
|
||||||
|
mention_notification_id = get_notification_id_by_activity(mention_activity)
|
||||||
|
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
|
||||||
|
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
|
||||||
|
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["follow"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["mention"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["favourite"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["reblog"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
result = conn |> get("/api/v1/notifications") |> json_response(200)
|
||||||
|
|
||||||
|
assert length(result) == 4
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/notifications", %{
|
||||||
|
include_types: ["follow", "mention", "favourite", "reblog"]
|
||||||
|
})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert length(result) == 4
|
||||||
|
end
|
||||||
|
|
||||||
test "destroy multiple" do
|
test "destroy multiple" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
@ -407,7 +452,7 @@ test "see notifications after muting user with notifications and with_muted para
|
||||||
assert length(json_response(conn, 200)) == 1
|
assert length(json_response(conn, 200)) == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "see move notifications with `with_move` parameter" do
|
test "see move notifications" do
|
||||||
old_user = insert(:user)
|
old_user = insert(:user)
|
||||||
new_user = insert(:user, also_known_as: [old_user.ap_id])
|
new_user = insert(:user, also_known_as: [old_user.ap_id])
|
||||||
%{user: follower, conn: conn} = oauth_access(["read:notifications"])
|
%{user: follower, conn: conn} = oauth_access(["read:notifications"])
|
||||||
|
@ -416,11 +461,7 @@ test "see move notifications with `with_move` parameter" do
|
||||||
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
||||||
Pleroma.Tests.ObanHelpers.perform_all()
|
Pleroma.Tests.ObanHelpers.perform_all()
|
||||||
|
|
||||||
ret_conn = get(conn, "/api/v1/notifications")
|
conn = get(conn, "/api/v1/notifications")
|
||||||
|
|
||||||
assert json_response(ret_conn, 200) == []
|
|
||||||
|
|
||||||
conn = get(conn, "/api/v1/notifications", %{"with_move" => "true"})
|
|
||||||
|
|
||||||
assert length(json_response(conn, 200)) == 1
|
assert length(json_response(conn, 200)) == 1
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
clear_config([ScheduledActivity, :enabled])
|
setup do: clear_config([ScheduledActivity, :enabled])
|
||||||
|
|
||||||
test "shows scheduled activities" do
|
test "shows scheduled activities" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
|
@ -19,9 +19,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
clear_config([:instance, :federating])
|
setup do: clear_config([:instance, :federating])
|
||||||
clear_config([:instance, :allow_relay])
|
setup do: clear_config([:instance, :allow_relay])
|
||||||
clear_config([:rich_media, :enabled])
|
setup do: clear_config([:rich_media, :enabled])
|
||||||
|
|
||||||
describe "posting statuses" do
|
describe "posting statuses" do
|
||||||
setup do: oauth_access(["write:statuses"])
|
setup do: oauth_access(["write:statuses"])
|
||||||
|
@ -476,6 +476,95 @@ test "get a status" do
|
||||||
assert id == to_string(activity.id)
|
assert id == to_string(activity.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities do
|
||||||
|
local = insert(:note_activity)
|
||||||
|
remote = insert(:note_activity, local: false)
|
||||||
|
{:ok, local: local, remote: remote}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for local and remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "getting a status that doesn't exist returns 404" do
|
test "getting a status that doesn't exist returns 404" do
|
||||||
%{conn: conn} = oauth_access(["read:statuses"])
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
|
@ -514,6 +603,70 @@ test "get statuses by IDs" do
|
||||||
assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"])
|
assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for local and remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert json_response(res_conn, 200) == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
remote_id = remote.id
|
||||||
|
assert [%{"id" => ^remote_id}] = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
local_id = local.id
|
||||||
|
assert [%{"id" => ^local_id}] = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "deleting a status" do
|
describe "deleting a status" do
|
||||||
test "when you created it" do
|
test "when you created it" do
|
||||||
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
||||||
|
@ -739,9 +892,7 @@ test "returns 404 error for a wrong id", %{conn: conn} do
|
||||||
%{activity: activity}
|
%{activity: activity}
|
||||||
end
|
end
|
||||||
|
|
||||||
clear_config([:instance, :max_pinned_statuses]) do
|
setup do: clear_config([:instance, :max_pinned_statuses], 1)
|
||||||
Config.put([:instance, :max_pinned_statuses], 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "pin status", %{conn: conn, user: user, activity: activity} do
|
test "pin status", %{conn: conn, user: user, activity: activity} do
|
||||||
id_str = to_string(activity.id)
|
id_str = to_string(activity.id)
|
||||||
|
|
|
@ -12,8 +12,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
clear_config([:instance, :public])
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
:ok
|
:ok
|
||||||
|
@ -80,15 +78,6 @@ test "the public timeline", %{conn: conn} do
|
||||||
assert [%{"content" => "test"}] = json_response(conn, :ok)
|
assert [%{"content" => "test"}] = json_response(conn, :ok)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "the public timeline when public is set to false", %{conn: conn} do
|
|
||||||
Config.put([:instance, :public], false)
|
|
||||||
|
|
||||||
assert %{"error" => "This resource requires authentication."} ==
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/timelines/public", %{"local" => "False"})
|
|
||||||
|> json_response(:forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "the public timeline includes only public statuses for an authenticated user" do
|
test "the public timeline includes only public statuses for an authenticated user" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
@ -102,6 +91,98 @@ test "the public timeline includes only public statuses for an authenticated use
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities do
|
||||||
|
insert(:note_activity)
|
||||||
|
insert(:note_activity, local: false)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for local and federated timelines" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated" do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{conn: _conn} do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{conn: _conn} do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "direct" do
|
describe "direct" do
|
||||||
test "direct timeline", %{conn: conn} do
|
test "direct timeline", %{conn: conn} do
|
||||||
user_one = insert(:user)
|
user_one = insert(:user)
|
||||||
|
|
|
@ -32,7 +32,8 @@ test "Represent a user account" do
|
||||||
background: background_image,
|
background: background_image,
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
name: ":karjalanpiirakka: shp",
|
name: ":karjalanpiirakka: shp",
|
||||||
bio: "<script src=\"invalid-html\"></script><span>valid html</span>",
|
bio:
|
||||||
|
"<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f",
|
||||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ test "Represent a user account" do
|
||||||
followers_count: 3,
|
followers_count: 3,
|
||||||
following_count: 0,
|
following_count: 0,
|
||||||
statuses_count: 5,
|
statuses_count: 5,
|
||||||
note: "<span>valid html</span>",
|
note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f",
|
||||||
url: user.ap_id,
|
url: user.ap_id,
|
||||||
avatar: "http://localhost:4001/images/avi.png",
|
avatar: "http://localhost:4001/images/avi.png",
|
||||||
avatar_static: "http://localhost:4001/images/avi.png",
|
avatar_static: "http://localhost:4001/images/avi.png",
|
||||||
|
@ -63,7 +64,7 @@ test "Represent a user account" do
|
||||||
fields: [],
|
fields: [],
|
||||||
bot: false,
|
bot: false,
|
||||||
source: %{
|
source: %{
|
||||||
note: "valid html",
|
note: "valid html. a\nb\nc\nd\nf",
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
actor_type: "Person",
|
actor_type: "Person",
|
||||||
|
|
|
@ -120,7 +120,7 @@ test "Move notification" do
|
||||||
old_user = refresh_record(old_user)
|
old_user = refresh_record(old_user)
|
||||||
new_user = refresh_record(new_user)
|
new_user = refresh_record(new_user)
|
||||||
|
|
||||||
[notification] = Notification.for_user(follower, %{with_move: true})
|
[notification] = Notification.for_user(follower)
|
||||||
|
|
||||||
expected = %{
|
expected = %{
|
||||||
id: to_string(notification.id),
|
id: to_string(notification.id),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue