# Pleroma: A lightweight social networking server # Copyright © 2017-2022 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do use Pleroma.DataCase require Pleroma.Constants alias Pleroma.Constants alias Pleroma.Object alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent alias Pleroma.Web.CommonAPI import Pleroma.Factory test "adds mentions to post content" do [lain, coolboymew, dielan, hakui, fence] = [ insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain@lain.com", local: false), insert(:user, ap_id: "https://shitposter.club/users/coolboymew", nickname: "coolboymew@shitposter.club", local: false ), insert(:user, ap_id: "https://shitposter.club/users/dielan", nickname: "dielan@shitposter.club", local: false ), insert(:user, ap_id: "https://tuusin.misono-ya.info/users/hakui", nickname: "hakui@tuusin.misono-ya.info", local: false ), insert(:user, ap_id: "https://xyzzy.link/users/fence", nickname: "fence@xyzzy.link", local: false ) ] object = File.read!("test/fixtures/soapbox_no_mentions_in_content.json") |> Jason.decode!() activity = %{ "type" => "Create", "actor" => "https://gleasonator.com/users/alex", "object" => object } {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == "

@dielan @coolboymew @fence @hakui @lain Haha yeah, you can control who you reply to.

" end test "the replied-to user is sorted to the left" do [mario, luigi, wario] = [ insert(:user, nickname: "mario"), insert(:user, nickname: "luigi"), insert(:user, nickname: "wario") ] {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"}) {:ok, post2} = CommonAPI.post(luigi, %{status: "Oh yaah", in_reply_to_id: post1.id, to: [mario.ap_id]}) activity = %{ "type" => "Create", "actor" => wario.ap_id, "object" => %{ "type" => "Note", "actor" => wario.ap_id, "content" => "WHA-HA!", "to" => [ mario.ap_id, luigi.ap_id, Constants.as_public() ], "inReplyTo" => Object.normalize(post2).data["id"] } } {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == "@luigi @mario WHA-HA!" end test "don't mention self" do mario = insert(:user, nickname: "mario") {:ok, post} = CommonAPI.post(mario, %{status: "Mama mia"}) activity = %{ "type" => "Create", "actor" => mario.ap_id, "object" => %{ "type" => "Note", "actor" => mario.ap_id, "content" => "I'ma tired...", "to" => [ mario.ap_id, Constants.as_public() ], "inReplyTo" => Object.normalize(post).data["id"] } } {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == "I'ma tired..." end test "don't mention in top-level posts" do mario = insert(:user, nickname: "mario") luigi = insert(:user, nickname: "luigi") {:ok, post} = CommonAPI.post(mario, %{status: "Letsa go"}) activity = %{ "type" => "Create", "actor" => mario.ap_id, "object" => %{ "type" => "Note", "actor" => mario.ap_id, "content" => "Mama mia!", "to" => [ luigi.ap_id, Constants.as_public() ], "quoteUrl" => Object.normalize(post).data["id"] } } {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == "Mama mia!" end test "with markdown formatting" do mario = insert(:user, nickname: "mario") luigi = insert(:user, nickname: "luigi") {:ok, post} = CommonAPI.post(luigi, %{status: "Mama mia"}) activity = %{ "type" => "Create", "actor" => mario.ap_id, "object" => %{ "type" => "Note", "actor" => mario.ap_id, "content" => "

I'ma tired...

", "to" => [ luigi.ap_id, Constants.as_public() ], "inReplyTo" => Object.normalize(post).data["id"] } } {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == "

@luigi I'ma tired...

" end test "aware of history" do mario = insert(:user, nickname: "mario") wario = insert(:user, nickname: "wario") {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"}) activity = %{ "type" => "Create", "actor" => wario.ap_id, "object" => %{ "type" => "Note", "actor" => wario.ap_id, "content" => "WHA-HA!", "to" => [ mario.ap_id, Constants.as_public() ], "inReplyTo" => post1.object.data["id"], "formerRepresentations" => %{ "orderedItems" => [ %{ "type" => "Note", "actor" => wario.ap_id, "content" => "WHA-HA!", "to" => [ mario.ap_id, Constants.as_public() ], "inReplyTo" => post1.object.data["id"] } ] } } } expected = "@mario WHA-HA!" assert {:ok, %{ "object" => %{ "content" => ^expected, "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]} } }} = MRF.filter_one(ForceMentionsInContent, activity) end test "works with Updates" do mario = insert(:user, nickname: "mario") wario = insert(:user, nickname: "wario") {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"}) activity = %{ "type" => "Update", "actor" => wario.ap_id, "object" => %{ "type" => "Note", "actor" => wario.ap_id, "content" => "WHA-HA!", "to" => [ mario.ap_id, Constants.as_public() ], "inReplyTo" => post1.object.data["id"], "formerRepresentations" => %{ "orderedItems" => [ %{ "type" => "Note", "actor" => wario.ap_id, "content" => "WHA-HA!", "to" => [ mario.ap_id, Constants.as_public() ], "inReplyTo" => post1.object.data["id"] } ] } } } expected = "@mario WHA-HA!" assert {:ok, %{ "object" => %{ "content" => ^expected, "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]} } }} = MRF.filter_one(ForceMentionsInContent, activity) end end