summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--benchmarks/load_testing/activities.ex10
-rw-r--r--benchmarks/load_testing/fetcher.ex34
-rw-r--r--config/config.exs2
-rw-r--r--config/description.exs1
-rw-r--r--docs/API/differences_in_mastoapi_responses.md2
-rw-r--r--docs/configuration/cheatsheet.md1
-rw-r--r--lib/pleroma/filter.ex42
-rw-r--r--lib/pleroma/notification.ex39
-rw-r--r--lib/pleroma/plugs/static_fe_plug.ex9
-rw-r--r--lib/pleroma/upload.ex9
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex24
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex34
-rw-r--r--lib/pleroma/web/mastodon_api/views/instance_view.ex2
-rw-r--r--test/filter_test.exs59
-rw-r--r--test/fixtures/tesla_mock/framatube.org-video.json1
-rw-r--r--test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json1
-rw-r--r--test/notification_test.exs100
-rw-r--r--test/support/factory.ex8
-rw-r--r--test/support/http_request_mock.ex16
-rw-r--r--test/upload_test.exs13
-rw-r--r--test/web/activity_pub/activity_pub_test.exs96
-rw-r--r--test/web/activity_pub/transmogrifier_test.exs48
-rw-r--r--test/web/mastodon_api/controllers/instance_controller_test.exs4
-rw-r--r--test/web/static_fe/static_fe_controller_test.exs14
25 files changed, 492 insertions, 85 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 85401809a..0e2b54916 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,10 +16,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<details>
<summary>API Changes</summary>
+- **Breaking:** Image description length is limited now.
- **Breaking:** Emoji API: changed methods and renamed routes.
- Streaming: Repeats of a user's posts will no longer be pushed to the user's stream.
- Mastodon API: Added `pleroma.metadata.fields_limits` to /api/v1/instance
- Mastodon API: On deletion, returns the original post text.
+- Mastodon API: Add `pleroma.unread_count` to the Marker entity.
</details>
<details>
@@ -58,8 +60,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: Extended `/api/v1/instance`.
- Mastodon API: Support for `include_types` in `/api/v1/notifications`.
- Mastodon API: Added `/api/v1/notifications/:id/dismiss` endpoint.
-- Mastodon API: Add support for filtering replies in public and home timelines
-- Mastodon API: Support for `bot` field in `/api/v1/accounts/update_credentials`
+- Mastodon API: Add support for filtering replies in public and home timelines.
+- Mastodon API: Support for `bot` field in `/api/v1/accounts/update_credentials`.
+- Mastodon API: Support irreversible property for filters.
- Admin API: endpoints for create/update/delete OAuth Apps.
- Admin API: endpoint for status view.
- OTP: Add command to reload emoji packs
@@ -214,7 +217,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: `pleroma.thread_muted` to the Status entity
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload.
-- Mastodon API: Add `pleroma.unread_count` to the Marker entity
- Admin API: Render whole status in grouped reports
- 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.
diff --git a/benchmarks/load_testing/activities.ex b/benchmarks/load_testing/activities.ex
index 074ded457..f5c7bfce8 100644
--- a/benchmarks/load_testing/activities.ex
+++ b/benchmarks/load_testing/activities.ex
@@ -24,6 +24,7 @@ defmodule Pleroma.LoadTesting.Activities do
@visibility ~w(public private direct unlisted)
@types [
:simple,
+ :simple_filtered,
:emoji,
:mentions,
:hell_thread,
@@ -242,6 +243,15 @@ defmodule Pleroma.LoadTesting.Activities do
insert_local_activity(visibility, group, users, "Simple status")
end
+ defp insert_activity(:simple_filtered, visibility, group, users, _opts)
+ when group in @remote_groups do
+ insert_remote_activity(visibility, group, users, "Remote status which must be filtered")
+ end
+
+ defp insert_activity(:simple_filtered, visibility, group, users, _opts) do
+ insert_local_activity(visibility, group, users, "Simple status which must be filtered")
+ end
+
defp insert_activity(:emoji, visibility, group, users, _opts)
when group in @remote_groups do
insert_remote_activity(visibility, group, users, "Remote status with emoji :firefox:")
diff --git a/benchmarks/load_testing/fetcher.ex b/benchmarks/load_testing/fetcher.ex
index 15fd06c3d..dfbd916be 100644
--- a/benchmarks/load_testing/fetcher.ex
+++ b/benchmarks/load_testing/fetcher.ex
@@ -32,10 +32,22 @@ defmodule Pleroma.LoadTesting.Fetcher do
)
end
+ defp create_filter(user) do
+ Pleroma.Filter.create(%Pleroma.Filter{
+ user_id: user.id,
+ phrase: "must be filtered",
+ hide: true
+ })
+ end
+
+ defp delete_filter(filter), do: Repo.delete(filter)
+
defp fetch_timelines(user) do
fetch_home_timeline(user)
+ fetch_home_timeline_with_filter(user)
fetch_direct_timeline(user)
fetch_public_timeline(user)
+ fetch_public_timeline_with_filter(user)
fetch_public_timeline(user, :with_blocks)
fetch_public_timeline(user, :local)
fetch_public_timeline(user, :tag)
@@ -61,7 +73,7 @@ defmodule Pleroma.LoadTesting.Fetcher do
}
end
- defp fetch_home_timeline(user) do
+ defp fetch_home_timeline(user, title_end \\ "") do
opts = opts_for_home_timeline(user)
recipients = [user.ap_id | User.following(user)]
@@ -84,9 +96,11 @@ defmodule Pleroma.LoadTesting.Fetcher do
|> Enum.reverse()
|> List.last()
+ title = "home timeline " <> title_end
+
Benchee.run(
%{
- "home timeline" => fn opts -> ActivityPub.fetch_activities(recipients, opts) end
+ title => fn opts -> ActivityPub.fetch_activities(recipients, opts) end
},
inputs: %{
"1 page" => opts,
@@ -108,6 +122,14 @@ defmodule Pleroma.LoadTesting.Fetcher do
)
end
+ defp fetch_home_timeline_with_filter(user) do
+ {:ok, filter} = create_filter(user)
+
+ fetch_home_timeline(user, "with filters")
+
+ delete_filter(filter)
+ end
+
defp opts_for_direct_timeline(user) do
%{
visibility: "direct",
@@ -210,6 +232,14 @@ defmodule Pleroma.LoadTesting.Fetcher do
fetch_public_timeline(opts, "public timeline")
end
+ defp fetch_public_timeline_with_filter(user) do
+ {:ok, filter} = create_filter(user)
+ opts = opts_for_public_timeline(user)
+
+ fetch_public_timeline(opts, "public timeline with filters")
+ delete_filter(filter)
+ end
+
defp fetch_public_timeline(user, :local) do
opts = opts_for_public_timeline(user, :local)
diff --git a/config/config.exs b/config/config.exs
index fd355867c..458d3a99a 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -97,6 +97,7 @@ config :pleroma, :uri_schemes,
"dat",
"dweb",
"gopher",
+ "hyper",
"ipfs",
"ipns",
"irc",
@@ -188,6 +189,7 @@ config :pleroma, :instance,
background_image: "/images/city.jpg",
instance_thumbnail: "/instance/thumbnail.jpeg",
limit: 5_000,
+ description_limit: 5_000,
chat_limit: 5_000,
remote_limit: 100_000,
upload_limit: 16_000_000,
diff --git a/config/description.exs b/config/description.exs
index 370af80a6..650610fbe 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -498,6 +498,7 @@ config :pleroma, :config_description, [
"dat",
"dweb",
"gopher",
+ "hyper",
"ipfs",
"ipns",
"irc",
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index 72b5984ae..d2455d5d7 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -220,6 +220,8 @@ Has theses additional parameters (which are the same as in Pleroma-API):
`GET /api/v1/instance` has additional fields
- `max_toot_chars`: The maximum characters per post
+- `chat_limit`: The maximum characters per chat message
+- `description_limit`: The maximum characters per image description
- `poll_limits`: The limits of polls
- `upload_limit`: The maximum upload file size
- `avatar_upload_limit`: The same for avatars
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 6759d5e93..6b640cebc 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -18,6 +18,7 @@ To add configuration to your config file, you can copy it from the base config.
* `notify_email`: Email used for notifications.
* `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance``.
* `limit`: Posts character limit (CW/Subject included in the counter).
+* `discription_limit`: The character limit for image descriptions.
* `chat_limit`: Character limit of the instance chat messages.
* `remote_limit`: Hard character limit beyond which remote posts will be dropped.
* `upload_limit`: File size limit of uploads (except for avatar, background, banner).
diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex
index 4d61b3650..5d6df9530 100644
--- a/lib/pleroma/filter.ex
+++ b/lib/pleroma/filter.ex
@@ -34,10 +34,18 @@ defmodule Pleroma.Filter do
Repo.one(query)
end
- def get_filters(%User{id: user_id} = _user) do
+ def get_active(query) do
+ from(f in query, where: is_nil(f.expires_at) or f.expires_at > ^NaiveDateTime.utc_now())
+ end
+
+ def get_irreversible(query) do
+ from(f in query, where: f.hide)
+ end
+
+ def get_filters(query \\ __MODULE__, %User{id: user_id}) do
query =
from(
- f in Pleroma.Filter,
+ f in query,
where: f.user_id == ^user_id,
order_by: [desc: :id]
)
@@ -95,4 +103,34 @@ defmodule Pleroma.Filter do
|> validate_required([:phrase, :context])
|> Repo.update()
end
+
+ def compose_regex(user_or_filters, format \\ :postgres)
+
+ def compose_regex(%User{} = user, format) do
+ __MODULE__
+ |> get_active()
+ |> get_irreversible()
+ |> get_filters(user)
+ |> compose_regex(format)
+ end
+
+ def compose_regex([_ | _] = filters, format) do
+ phrases =
+ filters
+ |> Enum.map(& &1.phrase)
+ |> Enum.join("|")
+
+ case format do
+ :postgres ->
+ "\\y(#{phrases})\\y"
+
+ :re ->
+ ~r/\b#{phrases}\b/i
+
+ _ ->
+ nil
+ end
+ end
+
+ def compose_regex(_, _), do: nil
end
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 2ef1a80c5..fcb2144ae 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -130,6 +130,7 @@ defmodule Pleroma.Notification do
|> preload([n, a, o], activity: {a, object: o})
|> exclude_notification_muted(user, exclude_notification_muted_opts)
|> exclude_blocked(user, exclude_blocked_opts)
+ |> exclude_filtered(user)
|> exclude_visibility(opts)
end
@@ -158,6 +159,20 @@ defmodule Pleroma.Notification do
|> where([n, a, o, tm], is_nil(tm.user_id))
end
+ defp exclude_filtered(query, user) do
+ case Pleroma.Filter.compose_regex(user) do
+ nil ->
+ query
+
+ regex ->
+ from([_n, a, o] in query,
+ where:
+ fragment("not(?->>'content' ~* ?)", o.data, ^regex) or
+ fragment("?->>'actor' = ?", o.data, ^user.ap_id)
+ )
+ end
+ end
+
@valid_visibilities ~w[direct unlisted public private]
defp exclude_visibility(query, %{exclude_visibilities: visibility})
@@ -337,6 +352,7 @@ defmodule Pleroma.Notification do
end
end
+ @spec create_notifications(Activity.t(), keyword()) :: {:ok, [Notification.t()] | []}
def create_notifications(activity, options \\ [])
def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity, options) do
@@ -555,7 +571,8 @@ defmodule Pleroma.Notification do
:follows,
:non_followers,
:non_follows,
- :recently_followed
+ :recently_followed,
+ :filtered
]
|> Enum.find(&skip?(&1, activity, user))
end
@@ -624,6 +641,26 @@ defmodule Pleroma.Notification do
end)
end
+ def skip?(:filtered, %{data: %{"type" => type}}, _) when type in ["Follow", "Move"], do: false
+
+ def skip?(:filtered, activity, user) do
+ object = Object.normalize(activity)
+
+ cond do
+ is_nil(object) ->
+ false
+
+ object.data["actor"] == user.ap_id ->
+ false
+
+ not is_nil(regex = Pleroma.Filter.compose_regex(user, :re)) ->
+ Regex.match?(regex, object.data["content"])
+
+ true ->
+ false
+ end
+ end
+
def skip?(_, _, _), do: false
def for_user_and_activity(user, activity) do
diff --git a/lib/pleroma/plugs/static_fe_plug.ex b/lib/pleroma/plugs/static_fe_plug.ex
index 156e6788e..143665c71 100644
--- a/lib/pleroma/plugs/static_fe_plug.ex
+++ b/lib/pleroma/plugs/static_fe_plug.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do
def init(options), do: options
def call(conn, _) do
- if enabled?() and accepts_html?(conn) do
+ if enabled?() and requires_html?(conn) do
conn
|> StaticFEController.call(:show)
|> halt()
@@ -20,10 +20,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do
defp enabled?, do: Pleroma.Config.get([:static_fe, :enabled], false)
- defp accepts_html?(conn) do
- case get_req_header(conn, "accept") do
- [accept | _] -> String.contains?(accept, "text/html")
- _ -> false
- end
+ defp requires_html?(conn) do
+ Phoenix.Controller.get_format(conn) == "html"
end
end
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
index 797555bff..0fa6b89dc 100644
--- a/lib/pleroma/upload.ex
+++ b/lib/pleroma/upload.ex
@@ -63,6 +63,10 @@ defmodule Pleroma.Upload do
with {:ok, upload} <- prepare_upload(upload, opts),
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"},
{:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload),
+ description = Map.get(opts, :description) || upload.name,
+ {_, true} <-
+ {:description_limit,
+ String.length(description) <= Pleroma.Config.get([:instance, :description_limit])},
{:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do
{:ok,
%{
@@ -75,9 +79,12 @@ defmodule Pleroma.Upload do
"href" => url_from_spec(upload, opts.base_url, url_spec)
}
],
- "name" => Map.get(opts, :description) || upload.name
+ "name" => description
}}
else
+ {:description_limit, _} ->
+ {:error, :description_too_long}
+
{:error, error} ->
Logger.error(
"#{__MODULE__} store (using #{inspect(opts.uploader)}) failed: #{inspect(error)}"
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 94117202c..8abbef487 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Constants
alias Pleroma.Conversation
alias Pleroma.Conversation.Participation
+ alias Pleroma.Filter
alias Pleroma.Maps
alias Pleroma.Notification
alias Pleroma.Object
@@ -446,6 +447,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> maybe_set_thread_muted_field(opts)
|> restrict_blocked(opts)
|> restrict_recipients(recipients, opts[:user])
+ |> restrict_filtered(opts)
|> where(
[activity],
fragment(
@@ -961,6 +963,26 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_instance(query, _), do: query
+ defp restrict_filtered(query, %{user: %User{} = user}) do
+ case Filter.compose_regex(user) do
+ nil ->
+ query
+
+ regex ->
+ from([activity, object] in query,
+ where:
+ fragment("not(?->>'content' ~* ?)", object.data, ^regex) or
+ activity.actor == ^user.ap_id
+ )
+ end
+ end
+
+ defp restrict_filtered(query, %{blocking_user: %User{} = user}) do
+ restrict_filtered(query, %{user: user})
+ end
+
+ defp restrict_filtered(query, _), do: query
+
defp exclude_poll_votes(query, %{include_poll_votes: true}), do: query
defp exclude_poll_votes(query, _) do
@@ -1091,6 +1113,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_favorited_by(opts)
|> restrict_blocked(restrict_blocked_opts)
|> restrict_muted(restrict_muted_opts)
+ |> restrict_filtered(opts)
|> restrict_media(opts)
|> restrict_visibility(opts)
|> restrict_thread_visibility(opts, config)
@@ -1099,6 +1122,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_muted_reblogs(restrict_muted_reblogs_opts)
|> restrict_instance(opts)
|> restrict_announce_object_actor(opts)
+ |> restrict_filtered(opts)
|> Activity.restrict_deactivated_users()
|> exclude_poll_votes(opts)
|> exclude_chat_messages(opts)
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index bc6fc4bd8..117e930b3 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -233,18 +233,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
is_map(url) && is_binary(url["href"]) -> url["href"]
is_binary(data["url"]) -> data["url"]
is_binary(data["href"]) -> data["href"]
+ true -> nil
end
- attachment_url =
- %{"href" => href}
- |> Maps.put_if_present("mediaType", media_type)
- |> Maps.put_if_present("type", Map.get(url || %{}, "type"))
+ if href do
+ attachment_url =
+ %{"href" => href}
+ |> Maps.put_if_present("mediaType", media_type)
+ |> Maps.put_if_present("type", Map.get(url || %{}, "type"))
- %{"url" => [attachment_url]}
- |> Maps.put_if_present("mediaType", media_type)
- |> Maps.put_if_present("type", data["type"])
- |> Maps.put_if_present("name", data["name"])
+ %{"url" => [attachment_url]}
+ |> Maps.put_if_present("mediaType", media_type)
+ |> Maps.put_if_present("type", data["type"])
+ |> Maps.put_if_present("name", data["name"])
+ else
+ nil
+ end
end)
+ |> Enum.filter(& &1)
Map.put(object, "attachment", attachments)
end
@@ -263,12 +269,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_url(%{"type" => object_type, "url" => url} = object)
when object_type in ["Video", "Audio"] and is_list(url) do
- first_element = Enum.at(url, 0)
+ attachment =
+ Enum.find(url, fn x ->
+ media_type = x["mediaType"] || x["mimeType"] || ""
+
+ is_map(x) and String.starts_with?(media_type, ["audio/", "video/"])
+ end)
- link_element = Enum.find(url, fn x -> is_map(x) and x["mimeType"] == "text/html" end)
+ link_element =
+ Enum.find(url, fn x -> is_map(x) and (x["mediaType"] || x["mimeType"]) == "text/html" end)
object
- |> Map.put("attachment", [first_element])
+ |> Map.put("attachment", [attachment])
|> Map.put("url", link_element["href"])
end
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
index 89e48fba5..5deb0d7ed 100644
--- a/lib/pleroma/web/mastodon_api/views/instance_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -34,6 +34,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
background_upload_limit: Keyword.get(instance, :background_upload_limit),
banner_upload_limit: Keyword.get(instance, :banner_upload_limit),
background_image: Keyword.get(instance, :background_image),
+ chat_limit: Keyword.get(instance, :chat_limit),
+ description_limit: Keyword.get(instance, :description_limit),
pleroma: %{
metadata: %{
account_activation_required: Keyword.get(instance, :account_activation_required),
diff --git a/test/filter_test.exs b/test/filter_test.exs
index 63a30c736..0a5c4426a 100644
--- a/test/filter_test.exs
+++ b/test/filter_test.exs
@@ -3,37 +3,39 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.FilterTest do
- alias Pleroma.Repo
use Pleroma.DataCase
import Pleroma.Factory
+ alias Pleroma.Filter
+ alias Pleroma.Repo
+
describe "creating filters" do
test "creating one filter" do
user = insert(:user)
- query = %Pleroma.Filter{
+ query = %Filter{
user_id: user.id,
filter_id: 42,
phrase: "knights",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query)
- result = Pleroma.Filter.get(filter.filter_id, user)
+ {:ok, %Filter{} = filter} = Filter.create(query)
+ result = Filter.get(filter.filter_id, user)
assert query.phrase == result.phrase
end
test "creating one filter without a pre-defined filter_id" do
user = insert(:user)
- query = %Pleroma.Filter{
+ query = %Filter{
user_id: user.id,
phrase: "knights",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query)
+ {:ok, %Filter{} = filter} = Filter.create(query)
# Should start at 1
assert filter.filter_id == 1
end
@@ -41,23 +43,23 @@ defmodule Pleroma.FilterTest do
test "creating additional filters uses previous highest filter_id + 1" do
user = insert(:user)
- query_one = %Pleroma.Filter{
+ query_one = %Filter{
user_id: user.id,
filter_id: 42,
phrase: "knights",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one)
+ {:ok, %Filter{} = filter_one} = Filter.create(query_one)
- query_two = %Pleroma.Filter{
+ query_two = %Filter{
user_id: user.id,
# No filter_id
phrase: "who",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two)
+ {:ok, %Filter{} = filter_two} = Filter.create(query_two)
assert filter_two.filter_id == filter_one.filter_id + 1
end
@@ -65,29 +67,29 @@ defmodule Pleroma.FilterTest do
user_one = insert(:user)
user_two = insert(:user)
- query_one = %Pleroma.Filter{
+ query_one = %Filter{
user_id: user_one.id,
phrase: "knights",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one)
+ {:ok, %Filter{} = filter_one} = Filter.create(query_one)
- query_two = %Pleroma.Filter{
+ query_two = %Filter{
user_id: user_two.id,
phrase: "who",
context: ["home"]
}
- {:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two)
+ {:ok, %Filter{} = filter_two} = Filter.create(query_two)
assert filter_one.filter_id == 1
assert filter_two.filter_id == 1
- result_one = Pleroma.Filter.get(filter_one.filter_id, user_one)
+ result_one = Filter.get(filter_one.filter_id, user_one)
assert result_one.phrase == filter_one.phrase
- result_two = Pleroma.Filter.get(filter_two.filter_id, user_two)
+ result_two = Filter.get(filter_two.filter_id, user_two)
assert result_two.phrase == filter_two.phrase
end
end
@@ -95,38 +97,38 @@ defmodule Pleroma.FilterTest do
test "deleting a filter" do
user = insert(:user)
- query = %Pleroma.Filter{
+ query = %Filter{
user_id: user.id,
filter_id: 0,
phrase: "knights",
context: ["home"]
}
- {:ok, _filter} = Pleroma.Filter.create(query)
- {:ok, filter} = Pleroma.Filter.delete(query)
- assert is_nil(Repo.get(Pleroma.Filter, filter.filter_id))
+ {:ok, _filter} = Filter.create(query)
+ {:ok, filter} = Filter.delete(query)
+ assert is_nil(Repo.get(Filter, filter.filter_id))
end
test "getting all filters by an user" do
user = insert(:user)
- query_one = %Pleroma.Filter{
+ query_one = %Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
context: ["home"]
}
- query_two = %Pleroma.Filter{
+ query_two = %Filter{
user_id: user.id,
filter_id: 2,
phrase: "who",
context: ["home"]
}
- {:ok, filter_one} = Pleroma.Filter.create(query_one)
- {:ok, filter_two} = Pleroma.Filter.create(query_two)
- filters = Pleroma.Filter.get_filters(user)
+ {:ok, filter_one} = Filter.create(query_one)
+ {:ok, filter_two} = Filter.create(query_two)
+ filters = Filter.get_filters(user)
assert filter_one in filters
assert filter_two in filters
end
@@ -134,7 +136,7 @@ defmodule Pleroma.FilterTest do
test "updating a filter" do
user = insert(:user)
- query_one = %Pleroma.Filter{
+ query_one = %Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
@@ -146,8 +148,9 @@ defmodule Pleroma.FilterTest do
context: ["home", "timeline"]
}
- {:ok, filter_one} = Pleroma.Filter.create(query_one)
- {:ok, filter_two} = Pleroma.Filter.update(filter_one, changes)
+ {:ok, filter_one} = Filter.create(query_one)
+ {:ok, filter_two} = Filter.update(filter_one, changes)
+
assert filter_one != filter_two
assert filter_two.phrase == changes.phrase
assert filter_two.context == changes.context
diff --git a/test/fixtures/tesla_mock/framatube.org-video.json b/test/fixtures/tesla_mock/framatube.org-video.json
new file mode 100644
index 000000000..3d53f0c97
--- /dev/null
+++ b/test/fixtures/tesla_mock/framatube.org-video.json
@@ -0,0 +1 @@
+{"type":"Video","id":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206","name":"Déframasoftisons Internet [Framasoft]","duration":"PT3622S","uuid":"6050732a-8a7a-43d4-a6cd-809525a1d206","tag":[{"type":"Hashtag","name":"déframasoftisons"},{"type":"Hashtag","name":"EPN23"},{"type":"Hashtag","name":"framaconf"},{"type":"Hashtag","name":"Framasoft"},{"type":"Hashtag","name":"pyg"}],"category":{"identifier":"15","name":"Science & Technology"},"views":122,"sensitive":false,"waitTranscoding":false,"state":1,"commentsEnabled":true,"downloadEnabled":true,"published":"2020-05-24T18:34:31.569Z","originallyPublishedAt":"2019-11-30T23:00:00.000Z","updated":"2020-07-05T09:01:01.720Z","mediaType":"text/markdown","content":"Après avoir mené avec un certain succès la campagne « Dégooglisons Internet » en 2014, l’association Framasoft annonce fin 2019 arrêter progressivement un certain nombre de ses services alternatifs aux GAFAM. Pourquoi ?\r\n\r\nTranscription par @april...","support":null,"subtitleLanguage":[],"icon":{"type":"Image","url":"https://framatube.org/static/thumbnails/6050732a-8a7a-43d4-a6cd-809525a1d206.jpg","mediaType":"image/jpeg","width":223,"height":122},"url":[{"type":"Link","mediaType":"text/html","href":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4","height":1080,"size":1157359410,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309939","height":1080,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.torrent","height":1080},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080.torrent&xt=urn:btih:381c9429900552e23a4eb506318f1fa01e4d63a8&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4&ws=https%3A%2F%2Fpeertube.iselfhost.com%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4&ws=https%3A%2F%2Ftube.privacytools.io%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4&ws=https%3A%2F%2Fpeertube.live%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4","height":1080},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-480.mp4","height":480,"size":250095131,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309941","height":480,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-480.torrent","height":480},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480.torrent&xt=urn:btih:a181dcbb5368ab5c31cc9ff07634becb72c344ee&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480.mp4&ws=https%3A%2F%2Fpeertube.iselfhost.com%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480.mp4&ws=https%3A%2F%2Ftube.privacytools.io%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480.mp4&ws=https%3A%2F%2Fpeertube.live%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480.mp4","height":480},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-360.mp4","height":360,"size":171357733,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309942","height":360,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-360.torrent","height":360},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360.torrent&xt=urn:btih:aedfa9479ea04a175eee0b0bd0bda64076308746&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360.mp4&ws=https%3A%2F%2Fpeertube.iselfhost.com%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360.mp4&ws=https%3A%2F%2Ftube.privacytools.io%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360.mp4&ws=https%3A%2F%2Fpeertube.live%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360.mp4","height":360},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-720.mp4","height":720,"size":497100839,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309943","height":720,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-720.torrent","height":720},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720.torrent&xt=urn:btih:71971668f82a3b24ac71bc3a982848dd8dc5a5f5&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720.mp4&ws=https%3A%2F%2Fpeertube.iselfhost.com%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720.mp4&ws=https%3A%2F%2Ftube.privacytools.io%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720.mp4&ws=https%3A%2F%2Fpeertube.live%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720.mp4","height":720},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-240.mp4","height":240,"size":113038439,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309944","height":240,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-240.torrent","height":240},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240.torrent&xt=urn:btih:c42aa6c95efb28d9f114ebd98537f7b00fa72246&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240.mp4&ws=https%3A%2F%2Fpeertube.iselfhost.com%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240.mp4&ws=https%3A%2F%2Ftube.privacytools.io%2Fstatic%2Fredundancy%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240.mp4","height":240},{"type":"Link","mediaType":"application/x-mpegURL","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/master.m3u8","tag":[{"type":"Infohash","name":"f7428214539626e062f300f2ca4cf9154575144e"},{"type":"Infohash","name":"46e236dffb1ea6b9123a5396cbe88e97dd94cc6c"},{"type":"Infohash","name":"11f1045830b5d786c788f2594d19f128764e7d87"},{"type":"Infohash","name":"4327ad3e0d84de100130a27e9ab6fe40c4284f0e"},{"type":"Infohash","name":"41e2eee8e7b23a63c23a77c40a46de11492a4831"},{"type":"Link","name":"sha256","mediaType":"application/json","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/segments-sha256.json"},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/6050732a-8a7a-43d4-a6cd-809525a1d206-1080-fragmented.mp4","height":1080,"size":1156777472,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309940","height":1080,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-1080-hls.torrent","height":1080},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080-hls.torrent&xt=urn:btih:0204d780ebfab0d5d9d3476a038e812ad792deeb&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fstreaming-playlists%2Fhls%2F6050732a-8a7a-43d4-a6cd-809525a1d206%2F6050732a-8a7a-43d4-a6cd-809525a1d206-1080-fragmented.mp4","height":1080},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/6050732a-8a7a-43d4-a6cd-809525a1d206-480-fragmented.mp4","height":480,"size":249562889,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309945","height":480,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-480-hls.torrent","height":480},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480-hls.torrent&xt=urn:btih:5d14f38ded29de629668fe1cfc61a75f4cce2628&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fstreaming-playlists%2Fhls%2F6050732a-8a7a-43d4-a6cd-809525a1d206%2F6050732a-8a7a-43d4-a6cd-809525a1d206-480-fragmented.mp4","height":480},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/6050732a-8a7a-43d4-a6cd-809525a1d206-360-fragmented.mp4","height":360,"size":170836415,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309946","height":360,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-360-hls.torrent","height":360},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360-hls.torrent&xt=urn:btih:30125488789080ad405ebcee6c214945f31b8f30&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fstreaming-playlists%2Fhls%2F6050732a-8a7a-43d4-a6cd-809525a1d206%2F6050732a-8a7a-43d4-a6cd-809525a1d206-360-fragmented.mp4","height":360},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/6050732a-8a7a-43d4-a6cd-809525a1d206-720-fragmented.mp4","height":720,"size":496533741,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309947","height":720,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-720-hls.torrent","height":720},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720-hls.torrent&xt=urn:btih:8ed1e8bccde709901c26e315fc8f53bfd26d1ba6&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fstreaming-playlists%2Fhls%2F6050732a-8a7a-43d4-a6cd-809525a1d206%2F6050732a-8a7a-43d4-a6cd-809525a1d206-720-fragmented.mp4","height":720},{"type":"Link","mediaType":"video/mp4","href":"https://framatube.org/static/streaming-playlists/hls/6050732a-8a7a-43d4-a6cd-809525a1d206/6050732a-8a7a-43d4-a6cd-809525a1d206-240-fragmented.mp4","height":240,"size":112529249,"fps":25},{"type":"Link","rel":["metadata","video/mp4"],"mediaType":"application/json","href":"https://framatube.org/api/v1/videos/6050732a-8a7a-43d4-a6cd-809525a1d206/metadata/1309948","height":240,"fps":25},{"type":"Link","mediaType":"application/x-bittorrent","href":"https://framatube.org/static/torrents/6050732a-8a7a-43d4-a6cd-809525a1d206-240-hls.torrent","height":240},{"type":"Link","mediaType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240-hls.torrent&xt=urn:btih:8b452bf4e70b9078d4e74ca8b5523cc9dc70d10a&dn=D%C3%A9framasoftisons+Internet+%5BFramasoft%5D&tr=wss%3A%2F%2Fframatube.org%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fstreaming-playlists%2Fhls%2F6050732a-8a7a-43d4-a6cd-809525a1d206%2F6050732a-8a7a-43d4-a6cd-809525a1d206-240-fragmented.mp4","height":240}]}],"likes":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206/likes","dislikes":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206/dislikes","shares":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206/announces","comments":"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206/comments","attributedTo":[{"type":"Person","id":"https://framatube.org/accounts/framasoft"},{"type":"Group","id":"https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8"}],"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://framatube.org/accounts/framasoft/followers"],"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"RsaSignature2017":"https://w3id.org/security#RsaSignature2017"},{"pt":"https://joinpeertube.org/ns#","sc":"http://schema.org#","Hashtag":"as:Hashtag","uuid":"sc:identifier","category":"sc:category","licence":"sc:license","subtitleLanguage":"sc:subtitleLanguage","sensitive":"as:sensitive","language":"sc:inLanguage","Infohash":"pt:Infohash","Playlist":"pt:Playlist","PlaylistElement":"pt:PlaylistElement","originallyPublishedAt":"sc:datePublished","views":{"@type":"sc:Number","@id":"pt:views"},"state":{"@type":"sc:Number","@id":"pt:state"},"size":{"@type":"sc:Number","@id":"pt:size"},"fps":{"@type":"sc:Number","@id":"pt:fps"},"startTimestamp":{"@type":"sc:Number","@id":"pt:startTimestamp"},"stopTimestamp":{"@type":"sc:Number","@id":"pt:stopTimestamp"},"position":{"@type":"sc:Number","@id":"pt:position"},"commentsEnabled":{"@type":"sc:Boolean","@id":"pt:commentsEnabled"},"downloadEnabled":{"@type":"sc:Boolean","@id":"pt:downloadEnabled"},"waitTranscoding":{"@type":"sc:Boolean","@id":"pt:waitTranscoding"},"support":{"@type":"sc:Text","@id":"pt:support"},"likes":{"@id":"as:likes","@type":"@id"},"dislikes":{"@id":"as:dislikes","@type":"@id"},"playlists":{"@id":"pt:playlists","@type":"@id"},"shares":{"@id":"as:shares","@type":"@id"},"comments":{"@id":"as:comments","@type":"@id"}}]} \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json b/test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json
new file mode 100644
index 000000000..1c3f779b3
--- /dev/null
+++ b/test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json
@@ -0,0 +1 @@
+{"type":"Person","id":"https://framatube.org/accounts/framasoft","following":"https://framatube.org/accounts/framasoft/following","followers":"https://framatube.org/accounts/framasoft/followers","playlists":"https://framatube.org/accounts/framasoft/playlists","inbox":"https://framatube.org/accounts/framasoft/inbox","outbox":"https://framatube.org/accounts/framasoft/outbox","preferredUsername":"framasoft","url":"https://framatube.org/accounts/framasoft","name":"Framasoft","endpoints":{"sharedInbox":"https://framatube.org/inbox"},"publicKey":{"id":"https://framatube.org/accounts/framasoft#main-key","owner":"https://framatube.org/accounts/framasoft","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuRh3frgIg866D0y0FThp\nSUkJImMcHGkUvpYQYv2iUgarZZtEbwT8PfQf0bJazy+cP8KqQmMDf5PBhT7dfdny\nf/GKGMw9Olc+QISeKDj3sqZ3Csrm4KV4avMGCfth6eSU7LozojeSGCXdUFz/8UgE\nfhV4mJjEX/FbwRYoKlagv5rY9mkX5XomzZU+z9j6ZVXyofwOwJvmI1hq0SYDv2bc\neB/RgIh/H0nyMtF8o+0CT42FNEET9j9m1BKOBtPzwZHmitKRkEmui5cK256s1laB\nT61KHpcD9gQKkQ+I3sFEzCBUJYfVo6fUe+GehBZuAfq4qDhd15SfE4K9veDscDFI\nTwIDAQAB\n-----END PUBLIC KEY-----"},"icon":{"type":"Image","mediaType":"image/png","url":"https://framatube.org/lazy-static/avatars/f73876f5-1d45-4f8a-942a-d3d5d5ac5dc1.png"},"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"RsaSignature2017":"https://w3id.org/security#RsaSignature2017","pt":"https://joinpeertube.org/ns#","sc":"http://schema.org#","Hashtag":"as:Hashtag","uuid":"sc:identifier","category":"sc:category","licence":"sc:license","subtitleLanguage":"sc:subtitleLanguage","sensitive":"as:sensitive","language":"sc:inLanguage","expires":"sc:expires","CacheFile":"pt:CacheFile","Infohash":"pt:Infohash","originallyPublishedAt":"sc:datePublished","views":{"@type":"sc:Number","@id":"pt:views"},"state":{"@type":"sc:Number","@id":"pt:state"},"size":{"@type":"sc:Number","@id":"pt:size"},"fps":{"@type":"sc:Number","@id":"pt:fps"},"startTimestamp":{"@type":"sc:Number","@id":"pt:startTimestamp"},"stopTimestamp":{"@type":"sc:Number","@id":"pt:stopTimestamp"},"position":{"@type":"sc:Number","@id":"pt:position"},"commentsEnabled":{"@type":"sc:Boolean","@id":"pt:commentsEnabled"},"downloadEnabled":{"@type":"sc:Boolean","@id":"pt:downloadEnabled"},"waitTranscoding":{"@type":"sc:Boolean","@id":"pt:waitTranscoding"},"support":{"@type":"sc:Text","@id":"pt:support"}},{"likes":{"@id":"as:likes","@type":"@id"},"dislikes":{"@id":"as:dislikes","@type":"@id"},"playlists":{"@id":"pt:playlists","@type":"@id"},"shares":{"@id":"as:shares","@type":"@id"},"comments":{"@id":"as:comments","@type":"@id"}}],"summary":null} \ No newline at end of file
diff --git a/test/notification_test.exs b/test/notification_test.exs
index 6add3f7eb..13e82ab2a 100644
--- a/test/notification_test.exs
+++ b/test/notification_test.exs
@@ -324,6 +324,44 @@ defmodule Pleroma.NotificationTest do
{:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
refute Notification.create_notification(status, user)
end
+
+ test "it doesn't create notifications if content matches with an irreversible filter" do
+ user = insert(:user)
+ subscriber = insert(:user)
+
+ User.subscribe(subscriber, user)
+ insert(:filter, user: subscriber, phrase: "cofe", hide: true)
+
+ {:ok, status} = CommonAPI.post(user, %{status: "got cofe?"})
+
+ assert {:ok, []} == Notification.create_notifications(status)
+ end
+
+ test "it creates notifications if content matches with a not irreversible filter" do
+ user = insert(:user)
+ subscriber = insert(:user)
+
+ User.subscribe(subscriber, user)
+ insert(:filter, user: subscriber, phrase: "cofe", hide: false)
+
+ {:ok, status} = CommonAPI.post(user, %{status: "got cofe?"})
+ {:ok, [notification]} = Notification.create_notifications(status)
+
+ assert notification
+ end
+
+ test "it creates notifications when someone likes user's status with a filtered word" do
+ user = insert(:user)
+ other_user = insert(:user)
+ insert(:filter, user: user, phrase: "tesla", hide: true)
+
+ {:ok, activity_one} = CommonAPI.post(user, %{status: "wow tesla"})
+ {:ok, activity_two} = CommonAPI.favorite(other_user, activity_one.id)
+
+ {:ok, [notification]} = Notification.create_notifications(activity_two)
+
+ assert notification
+ end
end
describe "follow / follow_request notifications" do
@@ -990,8 +1028,13 @@ defmodule Pleroma.NotificationTest do
end
describe "for_user" do
- test "it returns notifications for muted user without notifications" do
+ setup do
user = insert(:user)
+
+ {:ok, %{user: user}}
+ end
+
+ test "it returns notifications for muted user without notifications", %{user: user} do
muted = insert(:user)
{:ok, _user_relationships} = User.mute(user, muted, false)
@@ -1002,8 +1045,7 @@ defmodule Pleroma.NotificationTest do
assert notification.activity.object
end
- test "it doesn't return notifications for muted user with notifications" do
- user = insert(:user)
+ test "it doesn't return notifications for muted user with notifications", %{user: user} do
muted = insert(:user)
{:ok, _user_relationships} = User.mute(user, muted)
@@ -1012,8 +1054,7 @@ defmodule Pleroma.NotificationTest do
assert Notification.for_user(user) == []
end
- test "it doesn't return notifications for blocked user" do
- user = insert(:user)
+ test "it doesn't return notifications for blocked user", %{user: user} do
blocked = insert(:user)
{:ok, _user_relationship} = User.block(user, blocked)
@@ -1022,8 +1063,7 @@ defmodule Pleroma.NotificationTest do
assert Notification.for_user(user) == []
end
- test "it doesn't return notifications for domain-blocked non-followed user" do
- user = insert(:user)
+ test "it doesn't return notifications for domain-blocked non-followed user", %{user: user} do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
@@ -1044,8 +1084,7 @@ defmodule Pleroma.NotificationTest do
assert length(Notification.for_user(user)) == 1
end
- test "it doesn't return notifications for muted thread" do
- user = insert(:user)
+ test "it doesn't return notifications for muted thread", %{user: user} do
another_user = insert(:user)
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
@@ -1054,8 +1093,7 @@ defmodule Pleroma.NotificationTest do
assert Notification.for_user(user) == []
end
- test "it returns notifications from a muted user when with_muted is set" do
- user = insert(:user)
+ test "it returns notifications from a muted user when with_muted is set", %{user: user} do
muted = insert(:user)
{:ok, _user_relationships} = User.mute(user, muted)
@@ -1064,8 +1102,9 @@ defmodule Pleroma.NotificationTest do
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
- test "it doesn't return notifications from a blocked user when with_muted is set" do
- user = insert(:user)
+ test "it doesn't return notifications from a blocked user when with_muted is set", %{
+ user: user
+ } do
blocked = insert(:user)
{:ok, _user_relationship} = User.block(user, blocked)
@@ -1075,8 +1114,8 @@ defmodule Pleroma.NotificationTest do
end
test "when with_muted is set, " <>
- "it doesn't return notifications from a domain-blocked non-followed user" do
- user = insert(:user)
+ "it doesn't return notifications from a domain-blocked non-followed user",
+ %{user: user} do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
@@ -1085,8 +1124,7 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
end
- test "it returns notifications from muted threads when with_muted is set" do
- user = insert(:user)
+ test "it returns notifications from muted threads when with_muted is set", %{user: user} do
another_user = insert(:user)
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
@@ -1094,5 +1132,33 @@ defmodule Pleroma.NotificationTest do
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
+
+ test "it doesn't return notifications about mentions with filtered word", %{user: user} do
+ insert(:filter, user: user, phrase: "cofe", hide: true)
+ another_user = insert(:user)
+
+ {:ok, _activity} = CommonAPI.post(another_user, %{status: "@#{user.nickname} got cofe?"})
+
+ assert Enum.empty?(Notification.for_user(user))
+ end
+
+ test "it returns notifications about mentions with not hidden filtered word", %{user: user} do
+ insert(:filter, user: user, phrase: "test", hide: false)
+ another_user = insert(:user)
+
+ {:ok, _} = CommonAPI.post(another_user, %{status: "@#{user.nickname} test"})
+
+ assert length(Notification.for_user(user)) == 1
+ end
+
+ test "it returns notifications about favorites with filtered word", %{user: user} do
+ insert(:filter, user: user, phrase: "cofe", hide: true)
+ another_user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "Give me my cofe!"})
+ {:ok, _} = CommonAPI.favorite(another_user, activity.id)
+
+ assert length(Notification.for_user(user)) == 1
+ end
end
end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index af580021c..635d83650 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -428,4 +428,12 @@ defmodule Pleroma.Factory do
user: build(:user)
}
end
+
+ def filter_factory do
+ %Pleroma.Filter{
+ user: build(:user),
+ filter_id: sequence(:filter_id, & &1),
+ phrase: "cofe"
+ }
+ end
end
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index 3d5128835..da04ac6f1 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -308,6 +308,22 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://framatube.org/accounts/framasoft", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json")
+ }}
+ end
+
+ def get("https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/framatube.org-video.json")
+ }}
+ end
+
def get("https://peertube.social/accounts/craigmaloney", _, _, _) do
{:ok,
%Tesla.Env{
diff --git a/test/upload_test.exs b/test/upload_test.exs
index 2abf0edec..b06b54487 100644
--- a/test/upload_test.exs
+++ b/test/upload_test.exs
@@ -107,6 +107,19 @@ defmodule Pleroma.UploadTest do
describe "Storing a file with the Local uploader" do
setup [:ensure_local_uploader]
+ test "does not allow descriptions longer than the post limit" do
+ clear_config([:instance, :description_limit], 2)
+ File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image_tmp.jpg"),
+ filename: "image.jpg"
+ }
+
+ {:error, :description_too_long} = Upload.store(file, description: "123")
+ end
+
test "returns a media url" do
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 575e0c5db..17e12a1a7 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -507,6 +507,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities = ActivityPub.fetch_activities_for_context("2hu", %{blocking_user: user})
assert activities == [activity_two, activity]
end
+
+ test "doesn't return activities with filtered words" do
+ user = insert(:user)
+ user_two = insert(:user)
+ insert(:filter, user: user, phrase: "test", hide: true)
+
+ {:ok, %{id: id1, data: %{"context" => context}}} = CommonAPI.post(user, %{status: "1"})
+
+ {:ok, %{id: id2}} = CommonAPI.post(user_two, %{status: "2", in_reply_to_status_id: id1})
+
+ {:ok, %{id: id3} = user_activity} =
+ CommonAPI.post(user, %{status: "3 test?", in_reply_to_status_id: id2})
+
+ {:ok, %{id: id4} = filtered_activity} =
+ CommonAPI.post(user_two, %{status: "4 test!", in_reply_to_status_id: id3})
+
+ {:ok, _} = CommonAPI.post(user, %{status: "5", in_reply_to_status_id: id4})
+
+ activities =
+ context
+ |> ActivityPub.fetch_activities_for_context(%{user: user})
+ |> Enum.map(& &1.id)
+
+ assert length(activities) == 4
+ assert user_activity.id in activities
+ refute filtered_activity.id in activities
+ end
end
test "doesn't return blocked activities" do
@@ -785,6 +812,75 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert activity == expected_activity
end
+ describe "irreversible filters" do
+ setup do
+ user = insert(:user)
+ user_two = insert(:user)
+
+ insert(:filter, user: user_two, phrase: "cofe", hide: true)
+ insert(:filter, user: user_two, phrase: "ok boomer", hide: true)
+ insert(:filter, user: user_two, phrase: "test", hide: false)
+
+ params = %{
+ type: ["Create", "Announce"],
+ user: user_two
+ }
+
+ {:ok, %{user: user, user_two: user_two, params: params}}
+ end
+
+ test "it returns statuses if they don't contain exact filter words", %{
+ user: user,
+ params: params
+ } do
+ {:ok, _} = CommonAPI.post(user, %{status: "hey"})
+ {:ok, _} = CommonAPI.post(user, %{status: "got cofefe?"})
+ {:ok, _} = CommonAPI.post(user, %{status: "I am not a boomer"})
+ {:ok, _} = CommonAPI.post(user, %{status: "ok boomers"})
+ {:ok, _} = CommonAPI.post(user, %{status: "ccofee is not a word"})
+ {:ok, _} = CommonAPI.post(user, %{status: "this is a test"})
+
+ activities = ActivityPub.fetch_activities([], params)
+
+ assert Enum.count(activities) == 6
+ end
+
+ test "it does not filter user's own statuses", %{user_two: user_two, params: params} do
+ {:ok, _} = CommonAPI.post(user_two, %{status: "Give me some cofe!"})
+ {:ok, _} = CommonAPI.post(user_two, %{status: "ok boomer"})
+
+ activities = ActivityPub.fetch_activities([], params)
+
+ assert Enum.count(activities) == 2
+ end
+
+ test "it excludes statuses with filter words", %{user: user, params: params} do
+ {:ok, _} = CommonAPI.post(user, %{status: "Give me some cofe!"})
+ {:ok, _} = CommonAPI.post(user, %{status: "ok boomer"})
+ {:ok, _} = CommonAPI.post(user, %{status: "is it a cOfE?"})
+ {:ok, _} = CommonAPI.post(user, %{status: "cofe is all I need"})
+ {:ok, _} = CommonAPI.post(user, %{status: "— ok BOOMER\n"})
+
+ activities = ActivityPub.fetch_activities([], params)
+
+ assert Enum.empty?(activities)
+ end
+
+ test "it returns all statuses if user does not have any filters" do
+ another_user = insert(:user)
+ {:ok, _} = CommonAPI.post(another_user, %{status: "got cofe?"})
+ {:ok, _} = CommonAPI.post(another_user, %{status: "test!"})
+
+ activities =
+ ActivityPub.fetch_activities([], %{
+ type: ["Create", "Announce"],
+ user: another_user
+ })
+
+ assert Enum.count(activities) == 2
+ end
+ end
+
describe "public fetch activities" do
test "doesn't retrieve unlisted activities" do
user = insert(:user)
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 6a53fd3f0..01179206c 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -659,22 +659,44 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
)
- attachment = %{
- "type" => "Link",
- "mediaType" => "video/mp4",
- "url" => [
- %{
- "href" =>
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4"
- }
- ]
- }
-
assert object.data["url"] ==
"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
- assert object.data["attachment"] == [attachment]
+ assert object.data["attachment"] == [
+ %{
+ "type" => "Link",
+ "mediaType" => "video/mp4",
+ "url" => [
+ %{
+ "href" =>
+ "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
+ "mediaType" => "video/mp4"
+ }
+ ]
+ }
+ ]
+
+ {:ok, object} =
+ Fetcher.fetch_object_from_id(
+ "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
+ )
+
+ assert object.data["attachment"] == [
+ %{
+ "type" => "Link",
+ "mediaType" => "video/mp4",
+ "url" => [
+ %{
+ "href" =>
+ "https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4",
+ "mediaType" => "video/mp4"
+ }
+ ]
+ }
+ ]
+
+ assert object.data["url"] ==
+ "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
end
test "it accepts Flag activities" do
diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs
index 95ee26416..cc880d82c 100644
--- a/test/web/mastodon_api/controllers/instance_controller_test.exs
+++ b/test/web/mastodon_api/controllers/instance_controller_test.exs
@@ -32,7 +32,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
"avatar_upload_limit" => _,
"background_upload_limit" => _,
"banner_upload_limit" => _,
- "background_image" => _
+ "background_image" => _,
+ "chat_limit" => _,
+ "description_limit" => _
} = result
assert result["pleroma"]["metadata"]["account_activation_required"] != nil
diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs
index a49ab002f..1598bf675 100644
--- a/test/web/static_fe/static_fe_controller_test.exs
+++ b/test/web/static_fe/static_fe_controller_test.exs
@@ -87,6 +87,20 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do
assert html =~ "testing a thing!"
end
+ test "redirects to json if requested", %{conn: conn, user: user} do
+ {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
+
+ conn =
+ conn
+ |> put_req_header(
+ "accept",
+ "Accept: application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", text/html"
+ )
+ |> get("/notice/#{activity.id}")
+
+ assert redirected_to(conn, 302) =~ activity.data["object"]
+ end
+
test "filters HTML tags", %{conn: conn} do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "<script>alert('xss')</script>"})