From f888b39cdb8298e25fea348ac751434ebcf5319f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 5 Feb 2016 12:51:26 +0100 Subject: [PATCH] improve test, modify exportInterface, use constants for ExportType keys - add a test for 'generate' ; - the ExportType declare keys, and those keys are used in ExportManager; - the export interface does not require the "has form" function, and export form is taken into account --- Export/ExportInterface.php | 12 +-- Export/ExportManager.php | 27 +++--- Form/Type/Export/ExportType.php | 20 +++-- Resources/views/Export/new.html.twig | 10 +++ Tests/Export/ExportManagerTest.php | 119 +++++++++++++++++++++++++-- 5 files changed, 150 insertions(+), 38 deletions(-) diff --git a/Export/ExportInterface.php b/Export/ExportInterface.php index 3a0fba63e..23716380b 100644 --- a/Export/ExportInterface.php +++ b/Export/ExportInterface.php @@ -60,17 +60,9 @@ interface ExportInterface extends ExportElementInterface * @param QueryBuilder $qb * @param array $requiredModifiers * @param array $acl an array where each row as a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` containing the reachable circles - * TODO : we should add ability to receive data from a form + * @param array $data the data from the form, if any */ - public function initiateQuery(QueryBuilder $qb, array $requiredModifiers, $acl); - - - /** - * Return wether this export has a form. - * - * @return bool - */ - public function hasForm(); + public function initiateQuery(QueryBuilder $qb, array $requiredModifiers, array $acl, array $data = array()); /** * Inform which ModifiersInterface (i.e. AggregatorInterface, FilterInterface) diff --git a/Export/ExportManager.php b/Export/ExportManager.php index e18c643cd..d605466f9 100644 --- a/Export/ExportManager.php +++ b/Export/ExportManager.php @@ -32,6 +32,7 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; +use Chill\MainBundle\Form\Type\Export\ExportType; /** * Collects all agregators, filters and export from @@ -384,14 +385,18 @@ class ExportManager $qb = $this->em->createQueryBuilder(); $centers = $this->getPickedCenters($pickedCentersData); - $qb = $export->initiateQuery($qb, $this->retrieveUsedModifiers($data), - $this->buildCenterReachableScopes($centers, $export)); + $qb = $export->initiateQuery( + $qb, + $this->retrieveUsedModifiers($data), + $this->buildCenterReachableScopes($centers, $export), + $data[ExportType::EXPORT_KEY] + ); //handle filters - $this->handleFilters($export, $qb, $data['filters'], $centers); + $this->handleFilters($export, $qb, $data[ExportType::FILTER_KEY], $centers); //handle aggregators - $this->handleAggregators($export, $qb, $data['aggregators'], $centers); + $this->handleAggregators($export, $qb, $data[ExportType::AGGREGATOR_KEY], $centers); $this->logger->debug('current query is '.$qb->getDQL(), array( 'class' => self::class, 'function' => __FUNCTION__ @@ -403,10 +408,10 @@ class ExportManager $formatter = $this->getFormatter($this->getFormatterAlias($data)); $filters = array(); - $aggregators = $this->retrieveUsedAggregators($data['aggregators']); + $aggregators = $this->retrieveUsedAggregators($data[ExportType::AGGREGATOR_KEY]); $aggregatorsData = array(); foreach($aggregators as $alias => $aggregator) { - $aggregatorsData[$alias] = $data['aggregators'][$alias]['form']; + $aggregatorsData[$alias] = $data[ExportType::AGGREGATOR_KEY][$alias]['form']; } return $formatter->getResponse($result, $formatterData, $exportAlias, $data, @@ -441,7 +446,7 @@ class ExportManager */ public function getUsedAggregatorsAliases(array $data) { - $aggregators = $this->retrieveUsedAggregators($data['aggregators']); + $aggregators = $this->retrieveUsedAggregators($data[ExportType::AGGREGATOR_KEY]); return array_keys(iterator_to_array($aggregators)); } @@ -454,7 +459,7 @@ class ExportManager */ public function getFormatterAlias(array $data) { - return $data['pick_formatter']['alias']; + return $data[ExportType::PICK_FORMATTER_KEY]['alias']; } /** @@ -478,14 +483,14 @@ class ExportManager private function retrieveUsedModifiers($data) { $usedTypes = array_merge( - $this->retrieveUsedFiltersType($data['filters']), - $this->retrieveUsedAggregatorsType($data['aggregators']) + $this->retrieveUsedFiltersType($data[ExportType::FILTER_KEY]), + $this->retrieveUsedAggregatorsType($data[ExportType::AGGREGATOR_KEY]) ); $this->logger->debug('Required types are '.implode(', ', $usedTypes), array('class' => self::class, 'function' => __FUNCTION__)); - return $usedTypes; + return array_unique($usedTypes); } /** diff --git a/Form/Type/Export/ExportType.php b/Form/Type/Export/ExportType.php index 056dcd452..16282a6b3 100644 --- a/Form/Type/Export/ExportType.php +++ b/Form/Type/Export/ExportType.php @@ -42,6 +42,11 @@ class ExportType extends AbstractType */ protected $exportManager; + const FILTER_KEY = 'filters'; + const AGGREGATOR_KEY = 'aggregators'; + const PICK_FORMATTER_KEY = 'pick_formatter'; + const EXPORT_KEY = 'export'; + public function __construct(ExportManager $exportManager) { $this->exportManager = $exportManager; @@ -51,16 +56,15 @@ class ExportType extends AbstractType { $export = $this->exportManager->getExport($options['export_alias']); - /* this part has not been experimented - if ($export->hasForm()) { - $exportBuilder = $builder->create('export', null, array('compound' => true)); + $exportBuilder = $builder->create(self::EXPORT_KEY, null, array('compound' => true)); + //if ($export->hasForm()) { $export->buildForm($exportBuilder); - $builder->add($exportBuilder); - } */ + //} + $builder->add($exportBuilder); //add filters $filters = $this->exportManager->getFiltersApplyingOn($export, $options['picked_centers']); - $filterBuilder = $builder->create('filters', 'form', array('compound' => true)); + $filterBuilder = $builder->create(self::FILTER_KEY, 'form', array('compound' => true)); foreach($filters as $alias => $filter) { $filterBuilder->add($alias, new FilterType($this->exportManager), array( @@ -74,7 +78,7 @@ class ExportType extends AbstractType //add aggregators $aggregators = $this->exportManager ->getAggregatorsApplyingOn($export, $options['picked_centers']); - $aggregatorBuilder = $builder->create('aggregators', 'form', + $aggregatorBuilder = $builder->create(self::AGGREGATOR_KEY, 'form', array('compound' => true)); foreach($aggregators as $alias => $aggregator) { @@ -86,7 +90,7 @@ class ExportType extends AbstractType $builder->add($aggregatorBuilder); - $builder->add('pick_formatter', PickFormatterType::class, array( + $builder->add(self::PICK_FORMATTER_KEY, PickFormatterType::class, array( 'export_alias' => $options['export_alias'] )); diff --git a/Resources/views/Export/new.html.twig b/Resources/views/Export/new.html.twig index acfe007c7..812999d83 100644 --- a/Resources/views/Export/new.html.twig +++ b/Resources/views/Export/new.html.twig @@ -50,6 +50,16 @@ {{ form_row(form.children.export.children.pick_formatter.children.alias) }} + {% if form.children.export.children.export.children|length > 0 %} +
+

{{ 'Export'|trans }}

+ {{ form_widget(form.children.export.children.export) }} +
+ {% else %} + {# render the children, to mark the widget as 'rendered' #} + {{ form_widget(form.children.export.children.export) }} + {% endif %} +

{{ form_widget(form.submit, { 'attr' : { 'class' : 'sc-button btn-action' } } ) }}

{{ form_end(form) }} diff --git a/Tests/Export/ExportManagerTest.php b/Tests/Export/ExportManagerTest.php index 05ef24e24..0b7f0cbee 100644 --- a/Tests/Export/ExportManagerTest.php +++ b/Tests/Export/ExportManagerTest.php @@ -27,6 +27,10 @@ use Chill\MainBundle\Export\FilterInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Chill\MainBundle\Export\ExportInterface; use Prophecy\Argument; +use Doctrine\ORM\QueryBuilder; +use Chill\MainBundle\Form\Type\Export\ExportType; +use Symfony\Component\HttpFoundation\Response; +use Chill\MainBundle\Form\Type\Export\PickCenterType; /** * Test the export manager @@ -66,6 +70,11 @@ class ExportManagerTest extends KernelTestCase $this->prophet = new \Prophecy\Prophet; } + public function tearDown() + { + $this->prophet->checkPredictions(); + } + /** * Create an ExportManager where every element may be replaced by a double. * @@ -515,11 +524,12 @@ class ExportManagerTest extends KernelTestCase $this->assertEquals(0, count($obtained)); } + /** + * Test the generation of an export + */ public function testGenerate() { - $this->markTestSkipped("work in progress"); $center = $this->prepareCenter(100, 'center'); - $centers = array($center); $user = $this->prepareUser(array()); $authorizationChecker = $this->prophet->prophesize(); @@ -531,12 +541,22 @@ class ExportManagerTest extends KernelTestCase $authorizationChecker->reveal(), null, $user); $export = $this->prophet->prophesize(); - $export->initiateQuery(Argument::any(), Argument::any(), Argument::any()) - ->willReturn(null); + $export->willImplement(ExportInterface::class); + $export->initiateQuery( + Argument::Type(QueryBuilder::class), + Argument::is(array('foo')), + Argument::Type('array'), + Argument::is(array('a' => 'b')) + ) + ->will(function ($qb) { + return $qb[0]->addSelect('COUNT(user.id) as export') + ->from('ChillMainBundle:User', 'user'); + + }); + //$export->initiateQuery()->shouldBeCalled(); $export->supportsModifiers()->willReturn(array('foo')); - $export->hasForm()->willReturn(false); - $export->requiredRole()->willReturn('CHILL_STAT_DUMMY'); - $export->getResult()->willReturn(array( + $export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY')); + $export->getResult(Argument::Type(QueryBuilder::class), Argument::Type('array'))->willReturn(array( array( 'aggregator' => 'cat a', 'export' => 0, @@ -546,9 +566,90 @@ class ExportManagerTest extends KernelTestCase 'export' => 1 ) )); - $export->getLabels()->willReturn(); + $export->getLabels( + Argument::is('export'), + Argument::is(array(0, 1)), + Argument::Type('array') + ) + ->willReturn(array( 1 => 1, 0 => 0)); + $export->getQueryKeys(Argument::Type('array'))->willReturn(array('export')); + $export->getTitle()->willReturn('dummy title'); + $exportManager->addExport($export->reveal(), 'dummy'); - $filter ; + $filter = $this->prophet->prophesize(); + $filter->willImplement(FilterInterface::class); + //$filter->alterQuery()->shouldBeCalled(); + $filter->alterQuery(Argument::Type(QueryBuilder::class), Argument::Type('array')) + ->willReturn(null); + $filter->addRole()->shouldBeCalled(); + //$filter->addRole()->shouldBeCalled(); + $filter->applyOn()->willReturn('foo'); + $exportManager->addFilter($filter->reveal(), 'filter_foo'); + + $aggregator = $this->prophet->prophesize(); + $aggregator->willImplement(AggregatorInterface::class); + $aggregator->applyOn()->willReturn('foo'); + $aggregator->alterQuery(Argument::Type(QueryBuilder::class), Argument::Type('array')) + ->willReturn(null); + //$aggregator->alterQuery()->shouldBeCalled(); + $aggregator->getQueryKeys(Argument::Type('array'))->willReturn(array('aggregator')); + $aggregator->getLabels( + Argument::is('aggregator'), + Argument::is(array('cat a', 'cat b')), + Argument::is(array()) + ) + ->willReturn(array( + 'cat a' => 'label cat a', 'cat b' => 'label cat b' + )); + $aggregator->addRole()->willReturn(null); + //$aggregator->addRole()->shouldBeCalled(); + $exportManager->addAggregator($aggregator->reveal(), 'aggregator_foo'); + + //add csv formatter + $formatter = new \Chill\MainBundle\Export\Formatter\CSVFormatter( + $this->container->get('translator'), $exportManager); + $exportManager->addFormatter($formatter, 'csv'); + + ob_start(); + $response = $exportManager->generate('dummy', + array(PickCenterType::CENTERS_IDENTIFIERS => array($center)), + array( + ExportType::FILTER_KEY => array( + 'filter_foo' => array( + 'enabled' => true, + 'form' => array() + ) + ), + ExportType::AGGREGATOR_KEY => array( + 'aggregator_foo' => array( + 'enabled' => true, + 'form' => array() + ) + ), + ExportType::PICK_FORMATTER_KEY => array( + 'alias' => 'csv' + ), + ExportType::EXPORT_KEY => array( + 'a' => 'b' + ) + ), + array( + 'aggregator_foo' => array( + 'order' => 1, 'position' => 'r' + ) + ) + ); + $content = ob_get_clean(); + $this->assertInstanceOf(Response::class, $response); + $expected = <<assertEquals($expected, $content); } }