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>
|
* @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;
|
private Collection $ratings;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ final class RatingFactory extends PersistentObjectFactory
|
||||||
protected function defaults(): array|callable
|
protected function defaults(): array|callable
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'subject_id' => SubjectFactory::new(),
|
'subject' => SubjectFactory::new(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ final class SubjectFactory extends PersistentObjectFactory
|
||||||
protected function defaults(): array|callable
|
protected function defaults(): array|callable
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => self::faker()->text(255),
|
'name' => self::faker()->text(10),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\Rating;
|
use App\Entity\Rating;
|
||||||
|
use App\Entity\Subject;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
|
@ -16,6 +17,24 @@ class RatingRepository extends ServiceEntityRepository
|
||||||
parent::__construct($registry, Rating::class);
|
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
|
// * @return Rating[] Returns an array of Rating objects
|
||||||
// */
|
// */
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@ class SubjectRepository extends ServiceEntityRepository
|
||||||
parent::__construct($registry, Subject::class);
|
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
|
// * @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