* * 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\EventBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * Test the creation of participation controller * * * @author Julien Fastré */ class ParticipationControllerTest extends WebTestCase { /** * * @var \Symfony\Component\BrowserKit\Client */ protected $client; /** * * @var \Doctrine\ORM\EntityManagerInterface */ protected $em; /** * Keep a cache for each person id given by the function getRandomPerson. * * You may ask to ignore some people by adding their id to the array. * * This is reset by setUp(). * * @var int[] */ private $personsIdsCache = array(); public function setUp() { self::bootKernel(); $this->client = static::createClient(array(), array( 'PHP_AUTH_USER' => 'center a_social', 'PHP_AUTH_PW' => 'password', 'HTTP_ACCEPT_LANGUAGE' => 'fr_FR' )); $container = self::$kernel->getContainer(); $this->em = $container->get('doctrine.orm.entity_manager') ; $this->personsIdsCache = array(); } /** * * * @return \Chill\EventBundle\Entity\Event */ protected function getRandomEvent($centerName = 'Center A', $circleName = 'social') { $center = $this->em->getRepository('ChillMainBundle:Center') ->findByName($centerName); $circles = $this->em->getRepository('ChillMainBundle:Scope') ->findAll(); array_filter($circles, function($circle) use ($circleName) { return in_array($circleName, $circle->getName()); }); $circle = $circles[0]; $events = $this->em->getRepository('ChillEventBundle:Event') ->findBy(array('center' => $center, 'circle' => $circle)); return $events[array_rand($events)]; } /** * Return a random event only if he has more than one participation. * * @param string $centerName * @param type $circleName * @return \Chill\EventBundle\Entity\Event */ protected function getRandomEventWithMultipleParticipations( $centerName = 'Center A', $circleName = 'social') { $event = $this->getRandomEvent($centerName, $circleName); return $event->getParticipations()->count() > 1 ? $event : $this->getRandomEventWithMultipleParticipations($centerName, $circleName); } /** * Returns a person randomly. * * This function does not give the same person twice * for each test. * * You may ask to ignore some people by adding their id to the property * `$this->personsIdsCache` * * @param string $centerName * @return \Chill\PersonBundle\Entity\Person */ protected function getRandomPerson($centerName = 'Center A') { $center = $this->em->getRepository('ChillMainBundle:Center') ->findByName($centerName); $persons = $this->em->getRepository('ChillPersonBundle:Person') ->findBy(array('center' => $center)); $person = $persons[array_rand($persons)]; if (in_array($person->getId(), $this->personsIdsCache)) { return $this->getRandomPerson($centerName); // we try another time } else { $this->personsIdsCache[] = $person->getId(); return $person; } } public function testNewActionWrongParameters() { $event = $this->getRandomEvent(); $person = $this->getRandomPerson(); // missing person_id or persons_ids $this->client->request('GET', '/fr/event/participation/new', array( 'event_id' => $event->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/new fail if " . "both person_id and persons_ids are missing"); // having both person_id and persons_ids $this->client->request('GET', '/fr/event/participation/new', array( 'event_id' => $event->getId(), 'persons_ids' => implode(',', array( $this->getRandomPerson()->getId(), $this->getRandomPerson()->getId() )), 'person_id' => $person->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/new fail if both person_id and " . "persons_ids are set"); // missing event_id $this->client->request('GET', '/fr/event/participation/new', array( 'person_id' => $person->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/new fails if event_id is missing"); // persons_ids with wrong content $this->client->request('GET', '/fr/event/participation/new', array( 'persons_ids' => 'a,b,531', 'event_id' => $event->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/new fails if persons_ids has wrong content"); } /** * This method test participation creation with wrong parameters. * * Those request should fail before any processing. */ public function testCreateActionWrongParameters() { $event = $this->getRandomEvent(); $person = $this->getRandomPerson(); // missing person_id or persons_ids $this->client->request('GET', '/fr/event/participation/create', array( 'event_id' => $event->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/create fail if " . "both person_id and persons_ids are missing"); // having both person_id and persons_ids $this->client->request('GET', '/fr/event/participation/create', array( 'event_id' => $event->getId(), 'persons_ids' => implode(',', array( $this->getRandomPerson()->getId(), $this->getRandomPerson()->getId() )), 'person_id' => $person->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/create fail if both person_id and " . "persons_ids are set"); // missing event_id $this->client->request('GET', '/fr/event/participation/create', array( 'person_id' => $person->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/create fails if event_id is missing"); // persons_ids with wrong content $this->client->request('GET', '/fr/event/participation/create', array( 'persons_ids' => 'a,b,531', 'event_id' => $event->getId() )); $this->assertEquals(400, $this->client->getResponse()->getStatusCode(), "Test that /fr/event/participation/create fails if persons_ids has wrong content"); } public function testNewSingleAction() { $event = $this->getRandomEvent(); // record the number of participation for the event $nbParticipations = $event->getParticipations()->count(); $person = $this->getRandomPerson(); $crawler = $this->client->request('GET', '/fr/event/participation/new', array( 'person_id' => $person->getId(), 'event_id' => $event->getId() )); $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/new is successful"); $button = $crawler->selectButton('Créer'); $this->assertNotNull($button, "test the form with button 'Créer' exists"); $this->client->submit($button->form(), array( 'participation[role]' => $event->getType()->getRoles()->first()->getId(), 'participation[status]' => $event->getType()->getStatuses()->first()->getId() )); $this->assertTrue($this->client->getResponse()->isRedirect()); $crawler = $this->client->followRedirect(); $span = $crawler->filter('table td span.entity-person a:contains("' .$person->getFirstName().'"):contains("'.$person->getLastname().'")'); $this->assertGreaterThan(0, count($span)); // as the container has reloaded, reload the event $event = $this->em->getRepository('ChillEventBundle:Event')->find($event->getId()); $this->em->refresh($event); $this->assertEquals($nbParticipations + 1, $event->getParticipations()->count()); } public function testNewMultipleAction() { $event = $this->getRandomEvent(); // record the number of participation for the event (used later in this test) $nbParticipations = $event->getParticipations()->count(); // make ignore the people already in the event from the function getRandomPerson $this->personsIdsCache = array_merge( $this->personsIdsCache, $event->getParticipations()->map( function($p) { return $p->getPerson()->getId(); } ) ->toArray() ); // get some random people $person1 = $this->getRandomPerson(); $person2 = $this->getRandomPerson(); $crawler = $this->client->request('GET', '/fr/event/participation/new', array( 'persons_ids' => implode(',', array($person1->getId(), $person2->getId())), 'event_id' => $event->getId() )); $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/new is successful"); $button = $crawler->selectButton('Créer'); $this->assertNotNull($button, "test the form with button 'Créer' exists"); $this->client->submit($button->form(), array( 'form' => array( 'participations' => array( 0 => array( 'role' => $event->getType()->getRoles()->first()->getId(), 'status' => $event->getType()->getStatuses()->first()->getId() ), 1 => array( 'role' => $event->getType()->getRoles()->first()->getId(), 'status' => $event->getType()->getStatuses()->first()->getId() ), ) ) )); $this->assertTrue($this->client->getResponse()->isRedirect()); $crawler = $this->client->followRedirect(); $span1 = $crawler->filter('table td span.entity-person a:contains("' .$person1->getFirstName().'"):contains("'.$person1->getLastname().'")'); $this->assertGreaterThan(0, count($span1)); $span2 = $crawler->filter('table td span.entity-person a:contains("' .$person2->getFirstName().'"):contains("'.$person2->getLastname().'")'); $this->assertGreaterThan(0, count($span2)); // as the container has reloaded, reload the event $event = $this->em->getRepository('ChillEventBundle:Event')->find($event->getId()); $this->em->refresh($event); $this->assertEquals($nbParticipations + 2, $event->getParticipations()->count()); } public function testMultipleWithAllPeopleParticipating() { $event = $this->getRandomEventWithMultipleParticipations(); $persons_id = implode(',', $event->getParticipations()->map( function($p) { return $p->getPerson()->getId(); } )->toArray()); $crawler = $this->client->request('GET', '/fr/event/participation/new', array( 'persons_ids' => $persons_id, 'event_id' => $event->getId() )); $this->assertEquals(302, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/new is redirecting"); } public function testMultipleWithSomePeopleParticipating() { $event = $this->getRandomEventWithMultipleParticipations(); // record the number of participation for the event (used later in this test) $nbParticipations = $event->getParticipations()->count(); // get the persons_id participating on this event $persons_id = $event->getParticipations()->map( function($p) { return $p->getPerson()->getId(); } )->toArray(); // exclude the existing persons_ids from the new person $this->personsIdsCache = array_merge($this->personsIdsCache, $persons_id); // get a random person $newPerson = $this->getRandomPerson(); // build the `persons_ids` parameter $persons_ids_string = implode(',', array_merge($persons_id, array($newPerson->getId()))); $crawler = $this->client->request('GET', '/fr/event/participation/new', array( 'persons_ids' => $persons_ids_string, 'event_id' => $event->getId() )); $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "test that /fr/event/participation/new is successful"); // count that the one UL contains the new person string $firstPerson = $event->getParticipations()->first()->getPerson(); $ul = $crawler->filter('ul:contains("'.$firstPerson->getLastName().'")' . ':contains("'.$firstPerson->getFirstName().'")'); $this->assertEquals(1, $ul->count(), "assert an ul containing the name of ignored people is present"); $this->assertEquals($event->getParticipations()->count(), $ul->children()->count(), "assert the li listing ignored people has the correct number"); // test a form is present on the page $button = $crawler->selectButton('Créer'); $this->assertNotNull($button, "test the form with button 'Créer' exists"); // submit the form $this->client->submit($button->form(), array( 'participation[role]' => $event->getType()->getRoles()->first()->getId(), 'participation[status]' => $event->getType()->getStatuses()->first()->getId() )); $this->assertTrue($this->client->getResponse()->isRedirect()); // reload the event and test there is a new participation $event = $this->em->getRepository('ChillEventBundle:Event') ->find($event->getId()); $this->em->refresh($event); $this->assertEquals($nbParticipations + 1, $event->getParticipations()->count(), "Test we have persisted a new participation associated to the test"); } }