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())); } }