Release 2.40.0 (#5621)
This commit is contained in:
@@ -68,7 +68,7 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
|
||||
$data = [
|
||||
'message' => 'Unauthorized',
|
||||
'code' => 401
|
||||
'code' => Response::HTTP_UNAUTHORIZED
|
||||
];
|
||||
|
||||
self::assertEquals(
|
||||
@@ -100,7 +100,7 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function request(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], string $content = null): Crawler
|
||||
public function request(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], ?string $content = null): Crawler
|
||||
{
|
||||
$server = ['HTTP_CONTENT_TYPE' => 'application/json', 'CONTENT_TYPE' => 'application/json'];
|
||||
|
||||
@@ -276,6 +276,7 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
$fieldName = implode('.', $parts);
|
||||
}
|
||||
|
||||
self::assertIsString($fieldName);
|
||||
self::assertArrayHasKey($fieldName, $data, \sprintf('Could not find validation error for field "%s" in list: %s', $fieldName, implode(', ', $failedFields)));
|
||||
self::assertArrayHasKey('errors', $data[$fieldName], \sprintf('Field %s has no validation problem', $fieldName));
|
||||
foreach ($messages as $i => $message) {
|
||||
@@ -356,6 +357,7 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
'enabled' => 'bool',
|
||||
'apiToken' => 'bool',
|
||||
'color' => '@string',
|
||||
'avatar' => '@string',
|
||||
'alias' => '@string',
|
||||
'accountNumber' => '@string',
|
||||
'initials' => '@string',
|
||||
@@ -431,6 +433,9 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
'color' => '@string',
|
||||
'number' => '@string',
|
||||
'comment' => '@string',
|
||||
'currency' => 'string', // since 2.40.0
|
||||
'country' => 'string', // since 2.40.0
|
||||
'company' => '@string', // since 2.40.0
|
||||
];
|
||||
|
||||
// if a list of customers is loaded
|
||||
@@ -446,6 +451,13 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
'metaFields' => ['result' => 'array', 'type' => 'CustomerMeta'],
|
||||
'teams' => ['result' => 'array', 'type' => 'Team'],
|
||||
'currency' => 'string', // since 1.10
|
||||
'country' => 'string',
|
||||
'company' => '@string',
|
||||
'homepage' => '@string',
|
||||
'fax' => '@string',
|
||||
'mobile' => '@string',
|
||||
'phone' => '@string',
|
||||
'timezone' => 'string',
|
||||
];
|
||||
|
||||
// if a customer is loaded explicitly
|
||||
@@ -490,6 +502,8 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
'orderNumber' => '@string',
|
||||
'globalActivities' => 'bool',
|
||||
'comment' => '@string',
|
||||
'start' => '@datetime',
|
||||
'end' => '@datetime',
|
||||
];
|
||||
|
||||
// if a project is embedded in an expanded collection (here timesheet)
|
||||
@@ -505,6 +519,8 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
|
||||
'orderNumber' => '@string',
|
||||
'globalActivities' => 'bool',
|
||||
'comment' => '@string',
|
||||
'start' => '@datetime',
|
||||
'end' => '@datetime',
|
||||
];
|
||||
|
||||
// if a collection of projects is loaded
|
||||
|
||||
@@ -407,7 +407,7 @@ class ActivityControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingName(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['value' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -415,7 +415,7 @@ class ActivityControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingValue(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -423,7 +423,7 @@ class ActivityControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingMetafield(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||
'code' => 404,
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ class ApiDocControllerTest extends AbstractControllerBaseTestCase
|
||||
'/api/users/{id}',
|
||||
'/api/users/me',
|
||||
'/api/users/api-token/{id}',
|
||||
'/api/users/{id}/preferences',
|
||||
];
|
||||
|
||||
self::assertArrayHasKey('openapi', $json);
|
||||
|
||||
@@ -390,7 +390,7 @@ class CustomerControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingName(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['value' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -398,7 +398,7 @@ class CustomerControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingValue(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -406,7 +406,7 @@ class CustomerControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingMetafield(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||
'code' => 404,
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ class ProjectControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingName(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['value' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -574,7 +574,7 @@ class ProjectControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingValue(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -582,7 +582,7 @@ class ProjectControllerTest extends APIControllerBaseTestCase
|
||||
public function testMetaActionThrowsExceptionOnMissingMetafield(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||
'code' => 404,
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
@@ -54,7 +55,7 @@ class ValidationFailedExceptionErrorHandlerTest extends TestCase
|
||||
$validations = new ValidationFailedException($constraints, 'Uuups, that is broken');
|
||||
|
||||
$expected = [
|
||||
'code' => '400',
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => null,
|
||||
'errors' => [
|
||||
'children' => []
|
||||
@@ -98,7 +99,7 @@ class ValidationFailedExceptionErrorHandlerTest extends TestCase
|
||||
$context->setAttribute('exception', $validations);
|
||||
|
||||
$expected = [
|
||||
'code' => '400',
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Uuups, that is broken',
|
||||
'errors' => [
|
||||
'children' => [
|
||||
|
||||
@@ -263,7 +263,7 @@ class TimesheetControllerTest extends APIControllerBaseTestCase
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->importFixtureForUser(User::ROLE_USER);
|
||||
$this->request($client, '/api/timesheets', 'GET', $query);
|
||||
$this->assertApiException($client->getResponse(), ['code' => 404, 'message' => 'Not Found']);
|
||||
$this->assertApiException($client->getResponse(), ['code' => Response::HTTP_NOT_FOUND, 'message' => 'Not Found']);
|
||||
}
|
||||
|
||||
public function testGetCollectionWithSingleParamsQuery(): void
|
||||
@@ -1434,7 +1434,7 @@ class TimesheetControllerTest extends APIControllerBaseTestCase
|
||||
$id = $timesheets[0]->getId();
|
||||
|
||||
$this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['value' => 'X'], [
|
||||
'code' => 400,
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
@@ -1446,7 +1446,7 @@ class TimesheetControllerTest extends APIControllerBaseTestCase
|
||||
$id = $timesheets[0]->getId();
|
||||
|
||||
$this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['name' => 'X'], [
|
||||
'code' => 404,
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
@@ -1458,7 +1458,7 @@ class TimesheetControllerTest extends APIControllerBaseTestCase
|
||||
$id = $timesheets[0]->getId();
|
||||
|
||||
$this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['name' => 'X', 'value' => 'Y'], [
|
||||
'code' => 404,
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@
|
||||
namespace App\Tests\API;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Tests\Mocks\PrepareUserEventSubscriberMock;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
#[Group('integration')]
|
||||
class UserControllerTest extends APIControllerBaseTestCase
|
||||
@@ -178,7 +181,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'ROLE_ADMIN'
|
||||
],
|
||||
];
|
||||
$this->request($client, '/api/users', 'POST', [], json_encode($data));
|
||||
$this->request($client, '/api/users', 'POST', [], (string) json_encode($data));
|
||||
self::assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$content = $client->getResponse()->getContent();
|
||||
@@ -211,7 +214,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'ROLE_ADMIN'
|
||||
],
|
||||
];
|
||||
$this->request($client, '/api/users', 'POST', [], json_encode($data));
|
||||
$this->request($client, '/api/users', 'POST', [], (string) json_encode($data));
|
||||
|
||||
$response = $client->getResponse();
|
||||
self::assertEquals(400, $response->getStatusCode());
|
||||
@@ -231,7 +234,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'ABC',
|
||||
],
|
||||
];
|
||||
$this->request($client, '/api/users', 'POST', [], json_encode($data));
|
||||
$this->request($client, '/api/users', 'POST', [], (string) json_encode($data));
|
||||
|
||||
$response = $client->getResponse();
|
||||
self::assertEquals(400, $response->getStatusCode());
|
||||
@@ -249,7 +252,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'language' => 'ru',
|
||||
'timezone' => 'Europe/Paris',
|
||||
];
|
||||
$this->request($client, '/api/users', 'POST', [], json_encode($data));
|
||||
$this->request($client, '/api/users', 'POST', [], (string) json_encode($data));
|
||||
$response = $client->getResponse();
|
||||
$this->assertApiResponseAccessDenied($response, 'Access denied.');
|
||||
}
|
||||
@@ -269,11 +272,12 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'ROLE_ADMIN'
|
||||
],
|
||||
];
|
||||
$this->request($client, '/api/users', 'POST', [], json_encode($data));
|
||||
$this->request($client, '/api/users', 'POST', [], (string) json_encode($data));
|
||||
self::assertTrue($client->getResponse()->isSuccessful());
|
||||
$content = $client->getResponse()->getContent();
|
||||
self::assertIsString($content);
|
||||
$result = json_decode($content, true);
|
||||
self::assertIsArray($result);
|
||||
self::assertFalse($result['enabled']);
|
||||
|
||||
$data = [
|
||||
@@ -287,7 +291,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
];
|
||||
$id = $result['id'];
|
||||
self::assertIsNumeric($id);
|
||||
$this->request($client, '/api/users/' . $id, 'PATCH', [], json_encode($data));
|
||||
$this->request($client, '/api/users/' . $id, 'PATCH', [], (string) json_encode($data));
|
||||
self::assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$content = $client->getResponse()->getContent();
|
||||
@@ -312,7 +316,7 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
public function testPatchActionWithInvalidUser(): void
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/api/users/1', 'PATCH', [], json_encode(['language' => 'hu']));
|
||||
$this->request($client, '/api/users/1', 'PATCH', [], (string) json_encode(['language' => 'hu']));
|
||||
$this->assertApiResponseAccessDenied($client->getResponse(), 'Not allowed to edit user');
|
||||
}
|
||||
|
||||
@@ -330,10 +334,73 @@ class UserControllerTest extends APIControllerBaseTestCase
|
||||
'ABC',
|
||||
],
|
||||
];
|
||||
$this->request($client, '/api/users/1', 'PATCH', [], json_encode($data));
|
||||
$this->request($client, '/api/users/1', 'PATCH', [], (string) json_encode($data));
|
||||
|
||||
$response = $client->getResponse();
|
||||
self::assertEquals(400, $response->getStatusCode());
|
||||
$this->assertApiCallValidationError($response, ['email', 'language', 'timezone', 'roles'], true);
|
||||
}
|
||||
|
||||
// ------------------------------------- [USER PREFERENCES] -------------------------------------
|
||||
|
||||
public function testUpdateUserPreferenceThrowsNotFound(): void
|
||||
{
|
||||
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/users/42/preferences', []);
|
||||
}
|
||||
|
||||
public function testUpdateUserPreferenceThrowsExceptionOnWrongStructure(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_SUPER_ADMIN, '/api/users/1/preferences', ['name' => 'X', 'value' => 'X'], [
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdateUserPreferenceThrowsExceptionOnMissingName(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_SUPER_ADMIN, '/api/users/1/preferences', [['value' => 'X']], [
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdateUserPreferenceThrowsExceptionOnMissingValue(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_SUPER_ADMIN, '/api/users/1/preferences', [['name' => 'X']], [
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdateUserPreferenceThrowsExceptionOnMissingMetafield(): void
|
||||
{
|
||||
$this->assertExceptionForPatchAction(User::ROLE_SUPER_ADMIN, '/api/users/1/preferences', [['name' => 'X', 'value' => 'Y']], [
|
||||
'code' => Response::HTTP_NOT_FOUND,
|
||||
'message' => 'Not Found'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdateUserPreference(): void
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
|
||||
/** @var EventDispatcher $dispatcher */
|
||||
$dispatcher = static::getContainer()->get('event_dispatcher');
|
||||
$dispatcher->addSubscriber(new PrepareUserEventSubscriberMock());
|
||||
|
||||
$data = [
|
||||
[
|
||||
'name' => 'metatestmock',
|
||||
'value' => 'another,testing,bar'
|
||||
]
|
||||
];
|
||||
$this->request($client, '/api/users/1/preferences', 'PATCH', [], (string) json_encode($data));
|
||||
|
||||
self::assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
/** @var User $user */
|
||||
$user = $em->getRepository(User::class)->find(1);
|
||||
self::assertEquals('another,testing,bar', $user->getPreferenceValue('metatestmock'));
|
||||
self::assertEquals('another,testing,bar', $user->getPreferenceValue('metatestmock'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,9 @@ class BundleInstallerCommandTest extends KernelTestCase
|
||||
{
|
||||
$kernel = self::bootKernel();
|
||||
$this->application = new Application($kernel);
|
||||
$this->application->add(new $className());
|
||||
$command = new $className();
|
||||
self::assertInstanceOf(AbstractBundleInstallerCommand::class, $command);
|
||||
$this->application->add($command);
|
||||
|
||||
return $this->application->find('kimai:bundle:test:install');
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ namespace App\Tests\Configuration;
|
||||
use App\Configuration\ConfigLoaderInterface;
|
||||
use App\Entity\Configuration;
|
||||
|
||||
/**
|
||||
* @covers \App\Configuration\SystemConfiguration
|
||||
*/
|
||||
class TestConfigLoader implements ConfigLoaderInterface
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -169,12 +169,12 @@ abstract class AbstractControllerBaseTestCase extends WebTestCase
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function request(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], string $content = null): Crawler
|
||||
public function request(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], ?string $content = null): Crawler
|
||||
{
|
||||
return $client->request($method, $this->createUrl($url), $parameters, [], [], $content);
|
||||
}
|
||||
|
||||
public function requestPure(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], string $content = null): Crawler
|
||||
public function requestPure(HttpKernelBrowser $client, string $url, string $method = 'GET', array $parameters = [], ?string $content = null): Crawler
|
||||
{
|
||||
return $client->request($method, $url, $parameters, [], [], $content);
|
||||
}
|
||||
@@ -381,7 +381,7 @@ abstract class AbstractControllerBaseTestCase extends WebTestCase
|
||||
* @param HttpKernelBrowser $client
|
||||
* @param string|null $message
|
||||
*/
|
||||
protected function assertHasFlashSuccess(HttpKernelBrowser $client, string $message = null): void
|
||||
protected function assertHasFlashSuccess(HttpKernelBrowser $client, ?string $message = null): void
|
||||
{
|
||||
$this->assertHasFlashMessage($client, 'success', $message);
|
||||
}
|
||||
@@ -390,12 +390,12 @@ abstract class AbstractControllerBaseTestCase extends WebTestCase
|
||||
* @param HttpKernelBrowser $client
|
||||
* @param string|null $message
|
||||
*/
|
||||
protected function assertHasFlashError(HttpKernelBrowser $client, string $message = null): void
|
||||
protected function assertHasFlashError(HttpKernelBrowser $client, ?string $message = null): void
|
||||
{
|
||||
$this->assertHasFlashMessage($client, 'error', $message);
|
||||
}
|
||||
|
||||
private function assertHasFlashMessage(HttpKernelBrowser $client, string $type, string $message = null): void
|
||||
private function assertHasFlashMessage(HttpKernelBrowser $client, string $type, ?string $message = null): void
|
||||
{
|
||||
$content = $client->getResponse()->getContent();
|
||||
self::assertStringContainsString('ALERT.' . $type . '(\'', $content, 'Could not find flash ' . $type . ' message');
|
||||
|
||||
@@ -45,4 +45,27 @@ abstract class AbstractEntityTestCase extends TestCase
|
||||
self::assertEquals('Unknown budget type: foo', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function assertCloneResetsId(object $sut): void
|
||||
{
|
||||
if (!property_exists($sut, 'id')) {
|
||||
$this->fail('Entity does not have an ID property');
|
||||
}
|
||||
if (!method_exists($sut, 'getId')) {
|
||||
$this->fail('Entity does not have a getId() method');
|
||||
}
|
||||
|
||||
self::assertNull($sut->getId());
|
||||
$obj = new \ReflectionObject($sut);
|
||||
$prop = $obj->getProperty('id');
|
||||
$prop->setAccessible(true);
|
||||
$prop->setValue($sut, 123);
|
||||
self::assertEquals(123, $sut->getId());
|
||||
|
||||
$clone = clone $sut;
|
||||
|
||||
self::assertNull($clone->getId());
|
||||
$prop->setValue($sut, null);
|
||||
$prop->setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,11 @@ class AccessTokenTest extends AbstractEntityTestCase
|
||||
$sut->setExpiresAt(new \DateTimeImmutable('-1 day'));
|
||||
self::assertFalse($sut->isValid());
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$user = new User();
|
||||
$sut = new AccessToken($user, 'foo');
|
||||
$this->assertCloneResetsId($sut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@ namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\ActivityRate;
|
||||
use App\Entity\Rate;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Rate
|
||||
*/
|
||||
#[CoversClass(Rate::class)]
|
||||
#[CoversClass(ActivityRate::class)]
|
||||
class ActivityRateTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -175,6 +175,8 @@ class ActivityTest extends AbstractEntityTestCase
|
||||
$sut->setName('activity1111');
|
||||
$sut->setComment('DE-0123456789');
|
||||
|
||||
$this->assertCloneResetsId($sut);
|
||||
|
||||
$project = new Project();
|
||||
$project->setName('foo');
|
||||
$project->setOrderNumber('1234567890');
|
||||
|
||||
@@ -12,10 +12,9 @@ namespace App\Tests\Entity;
|
||||
use App\Entity\Bookmark;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(Bookmark::class)]
|
||||
class BookmarkTest extends TestCase
|
||||
class BookmarkTest extends AbstractEntityTestCase
|
||||
{
|
||||
public function testDefaultValues(): void
|
||||
{
|
||||
@@ -48,4 +47,10 @@ class BookmarkTest extends TestCase
|
||||
self::assertEquals('sdsdsd', $sut2->getType());
|
||||
self::assertEquals('foo-bar', $sut2->getName());
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$sut = new Bookmark();
|
||||
$this->assertCloneResetsId($sut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,5 +31,14 @@ class ConfigurationTest extends TestCase
|
||||
self::assertEquals('foo-bar', $sut->getName());
|
||||
self::assertInstanceOf(Configuration::class, $sut->setValue('hello world'));
|
||||
self::assertEquals('hello world', $sut->getValue());
|
||||
|
||||
self::assertInstanceOf(Configuration::class, $sut->setValue(true));
|
||||
self::assertEquals('1', $sut->getValue());
|
||||
|
||||
self::assertInstanceOf(Configuration::class, $sut->setValue(null));
|
||||
self::assertNull($sut->getValue());
|
||||
|
||||
self::assertInstanceOf(Configuration::class, $sut->setValue(false));
|
||||
self::assertEquals('0', $sut->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@
|
||||
|
||||
namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\CommentTableTypeTrait;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerComment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\CommentTableTypeTrait
|
||||
*/
|
||||
#[CoversClass(CommentTableTypeTrait::class)]
|
||||
#[CoversClass(CustomerComment::class)]
|
||||
class CustomerCommentTest extends AbstractCommentEntityTestCase
|
||||
{
|
||||
|
||||
@@ -11,13 +11,12 @@ namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerRate;
|
||||
use App\Entity\Rate;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Rate
|
||||
*/
|
||||
#[CoversClass(Rate::class)]
|
||||
#[CoversClass(CustomerRate::class)]
|
||||
class CustomerRateTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace App\Tests\Entity;
|
||||
use App\Constants;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerMeta;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Team;
|
||||
use App\Export\Spreadsheet\ColumnDefinition;
|
||||
use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
|
||||
@@ -51,6 +52,26 @@ class CustomerTest extends AbstractEntityTestCase
|
||||
self::assertNull($sut->getMetaField('foo'));
|
||||
self::assertInstanceOf(Collection::class, $sut->getTeams());
|
||||
self::assertEquals(0, $sut->getTeams()->count());
|
||||
self::assertTrue($sut->isNew());
|
||||
self::assertNull($sut->getInvoiceText());
|
||||
self::assertNull($sut->getInvoiceTemplate());
|
||||
}
|
||||
|
||||
public function testInvoiceText(): void
|
||||
{
|
||||
$sut = new Customer('foo');
|
||||
self::assertNull($sut->getInvoiceText());
|
||||
$sut->setInvoiceText('Some fancy long text to explain that tax should be handled by the receiving party');
|
||||
self::assertEquals('Some fancy long text to explain that tax should be handled by the receiving party', $sut->getInvoiceText());
|
||||
}
|
||||
|
||||
public function testInvoiceTemplate(): void
|
||||
{
|
||||
$tpl = new InvoiceTemplate();
|
||||
$sut = new Customer('foo');
|
||||
self::assertNull($sut->getInvoiceTemplate());
|
||||
$sut->setInvoiceTemplate($tpl);
|
||||
self::assertSame($tpl, $sut->getInvoiceTemplate());
|
||||
}
|
||||
|
||||
public function testBudgets(): void
|
||||
@@ -221,6 +242,9 @@ class CustomerTest extends AbstractEntityTestCase
|
||||
public function testClone(): void
|
||||
{
|
||||
$sut = new Customer('mycustomer');
|
||||
|
||||
$this->assertCloneResetsId($sut);
|
||||
|
||||
$sut->setVatId('DE-0123456789');
|
||||
$sut->setTimeBudget(123456);
|
||||
$sut->setBudget(1234.56);
|
||||
|
||||
@@ -19,6 +19,7 @@ class ExportTemplateTest extends AbstractEntityTestCase
|
||||
{
|
||||
$sut = new ExportTemplate();
|
||||
self::assertNull($sut->getId());
|
||||
self::assertTrue($sut->isNew());
|
||||
self::assertNull($sut->getTitle());
|
||||
self::assertEquals('csv', $sut->getRenderer());
|
||||
self::assertNull($sut->getLanguage());
|
||||
@@ -115,6 +116,7 @@ class ExportTemplateTest extends AbstractEntityTestCase
|
||||
$p->setAccessible(true);
|
||||
$p->setValue($sut, 13);
|
||||
self::assertEquals(13, $sut->getId());
|
||||
self::assertFalse($sut->isNew());
|
||||
|
||||
$sut2 = clone $sut;
|
||||
self::assertNull($sut2->getId());
|
||||
|
||||
@@ -34,6 +34,7 @@ class InvoiceTemplateTest extends TestCase
|
||||
self::assertEquals('default', $sut->getNumberGenerator());
|
||||
self::assertEquals('default', $sut->getRenderer());
|
||||
self::assertEquals(30, $sut->getDueDays());
|
||||
self::assertTrue($sut->isDecimalDuration()); // @phpstan-ignore method.deprecated
|
||||
}
|
||||
|
||||
public function testSetNullForOptionalValues(): void
|
||||
|
||||
@@ -29,10 +29,9 @@ use App\Repository\Query\InvoiceQuery;
|
||||
use App\Tests\Invoice\DebugFormatter;
|
||||
use App\Tests\Mocks\InvoiceModelFactoryFactory;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(Invoice::class)]
|
||||
class InvoiceTest extends TestCase
|
||||
class InvoiceTest extends AbstractEntityTestCase
|
||||
{
|
||||
public function testDefaultValues(): void
|
||||
{
|
||||
@@ -219,6 +218,8 @@ class InvoiceTest extends TestCase
|
||||
public function testClone(): void
|
||||
{
|
||||
$sut = new Invoice();
|
||||
$this->assertCloneResetsId($sut);
|
||||
|
||||
$sut->setComment('foo kajsdhgf aksjdhfg');
|
||||
$sut->setFilename('1234567890');
|
||||
|
||||
|
||||
@@ -9,13 +9,12 @@
|
||||
|
||||
namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\CommentTableTypeTrait;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\ProjectComment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\CommentTableTypeTrait
|
||||
*/
|
||||
#[CoversClass(CommentTableTypeTrait::class)]
|
||||
#[CoversClass(ProjectComment::class)]
|
||||
class ProjectCommentTest extends AbstractCommentEntityTestCase
|
||||
{
|
||||
|
||||
@@ -11,13 +11,12 @@ namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\Project;
|
||||
use App\Entity\ProjectRate;
|
||||
use App\Entity\Rate;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Rate
|
||||
*/
|
||||
#[CoversClass(Rate::class)]
|
||||
#[CoversClass(ProjectRate::class)]
|
||||
class ProjectRateTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ class ActivityTestMetaFieldSubscriberMock implements EventSubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
public function loadMeta(ActivityMetaDefinitionEvent $event)
|
||||
public function loadMeta(ActivityMetaDefinitionEvent $event): void
|
||||
{
|
||||
$definition = (new ActivityMeta())
|
||||
->setName('metatestmock')
|
||||
|
||||
@@ -25,7 +25,7 @@ class CustomerTestMetaFieldSubscriberMock implements EventSubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
public function loadMeta(CustomerMetaDefinitionEvent $event)
|
||||
public function loadMeta(CustomerMetaDefinitionEvent $event): void
|
||||
{
|
||||
$definition = (new CustomerMeta())
|
||||
->setName('metatestmock')
|
||||
|
||||
43
tests/Mocks/PrepareUserEventSubscriberMock.php
Normal file
43
tests/Mocks/PrepareUserEventSubscriberMock.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?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\Mocks;
|
||||
|
||||
use App\Entity\UserPreference;
|
||||
use App\Event\PrepareUserEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
|
||||
class PrepareUserEventSubscriberMock implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
PrepareUserEvent::class => ['prepareUserEvent', 200],
|
||||
];
|
||||
}
|
||||
|
||||
public function prepareUserEvent(PrepareUserEvent $event): void
|
||||
{
|
||||
$definition = (new UserPreference('metatestmock'))
|
||||
->setType(TextType::class)
|
||||
->addConstraint(new Length(['max' => 200]))
|
||||
->setEnabled(true);
|
||||
|
||||
$event->getUser()->addPreference($definition);
|
||||
|
||||
$definition = (new UserPreference('foobar'))
|
||||
->setType(IntegerType::class)
|
||||
->setEnabled(false);
|
||||
|
||||
$event->getUser()->addPreference($definition);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class ProjectTestMetaFieldSubscriberMock implements EventSubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
public function loadMeta(ProjectMetaDefinitionEvent $event)
|
||||
public function loadMeta(ProjectMetaDefinitionEvent $event): void
|
||||
{
|
||||
$definition = (new ProjectMeta())
|
||||
->setName('metatestmock')
|
||||
|
||||
@@ -25,7 +25,7 @@ class TimesheetTestMetaFieldSubscriberMock implements EventSubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
public function loadMeta(TimesheetMetaDefinitionEvent $event)
|
||||
public function loadMeta(TimesheetMetaDefinitionEvent $event): void
|
||||
{
|
||||
$definition = (new TimesheetMeta())
|
||||
->setName('metatestmock')
|
||||
|
||||
@@ -129,7 +129,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#"
|
||||
count: 3
|
||||
count: 1
|
||||
path: API/APIControllerBaseTestCase.php
|
||||
|
||||
-
|
||||
@@ -301,26 +301,6 @@ parameters:
|
||||
count: 1
|
||||
path: API/TimesheetControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'enabled' on mixed\\.$#"
|
||||
count: 1
|
||||
path: API/UserControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'id' on mixed\\.$#"
|
||||
count: 1
|
||||
path: API/UserControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#5 \\$content of method App\\\\Tests\\\\API\\\\APIControllerBaseTestCase\\:\\:request\\(\\) expects string\\|null, string\\|false given\\.$#"
|
||||
count: 8
|
||||
path: API/UserControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$command of method Symfony\\\\Bundle\\\\FrameworkBundle\\\\Console\\\\Application\\:\\:add\\(\\) expects Symfony\\\\Component\\\\Console\\\\Command\\\\Command, object given\\.$#"
|
||||
count: 1
|
||||
path: Command/BundleInstallerCommandTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$hashedPassword of method Symfony\\\\Component\\\\PasswordHasher\\\\PasswordHasherInterface\\:\\:verify\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
@@ -1800,27 +1780,11 @@ parameters:
|
||||
message: "#^Parameter \\#2 \\$type of class PHPUnit\\\\Framework\\\\MockObject\\\\MockBuilder constructor expects class\\-string\\<TMockedClass\\>, string given\\.$#"
|
||||
count: 1
|
||||
path: Mocks/AbstractMockFactory.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\ActivityTestMetaFieldSubscriberMock\\:\\:loadMeta\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Mocks/ActivityTestMetaFieldSubscriberMock.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\CustomerTestMetaFieldSubscriberMock\\:\\:loadMeta\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Mocks/CustomerTestMetaFieldSubscriberMock.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$dataDir of class App\\\\Utils\\\\FileHelper constructor expects string, string\\|false given\\.$#"
|
||||
count: 1
|
||||
path: Mocks/FileHelperFactory.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\ProjectTestMetaFieldSubscriberMock\\:\\:loadMeta\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Mocks/ProjectTestMetaFieldSubscriberMock.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\RoundingServiceFactory\\:\\:create\\(\\) has parameter \\$rules with no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
@@ -1831,11 +1795,6 @@ parameters:
|
||||
count: 1
|
||||
path: Mocks/Saml/SamlAuthFactoryFactory.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\TimesheetTestMetaFieldSubscriberMock\\:\\:loadMeta\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Mocks/TimesheetTestMetaFieldSubscriberMock.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Mocks\\\\TrackingModeServiceFactory\\:\\:create\\(\\) has parameter \\$modes with no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
|
||||
Reference in New Issue
Block a user