From 565666b0306ae943a34840e244ee0c54fcf679b9 Mon Sep 17 00:00:00 2001 From: Karsten Nowak Date: Sat, 21 Dec 2024 19:00:41 +0100 Subject: [PATCH] [FEATURE] Add command controller to create test data (#1297) Fixes #1120 --- Classes/Command/CreateTestDataCommand.php | 83 ++++++++++++ Configuration/Services.php | 11 ++ Documentation/CommandController.rst | 28 ++++ Documentation/Index.rst | 1 + .../Command/CreateTestDataCommandTest.php | 124 ++++++++++++++++++ .../Fixtures/Database/ExistingTeas.csv | 4 + .../Fixtures/Database/OtherExistingTeas.csv | 6 + .../Command/Fixtures/Database/Pages.csv | 4 + .../Command/Fixtures/Database/Teas.csv | 4 + .../Fixtures/Database/TeasAfterDelete.csv | 4 + .../TeasAfterDeleteOtherExistingTeas.csv | 6 + phpstan.neon | 4 + 12 files changed, 279 insertions(+) create mode 100644 Classes/Command/CreateTestDataCommand.php create mode 100644 Documentation/CommandController.rst create mode 100644 Tests/Functional/Command/CreateTestDataCommandTest.php create mode 100644 Tests/Functional/Command/Fixtures/Database/ExistingTeas.csv create mode 100644 Tests/Functional/Command/Fixtures/Database/OtherExistingTeas.csv create mode 100644 Tests/Functional/Command/Fixtures/Database/Pages.csv create mode 100644 Tests/Functional/Command/Fixtures/Database/Teas.csv create mode 100644 Tests/Functional/Command/Fixtures/Database/TeasAfterDelete.csv create mode 100644 Tests/Functional/Command/Fixtures/Database/TeasAfterDeleteOtherExistingTeas.csv diff --git a/Classes/Command/CreateTestDataCommand.php b/Classes/Command/CreateTestDataCommand.php new file mode 100644 index 0000000..ac5247e --- /dev/null +++ b/Classes/Command/CreateTestDataCommand.php @@ -0,0 +1,83 @@ +}> + */ + protected array $teaData = [ + [ + 'title' => 'Darjeeling', + 'description' => 'I love that tea!', + 'sys_language_uid' => 0, + ], + [ + 'title' => 'Earl Grey', + 'description' => 'A nice tea!', + 'sys_language_uid' => 0, + ], + ]; + + protected function configure(): void + { + $this + ->setHelp('Create test data for the tea extension in an already existing page (sysfolder).') + ->addArgument( + 'pageUid', + InputArgument::REQUIRED, + 'Existing sysfolder page id.' + ) + ->addOption( + 'delete-data-before', + 'd', + InputOption::VALUE_NONE, + 'Delete all tea data in the defined pid before creating new data.' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $pageUid = $input->getArgument('pageUid') ?? 0; + \assert(\is_int($pageUid)); + $deleteDataBefore = $input->getOption('delete-data-before') ?? false; + \assert(\is_bool($deleteDataBefore)); + $table = 'tx_tea_domain_model_tea'; + $connectionForTable = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table); + + if ($deleteDataBefore) { + $query = $connectionForTable; + $query->delete($table, ['pid' => $pageUid], [Connection::PARAM_INT]); + $output->writeln(sprintf('Existing data in page %s deleted.', $pageUid)); + } + + $query = $connectionForTable; + foreach ($this->teaData as $item) { + $item = ['pid' => $pageUid, 'title' => $item['title'], 'description' => $item['description']]; + $query->insert($table, $item); + } + $output->writeln(\sprintf('Test data in page %s created.', $pageUid)); + + $referenceIndex = GeneralUtility::makeInstance(ReferenceIndex::class); + $referenceIndex->updateIndex(false); + $output->writeln('Reference index updated.'); + + return Command::SUCCESS; + } +} diff --git a/Configuration/Services.php b/Configuration/Services.php index f0f766f..15370d6 100644 --- a/Configuration/Services.php +++ b/Configuration/Services.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use TTN\Tea\Command\CreateTestDataCommand; + return static function (ContainerConfigurator $containerConfigurator) { $services = $containerConfigurator->services() ->defaults() @@ -12,4 +14,13 @@ return static function (ContainerConfigurator $containerConfigurator) { $services->load('TTN\\Tea\\', '../Classes/*') ->exclude('../Classes/Domain/Model/*'); + + $services->set(CreateTestDataCommand::class) + ->tag( + 'console.command', + [ + 'command' => 'tea:create-test-data', + 'description' => 'Create test data in existing sysfolder', + ] + ); }; diff --git a/Documentation/CommandController.rst b/Documentation/CommandController.rst new file mode 100644 index 0000000..5ed36d9 --- /dev/null +++ b/Documentation/CommandController.rst @@ -0,0 +1,28 @@ +.. include:: /Includes.rst.txt + +.. _command-controller: + +================== +Command Controller +================== + +The "tea" extension comes with a CommandController that can be used for the +automatic creation of test data. It also serves to illustrate how data can be +created in the database using a command controller. + +You must set a page id as argument. Therefore it's necessary to create an +sysfolder before. + +You can add option `-d` to delete already existing data. + + +.. code-block:: bash + + vendor/bin/typo3 tea:create-test-data 3 + + +.. seealso:: + + For further details to Console Commands read the + :ref:`Creating a basic command ` + tutorial. diff --git a/Documentation/Index.rst b/Documentation/Index.rst index 0bcfdb5..84aac66 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -47,6 +47,7 @@ continuous integration. ReleaseBranchingStrategy Environment DependencyManager + CommandController Running ContinuousIntegration Documentation diff --git a/Tests/Functional/Command/CreateTestDataCommandTest.php b/Tests/Functional/Command/CreateTestDataCommandTest.php new file mode 100644 index 0000000..00c558c --- /dev/null +++ b/Tests/Functional/Command/CreateTestDataCommandTest.php @@ -0,0 +1,124 @@ +importCSVDataSet(__DIR__ . '/Fixtures/Database/Pages.csv'); + $this->subject = new CreateTestDataCommand(self::COMMAND_NAME); + $application = new Application(); + $application->add($this->subject); + + $command = $application->find('tea:create-test-data'); + $this->commandTester = new CommandTester($command); + } + + /** + * @test + */ + public function isConsoleCommand(): void + { + self::assertInstanceOf(Command::class, $this->subject); + } + + /** + * @test + */ + public function hasDescription(): void + { + $expected = 'Create test data for the tea extension in an already existing page (sysfolder).'; + self::assertSame($expected, $this->subject->getHelp()); + } + + /** + * @test + */ + public function hasHelpText(): void + { + $expected = 'Create test data for the tea extension in an already existing page (sysfolder).'; + self::assertSame($expected, $this->subject->getHelp()); + } + + /** + * @test + */ + public function runReturnsSuccessStatus(): void + { + $result = $this->commandTester->execute( + [ + 'pageUid' => 1, + ], + ); + + self::assertSame(Command::SUCCESS, $result); + } + + /** + * @test + */ + public function createsTestData(): void + { + $this->commandTester->execute([ + 'pageUid' => 1, + ]); + + $this->assertCSVDataSet(__DIR__ . '/Fixtures/Database/Teas.csv'); + } + + /** + * @test + */ + public function deletesExistingDataOnGivenPidBeforeCreatingNewData(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/Database/ExistingTeas.csv'); + $this->commandTester->execute( + [ + 'pageUid' => 1, + '--delete-data-before' => true, + ] + ); + + $this->assertCSVDataSet(__DIR__ . '/Fixtures/Database/TeasAfterDelete.csv'); + } + + /** + * @test + */ + public function doesNotDeleteDataOnOtherPid(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/Database/OtherExistingTeas.csv'); + $this->commandTester->execute( + [ + 'pageUid' => 1, + '--delete-data-before' => true, + ] + ); + + $this->assertCSVDataSet(__DIR__ . '/Fixtures/Database/TeasAfterDeleteOtherExistingTeas.csv'); + } +} diff --git a/Tests/Functional/Command/Fixtures/Database/ExistingTeas.csv b/Tests/Functional/Command/Fixtures/Database/ExistingTeas.csv new file mode 100644 index 0000000..e1dd287 --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/ExistingTeas.csv @@ -0,0 +1,4 @@ +"tx_tea_domain_model_tea" +,"uid","pid","title","description","deleted" +,1,1,"Darjeeling","Which already existed in the system",0 +,2,1,"Earl Grey","Which already existed in the system",0 diff --git a/Tests/Functional/Command/Fixtures/Database/OtherExistingTeas.csv b/Tests/Functional/Command/Fixtures/Database/OtherExistingTeas.csv new file mode 100644 index 0000000..f78bd2e --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/OtherExistingTeas.csv @@ -0,0 +1,6 @@ +"tx_tea_domain_model_tea" +,"uid","pid","title","description","deleted" +,3,1,"Darjeeling","Exists and should be deleted","0" +,4,1,"Earl Grey","Exists and should be deleted","0" +,1,2,"Darjeeling","Which already existed in the system",0 +,2,2,"Earl Grey","Which already existed in the system",0 diff --git a/Tests/Functional/Command/Fixtures/Database/Pages.csv b/Tests/Functional/Command/Fixtures/Database/Pages.csv new file mode 100644 index 0000000..f4878eb --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/Pages.csv @@ -0,0 +1,4 @@ +"pages",,,,,,,,, +,"uid","pid","sorting","deleted","t3_origuid","title",,, +,1,0,256,0,0,"Tea data",,, +,2,0,512,0,0,"Other tea data",,, diff --git a/Tests/Functional/Command/Fixtures/Database/Teas.csv b/Tests/Functional/Command/Fixtures/Database/Teas.csv new file mode 100644 index 0000000..40e686b --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/Teas.csv @@ -0,0 +1,4 @@ +"tx_tea_domain_model_tea" +,"uid","pid","title","description","deleted" +,1,1,"Darjeeling","I love that tea!",0 +,2,1,"Earl Grey","A nice tea!",0 diff --git a/Tests/Functional/Command/Fixtures/Database/TeasAfterDelete.csv b/Tests/Functional/Command/Fixtures/Database/TeasAfterDelete.csv new file mode 100644 index 0000000..c0a2aec --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/TeasAfterDelete.csv @@ -0,0 +1,4 @@ +"tx_tea_domain_model_tea" +,"pid","title","description","deleted" +,1,"Darjeeling","I love that tea!",0 +,1,"Earl Grey","A nice tea!",0 diff --git a/Tests/Functional/Command/Fixtures/Database/TeasAfterDeleteOtherExistingTeas.csv b/Tests/Functional/Command/Fixtures/Database/TeasAfterDeleteOtherExistingTeas.csv new file mode 100644 index 0000000..a427bf0 --- /dev/null +++ b/Tests/Functional/Command/Fixtures/Database/TeasAfterDeleteOtherExistingTeas.csv @@ -0,0 +1,6 @@ +"tx_tea_domain_model_tea" +,"pid","title","description","deleted" +,1,"Darjeeling","I love that tea!",0 +,1,"Earl Grey","A nice tea!",0 +,2,"Darjeeling","Which already existed in the system",0 +,2,"Earl Grey","Which already existed in the system",0 diff --git a/phpstan.neon b/phpstan.neon index 58d6f6d..aabb7d1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -53,3 +53,7 @@ parameters: - '$_FILES' - '$_SERVER' message: 'Use PSR-7 API instead' + ignoreErrors: + - + message: '#Out of 1 possible constant types#' + path: Tests/Functional/Command/CreateTestDataCommandTest.php