Merge branch 'develop' into accept-tags-2.5
This commit is contained in:
commit
98b9c1bcb1
|
@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
### Fixed
|
||||
|
||||
- rel="me" was missing its cache
|
||||
|
||||
### Removed
|
||||
|
||||
## 2.5.0 - 2022-12-23
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
FROM elixir:1.11.4-alpine as build
|
||||
ARG ELIXIR_VER=1.11.4
|
||||
ARG ERLANG_VER=24.2.1
|
||||
ARG ALPINE_VER=3.17.0
|
||||
|
||||
FROM hexpm/elixir:${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER} as build
|
||||
|
||||
COPY . .
|
||||
|
||||
|
@ -12,7 +16,7 @@ RUN apk add git gcc g++ musl-dev make cmake file-dev &&\
|
|||
mkdir release &&\
|
||||
mix release --path release
|
||||
|
||||
FROM alpine
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
|
|
|
@ -1052,6 +1052,15 @@
|
|||
description:
|
||||
"Minimum required age (in days) for users to create account. Only used if birthday is required.",
|
||||
suggestions: [6570]
|
||||
},
|
||||
%{
|
||||
key: :languages,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes.",
|
||||
suggestions: [
|
||||
"en"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -6,7 +6,70 @@ defmodule Mix.Tasks.Pleroma.OpenapiSpec do
|
|||
def run([path]) do
|
||||
# Load Pleroma application to get version info
|
||||
Application.load(:pleroma)
|
||||
spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
|
||||
File.write(path, spec)
|
||||
|
||||
spec_json = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
|
||||
# to get rid of the structs
|
||||
spec_regened = spec_json |> Jason.decode!()
|
||||
|
||||
check_specs!(spec_regened)
|
||||
|
||||
File.write(path, spec_json)
|
||||
end
|
||||
|
||||
defp check_specs!(spec) do
|
||||
with :ok <- check_specs(spec) do
|
||||
:ok
|
||||
else
|
||||
{_, errors} ->
|
||||
IO.puts(IO.ANSI.format([:red, :bright, "Spec check failed, errors:"]))
|
||||
Enum.map(errors, &IO.puts/1)
|
||||
|
||||
raise "Spec check failed"
|
||||
end
|
||||
end
|
||||
|
||||
def check_specs(spec) do
|
||||
errors =
|
||||
spec["paths"]
|
||||
|> Enum.flat_map(fn {path, %{} = endpoints} ->
|
||||
Enum.map(
|
||||
endpoints,
|
||||
fn {method, endpoint} ->
|
||||
with :ok <- check_endpoint(spec, endpoint) do
|
||||
:ok
|
||||
else
|
||||
error ->
|
||||
"#{endpoint["operationId"]} (#{method} #{path}): #{error}"
|
||||
end
|
||||
end
|
||||
)
|
||||
|> Enum.reject(fn res -> res == :ok end)
|
||||
end)
|
||||
|
||||
if errors == [] do
|
||||
:ok
|
||||
else
|
||||
{:error, errors}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_endpoint(spec, endpoint) do
|
||||
valid_tags = available_tags(spec)
|
||||
|
||||
with {_, [_ | _] = tags} <- {:tags, endpoint["tags"]},
|
||||
{_, []} <- {:unavailable, Enum.reject(tags, &(&1 in valid_tags))} do
|
||||
:ok
|
||||
else
|
||||
{:tags, _} ->
|
||||
"No tags specified"
|
||||
|
||||
{:unavailable, tags} ->
|
||||
"Tags #{inspect(tags)} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
|
||||
end
|
||||
end
|
||||
|
||||
defp available_tags(spec) do
|
||||
spec["x-tagGroups"]
|
||||
|> Enum.flat_map(fn %{"tags" => tags} -> tags end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -209,7 +209,8 @@ defp cachex_children do
|
|||
build_cachex("chat_message_id_idempotency_key",
|
||||
expiration: chat_message_id_idempotency_key_expiration(),
|
||||
limit: 500_000
|
||||
)
|
||||
),
|
||||
build_cachex("rel_me", limit: 2500)
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ defp exclude_filtered(query, user) do
|
|||
from([_n, a, o] in query,
|
||||
where:
|
||||
fragment("not(?->>'content' ~* ?)", o.data, ^regex) or
|
||||
fragment("?->>'content' is null", o.data) or
|
||||
fragment("?->>'actor' = ?", o.data, ^user.ap_id)
|
||||
)
|
||||
end
|
||||
|
@ -679,7 +680,7 @@ def skip?(
|
|||
cond do
|
||||
opts[:type] == "poll" -> false
|
||||
user.ap_id == actor -> false
|
||||
!User.following?(follower, user) -> true
|
||||
!User.following?(user, follower) -> true
|
||||
true -> false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,7 +33,10 @@ defp read_when_empty(current_description, _, _) when is_binary(current_descripti
|
|||
defp read_when_empty(_, file, tag) do
|
||||
try do
|
||||
{tag_content, 0} =
|
||||
System.cmd("exiftool", ["-b", "-s3", tag, file], stderr_to_stdout: true, parallelism: true)
|
||||
System.cmd("exiftool", ["-b", "-s3", tag, file],
|
||||
stderr_to_stdout: false,
|
||||
parallelism: true
|
||||
)
|
||||
|
||||
tag_content = String.trim(tag_content)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripLocation do
|
|||
# Formats not compatible with exiftool at this time
|
||||
def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop}
|
||||
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
|
||||
def filter(%Pleroma.Upload{content_type: "image/svg" <> _}), do: {:ok, :noop}
|
||||
|
||||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||
try do
|
||||
|
|
|
@ -31,7 +31,7 @@ def extract_report_info(
|
|||
|
||||
defp make_fake_activity(act, user) do
|
||||
%Activity{
|
||||
id: "pleroma:fake",
|
||||
id: "pleroma:fake:#{act["id"]}",
|
||||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"type" => "Create",
|
||||
|
|
|
@ -95,7 +95,8 @@ def spec(opts \\ []) do
|
|||
"Relays",
|
||||
"Report managment",
|
||||
"Status administration",
|
||||
"User administration"
|
||||
"User administration",
|
||||
"Announcement management"
|
||||
]
|
||||
},
|
||||
%{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]},
|
||||
|
@ -110,10 +111,12 @@ def spec(opts \\ []) do
|
|||
"Follow requests",
|
||||
"Mascot",
|
||||
"Markers",
|
||||
"Notifications"
|
||||
"Notifications",
|
||||
"Filters",
|
||||
"Settings"
|
||||
]
|
||||
},
|
||||
%{"name" => "Instance", "tags" => ["Custom emojis"]},
|
||||
%{"name" => "Instance", "tags" => ["Custom emojis", "Instance misc"]},
|
||||
%{"name" => "Messaging", "tags" => ["Chats", "Conversations"]},
|
||||
%{
|
||||
"name" => "Statuses",
|
||||
|
@ -125,10 +128,21 @@ def spec(opts \\ []) do
|
|||
"Retrieve status information",
|
||||
"Scheduled statuses",
|
||||
"Search",
|
||||
"Status actions"
|
||||
"Status actions",
|
||||
"Media attachments"
|
||||
]
|
||||
},
|
||||
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
|
||||
%{
|
||||
"name" => "Miscellaneous",
|
||||
"tags" => [
|
||||
"Emoji packs",
|
||||
"Reports",
|
||||
"Suggestions",
|
||||
"Announcements",
|
||||
"Remote interaction",
|
||||
"Others"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -461,7 +461,7 @@ def blocks_operation do
|
|||
|
||||
def lookup_operation do
|
||||
%Operation{
|
||||
tags: ["Account lookup"],
|
||||
tags: ["Retrieve account information"],
|
||||
summary: "Find a user by nickname",
|
||||
operationId: "AccountController.lookup",
|
||||
parameters: [
|
||||
|
|
|
@ -17,7 +17,7 @@ def open_api_operation(action) do
|
|||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement managment"],
|
||||
tags: ["Announcement management"],
|
||||
summary: "Retrieve a list of announcements",
|
||||
operationId: "AdminAPI.AnnouncementController.index",
|
||||
security: [%{"oAuth" => ["admin:read"]}],
|
||||
|
@ -46,7 +46,7 @@ def index_operation do
|
|||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement managment"],
|
||||
tags: ["Announcement management"],
|
||||
summary: "Display one announcement",
|
||||
operationId: "AdminAPI.AnnouncementController.show",
|
||||
security: [%{"oAuth" => ["admin:read"]}],
|
||||
|
@ -69,7 +69,7 @@ def show_operation do
|
|||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement managment"],
|
||||
tags: ["Announcement management"],
|
||||
summary: "Delete one announcement",
|
||||
operationId: "AdminAPI.AnnouncementController.delete",
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
|
@ -92,7 +92,7 @@ def delete_operation do
|
|||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement managment"],
|
||||
tags: ["Announcement management"],
|
||||
summary: "Create one announcement",
|
||||
operationId: "AdminAPI.AnnouncementController.create",
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
|
@ -107,7 +107,7 @@ def create_operation do
|
|||
|
||||
def change_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement managment"],
|
||||
tags: ["Announcement management"],
|
||||
summary: "Change one announcement",
|
||||
operationId: "AdminAPI.AnnouncementController.change",
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
|
|
|
@ -70,7 +70,7 @@ def index_operation do
|
|||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Status adminitration)"],
|
||||
tags: ["Status administration"],
|
||||
summary: "Get status",
|
||||
operationId: "AdminAPI.StatusController.show",
|
||||
parameters: [id_param() | admin_api_params()],
|
||||
|
@ -84,7 +84,7 @@ def show_operation do
|
|||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Status adminitration)"],
|
||||
tags: ["Status administration"],
|
||||
summary: "Change the scope of a status",
|
||||
operationId: "AdminAPI.StatusController.update",
|
||||
parameters: [id_param() | admin_api_params()],
|
||||
|
@ -99,7 +99,7 @@ def update_operation do
|
|||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Status adminitration)"],
|
||||
tags: ["Status administration"],
|
||||
summary: "Delete status",
|
||||
operationId: "AdminAPI.StatusController.delete",
|
||||
parameters: [id_param() | admin_api_params()],
|
||||
|
@ -143,7 +143,7 @@ def admin_account do
|
|||
}
|
||||
},
|
||||
tags: %Schema{type: :string},
|
||||
is_confirmed: %Schema{type: :string}
|
||||
is_confirmed: %Schema{type: :boolean}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ def open_api_operation(action) do
|
|||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement"],
|
||||
tags: ["Announcements"],
|
||||
summary: "Retrieve a list of announcements",
|
||||
operationId: "MastodonAPI.AnnouncementController.index",
|
||||
security: [%{"oAuth" => []}],
|
||||
|
@ -28,7 +28,7 @@ def index_operation do
|
|||
|
||||
def mark_read_operation do
|
||||
%Operation{
|
||||
tags: ["Announcement"],
|
||||
tags: ["Announcements"],
|
||||
summary: "Mark one announcement as read",
|
||||
operationId: "MastodonAPI.AnnouncementController.mark_read",
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
|
|
|
@ -17,7 +17,7 @@ def open_api_operation(action) do
|
|||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Directory"],
|
||||
tags: ["Others"],
|
||||
summary: "Profile directory",
|
||||
operationId: "DirectoryController.index",
|
||||
parameters:
|
||||
|
|
|
@ -13,7 +13,7 @@ def open_api_operation(action) do
|
|||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve instance information",
|
||||
description: "Information about the server",
|
||||
operationId: "InstanceController.show",
|
||||
|
@ -25,7 +25,7 @@ def show_operation do
|
|||
|
||||
def peers_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve list of known instances",
|
||||
operationId: "InstanceController.peers",
|
||||
responses: %{
|
||||
|
|
|
@ -133,7 +133,11 @@ defp name_param do
|
|||
defp files_object do
|
||||
%Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{type: :string},
|
||||
additionalProperties: %Schema{
|
||||
type: :string,
|
||||
description: "Filename of the emoji",
|
||||
extensions: %{"x-additionalPropertiesName": "Emoji name"}
|
||||
},
|
||||
description: "Object with emoji names as keys and filenames as values"
|
||||
}
|
||||
end
|
||||
|
|
|
@ -227,13 +227,29 @@ defp ok_response do
|
|||
|
||||
defp emoji_packs_response do
|
||||
Operation.response(
|
||||
"Object with pack names as keys and pack contents as values",
|
||||
"Emoji packs and the count",
|
||||
"application/json",
|
||||
%Schema{
|
||||
type: :object,
|
||||
additionalProperties: emoji_pack(),
|
||||
properties: %{
|
||||
packs: %Schema{
|
||||
type: :object,
|
||||
description: "Object with pack names as keys and pack contents as values",
|
||||
additionalProperties: %Schema{
|
||||
emoji_pack()
|
||||
| extensions: %{"x-additionalPropertiesName": "Pack name"}
|
||||
}
|
||||
},
|
||||
count: %Schema{
|
||||
type: :integer,
|
||||
description: "Number of emoji packs"
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"emojos" => emoji_pack().example
|
||||
"packs" => %{
|
||||
"emojos" => emoji_pack().example
|
||||
},
|
||||
"count" => 1
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -274,7 +290,11 @@ defp emoji_pack do
|
|||
defp files_object do
|
||||
%Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{type: :string},
|
||||
additionalProperties: %Schema{
|
||||
type: :string,
|
||||
description: "Filename",
|
||||
extensions: %{"x-additionalPropertiesName": "Emoji name"}
|
||||
},
|
||||
description: "Object with emoji names as keys and filenames as values"
|
||||
}
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ def open_api_operation(action) do
|
|||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve federation status",
|
||||
description: "Information about instances deemed unreachable by the server",
|
||||
operationId: "PleromaInstances.show",
|
||||
|
|
|
@ -440,7 +440,7 @@ def bookmarks_operation do
|
|||
|
||||
def show_history_operation do
|
||||
%Operation{
|
||||
tags: ["Retrieve status history"],
|
||||
tags: ["Retrieve status information"],
|
||||
summary: "Status history",
|
||||
description: "View history of a status",
|
||||
operationId: "StatusController.show_history",
|
||||
|
@ -457,7 +457,7 @@ def show_history_operation do
|
|||
|
||||
def show_source_operation do
|
||||
%Operation{
|
||||
tags: ["Retrieve status source"],
|
||||
tags: ["Retrieve status information"],
|
||||
summary: "Status source",
|
||||
description: "View source of a status",
|
||||
operationId: "StatusController.show_source",
|
||||
|
@ -474,7 +474,7 @@ def show_source_operation do
|
|||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Update status"],
|
||||
tags: ["Status actions"],
|
||||
summary: "Update status",
|
||||
description: "Change the content of a status",
|
||||
operationId: "StatusController.update",
|
||||
|
|
|
@ -17,7 +17,7 @@ def open_api_operation(action) do
|
|||
|
||||
def emoji_operation do
|
||||
%Operation{
|
||||
tags: ["Emojis"],
|
||||
tags: ["Custom emojis"],
|
||||
summary: "List all custom emojis",
|
||||
operationId: "UtilController.emoji",
|
||||
parameters: [],
|
||||
|
@ -30,7 +30,8 @@ def emoji_operation do
|
|||
properties: %{
|
||||
image_url: %Schema{type: :string},
|
||||
tags: %Schema{type: :array, items: %Schema{type: :string}}
|
||||
}
|
||||
},
|
||||
extensions: %{"x-additionalPropertiesName": "Emoji name"}
|
||||
},
|
||||
example: %{
|
||||
"firefox" => %{
|
||||
|
@ -45,7 +46,7 @@ def emoji_operation do
|
|||
|
||||
def frontend_configurations_operation do
|
||||
%Operation{
|
||||
tags: ["Configuration"],
|
||||
tags: ["Others"],
|
||||
summary: "Dump frontend configurations",
|
||||
operationId: "UtilController.frontend_configurations",
|
||||
parameters: [],
|
||||
|
@ -53,7 +54,12 @@ def frontend_configurations_operation do
|
|||
200 =>
|
||||
Operation.response("List", "application/json", %Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{type: :object}
|
||||
additionalProperties: %Schema{
|
||||
type: :object,
|
||||
description:
|
||||
"Opaque object representing the instance-wide configuration for the frontend",
|
||||
extensions: %{"x-additionalPropertiesName": "Frontend name"}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +138,7 @@ defp change_email_request do
|
|||
|
||||
def update_notificaton_settings_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
tags: ["Settings"],
|
||||
summary: "Update Notification Settings",
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
operationId: "UtilController.update_notificaton_settings",
|
||||
|
@ -207,6 +213,7 @@ def captcha_operation do
|
|||
%Operation{
|
||||
summary: "Get a captcha",
|
||||
operationId: "UtilController.captcha",
|
||||
tags: ["Others"],
|
||||
parameters: [],
|
||||
responses: %{
|
||||
200 => Operation.response("Success", "application/json", %Schema{type: :object})
|
||||
|
@ -356,7 +363,7 @@ defp delete_alias_request do
|
|||
|
||||
def healthcheck_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
tags: ["Others"],
|
||||
summary: "Quick status check on the instance",
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
operationId: "UtilController.healthcheck",
|
||||
|
@ -371,7 +378,7 @@ def healthcheck_operation do
|
|||
|
||||
def remote_subscribe_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
tags: ["Remote interaction"],
|
||||
summary: "Remote Subscribe",
|
||||
operationId: "UtilController.remote_subscribe",
|
||||
parameters: [],
|
||||
|
@ -381,7 +388,7 @@ def remote_subscribe_operation do
|
|||
|
||||
def remote_interaction_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
tags: ["Remote interaction"],
|
||||
summary: "Remote interaction",
|
||||
operationId: "UtilController.remote_interaction",
|
||||
requestBody: request_body("Parameters", remote_interaction_request(), required: true),
|
||||
|
@ -407,7 +414,7 @@ defp remote_interaction_request do
|
|||
|
||||
def show_subscribe_form_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
tags: ["Remote interaction"],
|
||||
summary: "Show remote subscribe form",
|
||||
operationId: "UtilController.show_subscribe_form",
|
||||
parameters: [],
|
||||
|
|
|
@ -144,7 +144,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
properties: %{
|
||||
content: %Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{type: :string},
|
||||
additionalProperties: %Schema{
|
||||
type: :string,
|
||||
description: "Alternate representation in the MIME type specified",
|
||||
extensions: %{"x-additionalPropertiesName": "MIME type"}
|
||||
},
|
||||
description:
|
||||
"A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`"
|
||||
},
|
||||
|
@ -195,7 +199,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
},
|
||||
spoiler_text: %Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{type: :string},
|
||||
additionalProperties: %Schema{
|
||||
type: :string,
|
||||
description: "Alternate representation in the MIME type specified",
|
||||
extensions: %{"x-additionalPropertiesName": "MIME type"}
|
||||
},
|
||||
description:
|
||||
"A map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`."
|
||||
},
|
||||
|
|
|
@ -269,14 +269,11 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
|
|||
end
|
||||
|
||||
defp normalize_fields_attributes(fields) do
|
||||
if Enum.all?(fields, &is_tuple/1) do
|
||||
Enum.map(fields, fn {_, v} -> v end)
|
||||
else
|
||||
Enum.map(fields, fn
|
||||
%{} = field -> %{"name" => field.name, "value" => field.value}
|
||||
field -> field
|
||||
end)
|
||||
end
|
||||
if(Enum.all?(fields, &is_tuple/1), do: Enum.map(fields, fn {_, v} -> v end), else: fields)
|
||||
|> Enum.map(fn
|
||||
%{} = field -> %{"name" => field.name, "value" => field.value}
|
||||
field -> field
|
||||
end)
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/accounts/relationships"
|
||||
|
|
|
@ -27,7 +27,7 @@ def render("show.json", _) do
|
|||
thumbnail:
|
||||
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|
||||
|> to_string,
|
||||
languages: ["en"],
|
||||
languages: Keyword.get(instance, :languages, ["en"]),
|
||||
registrations: Keyword.get(instance, :registrations_open),
|
||||
approval_required: Keyword.get(instance, :account_approval_required),
|
||||
# Extra (not present in Mastodon):
|
||||
|
|
|
@ -9,17 +9,13 @@ defmodule Pleroma.Web.RelMe do
|
|||
recv_timeout: 2_000
|
||||
]
|
||||
|
||||
if Pleroma.Config.get(:env) == :test do
|
||||
def parse(url) when is_binary(url), do: parse_url(url)
|
||||
else
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
def parse(url) when is_binary(url) do
|
||||
@cachex.fetch!(:rel_me_cache, url, fn _ ->
|
||||
{:commit, parse_url(url)}
|
||||
end)
|
||||
rescue
|
||||
e -> {:error, "Cachex error: #{inspect(e)}"}
|
||||
end
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
def parse(url) when is_binary(url) do
|
||||
@cachex.fetch!(:rel_me_cache, url, fn _ ->
|
||||
{:commit, parse_url(url)}
|
||||
end)
|
||||
rescue
|
||||
e -> {:error, "Cachex error: #{inspect(e)}"}
|
||||
end
|
||||
|
||||
def parse(_), do: {:error, "No URL provided"}
|
||||
|
|
10
mix.exs
10
mix.exs
|
@ -148,11 +148,9 @@ defp deps do
|
|||
{:ex_aws, "~> 2.1.6"},
|
||||
{:ex_aws_s3, "~> 2.0"},
|
||||
{:sweet_xml, "~> 0.7.2"},
|
||||
{:earmark, "~> 1.4.15"},
|
||||
{:earmark, "~> 1.4.22"},
|
||||
{:bbcode_pleroma, "~> 0.2.0"},
|
||||
{:crypt,
|
||||
git: "https://github.com/msantos/crypt.git",
|
||||
ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"},
|
||||
{:crypt, "~> 1.0"},
|
||||
{:cors_plug, "~> 2.0"},
|
||||
{:web_push_encryption, "~> 0.3.1"},
|
||||
{:swoosh, "~> 1.0"},
|
||||
|
@ -162,7 +160,7 @@ defp deps do
|
|||
{:floki, "~> 0.27"},
|
||||
{:timex, "~> 3.6"},
|
||||
{:ueberauth, "~> 0.4"},
|
||||
{:linkify, "~> 0.5.2"},
|
||||
{:linkify, "~> 0.5.3"},
|
||||
{:http_signatures, "~> 0.1.1"},
|
||||
{:telemetry, "~> 1.0.0", override: true},
|
||||
{:poolboy, "~> 1.5"},
|
||||
|
@ -196,7 +194,7 @@ defp deps do
|
|||
{:restarter, path: "./restarter"},
|
||||
{:majic, "~> 1.0"},
|
||||
{:eblurhash, "~> 1.2.2"},
|
||||
{:open_api_spex, "~> 3.10"},
|
||||
{:open_api_spex, "~> 3.16"},
|
||||
{:ecto_psql_extras, "~> 0.6"},
|
||||
|
||||
# indirect dependency version override
|
||||
|
|
10
mix.lock
10
mix.lock
|
@ -21,13 +21,13 @@
|
|||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
|
||||
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"crypt": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]},
|
||||
"crypt": {:hex, :crypt, "1.0.1", "a3567e1c651a2ec42c6650d9f3ab789e0f12a508c060653a9bbb5fafe60f043c", [:rebar3], [], "hexpm", "968dffe321c7a5d9f9b4577c4a4ff56a1c26d1a8a2270eb22c7636a0b43d3982"},
|
||||
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
|
||||
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
|
||||
"earmark": {:hex, :earmark, "1.4.18", "618c4ff1563450d1832b7fb41dc6755e470f91a6fd4c70f350a58b14f64a7db8", [:mix], [{:earmark_parser, ">= 1.4.17", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "57ac3b6da3958ed09c669a9b159e86377fcccda56bacde8a209fa4dcdef52560"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"},
|
||||
"earmark": {:hex, :earmark, "1.4.22", "ea3e45c6359446dc308be0a64ce82a03260d973de7d0625a762e6d352ff57958", [:mix], [{:earmark_parser, "~> 1.4.23", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "1caf5145665a42fd76d5317286b0c171861fb1c04f86ab103dde76868814fdfb"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
|
||||
"eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"},
|
||||
"ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"},
|
||||
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
|
||||
|
@ -64,7 +64,7 @@
|
|||
"joken": {:hex, :joken, "2.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"},
|
||||
"jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"},
|
||||
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
|
||||
"linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"},
|
||||
"linkify": {:hex, :linkify, "0.5.3", "5f8143d8f61f5ff08d3aeeff47ef6509492b4948d8f08007fbf66e4d2246a7f2", [:mix], [], "hexpm", "3ef35a1377d47c25506e07c1c005ea9d38d700699d92ee92825f024434258177"},
|
||||
"majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"},
|
||||
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
|
||||
|
@ -83,7 +83,7 @@
|
|||
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
|
||||
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
|
||||
"oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"},
|
||||
"open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"},
|
||||
"open_api_spex": {:hex, :open_api_spex, "3.16.0", "9843af4e87550cd8ac5821b10e4c74f1d51f0d4e3310f824d780614743423b25", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "bb0be24a648b73e8fc8cbda17f514b8486262275e8b33e8b5ae66283df972129"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
|
||||
"phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"},
|
||||
|
|
|
@ -6033,3 +6033,15 @@ msgstr ""
|
|||
msgctxt "config label at :pleroma-:instance > :moderator_privileges"
|
||||
msgid "Moderator privileges"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-autogen, elixir-format
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
msgctxt "config description at :pleroma-:instance > :languages"
|
||||
msgid "Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes."
|
||||
msgstr ""
|
||||
|
||||
#, elixir-autogen, elixir-format
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
msgctxt "config label at :pleroma-:instance > :languages"
|
||||
msgid "Languages"
|
||||
msgstr ""
|
||||
|
|
|
@ -111,7 +111,7 @@ msgid "Can't display this activity"
|
|||
msgstr ""
|
||||
|
||||
#, elixir-autogen, elixir-format
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:337
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334
|
||||
msgid "Can't find user"
|
||||
msgstr ""
|
||||
|
||||
|
@ -236,7 +236,7 @@ msgid "Poll's author can't vote"
|
|||
msgstr ""
|
||||
|
||||
#, elixir-autogen, elixir-format
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:502
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:499
|
||||
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
|
||||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39
|
||||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51
|
||||
|
@ -558,7 +558,7 @@ msgid "Access denied"
|
|||
msgstr ""
|
||||
|
||||
#, elixir-autogen, elixir-format
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:331
|
||||
msgid "This API requires an authenticated user"
|
||||
msgstr ""
|
||||
|
||||
|
|
BIN
test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png
vendored
Normal file
BIN
test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 820 B |
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
|
@ -0,0 +1,62 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.OpenapiSpecTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Mix.Tasks.Pleroma.OpenapiSpec
|
||||
|
||||
@spec_base %{
|
||||
"paths" => %{
|
||||
"/cofe" => %{
|
||||
"get" => %{
|
||||
"operationId" => "Some.operation",
|
||||
"tags" => []
|
||||
}
|
||||
},
|
||||
"/mew" => %{
|
||||
"post" => %{
|
||||
"operationId" => "Another.operation",
|
||||
"tags" => ["mew mew"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-tagGroups" => [
|
||||
%{
|
||||
"name" => "mew",
|
||||
"tags" => ["mew mew", "abc"]
|
||||
},
|
||||
%{
|
||||
"name" => "lol",
|
||||
"tags" => ["lol lol", "xyz"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
describe "check_specs/1" do
|
||||
test "Every operation must have a tag" do
|
||||
assert {:error, ["Some.operation (get /cofe): No tags specified"]} ==
|
||||
OpenapiSpec.check_specs(@spec_base)
|
||||
end
|
||||
|
||||
test "Every tag must be in tag groups" do
|
||||
spec =
|
||||
@spec_base
|
||||
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "def", "not specified"])
|
||||
|
||||
assert {:error,
|
||||
[
|
||||
"Some.operation (get /cofe): Tags #{inspect(["def", "not specified"])} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
|
||||
]} == OpenapiSpec.check_specs(spec)
|
||||
end
|
||||
|
||||
test "No errors if ok" do
|
||||
spec =
|
||||
@spec_base
|
||||
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "mew mew"])
|
||||
|
||||
assert :ok == OpenapiSpec.check_specs(spec)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -334,6 +334,32 @@ test "it disables notifications from strangers" do
|
|||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from non-followees" do
|
||||
follower = insert(:user)
|
||||
|
||||
followed =
|
||||
insert(:user,
|
||||
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
|
||||
)
|
||||
|
||||
CommonAPI.follow(follower, followed)
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it allows notifications from followees" do
|
||||
poster = insert(:user)
|
||||
|
||||
receiver =
|
||||
insert(:user,
|
||||
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
|
||||
)
|
||||
|
||||
CommonAPI.follow(receiver, poster)
|
||||
{:ok, activity} = CommonAPI.post(poster, %{status: "hey @#{receiver.nickname}"})
|
||||
assert Notification.create_notification(activity, receiver)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for user if he is the activity author" do
|
||||
activity = insert(:note_activity)
|
||||
author = User.get_cached_by_ap_id(activity.data["actor"])
|
||||
|
@ -1225,5 +1251,32 @@ test "it returns notifications about favorites with filtered word", %{user: user
|
|||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
||||
test "it returns notifications when related object is without content and filters are defined",
|
||||
%{user: user} do
|
||||
followed_user = insert(:user, is_locked: true)
|
||||
|
||||
insert(:filter, user: followed_user, phrase: "test", hide: true)
|
||||
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
|
||||
refute FollowingRelationship.following?(user, followed_user)
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
assert %{type: "follow_request"} =
|
||||
NotificationView.render("show.json", %{
|
||||
notification: notification,
|
||||
for: followed_user
|
||||
})
|
||||
|
||||
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
|
||||
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
assert %{type: "follow"} =
|
||||
NotificationView.render("show.json", %{
|
||||
notification: notification,
|
||||
for: followed_user
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,6 +42,33 @@ test "otherwise returns ImageDescription when present" do
|
|||
{:ok, :filtered, uploads_after}
|
||||
end
|
||||
|
||||
test "Ignores warnings" do
|
||||
uploads = %Pleroma.Upload{
|
||||
name: "image_with_imagedescription_and_caption-abstract_and_stray_data_after.png",
|
||||
content_type: "image/png",
|
||||
path:
|
||||
Path.absname(
|
||||
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
|
||||
),
|
||||
tempfile:
|
||||
Path.absname(
|
||||
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
|
||||
)
|
||||
}
|
||||
|
||||
assert {:ok, :filtered, %{description: "a descriptive white pixel"}} =
|
||||
Filter.Exiftool.ReadDescription.filter(uploads)
|
||||
|
||||
uploads = %Pleroma.Upload{
|
||||
name: "image_with_stray_data_after.png",
|
||||
content_type: "image/png",
|
||||
path: Path.absname("test/fixtures/image_with_stray_data_after.png"),
|
||||
tempfile: Path.absname("test/fixtures/image_with_stray_data_after.png")
|
||||
}
|
||||
|
||||
assert {:ok, :filtered, %{description: nil}} = Filter.Exiftool.ReadDescription.filter(uploads)
|
||||
end
|
||||
|
||||
test "otherwise returns iptc:Caption-Abstract when present" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "image_with_caption-abstract.jpg",
|
||||
|
|
|
@ -31,12 +31,19 @@ test "apply exiftool filter" do
|
|||
refute String.match?(exif_filtered, ~r/GPS/)
|
||||
end
|
||||
|
||||
test "verify webp files are skipped" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "sample.webp",
|
||||
content_type: "image/webp"
|
||||
}
|
||||
test "verify webp, heic, svg files are skipped" do
|
||||
uploads =
|
||||
~w{webp heic svg svg+xml}
|
||||
|> Enum.map(fn type ->
|
||||
%Pleroma.Upload{
|
||||
name: "sample.#{type}",
|
||||
content_type: "image/#{type}"
|
||||
}
|
||||
end)
|
||||
|
||||
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
|
||||
uploads
|
||||
|> Enum.each(fn upload ->
|
||||
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.User.ImportTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UserSearchTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ test "it works for incoming unqualified emoji reactions" do
|
|||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert match?([[emoji, _]], object.data["reactions"])
|
||||
assert match?([[^emoji, _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it reject invalid emoji reactions" do
|
||||
|
|
|
@ -104,6 +104,7 @@ test "it does not fetch reply-to activities beyond max replies depth limit" do
|
|||
end
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "it does not crash if the object in inReplyTo can't be fetched" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|
@ -723,6 +724,7 @@ test "the standalone note uses its own ID when context is missing" do
|
|||
assert modified.data["context"] == object.data["id"]
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
|
||||
|
|
|
@ -316,6 +316,7 @@ test "create new config setting in db", %{conn: conn} do
|
|||
assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "save configs setting without explicit key", %{conn: conn} do
|
||||
adapter = Application.get_env(:http, :adapter)
|
||||
send_user_agent = Application.get_env(:http, :send_user_agent)
|
||||
|
|
|
@ -366,6 +366,34 @@ test "returns reports with specified state", %{conn: conn} do
|
|||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
|
||||
test "renders content correctly", %{conn: conn} do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
note = insert(:note, user: target_user, data: %{"content" => "mew 1"})
|
||||
note2 = insert(:note, user: target_user, data: %{"content" => "mew 2"})
|
||||
activity = insert(:note_activity, user: target_user, note: note)
|
||||
activity2 = insert(:note_activity, user: target_user, note: note2)
|
||||
|
||||
{:ok, _report} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id, activity2.id]
|
||||
})
|
||||
|
||||
CommonAPI.delete(activity.id, target_user)
|
||||
CommonAPI.delete(activity2.id, target_user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get(report_path(conn, :index))
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert [open_report] = response["reports"]
|
||||
assert %{"statuses" => [s1, s2]} = open_report
|
||||
assert "mew 1" in [s1["content"], s2["content"]]
|
||||
assert "mew 2" in [s1["content"], s2["content"]]
|
||||
end
|
||||
|
||||
test "returns 403 when requested by a non-admin" do
|
||||
user = insert(:user)
|
||||
token = insert(:oauth_token, user: user)
|
||||
|
|
|
@ -178,6 +178,10 @@ test "links" do
|
|||
code = "https://github.com/pragdave/earmark/"
|
||||
{result, [], []} = Utils.format_input(code, "text/markdown")
|
||||
assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
|
||||
|
||||
code = "https://github.com/~foo/bar"
|
||||
{result, [], []} = Utils.format_input(code, "text/markdown")
|
||||
assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
|
||||
end
|
||||
|
||||
test "link with local mention" do
|
||||
|
|
|
@ -518,6 +518,25 @@ test "it de-duplicates tags" do
|
|||
assert Object.tags(object) == ["2hu"]
|
||||
end
|
||||
|
||||
test "zwnj is treated as word character" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#ساٴينس"})
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert Object.tags(object) == ["ساٴينس"]
|
||||
end
|
||||
|
||||
test "double dot in link is allowed" do
|
||||
user = insert(:user)
|
||||
text = "https://example.to/something..mp3"
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: text})
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<a href=\"#{text}\" rel=\"ugc\">#{text}</a>"
|
||||
end
|
||||
|
||||
test "it adds emoji in the object" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})
|
||||
|
|
|
@ -92,4 +92,18 @@ test "get peers", %{conn: conn} do
|
|||
|
||||
assert ["peer1.com", "peer2.com"] == Enum.sort(result)
|
||||
end
|
||||
|
||||
test "instance languages", %{conn: conn} do
|
||||
assert %{"languages" => ["en"]} =
|
||||
conn
|
||||
|> get("/api/v1/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
clear_config([:instance, :languages], ["aa", "bb"])
|
||||
|
||||
assert %{"languages" => ["aa", "bb"]} =
|
||||
conn
|
||||
|> get("/api/v1/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -375,7 +375,9 @@ test "updates the user's background, upload_limit, returns a HTTP 413", %{
|
|||
"pleroma_background_image" => new_background_oversized
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert %{"error" => "File is too large"} == json_response_and_validate_schema(res, 413)
|
||||
|
||||
user = Repo.get(User, user.id)
|
||||
assert user.background == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
Code.put_compiler_option(:warnings_as_errors, true)
|
||||
|
||||
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
|
||||
ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude)
|
||||
|
||||
|
|
Loading…
Reference in New Issue