diff --git a/.codecov.yml b/.codecov.yml index 5a0f31e5..896cf821 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -6,6 +6,7 @@ coverage: ignore: - "**/*Dto.php" - "src/Codebase/Application/Dto/*.php" + - "src/ReleaseApp/Domain/Entities/*.php" - "src/DynamicEvaluator/**/Dto/*.php" - "src/DynamicEvaluator/Presentation/**.php" - "src/ReleaseApp/Infrastructure/Shared/Dto/*.php" diff --git a/config/Upgrade/services.yaml b/config/Upgrade/services.yaml index 475876ae..5fe81709 100644 --- a/config/Upgrade/services.yaml +++ b/config/Upgrade/services.yaml @@ -99,10 +99,13 @@ services: class: Upgrade\Application\Strategy\Common\Step\SendReportStep feature_dev_master.fixer: - class: Upgrade\Application\Strategy\Composer\Fixer\FeatureDevMasterPackageFixerStep + class: Upgrade\Application\Strategy\Composer\Fixer\FeatureDevMasterPackageUpgradeFixer feature_package.fixer: - class: Upgrade\Application\Strategy\Composer\Fixer\FeaturePackageFixerStep + class: Upgrade\Application\Strategy\Composer\Fixer\FeaturePackageUpgradeFixer + + backport.fixer: + class: Upgrade\Application\Strategy\Composer\Fixer\BackportUpgradeFixer composer.step_executor: class: Upgrade\Application\Executor\StepExecutor @@ -127,8 +130,6 @@ services: - '@create_pr.step' - '@checkout.step' - '@send_report.step' - - - '@feature_dev_master.fixer' - - '@feature_package.fixer' composer.strategy: class: Upgrade\Application\Strategy\Composer\ComposerStrategy @@ -153,8 +154,14 @@ services: - '@create_pr.step' - '@checkout.step' - '@send_report.step' + release_group_upgrader.upgrader: + class: Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupUpgrader + arguments: + - '@Upgrade\Application\Strategy\ReleaseApp\Processor\ModuleFetcher' + - '@monolog.logger' - - '@feature_dev_master.fixer' - '@feature_package.fixer' + - '@backport.fixer' create_empty_pr.step_executor: class: Upgrade\Application\Executor\StepExecutor @@ -300,7 +307,7 @@ services: arguments: - '@Upgrade\Application\Strategy\ReleaseApp\Validator\ReleaseGroupSoftValidator' - '@Upgrade\Application\Strategy\ReleaseApp\Validator\ThresholdSoftValidator' - - '@Upgrade\Application\Strategy\ReleaseApp\Processor\ModuleFetcher' + - '@release_group_upgrader.upgrader' - '@Upgrade\Application\Strategy\ReleaseApp\ReleaseGroupFilter\ReleaseGroupFilter' - '@event_dispatcher' diff --git a/src/PackageStorage/Application/Metric/ModuleStatisticUpdater.php b/src/PackageStorage/Application/Metric/ModuleStatisticUpdater.php index 5ffd6c6d..30f9477b 100644 --- a/src/PackageStorage/Application/Metric/ModuleStatisticUpdater.php +++ b/src/PackageStorage/Application/Metric/ModuleStatisticUpdater.php @@ -71,7 +71,7 @@ public function updateStatisticPostRequire(StepsResponseDto $stepsResponseDto): } } - $stepsResponseDto->getModelStatisticDto()->setIntersectingModels($intersectedModuleNames); + $stepsResponseDto->getModelStatisticDto()->setIntersectingModules($intersectedModuleNames); $stepsResponseDto->getModelStatisticDto()->setTotalIntersectingModels($totalIntersectingModels); return $stepsResponseDto; diff --git a/src/ReleaseApp/Domain/Entities/UpgradeInstructionsReleaseGroup.php b/src/ReleaseApp/Domain/Entities/UpgradeInstructionsReleaseGroup.php index 105f20f7..7eea3f85 100644 --- a/src/ReleaseApp/Domain/Entities/UpgradeInstructionsReleaseGroup.php +++ b/src/ReleaseApp/Domain/Entities/UpgradeInstructionsReleaseGroup.php @@ -22,6 +22,11 @@ class UpgradeInstructionsReleaseGroup */ protected const MODULES_KEY = 'modules'; + /** + * @var string + */ + protected const BACKPORTS_KEY = 'backports'; + /** * @var string */ @@ -92,6 +97,11 @@ class UpgradeInstructionsReleaseGroup */ protected ?UpgradeInstructionModuleCollection $moduleCollection = null; + /** + * @var \ReleaseApp\Domain\Entities\Collection\UpgradeInstructionModuleCollection|null + */ + protected ?UpgradeInstructionModuleCollection $backportModuleCollection = null; + /** * @var \ReleaseApp\Domain\Entities\UpgradeInstructionMeta|null */ @@ -185,6 +195,27 @@ public function getModuleCollection(): UpgradeInstructionModuleCollection return $this->moduleCollection; } + /** + * @return \ReleaseApp\Domain\Entities\Collection\UpgradeInstructionModuleCollection + */ + public function getBackportModuleCollection(): UpgradeInstructionModuleCollection + { + if ($this->backportModuleCollection) { + return $this->backportModuleCollection; + } + + $moduleList = []; + if (!isset($this->body[static::BACKPORTS_KEY])) { + return new UpgradeInstructionModuleCollection(); + } + foreach ($this->body[static::BACKPORTS_KEY] as $name => $moduleData) { + $moduleList[] = new UpgradeInstructionModule($moduleData, $name); + } + $this->backportModuleCollection = new UpgradeInstructionModuleCollection($moduleList); + + return $this->backportModuleCollection; + } + /** * @return \ReleaseApp\Domain\Entities\UpgradeInstructionMeta|null */ diff --git a/src/ReleaseApp/Infrastructure/Shared/Dto/ReleaseGroupDto.php b/src/ReleaseApp/Infrastructure/Shared/Dto/ReleaseGroupDto.php index 9f25a1e1..22742808 100644 --- a/src/ReleaseApp/Infrastructure/Shared/Dto/ReleaseGroupDto.php +++ b/src/ReleaseApp/Infrastructure/Shared/Dto/ReleaseGroupDto.php @@ -79,10 +79,16 @@ class ReleaseGroupDto */ protected bool $manualActionNeeded; + /** + * @var \ReleaseApp\Infrastructure\Shared\Dto\Collection\ModuleDtoCollection + */ + protected ModuleDtoCollection $backportModuleCollection; + /** * @param int $id * @param string $name * @param \ReleaseApp\Infrastructure\Shared\Dto\Collection\ModuleDtoCollection $moduleCollection + * @param \ReleaseApp\Infrastructure\Shared\Dto\Collection\ModuleDtoCollection $backportModuleCollection * @param \DateTimeInterface $released * @param bool $containsProjectChanges * @param string $link @@ -96,6 +102,7 @@ public function __construct( int $id, string $name, ModuleDtoCollection $moduleCollection, + ModuleDtoCollection $backportModuleCollection, DateTimeInterface $released, bool $containsProjectChanges, string $link, @@ -110,6 +117,7 @@ public function __construct( $this->released = $released; $this->link = $link; $this->moduleCollection = $moduleCollection; + $this->backportModuleCollection = $backportModuleCollection; $this->containsProjectChanges = $containsProjectChanges; $this->hasConflict = $hasConflict; $this->rating = $rating; @@ -144,6 +152,14 @@ public function setModuleCollection(ModuleDtoCollection $moduleCollection): void $this->moduleCollection = $moduleCollection; } + /** + * @return \ReleaseApp\Infrastructure\Shared\Dto\Collection\ModuleDtoCollection + */ + public function getBackportModuleCollection(): ModuleDtoCollection + { + return $this->backportModuleCollection; + } + /** * @return bool */ diff --git a/src/ReleaseApp/Infrastructure/Shared/Mapper/ReleaseGroupDtoCollectionMapper.php b/src/ReleaseApp/Infrastructure/Shared/Mapper/ReleaseGroupDtoCollectionMapper.php index 24bc3bda..99940ff0 100644 --- a/src/ReleaseApp/Infrastructure/Shared/Mapper/ReleaseGroupDtoCollectionMapper.php +++ b/src/ReleaseApp/Infrastructure/Shared/Mapper/ReleaseGroupDtoCollectionMapper.php @@ -73,6 +73,7 @@ protected function mapReleaseGroupDto(UpgradeInstructionsReleaseGroup $releaseGr $releaseGroup->getId(), $releaseGroup->getName(), $this->buildModuleTransferCollection($releaseGroup), + $this->buildBackportModuleTransferCollection($releaseGroup), $releaseGroup->getReleased(), $releaseGroup->hasProjectChanges(), $this->getReleaseGroupLink($releaseGroup->getId()), @@ -111,6 +112,24 @@ protected function buildModuleTransferCollection(UpgradeInstructionsReleaseGroup return $dataProviderModuleCollection; } + /** + * @param \ReleaseApp\Domain\Entities\UpgradeInstructionsReleaseGroup $releaseGroup + * + * @return \ReleaseApp\Infrastructure\Shared\Dto\Collection\ModuleDtoCollection + */ + protected function buildBackportModuleTransferCollection(UpgradeInstructionsReleaseGroup $releaseGroup): ModuleDtoCollection + { + $releaseGroupModuleCollection = $releaseGroup->getBackportModuleCollection(); + + $dataProviderModuleCollection = new ModuleDtoCollection(); + foreach ($releaseGroupModuleCollection->toArray() as $module) { + $dataProviderModule = new ModuleDto($module->getName(), $module->getVersion(), $module->getType()); + $dataProviderModuleCollection->add($dataProviderModule); + } + + return $dataProviderModuleCollection; + } + /** * @param int $id * diff --git a/src/Upgrade/Application/Dto/ModelStatisticDto.php b/src/Upgrade/Application/Dto/ModelStatisticDto.php index 283e2c3a..5347f4d4 100644 --- a/src/Upgrade/Application/Dto/ModelStatisticDto.php +++ b/src/Upgrade/Application/Dto/ModelStatisticDto.php @@ -29,20 +29,20 @@ class ModelStatisticDto /** * @var array */ - protected array $intersectingModels = []; + protected array $intersectingModules = []; /** * @param int $totalOverwrittenModels * @param int $totalChangedModels * @param int $totalIntersectingModels - * @param array $intersectingModels + * @param array $intersectingModules */ - public function __construct(int $totalOverwrittenModels = 0, int $totalChangedModels = 0, int $totalIntersectingModels = 0, array $intersectingModels = []) + public function __construct(int $totalOverwrittenModels = 0, int $totalChangedModels = 0, int $totalIntersectingModels = 0, array $intersectingModules = []) { $this->totalOverwrittenModels = $totalOverwrittenModels; $this->totalChangedModels = $totalChangedModels; $this->totalIntersectingModels = $totalIntersectingModels; - $this->intersectingModels = $intersectingModels; + $this->intersectingModules = $intersectingModules; } /** @@ -102,18 +102,18 @@ public function setTotalIntersectingModels(int $totalIntersectingModels): void /** * @return array */ - public function getIntersectingModels(): array + public function getIntersectingModules(): array { - return $this->intersectingModels; + return $this->intersectingModules; } /** - * @param array $intersectingModels + * @param array $intersectingModules * * @return void */ - public function setIntersectingModels(array $intersectingModels): void + public function setIntersectingModules(array $intersectingModules): void { - $this->intersectingModels = $intersectingModels; + $this->intersectingModules = $intersectingModules; } } diff --git a/src/Upgrade/Application/Dto/StepsResponseDto.php b/src/Upgrade/Application/Dto/StepsResponseDto.php index a87981eb..bd559d9b 100644 --- a/src/Upgrade/Application/Dto/StepsResponseDto.php +++ b/src/Upgrade/Application/Dto/StepsResponseDto.php @@ -98,9 +98,9 @@ class StepsResponseDto extends ResponseDto protected ModelStatisticDto $modelStatisticDto; /** - * @var int + * @var \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto|null */ - protected int $currentReleaseGroupId = self::UNDEFINED_RELEASE_GROUP_ID; + protected ?ReleaseGroupDto $currentReleaseGroup = null; /** * @var bool @@ -262,7 +262,7 @@ public function getIntegratorResponseDtoByReleaseGroupId(int $releaseGroupId): ? */ public function addIntegratorResponseDto(IntegratorResponseDto $integratorResponseDto): void { - $this->integratorResponseCollection[$this->currentReleaseGroupId] = $integratorResponseDto; + $this->integratorResponseCollection[$this->getCurrentReleaseGroupId()] = $integratorResponseDto; } /** @@ -292,7 +292,7 @@ public function setPullRequestId(?int $pullRequestId) */ public function addBlocker(ValidatorViolationDto $blockerInfo): void { - $currentReleaseGroupId = $this->currentReleaseGroupId; + $currentReleaseGroupId = $this->getCurrentReleaseGroupId(); if (!isset($this->blockers[$currentReleaseGroupId])) { $this->blockers[$currentReleaseGroupId] = []; @@ -308,7 +308,7 @@ public function addBlocker(ValidatorViolationDto $blockerInfo): void */ public function removeBlockersByTitle(string $title): void { - $currentReleaseGroupId = $this->currentReleaseGroupId; + $currentReleaseGroupId = $this->getCurrentReleaseGroupId(); if (!isset($this->blockers[$currentReleaseGroupId])) { return; @@ -413,7 +413,7 @@ public function getLastAppliedReleaseGroup(): ?ReleaseGroupDto } /** - * @return array<\ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto> + * @return array */ public function getAppliedReleaseGroups(): array { @@ -441,22 +441,30 @@ public function addAppliedReleaseGroup(ReleaseGroupDto $appliedReleaseGroup): vo $this->appliedReleaseGroups[$appliedReleaseGroup->getId()] = $appliedReleaseGroup; } + /** + * @return \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto|null + */ + public function getCurrentReleaseGroup(): ?ReleaseGroupDto + { + return $this->currentReleaseGroup; + } + /** * @return int */ public function getCurrentReleaseGroupId(): int { - return $this->currentReleaseGroupId; + return $this->currentReleaseGroup ? $this->currentReleaseGroup->getId() : static::UNDEFINED_RELEASE_GROUP_ID; } /** - * @param int $currentReleaseGroupId + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $currentReleaseGroup * * @return void */ - public function setCurrentReleaseGroupId(int $currentReleaseGroupId): void + public function setCurrentReleaseGroup(ReleaseGroupDto $currentReleaseGroup): void { - $this->currentReleaseGroupId = $currentReleaseGroupId; + $this->currentReleaseGroup = $currentReleaseGroup; } /** @@ -484,7 +492,7 @@ public function getViolationsByReleaseGroupId(int $releaseGroupId): array */ public function addViolation(ViolationDtoInterface $violation): void { - $currentReleaseGroupId = $this->currentReleaseGroupId; + $currentReleaseGroupId = $this->getCurrentReleaseGroupId(); if (!isset($this->violations[$currentReleaseGroupId])) { $this->violations[$currentReleaseGroupId] = []; diff --git a/src/Upgrade/Application/Executor/StepExecutor.php b/src/Upgrade/Application/Executor/StepExecutor.php index 35531c8d..4a24f543 100644 --- a/src/Upgrade/Application/Executor/StepExecutor.php +++ b/src/Upgrade/Application/Executor/StepExecutor.php @@ -26,21 +26,14 @@ class StepExecutor implements StepExecutorInterface */ protected array $steps = []; - /** - * @var array<\Upgrade\Application\Strategy\FixerStepInterface> - */ - protected array $fixers = []; - /** * @param \Psr\Log\LoggerInterface $logger * @param array<\Upgrade\Application\Strategy\StepInterface> $steps - * @param array<\Upgrade\Application\Strategy\FixerStepInterface> $fixers */ - public function __construct(LoggerInterface $logger, array $steps = [], array $fixers = []) + public function __construct(LoggerInterface $logger, array $steps = []) { $this->logger = $logger; $this->steps = $steps; - $this->fixers = $fixers; } /** @@ -56,13 +49,6 @@ public function execute(StepsResponseDto $stepsResponseDto): StepsResponseDto $this->logger->info(sprintf('Run step `%s`', $this->getStepName($step))); $stepsResponseDto = $step->run($stepsResponseDto); - if (!$stepsResponseDto->getIsSuccessful()) { - $this->logger->info( - sprintf('Step `%s` is failed. Trying to fix it', $this->getStepName($step)), - [$stepsResponseDto->getOutputMessage()], - ); - $stepsResponseDto = $this->runWithFixer($step, $stepsResponseDto); - } if ($stepsResponseDto->isSuccessful() && $stepsResponseDto->getIsStopPropagation()) { $this->logger->info(sprintf('Stop propagation from step`%s`', $this->getStepName($step)), [$stepsResponseDto]); @@ -88,43 +74,6 @@ public function execute(StepsResponseDto $stepsResponseDto): StepsResponseDto return $stepsResponseDto; } - /** - * @param \Upgrade\Application\Strategy\StepInterface $step - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsResponseDto - * - * @return \Upgrade\Application\Dto\StepsResponseDto - */ - protected function runWithFixer(StepInterface $step, StepsResponseDto $stepsResponseDto): StepsResponseDto - { - $this->logger->info(sprintf('Try to fix step `%s`', $this->getStepName($step))); - foreach ($this->fixers as $fixer) { - if (!$fixer->isApplicable($stepsResponseDto)) { - $this->logger->info(sprintf('Fixer `%s` is not applicable', get_class($fixer))); - - continue; - } - $stepsResponseDto->addOutputMessage('Step is failed. It will be reapplied with a fixer'); - - $this->logger->info(sprintf('Run fixer `%s`', get_class($fixer))); - $stepsResponseDto = $fixer->run($stepsResponseDto); - if (!$stepsResponseDto->getIsSuccessful()) { - $this->logger->warning(sprintf('Fixer `%s` is failed', get_class($fixer))); - - continue; - } - - $stepsResponseDto->setError(null); - - $this->logger->info(sprintf('Run step `%s` after fixer', $this->getStepName($step))); - $stepsResponseDto = $step->run($stepsResponseDto); - if ($stepsResponseDto->getIsSuccessful()) { - break; - } - } - - return $stepsResponseDto; - } - /** * @param \Upgrade\Application\Strategy\StepInterface $step * diff --git a/src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageFixerStep.php b/src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageUpgradeFixer.php similarity index 51% rename from src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageFixerStep.php rename to src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageUpgradeFixer.php index 90ca3d5f..8ac7a3ee 100644 --- a/src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageFixerStep.php +++ b/src/Upgrade/Application/Strategy/Composer/Fixer/AbstractFeaturePackageUpgradeFixer.php @@ -9,12 +9,18 @@ namespace Upgrade\Application\Strategy\Composer\Fixer; +use ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto; use Upgrade\Application\Adapter\PackageManagerAdapterInterface; -use Upgrade\Application\Dto\StepsResponseDto; -use Upgrade\Application\Strategy\FixerStepInterface; +use Upgrade\Application\Dto\PackageManagerResponseDto; +use Upgrade\Application\Strategy\UpgradeFixerInterface; -abstract class AbstractFeaturePackageFixerStep implements FixerStepInterface +abstract class AbstractFeaturePackageUpgradeFixer implements UpgradeFixerInterface { + /** + * @var bool + */ + protected const RE_RUN_STEP = true; + /** * @var string */ @@ -39,14 +45,23 @@ public function __construct(PackageManagerAdapterInterface $packageManager) } /** - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsExecutionDto + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto * * @return bool */ - public function isApplicable(StepsResponseDto $stepsExecutionDto): bool + public function isApplicable(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): bool + { + return !$packageManagerResponseDto->isSuccessful() && + $packageManagerResponseDto->getOutputMessage() !== null && + preg_match(static::FEATURE_PACKAGE_PATTERN, $packageManagerResponseDto->getOutputMessage()); + } + + /** + * @return bool + */ + public function isReRunStep(): bool { - return !$stepsExecutionDto->getIsSuccessful() && - $stepsExecutionDto->getOutputMessage() !== null && - preg_match(static::FEATURE_PACKAGE_PATTERN, $stepsExecutionDto->getOutputMessage()); + return static::RE_RUN_STEP; } } diff --git a/src/Upgrade/Application/Strategy/Composer/Fixer/BackportUpgradeFixer.php b/src/Upgrade/Application/Strategy/Composer/Fixer/BackportUpgradeFixer.php new file mode 100644 index 00000000..a6eb40b5 --- /dev/null +++ b/src/Upgrade/Application/Strategy/Composer/Fixer/BackportUpgradeFixer.php @@ -0,0 +1,79 @@ +isSuccessful() && $releaseGroup->getBackportModuleCollection()->count(); + } + + /** + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto + * + * @return \Upgrade\Application\Dto\PackageManagerResponseDto|null + */ + public function run(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): ?PackageManagerResponseDto + { + return $this->packageManager->require($this->getPackageCollectionWithBackports($releaseGroup)); + } + + /** + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroupDto + * + * @return \Upgrade\Domain\Entity\Collection\PackageCollection + */ + protected function getPackageCollectionWithBackports(ReleaseGroupDto $releaseGroupDto): PackageCollection + { + $moduleCollection = $releaseGroupDto->getModuleCollection(); + $backportModuleCollection = $releaseGroupDto->getBackportModuleCollection(); + $packages = []; + foreach ($moduleCollection->toArray() as $moduleDto) { + $packageName = $moduleDto->getName(); + $packages[$packageName] = new Package($packageName, $moduleDto->getVersion()); + } + foreach ($backportModuleCollection->toArray() as $moduleDto) { + $packageName = $moduleDto->getName(); + if (!isset($packages[$packageName])) { + continue; + } + $packages[$packageName] = new Package($packageName, $moduleDto->getVersion()); + } + + return new PackageCollection(array_values($packages)); + } +} diff --git a/src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStep.php b/src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixer.php similarity index 50% rename from src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStep.php rename to src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixer.php index 2e62a766..db3d65a3 100644 --- a/src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStep.php +++ b/src/Upgrade/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixer.php @@ -9,13 +9,13 @@ namespace Upgrade\Application\Strategy\Composer\Fixer; +use ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto; use Upgrade\Application\Adapter\PackageManagerAdapterInterface; -use Upgrade\Application\Dto\StepsResponseDto; -use Upgrade\Application\Factory\ComposerViolationDtoFactory; +use Upgrade\Application\Dto\PackageManagerResponseDto; use Upgrade\Domain\Entity\Collection\PackageCollection; use Upgrade\Domain\Entity\Package; -class FeatureDevMasterPackageFixerStep extends AbstractFeaturePackageFixerStep +class FeatureDevMasterPackageUpgradeFixer extends AbstractFeaturePackageUpgradeFixer { /** * @var string @@ -39,26 +39,28 @@ public function __construct(PackageManagerAdapterInterface $packageManager, bool } /** - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsExecutionDto + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto * * @return bool */ - public function isApplicable(StepsResponseDto $stepsExecutionDto): bool + public function isApplicable(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): bool { - return $this->isFeatureToDevMasterEnabled && parent::isApplicable($stepsExecutionDto); + return $this->isFeatureToDevMasterEnabled && parent::isApplicable($releaseGroup, $packageManagerResponseDto); } /** - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsExecutionDto + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto * - * @return \Upgrade\Application\Dto\StepsResponseDto + * @return \Upgrade\Application\Dto\PackageManagerResponseDto|null */ - public function run(StepsResponseDto $stepsExecutionDto): StepsResponseDto + public function run(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): ?PackageManagerResponseDto { - preg_match_all(static::FEATURE_PACKAGE_PATTERN, (string)$stepsExecutionDto->getOutputMessage(), $matches); + preg_match_all(static::FEATURE_PACKAGE_PATTERN, (string)$packageManagerResponseDto->getOutputMessage(), $matches); if (!isset($matches[static::KEY_FEATURES]) || !$matches[static::KEY_FEATURES] || !is_array($matches[static::KEY_FEATURES])) { - return $stepsExecutionDto; + return null; } $version = sprintf( @@ -71,27 +73,6 @@ public function run(StepsResponseDto $stepsExecutionDto): StepsResponseDto $matches[static::KEY_FEATURES], )); - $responseDto = $this->packageManager->require($packageCollection); - - $stepsExecutionDto->setIsSuccessful($responseDto->isSuccessful()); - - if (!$responseDto->isSuccessful()) { - $stepsExecutionDto->addOutputMessage($responseDto->getOutputMessage()); - - return $stepsExecutionDto; - } - $messages = $stepsExecutionDto->getOutputMessages(); - $foundMessages = (array)preg_grep(static::FEATURE_PACKAGE_PATTERN, $messages); - foreach ($foundMessages as $key => $foundMessage) { - unset($messages[$key]); - } - $stepsExecutionDto->setOutputMessages($messages); - $stepsExecutionDto->addOutputMessage(sprintf('Versions were changed to %s for %s feature package(s)', static::MASK_ALIAS_DEV_MASTER, count($matches[static::KEY_FEATURES]))); - - if ($stepsExecutionDto->getIsSuccessful()) { - $stepsExecutionDto->removeBlockersByTitle(ComposerViolationDtoFactory::VIOLATION_TITLE); - } - - return $stepsExecutionDto; + return $this->packageManager->require($packageCollection); } } diff --git a/src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageFixerStep.php b/src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixer.php similarity index 59% rename from src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageFixerStep.php rename to src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixer.php index 195ef06c..b7533822 100644 --- a/src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageFixerStep.php +++ b/src/Upgrade/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixer.php @@ -9,13 +9,13 @@ namespace Upgrade\Application\Strategy\Composer\Fixer; +use ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto; use Upgrade\Application\Adapter\PackageManagerAdapterInterface; -use Upgrade\Application\Dto\StepsResponseDto; -use Upgrade\Application\Factory\ComposerViolationDtoFactory; +use Upgrade\Application\Dto\PackageManagerResponseDto; use Upgrade\Domain\Entity\Collection\PackageCollection; use Upgrade\Domain\Entity\Package; -class FeaturePackageFixerStep extends AbstractFeaturePackageFixerStep +class FeaturePackageUpgradeFixer extends AbstractFeaturePackageUpgradeFixer { /** * @var bool @@ -34,70 +34,50 @@ public function __construct(PackageManagerAdapterInterface $packageManager, bool } /** - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsExecutionDto + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto * * @return bool */ - public function isApplicable(StepsResponseDto $stepsExecutionDto): bool + public function isApplicable(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): bool { if ($this->isReleaseGroupIntegratorEnabled) { return false; } - return parent::isApplicable($stepsExecutionDto); + return parent::isApplicable($releaseGroup, $packageManagerResponseDto); } /** - * @param \Upgrade\Application\Dto\StepsResponseDto $stepsExecutionDto + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $packageManagerResponseDto * - * @return \Upgrade\Application\Dto\StepsResponseDto + * @return \Upgrade\Application\Dto\PackageManagerResponseDto|null */ - public function run(StepsResponseDto $stepsExecutionDto): StepsResponseDto + public function run(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $packageManagerResponseDto): ?PackageManagerResponseDto { - $messages = $stepsExecutionDto->getOutputMessages(); - $foundMessages = (array)preg_grep(static::FEATURE_PACKAGE_PATTERN, $messages); - preg_match_all(static::FEATURE_PACKAGE_PATTERN, (string)$stepsExecutionDto->getOutputMessage(), $matches); + preg_match_all(static::FEATURE_PACKAGE_PATTERN, (string)$packageManagerResponseDto->getOutputMessage(), $matches); if (empty($matches[static::KEY_FEATURES]) || !is_array($matches[static::KEY_FEATURES])) { - return $stepsExecutionDto; + return null; } $featurePackages = $this->getPackagesFromFeatures($matches[static::KEY_FEATURES]); $packageCollection = new PackageCollection($featurePackages); - $responseDto = $this->packageManager->require($packageCollection); + $response = $this->packageManager->require($packageCollection); - $stepsExecutionDto->setIsSuccessful($responseDto->isSuccessful()); - if (!$responseDto->isSuccessful()) { - $stepsExecutionDto->addOutputMessage($responseDto->getOutputMessage()); - - return $stepsExecutionDto; + if (!$response->isSuccessful()) { + return $response; } $responseDto = $this->packageManager->remove(new PackageCollection(array_map( fn (string $featurePackage): Package => new Package($featurePackage), $matches[static::KEY_FEATURES], ))); - $stepsExecutionDto->setIsSuccessful($responseDto->isSuccessful()); - - if (!$responseDto->isSuccessful()) { - $stepsExecutionDto->addOutputMessage($responseDto->getOutputMessage()); - - return $stepsExecutionDto; - } - - foreach ($foundMessages as $key => $foundMessage) { - unset($messages[$key]); - } - $stepsExecutionDto->setOutputMessages($messages); - $stepsExecutionDto->addOutputMessage(sprintf('Splitted %s feature package(s)', count($matches[static::KEY_FEATURES]))); - - if ($stepsExecutionDto->getIsSuccessful()) { - $stepsExecutionDto->removeBlockersByTitle(ComposerViolationDtoFactory::VIOLATION_TITLE); - } - return $stepsExecutionDto; + return $responseDto; } /** diff --git a/src/Upgrade/Application/Strategy/FixerStepInterface.php b/src/Upgrade/Application/Strategy/FixerStepInterface.php deleted file mode 100644 index 0addb822..00000000 --- a/src/Upgrade/Application/Strategy/FixerStepInterface.php +++ /dev/null @@ -1,29 +0,0 @@ - + */ + protected array $fixers = []; + + /** + * @param \Upgrade\Application\Strategy\ReleaseApp\Processor\ModuleFetcher $moduleFetcher + * @param \Psr\Log\LoggerInterface $logger + * @param array<\Upgrade\Application\Strategy\UpgradeFixerInterface> $fixers + */ + public function __construct(ModuleFetcher $moduleFetcher, LoggerInterface $logger, array $fixers = []) + { + $this->moduleFetcher = $moduleFetcher; + $this->logger = $logger; + $this->fixers = $fixers; + } + + /** + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * + * @return \Upgrade\Application\Dto\PackageManagerResponseDto + */ + public function upgrade(ReleaseGroupDto $releaseGroup): PackageManagerResponseDto + { + $response = $this->moduleFetcher->require($releaseGroup->getModuleCollection()); + if (!$response->isSuccessful()) { + $response = $this->runWithFixer($releaseGroup, $response); + } + + return $response; + } + + /** + * @param \ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto $releaseGroup + * @param \Upgrade\Application\Dto\PackageManagerResponseDto $response + * + * @return \Upgrade\Application\Dto\PackageManagerResponseDto + */ + protected function runWithFixer(ReleaseGroupDto $releaseGroup, PackageManagerResponseDto $response): PackageManagerResponseDto + { + $this->logger->info( + sprintf('Release Group `%s` is failed. Trying to fix it', $releaseGroup->getId()), + [$response->getOutputMessage()], + ); + + foreach ($this->fixers as $fixer) { + $fixerNamespacePaths = explode('\\', get_class($fixer)); + $fixerName = end($fixerNamespacePaths); + if (!$fixer->isApplicable($releaseGroup, $response)) { + $this->logger->info(sprintf('Fixer `%s` is not applicable', $fixerName)); + + continue; + } + + $this->logger->info(sprintf('`%s` fixer is applying', $fixerName)); + + $fixerResponse = $fixer->run($releaseGroup, $response); + + if ($fixerResponse !== null && !$fixerResponse->isSuccessful()) { + $this->logger->warning( + sprintf('Fixer `%s` is failed', $fixerName), + [$response->getOutputMessage()], + ); + + continue; + } + if ($fixerResponse !== null) { + $response = $fixerResponse; + } + + if ($fixer->isReRunStep()) { + $this->logger->info('Run release group upgrade after fixer.'); + + $response = $this->moduleFetcher->require($releaseGroup->getModuleCollection()); + } + + if ($response->isSuccessful()) { + break; + } + } + + return $response; + } +} diff --git a/src/Upgrade/Application/Strategy/ReleaseApp/Processor/SequentialReleaseGroupProcessor.php b/src/Upgrade/Application/Strategy/ReleaseApp/Processor/SequentialReleaseGroupProcessor.php index 453069fd..ef1bec95 100644 --- a/src/Upgrade/Application/Strategy/ReleaseApp/Processor/SequentialReleaseGroupProcessor.php +++ b/src/Upgrade/Application/Strategy/ReleaseApp/Processor/SequentialReleaseGroupProcessor.php @@ -35,9 +35,9 @@ class SequentialReleaseGroupProcessor extends BaseReleaseGroupProcessor protected ThresholdSoftValidatorInterface $thresholdValidator; /** - * @var \Upgrade\Application\Strategy\ReleaseApp\Processor\ModuleFetcher + * @var \Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupUpgrader */ - protected ModuleFetcher $moduleFetcher; + protected ReleaseGroupUpgrader $releaseGroupUpgrader; /** * @var \Upgrade\Application\Strategy\ReleaseApp\ReleaseGroupFilter\ReleaseGroupFilterInterface @@ -52,7 +52,7 @@ class SequentialReleaseGroupProcessor extends BaseReleaseGroupProcessor /** * @param \Upgrade\Application\Strategy\ReleaseApp\Validator\ReleaseGroupSoftValidatorInterface $releaseGroupValidateManager * @param \Upgrade\Application\Strategy\ReleaseApp\Validator\ThresholdSoftValidatorInterface $thresholdSoftValidator - * @param \Upgrade\Application\Strategy\ReleaseApp\Processor\ModuleFetcher $moduleFetcher + * @param \Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupUpgrader $releaseGroupUpgrader * @param \Upgrade\Application\Strategy\ReleaseApp\ReleaseGroupFilter\ReleaseGroupFilterInterface $releaseGroupFilter * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher * @param \Psr\Log\LoggerInterface $logger @@ -61,7 +61,7 @@ class SequentialReleaseGroupProcessor extends BaseReleaseGroupProcessor public function __construct( ReleaseGroupSoftValidatorInterface $releaseGroupValidateManager, ThresholdSoftValidatorInterface $thresholdSoftValidator, - ModuleFetcher $moduleFetcher, + ReleaseGroupUpgrader $releaseGroupUpgrader, ReleaseGroupFilterInterface $releaseGroupFilter, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger, @@ -71,7 +71,7 @@ public function __construct( $this->releaseGroupValidator = $releaseGroupValidateManager; $this->thresholdValidator = $thresholdSoftValidator; - $this->moduleFetcher = $moduleFetcher; + $this->releaseGroupUpgrader = $releaseGroupUpgrader; $this->releaseGroupPackageFilter = $releaseGroupFilter; $this->composerViolationDtoFactory = $composerViolationDtoFactory; } @@ -115,7 +115,7 @@ public function process(ReleaseGroupDtoCollection $requireRequestCollection, Ste continue; } - $stepsExecutionDto->setCurrentReleaseGroupId($releaseGroup->getId()); + $stepsExecutionDto->setCurrentReleaseGroup($releaseGroup); $thresholdValidationResult = $this->thresholdValidator->validate($aggregatedReleaseGroupCollection); if (!$thresholdValidationResult->isSuccessful()) { @@ -150,7 +150,7 @@ public function process(ReleaseGroupDtoCollection $requireRequestCollection, Ste break; } - $response = $this->moduleFetcher->require($releaseGroup->getModuleCollection()); + $response = $this->releaseGroupUpgrader->upgrade($releaseGroup); $this->addReleaseGroupStat($stepsExecutionDto, $response); diff --git a/src/Upgrade/Application/Strategy/UpgradeFixerInterface.php b/src/Upgrade/Application/Strategy/UpgradeFixerInterface.php new file mode 100644 index 00000000..f772bc6b --- /dev/null +++ b/src/Upgrade/Application/Strategy/UpgradeFixerInterface.php @@ -0,0 +1,37 @@ + $modelStatisticDto->getTotalOverwrittenModels(), 'total_changed_models' => $modelStatisticDto->getTotalChangedModels(), 'total_intersecting_models' => $modelStatisticDto->getTotalIntersectingModels(), - 'intersecting_models' => $modelStatisticDto->getIntersectingModels(), + 'intersecting_modules' => $modelStatisticDto->getIntersectingModules(), ]; } } diff --git a/tests/ReleaseApp/Infrastructure/Service/ReleaseAppServiceTest.php b/tests/ReleaseApp/Infrastructure/Service/ReleaseAppServiceTest.php index 9d1048fb..0959a2f9 100644 --- a/tests/ReleaseApp/Infrastructure/Service/ReleaseAppServiceTest.php +++ b/tests/ReleaseApp/Infrastructure/Service/ReleaseAppServiceTest.php @@ -53,6 +53,7 @@ public function testGetNewReleaseGroupsSuccess(): void new ModuleDto('spryker/mail-extension', '1.0.0', 'major'), new ModuleDto('spryker/symfony-mailer', '1.0.2', 'major'), ]), + new ModuleDtoCollection(), DateTime::createFromFormat("Y-m-d\TH:i:s.uO", '2022-11-13T18:12:50.000000+0000'), true, 'https://api.release.spryker.com/release-group/4395', @@ -86,6 +87,9 @@ public function testGetReleaseGroupSuccess(): void new ModuleDto('spryker/shipment-types-backend-api', '0.1.0', 'minor'), new ModuleDto('spryker/shipment-type', '0.1.1', 'patch'), ]), + new ModuleDtoCollection([ + new ModuleDto('spryker/shipment-types-backend-api', '0.0.1', 'minor'), + ]), DateTime::createFromFormat("Y-m-d\TH:i:s.uO", '2023-05-23T14:26:52.000000+0000'), true, 'https://api.release.spryker.com/release-group/4821', diff --git a/tests/UpgradeTest/Application/Strategy/Common/Step/IntegratorStepTest.php b/tests/UpgradeTest/Application/Strategy/Common/Step/IntegratorStepTest.php index 3e08bd8b..bd8222f4 100644 --- a/tests/UpgradeTest/Application/Strategy/Common/Step/IntegratorStepTest.php +++ b/tests/UpgradeTest/Application/Strategy/Common/Step/IntegratorStepTest.php @@ -75,7 +75,7 @@ public function testRunShouldPassModulesInExecutor(): void { // Arrange $module = new ModuleDto('spryker/acl', '1.1.1', ReleaseAppConstant::MODULE_TYPE_MAJOR); - $releaseGroup = new ReleaseGroupDto(1, 'RG', new ModuleDtoCollection([$module]), new DateTime(), false, '', 100); + $releaseGroup = new ReleaseGroupDto(1, 'RG', new ModuleDtoCollection([$module]), new ModuleDtoCollection(), new DateTime(), false, '', 100); $stepsResponseDto = new StepsResponseDto(true); $stepsResponseDto->addAppliedReleaseGroup($releaseGroup); @@ -100,7 +100,7 @@ public function testRunShouldNotPassModulesInExecutorWhenNotSpecifiedReleaseGrou { // Arrange $module = new ModuleDto('spryker/acl', '1.1.1', ReleaseAppConstant::MODULE_TYPE_MAJOR); - $releaseGroup = new ReleaseGroupDto(1, 'RG', new ModuleDtoCollection([$module]), new DateTime(), false, '', 100); + $releaseGroup = new ReleaseGroupDto(1, 'RG', new ModuleDtoCollection([$module]), new ModuleDtoCollection(), new DateTime(), false, '', 100); $stepsResponseDto = new StepsResponseDto(true); $stepsResponseDto->addAppliedReleaseGroup($releaseGroup); diff --git a/tests/UpgradeTest/Application/Strategy/Composer/ComposerStrategyTest.php b/tests/UpgradeTest/Application/Strategy/Composer/ComposerStrategyTest.php index 1b8458cc..6c3b6f98 100644 --- a/tests/UpgradeTest/Application/Strategy/Composer/ComposerStrategyTest.php +++ b/tests/UpgradeTest/Application/Strategy/Composer/ComposerStrategyTest.php @@ -14,7 +14,6 @@ use Upgrade\Application\Dto\StepsResponseDto; use Upgrade\Application\Executor\StepExecutor; use Upgrade\Application\Strategy\Composer\ComposerStrategy; -use Upgrade\Application\Strategy\FixerStepInterface; use UpgradeData\Infrastructure\Processor\Strategy\Composer\Steps\FooRollbackStep; use UpgradeData\Infrastructure\Processor\Strategy\Composer\Steps\FooStep; @@ -113,51 +112,6 @@ public function testUpgradeSuccessFlowWithStoppedPropagation(): void $this->assertNull($stepsExecutionDto->getPullRequestId()); } - /** - * @return void - */ - public function testUpgradeSuccessFlowWithFix(): void - { - // Arrange - $stepsExecutionDto = new StepsResponseDto(false); - $fooStep = $this->createMock(FooRollbackStep::class); - $fooStep->method('run')->willReturn($stepsExecutionDto, new StepsResponseDto(true)); - $fooStep->expects($this->never())->method('rollBack'); - - $fixerStep = $this->createMock(FixerStepInterface::class); - $fixerStep - ->method('isApplicable') - ->with($stepsExecutionDto) - ->willReturn(true); - $fixerStep - ->method('run') - ->willReturn(new StepsResponseDto(true)); - - $strategy = new ComposerStrategy( - new StepExecutor( - $this->createMock(LoggerInterface::class), - [ - $fooStep, - new FooStep(), - new FooRollbackStep(), - ], - [ - $fixerStep, - ], - ), - new StepExecutor($this->createMock(LoggerInterface::class)), - $this->createMock(LoggerInterface::class), - ); - - // Act - $stepsExecutionDto = $strategy->upgrade(); - - // Assert - $this->assertTrue($stepsExecutionDto->getIsSuccessful()); - $this->assertNull($stepsExecutionDto->getComposerLockDiff()); - $this->assertNull($stepsExecutionDto->getPullRequestId()); - } - /** * @return void */ diff --git a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/BackportUpgradeFixerTest.php b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/BackportUpgradeFixerTest.php new file mode 100644 index 00000000..a6592feb --- /dev/null +++ b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/BackportUpgradeFixerTest.php @@ -0,0 +1,111 @@ +createMock(PackageManagerAdapterInterface::class), + ); + + // Act + $result = $fixer->isReRunStep(); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testIsApplicable(): void + { + // Arrange + $fixer = new BackportUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'test'); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getBackportModuleCollection')->willReturn(new ModuleDtoCollection([new ModuleDto('test', 'test', 'test')])); + + // Act + $result = $fixer->isApplicable($releaseGroupDtoMock, $packageManagerResponseDto); + + // Assert + $this->assertTrue($result); + } + + /** + * @return void + */ + public function testIsNotApplicable(): void + { + // Arrange + $packageManagerAdapterMock = $this->createMock(PackageManagerAdapterInterface::class); + $fixer = new BackportUpgradeFixer($packageManagerAdapterMock); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'test'); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testRunFix(): void + { + // Arrange + $packageManagerAdapterMock = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapterMock->method('require')->with(new PackageCollection([ + new Package('spryker/cart', '2.1.9'), + new Package('spryker-shup/cart-page', '0.1.9'), + new Package('spryker/merchant', '0.2.1'), + ]))->willReturn(new PackageManagerResponseDto(true)); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getModuleCollection')->willReturn(new ModuleDtoCollection([ + new ModuleDto('spryker/cart', '2.1.9', 'minor'), + new ModuleDto('spryker-shup/cart-page', '1.1.9', 'minor'), + new ModuleDto('spryker/merchant', '3.2.1', 'minor'), + ])); + $releaseGroupDtoMock->method('getBackportModuleCollection')->willReturn(new ModuleDtoCollection([ + new ModuleDto('spryker/cart-new', '2.1.9', 'minor'), + new ModuleDto('spryker-shup/cart-page', '0.1.9', 'minor'), + new ModuleDto('spryker/merchant', '0.2.1', 'minor'), + ])); + $fixer = new BackportUpgradeFixer($packageManagerAdapterMock); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'test'); + + // Act + $packageManagerResponseDto = $fixer->run($releaseGroupDtoMock, $packageManagerResponseDto); + + // Assert + $this->assertNotNull($packageManagerResponseDto); + $this->assertTrue($packageManagerResponseDto->isSuccessful()); + } +} diff --git a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStepTest.php b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStepTest.php deleted file mode 100644 index 36b4c4f8..00000000 --- a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageFixerStepTest.php +++ /dev/null @@ -1,178 +0,0 @@ - found spryker/glue-http[0.2.0] but it conflicts with your root composer.json require (0.3.0)'; - - /** - * @return void - */ - public function testIsApplicableWhenIsFeatureToDevMasterDisabled(): void - { - // Arrange - $fixer = new FeatureDevMasterPackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - ); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertFalse($result); - } - - /** - * @return void - */ - public function testIsApplicable(): void - { - // Arrange - $fixer = new FeatureDevMasterPackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - true, - ); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertTrue($result); - } - - /** - * @return void - */ - public function testRunSkip(): void - { - // Arrange - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->never()) - ->method('require'); - - $fixer = new FeatureDevMasterPackageFixerStep($packageManagerAdapter); - $stepsResponseDtoInput = new StepsResponseDto(false, 'n/a'); - - // Act - $stepsResponseDto = $fixer->run($stepsResponseDtoInput); - - // Assert - $this->assertEquals( - $stepsResponseDtoInput, - $stepsResponseDto, - ); - } - - /** - * @return void - */ - public function testIsNotApplicable(): void - { - // Arrange - $fixer = new FeatureDevMasterPackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - ); - $stepsResponseDto = new StepsResponseDto(false, 'spryker/spryker-core'); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertFalse($result); - } - - /** - * @return void - */ - public function testRunFix(): void - { - // Arrange - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn(new PackageManagerResponseDto(true)); - - $fixer = new FeatureDevMasterPackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponseDto = $fixer->run($stepsResponseDto); - - // Assert - $this->assertTrue($stepsResponseDto->isSuccessful()); - $this->assertSame( - sprintf( - 'Versions were changed to %s for %s feature package(s)', - FeatureDevMasterPackageFixerStep::MASK_ALIAS_DEV_MASTER, - 1, - ), - $stepsResponseDto->getOutputMessage(), - ); - } - - /** - * @return void - */ - public function testRunWithFailed(): void - { - // Arrange - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn(new PackageManagerResponseDto(false, 'error-output')); - - $fixer = new FeatureDevMasterPackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponseDto = $fixer->run($stepsResponseDto); - - // Assert - $this->assertFalse($stepsResponseDto->isSuccessful()); - $this->assertStringContainsString( - 'error-output', - (string)$stepsResponseDto->getOutputMessage(), - ); - } - - /** - * @return void - */ - public function testRunCanNotUpdateFeatureDevMaster(): void - { - // Arrange - $responseDto = new PackageManagerResponseDto(false); - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn(new PackageManagerResponseDto(true)); - - $fixer = new FeatureDevMasterPackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponse = $fixer->run($stepsResponseDto); - - // Assert - $this->assertSame($stepsResponseDto, $stepsResponse); - } -} diff --git a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixerTest.php b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixerTest.php new file mode 100644 index 00000000..cd033b51 --- /dev/null +++ b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeatureDevMasterPackageUpgradeFixerTest.php @@ -0,0 +1,206 @@ + found spryker/glue-http[0.2.0] but it conflicts with your root composer.json require (0.3.0)'; + + /** + * @return void + */ + public function testIsReRunStep(): void + { + // Arrange + $fixer = new FeatureDevMasterPackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + + // Act + $result = $fixer->isReRunStep(); + + // Assert + $this->assertTrue($result); + } + + /** + * @return void + */ + public function testIsApplicableWhenIsFeatureToDevMasterDisabled(): void + { + // Arrange + $fixer = new FeatureDevMasterPackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testIsApplicable(): void + { + // Arrange + $fixer = new FeatureDevMasterPackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + true, + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertTrue($result); + } + + /** + * @return void + */ + public function testRunSkip(): void + { + // Arrange + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->never()) + ->method('require'); + + $fixer = new FeatureDevMasterPackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDtoInput = new PackageManagerResponseDto(false, 'n/a'); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDtoInput); + + // Assert + $this->assertEquals( + null, + $packageManagerResponseDto, + ); + } + + /** + * @return void + */ + public function testIsNotApplicable(): void + { + // Arrange + $fixer = new FeatureDevMasterPackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'spryker/spryker-core'); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testRunFix(): void + { + // Arrange + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn(new PackageManagerResponseDto(true)); + + $fixer = new FeatureDevMasterPackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertNotNull($packageManagerResponseDto); + $this->assertTrue($packageManagerResponseDto->isSuccessful()); + } + + /** + * @return void + */ + public function testRunWithFailed(): void + { + // Arrange + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn(new PackageManagerResponseDto(false, 'error-output')); + + $fixer = new FeatureDevMasterPackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertNotNull($packageManagerResponseDto); + $this->assertFalse($packageManagerResponseDto->isSuccessful()); + $this->assertStringContainsString( + 'error-output', + (string)$packageManagerResponseDto->getOutputMessage(), + ); + } + + /** + * @return void + */ + public function testRunCanNotUpdateFeatureDevMaster(): void + { + // Arrange + $responseDto = new PackageManagerResponseDto(true); + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn($responseDto); + + $fixer = new FeatureDevMasterPackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $packageManagerResponse = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertEquals($responseDto, $packageManagerResponse); + } + + /** + * @return void + */ + public function testRunFixWithNoPackage(): void + { + // Arrange + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $fixer = new FeatureDevMasterPackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'test/package'); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertNull($packageManagerResponseDto); + } +} diff --git a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageFixerStepTest.php b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageFixerStepTest.php deleted file mode 100644 index c2903e49..00000000 --- a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageFixerStepTest.php +++ /dev/null @@ -1,155 +0,0 @@ - found spryker/glue-http[0.2.0] but it conflicts with your root composer.json require (0.3.0)'; - - /** - * @return void - */ - public function testIsApplicableWhenReleaseGroupIntegratorEnabled(): void - { - // Arrange - $fixer = new FeaturePackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - true, - ); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertFalse($result); - } - - /** - * @return void - */ - public function testIsApplicable(): void - { - // Arrange - $fixer = new FeaturePackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - ); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertTrue($result); - } - - /** - * @return void - */ - public function testIsNotApplicable(): void - { - // Arrange - $fixer = new FeaturePackageFixerStep( - $this->createMock(PackageManagerAdapterInterface::class), - ); - $stepsResponseDto = new StepsResponseDto(false, 'spryker-feature1/spryker-core'); - - // Act - $result = $fixer->isApplicable($stepsResponseDto); - - // Assert - $this->assertFalse($result); - } - - /** - * @return void - */ - public function testRunFix(): void - { - // Arrange - $responseDto = new PackageManagerResponseDto(true); - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('remove') - ->willReturn($responseDto); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn($responseDto); - $packageManagerAdapter->expects($this->once()) - ->method('getComposerLockFile') - ->willReturn(['packages' => [['name' => 'name']]]); - - $fixer = new FeaturePackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponseDto = $fixer->run($stepsResponseDto); - - // Assert - $this->assertTrue($stepsResponseDto->isSuccessful()); - $this->assertSame('Splitted 1 feature package(s)', $stepsResponseDto->getOutputMessage()); - } - - /** - * @return void - */ - public function testRunCanNotRequirePackages(): void - { - // Arrange - $responseDto = new PackageManagerResponseDto(false); - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn($responseDto); - - $fixer = new FeaturePackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponse = $fixer->run($stepsResponseDto); - - // Assert - $this->assertSame($stepsResponseDto, $stepsResponse); - } - - /** - * @return void - */ - public function testRunCanNotRemoveFeature(): void - { - // Arrange - $responseDto = new PackageManagerResponseDto(false); - $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); - $packageManagerAdapter->expects($this->once()) - ->method('remove') - ->willReturn($responseDto); - $packageManagerAdapter->expects($this->once()) - ->method('require') - ->willReturn(new PackageManagerResponseDto(true)); - - $fixer = new FeaturePackageFixerStep($packageManagerAdapter); - $stepsResponseDto = new StepsResponseDto(false, static::ERROR_MESSAGE); - - // Act - $stepsResponse = $fixer->run($stepsResponseDto); - - // Assert - $this->assertSame($stepsResponseDto, $stepsResponse); - } -} diff --git a/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixerTest.php b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixerTest.php new file mode 100644 index 00000000..12d0cf5d --- /dev/null +++ b/tests/UpgradeTest/Application/Strategy/Composer/Fixer/FeaturePackageUpgradeFixerTest.php @@ -0,0 +1,188 @@ + found spryker/glue-http[0.2.0] but it conflicts with your root composer.json require (0.3.0)'; + + /** + * @return void + */ + public function testIsReRunStep(): void + { + // Arrange + $fixer = new FeaturePackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + + // Act + $result = $fixer->isReRunStep(); + + // Assert + $this->assertTrue($result); + } + + /** + * @return void + */ + public function testIsApplicableWhenReleaseGroupIntegratorEnabled(): void + { + // Arrange + $fixer = new FeaturePackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + true, + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testIsApplicable(): void + { + // Arrange + $fixer = new FeaturePackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertTrue($result); + } + + /** + * @return void + */ + public function testIsNotApplicable(): void + { + // Arrange + $fixer = new FeaturePackageUpgradeFixer( + $this->createMock(PackageManagerAdapterInterface::class), + ); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'spryker-feature1/spryker-core'); + + // Act + $result = $fixer->isApplicable($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testRunFixWithNoPackage(): void + { + // Arrange + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $fixer = new FeaturePackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, 'test/package'); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertNull($packageManagerResponseDto); + } + + /** + * @return void + */ + public function testRunFix(): void + { + // Arrange + $responseDto = new PackageManagerResponseDto(true); + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('remove') + ->willReturn($responseDto); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn($responseDto); + $packageManagerAdapter->expects($this->once()) + ->method('getComposerLockFile') + ->willReturn(['packages' => [['name' => 'name']]]); + + $fixer = new FeaturePackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $packageManagerResponseDto = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertNotNull($packageManagerResponseDto); + $this->assertTrue($packageManagerResponseDto->isSuccessful()); + } + + /** + * @return void + */ + public function testRunCanNotRequirePackages(): void + { + // Arrange + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn($packageManagerResponseDto); + + $fixer = new FeaturePackageUpgradeFixer($packageManagerAdapter); + + // Act + $packageManagerResponse = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertSame($packageManagerResponseDto, $packageManagerResponse); + } + + /** + * @return void + */ + public function testRunCanNotRemoveFeature(): void + { + // Arrange + $responseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + $packageManagerAdapter = $this->createMock(PackageManagerAdapterInterface::class); + $packageManagerAdapter->expects($this->once()) + ->method('remove') + ->willReturn($responseDto); + $packageManagerAdapter->expects($this->once()) + ->method('require') + ->willReturn(new PackageManagerResponseDto(true)); + + $fixer = new FeaturePackageUpgradeFixer($packageManagerAdapter); + $packageManagerResponseDto = new PackageManagerResponseDto(false, static::ERROR_MESSAGE); + + // Act + $packageManagerResponse = $fixer->run($this->createMock(ReleaseGroupDto::class), $packageManagerResponseDto); + + // Assert + $this->assertEquals($responseDto, $packageManagerResponse); + } +} diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/Processor/ReleaseGroupUpgraderTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/Processor/ReleaseGroupUpgraderTest.php new file mode 100644 index 00000000..0d8b78f3 --- /dev/null +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/Processor/ReleaseGroupUpgraderTest.php @@ -0,0 +1,151 @@ +createMock(ModuleFetcher::class); + $moduleFetcherMock->method('require')->willReturn(new PackageManagerResponseDto(true)); + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock->expects($this->never())->method('info'); + $releaseGroupUpgrader = new ReleaseGroupUpgrader($moduleFetcherMock, $loggerMock, []); + + // Act + $packageManagerResponseDto = $releaseGroupUpgrader->upgrade($this->createMock(ReleaseGroupDto::class)); + + // Assert + $this->assertNotNull($releaseGroupUpgrader); + $this->assertTrue($packageManagerResponseDto->isSuccessful()); + } + + /** + * @return void + */ + public function testRequireWithRunFixer(): void + { + // Arrange + $moduleDtoCollection = new ModuleDtoCollection([ + new ModuleDto('spryker/cart', '2.1.9', 'minor'), + new ModuleDto('spryker-shup/cart-page', '1.1.9', 'minor'), + new ModuleDto('spryker/merchant', '3.2.1', 'minor'), + ]); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getModuleCollection')->willReturn($moduleDtoCollection); + $moduleFetcherMock = $this->createMock(ModuleFetcher::class); + $moduleFetcherMock->method('require')->willReturn( + new PackageManagerResponseDto(false), + new PackageManagerResponseDto(true), + )->with($moduleDtoCollection); + + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock->method('info')->withConsecutive( + ['Release Group `0` is failed. Trying to fix it', [null]], + ['Fixer `FixerOne` is not applicable'], + ['`FixerTwo` fixer is applying'], + ['Run release group upgrade after fixer.'], + ); + $fixer1 = $this->getMockBuilder(UpgradeFixerInterface::class); + $fixer1->setMockClassName('FixerOne'); + $fixer1 = $fixer1->getMock(); + $fixer1->expects($this->once())->method('isApplicable')->willReturn(false); + $fixer1->expects($this->never())->method('run'); + $fixer2 = $this->getMockBuilder(UpgradeFixerInterface::class); + $fixer2->setMockClassName('FixerTwo'); + $fixer2 = $fixer2->getMock(); + $fixer2->expects($this->once())->method('isApplicable')->willReturn(true); + $fixer2->expects($this->once())->method('run')->willReturn(new PackageManagerResponseDto(true)); + $fixer2->expects($this->once())->method('isReRunStep')->willReturn(true); + $releaseGroupUpgrader = new ReleaseGroupUpgrader( + $moduleFetcherMock, + $loggerMock, + [ + $fixer1, + $fixer2, + ], + ); + + // Act + $packageManagerResponseDto = $releaseGroupUpgrader->upgrade($releaseGroupDtoMock); + + // Assert + $this->assertNotNull($releaseGroupUpgrader); + $this->assertTrue($packageManagerResponseDto->isSuccessful()); + } + + /** + * @return void + */ + public function testRequireWithRunFixerThatFailed(): void + { + // Arrange + $moduleDtoCollection = new ModuleDtoCollection([ + new ModuleDto('spryker/cart', '2.1.9', 'minor'), + new ModuleDto('spryker-shup/cart-page', '1.1.9', 'minor'), + new ModuleDto('spryker/merchant', '3.2.1', 'minor'), + ]); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getModuleCollection')->willReturn($moduleDtoCollection); + $moduleFetcherMock = $this->createMock(ModuleFetcher::class); + $moduleFetcherMock->method('require')->willReturn( + new PackageManagerResponseDto(false), + new PackageManagerResponseDto(true), + )->with($moduleDtoCollection); + + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock->method('warning')->with('Fixer `FixerTwo` is failed', [null]); + $loggerMock->method('info')->withConsecutive( + ['Release Group `0` is failed. Trying to fix it', [null]], + ['Fixer `FixerOne` is not applicable'], + ['`FixerTwo` fixer is applying'], + ['Run release group upgrade after fixer.'], + ); + $fixer1 = $this->getMockBuilder(UpgradeFixerInterface::class); + $fixer1->setMockClassName('FixerOne'); + $fixer1 = $fixer1->getMock(); + $fixer1->expects($this->once())->method('isApplicable')->willReturn(false); + $fixer1->expects($this->never())->method('run'); + $fixer2 = $this->getMockBuilder(UpgradeFixerInterface::class); + $fixer2->setMockClassName('FixerTwo'); + $fixer2 = $fixer2->getMock(); + $fixer2->expects($this->once())->method('isApplicable')->willReturn(true); + $fixer2->expects($this->once())->method('run')->willReturn(new PackageManagerResponseDto(false)); + $releaseGroupUpgrader = new ReleaseGroupUpgrader( + $moduleFetcherMock, + $loggerMock, + [ + $fixer1, + $fixer2, + ], + ); + + // Act + $packageManagerResponseDto = $releaseGroupUpgrader->upgrade($releaseGroupDtoMock); + + // Assert + $this->assertNotNull($releaseGroupUpgrader); + $this->assertFalse($packageManagerResponseDto->isSuccessful()); + } +} diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/AlreadyInstalledPackageFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/AlreadyInstalledPackageFilterItemTest.php index e26ee647..a22e2824 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/AlreadyInstalledPackageFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/AlreadyInstalledPackageFilterItemTest.php @@ -80,6 +80,7 @@ protected function createReleaseGroupDto(array $moduleDto): ReleaseGroupDto 1, 'RG1', new ModuleDtoCollection($moduleDto), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/BetaMajorPackageFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/BetaMajorPackageFilterItemTest.php index d67b5e78..a49bc418 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/BetaMajorPackageFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/BetaMajorPackageFilterItemTest.php @@ -40,6 +40,7 @@ public function testFilterShouldFilterBetaMajors(): void 1, 'RG', new ModuleDtoCollection($modules), + new ModuleDtoCollection(), new DateTime(), true, '', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DevMasterPackageFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DevMasterPackageFilterItemTest.php index 70757636..188d61ee 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DevMasterPackageFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DevMasterPackageFilterItemTest.php @@ -76,6 +76,7 @@ protected function createReleaseGroupDto(array $moduleDto): ReleaseGroupDto 1, 'RG1', new ModuleDtoCollection($moduleDto), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DummyPackageFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DummyPackageFilterItemTest.php index aae4a1b5..0cfe7a30 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DummyPackageFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/DummyPackageFilterItemTest.php @@ -82,6 +82,7 @@ protected function createReleaseGroupDto(array $moduleDto): ReleaseGroupDto 1, 'RG1', new ModuleDtoCollection($moduleDto), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/NewPackageFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/NewPackageFilterItemTest.php index 0502f43a..6b14bbd3 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/NewPackageFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/NewPackageFilterItemTest.php @@ -129,6 +129,7 @@ protected function createReleaseGroupDto(array $moduleDto): ReleaseGroupDto 1, 'RG1', new ModuleDtoCollection($moduleDto), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/ReleaseGroupFilterTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/ReleaseGroupFilterTest.php index f55fa478..8956ff3b 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/ReleaseGroupFilterTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/ReleaseGroupFilterTest.php @@ -51,6 +51,7 @@ protected function createReleaseGroupDto(): ReleaseGroupDto 4821, 'CC-26540 Introduced the Shipment Types BAPI', new ModuleDtoCollection([$this->createModuleDto()]), + new ModuleDtoCollection(), new DateTime(), true, 'https://api.release.spryker.com/release-group/4821', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/SecurityMajorFilterItemTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/SecurityMajorFilterItemTest.php index 17b5225a..071d5f44 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/SecurityMajorFilterItemTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/ReleaseGroupFilter/SecurityMajorFilterItemTest.php @@ -103,6 +103,7 @@ protected function createReleaseGroupDto(): ReleaseGroupDto 1, 'RG1', new ModuleDtoCollection($moduleDto), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Application/Strategy/ReleaseApp/Step/ReleaseGroupUpdateStepTest.php b/tests/UpgradeTest/Application/Strategy/ReleaseApp/Step/ReleaseGroupUpdateStepTest.php index b8414900..def71c7b 100644 --- a/tests/UpgradeTest/Application/Strategy/ReleaseApp/Step/ReleaseGroupUpdateStepTest.php +++ b/tests/UpgradeTest/Application/Strategy/ReleaseApp/Step/ReleaseGroupUpdateStepTest.php @@ -30,6 +30,7 @@ use Upgrade\Application\Strategy\ReleaseApp\Processor\PackageManagerPackagesFetcher\PackageManagerPackagesFetcherInterface; use Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupProcessorInterface; use Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupProcessorResolver; +use Upgrade\Application\Strategy\ReleaseApp\Processor\ReleaseGroupUpgrader; use Upgrade\Application\Strategy\ReleaseApp\Processor\SequentialReleaseGroupProcessor; use Upgrade\Application\Strategy\ReleaseApp\ReleaseGroupFilter\BetaMajorPackageFilterItem; use Upgrade\Application\Strategy\ReleaseApp\ReleaseGroupFilter\DevMasterPackageFilterItem; @@ -539,20 +540,22 @@ protected function createSequentialReleaseGroupProcessor( ->getMock(); $composerAdapterMock->method('require')->willReturn($responseDto); $composerAdapterMock->method('requireDev')->willReturn($responseDto); + $moduleFetcher = new ModuleFetcher( + $composerAdapterMock, + new PackageCollectionMapper( + $composerAdapterMock, + ), + $this->createPackageManagerPackagesFetcherMock(), + ); + $logger = $this->createMock(LoggerInterface::class); return new SequentialReleaseGroupProcessor( new ReleaseGroupSoftValidator($releaseGroupValidators), new ThresholdSoftValidator($thresholdSoftValidators), - new ModuleFetcher( - $composerAdapterMock, - new PackageCollectionMapper( - $composerAdapterMock, - ), - $this->createPackageManagerPackagesFetcherMock(), - ), + new ReleaseGroupUpgrader($moduleFetcher, $logger, []), new ReleaseGroupFilter($releaseGroupFilters), $this->createEventDispatcherMock(), - $this->createMock(LoggerInterface::class), + $logger, new ComposerViolationDtoFactory(), ); } @@ -571,6 +574,7 @@ protected function buildReleaseGroupDtoCollection(bool $conflictDetected = false new ModuleDtoCollection([ new ModuleDto('spryker/product-category', '4.17.0', 'minor'), ]), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', @@ -582,6 +586,7 @@ protected function buildReleaseGroupDtoCollection(bool $conflictDetected = false new ModuleDtoCollection([ new ModuleDto('spryker/oauth-backend-api', '1.1.1', 'path'), ]), + new ModuleDtoCollection(), new DateTime(), true, 'https://api.release.spryker.com/release-groups/view/2', @@ -603,6 +608,7 @@ protected function buildReleaseGroupDtoCollectionByModules(array $moduleDtoColle 1, 'RG1', new ModuleDtoCollection($moduleDtoCollection), + new ModuleDtoCollection(), new DateTime(), false, 'https://api.release.spryker.com/release-groups/view/1', diff --git a/tests/UpgradeTest/Infrastructure/Report/Builder/ReportDtoBuilderTest.php b/tests/UpgradeTest/Infrastructure/Report/Builder/ReportDtoBuilderTest.php index 4766927e..f224c6a4 100644 --- a/tests/UpgradeTest/Infrastructure/Report/Builder/ReportDtoBuilderTest.php +++ b/tests/UpgradeTest/Infrastructure/Report/Builder/ReportDtoBuilderTest.php @@ -10,6 +10,7 @@ namespace UpgradeTest\Infrastructure\Report\Builder; use PHPUnit\Framework\TestCase; +use ReleaseApp\Infrastructure\Shared\Dto\ReleaseGroupDto; use Upgrade\Application\Dto\ComposerLockDiffDto; use Upgrade\Application\Dto\IntegratorResponseDto; use Upgrade\Application\Dto\StepsResponseDto; @@ -151,10 +152,14 @@ protected function createStepsResponseDto(?ComposerLockDiffDto $composerLockDiff $stepsResponseDto->setReportId(static::REPORT_ID); - $stepsResponseDto->setCurrentReleaseGroupId(1); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getId')->willReturn(1); + $stepsResponseDto->setCurrentReleaseGroup($releaseGroupDtoMock); $stepsResponseDto->addIntegratorResponseDto(new IntegratorResponseDto(['warning-list' => ['Warning One']])); - $stepsResponseDto->setCurrentReleaseGroupId(2); + $releaseGroupDtoMock = $this->createMock(ReleaseGroupDto::class); + $releaseGroupDtoMock->method('getId')->willReturn(2); + $stepsResponseDto->setCurrentReleaseGroup($releaseGroupDtoMock); $stepsResponseDto->addIntegratorResponseDto(new IntegratorResponseDto(['warning-list' => ['Warning Two']])); return $stepsResponseDto; diff --git a/tests/UpgradeTest/Infrastructure/Report/Serializer/Normalizer/ReportNormalizerTest.php b/tests/UpgradeTest/Infrastructure/Report/Serializer/Normalizer/ReportNormalizerTest.php index 2f53fecb..4e926a79 100644 --- a/tests/UpgradeTest/Infrastructure/Report/Serializer/Normalizer/ReportNormalizerTest.php +++ b/tests/UpgradeTest/Infrastructure/Report/Serializer/Normalizer/ReportNormalizerTest.php @@ -85,7 +85,7 @@ public function testNormalizeShouldReturnJsonArray(): void 'total_overwritten_models' => 2, 'total_changed_models' => 3, 'total_intersecting_models' => 1, - 'intersecting_models' => ['Test'], + 'intersecting_modules' => ['Test'], ], ], 'metadata' => [ diff --git a/tests/UpgradeTest/Infrastructure/VersionControlSystem/Git/GitTest.php b/tests/UpgradeTest/Infrastructure/VersionControlSystem/Git/GitTest.php index 96e20bba..3bed3007 100644 --- a/tests/UpgradeTest/Infrastructure/VersionControlSystem/Git/GitTest.php +++ b/tests/UpgradeTest/Infrastructure/VersionControlSystem/Git/GitTest.php @@ -291,6 +291,7 @@ protected function getReleaseGroupDto(): ReleaseGroupDto 4821, 'RGname', new ModuleDtoCollection(), + new ModuleDtoCollection(), new DateTime(), true, 'https://api.release.spryker.com/release-group/4821', diff --git a/tests/data/ReleaseApp/Api/Response/upgrade-instruction.json b/tests/data/ReleaseApp/Api/Response/upgrade-instruction.json index 7e976b25..76538fcc 100644 --- a/tests/data/ReleaseApp/Api/Response/upgrade-instruction.json +++ b/tests/data/ReleaseApp/Api/Response/upgrade-instruction.json @@ -24,6 +24,7 @@ "files": 9 } }, + "backports": [], "meta": { "include": { "Spryker.SymfonyMailer": "1.0.2" diff --git a/tests/data/ReleaseApp/Api/Response/upgrade-release-group-instructions.json b/tests/data/ReleaseApp/Api/Response/upgrade-release-group-instructions.json index 3501592f..cb0d465d 100644 --- a/tests/data/ReleaseApp/Api/Response/upgrade-release-group-instructions.json +++ b/tests/data/ReleaseApp/Api/Response/upgrade-release-group-instructions.json @@ -18,6 +18,13 @@ "files": 4 } }, + "backports": { + "spryker\/shipment-types-backend-api": { + "version": "0.0.1", + "type": "minor", + "files": 3 + } + }, "jira": { "issue": "CC-25420", "issue_link": "https://spryker.atlassian.net/browse/CC-25420" diff --git a/tests/data/ReleaseApp/Api/Response/upgrader-instruction-list.json b/tests/data/ReleaseApp/Api/Response/upgrader-instruction-list.json index 0379f2fb..75a009a8 100644 --- a/tests/data/ReleaseApp/Api/Response/upgrader-instruction-list.json +++ b/tests/data/ReleaseApp/Api/Response/upgrader-instruction-list.json @@ -25,6 +25,7 @@ "files": 9 } }, + "backports": [], "meta": { "include": { "Spryker.SymfonyMailer": "1.0.2"