mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
GenericDoc: add provider for AccompanyingCourseDocument, without filtering
This commit is contained in:
parent
afcd6e0605
commit
8dbe2d6ec2
@ -11,8 +11,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle;
|
||||
|
||||
use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class ChillDocStoreBundle extends Bundle
|
||||
{
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
$container->registerForAutoconfiguration(ProviderForAccompanyingPeriodInterface::class)
|
||||
->addTag('chill_doc_store.generic_doc_accompanying_period_provider');
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,10 @@ final readonly class GenericDocForAccompanyingPeriodController
|
||||
|
||||
$nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod);
|
||||
|
||||
foreach ($this->manager->findDocForAccompanyingPeriod($accompanyingPeriod) as $dto) {
|
||||
dump($dto);
|
||||
}
|
||||
|
||||
return new Response($nb);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle\GenericDoc;
|
||||
|
||||
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\Denormalizer\UnexpectedValueException;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
class FetchQuery implements FetchQueryInterface
|
||||
{
|
||||
@ -21,42 +21,56 @@ class FetchQuery implements FetchQueryInterface
|
||||
private array $joins = [];
|
||||
|
||||
/**
|
||||
* @var list<mixed>
|
||||
* @var list<list<mixed>>
|
||||
*/
|
||||
private array $joinParams = [];
|
||||
|
||||
/**
|
||||
* @var list<string>
|
||||
* @var array<list<Types::*>>
|
||||
*/
|
||||
private array $joinTypes = [];
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private array $wheres = [];
|
||||
|
||||
/**
|
||||
* @var list<mixed>
|
||||
* @var array<list<mixed>>
|
||||
*/
|
||||
private array $whereParams = [];
|
||||
|
||||
/**
|
||||
* @var array<list<Types::*>>
|
||||
*/
|
||||
private array $whereTypes = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly string $selectKeyString,
|
||||
private readonly string $selectIdentifierJsonB,
|
||||
private readonly string $selectDate,
|
||||
private string $from = '',
|
||||
private array $selectIdentifierParams = [],
|
||||
private array $selectIdentifierTypes = [],
|
||||
private array $selectDateParams = [],
|
||||
private array $selectDateTypes = [],
|
||||
) {
|
||||
}
|
||||
|
||||
public function addJoinClause(string $sql, array $params = []): int
|
||||
public function addJoinClause(string $sql, array $params = [], array $types = []): int
|
||||
{
|
||||
$this->joins[] = $sql;
|
||||
$this->joinParams[] = $params;
|
||||
$this->joinTypes[] = $types;
|
||||
|
||||
return count($this->joins) - 1;
|
||||
}
|
||||
|
||||
public function addWhereClause(string $sql, array $params = []): int
|
||||
public function addWhereClause(string $sql, array $params = [], array $types = []): int
|
||||
{
|
||||
$this->wheres[] = $sql;
|
||||
$this->whereParams[] = $params;
|
||||
$this->whereTypes[] = $types;
|
||||
|
||||
return count($this->wheres) - 1;
|
||||
}
|
||||
@ -67,7 +81,7 @@ class FetchQuery implements FetchQueryInterface
|
||||
throw new \UnexpectedValueException("this index does not exists");
|
||||
}
|
||||
|
||||
unset($this->wheres[$index], $this->whereParams[$index]);
|
||||
unset($this->wheres[$index], $this->whereParams[$index], $this->whereTypes[$index]);
|
||||
|
||||
}
|
||||
|
||||
@ -77,7 +91,7 @@ class FetchQuery implements FetchQueryInterface
|
||||
throw new \UnexpectedValueException("this index does not exists");
|
||||
}
|
||||
|
||||
unset($this->joins[$index], $this->joinParams[$index]);
|
||||
unset($this->joins[$index], $this->joinParams[$index], $this->joinTypes[$index]);
|
||||
|
||||
}
|
||||
|
||||
@ -99,11 +113,21 @@ class FetchQuery implements FetchQueryInterface
|
||||
return $this->selectIdentifierParams;
|
||||
}
|
||||
|
||||
public function getSelectIdentifiersTypes(): array
|
||||
{
|
||||
return $this->selectIdentifierTypes;
|
||||
}
|
||||
|
||||
public function getSelectDate(): string
|
||||
{
|
||||
return $this->selectDate;
|
||||
}
|
||||
|
||||
public function getSelectDateTypes(): array
|
||||
{
|
||||
return $this->selectDateTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -131,6 +155,17 @@ class FetchQuery implements FetchQueryInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getFromQueryTypes(): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($this->joinTypes as $types) {
|
||||
$result = [...$result, ...$types];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getWhereQuery(): string
|
||||
{
|
||||
return implode(' AND ', $this->wheres);
|
||||
@ -150,19 +185,49 @@ class FetchQuery implements FetchQueryInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $selectIdentifierParams
|
||||
*/
|
||||
public function setSelectIdentifierParams(array $selectIdentifierParams): void
|
||||
public function getWhereQueryTypes(): array
|
||||
{
|
||||
$this->selectIdentifierParams = $selectIdentifierParams;
|
||||
$result = [];
|
||||
|
||||
foreach ($this->whereTypes as $types) {
|
||||
$result = [...$result, ...$types];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $selectDateParams
|
||||
*/
|
||||
public function setSelectDateParams(array $selectDateParams): void
|
||||
public function setSelectIdentifierParams(array $selectIdentifierParams): self
|
||||
{
|
||||
$this->selectIdentifierParams = $selectIdentifierParams;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSelectDateParams(array $selectDateParams): self
|
||||
{
|
||||
$this->selectDateParams = $selectDateParams;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFrom(string $from): self
|
||||
{
|
||||
$this->from = $from;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSelectIdentifierTypes(array $selectIdentifierTypes): self
|
||||
{
|
||||
$this->selectIdentifierTypes = $selectIdentifierTypes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSelectDateTypes(array $selectDateTypes): self
|
||||
{
|
||||
$this->selectDateTypes = $selectDateTypes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle\GenericDoc;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
interface FetchQueryInterface
|
||||
{
|
||||
public function getSelectKeyString(): string;
|
||||
@ -22,6 +24,11 @@ interface FetchQueryInterface
|
||||
*/
|
||||
public function getSelectIdentifierParams(): array;
|
||||
|
||||
/**
|
||||
* @return list<Types::*>
|
||||
*/
|
||||
public function getSelectIdentifiersTypes(): array;
|
||||
|
||||
public function getSelectDate(): string;
|
||||
|
||||
/**
|
||||
@ -29,6 +36,11 @@ interface FetchQueryInterface
|
||||
*/
|
||||
public function getSelectDateParams(): array;
|
||||
|
||||
/**
|
||||
* @return list<Types::*>
|
||||
*/
|
||||
public function getSelectDateTypes(): array;
|
||||
|
||||
public function getFromQuery(): string;
|
||||
|
||||
/**
|
||||
@ -36,10 +48,20 @@ interface FetchQueryInterface
|
||||
*/
|
||||
public function getFromQueryParams(): array;
|
||||
|
||||
/**
|
||||
* @return list<Types::*>
|
||||
*/
|
||||
public function getFromQueryTypes(): array;
|
||||
|
||||
public function getWhereQuery(): string;
|
||||
|
||||
/**
|
||||
* @return list<mixed>
|
||||
*/
|
||||
public function getWhereQueryParams(): array;
|
||||
|
||||
/**
|
||||
* @return list<Types::*>
|
||||
*/
|
||||
public function getWhereQueryTypes(): array;
|
||||
}
|
||||
|
@ -11,20 +11,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle\GenericDoc;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
final readonly class FetchQueryToSqlBuilder
|
||||
{
|
||||
private const SQL = <<<'SQL'
|
||||
SELECT
|
||||
'{{ key }}' AS key,
|
||||
{{ identifiers }} AS identifiers,
|
||||
{{ date }} AS doc_date
|
||||
{{ date }}::date AS doc_date
|
||||
FROM {{ from }}
|
||||
WHERE {{ where }}
|
||||
{{ where }}
|
||||
SQL;
|
||||
|
||||
/**
|
||||
* @param FetchQueryInterface $query
|
||||
* @return array{sql: string, params: list<mixed>}
|
||||
* @return array{sql: string, params: list<mixed>, types: list<Types::*>}
|
||||
*/
|
||||
public function toSql(FetchQueryInterface $query): array
|
||||
{
|
||||
@ -33,7 +35,7 @@ final readonly class FetchQueryToSqlBuilder
|
||||
'{{ identifiers }}' => $query->getSelectIdentifierJsonB(),
|
||||
'{{ date }}' => $query->getSelectDate(),
|
||||
'{{ from }}' => $query->getFromQuery(),
|
||||
'{{ where }}' => $query->getWhereQuery(),
|
||||
'{{ where }}' => '' === ($w = $query->getWhereQuery()) ? '' : 'WHERE ' . $w,
|
||||
]);
|
||||
|
||||
$params = [
|
||||
@ -43,6 +45,13 @@ final readonly class FetchQueryToSqlBuilder
|
||||
...$query->getWhereQueryParams()
|
||||
];
|
||||
|
||||
return ['sql' => $sql, 'params' => $params];
|
||||
$types = [
|
||||
...$query->getSelectIdentifiersTypes(),
|
||||
...$query->getSelectDateTypes(),
|
||||
...$query->getFromQueryTypes(),
|
||||
...$query->getWhereQueryTypes(),
|
||||
];
|
||||
|
||||
return ['sql' => $sql, 'params' => $params, 'types' => $types];
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
class Manager
|
||||
{
|
||||
@ -41,7 +42,12 @@ class Manager
|
||||
?string $origin = null
|
||||
): int {
|
||||
['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin);
|
||||
$countSql = "SELECT count(*) AS c FROM {$sql} AS sq";
|
||||
|
||||
if ($sql === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$countSql = "SELECT count(*) AS c FROM ({$sql}) AS sq";
|
||||
$result = $this->connection->executeQuery($countSql, $params);
|
||||
|
||||
$number = $result->fetchOne();
|
||||
@ -50,7 +56,7 @@ class Manager
|
||||
throw new \UnexpectedValueException("number of documents failed to load");
|
||||
}
|
||||
|
||||
return $number['c'];
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,13 +71,18 @@ class Manager
|
||||
?string $content = null,
|
||||
?string $origin = null
|
||||
): iterable {
|
||||
['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin);
|
||||
['sql' => $sql, 'params' => $params, 'types' => $types] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin);
|
||||
|
||||
$runSql = "{$sql} LIMIT ? OFFSET ?";
|
||||
$runParams = [...$params, ...[$limit, $offset]];
|
||||
$runTypes = [...$types, ...[Types::INTEGER, Types::INTEGER]];
|
||||
|
||||
foreach($this->connection->iterateAssociative($runSql, $runParams) as $row) {
|
||||
yield new GenericDocDTO($row['key'], $row['identifiers'], $row['date_doc']);
|
||||
foreach($this->connection->iterateAssociative($runSql, $runParams, $runTypes) as $row) {
|
||||
yield new GenericDocDTO(
|
||||
$row['key'],
|
||||
json_decode($row['identifiers'], true, JSON_THROW_ON_ERROR),
|
||||
new \DateTimeImmutable($row['doc_date'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,17 +97,24 @@ class Manager
|
||||
): array {
|
||||
$sql = [];
|
||||
$params = [];
|
||||
$types = [];
|
||||
|
||||
if ($linked instanceof AccompanyingPeriod) {
|
||||
foreach ($this->providersForAccompanyingPeriod as $provider) {
|
||||
['sql' => $q, 'params' => $p ] = $this->builder
|
||||
if (!$provider->isAllowedForAccompanyingPeriod($linked)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
['sql' => $q, 'params' => $p, 'types' => $t ] = $this->builder
|
||||
->toSql($provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content, $origin));
|
||||
$params = [...$params, ...$p];
|
||||
$types = [...$types, ...$t];
|
||||
|
||||
$sql[] = $q;
|
||||
}
|
||||
}
|
||||
|
||||
return ['sql' => implode(' UNION ', $sql), 'params' => $params];
|
||||
return ['sql' => implode(' UNION ', $sql), 'params' => $params, 'types' => $types];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ interface ProviderForAccompanyingPeriodInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowed(): bool;
|
||||
public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\DocStoreBundle\GenericDoc\Providers;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQuery;
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface;
|
||||
use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
final readonly class AccompanyingCourseDocumentProvider implements ProviderForAccompanyingPeriodInterface
|
||||
{
|
||||
public function __construct(
|
||||
private Security $security,
|
||||
private EntityManagerInterface $entityManager,
|
||||
) {
|
||||
}
|
||||
|
||||
public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface
|
||||
{
|
||||
$classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class);
|
||||
|
||||
$query = new FetchQuery(
|
||||
'accompanying_course_document',
|
||||
sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]),
|
||||
sprintf($classMetadata->getColumnName('date')),
|
||||
$classMetadata->getSchemaName() . '.' . $classMetadata->getTableName()
|
||||
);
|
||||
|
||||
$query->addWhereClause(
|
||||
sprintf('%s = ?', $classMetadata->getSingleAssociationJoinColumnName('course')),
|
||||
[$accompanyingPeriod->getId()],
|
||||
[Types::INTEGER]
|
||||
);
|
||||
|
||||
if (null !== $startDate) {
|
||||
$query->addWhereClause(
|
||||
sprintf('? >= %s', $classMetadata->getColumnName('date')),
|
||||
[$startDate],
|
||||
[Types::DATE_IMMUTABLE]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $endDate) {
|
||||
$query->addWhereClause(
|
||||
sprintf('? < %s', $classMetadata->getColumnName('date')),
|
||||
[$endDate],
|
||||
[Types::DATE_IMMUTABLE]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $content) {
|
||||
$query->addWhereClause(
|
||||
sprintf(
|
||||
'(%s ilike ? OR %s ilike ?)',
|
||||
$classMetadata->getColumnName('title'),
|
||||
$classMetadata->getColumnName('description')
|
||||
),
|
||||
[$content, $content],
|
||||
[Types::STRING, Types::STRING]
|
||||
);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool
|
||||
{
|
||||
return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod);
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace Chill\DocStoreBundle\Tests\GenericDoc;
|
||||
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder;
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQuery;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
@ -29,15 +30,15 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase
|
||||
'a.datecolumn',
|
||||
'my_table a'
|
||||
);
|
||||
$query->addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo']);
|
||||
$index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar']);
|
||||
$query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz']);
|
||||
$query->addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo'], [Types::STRING]);
|
||||
$index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar'], [Types::STRING]);
|
||||
$query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz'], [Types::STRING]);
|
||||
$query->removeJoinClause($index);
|
||||
$query->addWhereClause('b.item = ?', ['baz']);
|
||||
$index = $query->addWhereClause('b.cancel', [ 'foz']);
|
||||
$query->addWhereClause('b.item = ?', ['baz'], [Types::STRING]);
|
||||
$index = $query->addWhereClause('b.cancel', [ 'foz'], [Types::STRING]);
|
||||
$query->removeWhereClause($index);
|
||||
|
||||
['sql' => $sql, 'params' => $params] = (new FetchQueryToSqlBuilder())->toSql($query);
|
||||
['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);
|
||||
|
||||
$filteredSql =
|
||||
implode(" ", array_filter(
|
||||
@ -48,10 +49,41 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase
|
||||
|
||||
self::assertEquals(
|
||||
"SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ".
|
||||
"a.datecolumn AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?",
|
||||
"a.datecolumn::date AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?",
|
||||
$filteredSql
|
||||
);
|
||||
self::assertEquals(['foo', 'bar_baz', 'baz'], $params);
|
||||
self::assertEquals([Types::STRING, Types::STRING, Types::STRING], $types);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testToSqlWithoutWhere(): void
|
||||
{
|
||||
$query = new FetchQuery(
|
||||
'test',
|
||||
'jsonb_build_object(\'id\', a.column)',
|
||||
'a.datecolumn',
|
||||
'my_table a'
|
||||
);
|
||||
|
||||
['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);
|
||||
|
||||
$filteredSql =
|
||||
implode(" ", array_filter(
|
||||
explode(" ", str_replace("\n", "", $sql)),
|
||||
fn (string $tok) => $tok !== ""
|
||||
))
|
||||
;
|
||||
|
||||
self::assertEquals(
|
||||
"SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ".
|
||||
"a.datecolumn::date AS doc_date FROM my_table a",
|
||||
$filteredSql
|
||||
);
|
||||
self::assertEquals([], $params);
|
||||
self::assertEquals([], $types);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,9 +11,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\DocStoreBundle\Tests\GenericDoc;
|
||||
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQuery;
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface;
|
||||
use Chill\DocStoreBundle\GenericDoc\GenericDocDTO;
|
||||
use Chill\DocStoreBundle\GenericDoc\Manager;
|
||||
use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
@ -22,21 +28,17 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
*/
|
||||
class ManagerTest extends KernelTestCase
|
||||
{
|
||||
private Manager $manager;
|
||||
|
||||
use ProphecyTrait;
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
private Connection $connection;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||
|
||||
if (null !== $manager = self::$container->get(Manager::class)) {
|
||||
$this->manager = $manager;
|
||||
} else {
|
||||
throw new \UnexpectedValueException("the manager was not found in the kernel");
|
||||
}
|
||||
$this->connection = self::$container->get(Connection::class);
|
||||
}
|
||||
|
||||
public function testCountByAccompanyingPeriod(): void
|
||||
@ -49,8 +51,51 @@ class ManagerTest extends KernelTestCase
|
||||
throw new \UnexpectedValueException("period not found");
|
||||
}
|
||||
|
||||
$nb = $this->manager->countDocForAccompanyingPeriod($period);
|
||||
$manager = new Manager(
|
||||
[new SimpleProvider()],
|
||||
$this->connection,
|
||||
);
|
||||
|
||||
$nb = $manager->countDocForAccompanyingPeriod($period);
|
||||
|
||||
self::assertIsInt($nb);
|
||||
}
|
||||
|
||||
public function testFindDocByAccompanyingPeriod(): void
|
||||
{
|
||||
$period = $this->em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a')
|
||||
->setMaxResults(1)
|
||||
->getSingleResult();
|
||||
|
||||
if (null === $period) {
|
||||
throw new \UnexpectedValueException("period not found");
|
||||
}
|
||||
|
||||
$manager = new Manager(
|
||||
[new SimpleProvider()],
|
||||
$this->connection,
|
||||
);
|
||||
|
||||
foreach ($manager->findDocForAccompanyingPeriod($period) as $doc) {
|
||||
self::assertInstanceOf(GenericDocDTO::class, $doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final readonly class SimpleProvider implements ProviderForAccompanyingPeriodInterface
|
||||
{
|
||||
public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface
|
||||
{
|
||||
return new FetchQuery(
|
||||
'accompanying_course_document',
|
||||
sprintf('jsonb_build_object(\'id\', %s)', 'id'),
|
||||
'd',
|
||||
'(VALUES (1, \'2023-05-01\'::date), (2, \'2023-05-01\'::date)) AS sq (id, d)',
|
||||
);
|
||||
}
|
||||
|
||||
public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\DocStoreBundle\Tests\GenericDoc\Providers;
|
||||
|
||||
use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder;
|
||||
use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingCourseDocumentProvider;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingCourseDocumentProviderTest extends KernelTestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSearchArguments
|
||||
*/
|
||||
public function testWithoutAnyArgument(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content = null): void
|
||||
{
|
||||
$period = $this->entityManager->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a')
|
||||
->setMaxResults(1)
|
||||
->getSingleResult();
|
||||
|
||||
if (null === $period) {
|
||||
throw new \UnexpectedValueException("period not found");
|
||||
}
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted(AccompanyingCourseDocumentVoter::SEE, $period)
|
||||
->willReturn(true);
|
||||
|
||||
$provider = new AccompanyingCourseDocumentProvider(
|
||||
$security->reveal(),
|
||||
$this->entityManager
|
||||
);
|
||||
|
||||
$query = $provider->buildFetchQueryForAccompanyingPeriod($period, $startDate, $endDate, $content);
|
||||
|
||||
['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);
|
||||
|
||||
$this->entityManager->getConnection()->executeQuery($sql, $params, $types);
|
||||
|
||||
self::assertTrue(true, "test that no errors occurs");
|
||||
}
|
||||
|
||||
public function provideSearchArguments(): iterable
|
||||
{
|
||||
yield [null, null, null];
|
||||
yield [new \DateTimeImmutable('1 month ago'), null, null];
|
||||
yield [new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('now'), null];
|
||||
yield [null, null, 'test'];
|
||||
}
|
||||
}
|
@ -51,3 +51,7 @@ services:
|
||||
arguments:
|
||||
$providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider
|
||||
|
||||
Chill\DocStoreBundle\GenericDoc\Providers\:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
resource: '../GenericDoc/Providers/'
|
||||
|
Loading…
x
Reference in New Issue
Block a user