configurable csv/xlsx export templates (#5531)

This commit is contained in:
Kevin Papst
2025-06-11 13:06:33 +02:00
committed by GitHub
parent 46129c7ab9
commit 05aaa1950a
83 changed files with 2632 additions and 412 deletions

View File

@@ -27,7 +27,7 @@ class ColorChoicesValidatorTest extends ConstraintValidatorTestCase
return new ColorChoicesValidator();
}
public static function getValidColors()
public static function getValidColors(): iterable
{
yield ['#000000'];
yield ['#fff000'];
@@ -57,7 +57,7 @@ class ColorChoicesValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
public static function getInvalidColors()
public static function getInvalidColors(): iterable
{
yield ['sdf_sdf|#000000', null, 'sdf_sdf', '#000000'];
yield ['sdfghjklöß.|#aaabbb', null, 'sdfghjklöß.', '#aaabbb'];

View File

@@ -27,7 +27,7 @@ class DateTimeFormatValidatorTest extends ConstraintValidatorTestCase
return new DateTimeFormatValidator();
}
public static function getValidData()
public static function getValidData(): array
{
return [
['10:00'],
@@ -56,7 +56,7 @@ class DateTimeFormatValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
public static function getInvalidData()
public static function getInvalidData(): array
{
return [
['13-13'],

View File

@@ -0,0 +1,92 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Validator\Constraints;
use App\Validator\Constraints\ExportRenderer;
use App\Validator\Constraints\ExportRendererValidator;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
/**
* @covers \App\Validator\Constraints\ExportRenderer
* @covers \App\Validator\Constraints\ExportRendererValidator
* @extends ConstraintValidatorTestCase<ExportRendererValidator>
*/
class ExportRendererValidatorTest extends ConstraintValidatorTestCase
{
protected function createValidator(): ExportRendererValidator
{
return new ExportRendererValidator();
}
public static function getValidColors(): iterable
{
yield ['csv'];
yield ['xlsx'];
yield [null];
}
public function testConstraintIsInvalid(): void
{
$this->expectException(UnexpectedTypeException::class);
$this->validator->validate('#000', new NotBlank());
}
/**
* @dataProvider getValidColors
*/
public function testConstraintWithValidColor(?string $color): void
{
$constraint = new ExportRenderer();
$this->validator->validate($color, $constraint);
$this->assertNoViolation();
}
public static function getInvalidColors(): iterable
{
yield ['CSV'];
yield ['XLSX'];
yield ['PDF'];
yield ['HTML'];
yield ['fff000'];
yield ['000aaa'];
yield ['fffaaa'];
yield ['#f'];
yield ['#ff'];
yield ['#ffdd'];
yield ['#ffddd'];
yield ['#ffddddd'];
yield [new \stdClass(), 'object'];
yield [[], 'array'];
}
/**
* @dataProvider getInvalidColors
*/
public function testValidationError(mixed $color, ?string $parameterType = null): void
{
$constraint = new ExportRenderer();
$this->validator->validate($color, $constraint);
if (\is_string($color)) {
$expectedFormat = '"' . $color . '"';
} else {
$expectedFormat = $parameterType ?? '';
}
$this->buildViolation('Unknown exporter type.')
->setParameter('{{ value }}', $expectedFormat)
->setCode(ExportRenderer::UNKNOWN_TYPE)
->assertRaised();
}
}

View File

@@ -27,7 +27,7 @@ class HexColorValidatorTest extends ConstraintValidatorTestCase
return new HexColorValidator();
}
public static function getValidColors()
public static function getValidColors(): iterable
{
yield ['#000'];
yield ['#aaa'];
@@ -56,7 +56,7 @@ class HexColorValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
public static function getInvalidColors()
public static function getInvalidColors(): iterable
{
yield ['string'];
yield ['000'];

View File

@@ -32,7 +32,7 @@ class RoleValidatorTest extends ConstraintValidatorTestCase
return new RoleValidator($roleService);
}
public static function getValidRoles()
public static function getValidRoles(): array
{
return [
[User::ROLE_USER],
@@ -69,7 +69,7 @@ class RoleValidatorTest extends ConstraintValidatorTestCase
->assertRaised();
}
public static function getInvalidRoles()
public static function getInvalidRoles(): array
{
return [
['foo'],

View File

@@ -52,7 +52,7 @@ class TimeFormatValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
public static function getValidTimes()
public static function getValidTimes(): array
{
return [
[''],
@@ -79,7 +79,7 @@ class TimeFormatValidatorTest extends ConstraintValidatorTestCase
->assertRaised();
}
public static function getInvalidTimes()
public static function getInvalidTimes(): array
{
return [
['a'],

View File

@@ -143,7 +143,7 @@ class TimesheetBasicValidatorTest extends ConstraintValidatorTestCase
->assertRaised();
}
public static function getProjectStartEndTestData()
public static function getProjectStartEndTestData(): iterable
{
yield [new \DateTime(), new \DateTime(), [
['begin_date', TimesheetBasic::PROJECT_NOT_STARTED, 'The project has not started at that time.'],

View File

@@ -195,7 +195,7 @@ class TimesheetBudgetUsedValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
public static function getViolationTestData()
public static function getViolationTestData(): array
{
return [
// activity: violations ----------------------------------------------------------------------
@@ -294,7 +294,7 @@ class TimesheetBudgetUsedValidatorTest extends ConstraintValidatorTestCase
string $duration,
array $rawData = [],
?Rate $rate = null
) {
): void {
$activityStatistic = new ActivityStatistic();
if ($activityDuration !== null) {
$activityStatistic->setDuration($activityDuration);

View File

@@ -171,7 +171,7 @@ class TimesheetLockdownValidatorTest extends ConstraintValidatorTestCase
}
}
public static function getTestData()
public static function getTestData(): iterable
{
// changing before last dockdown period is not allowed
yield [false, false, '-5 days', '+5 days', true];
@@ -219,7 +219,7 @@ class TimesheetLockdownValidatorTest extends ConstraintValidatorTestCase
}
}
public static function getConfigTestData()
public static function getConfigTestData(): iterable
{
yield [false, false, null, null, null, false];
yield [false, false, '+5 days', null, null, false];

View File

@@ -94,7 +94,7 @@ class TimesheetRestartValidatorTest extends ConstraintValidatorTestCase
}
}
public static function getTestData()
public static function getTestData(): iterable
{
yield [false, 'end_date', 'default'];
yield [true, null, 'default'];

View File

@@ -58,7 +58,7 @@ class TimesheetZeroDurationValidatorTest extends ConstraintValidatorTestCase
$this->validator->validate(new NotBlank(), new TimesheetZeroDuration(['message' => 'Duration cannot be zero.']));
}
private function prepareTimesheet()
private function prepareTimesheet(): Timesheet
{
// creates Timesheet with same begin and endtime
$begin = new \DateTime();