getFormData() as $data) { yield [$data]; } } /** * create data for `ìnitiateQuery` method. */ public function dataProviderInitiateQuery() { $acl = $this->getAcl(); foreach ($this->getModifiersCombination() as $modifiers) { foreach ($this->getFormData() as $data) { yield [$modifiers, $acl, $data]; } } } /** * Return an array usable as ACL. * * If this method is overridden, the returned result must be an array * with this form : * * ``` * array( * array( * 'center' => //center instance * 'circles' => array(// array of circles instances ) * ) * ); * ``` */ public function getACL() { if (null === static::$kernel) { static::bootKernel(); } $em = static::$kernel->getContainer() ->get('doctrine.orm.entity_manager'); $centers = $em->getRepository('ChillMainBundle:Center') ->findAll(); $circles = $em->getRepository('ChillMainBundle:Scope') ->findAll(); if (count($centers) === 0) { throw new RuntimeException('No center found. Did you forget to ' . 'run `doctrine:fixtures:load` command before ?'); } if (count($circles) === 0) { throw new RuntimeException('No circle found. Did you forget to ' . 'run `doctrine:fixtures:load` command before ?'); } return [[ 'center' => $centers[0], 'circles' => [ $circles, ], ]]; } /** * Create an instance of the report to test. * * @return \Chill\MainBundle\Export\ExportInterface an instance of the export to test */ abstract public function getExport(); /** * Create possible combinaison of data (produced by the form). * * This data will be used to generate data providers using this data. * * @return array an array of data. Example : `array( array(), array('fields' => array(1,2,3), ...)` where an empty array and `array(1,2,3)` are possible values */ abstract public function getFormData(); /** * get the possible modifiers which could apply in combination to this * export. * . * * @return array of string[] an array which contains an array of possible modifiers. Example : `array( array('modifier_1', 'modifier_2'), array('modifier_1'), ...)` */ abstract public function getModifiersCombination(); /** * Test the formatters type are string. */ public function testGetAllowedFormattersType() { $formattersTypes = $this->getExport()->getAllowedFormattersTypes(); $this->assertContainsOnly( 'string', $formattersTypes, 'Test that the method `getAllowedFormattersTypes` returns an array of string' ); } /** * Test that the description is not empty. */ public function testGetDescription() { $export = $this->getExport(); $this->assertInternalType( 'string', $export->getDescription(), 'Assert that the `getDescription` method return a string' ); $this->assertNotEmpty( $export->getDescription(), 'Assert that the `getDescription` method does not return an empty ' . 'string.' ); } /** * Test that the query keys are strings. * * @dataProvider dataProviderGetQueryKeys */ public function testGetQueryKeys(array $data) { $queryKeys = $this->getExport()->getQueryKeys($data); $this->assertContainsOnly( 'string', $queryKeys, 'test that the query keys returned by `getQueryKeys` are only strings' ); $this->assertGreaterThanOrEqual( 1, count($queryKeys), 'test that there are at least one query key returned' ); } /** * Test that. * * - the results have a correct form (are arrays or traversable) * - each key in a row are present in getQueryKeys ; * - each returned object of the `getLabels` method is callable * - each result can be converted to string using this callable * - each of this callable can provide a string for '_header' * * @param string[] $modifiers * @param array $acl * * @dataProvider dataProviderInitiateQuery */ public function testGetResultsAndLabels($modifiers, $acl, array $data) { // it is more convenient to group the `getResult` and `getLabels` test // due to the fact that testing both methods use the same tools. $queryKeys = $this->getExport()->getQueryKeys($data); $query = $this->getExport()->initiateQuery($modifiers, $acl, $data); // limit the result for the query for performance reason (only for QueryBuilder, // not possible in NativeQuery) if ($query instanceof QueryBuilder) { $query->setMaxResults(1); } $results = $this->getExport()->getResult($query, $data); $this->assertInternalType( 'array', $results, 'assert that the returned result is an array' ); if (count($results) === 0) { $this->markTestIncomplete('The result is empty. We cannot process tests ' . 'on results'); } // testing the result $result = $results[0]; $this->assertTrue( $result instanceof Traversable || is_array($result), 'test that each row in the result is traversable or an array' ); foreach ($result as $key => $value) { $this->assertContains( $key, $queryKeys, 'test that each key is present in `getQueryKeys`' ); $closure = $this->getExport()->getLabels($key, [$value], $data); $this->assertTrue( is_callable($closure, false), 'test that the `getLabels` for key is a callable' ); $this->assertTrue( is_string((string) call_user_func($closure, $value)), sprintf('test that the callable return by `getLabels` for key %s ' . 'is a string or an be converted to a string', $key) ); $this->assertTrue( // conditions is_string((string) call_user_func($closure, '_header')) && !empty(call_user_func($closure, '_header')) && call_user_func($closure, '_header') !== '_header', // message sprintf('Test that the callable return by `getLabels` for key %s ' . 'can provide an header', $key) ); } } /** * Test that the getType method return a string. */ public function testGetType() { $export = $this->getExport(); $this->assertInternalType( 'string', $export->getType(), 'Assert that the `getType` method return a string' ); $this->assertNotEmpty($export->getType(), 'Assert that the `getType` method' . ' does not return an empty string.'); } /** * test that the query returned is a QueryBuilder or a NativeQuery. * * If the query is a QueryBuilder, test that select and from is not empty. * * If the query is a native sql, test the query is not empty (length is * > 0). * * @dataProvider dataProviderInitiateQuery * * @param mixed $modifiers * @param mixed $acl * @param mixed $data */ public function testInitiateQuery($modifiers, $acl, $data) { $query = $this->getExport()->initiateQuery($modifiers, $acl, $data); $this->assertTrue( $query instanceof QueryBuilder || $query instanceof NativeQuery, sprintf( 'Assert that the returned query is an instance of %s or %s', QueryBuilder::class, Query::class ) ); if ($query instanceof QueryBuilder) { $this->assertGreaterThanOrEqual( 1, count($query->getDQLPart('select')), "assert there is at least one 'select' part" ); $this->assertGreaterThanOrEqual( 1, count($query->getDQLPart('from')), "assert there is at least one 'from' part" ); } elseif ($query instanceof NativeQuery) { $this->assertNotEmpty( $query->getSQL(), 'check that the SQL query is not empty' ); } } /** * Test that the translated title of the export is present the list, * and that the list of exports (under `/fr/exports/`) is still successfull. */ public function testListExportPage() { /* @var $client \Symfony\Component\BrowserKit\Client */ $client = $this->getClient(); $export = $this->getExport(); $prophet = new \Prophecy\Prophet(); $container = static::$kernel->getContainer(); // store the locale in a request $request = new Request(); $request->setLocale('fr'); $container->get('request_stack')->push($request); // translate the title $title = $container->get('translator')->trans($export->getTitle()); // performs the request to /fr/exports $crawler = $client->request('GET', '/fr/exports/'); // and finally make tests $this->assertTrue( $client->getResponse()->isSuccessful(), 'test that the response of /fr/exports/ is successful' ); $this->assertContains( $title, $crawler->text(), 'test that the page /fr/exports/ contains the title of the ' . "exports ('{$title}')" ); } /** * Test required role is an instance of Role. */ public function testRequiredRole() { $role = $this->getExport()->requiredRole(); $this->assertInstanceOf( Role::class, $role, sprintf('test that the returned value of `requiredRole` is an instance ' . 'of %s', Role::class) ); } /** * Test that supportsModifier return :. * * - an array of string, if the query is a QueryBuilder ; * - nothing, if the query is a native SQL * * @dataProvider dataProviderInitiateQuery * * @param mixed $modifiers * @param mixed $acl * @param mixed $data */ public function testSupportsModifier($modifiers, $acl, $data) { $export = $this->getExport(); $query = $export->initiateQuery($modifiers, $acl, $data); if ($query instanceof QueryBuilder) { $this->assertContainsOnly( 'string', $export->supportsModifiers(), 'Test that the `supportsModifiers` method returns only strings' ); } elseif ($query instanceof NativeQuery) { $this->assertTrue( $export->supportsModifiers() === null || count($export->supportsModifiers()) === 0, 'Test that the `supportsModifier` methods returns null or an empty array' ); } } }