From 641cd5694eb82a71dc7390902f89d53e8c781fb9 Mon Sep 17 00:00:00 2001 From: Marko Kunic Date: Mon, 23 Jul 2018 22:40:05 +0200 Subject: [PATCH] tests --- README.md | 4 +- phpunit.xml.dist | 1 + ...Extension.php => AdminImportExtension.php} | 2 +- src/Resources/config/extensions.xml | 2 +- tests/Admin/AdminImportExtensionTest.php | 72 +++++++++ tests/Controller/ImportCRUDControllerTest.php | 136 +++++++++++++++++ .../AutoConfigureCompilerPassTest.php | 140 ++++++++++++++++++ .../SonataImporterExtensionTest.php | 31 ++++ tests/Fixtures/Admin.php | 25 ++++ tests/Fixtures/CRUDController.php | 80 ++++++++++ tests/Fixtures/Controller.php | 17 +++ tests/Fixtures/ImportConfiguration.php | 32 ++++ tests/Fixtures/fake.csv | 6 + tests/Form/AdminImportTest.php | 53 +++++++ tests/SonataImporterBundleTest.php | 45 ++++++ 15 files changed, 642 insertions(+), 4 deletions(-) rename src/Admin/{ImportAdminExtension.php => AdminImportExtension.php} (94%) create mode 100644 tests/Admin/AdminImportExtensionTest.php create mode 100644 tests/Controller/ImportCRUDControllerTest.php create mode 100644 tests/DependencyInjection/Compiler/AutoConfigureCompilerPassTest.php create mode 100644 tests/DependencyInjection/SonataImporterExtensionTest.php create mode 100644 tests/Fixtures/Admin.php create mode 100644 tests/Fixtures/CRUDController.php create mode 100644 tests/Fixtures/Controller.php create mode 100644 tests/Fixtures/ImportConfiguration.php create mode 100644 tests/Fixtures/fake.csv create mode 100644 tests/Form/AdminImportTest.php create mode 100644 tests/SonataImporterBundleTest.php diff --git a/README.md b/README.md index e564654..631c255 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ Easier handling of Import in Sonata Admin. Built on top of [Importer](https://github.com/kunicmarko20/importer). [![PHP Version](https://img.shields.io/badge/php-%5E7.1-blue.svg)](https://img.shields.io/badge/php-%5E7.1-blue.svg) -[![Latest Stable Version](https://poser.pugx.org/kunicmarko/SonataImporterBundle/v/stable)](https://packagist.org/packages/kunicmarko/SonataImporterBundle) -[![Latest Unstable Version](https://poser.pugx.org/kunicmarko/SonataImporterBundle/v/unstable)](https://packagist.org/packages/kunicmarko/SonataImporterBundle) +[![Latest Stable Version](https://poser.pugx.org/kunicmarko/sonata-importer-bundle/v/stable)](https://packagist.org/packages/kunicmarko/sonata-importer-bundle) +[![Latest Unstable Version](https://poser.pugx.org/kunicmarko/sonata-importer-bundle/v/unstable)](https://packagist.org/packages/kunicmarko/sonata-importer-bundle) [![Build Status](https://travis-ci.org/kunicmarko20/SonataImporterBundle.svg?branch=master)](https://travis-ci.org/kunicmarko20/SonataImporterBundle) [![Coverage Status](https://coveralls.io/repos/github/kunicmarko20/SonataImporterBundle/badge.svg?branch=master)](https://coveralls.io/github/kunicmarko20/SonataImporterBundle?branch=master) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dac926f..0ac0a9e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -21,6 +21,7 @@ ./src/ ./vendor/ + ./src/Exception/ diff --git a/src/Admin/ImportAdminExtension.php b/src/Admin/AdminImportExtension.php similarity index 94% rename from src/Admin/ImportAdminExtension.php rename to src/Admin/AdminImportExtension.php index d10a199..ebd520e 100644 --- a/src/Admin/ImportAdminExtension.php +++ b/src/Admin/AdminImportExtension.php @@ -11,7 +11,7 @@ /** * @author Marko Kunic */ -final class ImportAdminExtension extends AbstractAdminExtension +final class AdminImportExtension extends AbstractAdminExtension { /** * @var array diff --git a/src/Resources/config/extensions.xml b/src/Resources/config/extensions.xml index 1bd204f..7b4c6d2 100644 --- a/src/Resources/config/extensions.xml +++ b/src/Resources/config/extensions.xml @@ -4,7 +4,7 @@ %sonata.importer.templates% - + diff --git a/tests/Admin/AdminImportExtensionTest.php b/tests/Admin/AdminImportExtensionTest.php new file mode 100644 index 0000000..61302dd --- /dev/null +++ b/tests/Admin/AdminImportExtensionTest.php @@ -0,0 +1,72 @@ + + */ +class AdminImportExtensionTest extends TestCase +{ + /** + * @var AdminImportExtension + */ + private $extension; + + public function setUp() + { + $this->extension = new AdminImportExtension([ + 'action_button' => 'action_button_template', + 'dashboard_action' => 'dashboard_action_template', + ]); + } + + public function testConfigureRoutes() + { + $routeCollection = $this->prophesize(RouteCollection::class); + $routeCollection->add(Argument::type('string'))->shouldBeCalled(); + + $this->extension->configureRoutes(new class('', '', '') extends AbstractAdmin implements AdminWithImport { + + }, $routeCollection->reveal()); + } + + public function testConfigureRoutesNoCall() + { + $routeCollection = $this->prophesize(RouteCollection::class); + $routeCollection->add()->shouldNotBeCalled(); + + $this->extension->configureRoutes($this->getAdmin(), $routeCollection->reveal()); + } + + private function getAdmin(): AdminInterface + { + return new class('', '', '') extends AbstractAdmin { + }; + } + + public function testConfigureActionButtons(): void + { + $result = $this->extension->configureActionButtons($this->getAdmin(), [], null, null); + + $this->assertArrayHasKey('import', $result); + $this->assertArrayHasKey('template', $result['import']); + $this->assertSame('action_button_template', $result['import']['template']); + } + + public function testConfigureDashboardActions(): void + { + $result = $this->extension->configureDashboardActions($this->getAdmin(), []); + + $this->assertArrayHasKey('import', $result); + $this->assertArrayHasKey('template', $result['import']); + $this->assertSame('dashboard_action_template', $result['import']['template']); + } +} diff --git a/tests/Controller/ImportCRUDControllerTest.php b/tests/Controller/ImportCRUDControllerTest.php new file mode 100644 index 0000000..dc1ada3 --- /dev/null +++ b/tests/Controller/ImportCRUDControllerTest.php @@ -0,0 +1,136 @@ + + */ +class ImportCRUDControllerTest extends TestCase +{ + /** + * @var CRUDController + */ + private $controller; + + /** + * @var FormInterface + */ + private $form; + + /** + * @var ContainerInterface + */ + private $container; + + /** + * @var Admin + */ + private $admin; + + /** + * @var UploadedFile|MockObject + */ + private $file; + + public function setUp() + { + $this->form = $this->prophesize(FormInterface::class); + $this->form->handleRequest(Argument::cetera())->shouldBeCalled(); + + $this->container = $this->prophesize(ContainerInterface::class); + $this->container->getParameter(Argument::cetera())->willReturn(['form' => 'form.template']); + + $this->admin = new Admin(); + + $this->file = $this->getMockBuilder(UploadedFile::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->controller = new CRUDController( + $this->form->reveal(), + $this->container->reveal(), + $this->admin, + $this->file + ); + + $importerFactory = new ImporterFactory(); + $importerFactory->addReader(new CsvReader()); + $this->controller->setImporterFactory($importerFactory); + } + + public function testNotSubmitted() + { + $this->form->createView(Argument::cetera())->shouldBeCalled(); + $this->form->isSubmitted()->willReturn(false); + + $this->controller->importAction(new Request()); + } + + public function testNotValid() + { + $this->form->createView(Argument::cetera())->shouldBeCalled(); + $this->form->isSubmitted()->willReturn(true); + $this->form->isValid()->willReturn(false); + + $this->controller->importAction(new Request()); + } + + public function testNoImportConfiguration() + { + $this->form->isSubmitted()->willReturn(true); + $this->form->isValid()->willReturn(true); + + $this->file->expects($this->once()) + ->method('getClientOriginalExtension') + ->willReturn($type = 'csv'); + + $this->controller->importAction(new Request()); + } + + public function testMissingImportConfigurationForType() + { + $this->form->isSubmitted()->willReturn(true); + $this->form->isValid()->willReturn(true); + + $this->file->expects($this->once()) + ->method('getClientOriginalExtension') + ->willReturn($type = 'csv'); + + + $this->controller->setImportConfigurations([Admin::class => []]); + $this->controller->importAction(new Request()); + } + + public function testValid() + { + $this->form->isSubmitted()->willReturn(true); + $this->form->isValid()->willReturn(true); + + $this->file->expects($this->once()) + ->method('getClientOriginalExtension') + ->willReturn($type = 'csv'); + + $this->file->expects($this->once()) + ->method('getPathname') + ->willReturn(__DIR__ . '/../Fixtures/fake.csv'); + + $this->controller->flashType = 'success'; + $this->admin->route = 'list'; + + $this->controller->setImportConfigurations([Admin::class => [$type => new ImportConfiguration()]]); + $this->controller->importAction(new Request()); + } +} diff --git a/tests/DependencyInjection/Compiler/AutoConfigureCompilerPassTest.php b/tests/DependencyInjection/Compiler/AutoConfigureCompilerPassTest.php new file mode 100644 index 0000000..6295001 --- /dev/null +++ b/tests/DependencyInjection/Compiler/AutoConfigureCompilerPassTest.php @@ -0,0 +1,140 @@ + + */ +class AutoConfigureCompilerPassTest extends TestCase +{ + /** + * @var AutoConfigureCompilerPass + */ + private $compilerPass; + + /** + * @var ContainerBuilder + */ + private $containerBuilder; + + public function setUp(): void + { + $this->compilerPass = new AutoConfigureCompilerPass(); + $this->containerBuilder = new ContainerBuilder(); + } + + public function testProcess(): void + { + $this->containerBuilder->setDefinition( + 'admin', + ($adminDefinition = new Definition( + Admin::class, + [ + 0, + 1, + 'SonataAdminBundle:CRUD' + ] + ) + )->setTags([ + 'sonata.importer.admin' => [], + 'sonata.admin' => [], + ]) + ); + + $this->containerBuilder->setDefinition( + 'controller', + ($controllerDefinition = new Definition( + Controller::class + ) + )->setTags([ + 'sonata.importer.controller' => [], + ]) + ); + + $this->containerBuilder->setDefinition( + 'importConfiguration', + (new Definition( + ImportConfiguration::class + ) + )->setTags([ + 'sonata.importer.configuration' => [], + ]) + ); + + $this->compilerPass->process($this->containerBuilder); + + $this->assertSame(ImportCRUDController::class, $adminDefinition->getArgument(2)); + + $methodCall = $controllerDefinition->getMethodCalls()[0]; + $methodName = $methodCall[0]; + $methodArguments = $methodCall[1][0]; + + $this->assertSame('setImportConfigurations', $methodName); + $this->assertCount(1, $methodArguments); + $this->assertSame(Admin::class, key($methodArguments)); + $this->assertSame('csv', key($methodArguments[Admin::class])); + $this->assertSame(ImportConfiguration::class, $methodArguments[Admin::class]['csv']->getClass()); + } + + /** + * @expectedException \KunicMarko\SonataImporterBundle\Exception\ImportConfigurationMissingInterface + */ + public function testProcessImportConfigurationMissing(): void + { + $this->containerBuilder->setDefinition( + 'importConfigurationMissing', + (new Definition( + self::class + ) + )->setTags([ + 'sonata.importer.configuration' => [], + ]) + ); + + $this->compilerPass->process($this->containerBuilder); + } + + /** + * @expectedException \KunicMarko\SonataImporterBundle\Exception\ControllerMissingMethod + */ + public function testProcessControllerMissingMethod(): void + { + $this->containerBuilder->setDefinition( + 'import admin that isn\'t sonata admin', + (new Definition( + Admin::class, + [ + 0, + 1, + 'SonataAdminBundle:CRUD' + ] + ) + )->setTags([ + 'sonata.importer.admin' => [], + ]) + ); + + $this->containerBuilder->setDefinition( + 'controllerMissingMethod', + (new Definition( + self::class + ) + )->setTags([ + 'sonata.importer.controller' => [], + ]) + ); + + $this->compilerPass->process($this->containerBuilder); + } +} diff --git a/tests/DependencyInjection/SonataImporterExtensionTest.php b/tests/DependencyInjection/SonataImporterExtensionTest.php new file mode 100644 index 0000000..e0097b5 --- /dev/null +++ b/tests/DependencyInjection/SonataImporterExtensionTest.php @@ -0,0 +1,31 @@ + + */ +final class SonataImporterExtensionTest extends AbstractExtensionTestCase +{ + public function testLoadsFormServiceDefinition(): void + { + $this->container->setParameter('kernel.project_dir', $param = 'test'); + + $this->load(); + + $this->assertContainerBuilderHasService( + ImportCRUDController::class + ); + } + + protected function getContainerExtensions(): array + { + return [new SonataImporterExtension()]; + } +} diff --git a/tests/Fixtures/Admin.php b/tests/Fixtures/Admin.php new file mode 100644 index 0000000..07fe2bd --- /dev/null +++ b/tests/Fixtures/Admin.php @@ -0,0 +1,25 @@ + + */ +class Admin extends TestCase +{ + /** + * @var string + */ + public $route = 'import'; + + public function generateUrl(string $route) + { + $this->assertSame($this->route, $route); + + return 'test'; + } +} diff --git a/tests/Fixtures/CRUDController.php b/tests/Fixtures/CRUDController.php new file mode 100644 index 0000000..35df39a --- /dev/null +++ b/tests/Fixtures/CRUDController.php @@ -0,0 +1,80 @@ + + */ +class CRUDController extends TestCase +{ + use ImportActionTrait; + + /** + * @var FormInterface + */ + private $form; + + /** + * @var ContainerInterface + */ + public $container; + + /** + * @var AdminInterface + */ + public $admin; + + /** + * @var string + */ + public $flashType = 'error'; + + /** + * @var UploadedFile + */ + private $file; + + public function __construct( + FormInterface $form, + ContainerInterface $container, + $admin, + UploadedFile $file + ) { + parent::__construct(); + $this->form = $form; + $this->container = $container; + $this->admin = $admin; + $this->file = $file; + } + + public function createForm(string $formName, AdminImportDTO $object): FormInterface + { + $this->assertSame(AdminImportForm::class, $formName); + + $object->file = $this->file; + + return $this->form; + } + + public function renderWithExtraParams(string $template, array $parameters) + { + $this->assertSame('form.template', $template); + + return new Response(); + } + + public function addFlash(string $type, string $message) + { + $this->assertSame($this->flashType, $type); + } +} diff --git a/tests/Fixtures/Controller.php b/tests/Fixtures/Controller.php new file mode 100644 index 0000000..0ded0b8 --- /dev/null +++ b/tests/Fixtures/Controller.php @@ -0,0 +1,17 @@ + + */ +class Controller extends TestCase +{ + public function setImportConfigurations(): void + { + } +} diff --git a/tests/Fixtures/ImportConfiguration.php b/tests/Fixtures/ImportConfiguration.php new file mode 100644 index 0000000..f138065 --- /dev/null +++ b/tests/Fixtures/ImportConfiguration.php @@ -0,0 +1,32 @@ + + */ +class ImportConfiguration extends TestCase implements SonataImportConfiguration +{ + public function map(array $item, array $additionalData) + { + } + + public function save(array $items, array $additionalData): void + { + } + + public static function adminClass(): string + { + return Admin::class; + } + + public static function format(): string + { + return 'csv'; + } +} diff --git a/tests/Fixtures/fake.csv b/tests/Fixtures/fake.csv new file mode 100644 index 0000000..3a606e4 --- /dev/null +++ b/tests/Fixtures/fake.csv @@ -0,0 +1,6 @@ +1,G.E. Longer-Life Indoor Recessed Floodlight Bulbs,Carlos Soltero,515,4.43,6.64,4.95,Nunavut,Office Furnishings,0.37 +2,"Angle-D Binders with Locking Rings, Label Holders",Carl Jackson,613,-54.04,7.3,7.72,Nunavut,Binders and Binder Accessories,0.38 +3,"SAFCO Mobile Desk Side File, Wire Frame",Carl Jackson,613,127.70,42.76,6.22,Nunavut,Storage & Organization, +4,"SAFCO Commercial Wire Shelving, Black",Monica Federle,643,-695.26,138.14,35,Nunavut,Storage & Organization, +5,Xerox 198,Dorothy Badders,678,-226.36,4.98,8.33,Nunavut,Paper,0.38 +6,Xerox 1980,Neola Schneider,807,-166.85,4.28,6.18,Nunavut,Paper,0.4 diff --git a/tests/Form/AdminImportTest.php b/tests/Form/AdminImportTest.php new file mode 100644 index 0000000..a90b094 --- /dev/null +++ b/tests/Form/AdminImportTest.php @@ -0,0 +1,53 @@ + + */ +class AdminImportTest extends TypeTestCase +{ + /** + * @var UploadedFile + */ + private $uploadedFile; + + private $file; + + public function setUp() + { + parent::setUp(); + + $this->uploadedFile = new UploadedFile( + $this->file = tempnam(sys_get_temp_dir(), 'test'), + 'imp.csv' + ); + } + + public function testSubmitValidData(): void + { + $form = $this->factory->create( + AdminImportForm::class, + new AdminImportDTO() + ); + + $form->submit([ + 'file' => $this->uploadedFile + ]); + + $this->assertTrue($form->isSynchronized()); + $view = $form->createView(); + + $this->assertArrayHasKey('file', $view->children); + } + + public function tearDown() + { + unlink($this->file); + } +} diff --git a/tests/SonataImporterBundleTest.php b/tests/SonataImporterBundleTest.php new file mode 100644 index 0000000..1a01d61 --- /dev/null +++ b/tests/SonataImporterBundleTest.php @@ -0,0 +1,45 @@ + + */ +final class SonataImporterBundleTest extends TestCase +{ + /** + * @var SonataImporterBundle + */ + private $bundle; + + protected function setUp() + { + $this->bundle = new SonataImporterBundle(); + } + + public function testBundle(): void + { + $this->assertInstanceOf(Bundle::class, $this->bundle); + } + + public function testCompilerPasses(): void + { + $containerBuilder = $this->prophesize(ContainerBuilder::class); + + $containerBuilder->addCompilerPass( + Argument::type(AutoConfigureCompilerPass::class), + Argument::cetera() + )->shouldBeCalledTimes(1); + + $this->bundle->build($containerBuilder->reveal()); + } +}