Merge branch and resolve conflict in database_test.exs

This commit is contained in:
Lain Soykaf 2025-02-25 16:23:46 +04:00
commit 5851d787b6
42 changed files with 1181 additions and 41 deletions

View file

@ -412,6 +412,7 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
["schema_migrations"],
["thread_mutes"],
["user_follows_hashtag"],
# ["user_frontend_setting_profiles"], # not in pleroma
["user_invite_tokens"],
["user_notes"],
["user_relationships"],

View file

@ -0,0 +1,56 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.ContentLanguageMapTest do
use Pleroma.DataCase, async: true
alias Pleroma.EctoType.ActivityPub.ObjectValidators.ContentLanguageMap
test "it validates" do
data = %{
"en-US" => "mew mew",
"en-GB" => "meow meow"
}
assert {:ok, ^data} = ContentLanguageMap.cast(data)
end
test "it validates empty strings" do
data = %{
"en-US" => "mew mew",
"en-GB" => ""
}
assert {:ok, ^data} = ContentLanguageMap.cast(data)
end
test "it ignores non-strings within the map" do
data = %{
"en-US" => "mew mew",
"en-GB" => 123
}
assert {:ok, validated_data} = ContentLanguageMap.cast(data)
assert validated_data == %{"en-US" => "mew mew"}
end
test "it ignores bad locale codes" do
data = %{
"en-US" => "mew mew",
"en_GB" => "meow meow",
"en<<#@!$#!@%!GB" => "meow meow"
}
assert {:ok, validated_data} = ContentLanguageMap.cast(data)
assert validated_data == %{"en-US" => "mew mew"}
end
test "it complains with non-map data" do
assert :error = ContentLanguageMap.cast("mew")
assert :error = ContentLanguageMap.cast(["mew"])
assert :error = ContentLanguageMap.cast([%{"en-US" => "mew"}])
end
end

View file

@ -0,0 +1,29 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.LanguageCodeTest do
use Pleroma.DataCase, async: true
alias Pleroma.EctoType.ActivityPub.ObjectValidators.LanguageCode
test "it accepts language code" do
text = "pl"
assert {:ok, ^text} = LanguageCode.cast(text)
end
test "it accepts language code with region" do
text = "pl-PL"
assert {:ok, ^text} = LanguageCode.cast(text)
end
test "errors for invalid language code" do
assert {:error, :invalid_language} = LanguageCode.cast("ru_RU")
assert {:error, :invalid_language} = LanguageCode.cast(" ")
assert {:error, :invalid_language} = LanguageCode.cast("en-US\n")
end
test "errors for non-text" do
assert :error == LanguageCode.cast(42)
end
end

View file

@ -2919,4 +2919,74 @@ defmodule Pleroma.UserTest do
assert [%{"verified_at" => ^verified_at}] = user.fields
end
describe "follow_hashtag/2" do
test "should follow a hashtag" do
user = insert(:user)
hashtag = insert(:hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.followed_hashtags |> Enum.count() == 1
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end
test "should not follow a hashtag twice" do
user = insert(:user)
hashtag = insert(:hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.followed_hashtags |> Enum.count() == 1
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end
test "can follow multiple hashtags" do
user = insert(:user)
hashtag = insert(:hashtag)
other_hashtag = insert(:hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {:ok, _} = user |> User.follow_hashtag(other_hashtag)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.followed_hashtags |> Enum.count() == 2
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
assert other_hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end
end
describe "unfollow_hashtag/2" do
test "should unfollow a hashtag" do
user = insert(:user)
hashtag = insert(:hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.followed_hashtags |> Enum.count() == 0
end
test "should not error when trying to unfollow a hashtag twice" do
user = insert(:user)
hashtag = insert(:hashtag)
assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.followed_hashtags |> Enum.count() == 0
end
end
end

View file

@ -867,6 +867,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "fetch activities for followed hashtags" do
test "it should return public activities that reference a given hashtag" do
hashtag = insert(:hashtag, name: "tenshi")
user = insert(:user)
other_user = insert(:user)
{:ok, normally_visible} =
CommonAPI.post(other_user, %{status: "hello :)", visibility: "public"})
{:ok, public} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "public"})
{:ok, _unrelated} = CommonAPI.post(user, %{status: "dai #tensh", visibility: "public"})
{:ok, unlisted} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "unlisted"})
{:ok, _private} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "private"})
activities =
ActivityPub.fetch_activities([other_user.follower_address], %{
followed_hashtags: [hashtag.id]
})
assert length(activities) == 3
normal_id = normally_visible.id
public_id = public.id
unlisted_id = unlisted.id
assert [%{id: ^normal_id}, %{id: ^public_id}, %{id: ^unlisted_id}] = activities
end
end
describe "fetch activities in context" do
test "retrieves activities that have a given context" do
{:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})

