mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
bootstrap api and apply on accompanying period
This commit is contained in:
@@ -8,33 +8,51 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
|
||||
class AccompanyingCourseApiController extends ApiController
|
||||
{
|
||||
public function participationApi($accompanyingPeriodId, Request $request)
|
||||
protected EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
protected ValidatorInterface $validator;
|
||||
|
||||
public function __construct(EventDispatcherInterface $eventDispatcher, $validator)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
public function participationApi($id, Request $request, $_format)
|
||||
{
|
||||
/** @var AccompanyingPeriod $accompanyingPeriod */
|
||||
$accompanyingPeriod = $this->getEntity($accompanyingPeriodId);
|
||||
$person = $this->serializer->deserialize($request->getContent(), Person::class, $_format, []);
|
||||
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
|
||||
$person = $this->getSerializer()
|
||||
->deserialize($request->getContent(), Person::class, $_format, []);
|
||||
|
||||
if (NULL === $person) {
|
||||
throw new BadRequestException('person id not found');
|
||||
}
|
||||
|
||||
// TODO add acl
|
||||
//
|
||||
$this->onPostCheckACL('participation', $request, $accompanyingPeriod, $_format);
|
||||
|
||||
switch ($request->getMethod()) {
|
||||
case Request::METHOD_POST:
|
||||
$participation = $accompanyingCours->addPerson($person);
|
||||
$participation = $accompanyingPeriod->addPerson($person);
|
||||
break;
|
||||
case Request::METHOD_DELETE:
|
||||
$participation = $accompanyingCours->removePerson($person);
|
||||
$participation = $accompanyingPeriod->removePerson($person);
|
||||
$participation->setEndDate(new \DateTimeImmutable('now'));
|
||||
break;
|
||||
default:
|
||||
throw new BadRequestException("This method is not supported");
|
||||
}
|
||||
|
||||
$errors = $this->validator->validate($accompanyingCourse);
|
||||
$errors = $this->validator->validate($accompanyingPeriod);
|
||||
|
||||
if ($errors->count() > 0) {
|
||||
// only format accepted
|
||||
@@ -44,5 +62,18 @@ class AccompanyingCourseApiController extends ApiController
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
return $this->json($participation);
|
||||
}
|
||||
}
|
||||
|
||||
protected function onPostCheckACL(string $action, Request $request, $entity, $_format): ?Response
|
||||
{
|
||||
$this->eventDispatcher->dispatch(
|
||||
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
|
||||
new AccompanyingPeriodPrivacyEvent($entity, [
|
||||
'action' => $action,
|
||||
'request' => $request->getMethod()
|
||||
])
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ use Doctrine\Persistence\ObjectManager;
|
||||
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
|
||||
use Chill\MainBundle\Entity\RoleScope;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
|
||||
/**
|
||||
* Add a role CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE for all groups except administrative,
|
||||
@@ -44,6 +45,7 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
|
||||
{
|
||||
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
||||
$permissionsGroup = $this->getReference($permissionsGroupRef);
|
||||
$scopeSocial = $this->getReference('scope_social');
|
||||
|
||||
//create permission group
|
||||
switch ($permissionsGroup->getName()) {
|
||||
@@ -51,6 +53,12 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
|
||||
case 'direction':
|
||||
printf("Adding CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE to %s permission group \n", $permissionsGroup->getName());
|
||||
|
||||
$permissionsGroup->addRoleScope(
|
||||
(new RoleScope())
|
||||
->setRole(AccompanyingPeriodVoter::SEE)
|
||||
->setScope($scopeSocial)
|
||||
);
|
||||
|
||||
$roleScopeUpdate = (new RoleScope())
|
||||
->setRole('CHILL_PERSON_UPDATE')
|
||||
->setScope(null);
|
||||
|
@@ -315,7 +315,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
[
|
||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
||||
'name' => 'accompanying_course',
|
||||
'base_path' => '/api/1.0/accompanying_course',
|
||||
'base_path' => '/api/1.0/person/accompanying-course',
|
||||
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
|
||||
'actions' => [
|
||||
'_entity' => [
|
||||
@@ -323,7 +323,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
||||
]
|
||||
],
|
||||
'/participation' => [
|
||||
'participation' => [
|
||||
'methods' => [
|
||||
Request::METHOD_POST => true,
|
||||
Request::METHOD_DELETE => true,
|
||||
|
@@ -118,7 +118,7 @@ class AccompanyingPeriod
|
||||
*
|
||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
||||
* mappedBy="accompanyingPeriod",
|
||||
* cascade={"persist", "remove", "merge", "detach"})
|
||||
* cascade={"persist", "refresh", "remove", "merge", "detach"})
|
||||
*/
|
||||
private $participations;
|
||||
|
||||
@@ -348,7 +348,7 @@ class AccompanyingPeriod
|
||||
*/
|
||||
public function getParticipationsContainsPerson(Person $person): Collection
|
||||
{
|
||||
return $this->getParticipations()->filter(
|
||||
return $this->getParticipations($person)->filter(
|
||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
||||
if ($person === $participation->getPerson()) {
|
||||
return $participation;
|
||||
@@ -361,11 +361,11 @@ class AccompanyingPeriod
|
||||
*
|
||||
* "Open" means that the closed date is NULL
|
||||
*/
|
||||
public function getOpenParticipationsContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
||||
public function getOpenParticipationContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
||||
{
|
||||
$collection = $this->getParticipationsContainsPerson()->filter(
|
||||
$collection = $this->getParticipationsContainsPerson($person)->filter(
|
||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
||||
if (NULL === $participation->getClosingDate()) {
|
||||
if (NULL === $participation->getEndDate()) {
|
||||
return $participation;
|
||||
}
|
||||
});
|
||||
@@ -380,7 +380,7 @@ class AccompanyingPeriod
|
||||
*/
|
||||
public function containsPerson(Person $person): bool
|
||||
{
|
||||
return $this->participationsContainsPerson($person)->count() > 0;
|
||||
return $this->getParticipationsContainsPerson($person)->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -38,7 +38,7 @@ class AccompanyingPeriodNormalizer implements NormalizerInterface, NormalizerAwa
|
||||
'remark' => $period->getRemark(),
|
||||
'participations' => $this->normalizer->normalize($period->getParticipations(), $format),
|
||||
'closingMotive' => $this->normalizer->normalize($period->getClosingMotive(), $format),
|
||||
'user' => $period->getUser() ? $this->normalize($period->getUser(), $format) : null,
|
||||
'user' => $period->getUser() ? $this->normalizer->normalize($period->getUser(), $format) : null,
|
||||
'step' => $period->getStep(),
|
||||
'origin' => $this->normalizer->normalize($period->getOrigin(), $format),
|
||||
'intensity' => $period->getIntensity(),
|
||||
|
@@ -55,7 +55,7 @@ class PersonNormalizer implements
|
||||
'id' => $person->getId(),
|
||||
'firstName' => $person->getFirstName(),
|
||||
'lastName' => $person->getLastName(),
|
||||
'birthdate' => $person->getBirthdate(),
|
||||
'birthdate' => $this->normalizer->normalize($person->getBirthdate()),
|
||||
'center' => $this->normalizer->normalize($person->getCenter())
|
||||
];
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
/**
|
||||
* Test api for AccompanyingCourseControllerTest
|
||||
*/
|
||||
class AccompanyingCourseControllerTest extends WebTestCase
|
||||
class AccompanyingCourseApiControllerTest extends WebTestCase
|
||||
{
|
||||
protected static EntityManagerInterface $em;
|
||||
|
||||
@@ -65,7 +65,7 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
*/
|
||||
public function testAccompanyingCourseShow(int $personId, AccompanyingPeriod $period)
|
||||
{
|
||||
$this->client->request(Request::METHOD_GET, sprintf('/fr/person/api/1.0/accompanying-course/%d/show.json', $period->getId()));
|
||||
$c = $this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()));
|
||||
$response = $this->client->getResponse();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||
@@ -77,6 +77,14 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
$this->assertGreaterThan(0, $data->participations);
|
||||
}
|
||||
|
||||
public function testShow404()
|
||||
{
|
||||
$this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', 99999));
|
||||
$response = $this->client->getResponse();
|
||||
|
||||
$this->assertEquals(404, $response->getStatusCode(), "Test that the response of rest api has a status code 'not found' (404)");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @dataProvider dataGenerateRandomAccompanyingCourse
|
||||
@@ -85,26 +93,55 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
{
|
||||
$this->client->request(
|
||||
Request::METHOD_POST,
|
||||
sprintf('/fr/person/api/1.0/accompanying-course/%d/participation.json', $period->getId()),
|
||||
sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $period->getId()),
|
||||
[], // parameters
|
||||
[], // files
|
||||
[], // server parameters
|
||||
\json_encode([ 'id' => $personId ])
|
||||
);
|
||||
$response = $this->client->getResponse();
|
||||
$data = \json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||
$this->client->request(Request::METHOD_GET, sprintf('/fr/person/api/1.0/accompanying-course/%d/show.json', $period->getId()));
|
||||
$this->assertArrayHasKey('id', $data);
|
||||
$this->assertArrayHasKey('startDate', $data);
|
||||
$this->assertNotNull($data['startDate']);
|
||||
|
||||
// check by deownloading the accompanying cours
|
||||
|
||||
$this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()));
|
||||
|
||||
$response = $this->client->getResponse();
|
||||
$data = \json_decode($response->getContent());
|
||||
|
||||
// check that the person id is contained
|
||||
$participationsPersonsIds = \array_map(
|
||||
function($participation) { return $participation->person->id; },
|
||||
$data->participations);
|
||||
|
||||
$this->assertContains($personId, $participationsPersonsIds);
|
||||
|
||||
// check removing the participation
|
||||
$this->client->request(
|
||||
Request::METHOD_DELETE,
|
||||
sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $period->getId()),
|
||||
[], // parameters
|
||||
[], // files
|
||||
[], // server parameters
|
||||
\json_encode([ 'id' => $personId ])
|
||||
);
|
||||
$response = $this->client->getResponse();
|
||||
$data = \json_decode($response->getContent(), true);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||
$this->assertArrayHasKey('id', $data);
|
||||
$this->assertArrayHasKey('startDate', $data);
|
||||
$this->assertNotNull($data['startDate']);
|
||||
$this->assertArrayHasKey('endDate', $data);
|
||||
$this->assertNotNull($data['endDate']);
|
||||
|
||||
|
||||
// set to variable for tear down
|
||||
$this->personId = $personId;
|
||||
$this->period = $period;
|
||||
}
|
||||
@@ -112,6 +149,7 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
protected function tearDown()
|
||||
{
|
||||
// remove participation created during test 'testAccompanyingCourseAddParticipation'
|
||||
// and if the test could not remove it
|
||||
|
||||
$testAddParticipationName = 'testAccompanyingCourseAddParticipation';
|
||||
|
||||
@@ -126,8 +164,10 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
->findOneBy(['person' => $this->personId, 'accompanyingPeriod' => $this->period])
|
||||
;
|
||||
|
||||
$em->remove($participation);
|
||||
$em->flush();
|
||||
if (NULL !== $participation) {
|
||||
$em->remove($participation);
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function dataGenerateRandomAccompanyingCourse()
|
||||
@@ -139,9 +179,9 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
||||
// * one for getting the person, which will in turn provide his accompanying period;
|
||||
// * one for getting the personId to populate to the data manager
|
||||
//
|
||||
// Ensure to keep always $maxGenerated to the double of $maxResults
|
||||
$maxGenerated = 1;
|
||||
$maxResults = 15 * 8;
|
||||
// Ensure to keep always $maxGenerated to the double of $maxResults. x8 is a good compromize :)
|
||||
$maxGenerated = 3;
|
||||
$maxResults = $maxGenerated * 8;
|
||||
|
||||
static::bootKernel();
|
||||
$em = static::$container->get(EntityManagerInterface::class);
|
@@ -27,7 +27,6 @@ use Chill\PersonBundle\Entity\Person;
|
||||
|
||||
class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testClosingIsAfterOpeningConsistency()
|
||||
{
|
||||
$datetime1 = new \DateTime('now');
|
||||
@@ -77,22 +76,24 @@ class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertFalse($period->isOpen());
|
||||
}
|
||||
|
||||
public function testCanBeReOpened()
|
||||
public function testPersonPeriod()
|
||||
{
|
||||
$person = new Person(\DateTime::createFromFormat('Y-m-d', '2010-01-01'));
|
||||
$person->close($person->getAccompanyingPeriods()[0]
|
||||
->setClosingDate(\DateTime::createFromFormat('Y-m-d', '2010-12-31')));
|
||||
|
||||
$firstAccompanygingPeriod = $person->getAccompanyingPeriodsOrdered()[0];
|
||||
|
||||
$this->assertTrue($firstAccompanygingPeriod->canBeReOpened());
|
||||
|
||||
$lastAccompanyingPeriod = (new AccompanyingPeriod(\DateTime::createFromFormat('Y-m-d', '2011-01-01')))
|
||||
->setClosingDate(\DateTime::createFromFormat('Y-m-d', '2011-12-31'))
|
||||
;
|
||||
$person->addAccompanyingPeriod($lastAccompanyingPeriod);
|
||||
|
||||
$this->assertFalse($firstAccompanygingPeriod->canBeReOpened());
|
||||
}
|
||||
$person = new Person();
|
||||
$period = new AccompanyingPeriod(new \DateTime());
|
||||
|
||||
$period->addPerson($person);
|
||||
|
||||
$this->assertEquals(1, $period->getParticipations()->count());
|
||||
$this->assertTrue($period->containsPerson($person));
|
||||
|
||||
$participation = $period->getOpenParticipationContainsPerson($person);
|
||||
$participations = $period->getParticipationsContainsPerson($person);
|
||||
$this->assertNotNull($participation);
|
||||
$this->assertEquals(1, $participations->count());
|
||||
|
||||
$period->removePerson($person);
|
||||
|
||||
$participation = $period->getOpenParticipationContainsPerson($person);
|
||||
$this->assertNull($participation);
|
||||
}
|
||||
}
|
||||
|
@@ -45,3 +45,9 @@ services:
|
||||
$dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
|
||||
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
Chill\PersonBundle\Controller\AccompanyingCourseApiController:
|
||||
arguments:
|
||||
$eventDispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
|
||||
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
||||
tags: ['controller.service_arguments']
|
||||
|
Reference in New Issue
Block a user