Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Add command controller to create test data #1297

Merged
merged 23 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
44cfc82
[FEATURE] Add command controller to create test data
kanow May 7, 2024
aa624b2
[TASK] Remove phpDocumentor reflection type
kanow Jul 26, 2024
a067246
[DOCS] Add documentation part for command controller
kanow Jul 26, 2024
8e3de93
[BUGFIX] Fix errors from php cs fixer
kanow Jul 29, 2024
41962da
Update Classes/Command/CreateTestDataCommand.php
kanow Jul 29, 2024
393e55f
Update Classes/Command/CreateTestDataCommand.php
kanow Jul 29, 2024
91f27b0
[TASK] Move comment directly above the class
kanow Jul 29, 2024
a430e32
[TASK] Rename pageId to pageUid
kanow Jul 29, 2024
d47b590
[TASK] use assert to state data restrictions
kanow Jul 30, 2024
05c4c1a
[TASK] Update reference index after changing test data
kanow Jul 30, 2024
e96cdb0
[TASK] Remove unnecessary is_int check of pageUid
kanow Jul 30, 2024
9c3e7ef
[TASK] Add functional test for createTestDataCommand
kanow Jul 30, 2024
fde77e6
Fix broken functional test
DanielSiepmann Jul 30, 2024
a928788
[TASK] Check that existing teas in other pids were not deleted
kanow Jul 30, 2024
06e39b3
[TASK] Rename test functions
kanow Jul 30, 2024
77f9b5c
[TASK] Remove unused imports
kanow Jul 30, 2024
d8fc929
[BUGFIX] Fix some php stan errors
kanow Aug 20, 2024
ed08a12
[BUGFIX] Fix error with spread operator in php 7.4
kanow Aug 20, 2024
745f043
[BUGFIX] Remove assert of int for the page id
kanow Dec 13, 2024
b05bbb7
[BUGFIX] Refactor that pageUid stuff with assert and type of int
kanow Dec 13, 2024
5ca9abe
[TASK] Ignore error with missing type for constant
kanow Dec 16, 2024
5207568
[TASK] Rename command to improve readability
kanow Dec 16, 2024
c7f3aff
Some polish after review
oliverklee Dec 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions Classes/Command/CreateTestDataCommand.php
Original file line number Diff line number Diff line change
@@ -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
oliverklee marked this conversation as resolved.
Show resolved Hide resolved
{
/**
* @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
kanow marked this conversation as resolved.
Show resolved Hide resolved
{
$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;
}
}
11 changes: 11 additions & 0 deletions Configuration/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use TTN\Tea\Command\CreateTestDataCommand;

return static function (ContainerConfigurator $containerConfigurator) {
$services = $containerConfigurator->services()
->defaults()
Expand All @@ -12,4 +14,13 @@

$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',
]
);
};
28 changes: 28 additions & 0 deletions Documentation/CommandController.rst
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions Documentation/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ continuous integration.
ReleaseBranchingStrategy
Environment
DependencyManager
CommandController
Running
ContinuousIntegration
Documentation
Expand Down
124 changes: 124 additions & 0 deletions Tests/Functional/Command/CreateTestDataCommandTest.php
Original file line number Diff line number Diff line change
@@ -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');
}
}
4 changes: 4 additions & 0 deletions Tests/Functional/Command/Fixtures/Database/ExistingTeas.csv
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions Tests/Functional/Command/Fixtures/Database/Pages.csv
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions Tests/Functional/Command/Fixtures/Database/Teas.csv
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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