From 04e9e309728e9b277c22c2d84aae338008da411c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 May 2021 11:44:09 +0200 Subject: [PATCH 1/5] quick fix for banner --- .../Resources/views/AccompanyingCourse/banner.html.twig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/banner.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/banner.html.twig index 2091cf54a..c8d566e84 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/banner.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/banner.html.twig @@ -22,8 +22,10 @@

- ouvert le {{ accompanyingCourse.openingDate|format_date('short') }}
- par {{ accompanyingCourse.user.usernameCanonical }} + {{ 'Started on %date%'|trans({'%date%': accompanyingCourse.openingDate|format_date('short') } ) }}
+ {% if accompanyingCourse.user is not null %} + par {{ accompanyingCourse.user.usernameCanonical }} + {% endif %}

From 22aa4afc029f078500b1a72027a0fa92df66b5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 May 2021 13:20:59 +0200 Subject: [PATCH 2/5] action: confirm accompanying period + create workflow --- .../AccompanyingCourseApiController.php | 33 ++++++- .../ChillPersonExtension.php | 45 ++++++++- .../AccompanyingCourseApiControllerTest.php | 93 +++++++++++++++---- .../Workflows/AccompanyingPeriodLifecycle.php | 27 ++++++ .../ChillPersonBundle/chill.api.specs.yaml | 24 +++++ .../config/services/controller.yaml | 1 + 6 files changed, 203 insertions(+), 20 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Workflows/AccompanyingPeriodLifecycle.php diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php index 38f09b49e..0d8189b6a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php @@ -5,7 +5,6 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; use Symfony\Component\HttpFoundation\Request; 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; @@ -18,6 +17,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource; use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\MainBundle\Entity\Scope; +use Symfony\Component\Workflow\Registry; class AccompanyingCourseApiController extends ApiController { @@ -25,10 +25,37 @@ class AccompanyingCourseApiController extends ApiController protected ValidatorInterface $validator; - public function __construct(EventDispatcherInterface $eventDispatcher, $validator) - { + private Registry $registry; + + public function __construct( + EventDispatcherInterface $eventDispatcher, + ValidatorInterface $validator, + Registry $registry + ) { $this->eventDispatcher = $eventDispatcher; $this->validator = $validator; + $this->registry = $registry; + } + + public function confirmApi($id, Request $request, $_format): Response + { + /** @var AccompanyingPeriod $accompanyingPeriod */ + $accompanyingPeriod = $this->getEntity('participation', $id, $request); + + $this->checkACL('confirm', $request, $_format, $accompanyingPeriod); +$workflow = $this->registry->get($accompanyingPeriod); + + if (FALSE === $workflow->can($accompanyingPeriod, 'confirm')) { + throw new BadRequestException('It is not possible to confirm this period'); + } + + $workflow->apply($accompanyingPeriod, 'confirm'); + + $this->getDoctrine()->getManager()->flush(); + + return $this->json($accompanyingPeriod, Response::HTTP_OK, [], [ + 'groups' => [ 'read' ] + ]); } public function participationApi($id, Request $request, $_format) diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 8941f5943..0d6346c01 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -1,5 +1,4 @@ * @@ -166,6 +165,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac $this->prependHomepageWidget($container); $this->prependDoctrineDQL($container); $this->prependCruds($container); + $this->prependWorkflows($container); //add person_fields parameter as global $chillPersonConfig = $container->getExtensionConfig($this->getAlias()); @@ -195,6 +195,39 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac )); } + protected function prependWorkflows(ContainerBuilder $container) + { + $container->prependExtensionConfig('framework', [ + 'workflows' => [ + 'accompanying_period_lifecycle' => [ + 'type' => 'state_machine', + 'audit_trail' => [ + 'enabled' => true + ], + 'marking_store' => [ + 'type' => 'method', + 'property' => 'step', + ], + 'supports' => [ + 'Chill\PersonBundle\Entity\AccompanyingPeriod' + ], + 'initial_marking' => 'DRAFT', + 'places' => [ + 'DRAFT', + 'CONFIRMED', + ], + 'transitions' => [ + 'confirm' => [ + 'from' => 'DRAFT', + 'to' => 'CONFIRMED' + ], + ], + ], + ] + ]); + + } + /** * Add a widget "add a person" on the homepage, automatically * @@ -406,6 +439,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac ] ], + 'confirm' => [ + 'methods' => [ + Request::METHOD_POST => true, + Request::METHOD_GET => false, + Request::METHOD_HEAD => false, + ], + 'roles' => [ + Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, + ] + ], ] ], [ diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php index 716048966..a41e570a5 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php @@ -43,6 +43,10 @@ class AccompanyingCourseApiControllerTest extends WebTestCase { protected static EntityManagerInterface $em; + protected ?int $personId = NULL; + + protected ?AccompanyingPeriod $period = NULL; + /** * Setup before the first test of this class (see phpunit doc) */ @@ -302,6 +306,22 @@ class AccompanyingCourseApiControllerTest extends WebTestCase $this->assertNull($period->getRequestor()); } + /** + * @dataProvider dataGenerateNewAccompanyingCourse + */ + public function testConfirm(AccompanyingPeriod $period) + { + $this->client->request( + Request::METHOD_POST, + sprintf('/api/1.0/person/accompanying-course/%d/confirm.json', $period->getId()) + ); + + $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + + // add period to remove it in tear down + $this->period = $period; + } + /** * * @dataProvider dataGenerateRandomAccompanyingCourse @@ -439,25 +459,32 @@ class AccompanyingCourseApiControllerTest extends WebTestCase protected function tearDown() { - // remove participation created during test 'testAccompanyingCourseAddParticipation' - // and if the test could not remove it - - $testAddParticipationName = 'testAccompanyingCourseAddParticipation'; - - if ($testAddParticipationName !== \substr($this->getName(), 0, \strlen($testAddParticipationName))) { - return; - } - $em = static::$container->get(EntityManagerInterface::class); - $participation = $em - ->getRepository(AccompanyingPeriodParticipation::class) - ->findOneBy(['person' => $this->personId, 'accompanyingPeriod' => $this->period]) - ; + // remove participation if set + if ($this->personId && $this->period) { + $participation = $em + ->getRepository(AccompanyingPeriodParticipation::class) + ->findOneBy(['person' => $this->personId, 'accompanyingPeriod' => $this->period]) + ; - if (NULL !== $participation) { - $em->remove($participation); - $em->flush(); + if (NULL !== $participation) { + $em->remove($participation); + $em->flush(); + } + $this->personId = NULL; + $this->period = NULL; + } elseif ($this->period) { + $period = $em + ->getRepository(AccompanyingPeriod::class) + ->find($this->period->getId()) ; + + if ($period !== NULL) { + $em->remove($period); + $em->flush(); + } + + $this->period = null; } } @@ -550,4 +577,38 @@ class AccompanyingCourseApiControllerTest extends WebTestCase } } + public function dataGenerateNewAccompanyingCourse() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $period = new AccompanyingPeriod(new \DateTime('1 week ago')); + $user = $em->getRepository(User::class) + ->findOneByUsernameCanonical('center a_social'); + $period->setCreatedBy($user); + //$period->setCreatedAt(new \DateTime('yesterday')); + + $center = $em->getRepository(Center::class) + ->findOneBy(array('name' => 'Center A')); + + $personIds = $em->createQuery("SELECT p.id FROM ". + Person::class." p ". + " WHERE p.center = :center") + ->setParameter('center', $center) + ->setMaxResults(100) + ->getScalarResult(); + + // create a random order + shuffle($personIds); + + for ($i = 0; $i<2; $i++) { + $person = $em->getRepository(Person::class)->find(\array_pop($personIds)); + $period->addPerson($person); + } + + $em->persist($period); + $em->flush(); + + yield [ $period ]; + } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Workflows/AccompanyingPeriodLifecycle.php b/src/Bundle/ChillPersonBundle/Tests/Workflows/AccompanyingPeriodLifecycle.php new file mode 100644 index 000000000..df86d79a6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Workflows/AccompanyingPeriodLifecycle.php @@ -0,0 +1,27 @@ +get(Registry::class); + $period = new AccompanyingPeriod(new \DateTime('now')); + $workflow = $registry->get($period); + + $this->assertArrayHasKey('DRAFT', $workflow->getMarking($period)->getPlaces()); + $this->assertTrue($workflow->can($period, 'confirm')); + } + +} diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index ba6da70e7..a5636d93e 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -677,3 +677,27 @@ paths: description: "OK" 422: description: "object with validation errors" + + /1.0/person/accompanying-course/{id}/confirm.json: + post: + tags: + - person + summary: confirm an accompanying course + parameters: + - name: id + in: path + required: true + description: The accompanying period's id + schema: + type: integer + format: integer + minimum: 1 + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + 400: + description: "transition cannot be applyed" diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml index 41a5ac719..fd5e1f952 100644 --- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml @@ -51,4 +51,5 @@ services: arguments: $eventDispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface' $validator: '@Symfony\Component\Validator\Validator\ValidatorInterface' + $registry: '@Symfony\Component\Workflow\Registry' tags: ['controller.service_arguments'] From 4440cf8a24e69378cc6bc3823a2f53e80ea08b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 May 2021 16:00:06 +0200 Subject: [PATCH 3/5] add missing declaration property --- .../Normalizer/AccompanyingPeriodResourceNormalizer.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php index 0ac49c905..b5fca8d59 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php @@ -17,8 +17,11 @@ use Chill\MainBundle\Serializer\Normalizer\DiscriminatedObjectDenormalizer; class AccompanyingPeriodResourceNormalizer implements DenormalizerInterface, DenormalizerAwareInterface { use DenormalizerAwareTrait; + use ObjectToPopulateTrait; + private ResourceRepository $repository; + public function __construct(ResourceRepository $repository) { $this->repository = $repository; From 03bd1674e1b3b91cbdd3646080a5b21a60869924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 May 2021 16:13:19 +0200 Subject: [PATCH 4/5] fix resource repository --- .../Entity/AccompanyingPeriod/Resource.php | 3 ++- .../Repository/AccompanyingPeriod/ResourceRepository.php | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php index 74620b7b2..cf796722a 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php @@ -25,13 +25,14 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository; use Chill\ThirdPartyBundle\Entity\ThirdParty; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; /** - * @ORM\Entity + * @ORM\Entity(repositoryClass=ResourceRepository::class) * @ORM\Table(name="chill_person_accompanying_period_resource") * @DiscriminatorMap(typeProperty="type", mapping={ * "accompanying_period_resource"=Resource::class diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ResourceRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ResourceRepository.php index 4f625b59c..c32f74762 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ResourceRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ResourceRepository.php @@ -23,8 +23,9 @@ namespace Chill\PersonBundle\Repository\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource; -use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; /** * @method Resource|null find($id, $lockMode = null, $lockVersion = null) @@ -32,12 +33,12 @@ use Doctrine\ORM\EntityRepository; * @method Resource[] findAll() * @method Resource[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -final class ResourceRepository +final class ResourceRepository extends ServiceEntityRepository { private EntityRepository $repository; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(ManagerRegistry $registry) { - $this->repository = $entityManager->getRepository(Resource::class); + parent::__construct($registry, Resource::class); } } From 25d7fc36a4c02937578baf0bd2d76ca9a4076371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 May 2021 16:14:36 +0200 Subject: [PATCH 5/5] action to create an accompanyinig period --- .../AccompanyingCourseController.php | 115 ++++++------------ .../Entity/AccompanyingPeriod.php | 4 +- .../Authorization/AccompanyingPeriodVoter.php | 3 + .../AccompanyingCourseControllerTest.php | 88 ++++++++++++++ .../ChillPersonBundle/config/services.yaml | 2 + 5 files changed, 131 insertions(+), 81 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 8134f6938..6786cb05f 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -6,6 +6,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; @@ -42,6 +43,41 @@ class AccompanyingCourseController extends Controller $this->dispatcher = $dispatcher; $this->validator = $validator; } + + /** + * @Route("/{_locale}/person/parcours/new", name="chill_person_accompanying_course_new") + */ + public function newAction(Request $request): Response + { + $period = new AccompanyingPeriod(); + $em = $this->getDoctrine()->getManager(); + + if ($request->query->has('person_id')) { + $personIds = $request->query->get('person_id'); + + if (FALSE === \is_array($personIds)) { + throw new BadRequestException("person_id parameter should be an array"); + } + + foreach ($personIds as $personId) { + $person = $em->getRepository(Person::class)->find($personId); + if (NULL !== $person) { + $period->addPerson($person); + } + } + } + + $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $period); + + $em->persist($period); + $em->flush(); + + return $this->redirectToRoute('chill_person_accompanying_course_show', [ + 'accompanying_period_id' => $period->getId() + ]); + + } + /** * Homepage of Accompanying Course section * @@ -86,83 +122,4 @@ class AccompanyingCourseController extends Controller ]); } - /** - * Get API Data for showing endpoint - * - * @Route( - * "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/show.{_format}", - * name="chill_person_accompanying_course_api_show" - * ) - * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"}) - */ - public function showAPI(AccompanyingPeriod $accompanyingCourse, $_format): Response - { - // TODO check ACL on AccompanyingPeriod - - $this->dispatcher->dispatch( - AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT, - new AccompanyingPeriodPrivacyEvent($accompanyingCourse, [ - 'action' => 'showApi' - ]) - ); - - //$accompanyingCourse->getRequestorPerson(); - //$accompanyingCourse->getRequestorThirdParty(); - //$accompanyingCourse->isRequestorAnonymous(); - //dump($accompanyingCourse); die; - - switch ($_format) { - case 'json': - return $this->json($accompanyingCourse); - default: - throw new BadRequestException('Unsupported format'); - } - - } - - /** - * Get API Data for showing endpoint - * - * @Route( - * "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}", - * name="chill_person_accompanying_course_api_add_participation", - * methods={"POST","DELETE"}, - * format="json", - * requirements={ - * "_format": "json", - * } - * ) - * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"}) - */ - public function participationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response - { - switch ($_format) { - case 'json': - $person = $this->serializer->deserialize($request->getContent(), Person::class, $_format, [ - - ]); - break; - default: - throw new BadRequestException('Unsupported format'); - } - - if (NULL === $person) { - throw new BadRequestException('person id not found'); - } - - // TODO add acl - $participation = ($request->getMethod() === 'POST') ? - $accompanyingCourse->addPerson($person) : $accompanyingCourse->removePerson($person); - - $errors = $this->validator->validate($accompanyingCourse); - - if ($errors->count() > 0) { - // only format accepted - return $this->json($errors); - } - - $this->getDoctrine()->getManager()->flush(); - - return $this->json($participation); - } } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 716edd118..69d461319 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -266,8 +266,8 @@ class AccompanyingPeriod * @param \DateTime $dateOpening * @uses AccompanyingPeriod::setClosingDate() */ - public function __construct(\DateTime $dateOpening) { - $this->setOpeningDate($dateOpening); + public function __construct(\DateTime $dateOpening = null) { + $this->setOpeningDate($dateOpening ?? new \DateTime('now')); $this->participations = new ArrayCollection(); $this->scopes = new ArrayCollection(); $this->socialIssues = new ArrayCollection(); diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index ca92c6d7c..2801cb8f7 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -38,6 +38,9 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole } // TODO take scopes into account + if (count($subject->getPersons()) === 0) { + return true; + } foreach ($subject->getPersons() as $person) { // give access as soon as on center is reachable if ($this->helper->userHasAccess($token->getUser(), $person->getCenter(), $attribute)) { diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php new file mode 100644 index 000000000..0143a70ed --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php @@ -0,0 +1,88 @@ +client = $this->getClientAuthenticated(); + } + + public function testNewWithoutUsers() + { + $this->client->request('GET', '/fr/person/parcours/new'); + + $this->assertResponseRedirects(); + $location = $this->client->getResponse()->headers->get('Location'); + + $this->assertEquals(1, \preg_match("|^\/[^\/]+\/parcours/([\d]+)/show$|", $location)); + + } + + /** + * @dataProvider dataGenerateRandomUsers + */ + public function testWithNewUsers($personId0, $personId1) + { + $this->client->request('GET', '/fr/person/parcours/new', [ + 'person_id' => [ + $personId0, + $personId1 + ] + ]); + + $this->assertResponseRedirects(); + $location = $this->client->getResponse()->headers->get('Location'); + $matches = []; + + $this->assertEquals(1, \preg_match("|^\/[^\/]+\/parcours/([\d]+)/show$|", $location, $matches)); + $id = $matches[1]; + + $period = self::$container->get(EntityManagerInterface::class) + ->getRepository(AccompanyingPeriod::class) + ->find($id); + + $this->assertNotNull($period); + + $this->assertEquals(2, count($period->getParticipations())); + } + + public function dataGenerateRandomUsers(): \Iterator + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $period = new AccompanyingPeriod(new \DateTime('1 week ago')); + $user = $em->getRepository(User::class) + ->findOneByUsernameCanonical('center a_social'); + $period->setCreatedBy($user); + //$period->setCreatedAt(new \DateTime('yesterday')); + + $center = $em->getRepository(Center::class) + ->findOneBy(array('name' => 'Center A')); + + $personIds = $em->createQuery("SELECT p.id FROM ". + Person::class." p ". + " WHERE p.center = :center") + ->setParameter('center', $center) + ->setMaxResults(100) + ->getScalarResult(); + + yield [ \array_pop($personIds), \array_pop($personIds) ]; + } + + +} diff --git a/src/Bundle/ChillPersonBundle/config/services.yaml b/src/Bundle/ChillPersonBundle/config/services.yaml index 1c1a3a29b..523545900 100644 --- a/src/Bundle/ChillPersonBundle/config/services.yaml +++ b/src/Bundle/ChillPersonBundle/config/services.yaml @@ -44,5 +44,7 @@ services: - { name: validator.constraint_validator, alias: birthdate_not_before } Chill\PersonBundle\Repository\: + autowire: true + autoconfigure: true resource: '../Repository/' tags: ['doctrine.repository_service']