Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View File

@@ -21,7 +21,6 @@ use App\Repository\ProjectRateRepository;
use App\Repository\ProjectRepository;
use App\Repository\Query\VisibilityInterface;
use App\Tests\Mocks\ProjectTestMetaFieldSubscriberMock;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelBrowser;
/**
@@ -112,10 +111,10 @@ class ProjectControllerTest extends APIControllerBaseTest
$customer = $em->getRepository(Customer::class)->find(1);
$customer2 = (new Customer())->setName('first one')->setVisible(false)->setCountry('de')->setTimezone('Europe/Berlin');
$customer2 = (new Customer('first one'))->setVisible(false)->setCountry('de')->setTimezone('Europe/Berlin');
$em->persist($customer2);
$customer3 = (new Customer())->setName('second one')->setCountry('at')->setTimezone('Europe/Vienna');
$customer3 = (new Customer('second one'))->setCountry('at')->setTimezone('Europe/Vienna');
$em->persist($customer3);
$project = (new Project())->setName('first')->setVisible(false)->setCustomer($customer2);
@@ -142,8 +141,7 @@ class ProjectControllerTest extends APIControllerBaseTest
$em->persist($project);
// and a team
$team = new Team();
$team->setName('Testing project team');
$team = new Team('Testing project team');
$team->addTeamlead($this->getUserByRole(User::ROLE_USER));
$team->addCustomer($customer);
$team->addProject($project);
@@ -161,7 +159,7 @@ class ProjectControllerTest extends APIControllerBaseTest
/**
* @dataProvider getCollectionTestData
*/
public function testGetCollectionWithParams($url, $customer, $parameters, $expected)
public function testGetCollectionWithParams($url, $customer, $parameters, $expected): void
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$imports = $this->loadProjectTestData($client);
@@ -171,11 +169,18 @@ class ProjectControllerTest extends APIControllerBaseTest
if ($customerId !== null) {
if (\array_key_exists('customer', $parameters)) {
$parameters['customer'] = $customerId;
} elseif (\array_key_exists('customers', $parameters)) {
if (stripos($parameters['customers'], ',') !== false) {
$parameters['customers'] = $customerId . ',' . $customerId;
}
if (\array_key_exists('customers', $parameters)) {
if (!\is_array($parameters['customers'])) {
throw new \InvalidArgumentException('customers needs to be an array');
}
$count = \count($parameters['customers']);
if ($count === 2) {
$parameters['customers'] = [$customerId, $customerId];
} elseif ($count === 1) {
$parameters['customers'] = [$customerId];
} else {
$parameters['customers'] = (string) $customerId;
throw new \InvalidArgumentException('Invalid count for customers');
}
}
}
@@ -195,7 +200,10 @@ class ProjectControllerTest extends APIControllerBaseTest
}
}
public function getCollectionTestData()
/**
* @return \Generator<array<mixed>>
*/
public function getCollectionTestData(): iterable
{
// if you wonder why: case-sensitive ordering feels strange ... "Title" > "fifth”
yield ['/api/projects', null, [], [[true, 1], [false, 1], [false, 3]]];
@@ -203,15 +211,15 @@ class ProjectControllerTest extends APIControllerBaseTest
yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_VISIBLE], [[true, 1], [false, 1]]];
yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_BOTH], [[true, 1], [false, 1], [false, 1]]];
yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_HIDDEN], [[false, 1]]];
// customer is invisible, so nothing should be returned
// customer is invisible => query only returns results for VisibilityInterface::SHOW_BOTH
yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_VISIBLE], []];
yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
yield ['/api/projects', 1, ['customer' => '2', 'customers' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
yield ['/api/projects', 1, ['customer' => '2', 'customers' => '2,2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
// customer is invisible, so nothing should be returned
yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
yield ['/api/projects', 1, ['customers' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
yield ['/api/projects', 1, ['customers' => '2,2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
yield ['/api/projects', 1, ['customer' => '2', 'customers' => ['2'], 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
yield ['/api/projects', 1, ['customers' => ['2', '2'], 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN], []];
yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11', 'end' => '2030-12-11'], []];
yield ['/api/projects', 1, ['customers' => ['2'], 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11', 'end' => '2030-12-11'], []];
yield ['/api/projects', 1, ['customers' => ['2', '2'], 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11', 'end' => '2030-12-11'], []];
}
public function testGetEntity()
@@ -219,8 +227,7 @@ class ProjectControllerTest extends APIControllerBaseTest
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$em = $this->getEntityManager();
$customer = (new Customer())
->setName('first one')
$customer = (new Customer('first one'))
->setVisible(true)
->setCountry('de')
->setTimezone('Europe/Berlin')
@@ -255,9 +262,9 @@ class ProjectControllerTest extends APIControllerBaseTest
'name' => 'first',
'orderNumber' => null,
// make sure the timezone is properly applied in serializer (see #1858)
'orderDate' => '2019-11-29T14:35:17+1300',
'start' => '2020-01-07T18:19:20+1300',
'end' => '2021-03-23T00:00:01+1300',
'orderDate' => '2019-11-29',
'start' => '2020-01-07',
'end' => '2021-03-23',
'comment' => null,
'visible' => true,
'budget' => 0.0,
@@ -274,7 +281,7 @@ class ProjectControllerTest extends APIControllerBaseTest
public function testNotFound()
{
$this->assertEntityNotFound(User::ROLE_USER, '/api/projects/2');
$this->assertEntityNotFound(User::ROLE_USER, '/api/projects/' . PHP_INT_MAX, 'GET', 'App\\Entity\\Project object not found by the @ParamConverter annotation.');
}
public function testPostAction()
@@ -283,10 +290,9 @@ class ProjectControllerTest extends APIControllerBaseTest
$data = [
'name' => 'foo',
'customer' => 1,
'visible' => true,
'orderDate' => '2018-02-08T13:02:54',
'start' => '2019-02-01T19:32:17',
'end' => '2020-02-08T21:11:42',
'orderDate' => '2018-04-17',
'start' => '2019-02-01',
'end' => '2020-02-08',
'budget' => '999',
'timeBudget' => '7200',
'orderNumber' => '1234567890/WXYZ/SUBPROJECT/1234/CONTRACT/EMPLOYEE1',
@@ -298,11 +304,13 @@ class ProjectControllerTest extends APIControllerBaseTest
$this->assertIsArray($result);
self::assertApiResponseTypeStructure('ProjectEntity', $result);
$this->assertNotEmpty($result['id']);
self::assertTrue($result['globalActivities']);
self::assertEquals('2018-02-08T13:02:54+0000', $result['orderDate']);
self::assertEquals('2019-02-01T19:32:17+0000', $result['start']);
self::assertEquals('2020-02-08T21:11:42+0000', $result['end']);
self::assertEquals('2018-04-17', $result['orderDate']);
self::assertEquals('2019-02-01', $result['start']);
self::assertEquals('2020-02-08', $result['end']);
self::assertEquals('1234567890/WXYZ/SUBPROJECT/1234/CONTRACT/EMPLOYEE1', $result['orderNumber']);
self::assertFalse($result['globalActivities']);
self::assertFalse($result['billable']);
self::assertFalse($result['visible']);
}
public function testPostActionWithOtherFields()
@@ -311,7 +319,32 @@ class ProjectControllerTest extends APIControllerBaseTest
$data = [
'name' => 'foo',
'customer' => 1,
'globalActivities' => '0',
'globalActivities' => true,
'billable' => 1,
'visible' => '',
];
$this->request($client, '/api/projects', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
self::assertApiResponseTypeStructure('ProjectEntity', $result);
$this->assertNotEmpty($result['id']);
self::assertEquals('foo', $result['name']);
self::assertTrue($result['globalActivities']);
self::assertTrue($result['billable']);
self::assertTrue($result['visible']);
}
public function testPostActionWithOtherFieldsAndFalse()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'customer' => 1,
'globalActivities' => false,
'billable' => false,
'visible' => false,
];
$this->request($client, '/api/projects', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -322,15 +355,19 @@ class ProjectControllerTest extends APIControllerBaseTest
$this->assertNotEmpty($result['id']);
self::assertEquals('foo', $result['name']);
self::assertFalse($result['globalActivities']);
self::assertFalse($result['billable']);
self::assertFalse($result['visible']);
}
public function testPostActionWithOtherFields2()
public function testPostActionWithOtherFields3()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'customer' => 1,
'globalActivities' => '1',
'globalActivities' => true,
'billable' => true,
'visible' => true,
];
$this->request($client, '/api/projects', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -341,6 +378,8 @@ class ProjectControllerTest extends APIControllerBaseTest
$this->assertNotEmpty($result['id']);
self::assertEquals('foo', $result['name']);
self::assertTrue($result['globalActivities']);
self::assertTrue($result['billable']);
self::assertTrue($result['visible']);
}
public function testPostActionWithLeastFields()
@@ -358,6 +397,9 @@ class ProjectControllerTest extends APIControllerBaseTest
self::assertApiResponseTypeStructure('ProjectEntity', $result);
$this->assertNotEmpty($result['id']);
self::assertEquals('foo', $result['name']);
self::assertFalse($result['globalActivities']);
self::assertFalse($result['billable']);
self::assertFalse($result['visible']);
}
public function testPostActionWithInvalidUser()
@@ -370,10 +412,7 @@ class ProjectControllerTest extends APIControllerBaseTest
];
$this->request($client, '/api/projects', 'POST', [], json_encode($data));
$response = $client->getResponse();
$this->assertFalse($response->isSuccessful());
$this->assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode());
$json = json_decode($response->getContent(), true);
$this->assertEquals('User cannot create projects', $json['message']);
$this->assertApiResponseAccessDenied($response, 'User cannot create projects');
}
public function testPostActionWithInvalidData()
@@ -422,10 +461,7 @@ class ProjectControllerTest extends APIControllerBaseTest
];
$this->request($client, '/api/projects/1', 'PATCH', [], json_encode($data));
$response = $client->getResponse();
$this->assertFalse($response->isSuccessful());
$this->assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode());
$json = json_decode($response->getContent(), true);
$this->assertEquals('User cannot update project', $json['message']);
$this->assertApiResponseAccessDenied($response, 'User cannot update project');
}
public function testPatchActionWithUnknownActivity()
@@ -455,32 +491,32 @@ class ProjectControllerTest extends APIControllerBaseTest
public function testMetaActionThrowsExceptionOnMissingName()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['value' => 'X'], [
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
'message' => 'Bad Request'
]);
}
public function testMetaActionThrowsExceptionOnMissingValue()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X'], [
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
'message' => 'Bad Request'
]);
}
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
$this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X', 'value' => 'Y'], [
'code' => 404,
'message' => 'Not Found'
]);
}
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
static::$kernel->getContainer()->get('event_dispatcher')->addSubscriber(new ProjectTestMetaFieldSubscriberMock());
self::getContainer()->get('event_dispatcher')->addSubscriber(new ProjectTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',