From eae9e6247622479ab33e99b9810d9645dbaaa9c5 Mon Sep 17 00:00:00 2001 From: Maksym Ohnyanikov Date: Fri, 21 Oct 2022 19:09:30 +0300 Subject: [PATCH 01/14] COMPONENTS UPGRADE --- .../OpenApi/Merger/ComponentMerger.php | 34 ++ ...ameterNotFoundInSourceOpenApiException.php | 14 - ...SchemaNotFoundInSourceOpenApiException.php | 14 - .../SyncApi/OpenApi/Merger/OpenApiMerger.php | 50 +++ .../SyncApi/OpenApi/Merger/PathsMerger.php | 285 +------------ .../OpenApi/Updater/OpenApiUpdater.php | 32 +- src/SprykerSdk/SyncApi/SyncApiFactory.php | 28 +- .../Console/OpenApiUpdateConsoleTest.php | 2 +- .../OpenApi/Merger/ComponentsCleanerTest.php | 45 ++ .../OpenApi/Merger/ComponentsMergerTest.php | 46 ++ .../OpenApi/Merger/PathsMergerTest.php | 40 +- .../api/invalid/missed_references_openapi.yml | 399 ------------------ .../api/merger/cleaner/expected_openapi.yml | 33 ++ .../api/merger/cleaner/target_openapi.yml | 45 ++ .../merger/components/expected_openapi.yml | 37 ++ .../api/merger/components/source_openapi.yml | 26 ++ .../api/merger/components/target_openapi.yml | 26 ++ .../api/merger/paths/expected_openapi.yml | 111 +---- .../_data/api/merger/paths/source_openapi.yml | 77 +--- .../source_openapi_with_parameter_missing.yml | 6 - .../source_openapi_with_schema_missing.yml | 10 - .../_data/api/merger/paths/target_openapi.yml | 69 +-- .../Helper/OpenApiValidatorHelper.php | 8 - 23 files changed, 386 insertions(+), 1051 deletions(-) create mode 100644 src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentMerger.php delete mode 100644 src/SprykerSdk/SyncApi/OpenApi/Merger/Exception/ParameterNotFoundInSourceOpenApiException.php delete mode 100644 src/SprykerSdk/SyncApi/OpenApi/Merger/Exception/SchemaNotFoundInSourceOpenApiException.php create mode 100644 src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php create mode 100644 tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php create mode 100644 tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsMergerTest.php delete mode 100644 tests/_data/api/invalid/missed_references_openapi.yml create mode 100644 tests/_data/api/merger/cleaner/expected_openapi.yml create mode 100644 tests/_data/api/merger/cleaner/target_openapi.yml create mode 100644 tests/_data/api/merger/components/expected_openapi.yml create mode 100644 tests/_data/api/merger/components/source_openapi.yml create mode 100644 tests/_data/api/merger/components/target_openapi.yml delete mode 100644 tests/_data/api/merger/paths/source_openapi_with_parameter_missing.yml delete mode 100644 tests/_data/api/merger/paths/source_openapi_with_schema_missing.yml diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentMerger.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentMerger.php new file mode 100644 index 0000000..f34a19d --- /dev/null +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentMerger.php @@ -0,0 +1,34 @@ +getParameters($sourceOpenApi) as $parameterName => $parameter) { + $this->addParameter($targetOpenApi, $parameterName, $parameter); + } + + foreach ($this->getSchemas($sourceOpenApi) as $schemaName => $schema) { + $this->addSchema($targetOpenApi, $schemaName, $schema); + } + + return $targetOpenApi; + } +} diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/Exception/ParameterNotFoundInSourceOpenApiException.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/Exception/ParameterNotFoundInSourceOpenApiException.php deleted file mode 100644 index 2d5df04..0000000 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/Exception/ParameterNotFoundInSourceOpenApiException.php +++ /dev/null @@ -1,14 +0,0 @@ - + */ + protected array $mergerCollection; + + /** + * @var \SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleanerInterface + */ + protected ComponentsCleanerInterface $componentsCleaner; + + /** + * @param array<\SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface> $mergerCollection + * @param \SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleanerInterface $componentsCleaner + */ + public function __construct( + array $mergerCollection, + ComponentsCleanerInterface $componentsCleaner + ) { + $this->mergerCollection = $mergerCollection; + $this->componentsCleaner = $componentsCleaner; + } + + /** + * @param \cebe\openapi\spec\OpenApi $targetOpenApi + * @param \cebe\openapi\spec\OpenApi $sourceOpenApi + * + * @return \cebe\openapi\spec\OpenApi + */ + public function merge(OpenApi $targetOpenApi, OpenApi $sourceOpenApi): OpenApi + { + foreach ($this->mergerCollection as $merger) { + $targetOpenApi = $merger->merge($targetOpenApi, $sourceOpenApi); + } + + return $this->componentsCleaner->cleanUnused($targetOpenApi); + } +} diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php index 452a656..c03df69 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php @@ -9,38 +9,23 @@ use cebe\openapi\spec\OpenApi; use cebe\openapi\spec\PathItem; -use cebe\openapi\Writer; -use SprykerSdk\SyncApi\OpenApi\Merger\Exception\ParameterNotFoundInSourceOpenApiException; -use SprykerSdk\SyncApi\OpenApi\Merger\Exception\SchemaNotFoundInSourceOpenApiException; use SprykerSdk\SyncApi\SyncApiConfig; class PathsMerger implements MergerInterface { use OpenApiAccessorTrait; - /** - * @var string - */ - protected const YAML_EXTENSION_PATTERN = '/(\.yaml|\.yml)/'; - /** * @var \SprykerSdk\SyncApi\SyncApiConfig */ - protected SyncApiConfig $syncApiConfig; - - /** - * @var \SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleanerInterface - */ - protected ComponentsCleanerInterface $componentsCleaner; + private SyncApiConfig $syncApiConfig; /** * @param \SprykerSdk\SyncApi\SyncApiConfig $syncApiConfig - * @param \SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleanerInterface $componentsCleaner */ - public function __construct(SyncApiConfig $syncApiConfig, ComponentsCleanerInterface $componentsCleaner) + public function __construct(SyncApiConfig $syncApiConfig) { $this->syncApiConfig = $syncApiConfig; - $this->componentsCleaner = $componentsCleaner; } /** @@ -55,28 +40,24 @@ public function merge(OpenApi $targetOpenApi, OpenApi $sourceOpenApi): OpenApi if (!$this->getPaths($targetOpenApi)->hasPath($pathName)) { $this->getPaths($targetOpenApi)->addPath($pathName, $sourcePathItem); - $targetOpenApi = $this->addReferencesFromPathItem($targetOpenApi, $sourceOpenApi, $pathName); - continue; } - $this->mergePath($targetOpenApi, $sourceOpenApi, $pathName, $sourcePathItem); + $this->mergePath($targetOpenApi, $pathName, $sourcePathItem); } - return $this->componentsCleaner->cleanUnused($targetOpenApi); + return $targetOpenApi; } /** * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi * @param string $pathName * @param \cebe\openapi\spec\PathItem $sourcePathItem * * @return \cebe\openapi\spec\OpenApi */ - protected function mergePath( + private function mergePath( OpenApi $targetOpenApi, - OpenApi $sourceOpenApi, string $pathName, PathItem $sourcePathItem ): OpenApi { @@ -85,265 +66,9 @@ protected function mergePath( foreach ($this->syncApiConfig->getAvailableHttpMethods() as $httpMethod) { if ($sourcePathItem->$httpMethod) { $targetPathItem->$httpMethod = $sourcePathItem->$httpMethod; - - $targetOpenApi = $this->addReferencesFromOperation($targetOpenApi, $sourceOpenApi, $pathName, $httpMethod); } } return $targetOpenApi; } - - /** - * Copies schemas by references from source OpenApi Path Item to target OpenApi - * - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $pathName - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addReferencesFromPathItem(OpenApi $targetOpenApi, OpenApi $sourceOpenApi, string $pathName): OpenApi - { - foreach ($this->syncApiConfig->getAvailableHttpMethods() as $httpMethod) { - $this->addReferencesFromOperation($targetOpenApi, $sourceOpenApi, $pathName, $httpMethod); - } - - return $targetOpenApi; - } - - /** - * Copies schemas by references from source OpenApi Operation Item to target OpenApi - * - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $pathName - * @param string $httpMethod - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addReferencesFromOperation( - OpenApi $targetOpenApi, - OpenApi $sourceOpenApi, - string $pathName, - string $httpMethod - ): OpenApi { - $sourceOpenApiAsArray = json_decode(Writer::writeToJson($sourceOpenApi), true); - - if (!isset($sourceOpenApiAsArray['paths'][$pathName][$httpMethod])) { - return $targetOpenApi; - } - - $references = ReferenceFinder::findInArray($sourceOpenApiAsArray['paths'][$pathName][$httpMethod]); - - foreach ($references as $reference) { - $this->addInternalReference($targetOpenApi, $sourceOpenApi, $reference); - } - - return $targetOpenApi; - } - - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $parameterName - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addReferencesFromParameter( - OpenApi $targetOpenApi, - OpenApi $sourceOpenApi, - string $parameterName - ): OpenApi { - $sourceOpenApiAsArray = json_decode(Writer::writeToJson($sourceOpenApi), true); - - $references = ReferenceFinder::findInArray($sourceOpenApiAsArray['components']['parameters'][$parameterName]); - - foreach ($references as $reference) { - $this->addInternalReference($targetOpenApi, $sourceOpenApi, $reference); - } - - return $targetOpenApi; - } - - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $schemaName - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addReferencesFromSchema( - OpenApi $targetOpenApi, - OpenApi $sourceOpenApi, - string $schemaName - ): OpenApi { - $sourceOpenApiAsArray = json_decode(Writer::writeToJson($sourceOpenApi), true); - - $references = ReferenceFinder::findInArray($sourceOpenApiAsArray['components']['schemas'][$schemaName]); - - foreach ($references as $reference) { - $this->addInternalReference($targetOpenApi, $sourceOpenApi, $reference); - } - - return $targetOpenApi; - } - - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $reference - * - * @return void - */ - protected function addInternalReference(OpenApi $targetOpenApi, OpenApi $sourceOpenApi, string $reference): void - { - if ($this->isExternalReference($reference)) { - return; - } - - if ($this->isParameter($reference)) { - $this->addInternalParameter($targetOpenApi, $sourceOpenApi, $reference); - } - - if ($this->isSchema($reference)) { - $this->addInternalSchema($targetOpenApi, $sourceOpenApi, $reference); - } - } - - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $reference - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addInternalParameter(OpenApi $targetOpenApi, OpenApi $sourceOpenApi, string $reference): OpenApi - { - $parameterName = $this->getObjectName($reference); - - $parameterItem = $this->getParameterByReference($sourceOpenApi, $parameterName); - - $this->addParameter($targetOpenApi, $parameterName, $parameterItem); - - return $this->addReferencesFromParameter($targetOpenApi, $sourceOpenApi, $parameterName); - } - - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * @param string $reference - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function addInternalSchema(OpenApi $targetOpenApi, OpenApi $sourceOpenApi, string $reference): OpenApi - { - $schemaName = $this->getObjectName($reference); - $schemaItem = $this->getSchemaByReference($sourceOpenApi, $schemaName); - - $this->addSchema($targetOpenApi, $schemaName, $schemaItem); - - return $this->addReferencesFromSchema($targetOpenApi, $sourceOpenApi, $schemaName); - } - - /** - * @param string $reference - * - * @return bool - */ - protected function isParameter(string $reference): bool - { - return strpos($reference, '/parameters/') !== false; - } - - /** - * @param string $reference - * - * @return bool - */ - protected function isSchema(string $reference): bool - { - return strpos($reference, '/schemas/') !== false; - } - - /** - * @param string $reference - * - * @return string - */ - protected function getObjectName(string $reference): string - { - $referenceParts = explode(DIRECTORY_SEPARATOR, $reference); - - return end($referenceParts); - } - - /** - * @param string $reference - * - * @return bool - */ - protected function isExternalReference(string $reference): bool - { - return (bool)preg_match(static::YAML_EXTENSION_PATTERN, $reference); - } - - /** - * @param \cebe\openapi\spec\OpenApi $openApi - * @param string $parameterName - * - * @throws \SprykerSdk\SyncApi\OpenApi\Merger\Exception\ParameterNotFoundInSourceOpenApiException - * - * @return \cebe\openapi\spec\Parameter|\cebe\openapi\spec\Reference - */ - protected function getParameterByReference(OpenApi $openApi, string $parameterName) - { - foreach ($this->getParameters($openApi) as $currentParameterName => $parameterItem) { - if ($currentParameterName === $parameterName) { - return $parameterItem; - } - } - - throw new ParameterNotFoundInSourceOpenApiException( - $this->createParameterIsNotFoundMessage($parameterName), - ); - } - - /** - * @param \cebe\openapi\spec\OpenApi $openApi - * @param string $schemaName - * - * @throws \SprykerSdk\SyncApi\OpenApi\Merger\Exception\SchemaNotFoundInSourceOpenApiException - * - * @return \cebe\openapi\spec\Schema|\cebe\openapi\spec\Reference - */ - protected function getSchemaByReference(OpenApi $openApi, string $schemaName) - { - foreach ($this->getSchemas($openApi) as $currentSchemaName => $schema) { - if ($currentSchemaName === $schemaName) { - return $schema; - } - } - - throw new SchemaNotFoundInSourceOpenApiException($this->createSchemaIsNotFoundMessage($schemaName)); - } - - /** - * @param string $parameterName - * - * @return string - */ - protected function createParameterIsNotFoundMessage(string $parameterName): string - { - return sprintf('Parameter "%s" is not found in given Open API', $parameterName); - } - - /** - * @param string $schemaName - * - * @return string - */ - protected function createSchemaIsNotFoundMessage(string $schemaName): string - { - return sprintf('Schema "%s" is not found in given Open API', $schemaName); - } } diff --git a/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php b/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php index 0a598cb..2ee0172 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php @@ -13,6 +13,7 @@ use SprykerSdk\SyncApi\Message\MessageBuilderInterface; use SprykerSdk\SyncApi\Message\SyncApiError; use SprykerSdk\SyncApi\Message\SyncApiInfo; +use SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface; use SprykerSdk\SyncApi\SyncApiConfig; use Throwable; use Transfer\OpenApiResponseTransfer; @@ -23,31 +24,31 @@ class OpenApiUpdater implements OpenApiUpdaterInterface /** * @var \SprykerSdk\SyncApi\Message\MessageBuilderInterface */ - protected MessageBuilderInterface $messageBuilder; + private MessageBuilderInterface $messageBuilder; /** * @var \SprykerSdk\SyncApi\SyncApiConfig */ - protected SyncApiConfig $syncApiConfig; + private SyncApiConfig $syncApiConfig; /** - * @var array<\SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface> + * @var \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface */ - protected array $mergerCollection; + private MergerInterface $openApiMerger; /** * @param \SprykerSdk\SyncApi\Message\MessageBuilderInterface $messageBuilder * @param \SprykerSdk\SyncApi\SyncApiConfig $syncApiConfig - * @param array<\SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface> $mergerCollection + * @param \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface $openApiMerger */ public function __construct( MessageBuilderInterface $messageBuilder, SyncApiConfig $syncApiConfig, - array $mergerCollection + MergerInterface $openApiMerger ) { $this->messageBuilder = $messageBuilder; $this->syncApiConfig = $syncApiConfig; - $this->mergerCollection = $mergerCollection; + $this->openApiMerger = $openApiMerger; } /** @@ -66,7 +67,7 @@ public function updateOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequest $syncApiTargetFilepath = $this->getSyncApiTargetFilepath($updateOpenApiRequestTransfer); - $targetOpenApi = $this->merge($this->getTargetOpenApi($syncApiTargetFilepath), $sourceOpenApi); + $targetOpenApi = $this->openApiMerger->merge($this->getTargetOpenApi($syncApiTargetFilepath), $sourceOpenApi); $this->saveTargetOpenApi($syncApiTargetFilepath, $targetOpenApi); } catch (Throwable $throwable) { @@ -133,21 +134,6 @@ protected function getFilePath(string $rootDirectory, string $fileName): string return $rootDirectory . DIRECTORY_SEPARATOR . $fileName; } - /** - * @param \cebe\openapi\spec\OpenApi $targetOpenApi - * @param \cebe\openapi\spec\OpenApi $sourceOpenApi - * - * @return \cebe\openapi\spec\OpenApi - */ - protected function merge(OpenApi $targetOpenApi, OpenApi $sourceOpenApi): OpenApi - { - foreach ($this->mergerCollection as $merger) { - $targetOpenApi = $merger->merge($targetOpenApi, $sourceOpenApi); - } - - return $targetOpenApi; - } - /** * @param string $syncApiTargetFilepath * @param \cebe\openapi\spec\OpenApi $targetOpenApi diff --git a/src/SprykerSdk/SyncApi/SyncApiFactory.php b/src/SprykerSdk/SyncApi/SyncApiFactory.php index 26f7b37..897e836 100644 --- a/src/SprykerSdk/SyncApi/SyncApiFactory.php +++ b/src/SprykerSdk/SyncApi/SyncApiFactory.php @@ -15,10 +15,12 @@ use SprykerSdk\SyncApi\OpenApi\Builder\OpenApiBuilderInterface; use SprykerSdk\SyncApi\OpenApi\Builder\OpenApiCodeBuilder; use SprykerSdk\SyncApi\OpenApi\Builder\OpenApiCodeBuilderInterface; +use SprykerSdk\SyncApi\OpenApi\Merger\ComponentMerger; use SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleaner; use SprykerSdk\SyncApi\OpenApi\Merger\ComponentsCleanerInterface; use SprykerSdk\SyncApi\OpenApi\Merger\InfoMerger; use SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface; +use SprykerSdk\SyncApi\OpenApi\Merger\OpenApiMerger; use SprykerSdk\SyncApi\OpenApi\Merger\PathsMerger; use SprykerSdk\SyncApi\OpenApi\Merger\ServersMerger; use SprykerSdk\SyncApi\OpenApi\Updater\OpenApiUpdater; @@ -148,7 +150,18 @@ public function createOpenApiUpdater(): OpenApiUpdaterInterface return new OpenApiUpdater( $this->createMessageBuilder(), $this->getConfig(), + $this->createOpenApiMerger(), + ); + } + + /** + * @return \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface + */ + public function createOpenApiMerger(): MergerInterface + { + return new OpenApiMerger( $this->getMergerCollection(), + $this->createComponentsCleaner(), ); } @@ -171,9 +184,17 @@ public function createServersMerger(): MergerInterface /** * @return \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface */ - public function createPathMerger(): MergerInterface + public function createPathsMerger(): MergerInterface + { + return new PathsMerger($this->getConfig()); + } + + /** + * @return \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface + */ + public function createComponentsMerger(): MergerInterface { - return new PathsMerger($this->getConfig(), $this->createComponentsCleaner()); + return new ComponentMerger(); } /** @@ -192,7 +213,8 @@ public function getMergerCollection(): array return [ $this->createInfoMerger(), $this->createServersMerger(), - $this->createPathMerger(), + $this->createPathsMerger(), + $this->createComponentsMerger(), ]; } } diff --git a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php index ce9dc5b..c839fa6 100644 --- a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php +++ b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php @@ -136,7 +136,7 @@ public function testOpenApiUpdateConsoleStopsWithErrorWhenMergeProcessWillFails( // Act $commandTester->execute( [ - OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getOpenApiContentsWithIsMissingReferenceJson(), + OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => '{"components":null}', ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, diff --git a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php new file mode 100644 index 0000000..556ac10 --- /dev/null +++ b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php @@ -0,0 +1,45 @@ +tester->getFactory()->createComponentsCleaner(); + + $targetOpenApi = $this->tester->loadOpenApiFromYaml('merger/cleaner/target_openapi.yml'); + $expectedOpenApi = $this->tester->loadOpenApiFromYaml('merger/cleaner/expected_openapi.yml'); + + // Act + $actualOpenApi = $componentsCleaner->cleanUnused($targetOpenApi); + + // Assert + $this->assertSame(Writer::writeToYaml($expectedOpenApi), Writer::writeToYaml($actualOpenApi)); + } +} diff --git a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsMergerTest.php b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsMergerTest.php new file mode 100644 index 0000000..10ac87b --- /dev/null +++ b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsMergerTest.php @@ -0,0 +1,46 @@ +tester->getFactory()->createComponentsMerger(); + + $targetOpenApi = $this->tester->loadOpenApiFromYaml('merger/components/target_openapi.yml'); + $sourceOpenApi = $this->tester->loadOpenApiFromYaml('merger/components/source_openapi.yml'); + $expectedOpenApi = $this->tester->loadOpenApiFromYaml('merger/components/expected_openapi.yml'); + + // Act + $actualOpenApi = $componentsMerger->merge($targetOpenApi, $sourceOpenApi); + + // Assert + $this->assertSame(Writer::writeToYaml($expectedOpenApi), Writer::writeToYaml($actualOpenApi)); + } +} diff --git a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/PathsMergerTest.php b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/PathsMergerTest.php index aab3099..a92367b 100644 --- a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/PathsMergerTest.php +++ b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/PathsMergerTest.php @@ -9,8 +9,6 @@ use cebe\openapi\Writer; use Codeception\Test\Unit; -use SprykerSdk\SyncApi\OpenApi\Merger\Exception\ParameterNotFoundInSourceOpenApiException; -use SprykerSdk\SyncApi\OpenApi\Merger\Exception\SchemaNotFoundInSourceOpenApiException; use SprykerSdkTest\SyncApi\SyncApiTester; /** @@ -33,7 +31,7 @@ class PathsMergerTest extends Unit public function testPathMergedSuccessfully(): void { // Arrange - $pathMerger = $this->tester->getFactory()->createPathMerger(); + $pathMerger = $this->tester->getFactory()->createPathsMerger(); $targetOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/target_openapi.yml'); $sourceOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/source_openapi.yml'); @@ -45,40 +43,4 @@ public function testPathMergedSuccessfully(): void // Assert $this->assertSame(Writer::writeToYaml($expectedOpenApi), Writer::writeToYaml($actualOpenApi)); } - - /** - * @return void - */ - public function testPathMergerThrowsExceptionWhenParameterIsMissedInSourceOpenApi(): void - { - // Arrange - $pathMerger = $this->tester->getFactory()->createPathMerger(); - - $targetOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/target_openapi.yml'); - $sourceOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/source_openapi_with_parameter_missing.yml'); - - // Assert - $this->expectException(ParameterNotFoundInSourceOpenApiException::class); - - // Act - $pathMerger->merge($targetOpenApi, $sourceOpenApi); - } - - /** - * @return void - */ - public function testPathMergerThrowsExceptionWhenSchemaIsMissedInSourceOpenApi(): void - { - // Arrange - $pathMerger = $this->tester->getFactory()->createPathMerger(); - - $targetOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/target_openapi.yml'); - $sourceOpenApi = $this->tester->loadOpenApiFromYaml('merger/paths/source_openapi_with_schema_missing.yml'); - - // Assert - $this->expectException(SchemaNotFoundInSourceOpenApiException::class); - - // Act - $pathMerger->merge($targetOpenApi, $sourceOpenApi); - } } diff --git a/tests/_data/api/invalid/missed_references_openapi.yml b/tests/_data/api/invalid/missed_references_openapi.yml deleted file mode 100644 index 2abff75..0000000 --- a/tests/_data/api/invalid/missed_references_openapi.yml +++ /dev/null @@ -1,399 +0,0 @@ -openapi: 3.0.0 -info: - title: 'App Tenant Registry Service (ATRS)' - description: 'The App Tenant Registry Service is capable of managing Apps, Tenants and connection and configureation between them.' - version: 0.2.3 - -servers: - - url: https://glue.trs.demo-spryker.com - description: 'Main (production) server' - - url: https://glue.trs-staging.demo-spryker.com - description: 'Internal staging server for testing' - - url: http://glue.registry.spryker.local - description: 'Internal development server' - -paths: - /apps: - post: - summary: 'Registers an App within the Registry service' - requestBody: - description: 'Contains all required data to register an App within the Registry service.' - required: true - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/AppRegistrationApiRequest' - responses: - 201: - description: 'App is registered.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/AppRegistrationApiResponse' - 400: - description: 'Invalid request.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - 500: - description: 'Server error' - content: - # servers may want to report the error directly as simple text if things go very wrong - text/plain: - schema: - type: string - default: - description: 'Expected response to a bad request.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - get: - summary: 'Lists all available apps for a given locale.' - parameters: - - name: Accept-Language - in: header - description: 'Locale to be used to get the localised details.' - example: 'en' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'Tenant ID' - example: 'tenantUuid' - schema: - type: string - responses: - 200: - description: 'Expected response to a valid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/AppCollectionApiResponse' - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - /apps/{appId}: - get: - summary: 'Expose the details of a single app.' - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - name: Accept-Language - in: header - description: 'Locale to be used to get the Localised details.' - example: 'en' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'Tenant ID' - example: 'tenantUuid' - schema: - type: string - responses: - 200: - description: 'Expected response to a valid request' - content: - application/json: - schema: - $ref: '#/components/schemas/AppApiResponse' - - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - 404: - description: 'Resource not found.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - patch: - summary: 'Updates App information' - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - requestBody: - description: 'Contains all required data to register an App within the Registry service.' - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/AppRegistrationApiRequest' - responses: - 204: - description: 'App is updated.' - 404: - description: 'Resource not found.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessages' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - put: - summary: 'Upload an image for app' - requestBody: - description: 'Contains all required data to add image to app.' - required: true - content: - image/png: - schema: - $ref: '#/components/schemas/AppAddImageRequest' - responses: - 201: - description: 'Image is added.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/AppAddImageResponse' - 400: - description: 'Invalid request.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - default: - description: 'Expected response to a bad request.' - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - /apps/{appId}/connect: - post: - summary: 'Posts a connect request' - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'Tenant ID' - example: 'tenantUuid' - schema: - type: string - - name: Accept-Language - in: header - description: 'Locale to be used to get the Localised details.' - example: 'en' - schema: - type: string - - responses: - 200: - description: 'Expected response to a valid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/AppConnectionApiResponse' - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessages' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - /apps/{appId}/disconnect: - post: - summary: 'Posts a disconnect request' - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'Tenant ID' - example: 'tenantUuid' - schema: - type: string - - name: Accept-Language - in: header - description: 'Locale to be used to get the Localised details.' - example: 'en' - schema: - type: string - - responses: - 200: - description: 'Expected response to a valid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/AppConnectionApiResponse' - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessages' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - /apps/{appId}/configuration: - get: - summary: 'Gets the configuration for the App.' - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'UUID of the tenant.' - example: 'UUID_tenant123' - schema: - type: string - - name: Accept-Language - in: header - description: 'Locale to be used to get the Localised details.' - example: 'en' - schema: - type: string - responses: - 200: - description: 'Expected response to a valid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/AppConfigurationApiResponse' - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - 404: - description: 'Resource not found.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - - post: - summary: 'Posts the configuration for the App.' - operationId: 'AppsApi.Configuration' # Module.Controller - parameters: - - name: appId - in: path - required: true - description: 'UUID of the app.' - example: 'UUID_app123' - schema: - type: string - - name: x-tenant-id - in: header - required: true - description: 'UUID of the tenant.' - example: 'UUID_tenant123' - schema: - type: string - - name: Accept-Language - in: header - description: 'Locale to be used to get the Localised details.' - example: 'en' - schema: - type: string - requestBody: - description: 'Used to configure an App for a Tenant.' - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/AppConfigurationApiRequest' - responses: - 200: - description: 'Expected response to a valid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/AppConfigurationApiResponse' - 400: - description: 'Invalid request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' - default: - description: 'Expected response to a bad request.' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorMessage' diff --git a/tests/_data/api/merger/cleaner/expected_openapi.yml b/tests/_data/api/merger/cleaner/expected_openapi.yml new file mode 100644 index 0000000..74b970b --- /dev/null +++ b/tests/_data/api/merger/cleaner/expected_openapi.yml @@ -0,0 +1,33 @@ +openapi: 3.0.0 +paths: + /apps: + post: + summary: 'Registers an App within the Registry service' + parameters: + - $ref: '#/components/parameters/storeReference' + requestBody: + description: 'Contains all required data to register an App within the Registry service.' + required: true + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/AppRegistrationApiRequest' +components: + schemas: + AppRegistrationApiRequest: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestData: + properties: + type: + type: string + example: 'apps' + parameters: + storeReference: + name: X-Store-Reference + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string diff --git a/tests/_data/api/merger/cleaner/target_openapi.yml b/tests/_data/api/merger/cleaner/target_openapi.yml new file mode 100644 index 0000000..b433089 --- /dev/null +++ b/tests/_data/api/merger/cleaner/target_openapi.yml @@ -0,0 +1,45 @@ +openapi: 3.0.0 +paths: + /apps: + post: + summary: 'Registers an App within the Registry service' + parameters: + - $ref: '#/components/parameters/storeReference' + requestBody: + description: 'Contains all required data to register an App within the Registry service.' + required: true + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/AppRegistrationApiRequest' +components: + schemas: + AppRegistrationApiRequest: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestData: + properties: + type: + type: string + example: 'apps' + AppRegistrationApiRequestDataToRemove: + properties: + type: + type: string + example: 'apps' + parameters: + storeReference: + name: X-Store-Reference + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string + storeReferenceToRemove: + name: 'to remove' + in: 'to remove' + required: 'to remove' + description: 'to remove' + schema: + type: 'to remove' diff --git a/tests/_data/api/merger/components/expected_openapi.yml b/tests/_data/api/merger/components/expected_openapi.yml new file mode 100644 index 0000000..802568d --- /dev/null +++ b/tests/_data/api/merger/components/expected_openapi.yml @@ -0,0 +1,37 @@ +openapi: 3.0.0 +components: + schemas: + AppRegistrationApiRequestExisted: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestExistedToReplace: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestNew: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + parameters: + storeReferenceExisted: + name: X-Store-Reference-Existed + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string + storeReferenceExistedToReplace: + name: X-Store-Reference-Existed + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string + storeReferenceNew: + name: X-Store-Reference-New + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string diff --git a/tests/_data/api/merger/components/source_openapi.yml b/tests/_data/api/merger/components/source_openapi.yml new file mode 100644 index 0000000..de2f1bb --- /dev/null +++ b/tests/_data/api/merger/components/source_openapi.yml @@ -0,0 +1,26 @@ +openapi: 3.0.0 +components: + schemas: + AppRegistrationApiRequestExistedToReplace: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestNew: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + parameters: + storeReferenceExistedToReplace: + name: X-Store-Reference-Existed + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string + storeReferenceNew: + name: X-Store-Reference-New + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string diff --git a/tests/_data/api/merger/components/target_openapi.yml b/tests/_data/api/merger/components/target_openapi.yml new file mode 100644 index 0000000..a718810 --- /dev/null +++ b/tests/_data/api/merger/components/target_openapi.yml @@ -0,0 +1,26 @@ +openapi: 3.0.0 +components: + schemas: + AppRegistrationApiRequestExisted: + properties: + data: + $ref: '#/components/schemas/AppRegistrationApiRequestData' + AppRegistrationApiRequestExistedToReplace: + properties: + data: + $ref: 'REPLACE' + parameters: + storeReferenceExisted: + name: X-Store-Reference-Existed + in: header + required: true + description: 'Reference of the Tenants store.' + schema: + type: string + storeReferenceExistedToReplace: + name: X-Store-Reference-Existed + in: header + required: true + description: 'REPLACE' + schema: + type: string diff --git a/tests/_data/api/merger/paths/expected_openapi.yml b/tests/_data/api/merger/paths/expected_openapi.yml index 98689d5..1e2ab70 100644 --- a/tests/_data/api/merger/paths/expected_openapi.yml +++ b/tests/_data/api/merger/paths/expected_openapi.yml @@ -61,113 +61,4 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorMessage' -components: - parameters: - storeReference: - name: X-Store-Reference - in: header - required: true - description: 'Reference of the Tenants store.' - schema: - type: string - testParamArray: - name: testParamArray - in: header - required: true - description: 'Reference of the Tenants store.' - schema: - type: array - items: - $ref: '#/components/schemas/testParamRef' - schemas: - AppRegistrationApiRequest: - properties: - data: - $ref: '#/components/schemas/AppRegistrationApiRequestData' - AppRegistrationApiRequestData: - properties: - type: - type: string - example: 'apps' - - attributes: - $ref: '#/components/schemas/AppRegistrationApiRequestAttributes' - AppRegistrationApiRequestAttributes: - properties: - api: - type: string - example: '{ - "connect": "https://some-url", - "disconnect": "https://some-url", - "configuration": "https://some-url" - }' - manifest: - type: string - example: '{ - "en_US", {}, - "de_DE", {}, - }' - configuration: - type: string - example: '{"type": "object", "title": "title", "description": "description", "properties": {"username": {"type": "string","title": "username"}}}' - translation: - type: string - example: '{"username": {"de_DE": "Benutzername","en_US": "Username"}}' - required: - - manifest - ApiErrorMessage: - properties: - code: - type: string - detail: - type: string - status: - type: integer - testParamRef: - properties: - data: - type: string - AppCollectionApiResponse: - properties: - data: - type: array - items: - $ref: '#/components/schemas/AppCollectionApiResponseData' - AppCollectionApiResponseData: - properties: - type: - type: string - example: 'App Collection' - items: - $ref: '#/components/schemas/AppApiResponseAttributes' - AppApiResponseAttributes: - properties: - id: - type: string - example: 'UUID_app123' - name: - type: string - example: 'Spryker App' - description: - type: string - example: 'App short description' - status: - $ref: 'remote_status.yml#/components/schemas/ConnectionStatus' - categories: - type: array - items: - type: string - example: [ 'Category A', 'Category B' ] - labels: - type: array - items: - type: string - example: [ 'Label A', 'Label B' ] - iconUrl: - type: string - example: 'https://app.com/icon/app.png' - manifest: - $ref: 'remote_manifest.yaml#/components/schemas/ConnectionStatus' - configuration: - type: string - example: '{"type": "object", "title": "Credentials", "description": "Security area", "properties": {"username": {"type": "string","title": "username"}}}' +components: []` diff --git a/tests/_data/api/merger/paths/source_openapi.yml b/tests/_data/api/merger/paths/source_openapi.yml index b5ea9e8..df9beb6 100644 --- a/tests/_data/api/merger/paths/source_openapi.yml +++ b/tests/_data/api/merger/paths/source_openapi.yml @@ -25,79 +25,4 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorMessage' -components: - schemas: - testParamRef: - properties: - data: - type: string - AppCollectionApiResponse: - properties: - data: - type: array - items: - $ref: '#/components/schemas/AppCollectionApiResponseData' - - AppCollectionApiResponseData: - properties: - type: - type: string - example: 'App Collection' - items: - $ref: '#/components/schemas/AppApiResponseAttributes' - AppApiResponseAttributes: - properties: - id: - type: string - example: 'UUID_app123' - name: - type: string - example: 'Spryker App' - description: - type: string - example: 'App short description' - status: - $ref: 'remote_status.yml#/components/schemas/ConnectionStatus' - categories: - type: array - items: - type: string - example: [ 'Category A', 'Category B' ] - labels: - type: array - items: - type: string - example: [ 'Label A', 'Label B' ] - iconUrl: - type: string - example: 'https://app.com/icon/app.png' - manifest: - $ref: 'remote_manifest.yaml#/components/schemas/ConnectionStatus' - configuration: - type: string - example: '{"type": "object", "title": "Credentials", "description": "Security area", "properties": {"username": {"type": "string","title": "username"}}}' - ApiErrorMessage: - properties: - code: - type: string - detail: - type: string - status: - type: integer - parameters: - storeReference: - name: X-Store-Reference - in: header - required: true - description: 'Reference of the Tenants store.' - schema: - type: string - testParamArray: - name: testParamArray - in: header - required: true - description: 'Reference of the Tenants store.' - schema: - type: array - items: - $ref: '#/components/schemas/testParamRef' +components: [] diff --git a/tests/_data/api/merger/paths/source_openapi_with_parameter_missing.yml b/tests/_data/api/merger/paths/source_openapi_with_parameter_missing.yml deleted file mode 100644 index f70f5d3..0000000 --- a/tests/_data/api/merger/paths/source_openapi_with_parameter_missing.yml +++ /dev/null @@ -1,6 +0,0 @@ -openapi: 3.0.0 -paths: - /apps: - get: - parameters: - - $ref: '#/components/parameters/storeReference' diff --git a/tests/_data/api/merger/paths/source_openapi_with_schema_missing.yml b/tests/_data/api/merger/paths/source_openapi_with_schema_missing.yml deleted file mode 100644 index 6faeece..0000000 --- a/tests/_data/api/merger/paths/source_openapi_with_schema_missing.yml +++ /dev/null @@ -1,10 +0,0 @@ -openapi: 3.0.0 -paths: - /apps: - get: - responses: - 200: - content: - application/json: - schema: - $ref: '#/components/schemas/AppCollectionApiResponse' diff --git a/tests/_data/api/merger/paths/target_openapi.yml b/tests/_data/api/merger/paths/target_openapi.yml index e6573d9..f7c8abe 100644 --- a/tests/_data/api/merger/paths/target_openapi.yml +++ b/tests/_data/api/merger/paths/target_openapi.yml @@ -60,71 +60,4 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorMessage' -components: - schemas: - AppRegistrationApiRequest: - properties: - data: - $ref: '#/components/schemas/AppRegistrationApiRequestData' - AppRegistrationApiRequestData: - properties: - type: - type: string - example: 'apps' - - attributes: - $ref: '#/components/schemas/AppRegistrationApiRequestAttributes' - AppRegistrationApiRequestAttributes: - properties: - api: - type: string - example: '{ - "connect": "https://some-url", - "disconnect": "https://some-url", - "configuration": "https://some-url" - }' - manifest: - type: string - example: '{ - "en_US", {}, - "de_DE", {}, - }' - configuration: - type: string - example: '{"type": "object", "title": "title", "description": "description", "properties": {"username": {"type": "string","title": "username"}}}' - translation: - type: string - example: '{"username": {"de_DE": "Benutzername","en_US": "Username"}}' - required: - - manifest - ApiErrorMessage: - properties: - code: - type: string - detail: - type: string - status: - type: integer - ApiErrorMessageToRemove: - properties: - code: - type: 'to remove' - detail: - type: 'to remove' - status: - type: 'to remove' - parameters: - storeReferenceObsolete: - name: X-Store-Reference-Obsolete - in: header - required: true - description: 'Reference of the Tenants store. (to remove)' - schema: - type: string - storeReferenceToRemove: - name: 'to remove' - in: 'to remove' - required: 'to remove' - description: 'to remove' - schema: - type: 'to remove' +components: [] diff --git a/tests/_support/Helper/OpenApiValidatorHelper.php b/tests/_support/Helper/OpenApiValidatorHelper.php index 94ff7dc..6b8ab65 100644 --- a/tests/_support/Helper/OpenApiValidatorHelper.php +++ b/tests/_support/Helper/OpenApiValidatorHelper.php @@ -34,14 +34,6 @@ public function getValidOpenApiContentsAsJson(): string return json_encode(Yaml::parseFile(codecept_data_dir('api/valid/valid_openapi.yml'))); } - /** - * @return string - */ - public function getOpenApiContentsWithIsMissingReferenceJson(): string - { - return json_encode(Yaml::parseFile(codecept_data_dir('api/invalid/missed_references_openapi.yml'))); - } - /** * @return string */ From afca5ab15ca816a6d1916877812131cd8a7bdccb Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Mon, 24 Oct 2022 16:44:16 +0300 Subject: [PATCH 02/14] APPS-4380 Stop removing unused schemas to avoid issues with configuration schema --- src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php index e860d0d..2cb39f8 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php @@ -25,9 +25,7 @@ public function cleanUnused(OpenApi $openApi): OpenApi $references = ReferenceFinder::findInArray($openApiAsArray); - $openApi = $this->cleanUnusedParameters($openApi, $references); - - return $this->cleanUnusedSchemas($openApi, $references); + return $this->cleanUnusedParameters($openApi, $references); } /** From 8dffd99caf2f51979410fd5437f818b759379b32 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Tue, 25 Oct 2022 08:47:25 +0300 Subject: [PATCH 03/14] APPS-4380 Marked components cleaner test as skipped - isn't used now --- .../SyncApi/OpenApi/Merger/ComponentsCleanerTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php index 556ac10..f410bc0 100644 --- a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php +++ b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php @@ -30,6 +30,8 @@ class ComponentsCleanerTest extends Unit */ public function testPathMergedSuccessfully(): void { + $this->markTestSkipped('Components cleaner is currently unused'); + // Arrange $componentsCleaner = $this->tester->getFactory()->createComponentsCleaner(); From 4d56b26b8c613637eb665dc61db9eac9658f838c Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Thu, 27 Oct 2022 16:10:55 +0300 Subject: [PATCH 04/14] APPS-4380 Components upgrade - CR fixes --- src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php | 4 +++- src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php | 2 +- src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php | 2 +- .../SyncApi/OpenApi/Merger/ComponentsCleanerTest.php | 2 -- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php index 2cb39f8..e860d0d 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/ComponentsCleaner.php @@ -25,7 +25,9 @@ public function cleanUnused(OpenApi $openApi): OpenApi $references = ReferenceFinder::findInArray($openApiAsArray); - return $this->cleanUnusedParameters($openApi, $references); + $openApi = $this->cleanUnusedParameters($openApi, $references); + + return $this->cleanUnusedSchemas($openApi, $references); } /** diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php index ed204d3..a5e09fc 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/OpenApiMerger.php @@ -45,6 +45,6 @@ public function merge(OpenApi $targetOpenApi, OpenApi $sourceOpenApi): OpenApi $targetOpenApi = $merger->merge($targetOpenApi, $sourceOpenApi); } - return $this->componentsCleaner->cleanUnused($targetOpenApi); + return $targetOpenApi; } } diff --git a/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php b/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php index c03df69..cfe4fba 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Merger/PathsMerger.php @@ -56,7 +56,7 @@ public function merge(OpenApi $targetOpenApi, OpenApi $sourceOpenApi): OpenApi * * @return \cebe\openapi\spec\OpenApi */ - private function mergePath( + protected function mergePath( OpenApi $targetOpenApi, string $pathName, PathItem $sourcePathItem diff --git a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php index f410bc0..556ac10 100644 --- a/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php +++ b/tests/SprykerSdkTest/SyncApi/OpenApi/Merger/ComponentsCleanerTest.php @@ -30,8 +30,6 @@ class ComponentsCleanerTest extends Unit */ public function testPathMergedSuccessfully(): void { - $this->markTestSkipped('Components cleaner is currently unused'); - // Arrange $componentsCleaner = $this->tester->getFactory()->createComponentsCleaner(); From cc1d4d3df8a136d9606371ae0dcc779f5cfb175b Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Thu, 27 Oct 2022 16:20:08 +0300 Subject: [PATCH 05/14] APPS-4380 Fixed tests --- tests/_data/api/update/expected_openapi.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/_data/api/update/expected_openapi.yml b/tests/_data/api/update/expected_openapi.yml index 382c09b..d52fa9b 100644 --- a/tests/_data/api/update/expected_openapi.yml +++ b/tests/_data/api/update/expected_openapi.yml @@ -35,7 +35,6 @@ paths: schema: type: string components: - parameters: [] schemas: AppRegistrationApiRequest: properties: From 5246ae4c7a097ed68712a78c204e1a56c69030c9 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Mon, 31 Oct 2022 13:49:56 +0200 Subject: [PATCH 06/14] APPS-4380 Added option to provide schema update as file --- .../SyncApi/Console/OpenApiUpdateConsole.php | 24 ++++- .../SyncApi/OpenApi/Reader/OpenApiReader.php | 66 ++++++++++++ .../OpenApi/Reader/OpenApiReaderInterface.php | 22 ++++ .../OpenApi/Updater/OpenApiUpdater.php | 77 ++++++++++++-- src/SprykerSdk/SyncApi/SyncApiFactory.php | 8 ++ src/Transfer/UpdateOpenApiRequestTransfer.php | 100 ++++++++++++++++++ 6 files changed, 289 insertions(+), 8 deletions(-) create mode 100644 src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php create mode 100644 src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReaderInterface.php diff --git a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php index 0646701..7be4ff2 100644 --- a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php +++ b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php @@ -25,6 +25,21 @@ class OpenApiUpdateConsole extends AbstractConsole */ public const ARGUMENT_OPENAPI_DOC_DESCRIPTION = 'A JSON-ed string that contains a valid OpenAPI scheme'; + /** + * @var string + */ + public const OPTION_OPEN_API_DOC_FILE = 'openapi-doc-file'; + + /** + * @var string + */ + public const OPTION_OPEN_API_DOC_FILE_SHORT = 'd'; + + /** + * @var string + */ + public const OPTION_OPEN_API_DOC_FILE_DESCRIPTION = 'Path to source OpenAPI file. Use this option if you want a provide a source file instead of source JSON. Supports both JSON and YAML files.'; + /** * @var string */ @@ -64,7 +79,7 @@ protected function configure(): void ->setDescription('Updates an OpenAPI file specified in options with provided OpenAPI doc') ->addArgument( static::ARGUMENT_OPENAPI_DOC, - InputArgument::REQUIRED, + InputArgument::OPTIONAL, static::ARGUMENT_OPENAPI_DOC_DESCRIPTION, ) ->addOption( @@ -74,6 +89,12 @@ protected function configure(): void static::OPTION_OPEN_API_FILE_DESCRIPTION, $this->getConfig()->getDefaultRelativePathToOpenApiFile(), ) + ->addOption( + static::OPTION_OPEN_API_DOC_FILE, + static::OPTION_OPEN_API_DOC_FILE_SHORT, + InputOption::VALUE_OPTIONAL, + static::OPTION_OPEN_API_DOC_FILE_DESCRIPTION, + ) ->addOption( static::OPTION_PROJECT_ROOT, static::OPTION_PROJECT_ROOT_SHORT, @@ -93,6 +114,7 @@ public function execute(InputInterface $input, OutputInterface $output): int { $updateOpenApiRequestTransfer = (new UpdateOpenApiRequestTransfer()) ->setOpenApiDoc($input->getArgument(static::ARGUMENT_OPENAPI_DOC)) + ->setOpenApiDocFile($input->getOption(static::OPTION_OPEN_API_DOC_FILE)) ->setOpenApiFile($input->getOption(static::OPTION_OPEN_API_FILE)) ->setProjectRoot($input->getOption(static::OPTION_PROJECT_ROOT)); diff --git a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php new file mode 100644 index 0000000..d6a31fa --- /dev/null +++ b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php @@ -0,0 +1,66 @@ +getFileExtension($filePath); + + if ($fileExtension === static::FILE_EXTENSION_JSON) { + return Reader::readFromJsonFile($filePath); + } + + if ($fileExtension === static::FILE_EXTENSION_YAML || $fileExtension === static::FILE_EXTENSION_YML) { + return Reader::readFromYamlFile($filePath); + } + + throw new OpenApiFileReadException('Unsupported OpenAPI file format'); + } + + /** + * @param string $filePath + * + * @return string + */ + protected function getFileExtension(string $filePath): string + { + return pathinfo($filePath)['extension']; + } +} diff --git a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReaderInterface.php b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReaderInterface.php new file mode 100644 index 0000000..4b802f6 --- /dev/null +++ b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReaderInterface.php @@ -0,0 +1,22 @@ +messageBuilder = $messageBuilder; $this->syncApiConfig = $syncApiConfig; $this->openApiMerger = $openApiMerger; + $this->openApiReader = $openApiReader; } /** @@ -59,11 +69,13 @@ public function __construct( public function updateOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer): OpenApiResponseTransfer { try { - if (!$this->isJsonValid($updateOpenApiRequestTransfer->getOpenApiDocOrFail())) { - return $this->createValidationErrorMessage('Provided JSON is invalid'); + $openApiErrorResponseTransfer = $this->validateSourceOpenApi($updateOpenApiRequestTransfer); + + if ($openApiErrorResponseTransfer) { + return $openApiErrorResponseTransfer; } - $sourceOpenApi = Reader::readFromJson($updateOpenApiRequestTransfer->getOpenApiDocOrFail()); + $sourceOpenApi = $this->getSourceOpenApi($updateOpenApiRequestTransfer); $syncApiTargetFilepath = $this->getSyncApiTargetFilepath($updateOpenApiRequestTransfer); @@ -77,6 +89,53 @@ public function updateOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequest return $this->createSuccessResponse($syncApiTargetFilepath); } + /** + * @param \Transfer\UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer + * + * @return \Transfer\OpenApiResponseTransfer|null + */ + protected function validateSourceOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer): ?OpenApiResponseTransfer + { + if (!$updateOpenApiRequestTransfer->getOpenApiDoc() && !$updateOpenApiRequestTransfer->getOpenApiDocFile()) { + return $this->createValidationErrorMessage('No source OpenApi data provided'); + } + + if ($updateOpenApiRequestTransfer->getOpenApiDoc()) { + if (!$this->isJsonValid($updateOpenApiRequestTransfer->getOpenApiDocOrFail())) { + return $this->createValidationErrorMessage('Provided JSON data is invalid'); + } + } + + if ($updateOpenApiRequestTransfer->getOpenApiDocFile()) { + if (!file_exists($this->getFilePath( + $updateOpenApiRequestTransfer->getProjectRootOrFail(), + $updateOpenApiRequestTransfer->getOpenApiDocFileOrFail()) + )) { + return $this->createValidationErrorMessage('Provided OpenAPI file does not exist'); + } + } + + return null; + } + + /** + * @param \Transfer\UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer + * + * @return \cebe\openapi\spec\OpenApi + */ + protected function getSourceOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer): OpenApi + { + if ($updateOpenApiRequestTransfer->getOpenApiDoc()) { + return $this->openApiReader->readOpenApiFromJsonString($updateOpenApiRequestTransfer->getOpenApiDocOrFail()); + } + + if ($updateOpenApiRequestTransfer->getOpenApiDocFile()) { + return $this->openApiReader->readOpenApiFromFile($updateOpenApiRequestTransfer->getOpenApiDocFileOrFail()); + } + + throw new OpenApiFileReadException('No OpenAPI data provided for update'); + } + /** * @param string $getOpenApiDocOrFail * @@ -131,6 +190,10 @@ protected function getTargetOpenApi(string $syncApiTargetFilepath): OpenApi */ protected function getFilePath(string $rootDirectory, string $fileName): string { + if ($rootDirectory === '') { + return $fileName; + } + return $rootDirectory . DIRECTORY_SEPARATOR . $fileName; } diff --git a/src/SprykerSdk/SyncApi/SyncApiFactory.php b/src/SprykerSdk/SyncApi/SyncApiFactory.php index 897e836..7a0276c 100644 --- a/src/SprykerSdk/SyncApi/SyncApiFactory.php +++ b/src/SprykerSdk/SyncApi/SyncApiFactory.php @@ -23,6 +23,8 @@ use SprykerSdk\SyncApi\OpenApi\Merger\OpenApiMerger; use SprykerSdk\SyncApi\OpenApi\Merger\PathsMerger; use SprykerSdk\SyncApi\OpenApi\Merger\ServersMerger; +use SprykerSdk\SyncApi\OpenApi\Reader\OpenApiReader; +use SprykerSdk\SyncApi\OpenApi\Reader\OpenApiReaderInterface; use SprykerSdk\SyncApi\OpenApi\Updater\OpenApiUpdater; use SprykerSdk\SyncApi\OpenApi\Updater\OpenApiUpdaterInterface; use SprykerSdk\SyncApi\OpenApi\Validator\OpenApiValidator; @@ -151,6 +153,7 @@ public function createOpenApiUpdater(): OpenApiUpdaterInterface $this->createMessageBuilder(), $this->getConfig(), $this->createOpenApiMerger(), + $this->createOpenApiReader(), ); } @@ -165,6 +168,11 @@ public function createOpenApiMerger(): MergerInterface ); } + public function createOpenApiReader(): OpenApiReaderInterface + { + return new OpenApiReader(); + } + /** * @return \SprykerSdk\SyncApi\OpenApi\Merger\MergerInterface */ diff --git a/src/Transfer/UpdateOpenApiRequestTransfer.php b/src/Transfer/UpdateOpenApiRequestTransfer.php index fb51883..bfcccff 100644 --- a/src/Transfer/UpdateOpenApiRequestTransfer.php +++ b/src/Transfer/UpdateOpenApiRequestTransfer.php @@ -17,6 +17,11 @@ class UpdateOpenApiRequestTransfer extends AbstractTransfer */ public const OPEN_API_FILE = 'openApiFile'; + /** + * @var string + */ + public const OPEN_API_DOC_FILE = 'openApiDocFile'; + /** * @var string */ @@ -49,6 +54,9 @@ class UpdateOpenApiRequestTransfer extends AbstractTransfer 'open_api_file' => 'openApiFile', 'openApiFile' => 'openApiFile', 'OpenApiFile' => 'openApiFile', + 'open_api_doc_file' => 'openApiDocFile', + 'openApiDocFile' => 'openApiDocFile', + 'OpenApiDocFile' => 'openApiDocFile', 'open_api_doc' => 'openApiDoc', 'openApiDoc' => 'openApiDoc', 'OpenApiDoc' => 'openApiDoc', @@ -73,6 +81,18 @@ class UpdateOpenApiRequestTransfer extends AbstractTransfer 'is_nullable' => false, 'is_strict' => false, ], + self::OPEN_API_DOC_FILE => [ + 'type' => 'string', + 'type_shim' => null, + 'name_underscore' => 'open_api_doc_file', + 'is_collection' => false, + 'is_transfer' => false, + 'is_value_object' => false, + 'rest_request_parameter' => 'no', + 'is_associative' => false, + 'is_nullable' => false, + 'is_strict' => false, + ], self::OPEN_API_DOC => [ 'type' => 'string', 'type_shim' => null, @@ -172,6 +192,79 @@ public function requireOpenApiFile() return $this; } + /** + * @module Syncapi + * + * @param string|null $openApiDocFile + * + * @return $this + */ + public function setOpenApiDocFile($openApiDocFile) + { + $this->openApiDocFile = $openApiDocFile; + $this->modifiedProperties[self::OPEN_API_DOC_FILE] = true; + + return $this; + } + + /** + * @module Syncapi + * + * @return string|null + */ + public function getOpenApiDocFile() + { + return $this->openApiDocFile; + } + + /** + * @module Syncapi + * + * @param string|null $openApiDocFile + * + * @throws \Spryker\Shared\Kernel\Transfer\Exception\NullValueException + * + * @return $this + */ + public function setOpenApiDocFileOrFail($openApiDocFile) + { + if ($openApiDocFile === null) { + $this->throwNullValueException(static::OPEN_API_DOC_FILE); + } + + return $this->setOpenApiDocFile($openApiDocFile); + } + + /** + * @module Syncapi + * + * @throws \Spryker\Shared\Kernel\Transfer\Exception\NullValueException + * + * @return string + */ + public function getOpenApiDocFileOrFail() + { + if ($this->openApiDocFile === null) { + $this->throwNullValueException(static::OPEN_API_DOC_FILE); + } + + return $this->openApiDocFile; + } + + /** + * @module Syncapi + * + * @throws \Spryker\Shared\Kernel\Transfer\Exception\RequiredTransferPropertyException + * + * @return $this + */ + public function requireOpenApiDocFile() + { + $this->assertPropertyIsSet(self::OPEN_API_DOC_FILE); + + return $this; + } + /** * @module Syncapi * @@ -333,6 +426,7 @@ public function fromArray(array $data, $ignoreMissingProperty = false) switch ($normalizedPropertyName) { case 'openApiFile': + case 'openApiDocFile': case 'openApiDoc': case 'projectRoot': $this->$normalizedPropertyName = $value; @@ -455,6 +549,7 @@ public function modifiedToArrayRecursiveCamelCased(): array } switch ($property) { case 'openApiFile': + case 'openApiDocFile': case 'openApiDoc': case 'projectRoot': $values[$arrayKey] = $value; @@ -484,6 +579,7 @@ public function modifiedToArrayRecursiveNotCamelCased(): array } switch ($property) { case 'openApiFile': + case 'openApiDocFile': case 'openApiDoc': case 'projectRoot': $values[$arrayKey] = $value; @@ -543,6 +639,7 @@ public function toArrayNotRecursiveCamelCased(): array { return [ 'openApiFile' => $this->openApiFile, + 'openApiDocFile' => $this->openApiDocFile, 'openApiDoc' => $this->openApiDoc, 'projectRoot' => $this->projectRoot, ]; @@ -555,6 +652,7 @@ public function toArrayNotRecursiveNotCamelCased(): array { return [ 'open_api_file' => $this->openApiFile, + 'open_api_doc_file' => $this->openApiDocFile, 'open_api_doc' => $this->openApiDoc, 'project_root' => $this->projectRoot, ]; @@ -567,6 +665,7 @@ public function toArrayRecursiveNotCamelCased(): array { return [ 'open_api_file' => $this->openApiFile instanceof AbstractTransfer ? $this->openApiFile->toArray(true, false) : $this->openApiFile, + 'open_api_doc_file' => $this->openApiDocFile instanceof AbstractTransfer ? $this->openApiDocFile->toArray(true, false) : $this->openApiDocFile, 'open_api_doc' => $this->openApiDoc instanceof AbstractTransfer ? $this->openApiDoc->toArray(true, false) : $this->openApiDoc, 'project_root' => $this->projectRoot instanceof AbstractTransfer ? $this->projectRoot->toArray(true, false) : $this->projectRoot, ]; @@ -579,6 +678,7 @@ public function toArrayRecursiveCamelCased(): array { return [ 'openApiFile' => $this->openApiFile instanceof AbstractTransfer ? $this->openApiFile->toArray(true, true) : $this->openApiFile, + 'openApiDocFile' => $this->openApiDocFile instanceof AbstractTransfer ? $this->openApiDocFile->toArray(true, true) : $this->openApiDocFile, 'openApiDoc' => $this->openApiDoc instanceof AbstractTransfer ? $this->openApiDoc->toArray(true, true) : $this->openApiDoc, 'projectRoot' => $this->projectRoot instanceof AbstractTransfer ? $this->projectRoot->toArray(true, true) : $this->projectRoot, ]; From 4b220a0c36d109e67c3bf1dc84fd31f124699031 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Mon, 31 Oct 2022 15:26:48 +0200 Subject: [PATCH 07/14] Fixed transfer --- src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php | 4 +++- src/Transfer/UpdateOpenApiRequestTransfer.php | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php index d6a31fa..21942a7 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php @@ -61,6 +61,8 @@ public function readOpenApiFromFile(string $filePath): OpenApi */ protected function getFileExtension(string $filePath): string { - return pathinfo($filePath)['extension']; + $parts = explode('.', basename($filePath)); + + return array_pop($parts); } } diff --git a/src/Transfer/UpdateOpenApiRequestTransfer.php b/src/Transfer/UpdateOpenApiRequestTransfer.php index bfcccff..4f1df12 100644 --- a/src/Transfer/UpdateOpenApiRequestTransfer.php +++ b/src/Transfer/UpdateOpenApiRequestTransfer.php @@ -37,6 +37,11 @@ class UpdateOpenApiRequestTransfer extends AbstractTransfer */ protected $openApiFile; + /** + * @var string|null + */ + protected $openApiDocFile; + /** * @var string|null */ From 046cd4c4eb62227da515a6ecae1e44f499ddfa11 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Mon, 31 Oct 2022 15:31:29 +0200 Subject: [PATCH 08/14] Rector fix --- .../SyncApi/OpenApi/Updater/OpenApiUpdater.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php b/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php index c625e3f..1e0df63 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Updater/OpenApiUpdater.php @@ -106,13 +106,11 @@ protected function validateSourceOpenApi(UpdateOpenApiRequestTransfer $updateOpe } } - if ($updateOpenApiRequestTransfer->getOpenApiDocFile()) { - if (!file_exists($this->getFilePath( - $updateOpenApiRequestTransfer->getProjectRootOrFail(), - $updateOpenApiRequestTransfer->getOpenApiDocFileOrFail()) - )) { - return $this->createValidationErrorMessage('Provided OpenAPI file does not exist'); - } + if (!file_exists($this->getFilePath( + $updateOpenApiRequestTransfer->getProjectRootOrFail(), + $updateOpenApiRequestTransfer->getOpenApiDocFileOrFail()) + )) { + return $this->createValidationErrorMessage('Provided OpenAPI file does not exist'); } return null; From 28c1ec62cde3e161f3abc113bc89c8fc982f2ae0 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Mon, 31 Oct 2022 19:44:31 +0200 Subject: [PATCH 09/14] Code style fixes --- .../SyncApi/OpenApi/Reader/OpenApiReader.php | 14 ++++++++++---- .../OpenApi/Reader/OpenApiReaderInterface.php | 5 +++++ .../SyncApi/OpenApi/Updater/OpenApiUpdater.php | 13 +++++++++---- src/SprykerSdk/SyncApi/SyncApiFactory.php | 3 +++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php index 21942a7..3aa70d6 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Reader/OpenApiReader.php @@ -1,5 +1,10 @@ getFilePath( - $updateOpenApiRequestTransfer->getProjectRootOrFail(), - $updateOpenApiRequestTransfer->getOpenApiDocFileOrFail()) - )) { + if ( + $updateOpenApiRequestTransfer->getOpenApiDocFile() + && !file_exists($this->getFilePath( + $updateOpenApiRequestTransfer->getProjectRootOrFail(), + $updateOpenApiRequestTransfer->getOpenApiDocFileOrFail(), + )) + ) { return $this->createValidationErrorMessage('Provided OpenAPI file does not exist'); } @@ -119,6 +122,8 @@ protected function validateSourceOpenApi(UpdateOpenApiRequestTransfer $updateOpe /** * @param \Transfer\UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer * + * @throws \SprykerSdk\SyncApi\Exception\OpenApiFileReadException + * * @return \cebe\openapi\spec\OpenApi */ protected function getSourceOpenApi(UpdateOpenApiRequestTransfer $updateOpenApiRequestTransfer): OpenApi diff --git a/src/SprykerSdk/SyncApi/SyncApiFactory.php b/src/SprykerSdk/SyncApi/SyncApiFactory.php index 7a0276c..9cfbc2c 100644 --- a/src/SprykerSdk/SyncApi/SyncApiFactory.php +++ b/src/SprykerSdk/SyncApi/SyncApiFactory.php @@ -168,6 +168,9 @@ public function createOpenApiMerger(): MergerInterface ); } + /** + * @return \SprykerSdk\SyncApi\OpenApi\Reader\OpenApiReaderInterface + */ public function createOpenApiReader(): OpenApiReaderInterface { return new OpenApiReader(); From 7de9bd4da7189250d9ab2b7d14cdb1f103b3e780 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Tue, 1 Nov 2022 13:42:14 +0200 Subject: [PATCH 10/14] Changed console command default parameter --- src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php index 7be4ff2..fde1110 100644 --- a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php +++ b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php @@ -100,7 +100,7 @@ protected function configure(): void static::OPTION_PROJECT_ROOT_SHORT, InputOption::VALUE_OPTIONAL, static::OPTION_PROJECT_ROOT_DESCRIPTION, - $this->getConfig()->getProjectRootPath(), + '', ); } From 0ba1ef3ee1fb86d5293b76fd7f6d40bef83fa883 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Wed, 2 Nov 2022 12:39:59 +0200 Subject: [PATCH 11/14] Code style fix --- src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php index fde1110..5979889 100644 --- a/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php +++ b/src/SprykerSdk/SyncApi/Console/OpenApiUpdateConsole.php @@ -100,7 +100,7 @@ protected function configure(): void static::OPTION_PROJECT_ROOT_SHORT, InputOption::VALUE_OPTIONAL, static::OPTION_PROJECT_ROOT_DESCRIPTION, - '', + '', ); } From 34f459850f505ac1091fcaa68ab46f3efa85732d Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Wed, 2 Nov 2022 12:48:50 +0200 Subject: [PATCH 12/14] Fixed test --- .../SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php index c839fa6..ec79e70 100644 --- a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php +++ b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php @@ -39,6 +39,7 @@ public function testOpenApiUpdateConsoleSuccessfullyUpdatesAnExistingFile(): voi $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data' ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, @@ -63,6 +64,7 @@ public function testOpenApiUpdateConsoleSuccessfullyAddsANewFileWithPassedJson() $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data' ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, From d8a4b3c1785a01e95932e034ff5eb0c9c5a31376 Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Wed, 2 Nov 2022 13:01:10 +0200 Subject: [PATCH 13/14] Fixed test --- .../SyncApi/Console/OpenApiUpdateConsoleTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php index ec79e70..df38643 100644 --- a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php +++ b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php @@ -39,7 +39,7 @@ public function testOpenApiUpdateConsoleSuccessfullyUpdatesAnExistingFile(): voi $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), - '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data' + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data', ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, @@ -64,7 +64,7 @@ public function testOpenApiUpdateConsoleSuccessfullyAddsANewFileWithPassedJson() $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), - '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data' + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data', ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, From ccc25d6b523cfd21d85cc527419c0f87327df21b Mon Sep 17 00:00:00 2001 From: Bohdan Turchyk Date: Wed, 2 Nov 2022 13:36:38 +0200 Subject: [PATCH 14/14] Fixed test --- .../SyncApi/Console/OpenApiUpdateConsoleTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php index df38643..d54e38c 100644 --- a/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php +++ b/tests/SprykerSdkTest/SyncApi/Console/OpenApiUpdateConsoleTest.php @@ -39,7 +39,7 @@ public function testOpenApiUpdateConsoleSuccessfullyUpdatesAnExistingFile(): voi $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), - '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data', + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => $this->tester->getRootPath(), ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, @@ -64,7 +64,7 @@ public function testOpenApiUpdateConsoleSuccessfullyAddsANewFileWithPassedJson() $commandTester->execute( [ OpenApiUpdateConsole::ARGUMENT_OPENAPI_DOC => $this->tester->getValidOpenApiContentsAsJson(), - '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => '/data', + '--' . OpenApiUpdateConsole::OPTION_PROJECT_ROOT => $this->tester->getRootPath(), ], [ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE,