List and add ratings
This commit is contained in:
parent
40eb1ca7a8
commit
a3963d093e
8 changed files with 172 additions and 3 deletions
62
src/Controller/Api/RatingController.php
Normal file
62
src/Controller/Api/RatingController.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Api;
|
||||
|
||||
use App\Entity\Rating;
|
||||
use App\Entity\Restaurant;
|
||||
use App\Repository\RatingRepository;
|
||||
use App\Repository\SubjectRepository;
|
||||
use App\Services\OutputService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class RatingController extends AbstractController
|
||||
{
|
||||
#[Route('/api/ratings', methods: ['GET'])]
|
||||
public function index(
|
||||
RatingRepository $repo,
|
||||
OutputService $output,
|
||||
): JsonResponse {
|
||||
return $this->json($output->success([
|
||||
'ratings' => array_map(
|
||||
fn(Rating $rating) => [
|
||||
'id' => $rating->getId(),
|
||||
'score' => $rating->getScore(),
|
||||
'subject' => [
|
||||
'id' => $rating->getSubject()->getId(),
|
||||
'name' => $rating->getSubject()->getName(),
|
||||
],
|
||||
],
|
||||
$repo->findAll()
|
||||
),
|
||||
]));
|
||||
}
|
||||
|
||||
#[Route('/api/ratings', methods: ['POST'])]
|
||||
public function create(
|
||||
Request $request,
|
||||
EntityManagerInterface $em,
|
||||
OutputService $output,
|
||||
SubjectRepository $subjectRepository,
|
||||
): JsonResponse {
|
||||
$subject = $subjectRepository->findById($request->getPayload()->get('subject_id'));
|
||||
|
||||
if ($subject === null) {
|
||||
return $this->json(
|
||||
$output->error(["UNKNOWN_SUBJECT"])
|
||||
);
|
||||
}
|
||||
|
||||
$rating = new Rating();
|
||||
$rating->setSubject($subject);
|
||||
$rating->setScore($request->getPayload()->get('score'));
|
||||
|
||||
$em->persist($rating);
|
||||
$em->flush();
|
||||
|
||||
return $this->json(null, 201);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ abstract class Subject
|
|||
/**
|
||||
* @var Collection<int, Rating>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Rating::class, mappedBy: 'subject_id', orphanRemoval: true)]
|
||||
#[ORM\OneToMany(targetEntity: Rating::class, mappedBy: 'subject', orphanRemoval: true)]
|
||||
private Collection $ratings;
|
||||
|
||||
public function __construct()
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ final class RatingFactory extends PersistentObjectFactory
|
|||
protected function defaults(): array|callable
|
||||
{
|
||||
return [
|
||||
'subject_id' => SubjectFactory::new(),
|
||||
'subject' => SubjectFactory::new(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ final class SubjectFactory extends PersistentObjectFactory
|
|||
protected function defaults(): array|callable
|
||||
{
|
||||
return [
|
||||
'name' => self::faker()->text(255),
|
||||
'name' => self::faker()->text(10),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Rating;
|
||||
use App\Entity\Subject;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
|
|
@ -16,6 +17,24 @@ class RatingRepository extends ServiceEntityRepository
|
|||
parent::__construct($registry, Rating::class);
|
||||
}
|
||||
|
||||
public function findById(int $id): ?Rating
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
->where('r.id = :id')
|
||||
->setParameter('id', $id)
|
||||
->getQuery()
|
||||
->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function findAllBySubject(Subject $subject): array
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
->where('r.subject = :subject')
|
||||
->setParameter('subject', $subject)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Rating[] Returns an array of Rating objects
|
||||
// */
|
||||
|
|
|
|||
|
|
@ -16,6 +16,15 @@ class SubjectRepository extends ServiceEntityRepository
|
|||
parent::__construct($registry, Subject::class);
|
||||
}
|
||||
|
||||
public function findById(int $id): ?Subject
|
||||
{
|
||||
return $this->createQueryBuilder('s')
|
||||
->where('s.id = :id')
|
||||
->setParameter('id', $id)
|
||||
->getQuery()
|
||||
->getOneOrNullResult();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Subject[] Returns an array of Subject objects
|
||||
// */
|
||||
|
|
|
|||
79
tests/Application/Controller/Api/RatingControllerTest.php
Normal file
79
tests/Application/Controller/Api/RatingControllerTest.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Tests\Unit\Controller\Api;
|
||||
|
||||
use App\Entity\Rating;
|
||||
use App\Entity\Restaurant;
|
||||
use App\Factory\RatingFactory;
|
||||
use App\Factory\RestaurantFactory;
|
||||
use App\Factory\UserFactory;
|
||||
use App\Repository\RatingRepository;
|
||||
use App\Repository\SubjectRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
class RatingControllerTest extends WebTestCase
|
||||
{
|
||||
public function testList(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
$user = UserFactory::createOne();
|
||||
$client->loginUser($user);
|
||||
|
||||
$subject = RestaurantFactory::createOne([
|
||||
'createdBy' => $user,
|
||||
]);
|
||||
|
||||
$ratings = RatingFactory::createMany(5, [
|
||||
'subject' => $subject,
|
||||
]);
|
||||
|
||||
$client->request(
|
||||
'GET',
|
||||
'/api/ratings',
|
||||
server: ['CONTENT_TYPE' => 'application/json'],
|
||||
content: json_encode(['name' => 'Riviera']),
|
||||
);
|
||||
|
||||
$data = json_decode($client->getResponse()->getContent(), true);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
$this->assertCount(5, $data['payload']['ratings']);
|
||||
}
|
||||
|
||||
public function testCreate(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
$repo = static::getContainer()->get(RatingRepository::class);
|
||||
|
||||
$user = UserFactory::createOne();
|
||||
$client->loginUser($user);
|
||||
|
||||
$subject = RestaurantFactory::createOne([
|
||||
'createdBy' => $user,
|
||||
]);
|
||||
|
||||
$client->request(
|
||||
'POST',
|
||||
'/api/ratings',
|
||||
server: ['CONTENT_TYPE' => 'application/json'],
|
||||
content: json_encode([
|
||||
'subject_id' => $subject->getId(),
|
||||
'score' => 8,
|
||||
]),
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
$this->assertResponseStatusCodeSame(201);
|
||||
$this->assertCount(1, $repo->findAll());
|
||||
|
||||
$ratings = static::getContainer()
|
||||
->get(RatingRepository::class)
|
||||
->findAllBySubject($subject);
|
||||
|
||||
$this->assertNotNull($ratings);
|
||||
$this->assertCount(1, $ratings);
|
||||
$this->assertInstanceOf(Rating::class, $ratings[0]);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue