Merge pull request #232 from goteo/feat/bump-benzina
feat: Bump goteo/benzina
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@
|
||||
"doctrine/orm": "^3.3",
|
||||
"embed/embed": "^4.4",
|
||||
"gedmo/doctrine-extensions": "^3.22",
|
||||
"goteo/benzina": "^0.5",
|
||||
"goteo/benzina": "^0.6.0",
|
||||
"jolicode/automapper": "9.2.1",
|
||||
"knpuniversity/oauth2-client-bundle": "^2.20",
|
||||
"kyzegs/doctrine-encryption-bundle": "^1.1",
|
||||
|
||||
Generated
+214
-276
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20260812124026 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Make territory_address LONGTEXT';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE match_call CHANGE territory_address territory_address LONGTEXT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE project CHANGE territory_address territory_address LONGTEXT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE user CHANGE territory_address territory_address LONGTEXT DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE user CHANGE territory_address territory_address VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE project CHANGE territory_address territory_address VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE ext_translations CHANGE foreign_key foreign_key INT NOT NULL');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20260813144440 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Split description into: brief, about, goal and team';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE project ADD desc_about LONGTEXT DEFAULT NULL, ADD desc_goal LONGTEXT DEFAULT NULL, ADD desc_team LONGTEXT DEFAULT NULL, CHANGE description desc_brief LONGTEXT DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE project ADD description LONGTEXT DEFAULT NULL, DROP desc_brief, DROP desc_about, DROP desc_goal, DROP desc_team');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260813171902 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Update categories to work with INT ids and VARCHAR slugs';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE IF EXISTS category');
|
||||
$this->addSql('DROP TABLE IF EXISTS project_category');
|
||||
$this->addSql('CREATE TABLE category (id INT AUTO_INCREMENT NOT NULL, slug VARCHAR(56) NOT NULL, name VARCHAR(255) NOT NULL, locales JSON NOT NULL COMMENT \'(DC2Type:json)\', UNIQUE INDEX UNIQ_64C19C1989D9B62 (slug), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||
$this->addSql('CREATE TABLE project_category (project_id INT NOT NULL, category_id INT NOT NULL, INDEX IDX_3B02921A166D1F9C (project_id), INDEX IDX_3B02921A12469DE2 (category_id), PRIMARY KEY(project_id, category_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||
$this->addSql('ALTER TABLE project_category ADD CONSTRAINT FK_3B02921A166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE');
|
||||
$this->addSql('ALTER TABLE project_category ADD CONSTRAINT FK_3B02921A12469DE2 FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE CASCADE');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE IF EXISTS category');
|
||||
$this->addSql('DROP TABLE IF EXISTS project_category');
|
||||
$this->addSql('CREATE TABLE category (id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, locales JSON NOT NULL COMMENT \'(DC2Type:json)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||
$this->addSql('CREATE TABLE project_category (project_id INT NOT NULL, category_id VARCHAR(255) NOT NULL, INDEX IDX_3B02921A166D1F9C (project_id), INDEX IDX_3B02921A12469DE2 (category_id), PRIMARY KEY(project_id, category_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||
$this->addSql('ALTER TABLE project_category ADD CONSTRAINT FK_3B02921A166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE');
|
||||
$this->addSql('ALTER TABLE project_category ADD CONSTRAINT FK_3B02921A12469DE2 FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE CASCADE');
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\ApiResource;
|
||||
|
||||
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
|
||||
use ApiPlatform\Doctrine\Orm\State\Options;
|
||||
use ApiPlatform\Metadata as API;
|
||||
use App\Entity\Category;
|
||||
use App\State\ApiResourceStateProcessor;
|
||||
use App\State\ApiResourceStateProvider;
|
||||
use App\State\CategoryStateProvider;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
@@ -25,7 +27,15 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
)]
|
||||
#[API\GetCollection()]
|
||||
#[API\Post(security: 'is_granted("ROLE_ADMIN")')]
|
||||
#[API\Get()]
|
||||
#[API\Get(
|
||||
provider: CategoryStateProvider::class,
|
||||
uriTemplate: '/categories/{idOrSlug}',
|
||||
uriVariables: [
|
||||
'idOrSlug' => new API\Link(
|
||||
description: 'Category identifier or slug',
|
||||
),
|
||||
]
|
||||
)]
|
||||
#[API\Patch(security: 'is_granted("ROLE_ADMIN")')]
|
||||
#[API\Delete(security: 'is_granted("ROLE_ADMIN")')]
|
||||
class CategoryApiResource
|
||||
@@ -36,13 +46,20 @@ class CategoryApiResource
|
||||
* This value will identify this Category in relationships with other resources.
|
||||
*/
|
||||
#[API\ApiProperty(identifier: true)]
|
||||
#[Assert\NotBlank()]
|
||||
public string $id;
|
||||
|
||||
/**
|
||||
* A unique, non white space, string identifier for this Category.
|
||||
*/
|
||||
#[API\ApiProperty(writable: false)]
|
||||
#[API\ApiFilter(SearchFilter::class, strategy: 'exact')]
|
||||
public string $slug;
|
||||
|
||||
/**
|
||||
* A human-readable self-descriptive string of what this Category is about.
|
||||
*/
|
||||
#[API\ApiProperty()]
|
||||
#[Assert\NotBlank()]
|
||||
#[API\ApiProperty()]
|
||||
#[API\ApiFilter(SearchFilter::class, strategy: 'partial')]
|
||||
public string $name;
|
||||
}
|
||||
|
||||
@@ -141,11 +141,25 @@ class ProjectApiResource
|
||||
public Territory $territory;
|
||||
|
||||
/**
|
||||
* Free-form rich text description for the Project.
|
||||
* Rich-text (markdown) introduction to the project.
|
||||
*/
|
||||
#[API\ApiFilter(filterClass: SearchFilter::class, strategy: 'partial')]
|
||||
#[Assert\NotBlank()]
|
||||
public string $description;
|
||||
public string $descBrief;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown) description on the main features of the project.
|
||||
*/
|
||||
public string $descAbout;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown) about why this project is important.
|
||||
*/
|
||||
public string $descGoal;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown) about team and previous experience.
|
||||
*/
|
||||
public string $descTeam;
|
||||
|
||||
/**
|
||||
* Extracted embedding data from the Project's video.
|
||||
|
||||
@@ -58,7 +58,7 @@ class ProjectsPump implements PumpInterface
|
||||
}
|
||||
|
||||
$created = new \DateTime($record['created']);
|
||||
if (\in_array($status, [ProjectStatus::InDraft]) && $created < new \DateTime('2025-01-01')) {
|
||||
if (\in_array($status, [ProjectStatus::InDraft]) && $created < new \DateTime('2026-01-01')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,10 @@ class ProjectsPump implements PumpInterface
|
||||
$project->addLocale($record['lang']);
|
||||
$project->setTitle($record['name'] ?? '');
|
||||
$project->setSubtitle($record['subtitle'] ?? '');
|
||||
$project->setDescription($this->getProjectDescription($record));
|
||||
$project->setDescBrief($record['description']);
|
||||
$project->setDescAbout($record['about']);
|
||||
$project->setDescGoal($record['motivation']);
|
||||
$project->setDescTeam($record['related']);
|
||||
|
||||
$this->setPreventFlushAndClear(true);
|
||||
$this->persist($project, $context);
|
||||
@@ -103,7 +106,10 @@ class ProjectsPump implements PumpInterface
|
||||
$this->localize($project, $localizations, $context, [
|
||||
'title' => fn($l) => $l['name'],
|
||||
'subtitle' => fn($l) => $l['subtitle'],
|
||||
'description' => fn($l) => $this->getProjectDescription($l),
|
||||
'descBrief' => fn($l) => $l['description'],
|
||||
'descAbout' => fn($l) => $l['about'],
|
||||
'descGoal' => fn($l) => $l['motivation'],
|
||||
'descTeam' => fn($l) => $l['related'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -123,34 +129,6 @@ class ProjectsPump implements PumpInterface
|
||||
return $this->userRepository->matching($criteria)->first() ?? null;
|
||||
}
|
||||
|
||||
private function getProjectDescription(array $record): string
|
||||
{
|
||||
$lang = $record['lang'];
|
||||
$hasTitles = \array_key_exists($lang, self::PROJECT_DESC_TITLES);
|
||||
|
||||
$description = $record['description'];
|
||||
|
||||
if ($hasTitles) {
|
||||
$description .= \sprintf("\n\n## %s", self::PROJECT_DESC_TITLES[$lang]['about']);
|
||||
}
|
||||
|
||||
$description .= \sprintf("\n%s", $record['about']);
|
||||
|
||||
if ($hasTitles) {
|
||||
$description .= \sprintf("\n\n## %s", self::PROJECT_DESC_TITLES[$lang]['motivation']);
|
||||
}
|
||||
|
||||
$description .= \sprintf("\n\n%s", $record['motivation']);
|
||||
|
||||
if ($hasTitles) {
|
||||
$description .= \sprintf("\n\n## %s", self::PROJECT_DESC_TITLES[$lang]['related']);
|
||||
}
|
||||
|
||||
$description .= \sprintf("\n%s", $record['related']);
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
private function getProjectLocalizations(Project $project, array $context): array
|
||||
{
|
||||
$query = $this->getDbConnection($context)->prepare(
|
||||
@@ -194,14 +172,30 @@ class ProjectsPump implements PumpInterface
|
||||
|
||||
private function getProjectTerritory(array $record): Territory
|
||||
{
|
||||
if ($record['project_location'] === null) {
|
||||
$address = $record['project_location'];
|
||||
|
||||
if ($address === null) {
|
||||
if ($record['address'] !== null) {
|
||||
$address = $record['address'];
|
||||
}
|
||||
|
||||
if ($record['location'] !== null) {
|
||||
$address = $record['location'];
|
||||
}
|
||||
|
||||
if ($record['address'] !== null && $record['location'] !== null) {
|
||||
$address = \sprintf('%s, %s', $record['address'], $record['location']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($address === null) {
|
||||
return Territory::unknown();
|
||||
}
|
||||
|
||||
$cleanAddress = $this->cleanLocation($record['project_location'], 2);
|
||||
$cleanAddress = $this->cleanLocation($address, 2);
|
||||
|
||||
if ($cleanAddress === '') {
|
||||
return Territory::unknown($record['project_location']);
|
||||
return Territory::unknown($address);
|
||||
}
|
||||
|
||||
return $this->territoryService->search($cleanAddress);
|
||||
@@ -209,12 +203,14 @@ class ProjectsPump implements PumpInterface
|
||||
|
||||
private function getProjectVideoSource(array $record): ?string
|
||||
{
|
||||
if ($record['video'] !== null) {
|
||||
return \trim($record['video']);
|
||||
$video = \trim($record['video']);
|
||||
if ($video !== '' && $record['video'] !== null) {
|
||||
return $video;
|
||||
}
|
||||
|
||||
if ($record['media'] !== null) {
|
||||
return \trim($record['media']);
|
||||
$media = \trim($record['media']);
|
||||
if ($media !== '' && $record['media'] !== null) {
|
||||
return $media;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -24,6 +24,7 @@ class ProjectUpdationDto
|
||||
* Main headline for the Project.
|
||||
*/
|
||||
#[Assert\Regex('/[a-zA-Z]{1,}/')]
|
||||
#[Assert\Length(min: 3)]
|
||||
public string $title;
|
||||
|
||||
/**
|
||||
@@ -47,9 +48,28 @@ class ProjectUpdationDto
|
||||
public Territory $territory;
|
||||
|
||||
/**
|
||||
* Free-form rich text description for the Project.
|
||||
* Rich-text (markdown allowed) introduction to the project.
|
||||
*/
|
||||
public string $description;
|
||||
#[Assert\Length(min: 20)]
|
||||
public string $descBrief;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown allowed) description on the main features of the project.
|
||||
*/
|
||||
#[Assert\Length(min: 20)]
|
||||
public string $descAbout;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown allowed) about why this project is important.
|
||||
*/
|
||||
#[Assert\Length(min: 20)]
|
||||
public string $descGoal;
|
||||
|
||||
/**
|
||||
* Rich-text (markdown allowed) about team and previous experience.
|
||||
*/
|
||||
#[Assert\Length(min: 20)]
|
||||
public string $descTeam;
|
||||
|
||||
/**
|
||||
* On `minimum`, Project will campaign until the minimum deadline.\
|
||||
|
||||
+14
-4
@@ -15,8 +15,13 @@ class Category implements LocalizedInterface
|
||||
use LocalizedTrait;
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $id = null;
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 56, unique: true)]
|
||||
#[Gedmo\Slug(fields: ['name'])]
|
||||
private ?string $slug = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Gedmo\Translatable()]
|
||||
@@ -27,9 +32,14 @@ class Category implements LocalizedInterface
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(string $id): static
|
||||
public function getSlug(): ?string
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): static
|
||||
{
|
||||
$this->slug = $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -78,12 +78,21 @@ class Project implements UserOwnedInterface, AccountingOwnerInterface, Localized
|
||||
#[ORM\Embedded(class: Territory::class)]
|
||||
private ?Territory $territory;
|
||||
|
||||
/**
|
||||
* The description body for the Project.
|
||||
*/
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Gedmo\Translatable()]
|
||||
private ?string $description = null;
|
||||
private ?string $descBrief = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Gedmo\Translatable()]
|
||||
private ?string $descAbout = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Gedmo\Translatable()]
|
||||
private ?string $descGoal = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Gedmo\Translatable()]
|
||||
private ?string $descTeam = null;
|
||||
|
||||
/**
|
||||
* A video showcasing the Project.
|
||||
@@ -277,14 +286,50 @@ class Project implements UserOwnedInterface, AccountingOwnerInterface, Localized
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
public function getDescBrief(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
return $this->descBrief;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): static
|
||||
public function setDescBrief(?string $descBrief): static
|
||||
{
|
||||
$this->description = $description;
|
||||
$this->descBrief = $descBrief;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescAbout(): ?string
|
||||
{
|
||||
return $this->descAbout;
|
||||
}
|
||||
|
||||
public function setDescAbout(?string $descAbout): static
|
||||
{
|
||||
$this->descAbout = $descAbout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescGoal(): ?string
|
||||
{
|
||||
return $this->descGoal;
|
||||
}
|
||||
|
||||
public function setDescGoal(?string $descGoal): static
|
||||
{
|
||||
$this->descGoal = $descGoal;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescTeam(): ?string
|
||||
{
|
||||
return $this->descTeam;
|
||||
}
|
||||
|
||||
public function setDescTeam(?string $descTeam): static
|
||||
{
|
||||
$this->descTeam = $descTeam;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Territory
|
||||
* Plain-text address.\
|
||||
* e.g: Forn de l’Olivera 22B, 07012 Palma, Illes Balears.
|
||||
*/
|
||||
#[ORM\Column(type: Types::STRING, nullable: true)]
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
public readonly ?string $address;
|
||||
|
||||
public function __construct(
|
||||
|
||||
@@ -16,11 +16,9 @@ final class CategoryFactory extends PersistentProxyObjectFactory
|
||||
}
|
||||
|
||||
protected function defaults(
|
||||
string $id = 'test',
|
||||
string $name = 'Test Category',
|
||||
): array|callable {
|
||||
return [
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -41,8 +41,11 @@ final class ProjectFactory extends PersistentProxyObjectFactory
|
||||
{
|
||||
return [
|
||||
'deadline' => ProjectDeadline::Minimum,
|
||||
'description' => '',
|
||||
'territory' => new Territory('ES'),
|
||||
'descBrief' => 'Brief information on this Project',
|
||||
'descAbout' => 'About this Project',
|
||||
'descGoal' => 'Project\'s goal',
|
||||
'descTeam' => 'Project\'s team',
|
||||
'owner' => new User(),
|
||||
'status' => ProjectStatus::InDraft,
|
||||
'subtitle' => 'Subtitle',
|
||||
@@ -54,7 +57,10 @@ final class ProjectFactory extends PersistentProxyObjectFactory
|
||||
{
|
||||
return [
|
||||
'deadline' => self::faker()->randomElement(ProjectDeadline::cases()),
|
||||
'description' => self::faker()->text(),
|
||||
'descBrief' => self::faker()->text(),
|
||||
'descAbout' => self::faker()->text(),
|
||||
'descGoal' => self::faker()->text(),
|
||||
'descTeam' => self::faker()->text(),
|
||||
'territory' => new Territory('ES'),
|
||||
'owner' => UserFactory::createWithMode(),
|
||||
'status' => self::faker()->randomElement(ProjectStatus::cases()),
|
||||
|
||||
@@ -13,10 +13,10 @@ class NominatimService
|
||||
private float $lastRequestTime = 0.0;
|
||||
|
||||
/**
|
||||
* Cache calls to Nominatim for 1 hour.
|
||||
* Cache calls to Nominatim for 24 hours.
|
||||
* This ensures freshness of the data but minimizes bulk-operations hit rates to Nominatim.
|
||||
*/
|
||||
public const NOMINATIM_CACHE_TTL = 3600;
|
||||
public const NOMINATIM_CACHE_TTL = 86400;
|
||||
|
||||
private HttpClientInterface $httpClient;
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\ApiResource\CategoryApiResource;
|
||||
use App\Doctrine\LocalizedExtensionTrait;
|
||||
use App\Mapping\AutoMapper;
|
||||
use App\Repository\CategoryRepository;
|
||||
|
||||
class CategoryStateProvider implements ProviderInterface
|
||||
{
|
||||
use LocalizedExtensionTrait;
|
||||
|
||||
public function __construct(
|
||||
private CategoryRepository $categoryRepository,
|
||||
private AutoMapper $autoMapper,
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
|
||||
{
|
||||
$idOrSlug = $uriVariables['idOrSlug'];
|
||||
|
||||
$queryBuilder = $this->categoryRepository->createQueryBuilder('c');
|
||||
$queryBuilder->where(\is_numeric($idOrSlug) ? 'c.id = :value' : 'c.slug = :value');
|
||||
$queryBuilder->setParameter('value', $idOrSlug);
|
||||
|
||||
$query = $this->addLocalizationHints($queryBuilder, $this->getAcceptedLanguages($context));
|
||||
|
||||
$project = $query->getOneOrNullResult();
|
||||
|
||||
if ($project === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->autoMapper->map($project, CategoryApiResource::class);
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,7 @@ class GetAllTest extends ProjectTestCase
|
||||
$partialDescription = 'Physically defined as a modulable space';
|
||||
|
||||
$this->testGetAllByParam(
|
||||
'description',
|
||||
'descBrief',
|
||||
"lorem ipsum $partialDescription",
|
||||
'lorem ipsum vitae'
|
||||
);
|
||||
|
||||
@@ -21,7 +21,6 @@ class GetOneTest extends ProjectTestCase
|
||||
'title' => $project->getTitle(),
|
||||
'subtitle' => $project->getSubtitle(),
|
||||
'territory' => ['country' => $project->getTerritory()->country],
|
||||
'description' => $project->getDescription(),
|
||||
'deadline' => $project->getDeadline()->value,
|
||||
'status' => $project->getStatus()->value,
|
||||
];
|
||||
|
||||
@@ -26,7 +26,7 @@ abstract class ProjectTestCase extends ApiTestCase
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
save(CategoryFactory::createOne(['id' => 'test']));
|
||||
save(CategoryFactory::createOne(['name' => 'test']));
|
||||
}
|
||||
|
||||
// Auxiliary Methods
|
||||
|
||||
@@ -25,7 +25,7 @@ class UpdateTest extends ProjectTestCase
|
||||
'headers' => $this->withAuthHeader(TestUser::get()),
|
||||
'json' => [
|
||||
'title' => 'New project title',
|
||||
'description' => 'Updated project description',
|
||||
'descBrief' => 'Updated Project\'s brief description',
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
@@ -6,14 +6,16 @@ use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
||||
use App\Entity\Project\Project;
|
||||
use App\Entity\Project\ProjectDeadline;
|
||||
use App\Entity\Project\ProjectStatus;
|
||||
use App\Entity\Territory;
|
||||
use App\Entity\User\User;
|
||||
use App\Factory\Project\ProjectFactory;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class ProjectCalendarTest extends ApiTestCase
|
||||
{
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
private EntityManagerInterface $entityManager;
|
||||
private User $owner;
|
||||
@@ -40,16 +42,10 @@ class ProjectCalendarTest extends ApiTestCase
|
||||
|
||||
private function createTestProject(ProjectDeadline $deadline = ProjectDeadline::Minimum): Project
|
||||
{
|
||||
$project = new Project();
|
||||
$project->setTitle('Test Project');
|
||||
$project->setSubtitle('Test Project Subtitle');
|
||||
$project->setDeadline($deadline);
|
||||
$project->setDescription('Test Project Description');
|
||||
$project->setTerritory(new Territory('ES'));
|
||||
$project->setOwner($this->owner);
|
||||
$project->setStatus(ProjectStatus::InCampaignReview);
|
||||
|
||||
return $project;
|
||||
return ProjectFactory::createOne([
|
||||
'owner' => $this->owner,
|
||||
'deadline' => $deadline,
|
||||
])->_real();
|
||||
}
|
||||
|
||||
private function createProjectAndSetToInCampaign(
|
||||
@@ -104,6 +100,8 @@ class ProjectCalendarTest extends ApiTestCase
|
||||
$this->entityManager->persist($project);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->assertNull($project->getCalendar());
|
||||
$this->assertNull($project->getCalendar()->release);
|
||||
$this->assertNull($project->getCalendar()->minimum);
|
||||
$this->assertNull($project->getCalendar()->optimum);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user