Release 2.0.30 (#4225)

This commit is contained in:
Kevin Papst
2023-08-16 18:20:14 +02:00
committed by GitHub
parent c7bc8fae73
commit adc0779912
21 changed files with 860 additions and 520 deletions

908
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4796,11 +4796,6 @@ parameters:
count: 2
path: src/Repository/ActivityRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/ActivityRepository.php
-
message: "#^Method App\\\\Repository\\\\ActivityRepository\\:\\:addPermissionCriteria\\(\\) has parameter \\$teams with no value type specified in iterable type array\\.$#"
count: 1
@@ -4866,11 +4861,6 @@ parameters:
count: 2
path: src/Repository/CustomerRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/CustomerRepository.php
-
message: "#^Method App\\\\Repository\\\\CustomerRepository\\:\\:addPermissionCriteria\\(\\) has no return type specified\\.$#"
count: 1
@@ -4931,11 +4921,6 @@ parameters:
count: 2
path: src/Repository/InvoiceRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 2
path: src/Repository/InvoiceRepository.php
-
message: "#^Method App\\\\Repository\\\\InvoiceRepository\\:\\:addPermissionCriteria\\(\\) has no return type specified\\.$#"
count: 1
@@ -4956,11 +4941,6 @@ parameters:
count: 1
path: src/Repository/InvoiceRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/InvoiceTemplateRepository.php
-
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
count: 1
@@ -5076,11 +5056,6 @@ parameters:
count: 2
path: src/Repository/ProjectRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/ProjectRepository.php
-
message: "#^Method App\\\\Repository\\\\ProjectRepository\\:\\:addPermissionCriteria\\(\\) has parameter \\$teams with no value type specified in iterable type array\\.$#"
count: 1
@@ -5236,16 +5211,6 @@ parameters:
count: 1
path: src/Repository/TagRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/TagRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/TeamRepository.php
-
message: "#^Method App\\\\Repository\\\\TeamRepository\\:\\:addPermissionCriteria\\(\\) has no return type specified\\.$#"
count: 1
@@ -5336,11 +5301,6 @@ parameters:
count: 2
path: src/Repository/TimesheetRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 2
path: src/Repository/TimesheetRepository.php
-
message: "#^Cannot clone DateTime\\|null\\.$#"
count: 1
@@ -5436,11 +5396,6 @@ parameters:
count: 1
path: src/Repository/UserRepository.php
-
message: "#^Cannot cast mixed to int\\.$#"
count: 1
path: src/Repository/UserRepository.php
-
message: "#^Method App\\\\Repository\\\\UserRepository\\:\\:addPermissionCriteria\\(\\) has no return type specified\\.$#"
count: 1
@@ -5776,11 +5731,6 @@ parameters:
count: 1
path: src/Timesheet/TimesheetStatisticService.php
-
message: "#^Parameter \\#1 \\$datetime of class DateTime constructor expects string, mixed given\\.$#"
count: 1
path: src/Timesheet/TimesheetStatisticService.php
-
message: "#^Method App\\\\Timesheet\\\\TrackingMode\\\\AbstractTrackingMode\\:\\:setBeginEndFromRequest\\(\\) has no return type specified\\.$#"
count: 1
@@ -6336,18 +6286,13 @@ parameters:
count: 2
path: src/Validator/Constraints/TimesheetExportedValidator.php
-
message: "#^Cannot call method getTimestamp\\(\\) on DateTime\\|null\\.$#"
count: 1
path: src/Validator/Constraints/TimesheetFutureTimesValidator.php
-
message: "#^Cannot call method getTimezone\\(\\) on DateTime\\|null\\.$#"
count: 1
path: src/Validator/Constraints/TimesheetFutureTimesValidator.php
-
message: "#^Parameter \\#1 \\$timesheet \\(App\\\\Entity\\\\Timesheet\\) of method App\\\\Validator\\\\Constraints\\\\TimesheetFutureTimesValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#"
message: "#^Parameter \\#1 \\$value \\(App\\\\Entity\\\\Timesheet\\) of method App\\\\Validator\\\\Constraints\\\\TimesheetFutureTimesValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#"
count: 2
path: src/Validator/Constraints/TimesheetFutureTimesValidator.php
@@ -6790,3 +6735,93 @@ parameters:
message: "#^Method App\\\\Form\\\\MultiUpdate\\\\MultiUpdateTableDTO\\:\\:setEntities\\(\\) has parameter \\$entities with generic interface Doctrine\\\\Common\\\\Collections\\\\Collection but does not specify its types\\: TKey, T$#"
count: 1
path: src/Form/MultiUpdate/MultiUpdateTableDTO.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\MarkdownExtension', 'commentContent'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\MarkdownExtension', 'commentOneLiner'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\MarkdownExtension', 'markdownToHtml'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\MarkdownExtension', 'timesheetContent'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'colorize'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFilter constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'KevinPapst\\\\\\\\TablerBundle\\\\\\\\Twig\\\\\\\\RuntimeExtension', 'icon'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\EncoreExtension', 'getEncoreEntryCssSo…'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\QrCodeExtension', 'qrCodeDataUriFuncti…'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'actions'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'generateTitle'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'getJavascriptTransl…'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'getProgressbarClass'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'getTimePresets'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\ThemeExtension', 'trigger'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\TimesheetExtension', 'activeEntries'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\TimesheetExtension', 'favoriteEntries'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'App\\\\\\\\Twig\\\\\\\\Runtime\\\\\\\\WidgetExtension', 'renderWidget'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php
-
message: "#^Parameter \\#2 \\$callable of class Twig\\\\TwigFunction constructor expects array\\<class\\-string, string\\>\\|\\(callable\\(\\)\\: mixed\\)\\|null, array\\{'KevinPapst\\\\\\\\TablerBundle\\\\\\\\Twig\\\\\\\\RuntimeExtension', 'createIcon'\\} given\\.$#"
count: 1
path: src/Twig/RuntimeExtensions.php

View File

@@ -15,7 +15,7 @@
<env name="APP_ENV" value="test" force="true"/>
<env name="APP_DEBUG" value="0" force="true"/>
<env name="APP_SECRET" value="5a79a1c866efef9ca1800f971d689f3e" force="true"/>
<env name="DATABASE_URL" value="mysql://kimai2_test:kimai2_test@127.0.0.1:3306/kimai2_test"/>
<env name="DATABASE_URL" value="mysql://kimai2_test:kimai2_test@127.0.0.1:3306/kimai2_test?serverVersion=mariadb-10.7.3"/>
<env name="CORS_ALLOW_ORIGIN" value="^https?://localhost(:[0-9]+)?$"/>
<env name="MAILER_URL" value="null://null"/>
<env name="MAILER_FROM" value="kimai@example.com"/>

View File

@@ -17,11 +17,11 @@ class Constants
/**
* The current release version
*/
public const VERSION = '2.0.29';
public const VERSION = '2.0.30';
/**
* The current release: major * 10000 + minor * 100 + patch
*/
public const VERSION_ID = 20029;
public const VERSION_ID = 20030;
/**
* The software name
*/

View File

@@ -34,10 +34,16 @@ use InvalidArgumentException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
final class TimesheetService
{
/**
* @var array<string>
*/
private array $doNotValidateCodes = [];
public function __construct(
private SystemConfiguration $configuration,
private TimesheetRepository $repository,
@@ -236,10 +242,25 @@ final class TimesheetService
$errors = $this->validator->validate($timesheet, null, $groups);
if ($errors->count() > 0) {
throw new ValidationFailedException($errors, 'Validation Failed');
/** @var ConstraintViolation $error */
foreach ($errors as $error) {
if (\in_array($error->getCode(), $this->doNotValidateCodes, true)) {
continue;
}
throw new ValidationFailedException($errors, 'Validation Failed');
}
}
}
/**
* @param array<string> $validationCodes
*/
public function setIgnoreValidationCodes(array $validationCodes): void
{
$this->doNotValidateCodes = $validationCodes;
}
/**
* Makes sure, that the timesheet record has the timezone of the user.
*

View File

@@ -254,7 +254,7 @@ final class TimesheetStatisticService
return null;
}
return new DateTime($result, new \DateTimeZone($user->getTimezone()));
return new DateTime((string) $result, new \DateTimeZone($user->getTimezone()));
}
/**

View File

@@ -9,10 +9,8 @@
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
#[\Attribute(\Attribute::TARGET_CLASS)]
final class TimesheetDeactivated extends Constraint
final class TimesheetDeactivated extends TimesheetConstraint
{
public const DISABLED_ACTIVITY_ERROR = 'kimai-timesheet-deactivated-activity';
public const DISABLED_PROJECT_ERROR = 'kimai-timesheet-deactivated-project';

View File

@@ -9,15 +9,18 @@
namespace App\Validator\Constraints;
#[\Attribute(\Attribute::TARGET_CLASS)]
final class TimesheetFutureTimes extends TimesheetConstraint
{
public const BEGIN_IN_FUTURE_ERROR = 'kimai-timesheet-future-times-01';
public const END_IN_FUTURE_ERROR = 'kimai-timesheet-future-times-02';
protected const ERROR_NAMES = [
self::BEGIN_IN_FUTURE_ERROR => 'The begin date cannot be in the future.',
self::END_IN_FUTURE_ERROR => 'The end date cannot be in the future.',
];
public string $message = 'The begin date cannot be in the future.';
public string $message = 'The date cannot be in the future.';
public function getTargets(): string|array
{

View File

@@ -22,33 +22,44 @@ final class TimesheetFutureTimesValidator extends ConstraintValidator
}
/**
* @param TimesheetEntity $timesheet
* @param TimesheetEntity $value
* @param Constraint $constraint
*/
public function validate(mixed $timesheet, Constraint $constraint): void
public function validate(mixed $value, Constraint $constraint): void
{
if (!($constraint instanceof TimesheetFutureTimes)) {
throw new UnexpectedTypeException($constraint, TimesheetFutureTimes::class);
}
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
throw new UnexpectedTypeException($value, TimesheetEntity::class);
}
if ($this->configuration->isTimesheetAllowFutureTimes()) {
return;
}
$now = new \DateTime('now', $timesheet->getBegin()->getTimezone());
$now = new \DateTime('now', $value->getBegin()->getTimezone());
// allow configured default rounding time + 1 minute - see #1295
$allowedDiff = ($this->configuration->getTimesheetDefaultRoundingBegin() * 60) + 60;
if (($now->getTimestamp() + $allowedDiff) < $timesheet->getBegin()->getTimestamp()) {
$this->context->buildViolation('The begin date cannot be in the future.')
$nowTs = $now->getTimestamp() + $allowedDiff;
if ($value->getBegin() !== null && $nowTs < $value->getBegin()->getTimestamp()) {
$this->context->buildViolation(TimesheetFutureTimes::getErrorName(TimesheetFutureTimes::BEGIN_IN_FUTURE_ERROR))
->atPath('begin_date')
->setTranslationDomain('validators')
->setCode(TimesheetFutureTimes::BEGIN_IN_FUTURE_ERROR)
->addViolation();
}
$allowedDiff = ($this->configuration->getTimesheetDefaultRoundingEnd() * 60) + 60;
$nowTs = $now->getTimestamp() + $allowedDiff;
if ($value->getEnd() !== null && $nowTs < $value->getEnd()->getTimestamp()) {
$this->context->buildViolation(TimesheetFutureTimes::getErrorName(TimesheetFutureTimes::END_IN_FUTURE_ERROR))
->atPath('end_time')
->setTranslationDomain('validators')
->setCode(TimesheetFutureTimes::END_IN_FUTURE_ERROR)
->addViolation();
}
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetBasic;
use App\Validator\Constraints\TimesheetConstraint;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetBasic
*/
class TimesheetBasicTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetBasic());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetBudgetUsed;
use App\Validator\Constraints\TimesheetConstraint;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetBudgetUsed
*/
class TimesheetBudgetUsedTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetBudgetUsed());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetDeactivated;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetDeactivated
*/
class TimesheetDeactivatedTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetDeactivated());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetExported;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetExported
*/
class TimesheetExportedTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetExported());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetFutureTimes;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetFutureTimes
*/
class TimesheetFutureTimesTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetFutureTimes());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetLockdown;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetLockdown
*/
class TimesheetLockdownTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetLockdown());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetLongRunning;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetLongRunning
*/
class TimesheetLongRunningTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetLongRunning());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetOverlapping;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetOverlapping
*/
class TimesheetOverlappingTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetOverlapping());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetRestart;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetRestart
*/
class TimesheetRestartTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetRestart());
}
}

