From 9cf5e1a77a04f7a9f8b3dc8ff1c04355235d6de4 Mon Sep 17 00:00:00 2001 From: BentiGorlich Date: Mon, 13 Jan 2025 19:09:44 +0000 Subject: [PATCH] Add test case for liking a hashtag matched post (#1364) --- .../Outbox/AnnounceLikeHandler.php | 9 ++- tests/Unit/ActivityPub/TagMatchTest.php | 61 +++++++++++++++++-- tests/WebTestCase.php | 3 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/MessageHandler/ActivityPub/Outbox/AnnounceLikeHandler.php b/src/MessageHandler/ActivityPub/Outbox/AnnounceLikeHandler.php index ac532971f..667f0c97e 100644 --- a/src/MessageHandler/ActivityPub/Outbox/AnnounceLikeHandler.php +++ b/src/MessageHandler/ActivityPub/Outbox/AnnounceLikeHandler.php @@ -85,11 +85,10 @@ public function doWork(MessageInterface $message): void $likeActivity ); - $inboxes = array_filter(array_unique(array_merge( - $this->magazineRepository->findAudience($object->magazine), - $this->userRepository->findAudience($user), - [$object->user->apInboxUrl] - ))); + // send the announcement only to the subscribers of the magazine + $inboxes = array_filter( + $this->magazineRepository->findAudience($object->magazine) + ); $this->deliverManager->deliver($inboxes, $activity); } } diff --git a/tests/Unit/ActivityPub/TagMatchTest.php b/tests/Unit/ActivityPub/TagMatchTest.php index b4e764cfb..34ba714ba 100644 --- a/tests/Unit/ActivityPub/TagMatchTest.php +++ b/tests/Unit/ActivityPub/TagMatchTest.php @@ -5,8 +5,11 @@ namespace App\Tests\Unit\ActivityPub; use App\ActivityPub\JsonRd; +use App\Entity\Magazine; +use App\Entity\User; use App\Event\ActivityPub\WebfingerResponseEvent; use App\Message\ActivityPub\Inbox\CreateMessage; +use App\Message\ActivityPub\Inbox\LikeMessage; use App\Service\ActivityPub\Webfinger\WebFingerFactory; use App\Tests\WebTestCase; use Doctrine\Common\Collections\ArrayCollection; @@ -26,8 +29,10 @@ class TagMatchTest extends WebTestCase 'mbin10.tld', ]; + /** @var User[] */ private array $remoteUsers = []; + /** @var Magazine[] */ private array $remoteMagazines = []; /** @@ -123,19 +128,63 @@ public function testMatching(): void self::assertEquals(\sizeof($this->domains), \sizeof(array_filter($this->remoteMagazines))); self::assertEquals(\sizeof($this->domains), \sizeof(array_filter($this->remoteUsers))); - // pull in the 10 prepared remote entries + $this->pullInRemoteEntries(); + $this->pullInMastodonPost(); + + $postedObjects = $this->testingApHttpClient->getPostedObjects(); + $postedAnnounces = array_filter($postedObjects, fn ($item) => 'Announce' === $item['payload']['type']); + $targetInboxes = array_map(fn ($item) => parse_url($item['inboxUrl'], PHP_URL_HOST), $postedAnnounces); + sort($targetInboxes); + self::assertArrayIsEqualToArrayIgnoringListOfKeys($this->domains, $targetInboxes, []); + } + + public function testMatchingLikeAnnouncing(): void + { + self::assertEquals(\sizeof($this->domains), \sizeof(array_filter($this->remoteMagazines))); + self::assertEquals(\sizeof($this->domains), \sizeof(array_filter($this->remoteUsers))); + + $this->pullInRemoteEntries(); + $this->pullInMastodonPost(); + + $mastodonPost = $this->postRepository->findOneBy(['apId' => $this->mastodonPost['id']]); + $user = $this->getUserByUsername('user'); + $this->favouriteManager->toggle($user, $mastodonPost); + + $postedObjects = $this->testingApHttpClient->getPostedObjects(); + $postedLikes = array_filter($postedObjects, fn ($item) => 'Like' === $item['payload']['type']); + $targetInboxes2 = array_map(fn ($item) => parse_url($item['inboxUrl'], PHP_URL_HOST), $postedLikes); + sort($targetInboxes2); + + // the pure like activity is expected to be sent to the author of the post + $expectedInboxes = [...$this->domains, parse_url($mastodonPost->user->apInboxUrl, PHP_URL_HOST)]; + sort($expectedInboxes); + self::assertArrayIsEqualToArrayIgnoringListOfKeys($expectedInboxes, $targetInboxes2, []); + + // dispatch a remote like message, so we trigger the announcement of it + $this->bus->dispatch(new LikeMessage($this->likeWrapper->build($this->remoteUsers[0]->apProfileId, $this->mastodonPost))); + + $postedObjects = $this->testingApHttpClient->getPostedObjects(); + $postedLikeAnnounces = array_filter($postedObjects, fn ($item) => 'Announce' === $item['payload']['type'] && 'Like' === $item['payload']['object']['type']); + $targetInboxes3 = array_map(fn ($item) => parse_url($item['inboxUrl'], PHP_URL_HOST), $postedLikeAnnounces); + sort($targetInboxes3); + + // the announcement of the like is expected to be delivered only to the subscribers of the magazine, + // because we expect the pure like activity to already be sent to the author of the post by the remote server + self::assertArrayIsEqualToArrayIgnoringListOfKeys($this->domains, $targetInboxes3, []); + } + + private function pullInRemoteEntries(): void + { foreach (array_filter($this->testingApHttpClient->activityObjects, fn ($item) => 'Page' === $item['type']) as $apObject) { $this->bus->dispatch(new CreateMessage($apObject)); $entry = $this->entryRepository->findOneBy(['apId' => $apObject['id']]); self::assertNotNull($entry); } + } + private function pullInMastodonPost(): void + { $this->bus->dispatch(new CreateMessage($this->mastodonPost)); - $postedObjects = $this->testingApHttpClient->getPostedObjects(); - $postedAnnounces = array_filter($postedObjects, fn ($item) => 'Announce' === $item['payload']['type']); - $targetInboxes = array_map(fn ($item) => parse_url($item['inboxUrl'], PHP_URL_HOST), $postedAnnounces); - sort($targetInboxes); - self::assertArrayIsEqualToArrayIgnoringListOfKeys($this->domains, $targetInboxes, []); } private array $mastodonUser = [ diff --git a/tests/WebTestCase.php b/tests/WebTestCase.php index 958b0da51..cc86ea738 100644 --- a/tests/WebTestCase.php +++ b/tests/WebTestCase.php @@ -26,6 +26,7 @@ use App\Repository\UserRepository; use App\Service\ActivityPub\ApHttpClientInterface; use App\Service\ActivityPub\Wrapper\CreateWrapper; +use App\Service\ActivityPub\Wrapper\LikeWrapper; use App\Service\ActivityPubManager; use App\Service\BadgeManager; use App\Service\DomainManager; @@ -130,6 +131,7 @@ abstract class WebTestCase extends BaseWebTestCase protected TestingApHttpClient $testingApHttpClient; protected CreateWrapper $createWrapper; + protected LikeWrapper $likeWrapper; protected UrlGeneratorInterface $urlGenerator; protected TranslatorInterface $translator; @@ -194,6 +196,7 @@ public function setUp(): void $this->pageFactory = $this->getService(EntryPageFactory::class); $this->createWrapper = $this->getService(CreateWrapper::class); + $this->likeWrapper = $this->getService(LikeWrapper::class); $this->urlGenerator = $this->getService(UrlGeneratorInterface::class); $this->translator = $this->getService(TranslatorInterface::class);