diff --git a/src/ApiPlatform/Resources/Module/UpgradeModule.php b/src/ApiPlatform/Resources/Module/UpgradeModule.php new file mode 100644 index 0000000..bd3ff14 --- /dev/null +++ b/src/ApiPlatform/Resources/Module/UpgradeModule.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License version 3.0 + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA and Contributors <contact@prestashop.com> + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Module; + +use ApiPlatform\Metadata\ApiResource; +use PrestaShop\PrestaShop\Core\Domain\Module\Command\UpgradeModuleCommand; +use PrestaShop\PrestaShop\Core\Domain\Module\Query\GetModuleInfos; +use PrestaShopBundle\ApiPlatform\Metadata\CQRSUpdate; + +#[ApiResource( + operations: [ + new CQRSUpdate( + uriTemplate: '/module/{technicalName}/upgrade', + CQRSCommand: UpgradeModuleCommand::class, + CQRSQuery: GetModuleInfos::class, + scopes: [ + 'module_write', + ], + ), + ], +)] +class UpgradeModule extends Module +{ +} diff --git a/tests/Integration/ApiPlatform/ModuleEndpointTest.php b/tests/Integration/ApiPlatform/ModuleEndpointTest.php index 9a7e431..bd70554 100644 --- a/tests/Integration/ApiPlatform/ModuleEndpointTest.php +++ b/tests/Integration/ApiPlatform/ModuleEndpointTest.php @@ -89,6 +89,11 @@ public function getProtectedEndpoints(): iterable 'multipart/form-data', ]; + yield 'upgrade' => [ + 'PUT', + '/module/{technicalName}/upgrade', + ]; + yield 'uninstall module' => [ 'PUT', '/module/{technicalName}/uninstall', @@ -646,6 +651,93 @@ public function testBulkUninstallModule() } } + public function testUpgradeModule(): void + { + $bearerToken = $this->getBearerToken(['module_write']); + + // Upload Zip from GitHub with version 2.1.2 the module is present but not installed + $response = static::createClient()->request('POST', '/module/upload-source', [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'source' => 'https://github.com/PrestaShop/dashproducts/releases/download/v2.1.2/dashproducts.zip', + ], + ]); + self::assertResponseStatusCodeSame(201); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // The returned response and the GET infos response should be identical + $module212 = [ + 'moduleId' => null, + 'technicalName' => 'dashproducts', + 'moduleVersion' => '2.1.2', + // Module is simply uploaded not installed + 'installedVersion' => null, + 'enabled' => false, + 'installed' => false, + ]; + $this->assertEquals($module212, $decodedResponse); + $this->assertEquals($module212, $this->getModuleInfos($module212['technicalName'])); + + // Now we install the module + $response = static::createClient()->request('PUT', sprintf('/module/%s/install', $module212['technicalName']), [ + 'auth_bearer' => $bearerToken, + // We must define a JSON body even if it is empty, we need to search how to make this optional + 'json' => [ + ], + ]); + self::assertResponseStatusCodeSame(200); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // The ID is dynamic, so we fetch it after creation + $this->assertArrayHasKey('moduleId', $decodedResponse); + $module212['moduleId'] = $decodedResponse['moduleId']; + $module212['installed'] = true; + $module212['enabled'] = true; + $module212['installedVersion'] = '2.1.2'; + $this->assertEquals($module212, $decodedResponse); + $this->assertEquals($module212, $this->getModuleInfos($module212['technicalName'])); + + // Now upload the source for version 2.1.3, the module version is updated but not the installed one + $response = static::createClient()->request('POST', '/module/upload-source', [ + 'auth_bearer' => $bearerToken, + 'json' => [ + 'source' => 'https://github.com/PrestaShop/dashproducts/releases/download/v2.1.3/dashproducts.zip', + ], + ]); + self::assertResponseStatusCodeSame(201); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + $module213 = [ + 'moduleId' => $module212['moduleId'], + 'technicalName' => 'dashproducts', + 'moduleVersion' => '2.1.3', + // Module is simply uploaded not installed + 'installedVersion' => '2.1.2', + 'enabled' => true, + 'installed' => true, + ]; + $this->assertEquals($module213, $decodedResponse); + $this->assertEquals($module213, $this->getModuleInfos($module213['technicalName'])); + + $response = static::createClient()->request('PUT', sprintf('/module/%s/upgrade', $module212['technicalName']), [ + 'auth_bearer' => $bearerToken, + // We must define a JSON body even if it is empty, we need to search how to make this optional + 'json' => [ + ], + ]); + self::assertResponseStatusCodeSame(200); + $decodedResponse = json_decode($response->getContent(), true); + $this->assertNotFalse($decodedResponse); + + // Check response from status upgrade request + $module213['installedVersion'] = '2.1.3'; + $this->assertEquals($module213, $decodedResponse); + $this->assertEquals($module213, $this->getModuleInfos($module213['technicalName'])); + } + private function getModuleInfos(string $technicalName): array { $bearerToken = $this->getBearerToken(['module_read']);