forked from AkkomaGang/akkoma
Merge branch 'develop' into feature/tag_feed
This commit is contained in:
commit
41e2332007
25 changed files with 310 additions and 62 deletions
|
@ -281,19 +281,19 @@ docker:
|
|||
IMAGE_TAG_LATEST_STABLE: $CI_REGISTRY_IMAGE:latest-stable
|
||||
before_script: &before-docker
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
- docker pull $IMAGE_TAG_SLUG || true
|
||||
- export CI_JOB_TIMESTAMP=$(date --utc -Iseconds)
|
||||
- export CI_VCS_REF=$CI_COMMIT_SHORT_SHA
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker pull $IMAGE_TAG_SLUG || true
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
- docker push $IMAGE_TAG_LATEST
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
- develop
|
||||
- develop@pleroma/pleroma
|
||||
|
||||
docker-stable:
|
||||
stage: docker
|
||||
|
@ -304,12 +304,28 @@ docker-stable:
|
|||
before_script: *before-docker
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker pull $IMAGE_TAG_SLUG || true
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
- docker push $IMAGE_TAG_LATEST_STABLE
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
- stable
|
||||
- stable@pleroma/pleroma
|
||||
|
||||
docker-release:
|
||||
stage: docker
|
||||
image: docker:latest
|
||||
cache: {}
|
||||
dependencies: []
|
||||
variables: *docker-variables
|
||||
before_script: *before-docker
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
- /^release/.*$/@pleroma/pleroma
|
||||
|
|
|
@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- **Breaking**: MDII uploader
|
||||
|
||||
### Changed
|
||||
- **Breaking:** Pleroma won't start if it detects unapplied migrations
|
||||
- **Breaking:** attachments are removed along with statuses when there are no other references to it
|
||||
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
|
||||
- **Breaking:** attachment links (`config :pleroma, :instance, no_attachment_links` and `config :pleroma, Pleroma.Upload, link_name`) disabled by default
|
||||
|
@ -43,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload.
|
||||
- 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.
|
||||
</details>
|
||||
|
||||
### Added
|
||||
|
|
|
@ -9,7 +9,7 @@ def generate_like_activities(user, posts) do
|
|||
{time, _} =
|
||||
:timer.tc(fn ->
|
||||
Task.async_stream(
|
||||
Enum.take_random(posts, count_likes),
|
||||
Enum.take_random(posts, count_likes),
|
||||
fn post -> {:ok, _, _} = CommonAPI.favorite(post.id, user) end,
|
||||
max_concurrency: 10,
|
||||
timeout: 30_000
|
||||
|
@ -142,6 +142,48 @@ defp do_generate_activity(users) do
|
|||
CommonAPI.post(Enum.random(users), post)
|
||||
end
|
||||
|
||||
def generate_power_intervals(opts \\ []) do
|
||||
count = Keyword.get(opts, :count, 20)
|
||||
power = Keyword.get(opts, :power, 2)
|
||||
IO.puts("Generating #{count} intervals for a power #{power} series...")
|
||||
counts = Enum.map(1..count, fn n -> :math.pow(n, power) end)
|
||||
sum = Enum.sum(counts)
|
||||
|
||||
densities =
|
||||
Enum.map(counts, fn c ->
|
||||
c / sum
|
||||
end)
|
||||
|
||||
densities
|
||||
|> Enum.reduce(0, fn density, acc ->
|
||||
if acc == 0 do
|
||||
[{0, density}]
|
||||
else
|
||||
[{_, lower} | _] = acc
|
||||
[{lower, lower + density} | acc]
|
||||
end
|
||||
end)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
def generate_tagged_activities(opts \\ []) do
|
||||
tag_count = Keyword.get(opts, :tag_count, 20)
|
||||
users = Keyword.get(opts, :users, Repo.all(User))
|
||||
activity_count = Keyword.get(opts, :count, 200_000)
|
||||
|
||||
intervals = generate_power_intervals(count: tag_count)
|
||||
|
||||
IO.puts(
|
||||
"Generating #{activity_count} activities using #{tag_count} different tags of format `tag_n`, starting at tag_0"
|
||||
)
|
||||
|
||||
Enum.each(1..activity_count, fn _ ->
|
||||
random = :rand.uniform()
|
||||
i = Enum.find_index(intervals, fn {lower, upper} -> lower <= random && upper > random end)
|
||||
CommonAPI.post(Enum.random(users), %{"status" => "a post with the tag #tag_#{i}"})
|
||||
end)
|
||||
end
|
||||
|
||||
defp do_generate_activity_with_mention(user, users) do
|
||||
mentions_cnt = Enum.random([2, 3, 4, 5])
|
||||
with_user = Enum.random([true, false])
|
||||
|
|
87
benchmarks/mix/tasks/pleroma/benchmarks/tags.ex
Normal file
87
benchmarks/mix/tasks/pleroma/benchmarks/tags.ex
Normal file
|
@ -0,0 +1,87 @@
|
|||
defmodule Mix.Tasks.Pleroma.Benchmarks.Tags do
|
||||
use Mix.Task
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.LoadTesting.Generator
|
||||
import Ecto.Query
|
||||
|
||||
def run(_args) do
|
||||
Mix.Pleroma.start_pleroma()
|
||||
activities_count = Repo.aggregate(from(a in Pleroma.Activity), :count, :id)
|
||||
|
||||
if activities_count == 0 do
|
||||
IO.puts("Did not find any activities, cleaning and generating")
|
||||
clean_tables()
|
||||
Generator.generate_users(users_max: 10)
|
||||
Generator.generate_tagged_activities()
|
||||
else
|
||||
IO.puts("Found #{activities_count} activities, won't generate new ones")
|
||||
end
|
||||
|
||||
tags = Enum.map(0..20, fn i -> {"For #tag_#{i}", "tag_#{i}"} end)
|
||||
|
||||
Enum.each(tags, fn {_, tag} ->
|
||||
query =
|
||||
from(o in Pleroma.Object,
|
||||
where: fragment("(?)->'tag' \\? (?)", o.data, ^tag)
|
||||
)
|
||||
|
||||
count = Repo.aggregate(query, :count, :id)
|
||||
IO.puts("Database contains #{count} posts tagged with #{tag}")
|
||||
end)
|
||||
|
||||
user = Repo.all(Pleroma.User) |> List.first()
|
||||
|
||||
Benchee.run(
|
||||
%{
|
||||
"Hashtag fetching, any" => fn tags ->
|
||||
Pleroma.Web.MastodonAPI.TimelineController.hashtag_fetching(
|
||||
%{
|
||||
"any" => tags
|
||||
},
|
||||
user,
|
||||
false
|
||||
)
|
||||
end,
|
||||
# Will always return zero results because no overlapping hashtags are generated.
|
||||
"Hashtag fetching, all" => fn tags ->
|
||||
Pleroma.Web.MastodonAPI.TimelineController.hashtag_fetching(
|
||||
%{
|
||||
"all" => tags
|
||||
},
|
||||
user,
|
||||
false
|
||||
)
|
||||
end
|
||||
},
|
||||
inputs:
|
||||
tags
|
||||
|> Enum.map(fn {_, v} -> v end)
|
||||
|> Enum.chunk_every(2)
|
||||
|> Enum.map(fn tags -> {"For #{inspect(tags)}", tags} end),
|
||||
time: 5
|
||||
)
|
||||
|
||||
Benchee.run(
|
||||
%{
|
||||
"Hashtag fetching" => fn tag ->
|
||||
Pleroma.Web.MastodonAPI.TimelineController.hashtag_fetching(
|
||||
%{
|
||||
"tag" => tag
|
||||
},
|
||||
user,
|
||||
false
|
||||
)
|
||||
end
|
||||
},
|
||||
inputs: tags,
|
||||
time: 5
|
||||
)
|
||||
end
|
||||
|
||||
defp clean_tables do
|
||||
IO.puts("Deleting old data...\n")
|
||||
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE users CASCADE;")
|
||||
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE activities CASCADE;")
|
||||
Ecto.Adapters.SQL.query!(Repo, "TRUNCATE objects CASCADE;")
|
||||
end
|
||||
end
|
|
@ -33,6 +33,7 @@ def user_agent do
|
|||
def start(_type, _args) do
|
||||
Pleroma.HTML.compile_scrubbers()
|
||||
Pleroma.Config.DeprecationWarnings.warn()
|
||||
Pleroma.Repo.check_migrations_applied!()
|
||||
setup_instrumenters()
|
||||
load_custom_modules()
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ defmodule Pleroma.Repo do
|
|||
adapter: Ecto.Adapters.Postgres,
|
||||
migration_timestamps: [type: :naive_datetime_usec]
|
||||
|
||||
require Logger
|
||||
|
||||
defmodule Instrumenter do
|
||||
use Prometheus.EctoInstrumenter
|
||||
end
|
||||
|
@ -47,4 +49,37 @@ def get_assoc(resource, association) do
|
|||
_ -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def check_migrations_applied!() do
|
||||
unless Pleroma.Config.get(
|
||||
[:i_am_aware_this_may_cause_data_loss, :disable_migration_check],
|
||||
false
|
||||
) do
|
||||
Ecto.Migrator.with_repo(__MODULE__, fn repo ->
|
||||
down_migrations =
|
||||
Ecto.Migrator.migrations(repo)
|
||||
|> Enum.reject(fn
|
||||
{:up, _, _} -> true
|
||||
{:down, _, _} -> false
|
||||
end)
|
||||
|
||||
if length(down_migrations) > 0 do
|
||||
down_migrations_text =
|
||||
Enum.map(down_migrations, fn {:down, id, name} -> "- #{name} (#{id})\n" end)
|
||||
|
||||
Logger.error(
|
||||
"The following migrations were not applied:\n#{down_migrations_text}If you want to start Pleroma anyway, set\nconfig :pleroma, :i_am_aware_this_may_cause_data_loss, disable_migration_check: true"
|
||||
)
|
||||
|
||||
raise Pleroma.Repo.UnappliedMigrationsError
|
||||
end
|
||||
end)
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Pleroma.Repo.UnappliedMigrationsError do
|
||||
defexception message: "Unapplied Migrations detected"
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ def filter(%{"type" => message_type} = message) do
|
|||
with accepted_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :accept]),
|
||||
rejected_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :reject]),
|
||||
true <-
|
||||
length(accepted_vocabulary) == 0 || Enum.member?(accepted_vocabulary, message_type),
|
||||
Enum.empty?(accepted_vocabulary) || Enum.member?(accepted_vocabulary, message_type),
|
||||
false <-
|
||||
length(rejected_vocabulary) > 0 && Enum.member?(rejected_vocabulary, message_type),
|
||||
{:ok, _} <- filter(message["object"]) do
|
||||
|
|
|
@ -658,24 +658,8 @@ def handle_incoming(
|
|||
with %User{ap_id: ^actor_id} = actor <- User.get_cached_by_ap_id(object["id"]) do
|
||||
{:ok, new_user_data} = ActivityPub.user_data_from_user_object(object)
|
||||
|
||||
locked = new_user_data[:locked] || false
|
||||
attachment = get_in(new_user_data, [:source_data, "attachment"]) || []
|
||||
invisible = new_user_data[:invisible] || false
|
||||
|
||||
fields =
|
||||
attachment
|
||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
||||
|
||||
update_data =
|
||||
new_user_data
|
||||
|> Map.take([:avatar, :banner, :bio, :name, :also_known_as])
|
||||
|> Map.put(:fields, fields)
|
||||
|> Map.put(:locked, locked)
|
||||
|> Map.put(:invisible, invisible)
|
||||
|
||||
actor
|
||||
|> User.upgrade_changeset(update_data, true)
|
||||
|> User.upgrade_changeset(new_user_data, true)
|
||||
|> User.update_and_set_cache()
|
||||
|
||||
ActivityPub.update(%{
|
||||
|
|
|
@ -75,7 +75,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["write:reports"], admin: true}
|
||||
when action in [:report_update_state, :report_respond]
|
||||
when action in [:reports_update]
|
||||
)
|
||||
|
||||
plug(
|
||||
|
@ -639,7 +639,7 @@ def get_password_reset(conn, %{"nickname" => nickname}) do
|
|||
def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||
users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
|
||||
|
||||
Enum.map(users, &User.force_password_reset_async/1)
|
||||
Enum.each(users, &User.force_password_reset_async/1)
|
||||
|
||||
ModerationLog.insert_log(%{
|
||||
actor: admin,
|
||||
|
|
|
@ -85,9 +85,13 @@ def delete(activity_id, user) do
|
|||
def repeat(id_or_ap_id, user, params \\ %{}) do
|
||||
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
|
||||
object <- Object.normalize(activity),
|
||||
nil <- Utils.get_existing_announce(user.ap_id, object),
|
||||
announce_activity <- Utils.get_existing_announce(user.ap_id, object),
|
||||
public <- public_announce?(object, params) do
|
||||
ActivityPub.announce(user, object, nil, true, public)
|
||||
if announce_activity do
|
||||
{:ok, announce_activity, object}
|
||||
else
|
||||
ActivityPub.announce(user, object, nil, true, public)
|
||||
end
|
||||
else
|
||||
_ -> {:error, dgettext("errors", "Could not repeat")}
|
||||
end
|
||||
|
@ -105,8 +109,12 @@ def unrepeat(id_or_ap_id, user) do
|
|||
def favorite(id_or_ap_id, user) do
|
||||
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
|
||||
object <- Object.normalize(activity),
|
||||
nil <- Utils.get_existing_like(user.ap_id, object) do
|
||||
ActivityPub.like(user, object)
|
||||
like_activity <- Utils.get_existing_like(user.ap_id, object) do
|
||||
if like_activity do
|
||||
{:ok, like_activity, object}
|
||||
else
|
||||
ActivityPub.like(user, object)
|
||||
end
|
||||
else
|
||||
_ -> {:error, dgettext("errors", "Could not favorite")}
|
||||
end
|
||||
|
|
|
@ -6,9 +6,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionController do
|
|||
@moduledoc "The module represents functions to manage user subscriptions."
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View
|
||||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Push.Subscription
|
||||
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View
|
||||
|
||||
action_fallback(:errors)
|
||||
|
||||
|
|
|
@ -77,10 +77,7 @@ def public(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json", activities: activities, for: user, as: :activity)
|
||||
end
|
||||
|
||||
# GET /api/v1/timelines/tag/:tag
|
||||
def hashtag(%{assigns: %{user: user}} = conn, params) do
|
||||
local_only = truthy_param?(params["local"])
|
||||
|
||||
def hashtag_fetching(params, user, local_only) do
|
||||
tags =
|
||||
[params["tag"], params["any"]]
|
||||
|> List.flatten()
|
||||
|
@ -98,7 +95,7 @@ def hashtag(%{assigns: %{user: user}} = conn, params) do
|
|||
|> Map.get("none", [])
|
||||
|> Enum.map(&String.downcase(&1))
|
||||
|
||||
activities =
|
||||
_activities =
|
||||
params
|
||||
|> Map.put("type", "Create")
|
||||
|> Map.put("local_only", local_only)
|
||||
|
@ -109,6 +106,13 @@ def hashtag(%{assigns: %{user: user}} = conn, params) do
|
|||
|> Map.put("tag_all", tag_all)
|
||||
|> Map.put("tag_reject", tag_reject)
|
||||
|> ActivityPub.fetch_public_activities()
|
||||
end
|
||||
|
||||
# GET /api/v1/timelines/tag/:tag
|
||||
def hashtag(%{assigns: %{user: user}} = conn, params) do
|
||||
local_only = truthy_param?(params["local"])
|
||||
|
||||
activities = hashtag_fetching(params, user, local_only)
|
||||
|
||||
conn
|
||||
|> add_link_headers(activities, %{"local" => local_only})
|
||||
|
|
|
@ -14,10 +14,10 @@ defmodule Pleroma.Web.OAuth.OAuthController do
|
|||
alias Pleroma.Web.ControllerHelper
|
||||
alias Pleroma.Web.OAuth.App
|
||||
alias Pleroma.Web.OAuth.Authorization
|
||||
alias Pleroma.Web.OAuth.Scopes
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken
|
||||
alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken
|
||||
alias Pleroma.Web.OAuth.Scopes
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|
|||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["read:statuses"]}
|
||||
when action in [:conversation, :conversation_statuses, :emoji_reactions_by]
|
||||
when action in [:conversation, :conversation_statuses]
|
||||
)
|
||||
|
||||
plug(
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -124,7 +124,7 @@ defp deps do
|
|||
{:earmark, "~> 1.3"},
|
||||
{:bbcode, "~> 0.1.1"},
|
||||
{:ex_machina, "~> 2.3", only: :test},
|
||||
{:credo, "~> 0.9.3", only: [:dev, :test]},
|
||||
{:credo, "~> 1.1.0", only: [:dev, :test], runtime: false},
|
||||
{:mock, "~> 0.3.3", only: :test},
|
||||
{:crypt,
|
||||
git: "https://github.com/msantos/crypt", ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"},
|
||||
|
|
4
mix.lock
4
mix.lock
|
@ -16,7 +16,7 @@
|
|||
"cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm"},
|
||||
"credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"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", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
|
||||
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm"},
|
||||
|
@ -63,7 +63,7 @@
|
|||
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
|
||||
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
|
||||
"mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm"},
|
||||
"mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm"},
|
||||
"myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
|
||||
|
|
|
@ -745,7 +745,7 @@ test "it doesn't return notifications from a blocked user when with_muted is set
|
|||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
|
||||
assert length(Notification.for_user(user, %{with_muted: true})) == 0
|
||||
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
|
||||
end
|
||||
|
||||
test "it doesn't return notifications from a domain-blocked user when with_muted is set" do
|
||||
|
@ -755,7 +755,7 @@ test "it doesn't return notifications from a domain-blocked user when with_muted
|
|||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
|
||||
assert length(Notification.for_user(user, %{with_muted: true})) == 0
|
||||
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
|
||||
end
|
||||
|
||||
test "it returns notifications from muted threads when with_muted is set" do
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
defmodule Pleroma.RepoTest do
|
||||
use Pleroma.DataCase
|
||||
import ExUnit.CaptureLog
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
describe "find_resource/1" do
|
||||
|
@ -46,4 +49,44 @@ test "return error if has not assoc " do
|
|||
assert Repo.get_assoc(token, :user) == {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
describe "check_migrations_applied!" do
|
||||
setup_with_mocks([
|
||||
{Ecto.Migrator, [],
|
||||
[
|
||||
with_repo: fn repo, fun -> passthrough([repo, fun]) end,
|
||||
migrations: fn Pleroma.Repo ->
|
||||
[
|
||||
{:up, 20_191_128_153_944, "fix_missing_following_count"},
|
||||
{:up, 20_191_203_043_610, "create_report_notes"},
|
||||
{:down, 20_191_220_174_645, "add_scopes_to_pleroma_feo_auth_records"}
|
||||
]
|
||||
end
|
||||
]}
|
||||
]) do
|
||||
:ok
|
||||
end
|
||||
|
||||
test "raises if it detects unapplied migrations" do
|
||||
assert_raise Pleroma.Repo.UnappliedMigrationsError, fn ->
|
||||
capture_log(&Repo.check_migrations_applied!/0)
|
||||
end
|
||||
end
|
||||
|
||||
test "doesn't do anything if disabled" do
|
||||
disable_migration_check =
|
||||
Pleroma.Config.get([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
|
||||
|
||||
Pleroma.Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true)
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put(
|
||||
[:i_am_aware_this_may_cause_data_loss, :disable_migration_check],
|
||||
disable_migration_check
|
||||
)
|
||||
end)
|
||||
|
||||
assert :ok == Repo.check_migrations_applied!()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ test "with locked accounts, it does not create a follow or an accept" do
|
|||
)
|
||||
|> Repo.all()
|
||||
|
||||
assert length(accepts) == 0
|
||||
assert Enum.empty?(accepts)
|
||||
end
|
||||
|
||||
test "it works for follow requests when you are already followed, creating a new accept activity" do
|
||||
|
|
|
@ -1363,6 +1363,30 @@ test "returns 404 when report id is invalid", %{conn: conn} do
|
|||
}
|
||||
end
|
||||
|
||||
test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
|
||||
read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||
write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> assign(:token, read_token)
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [%{"state" => "resolved", "id" => id}]
|
||||
})
|
||||
|> json_response(403)
|
||||
|
||||
assert response == %{
|
||||
"error" => "Insufficient permissions: admin:write:reports."
|
||||
}
|
||||
|
||||
conn
|
||||
|> assign(:token, write_token)
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [%{"state" => "resolved", "id" => id}]
|
||||
})
|
||||
|> json_response(:no_content)
|
||||
end
|
||||
|
||||
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
|
@ -2840,7 +2864,7 @@ test "GET /instances/:instance/statuses", %{conn: conn} do
|
|||
|
||||
response = json_response(ret_conn, 200)
|
||||
|
||||
assert length(response) == 0
|
||||
assert Enum.empty?(response)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -284,22 +284,22 @@ test "favoriting a status" do
|
|||
{:ok, %Activity{}, _} = CommonAPI.favorite(activity.id, user)
|
||||
end
|
||||
|
||||
test "retweeting a status twice returns an error" do
|
||||
test "retweeting a status twice returns the status" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
|
||||
{:ok, %Activity{}, _object} = CommonAPI.repeat(activity.id, user)
|
||||
{:error, _} = CommonAPI.repeat(activity.id, user)
|
||||
{:ok, %Activity{} = activity, object} = CommonAPI.repeat(activity.id, user)
|
||||
{:ok, ^activity, ^object} = CommonAPI.repeat(activity.id, user)
|
||||
end
|
||||
|
||||
test "favoriting a status twice returns an error" do
|
||||
test "favoriting a status twice returns the status" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
|
||||
{:ok, %Activity{}, _object} = CommonAPI.favorite(activity.id, user)
|
||||
{:error, _} = CommonAPI.favorite(activity.id, user)
|
||||
{:ok, %Activity{} = activity, object} = CommonAPI.favorite(activity.id, user)
|
||||
{:ok, ^activity, ^object} = CommonAPI.favorite(activity.id, user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ test "for private posts, not a reply" do
|
|||
|
||||
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil)
|
||||
assert length(to) == 2
|
||||
assert length(cc) == 0
|
||||
assert Enum.empty?(cc)
|
||||
|
||||
assert mentioned_user.ap_id in to
|
||||
assert user.follower_address in to
|
||||
|
@ -323,7 +323,7 @@ test "for private posts, a reply" do
|
|||
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil)
|
||||
|
||||
assert length(to) == 3
|
||||
assert length(cc) == 0
|
||||
assert Enum.empty?(cc)
|
||||
|
||||
assert mentioned_user.ap_id in to
|
||||
assert third_user.ap_id in to
|
||||
|
@ -338,7 +338,7 @@ test "for direct posts, not a reply" do
|
|||
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil)
|
||||
|
||||
assert length(to) == 1
|
||||
assert length(cc) == 0
|
||||
assert Enum.empty?(cc)
|
||||
|
||||
assert mentioned_user.ap_id in to
|
||||
end
|
||||
|
@ -353,7 +353,7 @@ test "for direct posts, a reply" do
|
|||
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil)
|
||||
|
||||
assert length(to) == 2
|
||||
assert length(cc) == 0
|
||||
assert Enum.empty?(cc)
|
||||
|
||||
assert mentioned_user.ap_id in to
|
||||
assert third_user.ap_id in to
|
||||
|
|
|
@ -638,6 +638,13 @@ test "favs a status and returns it", %{conn: conn} do
|
|||
assert to_string(activity.id) == id
|
||||
end
|
||||
|
||||
test "favoriting twice will just return 200", %{conn: conn} do
|
||||
activity = insert(:note_activity)
|
||||
|
||||
post(conn, "/api/v1/statuses/#{activity.id}/favourite")
|
||||
assert post(conn, "/api/v1/statuses/#{activity.id}/favourite") |> json_response(200)
|
||||
end
|
||||
|
||||
test "returns 400 error for a wrong id", %{conn: conn} do
|
||||
conn = post(conn, "/api/v1/statuses/1/favourite")
|
||||
|
||||
|
|
|
@ -57,11 +57,6 @@ test "GET /api/v1/pleroma/statuses/:id/emoji_reactions_by", %{conn: conn} do
|
|||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["read:statuses"]))
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/emoji_reactions_by")
|
||||
|
|
|
@ -55,7 +55,7 @@ test "it returns HTTP 200", %{conn: conn} do
|
|||
|
||||
user = refresh_record(user)
|
||||
assert Comeonin.Pbkdf2.checkpw("test", user.password_hash)
|
||||
assert length(Token.get_user_tokens(user)) == 0
|
||||
assert Enum.empty?(Token.get_user_tokens(user))
|
||||
end
|
||||
|
||||
test "it sets password_reset_pending to false", %{conn: conn} do
|
||||
|
|
Loading…
Reference in a new issue