View file

@ -187,4 +187,71 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
name: "RE: https://server.example/objects/123"
}
end
describe "Note language" do
test "it detects language from JSON-LD context" do
user = insert(:user)
note_activity = %{
"@context" => ["https://www.w3.org/ns/activitystreams", %{"@language" => "pl"}],
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"type" => "Create",
"object" => %{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"id" => Utils.generate_object_id(),
"type" => "Note",
"content" => "Szczęść Boże",
"attributedTo" => user.ap_id
},
"actor" => user.ap_id
}
{:ok, _create_activity, meta} = ObjectValidator.validate(note_activity, [])
assert meta[:object_data]["language"] == "pl"
end
test "it detects language from contentMap" do
user = insert(:user)
note = %{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"id" => Utils.generate_object_id(),
"type" => "Note",
"content" => "Szczęść Boże",
"contentMap" => %{
"de" => "Gott segne",
"pl" => "Szczęść Boże"
},
"attributedTo" => user.ap_id
}
{:ok, object} = ArticleNotePageValidator.cast_and_apply(note)
assert object.language == "pl"
end
test "it adds contentMap if language is specified" do
user = insert(:user)
note = %{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"id" => Utils.generate_object_id(),
"type" => "Note",
"content" => "тест",
"language" => "uk",
"attributedTo" => user.ap_id
}
{:ok, object} = ArticleNotePageValidator.cast_and_apply(note)
assert object.contentMap == %{
"uk" => "тест"
}
end
end
end

View file

@ -219,6 +219,36 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
"<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
end
test "it only uses contentMap if content is not present" do
user = insert(:user)
message = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"type" => "Create",
"object" => %{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"id" => Utils.generate_object_id(),
"type" => "Note",
"content" => "Hi",
"contentMap" => %{
"de" => "Hallo",
"uk" => "Привіт"
},
"inReplyTo" => nil,
"attributedTo" => user.ap_id
},
"actor" => user.ap_id
}
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(message)
object = Object.normalize(data["object"], fetch: false)
assert object.data["content"] == "Hi"
end
test "it works for incoming notices with a nil contentMap (firefish)" do
data =
File.read!("test/fixtures/mastodon-post-activity-contentmap.json")

View file

@ -384,6 +384,24 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert modified["object"]["quoteUrl"] == quote_id
assert modified["object"]["quoteUri"] == quote_id
end
test "it adds language of the object to its json-ld context" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.object.data)
assert [_, _, %{"@language" => "pl"}] = modified["@context"]
end
test "it adds language of the object to Create activity json-ld context" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
assert [_, _, %{"@language" => "pl"}] = modified["@context"]
end
end
describe "actor rewriting" do
@ -621,5 +639,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
processed = Transmogrifier.prepare_object(original)
assert processed["formerRepresentations"] == original["formerRepresentations"]
end
test "it uses contentMap to specify post language" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"})
object = Transmogrifier.prepare_object(activity.object.data)
assert %{"contentMap" => %{"pl" => "Cześć"}} = object
end
end
end

View file

@ -173,16 +173,30 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
end
end
test "make_json_ld_header/0" do
assert Utils.make_json_ld_header() == %{
"@context" => [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{
"@language" => "und"
}
]
}
describe "make_json_ld_header/1" do
test "makes jsonld header" do
assert Utils.make_json_ld_header() == %{
"@context" => [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{
"@language" => "und"
}
]
}
end
test "includes language if specified" do
assert Utils.make_json_ld_header(%{"language" => "pl"}) == %{
"@context" => [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{
"@language" => "pl"
}
]
}
end
end
describe "get_existing_votes" do

View file

