Skip to content

Commit

Permalink
Add identifier factory (#326)
Browse files Browse the repository at this point in the history
This will:
- Add IdentifierFactory which will allow us to generate predictable
UUIDs during tests
  • Loading branch information
jskowronski39 authored Mar 15, 2024
2 parents 8cc9928 + 1f916eb commit 4402790
Show file tree
Hide file tree
Showing 25 changed files with 200 additions and 28 deletions.
4 changes: 4 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ services:

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\Service\IdentifierFactory\IdentifierFactoryInterface: '@App\Service\IdentifierFactory\IdentifierFactory'

App\Security\Authenticator\DiscordAuthenticator:
arguments:
$discordServerId: '%app.security.oauth.discord.server_id%'
Expand Down Expand Up @@ -109,3 +111,5 @@ when@test:
class: Symfony\Bundle\SecurityBundle\Security
arguments:
- '@test.service_container'

App\Service\IdentifierFactory\IdentifierFactoryInterface: '@App\Service\IdentifierFactory\IdentifierFactoryStub'
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use ApiPlatform\Validator\ValidatorInterface;
use App\Api\Input\Attendance\AttendanceInput;
use App\Entity\Attendance\Attendance;
use Ramsey\Uuid\Uuid;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;

class AttendanceInputDataTransformer
{
public function __construct(
private ValidatorInterface $validator
private ValidatorInterface $validator,
private IdentifierFactoryInterface $identifierFactory
) {
}

Expand All @@ -21,7 +22,7 @@ public function transform(AttendanceInput $attendanceInput): Attendance
$this->validator->validate($attendanceInput);

return new Attendance(
Uuid::uuid4(),
$this->identifierFactory->create(),
$attendanceInput->missionId,
$attendanceInput->playerId
);
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Dlc/CreateAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
#[IsGranted(PermissionsEnum::DLC_CREATE->value)]
public function __invoke(Request $request): Response
{
$dlcFormDto = new DlcFormDto();
$dlcFormDto = $this->dlcFormDtoDataTransformer->transformFromEntity(new DlcFormDto());
$form = $this->createForm(DlcFormType::class, $dlcFormDto);
$form->handleRequest($request);

Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Mod/CreateAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
#[IsGranted(PermissionsEnum::MOD_CREATE->value)]
public function __invoke(Request $request): Response
{
$modFormDto = new ModFormDto();
$modFormDto = $this->modFormDtoDataTransformer->transformFromEntity(new ModFormDto());
$form = $this->createForm(ModFormType::class, $modFormDto);
$form->handleRequest($request);

Expand Down
2 changes: 1 addition & 1 deletion src/Controller/ModGroup/CreateAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
#[IsGranted(PermissionsEnum::MOD_GROUP_CREATE->value)]
public function __invoke(Request $request): Response
{
$modGroupFormDto = new ModGroupFormDto();
$modGroupFormDto = $this->modGroupFormDtoDataTransformer->transformFromEntity(new ModGroupFormDto());
$form = $this->createForm(ModGroupFormType::class, $modGroupFormDto);
$form->handleRequest($request);

Expand Down
2 changes: 1 addition & 1 deletion src/Controller/ModList/CreateAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
#[IsGranted(PermissionsEnum::MOD_LIST_CREATE->value)]
public function __invoke(Request $request): Response
{
$modListFormDto = new ModListFormDto();
$modListFormDto = $this->modListFormDtoDataTransformer->transformFromEntity(new ModListFormDto());
$form = $this->createForm(ModListFormType::class, $modListFormDto);
$form->handleRequest($request);

Expand Down
2 changes: 1 addition & 1 deletion src/Controller/UserGroup/CreateAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
#[IsGranted(PermissionsEnum::USER_GROUP_CREATE->value)]
public function __invoke(Request $request): Response
{
$userGroupFormDto = new UserGroupFormDto();
$userGroupFormDto = $this->userGroupFormDtoDataTransformer->transformFromEntity(new UserGroupFormDto());
$form = $this->createForm(UserGroupFormType::class, $userGroupFormDto);
$form->handleRequest($request);

Expand Down
7 changes: 4 additions & 3 deletions src/Form/Dlc/DataTransformer/DlcFormDtoDataTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

use App\Entity\Dlc\Dlc;
use App\Form\Dlc\Dto\DlcFormDto;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;
use App\Service\SteamApiClient\Helper\SteamHelper;
use App\Service\SteamApiClient\SteamApiClientInterface;
use Ramsey\Uuid\Uuid;

class DlcFormDtoDataTransformer
{
public function __construct(
private SteamApiClientInterface $steamApiClient
private SteamApiClientInterface $steamApiClient,
private IdentifierFactoryInterface $identifierFactory
) {
}

Expand All @@ -25,7 +26,7 @@ public function transformToEntity(DlcFormDto $dlcFormDto, Dlc $dlc = null): Dlc

if (!$dlc instanceof Dlc) {
return new Dlc(
Uuid::uuid4(),
$this->identifierFactory->create(),
$name,
$dlcFormDto->getDescription(),
$appId,
Expand Down
9 changes: 5 additions & 4 deletions src/Form/Mod/DataTransformer/ModFormDtoDataTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
use App\Entity\Mod\Enum\ModTypeEnum;
use App\Entity\Mod\SteamWorkshopMod;
use App\Form\Mod\Dto\ModFormDto;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;
use App\Service\SteamApiClient\Helper\SteamHelper;
use App\Service\SteamApiClient\SteamApiClientInterface;
use Ramsey\Uuid\Uuid;

class ModFormDtoDataTransformer
{
public function __construct(
private SteamApiClientInterface $steamApiClient
private SteamApiClientInterface $steamApiClient,
private IdentifierFactoryInterface $identifierFactory
) {
}

Expand All @@ -36,7 +37,7 @@ public function transformToEntity(ModFormDto $modFormDto, AbstractMod $mod = nul

if (!$mod instanceof SteamWorkshopMod) {
return new SteamWorkshopMod(
Uuid::uuid4(),
$this->identifierFactory->create(),
$name,
$modFormDto->getDescription(),
$status,
Expand All @@ -57,7 +58,7 @@ public function transformToEntity(ModFormDto $modFormDto, AbstractMod $mod = nul
if (ModSourceEnum::DIRECTORY === $source) {
if (!$mod instanceof DirectoryMod) {
return new DirectoryMod(
Uuid::uuid4(),
$this->identifierFactory->create(),
$modFormDto->getName(),
$modFormDto->getDescription(),
$status,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@

use App\Entity\ModGroup\ModGroup;
use App\Form\ModGroup\Dto\ModGroupFormDto;
use Ramsey\Uuid\Uuid;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;

class ModGroupFormDtoDataTransformer
{
public function __construct(
private IdentifierFactoryInterface $identifierFactory
) {
}

public function transformToEntity(ModGroupFormDto $modGroupFormDto, ModGroup $modGroup = null): ModGroup
{
if (!$modGroup instanceof ModGroup) {
return new ModGroup(
Uuid::uuid4(),
$this->identifierFactory->create(),
$modGroupFormDto->getName(),
$modGroupFormDto->getDescription(),
$modGroupFormDto->getMods()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
use App\Entity\Permissions\AbstractPermissions;
use App\Entity\User\User;
use App\Form\ModList\Dto\ModListFormDto;
use Ramsey\Uuid\Uuid;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;
use Symfony\Bundle\SecurityBundle\Security;

class ModListFormDtoDataTransformer
{
public function __construct(
private Security $security
private Security $security,
private IdentifierFactoryInterface $identifierFactory
) {
}

Expand All @@ -32,7 +33,7 @@ public function transformToEntity(ModListFormDto $modListFormDto, ModList $modLi

if (!$modList instanceof ModList) {
return new ModList(
Uuid::uuid4(),
$this->identifierFactory->create(),
$modListFormDto->getName(),
$modListFormDto->getDescription(),
$modListFormDto->getMods(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@

namespace App\Form\UserGroup\DataTransformer;

use App\Entity\Permissions\UserGroupPermissions;
use App\Entity\UserGroup\UserGroup;
use App\Form\UserGroup\Dto\UserGroupFormDto;
use Ramsey\Uuid\Uuid;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;

class UserGroupFormDtoDataTransformer
{
public function __construct(
private IdentifierFactoryInterface $identifierFactory
) {
}

public function transformToEntity(UserGroupFormDto $userGroupFormDto, UserGroup $userGroup = null): UserGroup
{
if (!$userGroup instanceof UserGroup) {
return new UserGroup(
Uuid::uuid4(),
$this->identifierFactory->create(),
$userGroupFormDto->getName(),
$userGroupFormDto->getDescription(),
$userGroupFormDto->getPermissions(),
Expand All @@ -35,6 +41,9 @@ public function transformToEntity(UserGroupFormDto $userGroupFormDto, UserGroup
public function transformFromEntity(UserGroupFormDto $userGroupFormDto, UserGroup $userGroup = null): UserGroupFormDto
{
if (!$userGroup instanceof UserGroup) {
$permissions = new UserGroupPermissions($this->identifierFactory->create());
$userGroupFormDto->setPermissions($permissions);

return $userGroupFormDto;
}

Expand Down
2 changes: 0 additions & 2 deletions src/Form/UserGroup/Dto/UserGroupFormDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use App\Validator\UserGroup\UniqueUserGroupName;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Validator\Constraints as Assert;

Expand All @@ -32,7 +31,6 @@ class UserGroupFormDto
public function __construct()
{
$this->users = new ArrayCollection();
$this->permissions = new UserGroupPermissions(Uuid::uuid4());
}

public function getId(): ?UuidInterface
Expand Down
7 changes: 4 additions & 3 deletions src/Security/Authenticator/DiscordAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
use App\Security\Exception\RoleNotFoundException;
use App\Security\Exception\UserNotADiscordMemberException;
use App\Service\Discord\DiscordClientFactory;
use App\Service\IdentifierFactory\IdentifierFactoryInterface;
use Discord\Http\Endpoint;
use Discord\Http\Exceptions\NotFoundException;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use Ramsey\Uuid\Uuid;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down Expand Up @@ -52,6 +52,7 @@ public function __construct(
private EntityManagerInterface $em,
private RouterInterface $router,
private DiscordClientFactory $discordClientFactory,
private IdentifierFactoryInterface $identifierFactory,
private string $discordServerId,
private string $botToken,
private array $requiredServerRoleNames
Expand Down Expand Up @@ -145,9 +146,9 @@ public function authenticate(Request $request): Passport
return new SelfValidatingPassport(new UserBadge($externalId));
}

$permissions = new UserPermissions(Uuid::uuid4());
$permissions = new UserPermissions($this->identifierFactory->create());
$user = new User(
Uuid::uuid4(),
$this->identifierFactory->create(),
$fullUsername,
$email,
$externalId,
Expand Down
16 changes: 16 additions & 0 deletions src/Service/IdentifierFactory/IdentifierFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace App\Service\IdentifierFactory;

use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;

class IdentifierFactory implements IdentifierFactoryInterface
{
public function create(): UuidInterface
{
return Uuid::uuid4();
}
}
12 changes: 12 additions & 0 deletions src/Service/IdentifierFactory/IdentifierFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace App\Service\IdentifierFactory;

use Ramsey\Uuid\UuidInterface;

interface IdentifierFactoryInterface
{
public function create(): UuidInterface;
}
47 changes: 47 additions & 0 deletions src/Service/IdentifierFactory/IdentifierFactoryStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace App\Service\IdentifierFactory;

use Ramsey\Uuid\UuidInterface;

class IdentifierFactoryStub implements IdentifierFactoryInterface
{
/**
* @param UuidInterface[] $identifiers
*/
private array $identifiers = [];

/**
* @param UuidInterface[] $identifiers
*/
public function setIdentifiers(array $identifiers): void
{
foreach ($identifiers as $identifier) {
$this->addIdentifier($identifier);
}
}

public function create(): UuidInterface
{
if (!$this->identifiers) {
throw new \LogicException('No identifiers provided');
}

$key = array_key_first($this->identifiers);
$value = $this->identifiers[$key];
unset($this->identifiers[$key]);

return $value;
}

private function addIdentifier(UuidInterface $identifier): void
{
if (\in_array($identifier, $this->identifiers, true)) {
throw new \LogicException('Non unique identifier provided');
}

$this->identifiers[] = $identifier;
}
}
9 changes: 9 additions & 0 deletions tests/functional/Api/Attendance/CreateAttendanceCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@
namespace App\Tests\Functional\Api\Attendance;

use App\Entity\Attendance\Attendance;
use App\Service\IdentifierFactory\IdentifierFactoryStub;
use App\Tests\FunctionalTester;
use Codeception\Util\HttpCode;
use Ramsey\Uuid\Uuid;

class CreateAttendanceCest
{
public function _before(FunctionalTester $I): void
{
$I->haveHttpHeader('Accept', 'application/json');
$I->haveHttpHeader('Content-Type', 'application/json');

/** @var IdentifierFactoryStub $identifierFactory */
$identifierFactory = $I->grabService(IdentifierFactoryStub::class);
$identifierFactory->setIdentifiers([
Uuid::fromString('805c9fcd-d674-4a27-8f0c-78dbf2484bb2'),
]);
}

public function createAttendanceWithoutApiKey(FunctionalTester $I): void
Expand Down Expand Up @@ -61,6 +69,7 @@ public function createAttendanceUsingApiKey(FunctionalTester $I): void

/** @var Attendance $attendance */
$attendance = $I->grabEntityFromRepository(Attendance::class, ['missionId' => 'mission_99']);
$I->assertSame('805c9fcd-d674-4a27-8f0c-78dbf2484bb2', $attendance->getId()->toString());
$I->assertSame('mission_99', $attendance->getMissionId());
$I->assertSame(76561198048200529, $attendance->getPlayerId());
}
Expand Down
Loading

0 comments on commit 4402790

Please sign in to comment.