Skip to content

Commit

Permalink
factory and strategy to apply rules for a project. add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rigonlucas committed Aug 30, 2024
1 parent 63b018b commit 24263b5
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 28 deletions.
2 changes: 1 addition & 1 deletion core/Application/Project/Update/UpdateProjectUseCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function execute(UpdateProjectInput $createProjectInput, UserEntity $auth
$recordedProjectEntity->canChangeProject();
$recordedProjectEntity->datesValidation();

StatusValidationFactory::make($recordedProjectEntity)->validateWithThrowException();
StatusValidationFactory::make($recordedProjectEntity)->validate();


return $this->projectCommand->update($recordedProjectEntity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Core\Domain\Entities\Project\ProjectEntity;
use Core\Domain\Entities\Project\StatusValidation\Strategies\DefaultValidation;
use Core\Domain\Entities\Project\StatusValidation\Strategies\InProgressValidation;
use Core\Domain\Entities\Project\StatusValidation\Strategies\PendingValidation;
use Core\Domain\Enum\Project\StatusProjectEnum;

class StatusValidationFactory
Expand All @@ -13,6 +14,7 @@ public static function make(ProjectEntity $projectEntity): StatusValidationInter
{
return match ($projectEntity->getStatus()) {
StatusProjectEnum::IN_PROGRESS => new InProgressValidation($projectEntity),
StatusProjectEnum::PENDING => new PendingValidation($projectEntity),
default => new DefaultValidation($projectEntity),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ interface StatusValidationInterface
{
public function __construct(ProjectEntity $projectEntity);

public function validate(): bool;

public function validateWithThrowException(): void;
public function validate(): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ public function __construct(ProjectEntity $projectEntity)
{
}

public function validate(): bool
{
return true;
}

public function validateWithThrowException(): void
public function validate(): void
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Core\Domain\Entities\Project\ProjectEntity;
use Core\Domain\Entities\Project\StatusValidation\StatusValidationInterface;
use Core\Support\Exceptions\Dates\DateNotAllowedException;
use Core\Support\Exceptions\Dates\DateRequiredException;

readonly class InProgressValidation implements StatusValidationInterface
Expand All @@ -12,22 +13,18 @@ public function __construct(private ProjectEntity $projectEntity)
{
}

public function validate(): bool
{
if (is_null($this->projectEntity->getStartAt())) {
return false;
}

return true;
}

/**
* @throws DateRequiredException
* @throws DateNotAllowedException
*/
public function validateWithThrowException(): void
public function validate(): void
{
if (is_null($this->projectEntity->getStartAt())) {
throw new DateRequiredException('Project must have a start date when status is in progress');
}

if (!is_null($this->projectEntity->getFinishAt())) {
throw new DateNotAllowedException('Project must not have a finish date when status is in progress');
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Core\Domain\Entities\Project\StatusValidation\Strategies;

use Core\Domain\Entities\Project\ProjectEntity;
use Core\Domain\Entities\Project\StatusValidation\StatusValidationInterface;
use Core\Support\Exceptions\Dates\DateNotAllowedException;

readonly class PendingValidation implements StatusValidationInterface
{
public function __construct(private ProjectEntity $projectEntity)
{
}

/**
* @throws DateNotAllowedException
*/
public function validate(): void
{
if ($this->projectEntity->getFinishAt() !== null) {
throw new DateNotAllowedException('Project must not have a finish date when status is pending');
}
}
}
19 changes: 19 additions & 0 deletions core/Support/Exceptions/Dates/DateNotAllowedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Core\Support\Exceptions\Dates;

use Core\Support\Exceptions\OutputErrorException;
use Core\Support\Http\ResponseStatus;
use Exception;

class DateNotAllowedException extends OutputErrorException
{
public function __construct(
string $message,
int $code = ResponseStatus::FORBIDDEN->value,
Exception $previous = null,
?array $errors = []
) {
parent::__construct($message, $code, $previous, $errors);
}
}
57 changes: 49 additions & 8 deletions tests/Unit/Entities/Project/StatusFactoryStrategiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Core\Domain\Entities\Project\StatusValidation\StatusValidationFactory;
use Core\Domain\Entities\User\UserEntity;
use Core\Domain\Enum\Project\StatusProjectEnum;
use Core\Support\Exceptions\Dates\DateNotAllowedException;
use Core\Support\Exceptions\Dates\DateRequiredException;
use Core\Support\Permissions\UserRoles;
use Ramsey\Uuid\Uuid;
Expand Down Expand Up @@ -48,7 +49,8 @@ public static function projectEntityProvider(): array
account: AccountEntity::forIdentify(1),
uuid: Uuid::uuid7(),
status: StatusProjectEnum::IN_PROGRESS,
finishAt: now()
startAt: now()->addDay(),
finishAt: now()->addDays(2)
)
]
];
Expand All @@ -57,30 +59,69 @@ public static function projectEntityProvider(): array
/**
* @dataProvider projectEntityProvider
*/
public function test_default_strategy_from_factory(ProjectEntity $projectEntity)
public function test_default_strategy_from_factory_has_only_success_case(ProjectEntity $projectEntity)
{
$this->expectNotToPerformAssertions();
$projectEntity->setStatus(StatusProjectEnum::BACKLOG);
StatusValidationFactory::make($projectEntity)->validateWithThrowException();
StatusValidationFactory::make($projectEntity)->validate();
}

/**
* @dataProvider projectEntityProvider
*/
public function test_pending_strategy_from_factory(projectentity $projectEntity)
{
public function test_pending_strategy_from_factory_success_case_when_finish_date_are_null(
projectentity $projectEntity
) {
$this->expectNotToPerformAssertions();
$projectEntity->setStatus(StatusProjectEnum::PENDING);
StatusValidationFactory::make($projectEntity)->validateWithThrowException();
$projectEntity->setFinishAt(null);
StatusValidationFactory::make($projectEntity)->validate();
}

/**
* @dataProvider projectEntityProvider
*/
public function test_in_progress_strategy_from_factory(ProjectEntity $projectEntity)
public function test_pending_strategy_from_factory_throw_case_when_finish_date_are_not_null(
projectentity $projectEntity
) {
$this->expectException(DateNotAllowedException::class);
$projectEntity->setStatus(StatusProjectEnum::PENDING);
StatusValidationFactory::make($projectEntity)->validate();
}

/**
* @dataProvider projectEntityProvider
*/
public function test_in_progress_strategy_from_factory_fail_case_without_started_date(ProjectEntity $projectEntity)
{
$this->expectException(DateRequiredException::class);
$projectEntity->setStatus(StatusProjectEnum::IN_PROGRESS);
StatusValidationFactory::make($projectEntity)->validateWithThrowException();
$projectEntity->setStartAt(null);
StatusValidationFactory::make($projectEntity)->validate();
}

/**
* @dataProvider projectEntityProvider
*/
public function test_in_progress_strategy_from_factory_fail_case_when_finished_date_are_setted(
ProjectEntity $projectEntity
) {
$this->expectException(DateNotAllowedException::class);
$projectEntity->setStatus(StatusProjectEnum::IN_PROGRESS);
$projectEntity->setStartAt(now());
$projectEntity->setFinishAt(now());
StatusValidationFactory::make($projectEntity)->validate();
}

/**
* @dataProvider projectEntityProvider
*/
public function test_in_progress_strategy_from_factory_success_case(ProjectEntity $projectEntity)
{
$this->expectNotToPerformAssertions();
$projectEntity->setStatus(StatusProjectEnum::IN_PROGRESS);
$projectEntity->setStartAt(now());
$projectEntity->setFinishAt(null);
StatusValidationFactory::make($projectEntity)->validate();
}
}

0 comments on commit 24263b5

Please sign in to comment.