, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\PersonBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; use Chill\PersonBundle\Entity\Person; use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\Center; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\Request; /** * Test api for AccompanyingCourseControllerTest */ class AccompanyingCourseApiControllerTest extends WebTestCase { protected static EntityManagerInterface $em; /** * Setup before the first test of this class (see phpunit doc) */ public static function setUpBeforeClass() { static::bootKernel(); } /** * Setup before each test method (see phpunit doc) */ public function setUp() { $this->client = static::createClient(array(), array( 'PHP_AUTH_USER' => 'center a_social', 'PHP_AUTH_PW' => 'password', )); } /** * * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingCourseShow(int $personId, AccompanyingPeriod $period) { $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)"); $data = \json_decode($response->getContent()); $this->assertEquals($data->id, $period->getId(), "test that the response's data contains the id of the period" ); $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 dataGenerateRandomRequestorValidData */ public function testRequestorWithValidData(AccompanyingPeriod $period, $personId, $thirdPartyId) { $em = self::$container->get(EntityManagerInterface::class); // post a person $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], // parameters [], // files [], // server parameters \json_encode([ 'type' => 'person', 'id' => $personId ]) ); $response = $this->client->getResponse(); $data = \json_decode($response->getContent(), true); $this->assertEquals(200, $response->getStatusCode()); $this->assertArrayHasKey('id', $data); $this->assertEquals($personId, $data['id']); // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $this->assertInstanceOf(Person::class, $period->getRequestor()); $this->assertEquals($personId, $period->getRequestor()->getId()); // post a third party $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], // parameters [], // files [], // server parameters \json_encode([ 'type' => 'thirdparty', 'id' => $thirdPartyId ]) ); $response = $this->client->getResponse(); $data = \json_decode($response->getContent(), true); $this->assertEquals(200, $response->getStatusCode()); $this->assertArrayHasKey('id', $data); $this->assertEquals($thirdPartyId, $data['id']); // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $this->assertInstanceOf(ThirdParty::class, $period->getRequestor()); $this->assertEquals($thirdPartyId, $period->getRequestor()->getId()); // remove the requestor $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()) ); $response = $this->client->getResponse(); $this->assertEquals(200, $response->getStatusCode()); // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $em->refresh($period); $this->assertNull($period->getRequestor()); } /** * * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingPeriodPatch(int $personId, AccompanyingPeriod $period) { $initialValueEmergency = $period->isEmergency(); $em = self::$container->get(EntityManagerInterface::class); $this->client->request( Request::METHOD_PATCH, sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()), [], // parameters [], // files [], // server parameters \json_encode([ 'type' => 'accompanying_period', 'emergency' => !$initialValueEmergency ]) ); $response = $this->client->getResponse(); $this->assertEquals(200, $response->getStatusCode()); $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $em->refresh($period); $this->assertEquals(!$initialValueEmergency, $period->isEmergency()); // restore the initial valud $period->setEmergency($initialValueEmergency); $em->flush(); } public function dataGenerateRandomRequestorValidData(): \Iterator { $dataLength = 2; $maxResults = 100; 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); $thirdPartyIds = $em->createQuery("SELECT t.id FROM ". ThirdParty::class." t ") ->setMaxResults($maxResults) ->getScalarResult(); // create a random order shuffle($thirdPartyIds); $i = 0; while ($i <= $dataLength) { $person = $em->getRepository(Person::class) ->find(\array_pop($personIds)['id']); if (count($person->getAccompanyingPeriods()) === 0) { continue; } $period = $person->getAccompanyingPeriods()[0]; yield [$period, \array_pop($personIds)['id'], \array_pop($thirdPartyIds)['id'] ]; $i++; } } /** * * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingCourseAddParticipation(int $personId, AccompanyingPeriod $period) { $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $period->getId()), [], // parameters [], // files [], // server parameters \json_encode([ 'type' => 'person', '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']); // 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([ 'type' => 'person', '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; } 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]) ; if (NULL !== $participation) { $em->remove($participation); $em->flush(); } } public function dataGenerateRandomAccompanyingCourse() { // 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); $nbGenerated = 0; while ($nbGenerated < $maxGenerated) { $id = \array_pop($personIds)["id"]; $person = $em->getRepository(Person::class) ->find($id); $periods = $person->getAccompanyingPeriods(); yield [\array_pop($personIds)["id"], $periods[\array_rand($periods)] ]; $nbGenerated++; } } }