getPersonFromFixtures(); $activities = $this->getActivitiesForPerson($person); $user = $this->createFakeUser(); return [ [ $this->getAuthenticatedClient('center b_social'), sprintf('fr/person/%d/activity/', $person->getId()), ], [ $this->getAuthenticatedClient('center b_social'), sprintf('fr/person/%d/activity/new', $person->getId()), ], [ $this->getAuthenticatedClient('center b_social'), sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId()), ], [ $this->getAuthenticatedClient('center b_social'), sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId()), ], [ $this->getAuthenticatedClient($user->getUsername()), sprintf('fr/person/%d/activity/new', $person->getId()), ], ]; } /** * Provide a client unauthenticated and. */ public function getSecuredPagesUnauthenticated() { self::bootKernel(); $person = $this->getPersonFromFixtures(); $activities = $this->getActivitiesForPerson($person); return [ [sprintf('fr/person/%d/activity/', $person->getId())], [sprintf('fr/person/%d/activity/new', $person->getId())], [sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())], [sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())], ]; } /** * @dataProvider getSecuredPagesUnauthenticated * * @param mixed $url */ public function testAccessIsDeniedForUnauthenticated($url) { $client = $this->createClient(); $client->request('GET', $url); $this->assertEquals(302, $client->getResponse()->getStatusCode()); $this->assertTrue( $client->getResponse()->isRedirect('http://localhost/login'), sprintf('the page "%s" does not redirect to http://localhost/login', $url) ); } /** * @dataProvider getSecuredPagesAuthenticated * * @param type $client * @param type $url */ public function testAccessIsDeniedForUnauthorized($client, $url) { $client->request('GET', $url); $this->assertEquals(403, $client->getResponse()->getStatusCode()); } public function testCompleteScenario() { // Create a new client to browse the application $client = $this->getAuthenticatedClient(); $person = $this->getPersonFromFixtures(); // Create a new entry in the database $crawler = $client->request('GET', sprintf( 'en/person/%d/activity/', $person->getId() )); $this->assertEquals( 200, $client->getResponse()->getStatusCode(), 'Unexpected HTTP status code for GET /activity/' ); $crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité') ->link()); $reason1 = $this->getRandomActivityReason(); $reason2 = $this->getRandomActivityReason([$reason1->getId()]); // Fill in the form and submit it $form = $crawler->selectButton('Ajouter une nouvelle activité')->form([ 'chill_activitybundle_activity' => [ 'date' => '15-01-2015', 'durationTime' => 600, // 'remark' => 'blabla', 'scope' => $this->getRandomScope('center a_social', 'Center A')->getId(), 'type' => $this->getRandomActivityType()->getId(), ], ]); $form['chill_activitybundle_activity[reasons]']->select([$reason1->getId(), $reason2->getId()]); $client->submit($form); $this->assertTrue($client->getResponse()->isRedirect()); $crawler = $client->followRedirect(); // Check data in the show view $this->assertGreaterThan( 0, $crawler->filter('dd:contains("January 15, 2015")')->count(), 'Missing element dd:contains("January 15, 2015")' ); // Edit the entity $crawler = $client->click($crawler->selectLink("Modifier l'activité")->link()); $form = $crawler->selectButton("Sauver l'activité")->form([ 'chill_activitybundle_activity' => [ 'date' => '25-01-2015', // 'remark' => 'Foo' ], ]); $client->submit($form); $this->assertTrue($client->getResponse()->isRedirect()); $crawler = $client->followRedirect(); // check that new data are present $this->assertGreaterThan( 0, $crawler->filter('dd:contains("January 25, 2015")')->count(), 'Missing element dd:contains("January 25, 2015")' ); $this->assertGreaterThan( 0, $crawler->filter('dd:contains("Foo")')->count(), 'Missing element dd:contains("Foo")' ); // delete the actvity $crawler = $client->click($crawler->selectLink('Supprimer')->link()); $button = $crawler->selectButton('Supprimer'); $form = $button->form(); $client->submit($form); $this->assertTrue($client->getResponse()->isRedirect(sprintf( '/en/person/%d/activity/', $person->getId() ))); $crawler = $client->followRedirect(); $this->assertNotContains('January 25, 2015', $crawler->text()); } /** * create a user without any permissions on CHILL_ACTIVITY_* but with * permissions on center. * * @return \Chill\MainBundle\Entity\User a fake user within a group without activity */ private function createFakeUser() { $container = self::$kernel->getContainer(); $em = $container->get('doctrine.orm.entity_manager'); //get the social PermissionGroup, and remove CHILL_ACTIVITY_* $socialPermissionGroup = $em ->getRepository(\Chill\MainBundle\Entity\PermissionsGroup::class) ->findOneByName('social'); $withoutActivityPermissionGroup = (new \Chill\MainBundle\Entity\PermissionsGroup()) ->setName('social without activity'); //copy role scopes where ACTIVITY is not present foreach ($socialPermissionGroup->getRoleScopes() as $roleScope) { if (!strpos($roleScope->getRole(), 'ACTIVITY')) { $withoutActivityPermissionGroup->addRoleScope($roleScope); } } //create groupCenter $groupCenter = new \Chill\MainBundle\Entity\GroupCenter(); $groupCenter->setCenter($em->getRepository(\Chill\MainBundle\Entity\Center::class) ->findOneBy(['name' => 'Center A'])) ->setPermissionsGroup($withoutActivityPermissionGroup); $em->persist($withoutActivityPermissionGroup); $em->persist($groupCenter); //create user $faker = \Faker\Factory::create(); $username = $faker->name; $user = new \Chill\MainBundle\Entity\User(); $user ->setPassword($container->get('security.password_encoder') ->encodePassword($user, 'password')) ->setUsername($username) ->addGroupCenter($groupCenter); $em->persist($user); $em->flush(); return $user; } private function getActivitiesForPerson(\Chill\PersonBundle\Entity\Person $person) { $em = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager'); $activities = $em->getRepository(\Chill\ActivityBundle\Entity\Activity::class) ->findBy(['person' => $person]); if (count($activities) === 0) { throw new RuntimeException('We need activities associated with this ' . 'person. Did you forget to add fixtures ?'); } return $activities; } /** * @param mixed $username * * @return \Symfony\Component\BrowserKit\Client */ private function getAuthenticatedClient($username = 'center a_social') { return self::createClient([], [ 'PHP_AUTH_USER' => $username, 'PHP_AUTH_PW' => 'password', ]); } /** * @return \Chill\PersonBundle\Entity\Person */ private function getPersonFromFixtures() { $em = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager'); $person = $em->getRepository(\Chill\PersonBundle\Entity\Person::class) ->findOneBy([ 'firstName' => 'Depardieu', 'lastName' => 'Gérard', ]); if (null === $person) { throw new RuntimeException('We need a person with firstname Gérard and' . ' lastname Depardieu. Did you add fixtures ?'); } return $person; } /** * @param int[] $excludeIds An array of id to exclude * * @return \Chill\ActivityBundle\Entity\ActivityReason */ private function getRandomActivityReason(array $excludeIds = []) { $reasons = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager') ->getRepository(\Chill\ActivityBundle\Entity\ActivityReason::class) ->findAll(); $reason = $reasons[array_rand($reasons)]; if (in_array($reason->getId(), $excludeIds, true)) { return $this->getRandomActivityReason($excludeIds); } return $reason; } /** * @return \Chill\ActivityBundle\Entity\ActivityType */ private function getRandomActivityType() { $types = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager') ->getRepository(ActivityType::class) ->findAll(); return $types[array_rand($types)]; } /** * @param string $username * @param string $centerName * * @return \Chill\MainBundle\Entity\Scope */ private function getRandomScope($username, $centerName) { $user = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager') ->getRepository(\Chill\MainBundle\Entity\User::class) ->findOneByUsername($username); if (null === $user) { throw new RuntimeException("The user with username {$username} " . 'does not exists in database. Did you add fixtures ?'); } $center = self::$kernel->getContainer() ->get('doctrine.orm.entity_manager') ->getRepository(\Chill\MainBundle\Entity\Center::class) ->findOneByName($centerName); // get scope reachable by both role UPDATE and DELETE $reachableScopesUpdate = self::$kernel->getContainer() ->get('chill.main.security.authorization.helper') ->getReachableScopes( $user, new Role('CHILL_ACTIVITY_UPDATE'), $center ); $reachableScopesDelete = self::$kernel->getContainer() ->get('chill.main.security.authorization.helper') ->getReachableScopes( $user, new Role('CHILL_ACTIVITY_DELETE'), $center ); $reachableScopesId = array_intersect( array_map(static function ($s) { return $s->getId(); }, $reachableScopesDelete), array_map(static function ($s) { return $s->getId(); }, $reachableScopesUpdate) ); if (count($reachableScopesId) === 0) { throw new RuntimeException('there are not scope reachable for ' . 'both CHILL_ACTIVITY_UPDATE and CHILL_ACTIVITY_DELETE'); } foreach ($reachableScopesUpdate as $scope) { if (in_array($scope->getId(), $reachableScopesId, true)) { $reachableScopes[] = $scope; } } return $reachableScopes[array_rand($reachableScopes)]; } }