@ -0,0 +1,159 @@
defmodule Pleroma.Web.MastodonAPI.TagControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
import Tesla.Mock
alias Pleroma.User
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
describe "GET /api/v1/tags/:id" do
test "returns 200 with tag" do
%{user: user, conn: conn} = oauth_access(["read"])
tag = insert(:hashtag, name: "jubjub")
{:ok, _user} = User.follow_hashtag(user, tag)
response =
conn
|> get("/api/v1/tags/jubjub")
|> json_response_and_validate_schema(200)
assert %{
"name" => "jubjub",
"url" => "http://localhost:4001/tags/jubjub",
"history" => [],
"following" => true
} = response
end
test "returns 404 with unknown tag" do
%{conn: conn} = oauth_access(["read"])
conn
|> get("/api/v1/tags/jubjub")
|> json_response_and_validate_schema(404)
end
end
describe "POST /api/v1/tags/:id/follow" do
test "should follow a hashtag" do
%{user: user, conn: conn} = oauth_access(["write:follows"])
hashtag = insert(:hashtag, name: "jubjub")
response =
conn
|> post("/api/v1/tags/jubjub/follow")
|> json_response_and_validate_schema(200)
assert response["following"] == true
user = User.get_cached_by_ap_id(user.ap_id)
assert User.following_hashtag?(user, hashtag)
end
test "should 404 if hashtag doesn't exist" do
%{conn: conn} = oauth_access(["write:follows"])
response =
conn
|> post("/api/v1/tags/rubrub/follow")
|> json_response_and_validate_schema(404)
assert response["error"] == "Hashtag not found"
end
end
describe "POST /api/v1/tags/:id/unfollow" do
test "should unfollow a hashtag" do
%{user: user, conn: conn} = oauth_access(["write:follows"])
hashtag = insert(:hashtag, name: "jubjub")
{:ok, user} = User.follow_hashtag(user, hashtag)
response =
conn
|> post("/api/v1/tags/jubjub/unfollow")
|> json_response_and_validate_schema(200)
assert response["following"] == false
user = User.get_cached_by_ap_id(user.ap_id)
refute User.following_hashtag?(user, hashtag)
end
test "should 404 if hashtag doesn't exist" do
%{conn: conn} = oauth_access(["write:follows"])
response =
conn
|> post("/api/v1/tags/rubrub/unfollow")
|> json_response_and_validate_schema(404)
assert response["error"] == "Hashtag not found"
end
end
describe "GET /api/v1/followed_tags" do
test "should list followed tags" do
%{user: user, conn: conn} = oauth_access(["read:follows"])
response =
conn
|> get("/api/v1/followed_tags")
|> json_response_and_validate_schema(200)
assert Enum.empty?(response)
hashtag = insert(:hashtag, name: "jubjub")
{:ok, _user} = User.follow_hashtag(user, hashtag)
response =
conn
|> get("/api/v1/followed_tags")
|> json_response_and_validate_schema(200)
assert [%{"name" => "jubjub"}] = response
end
test "should include a link header to paginate" do
%{user: user, conn: conn} = oauth_access(["read:follows"])
for i <- 1..21 do
hashtag = insert(:hashtag, name: "jubjub#{i}}")
{:ok, _user} = User.follow_hashtag(user, hashtag)
end
response =
conn
|> get("/api/v1/followed_tags")
json = json_response_and_validate_schema(response, 200)
assert Enum.count(json) == 20
assert [link_header] = get_resp_header(response, "link")
assert link_header =~ "rel=\"next\""
next_link = extract_next_link_header(link_header)
response =
conn
|> get(next_link)
|> json_response_and_validate_schema(200)
assert Enum.count(response) == 1
end
test "should refuse access without read:follows scope" do
%{conn: conn} = oauth_access(["write"])
conn
|> get("/api/v1/followed_tags")
|> json_response_and_validate_schema(403)
end
end
defp extract_next_link_header(header) do
[_, next_link] = Regex.run(~r{<(?<next_link>.*)>; rel="next"}, header)
next_link
end
end

View file

@ -951,6 +951,26 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert status.edited_at
end
test "it shows post language" do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "Szczęść Boże", language: "pl"})
status = StatusView.render("show.json", activity: post)
assert status.language == "pl"
end
test "doesn't show post language if it's 'und'" do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "sdifjogijodfg", language: "und"})
status = StatusView.render("show.json", activity: post)
assert status.language == nil
end
test "with a source object" do
note =
insert(:note,

View file

@ -558,6 +558,36 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:render_with_user, _, "status_update.json", ^create, _}
refute Streamer.filtered_by_user?(user, edited)
end
test "it streams posts containing followed hashtags on the 'user' stream", %{
user: user,
token: oauth_token
} do
hashtag = insert(:hashtag, %{name: "tenshi"})
other_user = insert(:user)
{:ok, user} = User.follow_hashtag(user, hashtag)
Streamer.get_topic_and_add_socket("user", user, oauth_token)
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey #tenshi"})
assert_receive {:render_with_user, _, "update.json", ^activity, _}
end
test "should not stream private posts containing followed hashtags on the 'user' stream", %{
user: user,
token: oauth_token
} do
hashtag = insert(:hashtag, %{name: "tenshi"})
other_user = insert(:user)
{:ok, user} = User.follow_hashtag(user, hashtag)
Streamer.get_topic_and_add_socket("user", user, oauth_token)
{:ok, activity} =
CommonAPI.post(other_user, %{status: "hey #tenshi", visibility: "private"})
refute_receive {:render_with_user, _, "update.json", ^activity, _}
end
end
describe "public streams" do

View file

@ -668,4 +668,11 @@ defmodule Pleroma.Factory do
|> Map.merge(params)
|> Pleroma.Announcement.add_rendered_properties()
end
def hashtag_factory(params \\ %{}) do
%Pleroma.Hashtag{
name: "test #{sequence(:hashtag_name, & &1)}"
}
|> Map.merge(params)
end
end