mirror of
https://github.com/FriendsOfTYPO3/tea.git
synced 2024-12-22 13:06:11 +01:00
[FEATURE] Add command controller to create test data (#1297)
Fixes #1120
This commit is contained in:
parent
68eb2e1e2f
commit
565666b030
12 changed files with 279 additions and 0 deletions
83
Classes/Command/CreateTestDataCommand.php
Normal file
83
Classes/Command/CreateTestDataCommand.php
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace TTN\Tea\Command;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
|
use TYPO3\CMS\Core\Database\ReferenceIndex;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command to create test data for the tea extension.
|
||||||
|
*/
|
||||||
|
final class CreateTestDataCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var list<array{title: non-empty-string, description: non-empty-string, sys_language_uid: int<0, max>}>
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||||
|
|
||||||
|
use TTN\Tea\Command\CreateTestDataCommand;
|
||||||
|
|
||||||
return static function (ContainerConfigurator $containerConfigurator) {
|
return static function (ContainerConfigurator $containerConfigurator) {
|
||||||
$services = $containerConfigurator->services()
|
$services = $containerConfigurator->services()
|
||||||
->defaults()
|
->defaults()
|
||||||
|
@ -12,4 +14,13 @@ return static function (ContainerConfigurator $containerConfigurator) {
|
||||||
|
|
||||||
$services->load('TTN\\Tea\\', '../Classes/*')
|
$services->load('TTN\\Tea\\', '../Classes/*')
|
||||||
->exclude('../Classes/Domain/Model/*');
|
->exclude('../Classes/Domain/Model/*');
|
||||||
|
|
||||||
|
$services->set(CreateTestDataCommand::class)
|
||||||
|
->tag(
|
||||||
|
'console.command',
|
||||||
|
[
|
||||||
|
'command' => 'tea:create-test-data',
|
||||||
|
'description' => 'Create test data in existing sysfolder',
|
||||||
|
]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
28
Documentation/CommandController.rst
Normal file
28
Documentation/CommandController.rst
Normal file
|
@ -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 <t3coreapi:console-command-tutorial-create>`
|
||||||
|
tutorial.
|
|
@ -47,6 +47,7 @@ continuous integration.
|
||||||
ReleaseBranchingStrategy
|
ReleaseBranchingStrategy
|
||||||
Environment
|
Environment
|
||||||
DependencyManager
|
DependencyManager
|
||||||
|
CommandController
|
||||||
Running
|
Running
|
||||||
ContinuousIntegration
|
ContinuousIntegration
|
||||||
Documentation
|
Documentation
|
||||||
|
|
124
Tests/Functional/Command/CreateTestDataCommandTest.php
Normal file
124
Tests/Functional/Command/CreateTestDataCommandTest.php
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace TTN\Tea\Tests\Functional\Command;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
use TTN\Tea\Command\CreateTestDataCommand;
|
||||||
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \TTN\Tea\Command\CreateTestDataCommand
|
||||||
|
*/
|
||||||
|
final class CreateTestDataCommandTest extends FunctionalTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var non-empty-string
|
||||||
|
*/
|
||||||
|
private const COMMAND_NAME = 'tea:create-test-data';
|
||||||
|
|
||||||
|
protected array $testExtensionsToLoad = ['ttn/tea'];
|
||||||
|
|
||||||
|
private CreateTestDataCommand $subject;
|
||||||
|
|
||||||
|
private CommandTester $commandTester;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->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');
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -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
|
Can't render this file because it has a wrong number of fields in line 2.
|
4
Tests/Functional/Command/Fixtures/Database/Pages.csv
Normal file
4
Tests/Functional/Command/Fixtures/Database/Pages.csv
Normal file
|
@ -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",,,
|
|
4
Tests/Functional/Command/Fixtures/Database/Teas.csv
Normal file
4
Tests/Functional/Command/Fixtures/Database/Teas.csv
Normal file
|
@ -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
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -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
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -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
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -53,3 +53,7 @@ parameters:
|
||||||
- '$_FILES'
|
- '$_FILES'
|
||||||
- '$_SERVER'
|
- '$_SERVER'
|
||||||
message: 'Use PSR-7 API instead'
|
message: 'Use PSR-7 API instead'
|
||||||
|
ignoreErrors:
|
||||||
|
-
|
||||||
|
message: '#Out of 1 possible constant types#'
|
||||||
|
path: Tests/Functional/Command/CreateTestDataCommandTest.php
|
||||||
|
|
Loading…
Reference in a new issue