View File

@@ -0,0 +1,25 @@
<?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\TimesheetConstraint;
use App\Validator\Constraints\TimesheetZeroDuration;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Validator\Constraints\TimesheetZeroDuration
*/
class TimesheetZeroDurationTest extends TestCase
{
public function testIsTimesheetConstraint(): void
{
self::assertInstanceOf(TimesheetConstraint::class, new TimesheetZeroDuration());
}
}

View File

@@ -9398,7 +9398,7 @@ parameters:
path: Twig/ExtensionsTest.php
-
message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, \\(callable\\(\\)\\: mixed\\)\\|null given\\.$#"
message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, array<class-string, string>|\\(callable\\(\\)\\: mixed\\)\\|null given\\.$#"
count: 6
path: Twig/ExtensionsTest.php
@@ -9488,7 +9488,7 @@ parameters:
path: Twig/LocaleFormatExtensionsTest.php
-
message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, \\(callable\\(\\)\\: mixed\\)\\|null given\\.$#"
message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, array<class-string, string>|\\(callable\\(\\)\\: mixed\\)\\|null given\\.$#"
count: 5
path: Twig/LocaleFormatExtensionsTest.php

View File

@@ -2892,9 +2892,9 @@ __metadata:
linkType: hard
"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001359, caniuse-lite@npm:^1.0.30001400":
version: 1.0.30001446
resolution: "caniuse-lite@npm:1.0.30001446"
checksum: b31a7e1837783afd7f3d4cb742689996c0a09d67394ddaa0609fd2bce00ceea65c448e25f91c03ba0f2d0e345b7e28fd5bc636c6760c949621a654c0effe74b5
version: 1.0.30001520
resolution: "caniuse-lite@npm:1.0.30001520"
checksum: 59991ad8f36cf282f81abbcc6074c3097c21914cdd54bd2b3f73ac9462f57fc74e90371cd22bcdff4d085d09da42a07dcea384cb81e4ac260496e1bd79e1fe7c
languageName: node
linkType: hard