diff --git a/config/api_platform/mods/filters/ModList.yaml b/config/api_platform/mods/filters/StandardModList.yaml similarity index 100% rename from config/api_platform/mods/filters/ModList.yaml rename to config/api_platform/mods/filters/StandardModList.yaml diff --git a/config/api_platform/mods/resources/ModList.yaml b/config/api_platform/mods/resources/StandardModList.yaml similarity index 82% rename from config/api_platform/mods/resources/ModList.yaml rename to config/api_platform/mods/resources/StandardModList.yaml index 32e13769..446a5d94 100644 --- a/config/api_platform/mods/resources/ModList.yaml +++ b/config/api_platform/mods/resources/StandardModList.yaml @@ -1,9 +1,10 @@ resources: - App\Mods\Entity\ModList\ModList: + App\Mods\Entity\ModList\StandardModList: operations: ApiPlatform\Metadata\GetCollection: provider: 'App\Mods\Api\Provider\ModList\ModListDataProvider' output: 'App\Mods\Api\Output\ModList\ModListOutput' + uriTemplate: '/mod-lists' filters: - 'mod_list.search_filter' - 'mod_list.date_filter' @@ -12,6 +13,7 @@ resources: ApiPlatform\Metadata\Get: provider: 'App\Mods\Api\Provider\ModList\ModListDetailsDataProvider' output: 'App\Mods\Api\Output\ModList\ModListDetailsOutput' + uriTemplate: '/mod-lists/{id}' get_by_name: output: 'App\Mods\Api\Output\ModList\ModListDetailsOutput' @@ -19,7 +21,7 @@ resources: uriTemplate: '/mod-lists/by-name/{name}' uriVariables: name: - fromClass: 'App\Mods\Entity\ModList\ModList' + fromClass: 'App\Mods\Entity\ModList\StandardModList' fromProperty: 'name' controller: 'App\Mods\Api\Controller\ModList\GetModListByNameOperation' read: false diff --git a/config/doctrine/Mods/ModList.AbstractModList.orm.xml b/config/doctrine/Mods/ModList.AbstractModList.orm.xml new file mode 100644 index 00000000..662745c9 --- /dev/null +++ b/config/doctrine/Mods/ModList.AbstractModList.orm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/doctrine/Mods/ModList.ExternalModList.orm.xml b/config/doctrine/Mods/ModList.ExternalModList.orm.xml new file mode 100644 index 00000000..2b763ea6 --- /dev/null +++ b/config/doctrine/Mods/ModList.ExternalModList.orm.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/config/doctrine/Mods/ModList.ModList.orm.xml b/config/doctrine/Mods/ModList.StandardModList.orm.xml similarity index 78% rename from config/doctrine/Mods/ModList.ModList.orm.xml rename to config/doctrine/Mods/ModList.StandardModList.orm.xml index fd7894e5..e90ea0e5 100644 --- a/config/doctrine/Mods/ModList.ModList.orm.xml +++ b/config/doctrine/Mods/ModList.StandardModList.orm.xml @@ -4,10 +4,7 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - - - - + @@ -54,20 +51,7 @@ - - - - - - - - - - - - - diff --git a/config/doctrine/Users/Permissions.AbstractPermissions.orm.xml b/config/doctrine/Users/Permissions.AbstractPermissions.orm.xml index 24a1ffa9..6e0c715c 100644 --- a/config/doctrine/Users/Permissions.AbstractPermissions.orm.xml +++ b/config/doctrine/Users/Permissions.AbstractPermissions.orm.xml @@ -42,11 +42,16 @@ - - - - - + + + + + + + + + + diff --git a/migrations/Version20241117133108.php b/migrations/Version20241117133108.php new file mode 100644 index 00000000..087cf5bb --- /dev/null +++ b/migrations/Version20241117133108.php @@ -0,0 +1,66 @@ +addSql('ALTER TABLE mod_lists ADD type VARCHAR(255)'); + $this->addSql("UPDATE mod_lists SET type = 'standard'"); + $this->addSql('ALTER TABLE mod_lists ALTER type SET NOT NULL'); + + $this->addSql('ALTER TABLE mod_lists ADD url VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE mod_lists ALTER approved DROP NOT NULL'); + + $this->addSql('ALTER TABLE permissions RENAME COLUMN mod_list_create TO standard_mod_list_create'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN mod_list_update TO standard_mod_list_update'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN mod_list_delete TO standard_mod_list_delete'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN mod_list_copy TO standard_mod_list_copy'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN mod_list_approve TO standard_mod_list_approve'); + + $this->addSql('ALTER TABLE permissions ADD external_mod_list_create BOOLEAN'); + $this->addSql('ALTER TABLE permissions ADD external_mod_list_update BOOLEAN'); + $this->addSql('ALTER TABLE permissions ADD external_mod_list_delete BOOLEAN'); + $this->addSql('UPDATE permissions SET external_mod_list_create = false'); + $this->addSql('UPDATE permissions SET external_mod_list_update = false'); + $this->addSql('UPDATE permissions SET external_mod_list_delete = false'); + $this->addSql('ALTER TABLE permissions ALTER external_mod_list_create SET NOT NULL'); + $this->addSql('ALTER TABLE permissions ALTER external_mod_list_update SET NOT NULL'); + $this->addSql('ALTER TABLE permissions ALTER external_mod_list_delete SET NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql("DELETE FROM mod_lists WHERE type = 'external'"); + + $this->addSql('ALTER TABLE mod_lists DROP type'); + $this->addSql('ALTER TABLE mod_lists DROP url'); + $this->addSql('ALTER TABLE mod_lists ALTER approved SET NOT NULL'); + + $this->addSql('ALTER TABLE permissions RENAME COLUMN standard_mod_list_create TO mod_list_create'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN standard_mod_list_update TO mod_list_update'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN standard_mod_list_delete TO mod_list_delete'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN standard_mod_list_copy TO mod_list_copy'); + $this->addSql('ALTER TABLE permissions RENAME COLUMN standard_mod_list_approve TO mod_list_approve'); + + $this->addSql('ALTER TABLE permissions DROP external_mod_list_create'); + $this->addSql('ALTER TABLE permissions DROP external_mod_list_update'); + $this->addSql('ALTER TABLE permissions DROP external_mod_list_delete'); + } +} diff --git a/src/Mods/Api/Controller/ModList/GetModListByNameOperation.php b/src/Mods/Api/Controller/ModList/GetModListByNameOperation.php index 95b76ad3..550937e4 100644 --- a/src/Mods/Api/Controller/ModList/GetModListByNameOperation.php +++ b/src/Mods/Api/Controller/ModList/GetModListByNameOperation.php @@ -6,7 +6,7 @@ use App\Mods\Api\DataTransformer\ModList\ModListDetailsOutputDataTransformer; use App\Mods\Api\Output\ModList\ModListOutput; -use App\Mods\Repository\ModList\ModListRepository; +use App\Mods\Repository\ModList\StandardModListRepository; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -14,19 +14,19 @@ class GetModListByNameOperation { public function __construct( - private ModListRepository $modListRepository, + private StandardModListRepository $standardModListRepository, private ModListDetailsOutputDataTransformer $modListDetailsOutputDataTransformer, ) { } public function __invoke(string $name): ?ModListOutput { - $modList = $this->modListRepository->findOneByName($name); + $standardModList = $this->standardModListRepository->findOneByName($name); - if (!$modList) { + if (!$standardModList) { throw new NotFoundHttpException('Not Found'); } - return $this->modListDetailsOutputDataTransformer->transform($modList); + return $this->modListDetailsOutputDataTransformer->transform($standardModList); } } diff --git a/src/Mods/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php b/src/Mods/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php index 4382cc13..9207a12c 100644 --- a/src/Mods/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php +++ b/src/Mods/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php @@ -10,7 +10,7 @@ use App\Mods\Api\Output\ModList\ModListOutput; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Mods\Repository\Mod\ModRepository; class ModListDetailsOutputDataTransformer @@ -22,22 +22,22 @@ public function __construct( ) { } - public function transform(ModList $modList): ModListOutput + public function transform(StandardModList $standardModList): ModListOutput { return new ModListDetailsOutput( - $modList->getId()->toString(), - $modList->getName(), - $modList->isActive(), - $modList->isApproved(), - $modList->getCreatedAt(), - $modList->getLastUpdatedAt(), + $standardModList->getId()->toString(), + $standardModList->getName(), + $standardModList->isActive(), + $standardModList->isApproved(), + $standardModList->getCreatedAt(), + $standardModList->getLastUpdatedAt(), array_map( fn (AbstractMod $mod) => $this->modOutputDataTransformer->transform($mod), - $this->modRepository->findIncludedMods($modList) + $this->modRepository->findIncludedMods($standardModList) ), array_map( fn (Dlc $dlc) => $this->dlcOutputDataTransformer->transform($dlc), - $modList->getDlcs() + $standardModList->getDlcs() ), ); } diff --git a/src/Mods/Api/DataTransformer/ModList/ModListOutputDataTransformer.php b/src/Mods/Api/DataTransformer/ModList/ModListOutputDataTransformer.php index bc23afaa..cc504662 100644 --- a/src/Mods/Api/DataTransformer/ModList/ModListOutputDataTransformer.php +++ b/src/Mods/Api/DataTransformer/ModList/ModListOutputDataTransformer.php @@ -5,19 +5,19 @@ namespace App\Mods\Api\DataTransformer\ModList; use App\Mods\Api\Output\ModList\ModListOutput; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; class ModListOutputDataTransformer { - public function transform(ModList $modList): ModListOutput + public function transform(StandardModList $standardModList): ModListOutput { return new ModListOutput( - $modList->getId()->toString(), - $modList->getName(), - $modList->isActive(), - $modList->isApproved(), - $modList->getCreatedAt(), - $modList->getLastUpdatedAt(), + $standardModList->getId()->toString(), + $standardModList->getName(), + $standardModList->isActive(), + $standardModList->isApproved(), + $standardModList->getCreatedAt(), + $standardModList->getLastUpdatedAt(), ); } } diff --git a/src/Mods/Controller/ModList/ListAction.php b/src/Mods/Controller/ModList/Common/ListAction.php similarity index 70% rename from src/Mods/Controller/ModList/ListAction.php rename to src/Mods/Controller/ModList/Common/ListAction.php index c0263fe0..9031958d 100644 --- a/src/Mods/Controller/ModList/ListAction.php +++ b/src/Mods/Controller/ModList/Common/ListAction.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace App\Mods\Controller\ModList; +namespace App\Mods\Controller\ModList\Common; -use App\Mods\Repository\ModList\ModListRepository; +use App\Mods\Query\ModList\ModListListQuery; use App\Shared\Security\Enum\PermissionsEnum; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -14,7 +14,7 @@ class ListAction extends AbstractController { public function __construct( - private ModListRepository $modListRepository, + private ModListListQuery $modListListQuery, ) { } @@ -22,10 +22,7 @@ public function __construct( #[IsGranted(PermissionsEnum::MOD_LIST_LIST->value)] public function __invoke(): Response { - $modLists = $this->modListRepository->findBy([], [ - 'approved' => 'DESC', - 'name' => 'ASC', - ]); + $modLists = $this->modListListQuery->getResult(); return $this->render('mods/mod_list/list.html.twig', [ 'modLists' => $modLists, diff --git a/src/Mods/Controller/ModList/CopyAction.php b/src/Mods/Controller/ModList/CopyAction.php deleted file mode 100644 index a12cb02b..00000000 --- a/src/Mods/Controller/ModList/CopyAction.php +++ /dev/null @@ -1,48 +0,0 @@ -value, 'modList')] - public function __invoke(Request $request, ModList $modList): Response - { - $modListFormDto = $this->modListFormDtoDataTransformer->transformFromEntity(new ModListFormDto(), $modList, true); - $form = $this->createForm(ModListFormType::class, $modListFormDto); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $modListCopy = $this->modListFormDtoDataTransformer->transformToEntity($modListFormDto); - - $this->entityManager->persist($modListCopy); - $this->entityManager->flush(); - - return $this->redirectToRoute('app_mod_list_list'); - } - - return $this->render('mods/mod_list/form.html.twig', [ - 'form' => $form->createView(), - ]); - } -} diff --git a/src/Mods/Controller/ModList/External/CreateAction.php b/src/Mods/Controller/ModList/External/CreateAction.php new file mode 100644 index 00000000..1a9b6151 --- /dev/null +++ b/src/Mods/Controller/ModList/External/CreateAction.php @@ -0,0 +1,47 @@ +value)] + public function __invoke(Request $request): Response + { + $externalModListFormDto = $this->externalModListFormDtoDataTransformer->transformFromEntity(new ExternalModListFormDto()); + $form = $this->createForm(ExternalModListFormType::class, $externalModListFormDto); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $externalModList = $this->externalModListFormDtoDataTransformer->transformToEntity($externalModListFormDto); + + $this->entityManager->persist($externalModList); + $this->entityManager->flush(); + + return $this->redirectToRoute('app_mod_list_list'); + } + + return $this->render('mods/mod_list/remote_form.html.twig', [ + 'form' => $form->createView(), + ]); + } +} diff --git a/src/Mods/Controller/ModList/DeleteAction.php b/src/Mods/Controller/ModList/External/DeleteAction.php similarity index 60% rename from src/Mods/Controller/ModList/DeleteAction.php rename to src/Mods/Controller/ModList/External/DeleteAction.php index 69d225e9..75635eb8 100644 --- a/src/Mods/Controller/ModList/DeleteAction.php +++ b/src/Mods/Controller/ModList/External/DeleteAction.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace App\Mods\Controller\ModList; +namespace App\Mods\Controller\ModList\External; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\ExternalModList; use App\Shared\Security\Enum\PermissionsEnum; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -19,11 +19,11 @@ public function __construct( ) { } - #[Route('/mod-list/{name}/delete', name: 'app_mod_list_delete')] - #[IsGranted(PermissionsEnum::MOD_LIST_DELETE->value, 'modList')] - public function __invoke(ModList $modList): Response + #[Route('/external-mod-list/{name}/delete', name: 'app_external_mod_list_delete')] + #[IsGranted(PermissionsEnum::EXTERNAL_MOD_LIST_DELETE->value, 'externalModList')] + public function __invoke(ExternalModList $externalModList): Response { - $this->entityManager->remove($modList); + $this->entityManager->remove($externalModList); $this->entityManager->flush(); return $this->redirectToRoute('app_mod_list_list'); diff --git a/src/Mods/Controller/ModList/External/UpdateAction.php b/src/Mods/Controller/ModList/External/UpdateAction.php new file mode 100644 index 00000000..16b15b3d --- /dev/null +++ b/src/Mods/Controller/ModList/External/UpdateAction.php @@ -0,0 +1,47 @@ +value, 'externalModList')] + public function __invoke(Request $request, ExternalModList $externalModList): Response + { + $externalModListFormDto = $this->externalModListFormDtoDataTransformer->transformFromEntity(new ExternalModListFormDto(), $externalModList); + $form = $this->createForm(ExternalModListFormType::class, $externalModListFormDto); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->externalModListFormDtoDataTransformer->transformToEntity($externalModListFormDto, $externalModList); + + $this->entityManager->flush(); + + return $this->redirectToRoute('app_mod_list_list'); + } + + return $this->render('mods/mod_list/remote_form.html.twig', [ + 'form' => $form->createView(), + ]); + } +} diff --git a/src/Mods/Controller/ModList/Standard/CopyAction.php b/src/Mods/Controller/ModList/Standard/CopyAction.php new file mode 100644 index 00000000..72fe3630 --- /dev/null +++ b/src/Mods/Controller/ModList/Standard/CopyAction.php @@ -0,0 +1,48 @@ +value, 'standardModList')] + public function __invoke(Request $request, StandardModList $standardModList): Response + { + $standardModListFormDto = $this->standardModListFormDtoDataTransformer->transformFromEntity(new StandardModListFormDto(), $standardModList, true); + $form = $this->createForm(StandardModListFormType::class, $standardModListFormDto); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $standardModListCopy = $this->standardModListFormDtoDataTransformer->transformToEntity($standardModListFormDto); + + $this->entityManager->persist($standardModListCopy); + $this->entityManager->flush(); + + return $this->redirectToRoute('app_mod_list_list'); + } + + return $this->render('mods/mod_list/standard_form.html.twig', [ + 'form' => $form->createView(), + ]); + } +} diff --git a/src/Mods/Controller/ModList/CreateAction.php b/src/Mods/Controller/ModList/Standard/CreateAction.php similarity index 50% rename from src/Mods/Controller/ModList/CreateAction.php rename to src/Mods/Controller/ModList/Standard/CreateAction.php index 2c3a1dbc..854b71c7 100644 --- a/src/Mods/Controller/ModList/CreateAction.php +++ b/src/Mods/Controller/ModList/Standard/CreateAction.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace App\Mods\Controller\ModList; +namespace App\Mods\Controller\ModList\Standard; -use App\Mods\Form\ModList\DataTransformer\ModListFormDtoDataTransformer; -use App\Mods\Form\ModList\Dto\ModListFormDto; -use App\Mods\Form\ModList\ModListFormType; +use App\Mods\Form\ModList\Standard\DataTransformer\StandardModListFormDtoDataTransformer; +use App\Mods\Form\ModList\Standard\Dto\StandardModListFormDto; +use App\Mods\Form\ModList\Standard\StandardModListFormType; use App\Shared\Security\Enum\PermissionsEnum; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -19,20 +19,20 @@ class CreateAction extends AbstractController { public function __construct( private EntityManagerInterface $entityManager, - private ModListFormDtoDataTransformer $modListFormDtoDataTransformer + private StandardModListFormDtoDataTransformer $standardModListFormDtoDataTransformer ) { } - #[Route('/mod-list/create', name: 'app_mod_list_create')] - #[IsGranted(PermissionsEnum::MOD_LIST_CREATE->value)] + #[Route('/standard-mod-list/create', name: 'app_standard_mod_list_create')] + #[IsGranted(PermissionsEnum::STANDARD_MOD_LIST_CREATE->value)] public function __invoke(Request $request): Response { - $modListFormDto = $this->modListFormDtoDataTransformer->transformFromEntity(new ModListFormDto()); - $form = $this->createForm(ModListFormType::class, $modListFormDto); + $standardModListFormDto = $this->standardModListFormDtoDataTransformer->transformFromEntity(new StandardModListFormDto()); + $form = $this->createForm(StandardModListFormType::class, $standardModListFormDto); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $modList = $this->modListFormDtoDataTransformer->transformToEntity($modListFormDto); + $modList = $this->standardModListFormDtoDataTransformer->transformToEntity($standardModListFormDto); $this->entityManager->persist($modList); $this->entityManager->flush(); @@ -40,7 +40,7 @@ public function __invoke(Request $request): Response return $this->redirectToRoute('app_mod_list_list'); } - return $this->render('mods/mod_list/form.html.twig', [ + return $this->render('mods/mod_list/standard_form.html.twig', [ 'form' => $form->createView(), ]); } diff --git a/src/Mods/Controller/ModList/Standard/DeleteAction.php b/src/Mods/Controller/ModList/Standard/DeleteAction.php new file mode 100644 index 00000000..3450853d --- /dev/null +++ b/src/Mods/Controller/ModList/Standard/DeleteAction.php @@ -0,0 +1,31 @@ +value, 'standardModList')] + public function __invoke(StandardModList $standardModList): Response + { + $this->entityManager->remove($standardModList); + $this->entityManager->flush(); + + return $this->redirectToRoute('app_mod_list_list'); + } +} diff --git a/src/Mods/Controller/ModList/Standard/UpdateAction.php b/src/Mods/Controller/ModList/Standard/UpdateAction.php new file mode 100644 index 00000000..003dd759 --- /dev/null +++ b/src/Mods/Controller/ModList/Standard/UpdateAction.php @@ -0,0 +1,47 @@ +value, 'standardModList')] + public function __invoke(Request $request, StandardModList $standardModList): Response + { + $standardModListFormDto = $this->standardModListFormDtoDataTransformer->transformFromEntity(new StandardModListFormDto(), $standardModList); + $form = $this->createForm(StandardModListFormType::class, $standardModListFormDto); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->standardModListFormDtoDataTransformer->transformToEntity($standardModListFormDto, $standardModList); + + $this->entityManager->flush(); + + return $this->redirectToRoute('app_mod_list_list'); + } + + return $this->render('mods/mod_list/standard_form.html.twig', [ + 'form' => $form->createView(), + ]); + } +} diff --git a/src/Mods/Controller/ModList/UpdateAction.php b/src/Mods/Controller/ModList/UpdateAction.php deleted file mode 100644 index 1a396829..00000000 --- a/src/Mods/Controller/ModList/UpdateAction.php +++ /dev/null @@ -1,47 +0,0 @@ -value, 'modList')] - public function __invoke(Request $request, ModList $modList): Response - { - $modListFormDto = $this->modListFormDtoDataTransformer->transformFromEntity(new ModListFormDto(), $modList); - $form = $this->createForm(ModListFormType::class, $modListFormDto); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $this->modListFormDtoDataTransformer->transformToEntity($modListFormDto, $modList); - - $this->entityManager->flush(); - - return $this->redirectToRoute('app_mod_list_list'); - } - - return $this->render('mods/mod_list/form.html.twig', [ - 'form' => $form->createView(), - ]); - } -} diff --git a/src/Mods/Controller/ModListPublic/CustomizeAction.php b/src/Mods/Controller/ModListPublic/CustomizeAction.php index a8fab737..dddcfa0c 100644 --- a/src/Mods/Controller/ModListPublic/CustomizeAction.php +++ b/src/Mods/Controller/ModListPublic/CustomizeAction.php @@ -4,7 +4,9 @@ namespace App\Mods\Controller\ModListPublic; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\AbstractModList; +use App\Mods\Entity\ModList\ExternalModList; +use App\Mods\Entity\ModList\StandardModList; use App\Mods\Repository\Mod\ModRepository; use App\Shared\Security\Enum\PermissionsEnum; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -21,8 +23,13 @@ public function __construct( #[Route('/mod-list/{name}', name: 'app_mod_list_public_customize', priority: -1)] #[IsGranted(PermissionsEnum::MOD_LIST_DOWNLOAD->value, 'modList')] - public function __invoke(ModList $modList): Response + public function __invoke(AbstractModList $modList): Response { + /** @var ExternalModList|StandardModList $modList */ + if ($modList instanceof ExternalModList) { + return $this->redirect($modList->getUrl()); + } + $optionalMods = $this->modRepository->findIncludedOptionalSteamWorkshopMods($modList); $requiredMods = $this->modRepository->findIncludedRequiredSteamWorkshopMods($modList); diff --git a/src/Mods/Controller/ModListPublic/DownloadAction.php b/src/Mods/Controller/ModListPublic/DownloadAction.php index 5d6a9436..1f482ffd 100644 --- a/src/Mods/Controller/ModListPublic/DownloadAction.php +++ b/src/Mods/Controller/ModListPublic/DownloadAction.php @@ -4,7 +4,7 @@ namespace App\Mods\Controller\ModListPublic; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Mods\Repository\Mod\ModRepository; use App\Shared\Security\Enum\PermissionsEnum; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -24,7 +24,7 @@ public function __construct( #[Route('/mod-list/{name}/download/{optionalModsJson}', name: 'app_mod_list_public_download', options: ['expose' => true])] #[IsGranted(PermissionsEnum::MOD_LIST_DOWNLOAD->value, 'modList')] - public function __invoke(ModList $modList, string $optionalModsJson = null): Response + public function __invoke(StandardModList $modList, string $optionalModsJson = null): Response { $name = sprintf('ArmaForces %s %s', $modList->getName(), now()->format('Y_m_d H_i')); $mods = $this->modRepository->findIncludedSteamWorkshopMods($modList); diff --git a/src/Mods/Controller/ModListPublic/SelectAction.php b/src/Mods/Controller/ModListPublic/SelectAction.php index 8f3cd6d5..c37148f3 100644 --- a/src/Mods/Controller/ModListPublic/SelectAction.php +++ b/src/Mods/Controller/ModListPublic/SelectAction.php @@ -4,6 +4,7 @@ namespace App\Mods\Controller\ModListPublic; +use App\Mods\Query\ModList\ActiveModListListQuery; use App\Mods\Repository\ModList\ModListRepository; use App\Shared\Service\Mission\MissionClientInterface; use Psr\Log\LoggerInterface; @@ -16,6 +17,7 @@ class SelectAction extends AbstractController public function __construct( private LoggerInterface $logger, private ModListRepository $modListRepository, + private ActiveModListListQuery $activeModListListQuery, private MissionClientInterface $missionClient, ) { } @@ -23,10 +25,7 @@ public function __construct( #[Route('/mod-list/select', name: 'app_mod_list_public_select')] public function __invoke(): Response { - $modLists = $this->modListRepository->findBy(['active' => true], [ - 'approved' => 'DESC', - 'name' => 'ASC', - ]); + $modLists = $this->activeModListListQuery->getResult(); try { $nextMission = $this->missionClient->getCurrentMission(); diff --git a/src/Mods/DataFixtures/ModList/External/GoogleExternalModList.php b/src/Mods/DataFixtures/ModList/External/GoogleExternalModList.php new file mode 100644 index 00000000..cd3a5330 --- /dev/null +++ b/src/Mods/DataFixtures/ModList/External/GoogleExternalModList.php @@ -0,0 +1,51 @@ +withTimeFrozenAt('2020-01-01T00:00:00+00:00', function () use ($manager): void { + $createdBy = $this->getReference(self::CREATED_BY_ID); + + $externalModList = new ExternalModList( + Uuid::fromString(self::ID), + self::NAME, + null, + 'https://google.com', + false, + ); + + $externalModList->created($createdBy); + + $manager->persist($externalModList); + $manager->flush(); + + $this->addReference(self::ID, $externalModList); + }); + } + + public function getDependencies(): array + { + return [ + User2Fixture::class, // created by + ]; + } +} diff --git a/src/Mods/DataFixtures/ModList/External/LocalhostExternalModList.php b/src/Mods/DataFixtures/ModList/External/LocalhostExternalModList.php new file mode 100644 index 00000000..aa6bc3c1 --- /dev/null +++ b/src/Mods/DataFixtures/ModList/External/LocalhostExternalModList.php @@ -0,0 +1,51 @@ +withTimeFrozenAt('2020-01-01T00:00:00+00:00', function () use ($manager): void { + $createdBy = $this->getReference(self::CREATED_BY_ID); + + $externalModList = new ExternalModList( + Uuid::fromString(self::ID), + self::NAME, + null, + 'https://localhost', + true, + ); + + $externalModList->created($createdBy); + + $manager->persist($externalModList); + $manager->flush(); + + $this->addReference(self::ID, $externalModList); + }); + } + + public function getDependencies(): array + { + return [ + User1Fixture::class, // created by + ]; + } +} diff --git a/src/Mods/DataFixtures/ModList/CupModListFixture.php b/src/Mods/DataFixtures/ModList/Standard/CupStandardModListFixture.php similarity index 88% rename from src/Mods/DataFixtures/ModList/CupModListFixture.php rename to src/Mods/DataFixtures/ModList/Standard/CupStandardModListFixture.php index d30387cb..50ee4fd0 100644 --- a/src/Mods/DataFixtures/ModList/CupModListFixture.php +++ b/src/Mods/DataFixtures/ModList/Standard/CupStandardModListFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\DataFixtures\ModList; +namespace App\Mods\DataFixtures\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Mod\Directory\ArmaScriptProfilerModFixture; @@ -13,7 +13,7 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Deprecated\LegacyArmaForcesModsModFixture; use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Disabled\ArmaForcesJbadBuildingFixModFixture; use App\Mods\DataFixtures\ModGroup\CupModGroupFixture; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Test\Traits\TimeTrait; use App\Users\DataFixtures\User\User1Fixture; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -21,7 +21,7 @@ use Doctrine\Persistence\ObjectManager; use Ramsey\Uuid\Uuid; -class CupModListFixture extends Fixture implements DependentFixtureInterface +class CupStandardModListFixture extends Fixture implements DependentFixtureInterface { use TimeTrait; @@ -34,7 +34,7 @@ public function load(ObjectManager $manager): void $this->withTimeFrozenAt('2020-01-01T00:00:00+00:00', function () use ($manager): void { $owner = $this->getReference(self::OWNER_ID); - $modList = new ModList( + $standardModList = new StandardModList( Uuid::fromString(self::ID), self::NAME, null, @@ -59,12 +59,12 @@ public function load(ObjectManager $manager): void false, ); - $modList->created($owner); + $standardModList->created($owner); - $manager->persist($modList); + $manager->persist($standardModList); $manager->flush(); - $this->addReference(self::ID, $modList); + $this->addReference(self::ID, $standardModList); }); } diff --git a/src/Mods/DataFixtures/ModList/DefaultModListFixture.php b/src/Mods/DataFixtures/ModList/Standard/DefaultStandardModListFixture.php similarity index 93% rename from src/Mods/DataFixtures/ModList/DefaultModListFixture.php rename to src/Mods/DataFixtures/ModList/Standard/DefaultStandardModListFixture.php index 805d03e0..dbbb33be 100644 --- a/src/Mods/DataFixtures/ModList/DefaultModListFixture.php +++ b/src/Mods/DataFixtures/ModList/Standard/DefaultStandardModListFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\DataFixtures\ModList; +namespace App\Mods\DataFixtures\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Dlc\GlobalMobilizationDlcFixture; @@ -25,14 +25,14 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\RhsUsafModFixture; use App\Mods\DataFixtures\ModGroup\CupModGroupFixture; use App\Mods\DataFixtures\ModGroup\RhsModGroupFixture; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Test\Traits\TimeTrait; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; use Ramsey\Uuid\Uuid; -class DefaultModListFixture extends Fixture implements DependentFixtureInterface +class DefaultStandardModListFixture extends Fixture implements DependentFixtureInterface { use TimeTrait; @@ -42,7 +42,7 @@ class DefaultModListFixture extends Fixture implements DependentFixtureInterface public function load(ObjectManager $manager): void { $this->withTimeFrozenAt('2020-01-01T00:00:00+00:00', function () use ($manager): void { - $modList = new ModList( + $standardModList = new StandardModList( Uuid::fromString(self::ID), self::NAME, null, @@ -81,10 +81,10 @@ public function load(ObjectManager $manager): void true, ); - $manager->persist($modList); + $manager->persist($standardModList); $manager->flush(); - $this->addReference(self::ID, $modList); + $this->addReference(self::ID, $standardModList); }); } diff --git a/src/Mods/DataFixtures/ModList/RhsModListFixture.php b/src/Mods/DataFixtures/ModList/Standard/RhsStandardModListFixture.php similarity index 88% rename from src/Mods/DataFixtures/ModList/RhsModListFixture.php rename to src/Mods/DataFixtures/ModList/Standard/RhsStandardModListFixture.php index 1604611c..166d69d5 100644 --- a/src/Mods/DataFixtures/ModList/RhsModListFixture.php +++ b/src/Mods/DataFixtures/ModList/Standard/RhsStandardModListFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\DataFixtures\ModList; +namespace App\Mods\DataFixtures\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Mod\Directory\ArmaScriptProfilerModFixture; @@ -13,7 +13,7 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Deprecated\LegacyArmaForcesModsModFixture; use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Disabled\ArmaForcesJbadBuildingFixModFixture; use App\Mods\DataFixtures\ModGroup\RhsModGroupFixture; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Test\Traits\TimeTrait; use App\Users\DataFixtures\User\User2Fixture; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -21,7 +21,7 @@ use Doctrine\Persistence\ObjectManager; use Ramsey\Uuid\Uuid; -class RhsModListFixture extends Fixture implements DependentFixtureInterface +class RhsStandardModListFixture extends Fixture implements DependentFixtureInterface { use TimeTrait; @@ -34,7 +34,7 @@ public function load(ObjectManager $manager): void $this->withTimeFrozenAt('2020-01-01T00:00:00+00:00', function () use ($manager): void { $owner = $this->getReference(self::OWNER_ID); - $modList = new ModList( + $standardModList = new StandardModList( Uuid::fromString(self::ID), self::NAME, null, @@ -59,12 +59,12 @@ public function load(ObjectManager $manager): void false, ); - $modList->created($owner); + $standardModList->created($owner); - $manager->persist($modList); + $manager->persist($standardModList); $manager->flush(); - $this->addReference(self::ID, $modList); + $this->addReference(self::ID, $standardModList); }); } diff --git a/src/Mods/Entity/ModList/AbstractModList.php b/src/Mods/Entity/ModList/AbstractModList.php new file mode 100644 index 00000000..82d4d11e --- /dev/null +++ b/src/Mods/Entity/ModList/AbstractModList.php @@ -0,0 +1,29 @@ +name; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function isActive(): bool + { + return $this->active; + } +} diff --git a/src/Mods/Entity/ModList/Enum/ModListTypeEnum.php b/src/Mods/Entity/ModList/Enum/ModListTypeEnum.php new file mode 100644 index 00000000..68f8efee --- /dev/null +++ b/src/Mods/Entity/ModList/Enum/ModListTypeEnum.php @@ -0,0 +1,12 @@ +name = $name; + $this->description = $description; + $this->url = $url; + $this->active = $active; + } + + public function update( + string $name, + ?string $description, + string $url, + bool $active, + ): void { + $this->name = $name; + $this->description = $description; + $this->url = $url; + $this->active = $active; + } + + public function getUrl(): string + { + return $this->url; + } +} diff --git a/src/Mods/Entity/ModList/ModList.php b/src/Mods/Entity/ModList/StandardModList.php similarity index 88% rename from src/Mods/Entity/ModList/ModList.php rename to src/Mods/Entity/ModList/StandardModList.php index e99fefe9..20e24e01 100644 --- a/src/Mods/Entity/ModList/ModList.php +++ b/src/Mods/Entity/ModList/StandardModList.php @@ -7,21 +7,17 @@ use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Shared\Entity\Common\AbstractBlamableEntity; use App\Users\Entity\User\User; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Ramsey\Uuid\UuidInterface; -class ModList extends AbstractBlamableEntity +class StandardModList extends AbstractModList { - private string $name; - private ?string $description; private Collection $mods; private Collection $modGroups; private Collection $dlcs; private ?User $owner; - private bool $active; private bool $approved; public function __construct( @@ -70,16 +66,6 @@ public function update( $this->approved = $approved; } - public function getName(): string - { - return $this->name; - } - - public function getDescription(): ?string - { - return $this->description; - } - /** * @return AbstractMod[] */ @@ -96,14 +82,17 @@ public function getModGroups(): array return $this->modGroups->toArray(); } - public function getOwner(): ?User + /** + * @return Dlc[] + */ + public function getDlcs(): array { - return $this->owner; + return $this->dlcs->toArray(); } - public function isActive(): bool + public function getOwner(): ?User { - return $this->active; + return $this->owner; } public function isApproved(): bool @@ -111,14 +100,6 @@ public function isApproved(): bool return $this->approved; } - /** - * @return Dlc[] - */ - public function getDlcs(): array - { - return $this->dlcs->toArray(); - } - private function setMods(array $mods): void { $this->mods->clear(); diff --git a/src/Mods/Form/ModList/DataTransformer/ModListFormDtoDataTransformer.php b/src/Mods/Form/ModList/DataTransformer/ModListFormDtoDataTransformer.php deleted file mode 100644 index 34579e98..00000000 --- a/src/Mods/Form/ModList/DataTransformer/ModListFormDtoDataTransformer.php +++ /dev/null @@ -1,85 +0,0 @@ -security->getUser(); - - $canUpdate = $currentUser->hasPermissions( - static fn (AbstractPermissions $permissions) => $permissions->modListUpdate - ); - - // If user has permissions set selected user as owner. Otherwise assign current user. - $owner = $canUpdate ? $modListFormDto->getOwner() : $currentUser; - - if (!$modList instanceof ModList) { - return new ModList( - $this->identifierFactory->create(), - $modListFormDto->getName(), - $modListFormDto->getDescription(), - $modListFormDto->getMods(), - $modListFormDto->getModGroups(), - $modListFormDto->getDlcs(), - $owner, - $modListFormDto->isActive(), - $modListFormDto->isApproved(), - ); - } - - $modList->update( - $modListFormDto->getName(), - $modListFormDto->getDescription(), - $modListFormDto->getMods(), - $modListFormDto->getModGroups(), - $modListFormDto->getDlcs(), - $owner, - $modListFormDto->isActive(), - $modListFormDto->isApproved(), - ); - - return $modList; - } - - public function transformFromEntity(ModListFormDto $modListFormDto, ModList $modList = null, bool $copy = false): ModListFormDto - { - if (!$modList instanceof ModList) { - return $modListFormDto; - } - - $modListFormDto->setId($modList->getId()); - $modListFormDto->setName($modList->getName()); - $modListFormDto->setDescription($modList->getDescription()); - $modListFormDto->setMods($modList->getMods()); - $modListFormDto->setModGroups($modList->getModGroups()); - $modListFormDto->setDlcs($modList->getDlcs()); - $modListFormDto->setOwner($modList->getOwner()); - $modListFormDto->setActive($modList->isActive()); - $modListFormDto->setApproved($modList->isApproved()); - - if ($copy) { - $modListFormDto->setId(null); // Entity will be treated as new by the unique name validator - $modListFormDto->setApproved(false); // Reset approval status - } - - return $modListFormDto; - } -} diff --git a/src/Mods/Form/ModList/External/DataTransformer/ExternalModListFormDtoDataTransformer.php b/src/Mods/Form/ModList/External/DataTransformer/ExternalModListFormDtoDataTransformer.php new file mode 100644 index 00000000..1488deac --- /dev/null +++ b/src/Mods/Form/ModList/External/DataTransformer/ExternalModListFormDtoDataTransformer.php @@ -0,0 +1,54 @@ +identifierFactory->create(), + $externalModListFormDto->getName(), + $externalModListFormDto->getDescription(), + $externalModListFormDto->getUrl(), + $externalModListFormDto->isActive(), + ); + } + + $externalModList->update( + $externalModListFormDto->getName(), + $externalModListFormDto->getDescription(), + $externalModListFormDto->getUrl(), + $externalModListFormDto->isActive(), + ); + + return $externalModList; + } + + public function transformFromEntity(ExternalModListFormDto $externalModListFormDto, ExternalModList $externalModList = null): ExternalModListFormDto + { + if (!$externalModList instanceof ExternalModList) { + return $externalModListFormDto; + } + + $externalModListFormDto->setId($externalModList->getId()); + $externalModListFormDto->setName($externalModList->getName()); + $externalModListFormDto->setDescription($externalModList->getDescription()); + $externalModListFormDto->setUrl($externalModList->getUrl()); + $externalModListFormDto->setActive($externalModList->isActive()); + + return $externalModListFormDto; + } +} diff --git a/src/Mods/Form/ModList/External/Dto/ExternalModListFormDto.php b/src/Mods/Form/ModList/External/Dto/ExternalModListFormDto.php new file mode 100644 index 00000000..08a31381 --- /dev/null +++ b/src/Mods/Form/ModList/External/Dto/ExternalModListFormDto.php @@ -0,0 +1,78 @@ +id; + } + + public function setId(?UuidInterface $id): void + { + $this->id = $id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(?string $name): void + { + $this->name = $name; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): void + { + $this->description = $description; + } + + public function getUrl(): ?string + { + return $this->url; + } + + public function setUrl(?string $url): void + { + $this->url = $url; + } + + public function isActive(): bool + { + return $this->active; + } + + public function setActive(bool $active): void + { + $this->active = $active; + } +} diff --git a/src/Mods/Form/ModList/External/ExternalModListFormType.php b/src/Mods/Form/ModList/External/ExternalModListFormType.php new file mode 100644 index 00000000..c0b0e87d --- /dev/null +++ b/src/Mods/Form/ModList/External/ExternalModListFormType.php @@ -0,0 +1,42 @@ +add('name', TextType::class, [ + 'label' => 'Mod list name', + ]) + ->add('description', TextType::class, [ + 'label' => 'Mod list description', + ]) + ->add('url', TextType::class, [ + 'label' => 'Mod list url', + ]) + ->add('active', CheckboxType::class, [ + 'label' => 'Mod list active', + 'required' => false, + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => ExternalModListFormDto::class, + 'required' => false, + ]); + } +} diff --git a/src/Mods/Form/ModList/Standard/DataTransformer/StandardModListFormDtoDataTransformer.php b/src/Mods/Form/ModList/Standard/DataTransformer/StandardModListFormDtoDataTransformer.php new file mode 100644 index 00000000..be08f68d --- /dev/null +++ b/src/Mods/Form/ModList/Standard/DataTransformer/StandardModListFormDtoDataTransformer.php @@ -0,0 +1,90 @@ +security->getUser(); + + $canUpdate = $currentUser->hasPermissions( + static fn (AbstractPermissions $permissions) => $permissions->standardModListUpdate + ); + + // If user has permissions set selected user as owner. Otherwise assign current user. + $owner = $canUpdate ? $standardModListFormDto->getOwner() : $currentUser; + + if (!$standardModList instanceof StandardModList) { + return new StandardModList( + $this->identifierFactory->create(), + $standardModListFormDto->getName(), + $standardModListFormDto->getDescription(), + $standardModListFormDto->getMods(), + $standardModListFormDto->getModGroups(), + $standardModListFormDto->getDlcs(), + $owner, + $standardModListFormDto->isActive(), + $standardModListFormDto->isApproved(), + ); + } + + $standardModList->update( + $standardModListFormDto->getName(), + $standardModListFormDto->getDescription(), + $standardModListFormDto->getMods(), + $standardModListFormDto->getModGroups(), + $standardModListFormDto->getDlcs(), + $owner, + $standardModListFormDto->isActive(), + $standardModListFormDto->isApproved(), + ); + + return $standardModList; + } + + public function transformFromEntity( + StandardModListFormDto $standardModListFormDto, + StandardModList $standardModList = null, + bool $copy = false + ): StandardModListFormDto { + if (!$standardModList instanceof StandardModList) { + return $standardModListFormDto; + } + + $standardModListFormDto->setId($standardModList->getId()); + $standardModListFormDto->setName($standardModList->getName()); + $standardModListFormDto->setDescription($standardModList->getDescription()); + $standardModListFormDto->setMods($standardModList->getMods()); + $standardModListFormDto->setModGroups($standardModList->getModGroups()); + $standardModListFormDto->setDlcs($standardModList->getDlcs()); + $standardModListFormDto->setOwner($standardModList->getOwner()); + $standardModListFormDto->setActive($standardModList->isActive()); + $standardModListFormDto->setApproved($standardModList->isApproved()); + + if ($copy) { + $standardModListFormDto->setId(null); // Entity will be treated as new by the unique name validator + $standardModListFormDto->setApproved(false); // Reset approval status + } + + return $standardModListFormDto; + } +} diff --git a/src/Mods/Form/ModList/Dto/ModListFormDto.php b/src/Mods/Form/ModList/Standard/Dto/StandardModListFormDto.php similarity index 98% rename from src/Mods/Form/ModList/Dto/ModListFormDto.php rename to src/Mods/Form/ModList/Standard/Dto/StandardModListFormDto.php index 597917b1..73d13dfc 100644 --- a/src/Mods/Form/ModList/Dto/ModListFormDto.php +++ b/src/Mods/Form/ModList/Standard/Dto/StandardModListFormDto.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\Form\ModList\Dto; +namespace App\Mods\Form\ModList\Standard\Dto; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; @@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints as Assert; #[UniqueModListName(errorPath: 'name')] -class ModListFormDto +class StandardModListFormDto { private ?UuidInterface $id = null; diff --git a/src/Mods/Form/ModList/ModListFormType.php b/src/Mods/Form/ModList/Standard/StandardModListFormType.php similarity index 90% rename from src/Mods/Form/ModList/ModListFormType.php rename to src/Mods/Form/ModList/Standard/StandardModListFormType.php index 0b1a6c3b..9ba247d9 100644 --- a/src/Mods/Form/ModList/ModListFormType.php +++ b/src/Mods/Form/ModList/Standard/StandardModListFormType.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace App\Mods\Form\ModList; +namespace App\Mods\Form\ModList\Standard; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Form\ModList\Dto\ModListFormDto; +use App\Mods\Form\ModList\Standard\Dto\StandardModListFormDto; use App\Users\Entity\Permissions\AbstractPermissions; use App\Users\Entity\User\User; use Doctrine\ORM\EntityRepository; @@ -19,7 +19,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -class ModListFormType extends AbstractType +class StandardModListFormType extends AbstractType { public function __construct( private Security $security @@ -94,7 +94,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'data_class' => ModListFormDto::class, + 'data_class' => StandardModListFormDto::class, 'required' => false, ]); } @@ -105,7 +105,7 @@ private function addOwnerType(FormBuilderInterface $builder): void $currentUser = $this->security->getUser(); $canUpdate = $currentUser->hasPermissions( - static fn (AbstractPermissions $permissions) => $permissions->modListUpdate + static fn (AbstractPermissions $permissions) => $permissions->standardModListUpdate ); // User cannot change Mod List owner if he doesn't have full update permissions granted @@ -113,9 +113,9 @@ private function addOwnerType(FormBuilderInterface $builder): void return; } - /** @var ModListFormDto $modListFormDto */ - $modListFormDto = $builder->getData(); - $modListExists = null !== $modListFormDto->getId(); + /** @var StandardModListFormDto $standardModListFormDto */ + $standardModListFormDto = $builder->getData(); + $standardModListExists = null !== $standardModListFormDto->getId(); $ownerTypeConfig = [ 'label' => 'Mod list owner', @@ -130,7 +130,7 @@ private function addOwnerType(FormBuilderInterface $builder): void 'choice_label' => static fn (User $user) => $user->getUsername(), ]; - if (!$modListExists) { + if (!$standardModListExists) { // Set current user as default owner when creating new Mod List $ownerTypeConfig['data'] = $currentUser; } @@ -144,7 +144,7 @@ private function addApprovedType(FormBuilderInterface $builder): void $currentUser = $this->security->getUser(); $canApprove = $currentUser->hasPermissions( - static fn (AbstractPermissions $permissions) => $permissions->modListApprove + static fn (AbstractPermissions $permissions) => $permissions->standardModListApprove ); if (!$canApprove) { diff --git a/src/Mods/Query/ModList/ActiveModListListQuery.php b/src/Mods/Query/ModList/ActiveModListListQuery.php new file mode 100644 index 00000000..e80ca5c5 --- /dev/null +++ b/src/Mods/Query/ModList/ActiveModListListQuery.php @@ -0,0 +1,38 @@ +entityManager->createQueryBuilder(); + $expr = $qb->expr(); + + $qb + ->addSelect('ml') + ->from(AbstractModList::class, 'ml') + ->leftJoin(StandardModList::class, 'sml', Join::WITH, $expr->eq('ml.id', 'sml.id')) + ->andWhere($expr->eq('ml.active', 'true')) + ->addOrderBy('CASE WHEN sml.approved = true THEN true ELSE false END', 'DESC') + ->addOrderBy('ml.name', 'ASC') + ; + + return $qb->getQuery()->getResult(); + } +} diff --git a/src/Mods/Query/ModList/ModListListQuery.php b/src/Mods/Query/ModList/ModListListQuery.php new file mode 100644 index 00000000..ea23a1a7 --- /dev/null +++ b/src/Mods/Query/ModList/ModListListQuery.php @@ -0,0 +1,37 @@ +entityManager->createQueryBuilder(); + $expr = $qb->expr(); + + $qb + ->addSelect('ml') + ->from(AbstractModList::class, 'ml') + ->leftJoin(StandardModList::class, 'sml', Join::WITH, $expr->eq('ml.id', 'sml.id')) + ->addOrderBy('CASE WHEN sml.approved = true THEN true ELSE false END', 'DESC') + ->addOrderBy('ml.name', 'ASC') + ; + + return $qb->getQuery()->getResult(); + } +} diff --git a/src/Mods/Repository/Mod/ModRepository.php b/src/Mods/Repository/Mod/ModRepository.php index 2bfddee7..49c25718 100644 --- a/src/Mods/Repository/Mod/ModRepository.php +++ b/src/Mods/Repository/Mod/ModRepository.php @@ -8,7 +8,7 @@ use App\Mods\Entity\Mod\Enum\ModTypeEnum; use App\Mods\Entity\Mod\SteamWorkshopMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; @@ -30,7 +30,7 @@ public function __construct(ManagerRegistry $registry) /** * @return AbstractMod[] */ - public function findIncludedMods(ModList $modList): array + public function findIncludedMods(StandardModList $modList): array { $qb = $this->getEntityManager()->createQueryBuilder(); @@ -47,7 +47,7 @@ public function findIncludedMods(ModList $modList): array /** * @return SteamWorkshopMod[] */ - public function findIncludedSteamWorkshopMods(ModList $modList): array + public function findIncludedSteamWorkshopMods(StandardModList $modList): array { $qb = $this->getEntityManager()->createQueryBuilder(); $expr = $qb->expr(); @@ -70,7 +70,7 @@ public function findIncludedSteamWorkshopMods(ModList $modList): array /** * @return SteamWorkshopMod[] */ - public function findIncludedOptionalSteamWorkshopMods(ModList $modList): array + public function findIncludedOptionalSteamWorkshopMods(StandardModList $modList): array { $qb = $this->getEntityManager()->createQueryBuilder(); $expr = $qb->expr(); @@ -92,7 +92,7 @@ public function findIncludedOptionalSteamWorkshopMods(ModList $modList): array /** * @return SteamWorkshopMod[] */ - public function findIncludedRequiredSteamWorkshopMods(ModList $modList): array + public function findIncludedRequiredSteamWorkshopMods(StandardModList $modList): array { $qb = $this->getEntityManager()->createQueryBuilder(); $expr = $qb->expr(); @@ -108,14 +108,14 @@ public function findIncludedRequiredSteamWorkshopMods(ModList $modList): array return $qb->getQuery()->getResult(); } - private function applyIncludedModsFilter(QueryBuilder $queryBuilder, ModList $modList): void + private function applyIncludedModsFilter(QueryBuilder $queryBuilder, StandardModList $modList): void { $expr = $queryBuilder->expr(); $queryBuilder - ->leftJoin(ModList::class, 'ml', Join::WITH, (string) $expr->isMemberOf('m', 'ml.mods')) + ->leftJoin(StandardModList::class, 'ml', Join::WITH, (string) $expr->isMemberOf('m', 'ml.mods')) ->leftJoin(ModGroup::class, 'mg', Join::WITH, (string) $expr->isMemberOf('m', 'mg.mods')) - ->leftJoin(ModList::class, 'mgml', Join::WITH, (string) $expr->isMemberOf('mg', 'mgml.modGroups')) + ->leftJoin(StandardModList::class, 'mgml', Join::WITH, (string) $expr->isMemberOf('mg', 'mgml.modGroups')) ->andWhere($expr->orX( $expr->eq('ml.id', $expr->literal($modList->getId()->toString())), $expr->eq('mgml.id', $expr->literal($modList->getId()->toString())) diff --git a/src/Mods/Repository/ModList/ExternalModListRepository.php b/src/Mods/Repository/ModList/ExternalModListRepository.php new file mode 100644 index 00000000..bf592138 --- /dev/null +++ b/src/Mods/Repository/ModList/ExternalModListRepository.php @@ -0,0 +1,23 @@ +findOneBy(['name' => $name]); } diff --git a/src/Mods/Repository/ModList/StandardModListRepository.php b/src/Mods/Repository/ModList/StandardModListRepository.php new file mode 100644 index 00000000..2f508b2e --- /dev/null +++ b/src/Mods/Repository/ModList/StandardModListRepository.php @@ -0,0 +1,28 @@ +findOneBy(['name' => $name]); + } +} diff --git a/src/Mods/Security/Voter/ModList/DownloadModListVoter.php b/src/Mods/Security/Voter/ModList/Common/DownloadModListVoter.php similarity index 80% rename from src/Mods/Security/Voter/ModList/DownloadModListVoter.php rename to src/Mods/Security/Voter/ModList/Common/DownloadModListVoter.php index 17599fec..0bee69b6 100644 --- a/src/Mods/Security/Voter/ModList/DownloadModListVoter.php +++ b/src/Mods/Security/Voter/ModList/Common/DownloadModListVoter.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Common; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\AbstractModList; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; use App\Users\Entity\User\User; @@ -15,18 +15,18 @@ class DownloadModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_DOWNLOAD->value === $attribute && $subject instanceof ModList; + return PermissionsEnum::MOD_LIST_DOWNLOAD->value === $attribute && $subject instanceof AbstractModList; } + /** + * @param AbstractModList $subject + */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { $currentUser = $token->getUser(); - /** @var ModList $modList */ - $modList = $subject; - // User always can download active Mod List - if ($modList->isActive()) { + if ($subject->isActive()) { return true; } diff --git a/src/Mods/Security/Voter/ModList/ListModListsVoter.php b/src/Mods/Security/Voter/ModList/Common/ListModListsVoter.php similarity index 94% rename from src/Mods/Security/Voter/ModList/ListModListsVoter.php rename to src/Mods/Security/Voter/ModList/Common/ListModListsVoter.php index fa8c9767..77dea992 100644 --- a/src/Mods/Security/Voter/ModList/ListModListsVoter.php +++ b/src/Mods/Security/Voter/ModList/Common/ListModListsVoter.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Common; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; diff --git a/src/Mods/Security/Voter/ModList/CreateModListVoter.php b/src/Mods/Security/Voter/ModList/External/CreateExternalModListVoter.php similarity index 73% rename from src/Mods/Security/Voter/ModList/CreateModListVoter.php rename to src/Mods/Security/Voter/ModList/External/CreateExternalModListVoter.php index 75a6c9ef..c2fb8717 100644 --- a/src/Mods/Security/Voter/ModList/CreateModListVoter.php +++ b/src/Mods/Security/Voter/ModList/External/CreateExternalModListVoter.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\External; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; @@ -10,11 +10,11 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; -class CreateModListVoter extends Voter +class CreateExternalModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_CREATE->value === $attribute; + return PermissionsEnum::EXTERNAL_MOD_LIST_CREATE->value === $attribute; } protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool @@ -24,6 +24,6 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->modListCreate); + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->externalModListCreate); } } diff --git a/src/Mods/Security/Voter/ModList/External/DeleteExternalModListVoter.php b/src/Mods/Security/Voter/ModList/External/DeleteExternalModListVoter.php new file mode 100644 index 00000000..b46a1d23 --- /dev/null +++ b/src/Mods/Security/Voter/ModList/External/DeleteExternalModListVoter.php @@ -0,0 +1,30 @@ +value === $attribute && $subject instanceof ExternalModList; + } + + protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool + { + $currentUser = $token->getUser(); + if (!$currentUser instanceof User) { + return false; + } + + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->externalModListDelete); + } +} diff --git a/src/Mods/Security/Voter/ModList/External/UpdateExternalModListVoter.php b/src/Mods/Security/Voter/ModList/External/UpdateExternalModListVoter.php new file mode 100644 index 00000000..be594296 --- /dev/null +++ b/src/Mods/Security/Voter/ModList/External/UpdateExternalModListVoter.php @@ -0,0 +1,30 @@ +value === $attribute && $subject instanceof ExternalModList; + } + + protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool + { + $currentUser = $token->getUser(); + if (!$currentUser instanceof User) { + return false; + } + + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->externalModListUpdate); + } +} diff --git a/src/Mods/Security/Voter/ModList/CopyModListVoter.php b/src/Mods/Security/Voter/ModList/Standard/ApproveStandardModListVoter.php similarity index 71% rename from src/Mods/Security/Voter/ModList/CopyModListVoter.php rename to src/Mods/Security/Voter/ModList/Standard/ApproveStandardModListVoter.php index 04c029eb..67fa6813 100644 --- a/src/Mods/Security/Voter/ModList/CopyModListVoter.php +++ b/src/Mods/Security/Voter/ModList/Standard/ApproveStandardModListVoter.php @@ -2,20 +2,19 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Standard; -use App\Mods\Entity\ModList\ModList; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; use App\Users\Entity\User\User; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; -class CopyModListVoter extends Voter +class ApproveStandardModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_COPY->value === $attribute && $subject instanceof ModList; + return PermissionsEnum::STANDARD_MOD_LIST_APPROVE->value === $attribute; } protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool @@ -25,6 +24,6 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->modListCopy); + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->standardModListApprove); } } diff --git a/src/Mods/Security/Voter/ModList/Standard/CopyStandardModListVoter.php b/src/Mods/Security/Voter/ModList/Standard/CopyStandardModListVoter.php new file mode 100644 index 00000000..94e8cd21 --- /dev/null +++ b/src/Mods/Security/Voter/ModList/Standard/CopyStandardModListVoter.php @@ -0,0 +1,30 @@ +value === $attribute && $subject instanceof StandardModList; + } + + protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool + { + $currentUser = $token->getUser(); + if (!$currentUser instanceof User) { + return false; + } + + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->standardModListCopy); + } +} diff --git a/src/Mods/Security/Voter/ModList/ApproveModListVoter.php b/src/Mods/Security/Voter/ModList/Standard/CreateStandardModListVoter.php similarity index 73% rename from src/Mods/Security/Voter/ModList/ApproveModListVoter.php rename to src/Mods/Security/Voter/ModList/Standard/CreateStandardModListVoter.php index 2bd969ea..bf79967c 100644 --- a/src/Mods/Security/Voter/ModList/ApproveModListVoter.php +++ b/src/Mods/Security/Voter/ModList/Standard/CreateStandardModListVoter.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Standard; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; @@ -10,11 +10,11 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; -class ApproveModListVoter extends Voter +class CreateStandardModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_APPROVE->value === $attribute; + return PermissionsEnum::STANDARD_MOD_LIST_CREATE->value === $attribute; } protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool @@ -24,6 +24,6 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->modListApprove); + return $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->standardModListCreate); } } diff --git a/src/Mods/Security/Voter/ModList/UpdateModListVoter.php b/src/Mods/Security/Voter/ModList/Standard/DeleteStandardModListVoter.php similarity index 61% rename from src/Mods/Security/Voter/ModList/UpdateModListVoter.php rename to src/Mods/Security/Voter/ModList/Standard/DeleteStandardModListVoter.php index 033504ce..48a529b6 100644 --- a/src/Mods/Security/Voter/ModList/UpdateModListVoter.php +++ b/src/Mods/Security/Voter/ModList/Standard/DeleteStandardModListVoter.php @@ -2,22 +2,25 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Standard; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; use App\Users\Entity\User\User; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; -class UpdateModListVoter extends Voter +class DeleteStandardModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_UPDATE->value === $attribute && $subject instanceof ModList; + return PermissionsEnum::STANDARD_MOD_LIST_DELETE->value === $attribute && $subject instanceof StandardModList; } + /** + * @param StandardModList $subject + */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { $currentUser = $token->getUser(); @@ -25,10 +28,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - /** @var ModList $modList */ - $modList = $subject; - - return $modList->getOwner() === $currentUser - || $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->modListUpdate); + return $subject->getOwner() === $currentUser + || $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->standardModListDelete); } } diff --git a/src/Mods/Security/Voter/ModList/DeleteModListVoter.php b/src/Mods/Security/Voter/ModList/Standard/UpdateStandardModListVoter.php similarity index 61% rename from src/Mods/Security/Voter/ModList/DeleteModListVoter.php rename to src/Mods/Security/Voter/ModList/Standard/UpdateStandardModListVoter.php index bedca518..26e7477b 100644 --- a/src/Mods/Security/Voter/ModList/DeleteModListVoter.php +++ b/src/Mods/Security/Voter/ModList/Standard/UpdateStandardModListVoter.php @@ -2,22 +2,25 @@ declare(strict_types=1); -namespace App\Mods\Security\Voter\ModList; +namespace App\Mods\Security\Voter\ModList\Standard; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Security\Enum\PermissionsEnum; use App\Users\Entity\Permissions\AbstractPermissions; use App\Users\Entity\User\User; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; -class DeleteModListVoter extends Voter +class UpdateStandardModListVoter extends Voter { protected function supports(string $attribute, $subject): bool { - return PermissionsEnum::MOD_LIST_DELETE->value === $attribute && $subject instanceof ModList; + return PermissionsEnum::STANDARD_MOD_LIST_UPDATE->value === $attribute && $subject instanceof StandardModList; } + /** + * @param StandardModList $subject + */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { $currentUser = $token->getUser(); @@ -25,10 +28,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - /** @var ModList $modList */ - $modList = $subject; - - return $modList->getOwner() === $currentUser - || $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->modListDelete); + return $subject->getOwner() === $currentUser + || $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->standardModListUpdate); } } diff --git a/src/Mods/Service/ModListUpdateService/ModListUpdateService.php b/src/Mods/Service/ModListUpdateService/ModListUpdateService.php index b8c93103..ecc5b2b7 100644 --- a/src/Mods/Service/ModListUpdateService/ModListUpdateService.php +++ b/src/Mods/Service/ModListUpdateService/ModListUpdateService.php @@ -5,7 +5,7 @@ namespace App\Mods\Service\ModListUpdateService; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Users\Entity\User\User; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\SecurityBundle\Security; @@ -29,7 +29,7 @@ public function updateModListsAssociatedWithModGroup(ModGroup $modGroup): void $expr = $queryBuilder->expr(); $queryBuilder - ->update(ModList::class, 'ml') + ->update(StandardModList::class, 'ml') ->set('ml.lastUpdatedAt', ':dateTime') ->setParameter('dateTime', new \DateTimeImmutable()) diff --git a/src/Mods/Validator/ModList/UniqueModListNameValidator.php b/src/Mods/Validator/ModList/UniqueModListNameValidator.php index 51b3845f..e8590ccd 100644 --- a/src/Mods/Validator/ModList/UniqueModListNameValidator.php +++ b/src/Mods/Validator/ModList/UniqueModListNameValidator.php @@ -4,8 +4,9 @@ namespace App\Mods\Validator\ModList; -use App\Mods\Entity\ModList\ModList; -use App\Mods\Form\ModList\Dto\ModListFormDto; +use App\Mods\Entity\ModList\AbstractModList; +use App\Mods\Form\ModList\External\Dto\ExternalModListFormDto; +use App\Mods\Form\ModList\Standard\Dto\StandardModListFormDto; use App\Shared\Validator\Common\AbstractValidator; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -14,8 +15,8 @@ class UniqueModListNameValidator extends AbstractValidator { public function validate(mixed $value, Constraint $constraint): void { - if (!$value instanceof ModListFormDto) { - throw new UnexpectedTypeException($constraint, ModListFormDto::class); + if (!$value instanceof StandardModListFormDto && !$value instanceof ExternalModListFormDto) { + throw new UnexpectedTypeException($constraint, sprintf('%s|%s', StandardModListFormDto::class, ExternalModListFormDto::class)); } if (!$constraint instanceof UniqueModListName) { @@ -28,7 +29,7 @@ public function validate(mixed $value, Constraint $constraint): void } $id = $value->getId(); - if ($this->isColumnValueUnique(ModList::class, ['name' => $name], $id)) { + if ($this->isColumnValueUnique(AbstractModList::class, ['name' => $name], $id)) { return; } diff --git a/src/Shared/Security/Enum/PermissionsEnum.php b/src/Shared/Security/Enum/PermissionsEnum.php index cfe01203..3f7111e8 100644 --- a/src/Shared/Security/Enum/PermissionsEnum.php +++ b/src/Shared/Security/Enum/PermissionsEnum.php @@ -32,9 +32,14 @@ enum PermissionsEnum: string case MOD_LIST_LIST = 'mod_list_list'; case MOD_LIST_DOWNLOAD = 'mod_list_download'; - case MOD_LIST_CREATE = 'mod_list_create'; - case MOD_LIST_UPDATE = 'mod_list_update'; - case MOD_LIST_COPY = 'mod_list_copy'; - case MOD_LIST_DELETE = 'mod_list_delete'; - case MOD_LIST_APPROVE = 'mod_list_approve'; + + case STANDARD_MOD_LIST_CREATE = 'standard_mod_list_create'; + case STANDARD_MOD_LIST_UPDATE = 'standard_mod_list_update'; + case STANDARD_MOD_LIST_COPY = 'standard_mod_list_copy'; + case STANDARD_MOD_LIST_DELETE = 'standard_mod_list_delete'; + case STANDARD_MOD_LIST_APPROVE = 'standard_mod_list_approve'; + + case EXTERNAL_MOD_LIST_CREATE = 'external_mod_list_create'; + case EXTERNAL_MOD_LIST_UPDATE = 'external_mod_list_update'; + case EXTERNAL_MOD_LIST_DELETE = 'external_mod_list_delete'; } diff --git a/src/Shared/Service/IdentifierFactory/IdentifierFactoryStub.php b/src/Shared/Service/IdentifierFactory/IdentifierFactoryStub.php index 4efdc561..d9ca309a 100644 --- a/src/Shared/Service/IdentifierFactory/IdentifierFactoryStub.php +++ b/src/Shared/Service/IdentifierFactory/IdentifierFactoryStub.php @@ -9,7 +9,7 @@ class IdentifierFactoryStub implements IdentifierFactoryInterface { /** - * @param UuidInterface[] $identifiers + * @var UuidInterface[] */ private array $identifiers = []; diff --git a/src/Users/Entity/Permissions/AbstractPermissions.php b/src/Users/Entity/Permissions/AbstractPermissions.php index a748fd65..fe1d6f94 100644 --- a/src/Users/Entity/Permissions/AbstractPermissions.php +++ b/src/Users/Entity/Permissions/AbstractPermissions.php @@ -40,11 +40,16 @@ abstract class AbstractPermissions extends AbstractBlamableEntity // Mod List public bool $modListList = false; - public bool $modListCreate = false; - public bool $modListUpdate = false; - public bool $modListDelete = false; - public bool $modListCopy = false; - public bool $modListApprove = false; + + public bool $standardModListCreate = false; + public bool $standardModListUpdate = false; + public bool $standardModListDelete = false; + public bool $standardModListCopy = false; + public bool $standardModListApprove = false; + + public bool $externalModListCreate = false; + public bool $externalModListUpdate = false; + public bool $externalModListDelete = false; public function grantAll(): void { @@ -80,10 +85,15 @@ public function grantAll(): void // Mod List $this->modListList = true; - $this->modListCreate = true; - $this->modListUpdate = true; - $this->modListDelete = true; - $this->modListCopy = true; - $this->modListApprove = true; + + $this->standardModListCreate = true; + $this->standardModListUpdate = true; + $this->standardModListDelete = true; + $this->standardModListCopy = true; + $this->standardModListApprove = true; + + $this->externalModListCreate = true; + $this->externalModListUpdate = true; + $this->externalModListDelete = true; } } diff --git a/src/Users/Form/Permissions/PermissionsType.php b/src/Users/Form/Permissions/PermissionsType.php index f9e30002..cd660c32 100644 --- a/src/Users/Form/Permissions/PermissionsType.php +++ b/src/Users/Form/Permissions/PermissionsType.php @@ -125,28 +125,42 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'label' => 'Can list mod lists', 'label_attr' => ['class' => 'switch-custom'], ]) - ->add('modListCreate', CheckboxType::class, [ + + ->add('standardModListCreate', CheckboxType::class, [ 'label' => 'Can create mod lists', 'label_attr' => ['class' => 'switch-custom'], ]) - ->add('modListUpdate', CheckboxType::class, [ + ->add('standardModListUpdate', CheckboxType::class, [ 'label' => 'Can edit other users mod lists', 'label_attr' => ['class' => 'switch-custom'], 'help' => 'Note: User can always edit his own or assigned to him mod lists', ]) - ->add('modListCopy', CheckboxType::class, [ + ->add('standardModListCopy', CheckboxType::class, [ 'label' => 'Can copy mod lists', 'label_attr' => ['class' => 'switch-custom'], ]) - ->add('modListDelete', CheckboxType::class, [ + ->add('standardModListDelete', CheckboxType::class, [ 'label' => 'Can delete other users mod lists', 'label_attr' => ['class' => 'switch-custom'], 'help' => 'Note: User can always delete his own or assigned to him mod lists', ]) - ->add('modListApprove', CheckboxType::class, [ + ->add('standardModListApprove', CheckboxType::class, [ 'label' => 'Can approve mod lists', 'label_attr' => ['class' => 'switch-custom'], ]) + + ->add('externalModListCreate', CheckboxType::class, [ + 'label' => 'Can create external mod lists', + 'label_attr' => ['class' => 'switch-custom'], + ]) + ->add('externalModListUpdate', CheckboxType::class, [ + 'label' => 'Can edit external mod lists', + 'label_attr' => ['class' => 'switch-custom'], + ]) + ->add('externalModListDelete', CheckboxType::class, [ + 'label' => 'Can delete external mod lists', + 'label_attr' => ['class' => 'switch-custom'], + ]) ; } diff --git a/src/Users/Security/Voter/User/DeleteUserVoter.php b/src/Users/Security/Voter/User/DeleteUserVoter.php index dd02f497..3778106b 100644 --- a/src/Users/Security/Voter/User/DeleteUserVoter.php +++ b/src/Users/Security/Voter/User/DeleteUserVoter.php @@ -17,6 +17,9 @@ protected function supports(string $attribute, $subject): bool return PermissionsEnum::USER_DELETE->value === $attribute && $subject instanceof User; } + /** + * @param User $subject + */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { $currentUser = $token->getUser(); @@ -24,10 +27,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ return false; } - /** @var User $user */ - $user = $subject; - - return $currentUser !== $user + return $currentUser !== $subject && $currentUser->hasPermissions(static fn (AbstractPermissions $permissions) => $permissions->userDelete); } } diff --git a/src/Users/Validator/User/UniqueUserSteamIdValidator.php b/src/Users/Validator/User/UniqueUserSteamIdValidator.php index 2befc5ed..b0f6805a 100644 --- a/src/Users/Validator/User/UniqueUserSteamIdValidator.php +++ b/src/Users/Validator/User/UniqueUserSteamIdValidator.php @@ -4,7 +4,7 @@ namespace App\Users\Validator\User; -use App\Mods\Form\ModList\Dto\ModListFormDto; +use App\Mods\Form\ModList\Standard\Dto\StandardModListFormDto; use App\Shared\Validator\Common\AbstractValidator; use App\Users\Entity\User\User; use App\Users\Form\User\Dto\UserFormDto; @@ -16,7 +16,7 @@ class UniqueUserSteamIdValidator extends AbstractValidator public function validate(mixed $value, Constraint $constraint): void { if (!$value instanceof UserFormDto) { - throw new UnexpectedTypeException($constraint, ModListFormDto::class); + throw new UnexpectedTypeException($constraint, StandardModListFormDto::class); } if (!$constraint instanceof UniqueUserSteamId) { diff --git a/templates/mods/mod_list/list.html.twig b/templates/mods/mod_list/list.html.twig index 3d04b378..9e129831 100644 --- a/templates/mods/mod_list/list.html.twig +++ b/templates/mods/mod_list/list.html.twig @@ -6,8 +6,25 @@ {{ 'Mod lists'|trans }} {% endblock %} {% block page_actions %} - {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::MOD_LIST_CREATE').value) %} - {{ 'Create mod list'|trans }} + {% if + is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::STANDARD_MOD_LIST_CREATE').value) + and is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::EXTERNAL_MOD_LIST_CREATE').value) + %} + + {% else %} + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::STANDARD_MOD_LIST_CREATE').value) %} + {{ 'Create mod list'|trans }} + {% endif %} + + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::EXTERNAL_MOD_LIST_CREATE').value) %} + {{ 'Create external mod list'|trans }} + {% endif %} {% endif %} {% endblock %} {% endembed %} @@ -29,24 +46,37 @@ {% endblock %} {% block table_body %} - {# @var modList \App\Mods\Entity\ModList\ModList #} + {# @var modList \App\Mods\Entity\ModList\AbstractModList #} {% for modList in modLists %} {{ loop.index }} - {% if modList.approved %} - {{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {# @var modList \App\Mods\Entity\ModList\StandardModList #} + {% if modList.approved %} + {{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} + {% endif %} + {% elseif modList is instance_of('\\App\\Mods\\Entity\\ModList\\ExternalModList') %} + {{ tableMacro.icon('fa fa-external-link-alt', 'Mod list external'|trans) }} {% endif %} {{ tableMacro.row_name_with_description(modList.name, modList.description) }} - {# @var dlc \App\Mods\Entity\Dlc\Dlc #} - {% for dlc in modList.dlcs %} - {{ commonMacro.dlc_icon(dlc) }} - {% endfor %} + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {# @var modList \App\Mods\Entity\ModList\StandardModList #} + {# @var dlc \App\Mods\Entity\Dlc\Dlc #} + {% for dlc in modList.dlcs %} + {{ commonMacro.dlc_icon(dlc) }} + {% endfor %} + {% endif %} + + + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {# @var modList \App\Mods\Entity\ModList\StandardModList #} + {{ modList.owner ? modList.owner.username : '' }} + {% endif %} - {{ modList.owner ? modList.owner.username : '' }} {{ modList.active ? 'Yes'|trans : 'No'|trans }} @@ -55,16 +85,26 @@ {{ tableMacro.row_action(path('app_mod_list_public_customize', { name: modList.name }), 'fas fa-download', 'Download mod list'|trans) }} - {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::MOD_LIST_UPDATE').value, modList) %} - {{ tableMacro.row_action_edit(path('app_mod_list_update', { name: modList.name }), 'Edit mod list'|trans) }} - {% endif %} + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::STANDARD_MOD_LIST_UPDATE').value, modList) %} + {{ tableMacro.row_action_edit(path('app_standard_mod_list_update', { name: modList.name }), 'Edit mod list'|trans) }} + {% endif %} - {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::MOD_LIST_COPY').value, modList) %} - {{ tableMacro.row_action(path('app_mod_list_copy', { name: modList.name }), 'fas fa-copy', 'Copy and edit mod list'|trans) }} - {% endif %} + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::STANDARD_MOD_LIST_COPY').value, modList) %} + {{ tableMacro.row_action(path('app_standard_mod_list_copy', { name: modList.name }), 'fas fa-copy', 'Copy and edit mod list'|trans) }} + {% endif %} + + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::STANDARD_MOD_LIST_DELETE').value, modList) %} + {{ tableMacro.row_action_delete(path('app_standard_mod_list_delete', { name: modList.name }), 'Are you sure you want to delete %name%?'|trans({ '%name%': modList.name }), 'Delete mod list'|trans) }} + {% endif %} + {% elseif modList is instance_of('\\App\\Mods\\Entity\\ModList\\ExternalModList') %} + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::EXTERNAL_MOD_LIST_UPDATE').value, modList) %} + {{ tableMacro.row_action_edit(path('app_external_mod_list_update', { name: modList.name }), 'Edit mod list'|trans) }} + {% endif %} - {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::MOD_LIST_DELETE').value, modList) %} - {{ tableMacro.row_action_delete(path('app_mod_list_delete', { name: modList.name }), 'Are you sure you want to delete %name%?'|trans({ '%name%': modList.name }), 'Delete mod list'|trans) }} + {% if is_granted(constant('App\\Shared\\Security\\Enum\\PermissionsEnum::EXTERNAL_MOD_LIST_DELETE').value, modList) %} + {{ tableMacro.row_action_delete(path('app_external_mod_list_delete', { name: modList.name }), 'Are you sure you want to delete %name%?'|trans({ '%name%': modList.name }), 'Delete mod list'|trans) }} + {% endif %} {% endif %} diff --git a/templates/mods/mod_list/remote_form.html.twig b/templates/mods/mod_list/remote_form.html.twig new file mode 100644 index 00000000..4cb15a4d --- /dev/null +++ b/templates/mods/mod_list/remote_form.html.twig @@ -0,0 +1,26 @@ +{% extends 'shared/card.html.twig' %} + +{% form_theme form _self %} + +{% block content %} + {# @var modListFormDto \App\Mods\Form\ModList\Dto\ModListFormDto #} + {% set modListFormDto = form.vars.data %} + + {% embed 'shared/_partial/_page_header.html.twig' %} + {% block page_title %} + {{ modListFormDto.id ? 'Edit external mod list'|trans : 'Create external mod list'|trans }} + {% endblock %} + {% endembed %} + + {{ form_start(form) }} + {{ form_row(form.name) }} + {{ form_row(form.description) }} + {{ form_row(form.url) }} + {{ form_row(form.active) }} + +
+ + {{ 'Cancel'|trans }} +
+ {{ form_end(form) }} +{% endblock %} diff --git a/templates/mods/mod_list/form.html.twig b/templates/mods/mod_list/standard_form.html.twig similarity index 93% rename from templates/mods/mod_list/form.html.twig rename to templates/mods/mod_list/standard_form.html.twig index 15ff9a75..476b4c63 100644 --- a/templates/mods/mod_list/form.html.twig +++ b/templates/mods/mod_list/standard_form.html.twig @@ -47,14 +47,14 @@ {{ form_end(form) }} {% endblock %} -{% block _mod_list_form_modGroups_row %} +{% block _standard_mod_list_form_modGroups_row %} {% include 'mods/_partial/mod_group_tabs/_mod_group_tabs_content.html.twig' with { active: 'mod-groups' } %} {% endblock %} -{% block _mod_list_form_dlcs_row %} +{% block _standard_mod_list_form_dlcs_row %} {% include 'mods/_partial/dlc_tabs/_dlc_tabs_content.html.twig' %} {% endblock %} -{% block _mod_list_form_mods_row %} +{% block _standard_mod_list_form_mods_row %} {% include 'mods/_partial/mod_tabs/_mod_tabs_content.html.twig' %} {% endblock %} diff --git a/templates/mods/mod_list_public/select.html.twig b/templates/mods/mod_list_public/select.html.twig index bb1a4554..0aa05ee4 100644 --- a/templates/mods/mod_list_public/select.html.twig +++ b/templates/mods/mod_list_public/select.html.twig @@ -46,22 +46,29 @@ {% endblock %} {% block table_body %} - {# @var modList \App\Mods\Entity\ModList\ModList #} + {# @var modList \App\Mods\Entity\ModList\StandardModList #} {% for modList in modLists %} {{ loop.index }} - {% if modList.approved %} - {{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {% if modList.approved %} + {{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} + {% endif %} + {% elseif modList is instance_of('\\App\\Mods\\Entity\\ModList\\ExternalModList') %} + {{ tableMacro.icon('fa fa-external-link-alt', 'Mod list external'|trans) }} {% endif %} {{ modList.name }} - {# @var dlc \App\Mods\Entity\Dlc\Dlc #} - {% for dlc in modList.dlcs %} - {{ commonMacro.dlc_icon(dlc) }} - {% endfor %} + {% if modList is instance_of('\\App\\Mods\\Entity\\ModList\\StandardModList') %} + {# @var modList \App\Mods\Entity\ModList\StandardModList #} + {# @var dlc \App\Mods\Entity\Dlc\Dlc #} + {% for dlc in modList.dlcs %} + {{ commonMacro.dlc_icon(dlc) }} + {% endfor %} + {% endif %} {{ tableMacro.format_date(modList.lastUpdatedAt) }} diff --git a/templates/users/_partial/permissions/form.html.twig b/templates/users/_partial/permissions/form.html.twig index aee39170..94be1522 100644 --- a/templates/users/_partial/permissions/form.html.twig +++ b/templates/users/_partial/permissions/form.html.twig @@ -50,10 +50,18 @@ {{ 'Mod lists'|trans }} {{ form_row(form.modListList) }} - {{ form_row(form.modListCreate) }} - {{ form_row(form.modListUpdate) }} - {{ form_row(form.modListCopy) }} - {{ form_row(form.modListDelete) }} - {{ form_row(form.modListApprove) }} + {{ form_row(form.standardModListCreate) }} + {{ form_row(form.standardModListUpdate) }} + {{ form_row(form.standardModListCopy) }} + {{ form_row(form.standardModListDelete) }} + {{ form_row(form.standardModListApprove) }} + + +
+ {{ 'External mod lists'|trans }} + + {{ form_row(form.externalModListCreate) }} + {{ form_row(form.externalModListUpdate) }} + {{ form_row(form.externalModListDelete) }}
diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index c0d9d9b8..b68e7688 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -5,6 +5,7 @@ namespace App\Tests; use App\Shared\Test\Traits\TimeTrait; +use App\Tests\Traits\CommonAssertsTrait; use App\Tests\Traits\CommonPageAssertsTrait; use App\Tests\Traits\DataTableAssertsTrait; use App\Tests\Traits\ResponseAssertTrait; @@ -30,6 +31,7 @@ class FunctionalTester extends Actor { use _generated\FunctionalTesterActions; + use CommonAssertsTrait; use CommonPageAssertsTrait; use DataTableAssertsTrait; use ResponseAssertTrait; diff --git a/tests/_support/Traits/CommonAssertsTrait.php b/tests/_support/Traits/CommonAssertsTrait.php new file mode 100644 index 00000000..cbaf75b2 --- /dev/null +++ b/tests/_support/Traits/CommonAssertsTrait.php @@ -0,0 +1,13 @@ +assertSame(sort($expected), sort($actual)); + } +} diff --git a/tests/functional/Mods/Api/ModList/GetModListsByIdCest.php b/tests/functional/Mods/Api/ModList/GetModListsByIdCest.php index b4102971..9140e3dd 100644 --- a/tests/functional/Mods/Api/ModList/GetModListsByIdCest.php +++ b/tests/functional/Mods/Api/ModList/GetModListsByIdCest.php @@ -4,7 +4,7 @@ namespace App\Tests\Functional\Mods\Api\ModList; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; use App\Tests\FunctionalTester; use Codeception\Util\HttpCode; @@ -18,7 +18,7 @@ public function _before(FunctionalTester $I): void public function getModListByIdWithoutApiKey(FunctionalTester $I): void { - $I->sendGet(sprintf('/api/mod-lists/%s', DefaultModListFixture::ID)); + $I->sendGet(sprintf('/api/mod-lists/%s', DefaultStandardModListFixture::ID)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); @@ -28,7 +28,7 @@ public function getModListByIdUsingInvalidApiKey(FunctionalTester $I): void { $I->amApiKeyAuthenticatedAs('invalid_key'); - $I->sendGet(sprintf('/api/mod-lists/%s', DefaultModListFixture::ID)); + $I->sendGet(sprintf('/api/mod-lists/%s', DefaultStandardModListFixture::ID)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); @@ -38,7 +38,7 @@ public function getModListByIdUsingValidApiKey(FunctionalTester $I): void { $I->amApiKeyAuthenticatedAs('test_key'); - $I->sendGet(sprintf('/api/mod-lists/%s', DefaultModListFixture::ID)); + $I->sendGet(sprintf('/api/mod-lists/%s', DefaultStandardModListFixture::ID)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); diff --git a/tests/functional/Mods/Api/ModList/GetModListsByNameCest.php b/tests/functional/Mods/Api/ModList/GetModListsByNameCest.php index 9d64c5fd..e693c130 100644 --- a/tests/functional/Mods/Api/ModList/GetModListsByNameCest.php +++ b/tests/functional/Mods/Api/ModList/GetModListsByNameCest.php @@ -4,7 +4,7 @@ namespace App\Tests\Functional\Mods\Api\ModList; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; use App\Tests\FunctionalTester; use Codeception\Util\HttpCode; @@ -18,7 +18,7 @@ public function _before(FunctionalTester $I): void public function getModListByNameWithoutApiKey(FunctionalTester $I): void { - $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultModListFixture::NAME)); + $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); @@ -28,7 +28,7 @@ public function getModListByNameUsingInvalidApiKey(FunctionalTester $I): void { $I->amApiKeyAuthenticatedAs('invalid_key'); - $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultModListFixture::NAME)); + $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); @@ -38,7 +38,7 @@ public function getModListByNameUsingValidApiKey(FunctionalTester $I): void { $I->amApiKeyAuthenticatedAs('test_key'); - $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultModListFixture::NAME)); + $I->sendGet(sprintf('/api/mod-lists/by-name/%s', DefaultStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); $I->seeResponseContainsJson($this->getExpectedPayload()); diff --git a/tests/functional/Mods/Web/ModList/Common/ListModListsCest.php b/tests/functional/Mods/Web/ModList/Common/ListModListsCest.php new file mode 100644 index 00000000..5588b273 --- /dev/null +++ b/tests/functional/Mods/Web/ModList/Common/ListModListsCest.php @@ -0,0 +1,321 @@ +stopFollowingRedirects(); + } + + public function listModListsAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage('/mod-list/list'); + $I->seeResponseRedirectsToLogInAction(); + } + + public function listModListsAsUnauthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + } + + public function listModListsAsAuthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithPermissionsToCreateBothTypesOfModList(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->standardModListCreate = true; + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeLink('Create mod list'); + $I->seeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithCreateStandardModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->standardModListCreate = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithUpdateStandardModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->standardModListUpdate = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->seeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', CupStandardModListFixture::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', LocalhostExternalModList::NAME)); + $I->seeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithStandardModListOwnership(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(CupStandardModListFixture::OWNER_ID, function (User $user): void { + $user->getPermissions()->modListList = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->seeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', CupStandardModListFixture::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', LocalhostExternalModList::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', DefaultStandardModListFixture::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Copy and edit mod list'); + + $I->seeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', CupStandardModListFixture::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', LocalhostExternalModList::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', RhsStandardModListFixture::NAME)); + } + + public function listModListsAsAuthorizedUserWithCopyStandardModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->standardModListCopy = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + + $I->seeActionButton('Copy and edit mod list', sprintf('/standard-mod-list/%s/copy', CupStandardModListFixture::NAME)); + $I->seeActionButton('Copy and edit mod list', sprintf('/standard-mod-list/%s/copy', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Copy and edit mod list', sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithDeleteStandardModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->standardModListDelete = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + + $I->seeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', CupStandardModListFixture::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', LocalhostExternalModList::NAME)); + $I->seeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', RhsStandardModListFixture::NAME)); + } + + public function listModListsAsAuthorizedUserWithCreateExternalModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->seeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithUpdateExternalModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', CupStandardModListFixture::NAME)); + $I->seeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + $I->seeActionButton('Edit mod list', sprintf('/external-mod-list/%s/update', LocalhostExternalModList::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', DefaultStandardModListFixture::NAME)); + $I->dontSeeActionButton('Edit mod list', sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Copy and edit mod list'); + $I->dontSeeActionButton('Delete mod list'); + } + + public function listModListsAsAuthorizedUserWithDeleteExternalModListPermission(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { + $user->getPermissions()->modListList = true; + $user->getPermissions()->externalModListDelete = true; + }); + + $I->amOnPage('/mod-list/list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->dontSeeLink('Create mod list'); + $I->dontSeeLink('Create external mod list'); + + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', CupStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', LocalhostExternalModList::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); + $I->seeActionButton('Download mod list', sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); + + $I->dontSeeActionButton('Edit mod list'); + $I->dontSeeActionButton('Copy and edit mod list'); + + $I->dontSeeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', CupStandardModListFixture::NAME)); + $I->seeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + $I->seeActionButton('Delete mod list', sprintf('/external-mod-list/%s/delete', LocalhostExternalModList::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + $I->dontSeeActionButton('Delete mod list', sprintf('/standard-mod-list/%s/delete', RhsStandardModListFixture::NAME)); + } +} diff --git a/tests/functional/Mods/Web/ModList/DeleteModListCest.php b/tests/functional/Mods/Web/ModList/DeleteModListCest.php deleted file mode 100644 index b8dbd8e3..00000000 --- a/tests/functional/Mods/Web/ModList/DeleteModListCest.php +++ /dev/null @@ -1,78 +0,0 @@ -stopFollowingRedirects(); - } - - public function deleteModListAsUnauthenticatedUser(FunctionalTester $I): void - { - $I->amOnPage(sprintf('/mod-list/%s/delete', DefaultModListFixture::NAME)); - - $I->seeResponseRedirectsToLogInAction(); - - $I->seeInRepository(ModList::class, ['name' => DefaultModListFixture::NAME]); - } - - public function deleteModListAsUnauthorizedUser(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User1Fixture::ID); - - $I->amOnPage(sprintf('/mod-list/%s/delete', DefaultModListFixture::NAME)); - - $I->seeResponseCodeIs(HttpCode::FORBIDDEN); - - $I->seeInRepository(ModList::class, ['name' => DefaultModListFixture::NAME]); - } - - public function deleteModListAsAuthorizedUser(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListDelete = true; - }); - - $I->amOnPage(sprintf('/mod-list/%s/delete', DefaultModListFixture::NAME)); - - $I->seeResponseRedirectsTo('/mod-list/list'); - - $I->dontSeeInRepository(ModList::class, ['name' => DefaultModListFixture::NAME]); - } - - public function deleteModListAsModListOwner(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(CupModListFixture::OWNER_ID, function (User $user): void { - $user->getPermissions()->modListDelete = false; - }); - - $I->amOnPage(sprintf('/mod-list/%s/delete', CupModListFixture::NAME)); - - $I->seeResponseRedirectsTo('/mod-list/list'); - - $I->dontSeeInRepository(ModList::class, ['name' => CupModListFixture::NAME]); - } - - public function deleteModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListDelete = true; - }); - - $I->amOnPage(sprintf('/mod-list/%s/delete', 'non existing')); - - $I->seeResponseCodeIs(HttpCode::NOT_FOUND); - } -} diff --git a/tests/functional/Mods/Web/ModList/External/CreateExternalModListCest.php b/tests/functional/Mods/Web/ModList/External/CreateExternalModListCest.php new file mode 100644 index 00000000..1d73c757 --- /dev/null +++ b/tests/functional/Mods/Web/ModList/External/CreateExternalModListCest.php @@ -0,0 +1,161 @@ +stopFollowingRedirects(); + $I->freezeTime('2020-01-01T00:00:00+00:00'); + + /** @var IdentifierFactoryStub $identifierFactory */ + $identifierFactory = $I->grabService(IdentifierFactoryStub::class); + $identifierFactory->setIdentifiers([ + Uuid::fromString('805c9fcd-d674-4a27-8f0c-78dbf2484bb2'), + ]); + } + + public function createExternalModListAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseRedirectsToLogInAction(); + } + + public function createExternalModListAsUnauthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + } + + public function createExternalModListAsAuthorizedUser(FunctionalTester $I): void + { + $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::OK); + + // Default form values + $I->seeInField('Mod list name', ''); + $I->seeInField('Mod list description', ''); + $I->seeInField('Mod list url', ''); + $I->seeCheckboxIsChecked('Mod list active'); + + // Fill form + $I->fillField('Mod list name', 'External'); + $I->fillField('Mod list description', 'External modlist'); + $I->fillField('Mod list url', 'https://external.local'); + $I->uncheckOption('Mod list active'); + $I->click('Create mod list'); + + $I->seeResponseRedirectsTo('/mod-list/list'); + + /** @var ExternalModList $modList */ + $modList = $I->grabEntityFromRepository(ExternalModList::class, ['name' => 'External']); + $I->assertSame('805c9fcd-d674-4a27-8f0c-78dbf2484bb2', $modList->getId()->toString()); + $I->assertSame('External', $modList->getName()); + $I->assertSame('External modlist', $modList->getDescription()); + $I->assertSame('https://external.local', $modList->getUrl()); + $I->assertSame(false, $modList->isActive()); + + $I->assertSame('2020-01-01T00:00:00+00:00', $modList->getCreatedAt()->format(DATE_ATOM)); + $I->assertSame($currentUser->getId()->toString(), $modList->getCreatedBy()?->getId()->toString()); + $I->assertSame(null, $modList->getLastUpdatedAt()); + $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); + } + + public function createExternalModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', GoogleExternalModList::NAME); + $I->click('Create mod list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'Mod list with the same name "Google" already exist.'); + } + + public function createExternalModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', ''); + $I->fillField('Mod list url', ''); + $I->click('Create mod list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'This value should not be blank.'); + $I->seeFormErrorMessage('url', 'This value should not be blank.'); + } + + public function createExternalModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', str_repeat('a', 256)); + $I->fillField('Mod list description', str_repeat('a', 256)); + $I->click('Create mod list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'This value is too long. It should have 255 characters or less.'); + $I->seeFormErrorMessage('description', 'This value is too long. It should have 255 characters or less.'); + } + + public function createExternalModListAsAuthorizedUserWithDataInvalid(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListCreate = true; + }); + + $I->amOnPage('/external-mod-list/create'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', 'External'); + $I->fillField('Mod list url', 'invalid'); + $I->click('Create mod list'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('url', 'This value is not a valid URL.'); + } +} diff --git a/tests/functional/Mods/Web/ModList/External/DeleteExternalModListCest.php b/tests/functional/Mods/Web/ModList/External/DeleteExternalModListCest.php new file mode 100644 index 00000000..78c07fe1 --- /dev/null +++ b/tests/functional/Mods/Web/ModList/External/DeleteExternalModListCest.php @@ -0,0 +1,64 @@ +stopFollowingRedirects(); + } + + public function deleteExternalModListAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage(sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + + $I->seeResponseRedirectsToLogInAction(); + + $I->seeInRepository(ExternalModList::class, ['name' => GoogleExternalModList::NAME]); + } + + public function deleteExternalModListAsUnauthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage(sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + + $I->seeInRepository(ExternalModList::class, ['name' => GoogleExternalModList::NAME]); + } + + public function deleteExternalModListAsAuthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListDelete = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/delete', GoogleExternalModList::NAME)); + + $I->seeResponseRedirectsTo('/mod-list/list'); + + $I->dontSeeInRepository(ExternalModList::class, ['name' => GoogleExternalModList::NAME]); + } + + public function deleteExternalModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListDelete = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/delete', 'non existing')); + + $I->seeResponseCodeIs(HttpCode::NOT_FOUND); + } +} diff --git a/tests/functional/Mods/Web/ModList/External/UpdateExternalModListCest.php b/tests/functional/Mods/Web/ModList/External/UpdateExternalModListCest.php new file mode 100644 index 00000000..72198f34 --- /dev/null +++ b/tests/functional/Mods/Web/ModList/External/UpdateExternalModListCest.php @@ -0,0 +1,162 @@ +stopFollowingRedirects(); + $I->freezeTime('2021-01-01T00:00:00+00:00'); + } + + public function updateExternalModListAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseRedirectsToLogInAction(); + } + + public function updateExternalModListAsUnauthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + } + + public function updateExternalModListAsAuthorizedUser(FunctionalTester $I): void + { + $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::OK); + + // Default form values + $I->seeInField('Mod list name', 'Google'); + $I->seeInField('Mod list description', ''); + $I->dontSeeCheckboxIsChecked('Mod list active'); + + // Fill form + $I->fillField('Mod list name', 'External'); + $I->fillField('Mod list description', 'External modlist'); + $I->fillField('Mod list url', 'https://external.local'); + $I->checkOption('Mod list active'); + $I->click('Apply'); + + $I->seeResponseRedirectsTo('/mod-list/list'); + + /** @var ExternalModList $modList */ + $modList = $I->grabEntityFromRepository(ExternalModList::class, ['name' => 'External']); + $I->assertSame('296cc791-c73f-4978-b377-da1d3aa28cfb', $modList->getId()->toString()); + $I->assertSame('External', $modList->getName()); + $I->assertSame('External modlist', $modList->getDescription()); + $I->assertSame('https://external.local', $modList->getUrl()); + $I->assertSame(true, $modList->isActive()); + + $I->assertSame('2020-01-01T00:00:00+00:00', $modList->getCreatedAt()->format(DATE_ATOM)); + $I->assertSame(GoogleExternalModList::CREATED_BY_ID, $modList->getCreatedBy()->getId()->toString()); + $I->assertSame('2021-01-01T00:00:00+00:00', $modList->getLastUpdatedAt()?->format(DATE_ATOM)); + $I->assertSame($currentUser->getId()->toString(), $modList->getLastUpdatedBy()?->getId()->toString()); + } + + public function updateExternalModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', DefaultStandardModListFixture::NAME); + $I->click('Apply'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'Mod list with the same name "Default" already exist.'); + } + + public function updateExternalModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', ''); + $I->click('Apply'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'This value should not be blank.'); + } + + public function updateExternalModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', str_repeat('a', 256)); + $I->fillField('Mod list description', str_repeat('a', 256)); + $I->click('Apply'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('name', 'This value is too long. It should have 255 characters or less.'); + $I->seeFormErrorMessage('description', 'This value is too long. It should have 255 characters or less.'); + } + + public function updateExternalModListAsAuthorizedUserWithDataInvalid(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->fillField('Mod list name', 'External'); + $I->fillField('Mod list url', 'invalid'); + $I->click('Apply'); + + $I->seeResponseCodeIs(HttpCode::OK); + + $I->seeFormErrorMessage('url', 'This value is not a valid URL.'); + } + + public function updateExternalModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->externalModListUpdate = true; + }); + + $I->amOnPage(sprintf('/external-mod-list/%s/update', 'non existing')); + + $I->seeResponseCodeIs(HttpCode::NOT_FOUND); + } +} diff --git a/tests/functional/Mods/Web/ModList/ListModListsCest.php b/tests/functional/Mods/Web/ModList/ListModListsCest.php deleted file mode 100644 index 21d5c825..00000000 --- a/tests/functional/Mods/Web/ModList/ListModListsCest.php +++ /dev/null @@ -1,140 +0,0 @@ -stopFollowingRedirects(); - } - - public function listModListsAsUnauthenticatedUser(FunctionalTester $I): void - { - $I->amOnPage('/mod-list/list'); - $I->seeResponseRedirectsToLogInAction(); - } - - public function listModListsAsUnauthorizedUser(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::FORBIDDEN); - } - - public function listModListsAsAuthorizedUser(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { - $user->getPermissions()->modListList = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->dontSeeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->dontSeeActionButton('Edit mod list'); - $I->dontSeeActionButton('Copy and edit mod list'); - $I->dontSeeActionButton('Delete mod list'); - } - - public function listModListsAsAuthorizedUserWithCreateModListPermission(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { - $user->getPermissions()->modListList = true; - $user->getPermissions()->modListCreate = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->seeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->dontSeeActionButton('Edit mod list'); - $I->dontSeeActionButton('Copy and edit mod list'); - $I->dontSeeActionButton('Delete mod list'); - } - - public function listModListsAsAuthorizedUserWithUpdateModListPermission(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { - $user->getPermissions()->modListList = true; - $user->getPermissions()->modListUpdate = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->dontSeeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->seeActionButton('Edit mod list'); - $I->dontSeeActionButton('Copy and edit mod list'); - $I->dontSeeActionButton('Delete mod list'); - } - - public function listModListsAsAuthorizedUserWithModListOwnership(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(CupModListFixture::OWNER_ID, function (User $user): void { - $user->getPermissions()->modListList = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->dontSeeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->seeActionButton('Edit mod list', '/mod-list/CUP/update'); - $I->dontSeeActionButton('Copy and edit mod list'); - $I->seeActionButton('Delete mod list', '/mod-list/CUP/delete'); - } - - public function listModListsAsAuthorizedUserWithCopyModListPermission(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { - $user->getPermissions()->modListList = true; - $user->getPermissions()->modListCopy = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->dontSeeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->dontSeeActionButton('Edit mod list'); - $I->seeActionButton('Copy and edit mod list'); - $I->dontSeeActionButton('Delete mod list'); - } - - public function listModListsAsAuthorizedUserWithDeleteModListPermission(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User3Fixture::ID, function (User $user): void { - $user->getPermissions()->modListList = true; - $user->getPermissions()->modListDelete = true; - }); - - $I->amOnPage('/mod-list/list'); - - $I->seeResponseCodeIs(HttpCode::OK); - - $I->dontSeeLink('Create mod list'); - $I->seeActionButton('Download mod list'); - $I->dontSeeActionButton('Edit mod list'); - $I->dontSeeActionButton('Copy and edit mod list'); - $I->seeActionButton('Delete mod list'); - } -} diff --git a/tests/functional/Mods/Web/ModList/CopyModListCest.php b/tests/functional/Mods/Web/ModList/Standard/CopyStandardModListCest.php similarity index 77% rename from tests/functional/Mods/Web/ModList/CopyModListCest.php rename to tests/functional/Mods/Web/ModList/Standard/CopyStandardModListCest.php index f057e7eb..2e55b78a 100644 --- a/tests/functional/Mods/Web/ModList/CopyModListCest.php +++ b/tests/functional/Mods/Web/ModList/Standard/CopyStandardModListCest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Tests\Functional\Mods\Web\ModList; +namespace App\Tests\Functional\Mods\Web\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Dlc\SogPrairieFireDlcFixture; @@ -15,12 +15,12 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Disabled\ArmaForcesJbadBuildingFixModFixture; use App\Mods\DataFixtures\ModGroup\CupModGroupFixture; use App\Mods\DataFixtures\ModGroup\RhsModGroupFixture; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; -use App\Mods\DataFixtures\ModList\RhsModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; +use App\Mods\DataFixtures\ModList\Standard\RhsStandardModListFixture; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Service\IdentifierFactory\IdentifierFactoryStub; use App\Tests\FunctionalTester; use App\Users\DataFixtures\User\User1Fixture; @@ -29,7 +29,7 @@ use Codeception\Util\HttpCode; use Ramsey\Uuid\Uuid; -class CopyModListCest +class CopyStandardModListCest { public function _before(FunctionalTester $I): void { @@ -43,29 +43,29 @@ public function _before(FunctionalTester $I): void ]); } - public function copyModListAsUnauthenticatedUser(FunctionalTester $I): void + public function copyStandardModListAsUnauthenticatedUser(FunctionalTester $I): void { - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseRedirectsToLogInAction(); } - public function copyModListAsUnauthorizedUser(FunctionalTester $I): void + public function copyStandardModListAsUnauthorizedUser(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::FORBIDDEN); } - public function copyModListAsAuthorizedUser(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUser(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; + $user->getPermissions()->standardModListCopy = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -75,13 +75,13 @@ public function copyModListAsAuthorizedUser(FunctionalTester $I): void $I->dontSee('Mod list owner'); $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -106,8 +106,8 @@ public function copyModListAsAuthorizedUser(FunctionalTester $I): void $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('805c9fcd-d674-4a27-8f0c-78dbf2484bb2', $modList->getId()->toString()); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); @@ -134,14 +134,14 @@ public function copyModListAsAuthorizedUser(FunctionalTester $I): void $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function copyModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; - $user->getPermissions()->modListApprove = true; + $user->getPermissions()->standardModListCopy = true; + $user->getPermissions()->standardModListApprove = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -151,13 +151,13 @@ public function copyModListAsAuthorizedUserWithModListApprovePermission(Function $I->dontSee('Mod list owner'); $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSeeCheckboxIsChecked('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -183,8 +183,8 @@ public function copyModListAsAuthorizedUserWithModListApprovePermission(Function $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User1Fixture::ID, $modList->getOwner()->getId()->toString()); // Current user @@ -210,14 +210,14 @@ public function copyModListAsAuthorizedUserWithModListApprovePermission(Function $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function copyModListAsAuthorizedUserWithModListUpdatePermission(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWithModListUpdatePermission(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListCopy = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -227,13 +227,13 @@ public function copyModListAsAuthorizedUserWithModListUpdatePermission(Functiona $I->seeOptionIsSelected('Mod list owner', User1Fixture::USERNAME); // Current user $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Same as the source mod list - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -259,8 +259,8 @@ public function copyModListAsAuthorizedUserWithModListUpdatePermission(Functiona $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User3Fixture::ID, $modList->getOwner()->getId()->toString()); @@ -286,17 +286,17 @@ public function copyModListAsAuthorizedUserWithModListUpdatePermission(Functiona $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function copyModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; + $user->getPermissions()->standardModListCopy = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); - $I->fillField('Mod list name', DefaultModListFixture::NAME); + $I->fillField('Mod list name', DefaultStandardModListFixture::NAME); $I->click('Create mod list'); $I->seeResponseCodeIs(HttpCode::OK); @@ -304,13 +304,13 @@ public function copyModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTe $I->seeFormErrorMessage('name', 'Mod list with the same name "Default" already exist.'); } - public function copyModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; + $user->getPermissions()->standardModListCopy = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -322,13 +322,13 @@ public function copyModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I->seeFormErrorMessage('name', 'This value should not be blank.'); } - public function copyModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; + $user->getPermissions()->standardModListCopy = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -342,13 +342,13 @@ public function copyModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): $I->seeFormErrorMessage('description', 'This value is too long. It should have 255 characters or less.'); } - public function copyModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void + public function copyStandardModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCopy = true; + $user->getPermissions()->standardModListCopy = true; }); - $I->amOnPage(sprintf('/mod-list/%s/copy', 'non existing')); + $I->amOnPage(sprintf('/standard-mod-list/%s/copy', 'non existing')); $I->seeResponseCodeIs(HttpCode::NOT_FOUND); } diff --git a/tests/functional/Mods/Web/ModList/CreateModListCest.php b/tests/functional/Mods/Web/ModList/Standard/CreateStandardModListCest.php similarity index 71% rename from tests/functional/Mods/Web/ModList/CreateModListCest.php rename to tests/functional/Mods/Web/ModList/Standard/CreateStandardModListCest.php index b220f79b..863f148b 100644 --- a/tests/functional/Mods/Web/ModList/CreateModListCest.php +++ b/tests/functional/Mods/Web/ModList/Standard/CreateStandardModListCest.php @@ -2,16 +2,16 @@ declare(strict_types=1); -namespace App\Tests\Functional\Mods\Web\ModList; +namespace App\Tests\Functional\Mods\Web\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\RhsAfrfModFixture; use App\Mods\DataFixtures\ModGroup\CupModGroupFixture; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Shared\Service\IdentifierFactory\IdentifierFactoryStub; use App\Tests\FunctionalTester; use App\Users\DataFixtures\User\User1Fixture; @@ -20,7 +20,7 @@ use Codeception\Util\HttpCode; use Ramsey\Uuid\Uuid; -class CreateModListCest +class CreateStandardModListCest { public function _before(FunctionalTester $I): void { @@ -34,29 +34,29 @@ public function _before(FunctionalTester $I): void ]); } - public function createModListAsUnauthenticatedUser(FunctionalTester $I): void + public function createStandardModListAsUnauthenticatedUser(FunctionalTester $I): void { - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseRedirectsToLogInAction(); } - public function createModListAsUnauthorizedUser(FunctionalTester $I): void + public function createStandardModListAsUnauthorizedUser(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::FORBIDDEN); } - public function createModListAsAuthorizedUser(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUser(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; + $user->getPermissions()->standardModListCreate = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); @@ -66,9 +66,9 @@ public function createModListAsAuthorizedUser(FunctionalTester $I): void $I->dontSee('Mod list owner'); $I->seeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_'); // All mod group checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_'); // All DLC checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_'); // All mod checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_'); // All mod group checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_'); // All DLC checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_'); // All mod checkboxes are unchecked // Fill form $I->fillField('Mod list name', 'Custom'); @@ -81,8 +81,8 @@ public function createModListAsAuthorizedUser(FunctionalTester $I): void $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('805c9fcd-d674-4a27-8f0c-78dbf2484bb2', $modList->getId()->toString()); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); @@ -105,14 +105,14 @@ public function createModListAsAuthorizedUser(FunctionalTester $I): void $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function createModListAsAuthorizedUserWithModListUpdatePermission(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUserWithModListUpdatePermission(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListCreate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); @@ -122,9 +122,9 @@ public function createModListAsAuthorizedUserWithModListUpdatePermission(Functio $I->seeOptionIsSelected('Mod list owner', User1Fixture::USERNAME); $I->seeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_'); // All mod group checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_'); // All DLC checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_'); // All mod checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_'); // All mod group checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_'); // All DLC checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_'); // All mod checkboxes are unchecked // Fill form $I->fillField('Mod list name', 'Custom'); @@ -138,8 +138,8 @@ public function createModListAsAuthorizedUserWithModListUpdatePermission(Functio $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User2Fixture::ID, $modList->getOwner()->getId()->toString()); // Current user @@ -161,14 +161,14 @@ public function createModListAsAuthorizedUserWithModListUpdatePermission(Functio $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function createModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; - $user->getPermissions()->modListApprove = true; + $user->getPermissions()->standardModListCreate = true; + $user->getPermissions()->standardModListApprove = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); @@ -178,9 +178,9 @@ public function createModListAsAuthorizedUserWithModListApprovePermission(Functi $I->dontSee('Mod list owner'); $I->seeCheckboxIsChecked('Mod list active'); $I->dontSeeCheckboxIsChecked('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_'); // All mod group checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_'); // All DLC checkboxes are unchecked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_'); // All mod checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_'); // All mod group checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_'); // All DLC checkboxes are unchecked + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_'); // All mod checkboxes are unchecked // Fill form $I->fillField('Mod list name', 'Custom'); @@ -194,8 +194,8 @@ public function createModListAsAuthorizedUserWithModListApprovePermission(Functi $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User1Fixture::ID, $modList->getOwner()->getId()->toString()); // Current user @@ -217,17 +217,17 @@ public function createModListAsAuthorizedUserWithModListApprovePermission(Functi $I->assertSame(null, $modList->getLastUpdatedBy()?->getId()->toString()); } - public function createModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; + $user->getPermissions()->standardModListCreate = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); - $I->fillField('Mod list name', DefaultModListFixture::NAME); + $I->fillField('Mod list name', DefaultStandardModListFixture::NAME); $I->click('Create mod list'); $I->seeResponseCodeIs(HttpCode::OK); @@ -235,13 +235,13 @@ public function createModListAsAuthorizedUserWhenModListAlreadyExists(Functional $I->seeFormErrorMessage('name', 'Mod list with the same name "Default" already exist.'); } - public function createModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; + $user->getPermissions()->standardModListCreate = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); @@ -253,13 +253,13 @@ public function createModListAsAuthorizedUserWithoutRequiredData(FunctionalTeste $I->seeFormErrorMessage('name', 'This value should not be blank.'); } - public function createModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void + public function createStandardModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListCreate = true; + $user->getPermissions()->standardModListCreate = true; }); - $I->amOnPage('/mod-list/create'); + $I->amOnPage('/standard-mod-list/create'); $I->seeResponseCodeIs(HttpCode::OK); diff --git a/tests/functional/Mods/Web/ModList/Standard/DeleteStandardModListCest.php b/tests/functional/Mods/Web/ModList/Standard/DeleteStandardModListCest.php new file mode 100644 index 00000000..e5878e9b --- /dev/null +++ b/tests/functional/Mods/Web/ModList/Standard/DeleteStandardModListCest.php @@ -0,0 +1,78 @@ +stopFollowingRedirects(); + } + + public function deleteStandardModListAsUnauthenticatedUser(FunctionalTester $I): void + { + $I->amOnPage(sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + + $I->seeResponseRedirectsToLogInAction(); + + $I->seeInRepository(StandardModList::class, ['name' => DefaultStandardModListFixture::NAME]); + } + + public function deleteStandardModListAsUnauthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage(sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + + $I->seeInRepository(StandardModList::class, ['name' => DefaultStandardModListFixture::NAME]); + } + + public function deleteStandardModListAsAuthorizedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->standardModListDelete = true; + }); + + $I->amOnPage(sprintf('/standard-mod-list/%s/delete', DefaultStandardModListFixture::NAME)); + + $I->seeResponseRedirectsTo('/mod-list/list'); + + $I->dontSeeInRepository(StandardModList::class, ['name' => DefaultStandardModListFixture::NAME]); + } + + public function deleteStandardModListAsModListOwner(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(CupStandardModListFixture::OWNER_ID, function (User $user): void { + $user->getPermissions()->standardModListDelete = false; + }); + + $I->amOnPage(sprintf('/standard-mod-list/%s/delete', CupStandardModListFixture::NAME)); + + $I->seeResponseRedirectsTo('/mod-list/list'); + + $I->dontSeeInRepository(StandardModList::class, ['name' => CupStandardModListFixture::NAME]); + } + + public function deleteStandardModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { + $user->getPermissions()->standardModListDelete = true; + }); + + $I->amOnPage(sprintf('/standard-mod-list/%s/delete', 'non existing')); + + $I->seeResponseCodeIs(HttpCode::NOT_FOUND); + } +} diff --git a/tests/functional/Mods/Web/ModList/UpdateModListCest.php b/tests/functional/Mods/Web/ModList/Standard/UpdateStandardModListCest.php similarity index 73% rename from tests/functional/Mods/Web/ModList/UpdateModListCest.php rename to tests/functional/Mods/Web/ModList/Standard/UpdateStandardModListCest.php index 394687af..e88b5db6 100644 --- a/tests/functional/Mods/Web/ModList/UpdateModListCest.php +++ b/tests/functional/Mods/Web/ModList/Standard/UpdateStandardModListCest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Tests\Functional\Mods\Web\ModList; +namespace App\Tests\Functional\Mods\Web\ModList\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Dlc\SogPrairieFireDlcFixture; @@ -15,12 +15,12 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\Disabled\ArmaForcesJbadBuildingFixModFixture; use App\Mods\DataFixtures\ModGroup\CupModGroupFixture; use App\Mods\DataFixtures\ModGroup\RhsModGroupFixture; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; -use App\Mods\DataFixtures\ModList\RhsModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; +use App\Mods\DataFixtures\ModList\Standard\RhsStandardModListFixture; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\AbstractMod; use App\Mods\Entity\ModGroup\ModGroup; -use App\Mods\Entity\ModList\ModList; +use App\Mods\Entity\ModList\StandardModList; use App\Tests\FunctionalTester; use App\Users\DataFixtures\User\User1Fixture; use App\Users\DataFixtures\User\User2Fixture; @@ -28,7 +28,7 @@ use App\Users\Entity\User\User; use Codeception\Util\HttpCode; -class UpdateModListCest +class UpdateStandardModListCest { public function _before(FunctionalTester $I): void { @@ -36,29 +36,29 @@ public function _before(FunctionalTester $I): void $I->freezeTime('2021-01-01T00:00:00+00:00'); } - public function updateModListAsUnauthenticatedUser(FunctionalTester $I): void + public function updateStandardModListAsUnauthenticatedUser(FunctionalTester $I): void { - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseRedirectsToLogInAction(); } - public function updateModListAsUnauthorizedUser(FunctionalTester $I): void + public function updateStandardModListAsUnauthorizedUser(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::FORBIDDEN); } - public function updateModListAsAuthorizedUser(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUser(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -68,13 +68,13 @@ public function updateModListAsAuthorizedUser(FunctionalTester $I): void $I->seeOptionIsSelected('Mod list owner', User2Fixture::USERNAME); $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -100,8 +100,8 @@ public function updateModListAsAuthorizedUser(FunctionalTester $I): void $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User3Fixture::ID, $modList->getOwner()->getId()->toString()); @@ -122,19 +122,19 @@ public function updateModListAsAuthorizedUser(FunctionalTester $I): void ], array_map(fn (AbstractMod $mod) => $mod->getId()->toString(), $modList->getMods())); $I->assertSame('2020-01-01T00:00:00+00:00', $modList->getCreatedAt()->format(DATE_ATOM)); - $I->assertSame(RhsModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); + $I->assertSame(RhsStandardModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); $I->assertSame('2021-01-01T00:00:00+00:00', $modList->getLastUpdatedAt()?->format(DATE_ATOM)); $I->assertSame($currentUser->getId()->toString(), $modList->getLastUpdatedBy()?->getId()->toString()); } - public function updateModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUserWithModListApprovePermission(FunctionalTester $I): void { $currentUser = $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; - $user->getPermissions()->modListApprove = true; + $user->getPermissions()->standardModListUpdate = true; + $user->getPermissions()->standardModListApprove = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -144,13 +144,13 @@ public function updateModListAsAuthorizedUserWithModListApprovePermission(Functi $I->seeOptionIsSelected('Mod list owner', User2Fixture::USERNAME); $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSeeCheckboxIsChecked('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -177,8 +177,8 @@ public function updateModListAsAuthorizedUserWithModListApprovePermission(Functi $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); $I->assertSame(User3Fixture::ID, $modList->getOwner()->getId()->toString()); @@ -199,18 +199,18 @@ public function updateModListAsAuthorizedUserWithModListApprovePermission(Functi ], array_map(fn (AbstractMod $mod) => $mod->getId()->toString(), $modList->getMods())); $I->assertSame('2020-01-01T00:00:00+00:00', $modList->getCreatedAt()->format(DATE_ATOM)); - $I->assertSame(RhsModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); + $I->assertSame(RhsStandardModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); $I->assertSame('2021-01-01T00:00:00+00:00', $modList->getLastUpdatedAt()?->format(DATE_ATOM)); $I->assertSame($currentUser->getId()->toString(), $modList->getLastUpdatedBy()?->getId()->toString()); } - public function updateModListAsModListOwner(FunctionalTester $I): void + public function updateStandardModListAsModListOwner(FunctionalTester $I): void { - $currentUser = $I->amDiscordAuthenticatedAs(RhsModListFixture::OWNER_ID, function (User $user): void { - $user->getPermissions()->modListUpdate = false; + $currentUser = $I->amDiscordAuthenticatedAs(RhsStandardModListFixture::OWNER_ID, function (User $user): void { + $user->getPermissions()->standardModListUpdate = false; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -220,13 +220,13 @@ public function updateModListAsModListOwner(FunctionalTester $I): void $I->dontSee('Mod list owner'); $I->dontSeeCheckboxIsChecked('Mod list active'); $I->dontSee('Mod list approved'); - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_modGroups_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_modGroups_', [ RhsModGroupFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_dlcs_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_dlcs_', [ CslaIronCurtainDlcFixture::ID, ]); // Some checkboxes checked - $I->seeTableRowCheckboxesAreUnchecked('mod_list_form_mods_', [ + $I->seeTableRowCheckboxesAreUnchecked('standard_mod_list_form_mods_', [ R3ModFixture::ID, ArmaScriptProfilerModFixture::ID, @@ -251,11 +251,11 @@ public function updateModListAsModListOwner(FunctionalTester $I): void $I->seeResponseRedirectsTo('/mod-list/list'); - /** @var ModList $modList */ - $modList = $I->grabEntityFromRepository(ModList::class, ['name' => 'Custom']); + /** @var StandardModList $modList */ + $modList = $I->grabEntityFromRepository(StandardModList::class, ['name' => 'Custom']); $I->assertSame('Custom', $modList->getName()); $I->assertSame('Custom modlist', $modList->getDescription()); - $I->assertSame(RhsModListFixture::OWNER_ID, $modList->getOwner()->getId()->toString()); + $I->assertSame(RhsStandardModListFixture::OWNER_ID, $modList->getOwner()->getId()->toString()); $I->assertSame(true, $modList->isActive()); $I->assertSame(false, $modList->isApproved()); $I->assertSame([ @@ -273,22 +273,22 @@ public function updateModListAsModListOwner(FunctionalTester $I): void ], array_map(fn (AbstractMod $mod) => $mod->getId()->toString(), $modList->getMods())); $I->assertSame('2020-01-01T00:00:00+00:00', $modList->getCreatedAt()->format(DATE_ATOM)); - $I->assertSame(RhsModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); + $I->assertSame(RhsStandardModListFixture::OWNER_ID, $modList->getCreatedBy()->getId()->toString()); $I->assertSame('2021-01-01T00:00:00+00:00', $modList->getLastUpdatedAt()?->format(DATE_ATOM)); $I->assertSame($currentUser->getId()->toString(), $modList->getLastUpdatedBy()?->getId()->toString()); } - public function updateModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUserWhenModListAlreadyExists(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); - $I->fillField('Mod list name', DefaultModListFixture::NAME); + $I->fillField('Mod list name', DefaultStandardModListFixture::NAME); $I->click('Apply'); $I->seeResponseCodeIs(HttpCode::OK); @@ -296,13 +296,13 @@ public function updateModListAsAuthorizedUserWhenModListAlreadyExists(Functional $I->seeFormErrorMessage('name', 'Mod list with the same name "Default" already exist.'); } - public function updateModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUserWithoutRequiredData(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -314,13 +314,13 @@ public function updateModListAsAuthorizedUserWithoutRequiredData(FunctionalTeste $I->seeFormErrorMessage('name', 'This value should not be blank.'); } - public function updateModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -334,13 +334,13 @@ public function updateModListAsAuthorizedUserWithDataTooLong(FunctionalTester $I $I->seeFormErrorMessage('description', 'This value is too long. It should have 255 characters or less.'); } - public function updateModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void + public function updateStandardModListAsAuthorizedUserWhenModListDoesNotExist(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID, function (User $user): void { - $user->getPermissions()->modListUpdate = true; + $user->getPermissions()->standardModListUpdate = true; }); - $I->amOnPage(sprintf('/mod-list/%s/update', 'non existing')); + $I->amOnPage(sprintf('/standard-mod-list/%s/update', 'non existing')); $I->seeResponseCodeIs(HttpCode::NOT_FOUND); } diff --git a/tests/functional/Mods/Web/ModListPublic/Common/SelectModListCest.php b/tests/functional/Mods/Web/ModListPublic/Common/SelectModListCest.php new file mode 100644 index 00000000..6e774187 --- /dev/null +++ b/tests/functional/Mods/Web/ModListPublic/Common/SelectModListCest.php @@ -0,0 +1,34 @@ +amOnPage('/mod-list/select'); + + $I->see(DefaultStandardModListFixture::NAME); + $I->see(CupStandardModListFixture::NAME); + $I->dontSee(RhsStandardModListFixture::NAME); // disabled + } + + public function selectModListAsAuthenticatedUser(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage('/mod-list/select'); + + $I->see(DefaultStandardModListFixture::NAME); + $I->see(CupStandardModListFixture::NAME); + $I->dontSee(RhsStandardModListFixture::NAME); // disabled + } +} diff --git a/tests/functional/Mods/Web/ModListPublic/External/RedirectToExternalModListCest.php b/tests/functional/Mods/Web/ModListPublic/External/RedirectToExternalModListCest.php new file mode 100644 index 00000000..152e7415 --- /dev/null +++ b/tests/functional/Mods/Web/ModListPublic/External/RedirectToExternalModListCest.php @@ -0,0 +1,53 @@ +freezeTime('2020-01-01T00:00:00+00:00'); + } + + public function redirectToExternalModListAsUnauthenticatedUser(FunctionalTester $I): void + { + /** @var ExternalModList $externalModList */ + $externalModList = $I->grabEntityFromRepository(ExternalModList::class, ['name' => LocalhostExternalModList::NAME]); + + $I->stopFollowingRedirects(); + $I->amOnPage(sprintf('/mod-list/%s', $externalModList->getName())); + + $I->seeResponseRedirectsTo($externalModList->getUrl()); + } + + public function redirectToExternalModListAsAuthenticatedUser(FunctionalTester $I): void + { + /** @var ExternalModList $externalModList */ + $externalModList = $I->grabEntityFromRepository(ExternalModList::class, ['name' => LocalhostExternalModList::NAME]); + + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->stopFollowingRedirects(); + $I->amOnPage(sprintf('/mod-list/%s', $externalModList->getName())); + + $I->seeResponseRedirectsTo($externalModList->getUrl()); + } + + public function redirectToExternalModListAsAuthenticatedUserWhenModListInactive(FunctionalTester $I): void + { + $I->amDiscordAuthenticatedAs(User1Fixture::ID); + + $I->amOnPage(sprintf('/mod-list/%s', GoogleExternalModList::NAME)); + + $I->seeResponseCodeIs(HttpCode::FORBIDDEN); + } +} diff --git a/tests/functional/Mods/Web/ModListPublic/SelectModListCest.php b/tests/functional/Mods/Web/ModListPublic/SelectModListCest.php deleted file mode 100644 index bcf1df28..00000000 --- a/tests/functional/Mods/Web/ModListPublic/SelectModListCest.php +++ /dev/null @@ -1,34 +0,0 @@ -amOnPage('/mod-list/select'); - - $I->see(DefaultModListFixture::NAME); - $I->see(CupModListFixture::NAME); - $I->dontSee(RhsModListFixture::NAME); // disabled - } - - public function selectModListAsAuthenticatedUser(FunctionalTester $I): void - { - $I->amDiscordAuthenticatedAs(User1Fixture::ID); - - $I->amOnPage('/mod-list/select'); - - $I->see(DefaultModListFixture::NAME); - $I->see(CupModListFixture::NAME); - $I->dontSee(RhsModListFixture::NAME); // disabled - } -} diff --git a/tests/functional/Mods/Web/ModListPublic/CustomizeModListCest.php b/tests/functional/Mods/Web/ModListPublic/Standard/CustomizeStandardModListCest.php similarity index 70% rename from tests/functional/Mods/Web/ModListPublic/CustomizeModListCest.php rename to tests/functional/Mods/Web/ModListPublic/Standard/CustomizeStandardModListCest.php index d53aba97..325589eb 100644 --- a/tests/functional/Mods/Web/ModListPublic/CustomizeModListCest.php +++ b/tests/functional/Mods/Web/ModListPublic/Standard/CustomizeStandardModListCest.php @@ -2,15 +2,15 @@ declare(strict_types=1); -namespace App\Tests\Functional\Mods\Web\ModListPublic; +namespace App\Tests\Functional\Mods\Web\ModListPublic\Standard; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; -use App\Mods\DataFixtures\ModList\RhsModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; +use App\Mods\DataFixtures\ModList\Standard\RhsStandardModListFixture; use App\Tests\FunctionalTester; use App\Users\DataFixtures\User\User1Fixture; use Codeception\Util\HttpCode; -class CustomizeModListCest +class CustomizeStandardModListCest { public function _before(FunctionalTester $I): void { @@ -19,7 +19,7 @@ public function _before(FunctionalTester $I): void public function customizeModListAsUnauthenticatedUser(FunctionalTester $I): void { - $I->amOnPage(sprintf('/mod-list/%s', DefaultModListFixture::NAME)); + $I->amOnPage(sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -33,7 +33,7 @@ public function customizeModListAsAuthenticatedUser(FunctionalTester $I): void { $I->amDiscordAuthenticatedAs(User1Fixture::ID); - $I->amOnPage(sprintf('/mod-list/%s', DefaultModListFixture::NAME)); + $I->amOnPage(sprintf('/mod-list/%s', DefaultStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::OK); @@ -47,7 +47,7 @@ public function customizeModListAsAuthenticatedUserWhenModListInactive(Functiona { $I->amDiscordAuthenticatedAs(User1Fixture::ID); - $I->amOnPage(sprintf('/mod-list/%s', RhsModListFixture::NAME)); + $I->amOnPage(sprintf('/mod-list/%s', RhsStandardModListFixture::NAME)); $I->seeResponseCodeIs(HttpCode::FORBIDDEN); } diff --git a/tests/functional/Mods/Web/ModListPublic/DownloadModListCest.php b/tests/functional/Mods/Web/ModListPublic/Standard/DownloadStandardModListCest.php similarity index 92% rename from tests/functional/Mods/Web/ModListPublic/DownloadModListCest.php rename to tests/functional/Mods/Web/ModListPublic/Standard/DownloadStandardModListCest.php index 7b79198d..b9a73f78 100644 --- a/tests/functional/Mods/Web/ModListPublic/DownloadModListCest.php +++ b/tests/functional/Mods/Web/ModListPublic/Standard/DownloadStandardModListCest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Tests\Functional\Mods\Web\ModListPublic; +namespace App\Tests\Functional\Mods\Web\ModListPublic\Standard; use App\Mods\DataFixtures\Dlc\CslaIronCurtainDlcFixture; use App\Mods\DataFixtures\Dlc\GlobalMobilizationDlcFixture; @@ -20,15 +20,15 @@ use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\RhsAfrfModFixture; use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\RhsGrefModFixture; use App\Mods\DataFixtures\Mod\SteamWorkshop\Required\RhsUsafModFixture; -use App\Mods\DataFixtures\ModList\DefaultModListFixture; -use App\Mods\DataFixtures\ModList\RhsModListFixture; +use App\Mods\DataFixtures\ModList\Standard\DefaultStandardModListFixture; +use App\Mods\DataFixtures\ModList\Standard\RhsStandardModListFixture; use App\Mods\Entity\Dlc\Dlc; use App\Mods\Entity\Mod\SteamWorkshopMod; use App\Tests\FunctionalTester; use App\Users\DataFixtures\User\User1Fixture; use Codeception\Util\HttpCode; -class DownloadModListCest +class DownloadStandardModListCest { public function _before(FunctionalTester $I): void { @@ -42,7 +42,7 @@ public function downloadModListAsUnauthenticatedUser(FunctionalTester $I): void 'invalid', ]; - $I->amOnPage(sprintf('/mod-list/%s/download/%s', DefaultModListFixture::NAME, json_encode($optionalMods))); + $I->amOnPage(sprintf('/mod-list/%s/download/%s', DefaultStandardModListFixture::NAME, json_encode($optionalMods))); $I->seeResponseContainsModListPresetWithMods('ArmaForces Default 2020_01_01 00_00.html', [ $I->grabEntityFromRepository(Dlc::class, ['id' => CslaIronCurtainDlcFixture::ID]), @@ -73,7 +73,7 @@ public function downloadModListAsAuthenticatedUser(FunctionalTester $I): void 'invalid', ]; - $I->amOnPage(sprintf('/mod-list/%s/download/%s', DefaultModListFixture::NAME, json_encode($optionalMods))); + $I->amOnPage(sprintf('/mod-list/%s/download/%s', DefaultStandardModListFixture::NAME, json_encode($optionalMods))); $I->seeResponseContainsModListPresetWithMods('ArmaForces Default 2020_01_01 00_00.html', [ $I->grabEntityFromRepository(Dlc::class, ['id' => CslaIronCurtainDlcFixture::ID]), @@ -104,7 +104,7 @@ public function downloadModListAsAuthenticatedUserWhenModListInactive(Functional 'invalid', ]; - $I->amOnPage(sprintf('/mod-list/%s/download/%s', RhsModListFixture::NAME, json_encode($optionalMods))); + $I->amOnPage(sprintf('/mod-list/%s/download/%s', RhsStandardModListFixture::NAME, json_encode($optionalMods))); $I->seeResponseCodeIs(HttpCode::FORBIDDEN); } diff --git a/tests/functional/Users/Web/User/UpdateUserCest.php b/tests/functional/Users/Web/User/UpdateUserCest.php index c778fe25..20bc9e60 100644 --- a/tests/functional/Users/Web/User/UpdateUserCest.php +++ b/tests/functional/Users/Web/User/UpdateUserCest.php @@ -150,11 +150,11 @@ public function updateUserAsAuthorizedUser(FunctionalTester $I): void $I->assertTrue($user->getPermissions()->dlcDelete); $I->assertTrue($user->getPermissions()->modListList); - $I->assertTrue($user->getPermissions()->modListCreate); - $I->assertTrue($user->getPermissions()->modListUpdate); - $I->assertTrue($user->getPermissions()->modListCopy); - $I->assertTrue($user->getPermissions()->modListDelete); - $I->assertTrue($user->getPermissions()->modListApprove); + $I->assertTrue($user->getPermissions()->standardModListCreate); + $I->assertTrue($user->getPermissions()->standardModListUpdate); + $I->assertTrue($user->getPermissions()->standardModListCopy); + $I->assertTrue($user->getPermissions()->standardModListDelete); + $I->assertTrue($user->getPermissions()->standardModListApprove); $I->assertSame('2020-01-01T00:00:00+00:00', $user->getCreatedAt()->format(DATE_ATOM)); $I->assertSame(null, $user->getCreatedBy()?->getId()->toString()); @@ -272,11 +272,11 @@ public function updateSelfAsAuthorizedUser(FunctionalTester $I): void $I->assertTrue($user->getPermissions()->dlcDelete); $I->assertTrue($user->getPermissions()->modListList); - $I->assertTrue($user->getPermissions()->modListCreate); - $I->assertTrue($user->getPermissions()->modListUpdate); - $I->assertTrue($user->getPermissions()->modListCopy); - $I->assertTrue($user->getPermissions()->modListDelete); - $I->assertTrue($user->getPermissions()->modListApprove); + $I->assertTrue($user->getPermissions()->standardModListCreate); + $I->assertTrue($user->getPermissions()->standardModListUpdate); + $I->assertTrue($user->getPermissions()->standardModListCopy); + $I->assertTrue($user->getPermissions()->standardModListDelete); + $I->assertTrue($user->getPermissions()->standardModListApprove); $I->assertSame('2020-01-01T00:00:00+00:00', $user->getCreatedAt()->format(DATE_ATOM)); $I->assertSame(null, $user->getCreatedBy()?->getId()->toString()); diff --git a/tests/functional/Users/Web/UserGroup/CreateUserGroupCest.php b/tests/functional/Users/Web/UserGroup/CreateUserGroupCest.php index a2bac0e4..7ac94e9f 100644 --- a/tests/functional/Users/Web/UserGroup/CreateUserGroupCest.php +++ b/tests/functional/Users/Web/UserGroup/CreateUserGroupCest.php @@ -113,12 +113,15 @@ public function createUserGroupAsAuthorizedUser(FunctionalTester $I): void $I->assertSame('7cb77e2f-c26e-4098-b47b-60539bf5bb70', $userGroup->getId()->toString()); $I->assertSame('All', $userGroup->getName()); $I->assertSame('All users', $userGroup->getDescription()); - $I->assertSame([ - AdminFixture::ID, + + $groupUserIds = array_map(fn (User $user) => $user->getId()->toString(), $userGroup->getUsers()); + $expectedGroupUserIds = [ User1Fixture::ID, User2Fixture::ID, User3Fixture::ID, - ], array_map(fn (User $user) => $user->getId()->toString(), $userGroup->getUsers())); + AdminFixture::ID, + ]; + $I->assertArraySame($expectedGroupUserIds, $groupUserIds); $I->assertSame('805c9fcd-d674-4a27-8f0c-78dbf2484bb2', $userGroup->getPermissions()->getId()->toString()); @@ -148,11 +151,11 @@ public function createUserGroupAsAuthorizedUser(FunctionalTester $I): void $I->assertTrue($userGroup->getPermissions()->dlcDelete); $I->assertTrue($userGroup->getPermissions()->modListList); - $I->assertTrue($userGroup->getPermissions()->modListCreate); - $I->assertTrue($userGroup->getPermissions()->modListUpdate); - $I->assertTrue($userGroup->getPermissions()->modListCopy); - $I->assertTrue($userGroup->getPermissions()->modListDelete); - $I->assertTrue($userGroup->getPermissions()->modListApprove); + $I->assertTrue($userGroup->getPermissions()->standardModListCreate); + $I->assertTrue($userGroup->getPermissions()->standardModListUpdate); + $I->assertTrue($userGroup->getPermissions()->standardModListCopy); + $I->assertTrue($userGroup->getPermissions()->standardModListDelete); + $I->assertTrue($userGroup->getPermissions()->standardModListApprove); $I->assertSame('2020-01-01T00:00:00+00:00', $userGroup->getCreatedAt()->format(DATE_ATOM)); $I->assertSame($currentUser->getId()->toString(), $userGroup->getCreatedBy()?->getId()->toString()); diff --git a/tests/functional/Users/Web/UserGroup/UpdateUserGroupCest.php b/tests/functional/Users/Web/UserGroup/UpdateUserGroupCest.php index 8e5d6060..51b96d0e 100644 --- a/tests/functional/Users/Web/UserGroup/UpdateUserGroupCest.php +++ b/tests/functional/Users/Web/UserGroup/UpdateUserGroupCest.php @@ -77,12 +77,15 @@ public function updateUserGroupAsAuthorizedUser(FunctionalTester $I): void $userGroup = $I->grabEntityFromRepository(UserGroup::class, ['name' => 'All']); $I->assertSame('All', $userGroup->getName()); $I->assertSame('All users', $userGroup->getDescription()); - $I->assertSame([ + + $groupUserIds = array_map(fn (User $user) => $user->getId()->toString(), $userGroup->getUsers()); + $expectedGroupUserIds = [ User1Fixture::ID, User2Fixture::ID, User3Fixture::ID, AdminFixture::ID, - ], array_map(fn (User $user) => $user->getId()->toString(), $userGroup->getUsers())); + ]; + $I->assertArraySame($expectedGroupUserIds, $groupUserIds); $I->assertTrue($userGroup->getPermissions()->userList); $I->assertFalse($userGroup->getPermissions()->userUpdate); @@ -110,11 +113,11 @@ public function updateUserGroupAsAuthorizedUser(FunctionalTester $I): void $I->assertFalse($userGroup->getPermissions()->dlcDelete); $I->assertTrue($userGroup->getPermissions()->modListList); - $I->assertFalse($userGroup->getPermissions()->modListCreate); - $I->assertFalse($userGroup->getPermissions()->modListUpdate); - $I->assertFalse($userGroup->getPermissions()->modListCopy); - $I->assertFalse($userGroup->getPermissions()->modListDelete); - $I->assertFalse($userGroup->getPermissions()->modListApprove); + $I->assertFalse($userGroup->getPermissions()->standardModListCreate); + $I->assertFalse($userGroup->getPermissions()->standardModListUpdate); + $I->assertFalse($userGroup->getPermissions()->standardModListCopy); + $I->assertFalse($userGroup->getPermissions()->standardModListDelete); + $I->assertFalse($userGroup->getPermissions()->standardModListApprove); $I->assertSame('2020-01-01T00:00:00+00:00', $userGroup->getCreatedAt()->format(DATE_ATOM)); $I->assertSame(null, $userGroup->getCreatedBy()?->getId()->toString()); diff --git a/tests/unit/Shared/Service/Mission/MissionClientTest.php b/tests/unit/Shared/Service/Mission/MissionClientTest.php index 19a9ed7f..f4b7aee4 100644 --- a/tests/unit/Shared/Service/Mission/MissionClientTest.php +++ b/tests/unit/Shared/Service/Mission/MissionClientTest.php @@ -89,7 +89,7 @@ public function provideGetCurrentMissionCases(): iterable 'closeDate' => $now->sub(new \DateInterval('P1D'))->format($dateFormat), 'description' => '', 'modlistName' => null, - 'modlist' => 'https://armaforces.com/mod-list/Default2', + 'modlist' => 'https://armaforces.com/standard-mod-list/Default2', 'image' => '', 'freeSlots' => 0, 'allSlots' => 0, diff --git a/translations/messages.pl.yaml b/translations/messages.pl.yaml index 21a86fef..8965042f 100644 --- a/translations/messages.pl.yaml +++ b/translations/messages.pl.yaml @@ -12,6 +12,7 @@ Mods: Mody Mod groups: Grupy modów DLCs: DLC Mod lists: Listy modów +External mod lists: Zewnętrzne listy modów Today's mission: Dzisiejsza misja Manage users: Zarządzaj użytkownikami @@ -111,6 +112,10 @@ Can delete other users mod lists: Może usuwać listy modów innych użytkownik 'Note: User can always delete his own or assigned to him mod lists': 'Uwaga: Użytkownik zawsze ma możliwość usuwania stworzonych przez siebie lub przypisanych mu list modów' Can approve mod lists: Może zatwierdzać listy modów +Can create external mod lists: Może tworzyć zewnętrzne listy modów +Can edit external mod lists: Może edytować zewnętrzne listy modów +Can delete external mod lists: Może usuwać zewnętrzne listy modów + # Mods Create mod: Utwórz mod Edit mod: Edytuj mod @@ -162,7 +167,9 @@ DLC directory: Katalog DLC # Mod Lists Download mod list: Pobierz listę modów Create mod list: Utwórz listę modów +Create external mod list: Utwórz zewnętrzną listę modów Edit mod list: Edytuj listę modów +Edit external mod list: Edytuj zewnętrzną listę modów Copy and edit mod list: Kopiuj i edytuj listę modów Delete mod list: Usuń listę modów @@ -171,6 +178,8 @@ Mod list description: Opis Mod list owner: Właściciel Mod list active: Aktywna Mod list approved: Zatwierdzona +Mod list url: Link +Mod list external: Zewnętrzna # Mod Lists Customization Mod list customization: Konfiguracja listy modów