diff --git a/classes/Parameters/RestoreConfigurationValidator.php b/classes/Parameters/RestoreConfigurationValidator.php new file mode 100644 index 000000000..453841d78 --- /dev/null +++ b/classes/Parameters/RestoreConfigurationValidator.php @@ -0,0 +1,96 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\AutoUpgrade\Parameters; + +use PrestaShop\Module\AutoUpgrade\Backup\BackupFinder; +use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator; + +class RestoreConfigurationValidator +{ + /** + * @var Translator + */ + private $translator; + + /** + * @var BackupFinder + */ + private $backupFinder; + + public function __construct(Translator $translator, BackupFinder $backupFinder) + { + $this->translator = $translator; + $this->backupFinder = $backupFinder; + } + + /** + * @param array $array + * + * @return array + */ + public function validate(array $array = []): array + { + $errors = []; + + $backupNameErrors = $this->validateBackupName($array); + if ($backupNameErrors) { + $errors[] = [ + 'message' => $backupNameErrors, + 'target' => RestoreConfiguration::BACKUP_NAME, + ]; + + return $errors; + } + + $backupNameExistErrors = $this->validateBackupExist($array[RestoreConfiguration::BACKUP_NAME]); + if ($backupNameExistErrors) { + $errors[] = [ + 'message' => $backupNameExistErrors, + 'target' => RestoreConfiguration::BACKUP_NAME, + ]; + } + + return $errors; + } + + /** + * @param array $backupConfiguration + * + * @return string|null + */ + private function validateBackupName(array $backupConfiguration): ?string + { + if (empty($backupConfiguration[RestoreConfiguration::BACKUP_NAME])) { + return $this->translator->trans('Backup name is missing'); + } + + return null; + } + + private function validateBackupExist(string $backupName): ?string + { + if (!in_array($backupName, $this->backupFinder->getAvailableBackups())) { + return $this->translator->trans('Backup %s does not exist', [$backupName]); + } + + return null; + } +} diff --git a/classes/Router/Middlewares/RestoreConfigurationIsValid.php b/classes/Router/Middlewares/RestoreConfigurationIsValid.php new file mode 100644 index 000000000..b7c4b7ef5 --- /dev/null +++ b/classes/Router/Middlewares/RestoreConfigurationIsValid.php @@ -0,0 +1,39 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\AutoUpgrade\Router\Middlewares; + +use PrestaShop\Module\AutoUpgrade\Router\Routes; + +class RestoreConfigurationIsValid extends AbstractMiddleware +{ + public function process(): ?string + { + $restoreConfiguration = $this->upgradeContainer->getRestoreConfiguration(); + + $errors = $this->upgradeContainer->getRestoreConfigurationValidator()->validate($restoreConfiguration->toArray()); + + if (!empty($errors)) { + return Routes::RESTORE_PAGE_BACKUP_SELECTION; + } + + return null; + } +} diff --git a/classes/Router/Middlewares/RestoreIsConfigured.php b/classes/Router/Middlewares/RestoreIsConfigured.php new file mode 100644 index 000000000..d4a16a62f --- /dev/null +++ b/classes/Router/Middlewares/RestoreIsConfigured.php @@ -0,0 +1,32 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\AutoUpgrade\Router\Middlewares; + +use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames; +use PrestaShop\Module\AutoUpgrade\Router\Routes; + +class RestoreIsConfigured extends AbstractMiddleware +{ + public function process(): ?string + { + return $this->upgradeContainer->getFileStorage()->exists(UpgradeFileNames::RESTORE_CONFIG_FILENAME) ? null : Routes::RESTORE_PAGE_BACKUP_SELECTION; + } +} diff --git a/classes/Router/RoutesConfig.php b/classes/Router/RoutesConfig.php index 444d5b15f..d76926e70 100644 --- a/classes/Router/RoutesConfig.php +++ b/classes/Router/RoutesConfig.php @@ -36,6 +36,8 @@ use PrestaShop\Module\AutoUpgrade\Router\Middlewares\BackupChoiceHasBeenMade; use PrestaShop\Module\AutoUpgrade\Router\Middlewares\HasBackupAvailable; use PrestaShop\Module\AutoUpgrade\Router\Middlewares\LocalChannelXmlAndZipAreValid; +use PrestaShop\Module\AutoUpgrade\Router\Middlewares\RestoreConfigurationIsValid; +use PrestaShop\Module\AutoUpgrade\Router\Middlewares\RestoreIsConfigured; use PrestaShop\Module\AutoUpgrade\Router\Middlewares\RestoreLogExists; use PrestaShop\Module\AutoUpgrade\Router\Middlewares\UpdateIsConfigured; use PrestaShop\Module\AutoUpgrade\Router\Middlewares\UpdateLogExists; @@ -204,6 +206,11 @@ class RoutesConfig Routes::RESTORE_PAGE_RESTORE => [ 'controller' => RestorePageRestoreController::class, 'method' => 'index', + 'middleware' => [ + HasBackupAvailable::class, + RestoreIsConfigured::class, + RestoreConfigurationIsValid::class, + ], ], Routes::RESTORE_STEP_RESTORE => [ 'controller' => RestorePageRestoreController::class, diff --git a/classes/UpgradeContainer.php b/classes/UpgradeContainer.php index bc9062187..985de2ba9 100644 --- a/classes/UpgradeContainer.php +++ b/classes/UpgradeContainer.php @@ -32,6 +32,7 @@ use PrestaShop\Module\AutoUpgrade\Parameters\FileStorage; use PrestaShop\Module\AutoUpgrade\Parameters\LocalChannelConfigurationValidator; use PrestaShop\Module\AutoUpgrade\Parameters\RestoreConfiguration; +use PrestaShop\Module\AutoUpgrade\Parameters\RestoreConfigurationValidator; use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration; use PrestaShop\Module\AutoUpgrade\Progress\CompletionCalculator; use PrestaShop\Module\AutoUpgrade\Repository\LocalArchiveRepository; @@ -194,6 +195,11 @@ class UpgradeContainer /** @var LocalChannelConfigurationValidator */ private $localChannelConfigurationValidator; + /** + * @var RestoreConfigurationValidator + */ + private $restoreConfigurationValidator; + /** @var PrestashopVersionService */ private $prestashopVersionService; @@ -890,6 +896,18 @@ public function getLocalChannelConfigurationValidator(): LocalChannelConfigurati return $this->localChannelConfigurationValidator; } + public function getRestoreConfigurationValidator(): RestoreConfigurationValidator + { + if (null === $this->restoreConfigurationValidator) { + $this->restoreConfigurationValidator = new RestoreConfigurationValidator( + $this->getTranslator(), + $this->getBackupFinder() + ); + } + + return $this->restoreConfigurationValidator; + } + /** * @return PrestashopVersionService */ diff --git a/tests/unit/Parameters/RestoreConfigurationValidatorTest.php b/tests/unit/Parameters/RestoreConfigurationValidatorTest.php new file mode 100644 index 000000000..ad93b7554 --- /dev/null +++ b/tests/unit/Parameters/RestoreConfigurationValidatorTest.php @@ -0,0 +1,82 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +use PHPUnit\Framework\TestCase; +use PrestaShop\Module\AutoUpgrade\Backup\BackupFinder; +use PrestaShop\Module\AutoUpgrade\Parameters\RestoreConfiguration; +use PrestaShop\Module\AutoUpgrade\Parameters\RestoreConfigurationValidator; +use PrestaShop\Module\AutoUpgrade\UpgradeContainer; + +class RestoreConfigurationValidatorTest extends TestCase +{ + /** + * @var RestoreConfigurationValidator + */ + private $validator; + + private $backupFinderMock; + + protected function setUp(): void + { + $this->container = new UpgradeContainer('/html', '/html/admin'); + + $this->backupFinderMock = $this->createMock(BackupFinder::class); + + $this->validator = new RestoreConfigurationValidator( + $this->container->getTranslator(), + $this->backupFinderMock + ); + } + + public function testValidateReturnsErrorWhenBackupNameIsMissing(): void + { + $errors = $this->validator->validate([]); + + $this->assertCount(1, $errors); + $this->assertSame(['message' => 'Backup name is missing', 'target' => RestoreConfiguration::BACKUP_NAME], $errors[0]); + } + + public function testValidateReturnsErrorWhenBackupDoesNotExist(): void + { + $backupName = 'non_existing_backup.zip'; + + $this->backupFinderMock + ->method('getAvailableBackups') + ->willReturn(['existing_backup.zip']); + + $errors = $this->validator->validate([RestoreConfiguration::BACKUP_NAME => $backupName]); + + $this->assertCount(1, $errors); + $this->assertSame(['message' => 'Backup non_existing_backup.zip does not exist', 'target' => RestoreConfiguration::BACKUP_NAME], $errors[0]); + } + + public function testValidateReturnsNoErrorsWhenBackupIsValid(): void + { + $backupName = 'existing_backup.zip'; + + $this->backupFinderMock + ->method('getAvailableBackups') + ->willReturn([$backupName]); + + $errors = $this->validator->validate([RestoreConfiguration::BACKUP_NAME => $backupName]); + + $this->assertCount(0, $errors); + } +}