refactored repositories and DB queries (#5026)

* removed unused teams from export order
* added new paginator for query instead of querybuilder
* added field hydrate enums
* hide PARTIAL deprecation
* never log deprecations in production
* replaced InvoiceLoader with native Doctrine feature
* prevent excessive permission queries
* support loading customers of team
* improved findByIds
* internalized API
* fix null string deprecations
This commit is contained in:
Kevin Papst
2024-08-27 10:11:19 +02:00
committed by GitHub
parent 9e3d243b4b
commit 9d933f62c0
81 changed files with 1648 additions and 1436 deletions

View File

@@ -18,7 +18,7 @@ use App\Tests\DataFixtures\TimesheetFixtures;
*/
abstract class AbstractUserPeriodControllerTest extends ControllerBaseTest
{
protected function importReportingFixture(string $role)
protected function importReportingFixture(string $role): void
{
$fixture = new TimesheetFixtures();
$fixture->setAmount(50);

View File

@@ -356,16 +356,10 @@ final class TimesheetFixtures implements TestFixture
}
/**
* @param User $user
* @param Activity $activity
* @param Project $project
* @param string $description
* @param \DateTime $start
* @param null|array $tagArray
* @param bool $setEndDate
* @return Timesheet
* @param array<Tag> $tagArray
*/
private function createTimesheetEntry(User $user, Activity $activity, Project $project, $description, \DateTime $start, $tagArray = [], $setEndDate = true)
private function createTimesheetEntry(User $user, Activity $activity, Project $project, ?string $description, \DateTime $start, array $tagArray = [], bool $setEndDate = true): Timesheet
{
$end = clone $start;
$end = $end->modify('+ ' . (rand(1, 86400)) . ' seconds');

View File

@@ -10,6 +10,7 @@
namespace App\Tests\Repository\Loader;
use App\Entity\Activity;
use App\Entity\Project;
use App\Repository\Loader\ActivityLoader;
/**
@@ -19,12 +20,15 @@ class ActivityLoaderTest extends AbstractLoaderTest
{
public function testLoadResults(): void
{
$em = $this->getEntityManagerMock(3);
$sut = new ActivityLoader($em);
$project = $this->createMock(Project::class);
$project->expects($this->once())->method('getId')->willReturn(13);
$entity = $this->createMock(Activity::class);
$entity->expects($this->once())->method('getId')->willReturn(1);
$entity->expects($this->exactly(3))->method('getProject')->willReturn($project);
$em = $this->getEntityManagerMock(3);
$sut = new ActivityLoader($em);
$sut->loadResults([$entity]);
}

View File

@@ -11,6 +11,7 @@ namespace App\Tests\Repository\Loader;
use App\Entity\Customer;
use App\Repository\Loader\CustomerLoader;
use App\Repository\Query\CustomerQuery;
/**
* @covers \App\Repository\Loader\CustomerLoader
@@ -19,13 +20,15 @@ class CustomerLoaderTest extends AbstractLoaderTest
{
public function testLoadResults(): void
{
$em = $this->getEntityManagerMock(2);
$em = $this->getEntityManagerMock(1);
$sut = new CustomerLoader($em);
$query = new CustomerQuery();
$query->loadTeams();
$sut = new CustomerLoader($em, $query);
$entity = $this->createMock(Customer::class);
$entity->expects($this->once())->method('getId')->willReturn(1);
$sut->loadResults([$entity, 4711]);
$sut->loadResults([$entity]);
}
}

View File

@@ -1,29 +0,0 @@
<?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\Repository\Loader;
use App\Repository\Loader\DefaultLoader;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Repository\Loader\DefaultLoader
*/
class DefaultLoaderTest extends TestCase
{
public function testLoadResults(): void
{
$sut = new DefaultLoader();
$input = [];
$sut->loadResults($input);
self::assertEquals([], $input);
}
}

View File

@@ -1,31 +0,0 @@
<?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\Repository\Loader;
use App\Entity\Invoice;
use App\Repository\Loader\InvoiceLoader;
/**
* @covers \App\Repository\Loader\InvoiceLoader
*/
class InvoiceLoaderTest extends AbstractLoaderTest
{
public function testLoadResults(): void
{
$em = $this->getEntityManagerMock(3);
$sut = new InvoiceLoader($em);
$entity = $this->createMock(Invoice::class);
$entity->expects($this->once())->method('getId')->willReturn(1);
$sut->loadResults([$entity]);
}
}

View File

@@ -25,13 +25,13 @@ class ProjectLoaderTest extends AbstractLoaderTest
$entity = $this->createMock(Project::class);
$entity->expects($this->once())->method('getId')->willReturn(1);
$entity->expects($this->once())->method('getCustomer')->willReturn($customer);
$entity->expects($this->exactly(2))->method('getCustomer')->willReturn($customer);
$results = [$entity];
$em = $this->getEntityManagerMock(4, $results);
$em = $this->getEntityManagerMock(2, $results);
$sut = new ProjectLoader($em);
$sut->loadResults([$entity, 4711]);
$sut->loadResults([$entity]);
}
}

View File

@@ -1,30 +0,0 @@
<?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\Repository\Paginator;
use App\Repository\Paginator\QueryBuilderPaginator;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\QueryBuilder;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Repository\Paginator\QueryBuilderPaginator
*/
class QueryBuilderPaginatorTest extends TestCase
{
public function testPaginator(): void
{
$em = $this->createMock(EntityManager::class);
$qb = new QueryBuilder($em);
$sut = new QueryBuilderPaginator($qb, 10);
self::assertEquals(10, $sut->getNbResults());
}
}

View File

@@ -18,7 +18,6 @@ use App\Form\Model\DateRange;
use App\Repository\Query\ActivityQuery;
use App\Repository\Query\BaseQuery;
use App\Repository\Query\DateRangeInterface;
use App\Repository\Query\ProjectQuery;
use App\Repository\Query\TimesheetQuery;
use App\Utils\SearchTerm;
use PHPUnit\Framework\TestCase;
@@ -251,8 +250,14 @@ class BaseQueryTest extends TestCase
$this->assertEquals([13, 27], $sut->getActivityIds());
}
protected function assertCustomer(ProjectQuery $sut): void
protected function assertCustomer(BaseQuery $sut): void
{
$this->assertTrue(method_exists($sut, 'getCustomers'));
$this->assertTrue(method_exists($sut, 'setCustomers'));
$this->assertTrue(method_exists($sut, 'hasCustomers'));
$this->assertTrue(method_exists($sut, 'addCustomer'));
$this->assertTrue(method_exists($sut, 'getCustomerIds'));
$this->assertEquals([], $sut->getCustomers());
$this->assertFalse($sut->hasCustomers());

View File

@@ -35,7 +35,6 @@ class AmountYearTest extends AbstractWidgetTypeTest
public function createSut(): AbstractWidgetType
{
$repository = $this->createMock(TimesheetRepository::class);
$repository->method('getStatistic')->willReturn([]);
$configuration = SystemConfigurationFactory::createStub();
$dispatcher = $this->createMock(EventDispatcherInterface::class);

View File

@@ -35,7 +35,6 @@ class UserAmountYearTest extends AbstractWidgetTypeTest
public function createSut(): AbstractWidgetType
{
$repository = $this->createMock(TimesheetRepository::class);
$repository->method('getStatistic')->willReturn([]);
$configuration = SystemConfigurationFactory::createStub();
$dispatcher = $this->createMock(EventDispatcherInterface::class);

View File

@@ -1218,11 +1218,6 @@ parameters:
count: 1
path: Controller/Reporting/AbstractUserPeriodControllerTest.php
-
message: "#^Method App\\\\Tests\\\\Controller\\\\Reporting\\\\AbstractUserPeriodControllerTest\\:\\:importReportingFixture\\(\\) has no return type specified\\.$#"
count: 1
path: Controller/Reporting/AbstractUserPeriodControllerTest.php
-
message: "#^Parameter \\#2 \\$haystack of static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertStringContainsString\\(\\) expects string, string\\|false given\\.$#"
count: 2
@@ -1468,21 +1463,6 @@ parameters:
count: 1
path: DataFixtures/TestFixture.php
-
message: "#^Method App\\\\Tests\\\\DataFixtures\\\\TimesheetFixtures\\:\\:createTimesheetEntry\\(\\) has parameter \\$tagArray with no value type specified in iterable type array\\.$#"
count: 1
path: DataFixtures/TimesheetFixtures.php
-
message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, array\\|null given\\.$#"
count: 1
path: DataFixtures/TimesheetFixtures.php
-
message: "#^Parameter \\#4 \\$description of method App\\\\Tests\\\\DataFixtures\\\\TimesheetFixtures\\:\\:createTimesheetEntry\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: DataFixtures/TimesheetFixtures.php
-
message: "#^Cannot access offset 'foo\\-bundle\\.bar' on array\\|bool\\|float\\|int\\|string\\|null\\.$#"
count: 1
@@ -1598,11 +1578,6 @@ parameters:
count: 1
path: Entity/ProjectTest.php
-
message: "#^Cannot access offset 0 on iterable\\<App\\\\Entity\\\\Team\\>\\.$#"
count: 1
path: Entity/TeamTest.php
-
message: "#^Cannot call method getUser\\(\\) on mixed\\.$#"
count: 1
@@ -1633,11 +1608,6 @@ parameters:
count: 1
path: Entity/TimesheetValidationTest.php
-
message: "#^Cannot access offset 0 on iterable\\<App\\\\Entity\\\\Team\\>\\.$#"
count: 1
path: Entity/UserTest.php
-
message: "#^Parameter \\#1 \\$string of function mb_strlen expects string, string\\|null given\\.$#"
count: 5