add api endpoint for adding/remove social issue on accompanying period

This commit is contained in:
Julien Fastré 2021-05-18 17:18:35 +02:00
parent e095cac7e0
commit 14bd211a5f
5 changed files with 200 additions and 3 deletions

View File

@ -16,6 +16,7 @@ use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\MainBundle\Entity\Scope;
class AccompanyingCourseApiController extends ApiController
@ -83,6 +84,11 @@ class AccompanyingCourseApiController extends ApiController
return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class);
}
public function socialIssueApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
}
public function requestorApi($id, Request $request, string $_format): Response
{
/** @var AccompanyingPeriod $accompanyingPeriod */

View File

@ -389,7 +389,20 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
]
],
'socialissue' => [
'methods' => [
Request::METHOD_POST => true,
Request::METHOD_DELETE => true,
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'socialIssueApi',
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
],
]
],

View File

@ -249,6 +249,7 @@ class AccompanyingPeriod
* @ORM\JoinTable(
* name="chill_person_accompanying_period_social_issues"
* )
* @Groups({"read"})
*/
private Collection $socialIssues;
@ -727,14 +728,14 @@ class AccompanyingPeriod
return $this->socialIssues;
}
public function addSocialIssues(SocialIssue $socialIssue): self
public function addSocialIssue(SocialIssue $socialIssue): self
{
$this->socialIssues[] = $socialIssue;
return $this;
}
public function removeSocialIssue(SocialIssue $socialissue): void
public function removeSocialIssue(SocialIssue $socialIssue): void
{
$this->socialIssues->removeElement($socialIssue);
}

View File

@ -27,6 +27,7 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Center;
@ -87,6 +88,41 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
$this->assertEquals(404, $response->getStatusCode(), "Test that the response of rest api has a status code 'not found' (404)");
}
/**
*
* @dataProvider dataGenerateRandomAccompanyingCourseWithSocialIssue
*/
public function testAccompanyingCourseAddRemoveSocialIssue(AccompanyingPeriod $period, SocialIssue $si)
{
$this->client->request(
Request::METHOD_POST,
sprintf('/api/1.0/person/accompanying-course/%d/socialissue.json', $period->getId()),
[],
[],
[],
\json_encode([ 'type' => 'social_issue', 'id' => $si->getId() ])
);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$data = \json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $data);
$this->assertArrayHasKey('type', $data);
$this->assertEquals('social_issue', $data['type']);
$this->client->request(
Request::METHOD_DELETE,
sprintf('/api/1.0/person/accompanying-course/%d/socialissue.json', $period->getId()),
[],
[],
[],
\json_encode([ 'type' => 'social_issue', 'id' => $si->getId() ])
);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}
/**
* @dataProvider dataGenerateRandomRequestorValidData
*/
@ -425,6 +461,53 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
}
}
public function dataGenerateRandomAccompanyingCourseWithSocialIssue()
{
// note about max result for person query, and maxGenerated:
//
// in the final loop, an id is popped out of the personIds array twice:
//
// * 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. x8 is a good compromize :)
$maxGenerated = 3;
$maxResults = $maxGenerated * 8;
static::bootKernel();
$em = static::$container->get(EntityManagerInterface::class);
$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($maxResults)
->getScalarResult();
// create a random order
shuffle($personIds);
$socialIssues = $em->createQuery("SELECT s FROM ".
SocialIssue::class." s ")
->setMaxResults(10)
->getResult();
$nbGenerated = 0;
while ($nbGenerated < $maxGenerated) {
$id = \array_pop($personIds)["id"];
$person = $em->getRepository(Person::class)
->find($id);
$periods = $person->getAccompanyingPeriods();
yield [$periods[\array_rand($periods)], $socialIssues[\array_rand($socialIssues)] ];
$nbGenerated++;
}
}
public function dataGenerateRandomAccompanyingCourse()
{
// note about max result for person query, and maxGenerated:

View File

@ -84,6 +84,8 @@ components:
required:
- id
- type
# ok to stay here
AccompanyingPeriod:
type: object
properties:
@ -147,6 +149,33 @@ components:
required:
- id
- type
SocialIssue:
type: object
properties:
id:
type: integer
type:
type: string
enum:
- 'social_issue'
parent_id:
type: integer
readOnly: true
children_ids:
type: array
items:
type: integer
readOnly: true
title:
type: object
additionalProperties:
type: string
example:
fr: Accompagnement Social Adulte
readOnly: true
text:
type: string
readOnly: true
paths:
/1.0/person/accompanying-course/{id}.json:
@ -534,3 +563,68 @@ paths:
description: "OK"
422:
description: "object with validation errors"
/1.0/person/accompanying-course/{id}/socialissue.json:
post:
tags:
- person
summary: "Add a social issue to the accompanying course"
parameters:
- name: id
in: path
required: true
description: The accompanying period's id
schema:
type: integer
format: integer
minimum: 1
requestBody:
description: "A social issue by id"
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SocialIssue'
examples:
add a social issue:
value:
type: social_issue
id: 5
responses:
401:
description: "Unauthorized"
404:
description: "Not found"
200:
description: "OK"
422:
description: "object with validation errors"
delete:
tags:
- person
summary: "Remove the social issue"
parameters:
- name: id
in: path
required: true
description: The accompanying period's id
schema:
type: integer
format: integer
minimum: 1
requestBody:
description: "A social issue with his id"
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SocialIssue'
responses:
401:
description: "Unauthorized"
404:
description: "Not found"
200:
description: "OK"
422:
description: "object with validation errors"