From 6c1978b1e63a9ba92b8c01ce7e80c27a0728509e Mon Sep 17 00:00:00 2001 From: Jonathan LELIEVRE Date: Tue, 5 Nov 2024 12:55:24 +0100 Subject: [PATCH] Add upload, install and uninstall endpoints --- .../Resources/Module/BulkModules.php | 11 ++ src/ApiPlatform/Resources/Module/Module.php | 31 ++++ .../ApiPlatform/ModuleEndpointTest.php | 150 ++++++++++++++++++ 3 files changed, 192 insertions(+) diff --git a/src/ApiPlatform/Resources/Module/BulkModules.php b/src/ApiPlatform/Resources/Module/BulkModules.php index 14de2e3..7bce69e 100644 --- a/src/ApiPlatform/Resources/Module/BulkModules.php +++ b/src/ApiPlatform/Resources/Module/BulkModules.php @@ -24,6 +24,7 @@ use ApiPlatform\Metadata\ApiResource; use PrestaShop\PrestaShop\Core\Domain\Module\Command\BulkToggleModuleStatusCommand; +use PrestaShop\PrestaShop\Core\Domain\Module\Command\BulkUninstallModuleCommand; use PrestaShop\PrestaShop\Core\Domain\Module\Exception\ModuleNotFoundException; use PrestaShopBundle\ApiPlatform\Metadata\CQRSUpdate; @@ -40,6 +41,14 @@ '[enabled]' => '[expectedStatus]', ], ), + new CQRSUpdate( + uriTemplate: '/modules/uninstall', + output: false, + CQRSCommand: BulkUninstallModuleCommand::class, + scopes: [ + 'module_write', + ], + ), ], exceptionToStatus: [ModuleNotFoundException::class => 404], )] @@ -51,4 +60,6 @@ class BulkModules public array $modules; public bool $enabled; + + public bool $deleteFile; } diff --git a/src/ApiPlatform/Resources/Module/Module.php b/src/ApiPlatform/Resources/Module/Module.php index 7a8151b..aa575a3 100644 --- a/src/ApiPlatform/Resources/Module/Module.php +++ b/src/ApiPlatform/Resources/Module/Module.php @@ -23,8 +23,11 @@ namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Module; use ApiPlatform\Metadata\ApiResource; +use PrestaShop\PrestaShop\Core\Domain\Module\Command\InstallModuleCommand; use PrestaShop\PrestaShop\Core\Domain\Module\Command\ResetModuleCommand; +use PrestaShop\PrestaShop\Core\Domain\Module\Command\UninstallModuleCommand; use PrestaShop\PrestaShop\Core\Domain\Module\Command\UpdateModuleStatusCommand; +use PrestaShop\PrestaShop\Core\Domain\Module\Command\UploadModuleCommand; use PrestaShop\PrestaShop\Core\Domain\Module\Exception\ModuleNotFoundException; use PrestaShop\PrestaShop\Core\Domain\Module\Query\GetModuleInfos; use PrestaShopBundle\ApiPlatform\Metadata\CQRSGet; @@ -57,6 +60,30 @@ 'module_write', ], ), + new CQRSCreate( + uriTemplate: '/module/{technicalName}/upload', + CQRSCommand: UploadModuleCommand::class, + CQRSQuery: GetModuleInfos::class, + scopes: [ + 'module_write', + ], + ), + new CQRSUpdate( + uriTemplate: '/module/{technicalName}/install', + CQRSCommand: InstallModuleCommand::class, + CQRSQuery: GetModuleInfos::class, + scopes: [ + 'module_write', + ], + ), + new CQRSUpdate( + uriTemplate: '/module/{technicalName}/uninstall', + output: false, + CQRSCommand: UninstallModuleCommand::class, + scopes: [ + 'module_write', + ], + ), new PaginatedList( uriTemplate: '/modules', scopes: [ @@ -78,4 +105,8 @@ class Module public bool $enabled; public bool $installed; + + public bool $deleteFile; + + public string $source; } diff --git a/tests/Integration/ApiPlatform/ModuleEndpointTest.php b/tests/Integration/ApiPlatform/ModuleEndpointTest.php index 71f23e9..0b56cf0 100644 --- a/tests/Integration/ApiPlatform/ModuleEndpointTest.php +++ b/tests/Integration/ApiPlatform/ModuleEndpointTest.php @@ -66,6 +66,21 @@ public function getProtectedEndpoints(): iterable 'PATCH', '/module/{technicalName}/reset', ]; + + yield 'upload module' => [ + 'POST', + '/module/{technicalName}/upload', + ]; + + yield 'uninstall module' => [ + 'PUT', + '/module/{technicalName}/uninstall', + ]; + + yield 'bulk uninstall' => [ + 'PUT', + '/modules/uninstall', + ]; } public function testModuleNotFound(): void @@ -301,6 +316,141 @@ public function restResetModuleNotActive(array $module): void self::assertResponseStatusCodeSame(400); } + public function testUninstallModule() + { + $module = [ + 'technicalName' => 'bankwire', + 'deleteFile' => false, + ]; + + // uninstall specific module deleteFile true + $bearerToken = $this->getBearerToken(['module_write']); + static::createClient()->request('PUT', sprintf('/module/%s/uninstall', $module['technicalName']), [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'deleteFile' => $module['deleteFile'], + ], + ]); + + self::assertResponseStatusCodeSame(204); + } + + public function testBulkUninstallModule() + { + $modules = ['ps_featuredproducts', 'ps_emailsubscription']; + + // uninstall specific module deleteFile true + $bearerToken = $this->getBearerToken(['module_write']); + static::createClient()->request('PUT', sprintf('/modules/uninstall'), [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'modules' => $modules, + 'deleteFile' => true, + ], + ]); + + self::assertResponseStatusCodeSame(204); + } + + /** + * @depends testUninstallModule + */ + public function testInstallModuleExistInFolder(): void + { + $module = [ + 'technicalName' => 'bankwire', + 'version' => '2.0.0', + ]; + + $bearerToken = $this->getBearerToken(['module_write']); + $response = static::createClient()->request('POST', sprintf('/module/%s/install', $module['technicalName']), [ + 'auth_bearer' => $bearerToken, + 'json' => [ + ], + ]); + + self::assertResponseStatusCodeSame(200); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // Check response from status update request + $expectedModuleInfos = [ + 'technicalName' => $module['technicalName'], + 'version' => $module['version'], + 'enabled' => true, + 'installed' => true, + ]; + + // Check response from status update request + $this->assertEquals($expectedModuleInfos, $decodedResponse); + } + + public function testInstallModuleFromZip(): void + { + $module = [ + 'technicalName' => 'test_install_cqrs_command', + 'source' => _PS_MODULE_DIR_ . 'test_install_cqrs_command.zip', + 'version' => '1.0.0', + ]; + $bearerToken = $this->getBearerToken(['module_write']); + $response = static::createClient()->request('POST', sprintf('/module/%s/install', $module['technicalName']), [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'source' => $module['source'], + ], + ]); + + self::assertResponseStatusCodeSame(201); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // Check response from status update request + $expectedModuleInfos = [ + 'technicalName' => $module['technicalName'], + 'version' => $module['version'], + 'enabled' => true, + 'installed' => true, + ]; + + // Check response from status update request + $this->assertEquals($expectedModuleInfos, $decodedResponse); + } + + /** + * @depends testBulkUpdateStatus + */ + public function testInstallModuleFromUrl(): void + { + $module = [ + 'technicalName' => 'ps_featuredproducts', + 'source' => 'https://github.com/PrestaShop/ps_featuredproducts/releases/download/v2.1.5/ps_featuredproducts.zip', + 'version' => '2.1.5', + ]; + + $bearerToken = $this->getBearerToken(['module_write']); + $response = static::createClient()->request('POST', sprintf('/module/%s/install', $module['technicalName']), [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'source' => $module['source'], + ], + ]); + + self::assertResponseStatusCodeSame(200); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // Check response from status update request + $expectedModuleInfos = [ + 'technicalName' => $module['technicalName'], + 'version' => $module['version'], + 'enabled' => true, + 'installed' => true, + ]; + + // Check response from status update request + $this->assertEquals($expectedModuleInfos, $decodedResponse); + } + private function getModuleInfos(string $technicalName): array { $bearerToken = $this->getBearerToken(['module_read']);