TIDE/backend/tests/Unit/Comment/UseCases/DeleteCommentTest.php

131 lines
3.6 KiB
PHP

<?php
namespace Tests\Unit\Comment\UseCases;
use App\Comment\Comment;
use App\Comment\CreateCommentDto;
use App\Comment\UseCases\DeleteComment\DeleteComment;
use App\Comment\UseCases\DeleteComment\DeleteCommentRequest;
use App\Exceptions\BadRequestException;
use App\Exceptions\ForbiddenException;
use DateTimeImmutable;
use DateTimeZone;
use Tests\Fakes\FakeCommentRepository;
use Tests\TestCase;
class DeleteCommentTest extends TestCase
{
private FakeCommentRepository $commentRepo;
private DateTimeImmutable $now;
private DeleteComment $useCase;
protected function setUp(): void
{
$this->now = new DateTimeImmutable(
'2026-05-06T12:00:00',
new DateTimeZone('UTC'),
);
$this->commentRepo = new FakeCommentRepository;
$this->useCase = new DeleteComment($this->commentRepo);
}
private function seedCommentByUser(int $userId): Comment
{
return $this->commentRepo->create(new CreateCommentDto(
postId: 1,
userId: $userId,
body: 'comment body',
createdAt: $this->now,
));
}
public function test_zero_comment_id_throws_bad_request(): void
{
$this->expectException(BadRequestException::class);
$this->useCase->execute(new DeleteCommentRequest(
commentId: 0,
requesterId: 1,
requesterIsAdmin: false,
));
}
public function test_zero_requester_id_throws_bad_request(): void
{
$comment = $this->seedCommentByUser(1);
$this->expectException(BadRequestException::class);
$this->useCase->execute(new DeleteCommentRequest(
commentId: $comment->getId(),
requesterId: 0,
requesterIsAdmin: false,
));
}
public function test_unknown_comment_is_no_op(): void
{
$this->useCase->execute(new DeleteCommentRequest(
commentId: 999,
requesterId: 1,
requesterIsAdmin: false,
));
$this->assertNull($this->commentRepo->find(999));
}
public function test_author_can_delete_own_comment(): void
{
$comment = $this->seedCommentByUser(1);
$this->useCase->execute(new DeleteCommentRequest(
commentId: $comment->getId(),
requesterId: 1,
requesterIsAdmin: false,
));
$this->assertNull($this->commentRepo->find($comment->getId()));
}
public function test_admin_can_delete_anyones_comment(): void
{
$comment = $this->seedCommentByUser(1);
$this->useCase->execute(new DeleteCommentRequest(
commentId: $comment->getId(),
requesterId: 99,
requesterIsAdmin: true,
));
$this->assertNull($this->commentRepo->find($comment->getId()));
}
public function test_other_user_cannot_delete_comment(): void
{
$comment = $this->seedCommentByUser(1);
$this->expectException(ForbiddenException::class);
$this->useCase->execute(new DeleteCommentRequest(
commentId: $comment->getId(),
requesterId: 2,
requesterIsAdmin: false,
));
}
public function test_forbidden_delete_does_not_remove_comment(): void
{
$comment = $this->seedCommentByUser(1);
try {
$this->useCase->execute(new DeleteCommentRequest(
commentId: $comment->getId(),
requesterId: 2,
requesterIsAdmin: false,
));
} catch (ForbiddenException) {
// expected
}
$this->assertNotNull($this->commentRepo->find($comment->getId()));
}
}