diff --git a/.gitignore b/.gitignore
index 503db3b..1de4327 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ composer.lock
# built resources
src/Generated
src/Orm/Zed/
+src/Orm/Propel/Schema/
src/Orm/Propel/Migration_SQLite/
tests/_data/app_kernel_db
diff --git a/composer.json b/composer.json
index 2d10934..7545bc5 100644
--- a/composer.json
+++ b/composer.json
@@ -1,76 +1,85 @@
{
- "name": "spryker/app-kernel",
- "type": "library",
- "description": "AppKernel module",
- "license": "proprietary",
- "require": {
- "php": ">=8.1",
- "spryker/app-kernel-extension": "dev-master",
- "spryker/glue-application-extension": "^1.0.0",
- "spryker/kernel": "^3.30.0",
- "spryker/log": "^3.0.0",
- "spryker/message-broker": "^1.11.0",
- "spryker/propel-encryption-behavior": "^0.1.1",
- "spryker/secrets-manager": "^1.0.0",
- "spryker/secrets-manager-extension": "^1.0.0",
- "spryker/symfony": "^3.0.0",
- "spryker/transfer": "^3.33.0",
- "spryker/util-encoding": "^2.0.0",
- "spryker/util-text": "^1.0.0"
- },
- "require-dev": {
- "codeception/codeception": "^5.0",
- "codeception/module-asserts": "^3.0",
- "phpstan/phpdoc-parser": "1.25.0",
- "phpstan/phpstan": "1.10.66",
- "rector/rector": "^0.19.0",
- "spryker/code-sniffer": "*",
- "spryker/container": "*",
- "spryker/development": "^3.34.0",
- "spryker/message-broker-aws": "^1.7.0",
- "spryker/propel": "*",
- "spryker/testify": "*",
- "spryker/testify-async-api": "^0.1.4"
- },
- "autoload": {
- "psr-4": {
- "Spryker\\": "src/Spryker/",
- "SprykerTest\\Glue\\AppKernel\\Helper\\": "tests/SprykerTest/Glue/AppKernel/_support/Helper/",
- "SprykerTest\\Zed\\AppKernel\\Helper\\": "tests/SprykerTest/Zed/AppKernel/_support/Helper/",
- "SprykerTest\\Shared\\AppKernel\\Helper\\": "tests/SprykerTest/Shared/AppKernel/_support/Helper/",
- "SprykerTest\\Zed\\Propel\\Helper\\": "tests/SprykerTest/Zed/Propel/_support/Helper/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "SprykerTest\\": "tests/SprykerTest/",
- "Generated\\": "src/Generated/",
- "Orm\\": "src/Orm/"
- }
- },
- "minimum-stability": "dev",
- "prefer-stable": true,
- "scripts": {
- "setup": "tests/bin/console app-kernel:setup && tests/bin/console transfer:generate && tests/bin/console transfer:databuilder:generate && tests/bin/console propel:install && tests/bin/console dev:ide-auto-completion:zed:generate && tests/bin/console dev:ide-auto-completion:glue:generate && tests/bin/console dev:ide-auto-completion:glue-backend:generate",
- "cs-check": "phpcs -p src/ tests/",
- "cs-fix": "phpcbf -p src/ tests/",
- "stan": "phpstan analyze src/Spryker/",
- "test": "codecept build && codecept run",
- "test-cover": "codecept build && codecept run --coverage-xml",
- "test-cover-html": "codecept build && codecept run --coverage-html",
- "rector": "vendor/bin/rector process src/Spryker/ --config rector.php --ansi",
- "rector-ci": "vendor/bin/rector process src/Spryker/ --config rector.php --ansi --dry-run",
- "local-ci": "composer cs-fix && composer cs-check && composer stan && composer rector-ci && composer test"
- },
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "config": {
- "sort-packages": true,
- "allow-plugins": {
- "dealerdirect/phpcodesniffer-composer-installer": true
- }
+ "name": "spryker/app-kernel",
+ "type": "library",
+ "description": "AppKernel module",
+ "license": "proprietary",
+ "require": {
+ "php": ">=8.1",
+ "spryker/app-kernel-extension": "dev-master",
+ "spryker/glue-application-extension": "^1.0.0",
+ "spryker/kernel": "^3.30.0",
+ "spryker/log": "^3.0.0",
+ "spryker/message-broker": "^1.11.0",
+ "spryker/propel-encryption-behavior": "^0.1.1",
+ "spryker/secrets-manager": "^1.0.0",
+ "spryker/secrets-manager-extension": "^1.0.0",
+ "spryker/symfony": "^3.0.0",
+ "spryker/transfer": "^3.33.0",
+ "spryker/util-encoding": "^2.0.0",
+ "spryker/util-text": "^1.0.0"
+ },
+ "require-dev": {
+ "codeception/codeception": "^5.0",
+ "codeception/module-cli": "^2.0.0",
+ "codeception/module-filesystem": "^3.0.0",
+ "codeception/module-phpbrowser": "^3.0.0",
+ "codeception/module-rest": "^3.0.0",
+ "codeception/module-webdriver": "^3.0.0",
+ "phpstan/phpdoc-parser": "1.25.0",
+ "phpstan/phpstan": "1.10.66",
+ "rector/rector": "^0.19.0",
+ "spryker/code-sniffer": "*",
+ "spryker/container": "*",
+ "spryker/development": "^3.34.0",
+ "spryker/glue-application": "^1.64.0",
+ "spryker/glue-backend-api-application": "^1.6.0",
+ "spryker/glue-json-api-convention": "^1.3.0",
+ "spryker/http": "^1.11.0",
+ "spryker/message-broker-aws": "^1.7.0",
+ "spryker/propel": "*",
+ "spryker/testify": "*",
+ "spryker/testify-async-api": "^0.1.4"
+ },
+ "autoload": {
+ "psr-4": {
+ "Spryker\\": "src/Spryker/",
+ "SprykerTest\\Glue\\AppKernel\\Helper\\": "tests/SprykerTest/Glue/AppKernel/_support/Helper/",
+ "SprykerTest\\Glue\\Testify\\Helper\\": "tests/SprykerTest/Glue/Testify/_support/Helper/",
+ "SprykerTest\\Zed\\AppKernel\\Helper\\": "tests/SprykerTest/Zed/AppKernel/_support/Helper/",
+ "SprykerTest\\Shared\\AppKernel\\Helper\\": "tests/SprykerTest/Shared/AppKernel/_support/Helper/",
+ "SprykerTest\\Zed\\Propel\\Helper\\": "tests/SprykerTest/Zed/Propel/_support/Helper/"
}
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "SprykerTest\\": "tests/SprykerTest/",
+ "Generated\\": "src/Generated/",
+ "Orm\\": "src/Orm/"
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "scripts": {
+ "setup": "tests/bin/console app-kernel:setup && tests/bin/console transfer:generate && tests/bin/console transfer:databuilder:generate && tests/bin/console propel:install && tests/bin/console dev:ide-auto-completion:zed:generate && tests/bin/console dev:ide-auto-completion:glue:generate && tests/bin/console dev:ide-auto-completion:glue-backend:generate",
+ "cs-check": "phpcs -p src/ tests/",
+ "cs-fix": "phpcbf -p src/ tests/",
+ "stan": "phpstan analyze src/Spryker/",
+ "test": "codecept build && codecept run",
+ "test-cover": "codecept build && codecept run --coverage-xml",
+ "test-cover-html": "codecept build && codecept run --coverage-html",
+ "rector": "vendor/bin/rector process src/Spryker/ --config rector.php --ansi",
+ "rector-ci": "vendor/bin/rector process src/Spryker/ --config rector.php --ansi --dry-run",
+ "local-ci": "composer cs-fix && composer cs-check && composer stan && composer rector-ci && composer test"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true,
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
+ }
}
diff --git a/config/Shared/config_default.php b/config/Shared/config_default.php
index 12e91a5..157a6d6 100644
--- a/config/Shared/config_default.php
+++ b/config/Shared/config_default.php
@@ -7,15 +7,55 @@
use Generated\Shared\Transfer\AppConfigUpdatedTransfer;
use Ramsey\Uuid\Uuid;
use Spryker\Shared\AppKernel\AppKernelConstants;
+use Spryker\Shared\Application\ApplicationConstants;
+use Spryker\Shared\GlueBackendApiApplication\GlueBackendApiApplicationConstants;
+use Spryker\Shared\GlueJsonApiConvention\GlueJsonApiConventionConstants;
+use Spryker\Shared\Http\HttpConstants;
+use Spryker\Shared\Kernel\KernelConstants;
use Spryker\Shared\MessageBroker\MessageBrokerConstants;
+use Spryker\Shared\ZedRequest\ZedRequestConstants;
use Spryker\Zed\MessageBrokerAws\MessageBrokerAwsConfig;
+use Spryker\Shared\MessageBrokerAws\MessageBrokerAwsConstants;
-$config[MessageBrokerConstants::MESSAGE_TO_CHANNEL_MAP] = [
+$config[AppKernelConstants::APP_IDENTIFIER] = Uuid::uuid4()->toString();
+
+// ----------------------------------------------------------------------------
+// ------------------------------ Glue Backend API ----------------------------
+// ----------------------------------------------------------------------------
+$config[GlueBackendApiApplicationConstants::GLUE_BACKEND_API_HOST] = 'api.payment.local';
+
+$config[KernelConstants::ENABLE_CONTAINER_OVERRIDING] = true;
+$config[KernelConstants::PROJECT_NAMESPACES] =
+$config[GlueBackendApiApplicationConstants::PROJECT_NAMESPACES] = [
+ 'Spryker',
+];
+$config[ZedRequestConstants::ZED_API_SSL_ENABLED] = (bool)getenv('SPRYKER_ZED_SSL_ENABLED');
+
+$config[ApplicationConstants::BASE_URL_ZED] = sprintf(
+ 'https://%s',
+ 'api.kernel.local',
+);
+
+$config[AppKernelConstants::APP_IDENTIFIER] = Uuid::uuid4()->toString();
+
+$config[HttpConstants::URI_SIGNER_SECRET_KEY] = Uuid::uuid4()->toString();
+
+$config[GlueJsonApiConventionConstants::GLUE_DOMAIN] = sprintf(
+ '%s://%s',
+ getenv('SPRYKER_SSL_ENABLE') ? 'https' : 'http',
+ $config[GlueBackendApiApplicationConstants::GLUE_BACKEND_API_HOST] ?: 'localhost',
+);
+
+$config[MessageBrokerConstants::MESSAGE_TO_CHANNEL_MAP] =
+$config[MessageBrokerAwsConstants::MESSAGE_TO_CHANNEL_MAP] = [
+ // App event
AppConfigUpdatedTransfer::class => 'app-events',
];
-$config[MessageBrokerConstants::CHANNEL_TO_SENDER_TRANSPORT_MAP] = [
- 'app-events' => MessageBrokerAwsConfig::HTTP_CHANNEL_TRANSPORT,
+$config[MessageBrokerConstants::CHANNEL_TO_TRANSPORT_MAP] = [
+ 'app-events' => MessageBrokerAwsConfig::HTTP_TRANSPORT,
];
-$config[AppKernelConstants::APP_IDENTIFIER] = Uuid::uuid4()->toString();
+$config[MessageBrokerAwsConstants::CHANNEL_TO_SENDER_TRANSPORT_MAP] = [
+ 'app-events' => MessageBrokerAwsConfig::HTTP_TRANSPORT,
+];
diff --git a/rector.php b/rector.php
index dc8f23f..dd58318 100644
--- a/rector.php
+++ b/rector.php
@@ -46,6 +46,7 @@
__DIR__ . '/src/Spryker/Zed/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php',
__DIR__ . '/src/Spryker/Zed/AppKernel/Dependency/Service/AppKernelToUtilTextServiceBridge.php',
__DIR__ . '/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php',
+ __DIR__ . '/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php',
],
AddParamTypeFromPropertyTypeRector::class => [
__DIR__ . '/src/Spryker/Zed/AppKernel/Dependency/Client/AppKernelToSecretsManagerClientBridge.php',
@@ -53,6 +54,7 @@
__DIR__ . '/src/Spryker/Zed/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php',
__DIR__ . '/src/Spryker/Zed/AppKernel/Dependency/Service/AppKernelToUtilTextServiceBridge.php',
__DIR__ . '/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php',
+ __DIR__ . '/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php',
],
]);
};
diff --git a/src/Orm/Propel/Schema/spy_app_kernel.schema.xml b/src/Orm/Propel/Schema/spy_app_kernel.schema.xml
deleted file mode 100644
index 8db2333..0000000
--- a/src/Orm/Propel/Schema/spy_app_kernel.schema.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Orm/Propel/Schema/spy_locale.schema.xml b/src/Orm/Propel/Schema/spy_locale.schema.xml
deleted file mode 100644
index b0e2c60..0000000
--- a/src/Orm/Propel/Schema/spy_locale.schema.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Orm/Propel/Schema/spy_queue.schema.xml b/src/Orm/Propel/Schema/spy_queue.schema.xml
deleted file mode 100644
index 35f2128..0000000
--- a/src/Orm/Propel/Schema/spy_queue.schema.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Orm/Propel/Schema/spy_store.schema.xml b/src/Orm/Propel/Schema/spy_store.schema.xml
deleted file mode 100644
index edf4bc5..0000000
--- a/src/Orm/Propel/Schema/spy_store.schema.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
diff --git a/src/Spryker/Glue/AppKernel/AppKernelDependencyProvider.php b/src/Spryker/Glue/AppKernel/AppKernelDependencyProvider.php
index c70d7bf..c161836 100644
--- a/src/Spryker/Glue/AppKernel/AppKernelDependencyProvider.php
+++ b/src/Spryker/Glue/AppKernel/AppKernelDependencyProvider.php
@@ -8,10 +8,11 @@
namespace Spryker\Glue\AppKernel;
use Spryker\Glue\AppKernel\Dependency\Facade\AppKernelToAppKernelFacadeBridge;
-use Spryker\Glue\AppKernel\Plugin\RequestValidator\BodyStructureValidatorPlugin;
-use Spryker\Glue\AppKernel\Plugin\RequestValidator\HeaderValidatorPlugin;
+use Spryker\Glue\AppKernel\Dependency\Facade\AppKernelToAppKernelFacadeInterface;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceBridge;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
use Spryker\Glue\Kernel\Backend\AbstractBundleDependencyProvider;
-use Spryker\Glue\Kernel\Backend\Container as GlueBackendContainer;
+use Spryker\Glue\Kernel\Backend\Container;
/**
* @method \Spryker\Glue\AppKernel\AppKernelConfig getConfig()
@@ -38,54 +39,43 @@ class AppKernelDependencyProvider extends AbstractBundleDependencyProvider
*/
public const PLUGINS_REQUEST_DISCONNECT_VALIDATOR = 'PLUGINS_REQUEST_DISCONNECT_VALIDATOR';
- public function provideBackendDependencies(GlueBackendContainer $glueBackendContainer): GlueBackendContainer
+ public function provideBackendDependencies(Container $container): Container
{
- $glueBackendContainer = parent::provideBackendDependencies($glueBackendContainer);
+ $container = parent::provideBackendDependencies($container);
- $glueBackendContainer = $this->addUtilEncodingService($glueBackendContainer);
- $glueBackendContainer = $this->addAppKernelFacade($glueBackendContainer);
- $glueBackendContainer = $this->addRequestConfigureValidatorPlugins($glueBackendContainer);
- $glueBackendContainer = $this->addRequestDisconnectValidatorPlugins($glueBackendContainer);
+ $container = $this->addUtilEncodingService($container);
+ $container = $this->addAppKernelFacade($container);
+ $container = $this->addRequestConfigureValidatorPlugins($container);
+ $container = $this->addRequestDisconnectValidatorPlugins($container);
- return $glueBackendContainer;
+ return $container;
}
- protected function addUtilEncodingService(GlueBackendContainer $glueBackendContainer): GlueBackendContainer
+ protected function addUtilEncodingService(Container $container): Container
{
- $glueBackendContainer->set(static::SERVICE_UTIL_ENCODING, static function (GlueBackendContainer $glueBackendContainer) {
- return $glueBackendContainer->getLocator()->utilEncoding()->service();
+ $container->set(static::SERVICE_UTIL_ENCODING, static function (Container $container): AppKernelToUtilEncodingServiceInterface {
+ return new AppKernelToUtilEncodingServiceBridge($container->getLocator()->utilEncoding()->service());
});
- return $glueBackendContainer;
+ return $container;
}
- protected function addAppKernelFacade(GlueBackendContainer $glueBackendContainer): GlueBackendContainer
+ protected function addAppKernelFacade(Container $container): Container
{
- $glueBackendContainer->set(static::FACADE_APP_KERNEL, static function (GlueBackendContainer $glueBackendContainer): AppKernelToAppKernelFacadeBridge {
- return new AppKernelToAppKernelFacadeBridge($glueBackendContainer->getLocator()->appKernel()->facade());
+ $container->set(static::FACADE_APP_KERNEL, static function (Container $container): AppKernelToAppKernelFacadeInterface {
+ return new AppKernelToAppKernelFacadeBridge($container->getLocator()->appKernel()->facade());
});
- return $glueBackendContainer;
+ return $container;
}
- protected function addRequestConfigureValidatorPlugins(GlueBackendContainer $glueBackendContainer): GlueBackendContainer
+ protected function addRequestConfigureValidatorPlugins(Container $container): Container
{
- $glueBackendContainer->set(static::PLUGINS_REQUEST_CONFIGURE_VALIDATOR, function (): array {
- return array_merge($this->getDefaultRequestConfigureValidatorPlugins(), $this->getRequestConfigureValidatorPlugins());
+ $container->set(static::PLUGINS_REQUEST_CONFIGURE_VALIDATOR, function (): array {
+ return $this->getRequestConfigureValidatorPlugins();
});
- return $glueBackendContainer;
- }
-
- /**
- * @return array<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\RequestValidatorPluginInterface>
- */
- private function getDefaultRequestConfigureValidatorPlugins(): array
- {
- return [
- new HeaderValidatorPlugin(),
- new BodyStructureValidatorPlugin(),
- ];
+ return $container;
}
/**
@@ -96,23 +86,13 @@ protected function getRequestConfigureValidatorPlugins(): array
return [];
}
- protected function addRequestDisconnectValidatorPlugins(GlueBackendContainer $glueBackendContainer): GlueBackendContainer
+ protected function addRequestDisconnectValidatorPlugins(Container $container): Container
{
- $glueBackendContainer->set(static::PLUGINS_REQUEST_DISCONNECT_VALIDATOR, function (): array {
- return array_merge($this->getDefaultRequestDisconnectValidatorPlugins(), $this->getRequestDisconnectValidatorPlugins());
+ $container->set(static::PLUGINS_REQUEST_DISCONNECT_VALIDATOR, function (): array {
+ return $this->getRequestDisconnectValidatorPlugins();
});
- return $glueBackendContainer;
- }
-
- /**
- * @return array<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\RequestValidatorPluginInterface>
- */
- protected function getDefaultRequestDisconnectValidatorPlugins(): array
- {
- return [
- new HeaderValidatorPlugin(),
- ];
+ return $container;
}
/**
diff --git a/src/Spryker/Glue/AppKernel/AppKernelFactory.php b/src/Spryker/Glue/AppKernel/AppKernelFactory.php
index b60de16..aae56cc 100644
--- a/src/Spryker/Glue/AppKernel/AppKernelFactory.php
+++ b/src/Spryker/Glue/AppKernel/AppKernelFactory.php
@@ -10,14 +10,15 @@
use Spryker\Glue\AppKernel\Builder\ResponseBuilder;
use Spryker\Glue\AppKernel\Builder\ResponseBuilderInterface;
use Spryker\Glue\AppKernel\Dependency\Facade\AppKernelToAppKernelFacadeInterface;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
use Spryker\Glue\AppKernel\Mapper\GlueRequestMapper;
use Spryker\Glue\AppKernel\Mapper\GlueRequestMapperInterface;
use Spryker\Glue\AppKernel\Validator\BodyStructureValidator;
+use Spryker\Glue\AppKernel\Validator\ConfigurationValidator;
use Spryker\Glue\AppKernel\Validator\HeaderValidator;
use Spryker\Glue\AppKernel\Validator\RequestValidator;
use Spryker\Glue\AppKernel\Validator\RequestValidatorInterface;
use Spryker\Glue\Kernel\Backend\AbstractFactory;
-use Spryker\Service\UtilEncoding\UtilEncodingServiceInterface;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -36,6 +37,14 @@ public function createBodyStructureValidator(): RequestValidatorInterface
);
}
+ public function createConfigurationValidator(): RequestValidatorInterface
+ {
+ return new ConfigurationValidator(
+ $this->createGlueRequestMapper(),
+ $this->getAppKernelFacade(),
+ );
+ }
+
public function createResponseBuilder(): ResponseBuilderInterface
{
return new ResponseBuilder($this->getUtilEncodingService());
@@ -55,15 +64,21 @@ public function createGlueRequestMapper(): GlueRequestMapperInterface
public function createApiRequestSaveConfigValidator(): RequestValidatorInterface
{
- return new RequestValidator($this->getApiRequestConfigureValidatorPlugins());
+ return new RequestValidator($this->getApiRequestConfigureValidatorPlugins(), [
+ $this->createBodyStructureValidator(),
+ $this->createHeaderValidator(),
+ $this->createConfigurationValidator(),
+ ]);
}
public function createApiRequestDisconnectValidator(): RequestValidatorInterface
{
- return new RequestValidator($this->getApiRequestDisconnectValidatorPlugins());
+ return new RequestValidator($this->getApiRequestDisconnectValidatorPlugins(), [
+ $this->createHeaderValidator(),
+ ]);
}
- public function getUtilEncodingService(): UtilEncodingServiceInterface
+ public function getUtilEncodingService(): AppKernelToUtilEncodingServiceInterface
{
return $this->getProvidedDependency(AppKernelDependencyProvider::SERVICE_UTIL_ENCODING);
}
diff --git a/src/Spryker/Glue/AppKernel/Builder/ResponseBuilder.php b/src/Spryker/Glue/AppKernel/Builder/ResponseBuilder.php
index 2264de3..4c2a2a7 100644
--- a/src/Spryker/Glue/AppKernel/Builder/ResponseBuilder.php
+++ b/src/Spryker/Glue/AppKernel/Builder/ResponseBuilder.php
@@ -11,12 +11,12 @@
use Generated\Shared\Transfer\GlueErrorTransfer;
use Generated\Shared\Transfer\GlueRequestValidationTransfer;
use Generated\Shared\Transfer\GlueResponseTransfer;
-use Spryker\Service\UtilEncoding\UtilEncodingServiceInterface;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
use Symfony\Component\HttpFoundation\Response;
class ResponseBuilder implements ResponseBuilderInterface
{
- public function __construct(protected UtilEncodingServiceInterface $utilEncodingService)
+ public function __construct(protected AppKernelToUtilEncodingServiceInterface $appKernelToUtilEncodingService)
{
}
@@ -38,7 +38,7 @@ public function buildRequestNotValidResponse(
}
return $glueResponseTransfer
- ->setContent($this->utilEncodingService->encodeJson(['errors' => $errors]))
+ ->setContent($this->appKernelToUtilEncodingService->encodeJson(['errors' => $errors]))
->setHttpStatus($glueRequestValidationTransfer->getStatus() ?? Response::HTTP_BAD_REQUEST);
}
@@ -47,7 +47,7 @@ public function buildErrorResponse(string $errorMessage): GlueResponseTransfer
$errorData = $this->composeErrorArray($errorMessage);
return (new GlueResponseTransfer())
- ->setContent($this->utilEncodingService
+ ->setContent($this->appKernelToUtilEncodingService
->encodeJson([
'errors' => [
$errorData,
@@ -71,7 +71,7 @@ public function buildSuccessfulResponse(?AppConfigTransfer $appConfigTransfer =
];
$glueResponseTransfer
- ->setContent($this->utilEncodingService->encodeJson($content))
+ ->setContent($this->appKernelToUtilEncodingService->encodeJson($content))
->setHttpStatus(Response::HTTP_OK);
}
diff --git a/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php b/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php
index e247048..fe65040 100644
--- a/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php
+++ b/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeBridge.php
@@ -10,6 +10,8 @@
use Generated\Shared\Transfer\AppConfigCriteriaTransfer;
use Generated\Shared\Transfer\AppConfigResponseTransfer;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
class AppKernelToAppKernelFacadeBridge implements AppKernelToAppKernelFacadeInterface
{
@@ -26,6 +28,12 @@ public function __construct($appKernelFacade)
$this->appKernelFacade = $appKernelFacade;
}
+ public function validateConfiguration(
+ ConfigurationValidationRequestTransfer $configurationValidationRequestTransfer
+ ): ConfigurationValidationResponseTransfer {
+ return $this->appKernelFacade->validateConfiguration($configurationValidationRequestTransfer);
+ }
+
public function getConfig(AppConfigCriteriaTransfer $appConfigCriteriaTransfer): AppConfigTransfer
{
return $this->appKernelFacade->getConfig($appConfigCriteriaTransfer);
diff --git a/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeInterface.php b/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeInterface.php
index 9e74feb..ba6e8f0 100644
--- a/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeInterface.php
+++ b/src/Spryker/Glue/AppKernel/Dependency/Facade/AppKernelToAppKernelFacadeInterface.php
@@ -10,9 +10,15 @@
use Generated\Shared\Transfer\AppConfigCriteriaTransfer;
use Generated\Shared\Transfer\AppConfigResponseTransfer;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
interface AppKernelToAppKernelFacadeInterface
{
+ public function validateConfiguration(
+ ConfigurationValidationRequestTransfer $configurationValidationRequestTransfer
+ ): ConfigurationValidationResponseTransfer;
+
public function getConfig(AppConfigCriteriaTransfer $appConfigCriteriaTransfer): AppConfigTransfer;
public function saveConfig(AppConfigTransfer $appConfigTransfer): AppConfigResponseTransfer;
diff --git a/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php b/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php
new file mode 100644
index 0000000..1c26462
--- /dev/null
+++ b/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceBridge.php
@@ -0,0 +1,47 @@
+utilEncodingService = $utilEncodingService;
+ }
+
+ /**
+ * @param string $jsonValue
+ * @param bool $assoc Deprecated: `false` is deprecated, always use `true` for array return.
+ * @param int|null $depth
+ * @param int|null $options
+ *
+ * @return object|array|null
+ */
+ public function decodeJson($jsonValue, $assoc = false, $depth = null, $options = null): object|array|null
+ {
+ return $this->utilEncodingService->decodeJson($jsonValue, $assoc, $depth, $options);
+ }
+
+ /**
+ * @param array $value
+ * @param int|null $options
+ * @param int|null $depth
+ */
+ public function encodeJson($value, $options = null, $depth = null): string|null
+ {
+ return $this->utilEncodingService->encodeJson($value, $options, $depth);
+ }
+}
diff --git a/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceInterface.php b/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceInterface.php
new file mode 100644
index 0000000..595ef2b
--- /dev/null
+++ b/src/Spryker/Glue/AppKernel/Dependency/Service/AppKernelToUtilEncodingServiceInterface.php
@@ -0,0 +1,28 @@
+|null
+ */
+ public function decodeJson($jsonValue, $assoc = false, $depth = null, $options = null): object|array|null;
+
+ /**
+ * @param array $value
+ * @param int|null $options
+ * @param int|null $depth
+ */
+ public function encodeJson($value, $options = null, $depth = null): string|null;
+}
diff --git a/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapper.php b/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapper.php
index d3738a3..4c8ea5a 100644
--- a/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapper.php
+++ b/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapper.php
@@ -8,13 +8,18 @@
namespace Spryker\Glue\AppKernel\Mapper;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
+use Generated\Shared\Transfer\GlueErrorTransfer;
use Generated\Shared\Transfer\GlueRequestTransfer;
+use Generated\Shared\Transfer\GlueRequestValidationTransfer;
use Spryker\Glue\AppKernel\AppKernelConfig;
-use Spryker\Service\UtilEncoding\UtilEncodingServiceInterface;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
+use Symfony\Component\HttpFoundation\Response;
class GlueRequestMapper implements GlueRequestMapperInterface
{
- public function __construct(protected UtilEncodingServiceInterface $utilEncodingService)
+ public function __construct(protected AppKernelToUtilEncodingServiceInterface $appKernelToUtilEncodingService)
{
}
@@ -28,12 +33,45 @@ public function mapGlueRequestTransferToAppConfigTransfer(
$appConfigTransfer->setConfig($configuration)
->setTenantIdentifier($tenantIdentifier);
+ if ($glueRequestTransfer->getLocale() === null) {
+ $glueRequestTransfer->setLocale('en_US');
+ }
+
+ $appConfigTransfer->setLocale($glueRequestTransfer->getLocale());
+
return $appConfigTransfer;
}
+ public function mapGlueRequestTransferToConfigurationValidationRequestTransfer(
+ GlueRequestTransfer $glueRequestTransfer
+ ): ConfigurationValidationRequestTransfer {
+ $configurationValidationRequestTransfer = new ConfigurationValidationRequestTransfer();
+ $configurationValidationRequestTransfer->setAppConfig($this->mapGlueRequestTransferToAppConfigTransfer($glueRequestTransfer, new AppConfigTransfer()));
+
+ return $configurationValidationRequestTransfer;
+ }
+
+ public function mapConfigurationValidationResponseTransferToGlueRequestValidationTransfer(
+ ConfigurationValidationResponseTransfer $configurationValidationResponseTransfer
+ ): GlueRequestValidationTransfer {
+ $glueRequestValidationTransfer = new GlueRequestValidationTransfer();
+ $glueRequestValidationTransfer->setIsValid($configurationValidationResponseTransfer->getIsSuccessful())
+ ->setStatus($configurationValidationResponseTransfer->getIsSuccessful() === false ? Response::HTTP_UNPROCESSABLE_ENTITY : null);
+
+ if ($configurationValidationResponseTransfer->getIsSuccessful() === false) {
+ $glueErrorTransfer = new GlueErrorTransfer();
+ $glueErrorTransfer->setMessage($configurationValidationResponseTransfer->getMessage() ?? $configurationValidationResponseTransfer->getExceptionMessage());
+
+ $glueRequestValidationTransfer->addError($glueErrorTransfer);
+ $glueRequestValidationTransfer->setStatus($configurationValidationResponseTransfer->getExceptionMessage() !== null && $configurationValidationResponseTransfer->getExceptionMessage() !== '' && $configurationValidationResponseTransfer->getExceptionMessage() !== '0' ? Response::HTTP_INTERNAL_SERVER_ERROR : Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
+
+ return $glueRequestValidationTransfer;
+ }
+
protected function getTenantIdentifier(GlueRequestTransfer $glueRequestTransfer): string
{
- return $glueRequestTransfer->getMeta()[AppKernelConfig::HEADER_TENANT_IDENTIFIER][0];
+ return $glueRequestTransfer->getMeta()[AppKernelConfig::HEADER_TENANT_IDENTIFIER][0] ?? '';
}
/**
@@ -41,12 +79,12 @@ protected function getTenantIdentifier(GlueRequestTransfer $glueRequestTransfer)
*/
protected function getConfiguration(GlueRequestTransfer $glueRequestTransfer): array
{
- $content = (array)$this->utilEncodingService->decodeJson((string)$glueRequestTransfer->getContent(), true);
+ $content = (array)$this->appKernelToUtilEncodingService->decodeJson((string)$glueRequestTransfer->getContent(), true);
if (!isset($content['data']['attributes']['configuration'])) {
return [];
}
- return (array)$this->utilEncodingService->decodeJson($content['data']['attributes']['configuration'], true);
+ return (array)$this->appKernelToUtilEncodingService->decodeJson($content['data']['attributes']['configuration'], true);
}
}
diff --git a/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapperInterface.php b/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapperInterface.php
index 52ad52f..38375ad 100644
--- a/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapperInterface.php
+++ b/src/Spryker/Glue/AppKernel/Mapper/GlueRequestMapperInterface.php
@@ -8,7 +8,10 @@
namespace Spryker\Glue\AppKernel\Mapper;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
use Generated\Shared\Transfer\GlueRequestTransfer;
+use Generated\Shared\Transfer\GlueRequestValidationTransfer;
interface GlueRequestMapperInterface
{
@@ -16,4 +19,12 @@ public function mapGlueRequestTransferToAppConfigTransfer(
GlueRequestTransfer $glueRequestTransfer,
AppConfigTransfer $appConfigTransfer
): AppConfigTransfer;
+
+ public function mapGlueRequestTransferToConfigurationValidationRequestTransfer(
+ GlueRequestTransfer $glueRequestTransfer
+ ): ConfigurationValidationRequestTransfer;
+
+ public function mapConfigurationValidationResponseTransferToGlueRequestValidationTransfer(
+ ConfigurationValidationResponseTransfer $configurationValidationResponseTransfer
+ ): GlueRequestValidationTransfer;
}
diff --git a/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/BodyStructureValidatorPlugin.php b/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/BodyStructureValidatorPlugin.php
deleted file mode 100644
index baac3ef..0000000
--- a/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/BodyStructureValidatorPlugin.php
+++ /dev/null
@@ -1,30 +0,0 @@
-getFactory()->createBodyStructureValidator()->validate($glueRequestTransfer);
- }
-}
diff --git a/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/HeaderValidatorPlugin.php b/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/HeaderValidatorPlugin.php
deleted file mode 100644
index b06cddc..0000000
--- a/src/Spryker/Glue/AppKernel/Plugin/RequestValidator/HeaderValidatorPlugin.php
+++ /dev/null
@@ -1,30 +0,0 @@
-getFactory()->createHeaderValidator()->validate($glueRequestTransfer);
- }
-}
diff --git a/src/Spryker/Glue/AppKernel/Plugin/RouteProvider/AppKernelRouteProviderPlugin.php b/src/Spryker/Glue/AppKernel/Plugin/RouteProvider/AppKernelRouteProviderPlugin.php
index 219c509..60c6556 100644
--- a/src/Spryker/Glue/AppKernel/Plugin/RouteProvider/AppKernelRouteProviderPlugin.php
+++ b/src/Spryker/Glue/AppKernel/Plugin/RouteProvider/AppKernelRouteProviderPlugin.php
@@ -16,6 +16,9 @@
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
+/**
+ * @codeCoverageIgnore
+ */
class AppKernelRouteProviderPlugin extends AbstractPlugin implements RouteProviderPluginInterface
{
public function addRoutes(RouteCollection $routeCollection): RouteCollection
diff --git a/src/Spryker/Glue/AppKernel/Validator/BodyStructureValidator.php b/src/Spryker/Glue/AppKernel/Validator/BodyStructureValidator.php
index e58aa59..49644d1 100644
--- a/src/Spryker/Glue/AppKernel/Validator/BodyStructureValidator.php
+++ b/src/Spryker/Glue/AppKernel/Validator/BodyStructureValidator.php
@@ -11,7 +11,7 @@
use Generated\Shared\Transfer\GlueRequestTransfer;
use Generated\Shared\Transfer\GlueRequestValidationTransfer;
use Spryker\Glue\AppKernel\AppKernelConfig;
-use Spryker\Service\UtilEncoding\UtilEncodingServiceInterface;
+use Spryker\Glue\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\EqualTo;
@@ -25,7 +25,7 @@ class BodyStructureValidator implements RequestValidatorInterface
{
public function __construct(
protected ValidatorInterface $validator,
- protected UtilEncodingServiceInterface $utilEncodingService
+ protected AppKernelToUtilEncodingServiceInterface $appKernelToUtilEncodingService
) {
}
@@ -35,7 +35,7 @@ public function validate(GlueRequestTransfer $glueRequestTransfer): GlueRequestV
->setIsValid(true)
->setStatus(Response::HTTP_OK);
- $content = $this->utilEncodingService->decodeJson((string)$glueRequestTransfer->getContent(), true);
+ $content = $this->appKernelToUtilEncodingService->decodeJson((string)$glueRequestTransfer->getContent(), true);
$constraintViolationList = $this->validator->validate($content, $this->getConstraintForRequestStructure());
if ($constraintViolationList->count() > 0) {
diff --git a/src/Spryker/Glue/AppKernel/Validator/ConfigurationValidator.php b/src/Spryker/Glue/AppKernel/Validator/ConfigurationValidator.php
new file mode 100644
index 0000000..1451610
--- /dev/null
+++ b/src/Spryker/Glue/AppKernel/Validator/ConfigurationValidator.php
@@ -0,0 +1,35 @@
+glueRequestMapper->mapGlueRequestTransferToConfigurationValidationRequestTransfer($glueRequestTransfer);
+ $configurationValidationResponseTransfer = $this->appKernelToAppKernelFacade->validateConfiguration($configurationValidationRequestTransfer);
+
+ return $this->glueRequestMapper->mapConfigurationValidationResponseTransferToGlueRequestValidationTransfer($configurationValidationResponseTransfer);
+ }
+}
diff --git a/src/Spryker/Glue/AppKernel/Validator/RequestValidator.php b/src/Spryker/Glue/AppKernel/Validator/RequestValidator.php
index a2f6dbb..d1f3bfe 100644
--- a/src/Spryker/Glue/AppKernel/Validator/RequestValidator.php
+++ b/src/Spryker/Glue/AppKernel/Validator/RequestValidator.php
@@ -14,15 +14,18 @@ class RequestValidator implements RequestValidatorInterface
{
/**
* @param array<\Spryker\Glue\GlueApplicationExtension\Dependency\Plugin\RequestValidatorPluginInterface> $requestValidatorPlugins
+ * @param array<\Spryker\Glue\AppKernel\Validator\RequestValidatorInterface> $defaultRequestValidatorPlugins
*/
- public function __construct(protected array $requestValidatorPlugins)
+ public function __construct(protected array $requestValidatorPlugins, protected array $defaultRequestValidatorPlugins = [])
{
}
public function validate(GlueRequestTransfer $glueRequestTransfer): GlueRequestValidationTransfer
{
- foreach ($this->requestValidatorPlugins as $requestValidatorPlugin) {
- $glueRequestValidationTransfer = $requestValidatorPlugin->validate($glueRequestTransfer);
+ $validators = array_merge($this->defaultRequestValidatorPlugins, $this->requestValidatorPlugins);
+
+ foreach ($validators as $validator) {
+ $glueRequestValidationTransfer = $validator->validate($glueRequestTransfer);
if (!$glueRequestValidationTransfer->getIsValid()) {
return $glueRequestValidationTransfer;
diff --git a/src/Spryker/Shared/AppKernel/Transfer/app_kernel.transfer.xml b/src/Spryker/Shared/AppKernel/Transfer/app_kernel.transfer.xml
index 53cd2f7..ef7f29b 100644
--- a/src/Spryker/Shared/AppKernel/Transfer/app_kernel.transfer.xml
+++ b/src/Spryker/Shared/AppKernel/Transfer/app_kernel.transfer.xml
@@ -5,6 +5,7 @@
+
@@ -31,6 +32,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -59,6 +80,7 @@
+
diff --git a/src/Spryker/Zed/AppKernel/AppKernelDependencyProvider.php b/src/Spryker/Zed/AppKernel/AppKernelDependencyProvider.php
index e977e20..d9845f0 100644
--- a/src/Spryker/Zed/AppKernel/AppKernelDependencyProvider.php
+++ b/src/Spryker/Zed/AppKernel/AppKernelDependencyProvider.php
@@ -7,11 +7,14 @@
namespace Spryker\Zed\AppKernel;
+use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\AppConfigValidateResponseTransfer;
use Spryker\Zed\AppKernel\Dependency\Client\AppKernelToSecretsManagerClientBridge;
use Spryker\Zed\AppKernel\Dependency\Facade\AppKernelToMessageBrokerFacadeBridge;
use Spryker\Zed\AppKernel\Dependency\Facade\AppKernelToMessageBrokerFacadeInterface;
use Spryker\Zed\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceBridge;
use Spryker\Zed\AppKernel\Dependency\Service\AppKernelToUtilTextServiceBridge;
+use Spryker\Zed\AppKernelExtension\Dependency\Plugin\AppKernelPlatformPluginInterface;
use Spryker\Zed\Kernel\AbstractBundleDependencyProvider;
use Spryker\Zed\Kernel\Container;
@@ -20,6 +23,11 @@
*/
class AppKernelDependencyProvider extends AbstractBundleDependencyProvider
{
+ /**
+ * @var string
+ */
+ public const PLUGIN_PLATFORM = 'APP_KERNEL:PLUGIN_PLATFORM';
+
/**
* @var string
*/
@@ -71,6 +79,7 @@ public function provideBusinessLayerDependencies(Container $container): Containe
$container = $this->addConfigurationAfterSavePlugins($container);
$container = $this->addConfigurationBeforeDeletePlugins($container);
$container = $this->addConfigurationAfterDeletePlugins($container);
+ $container = $this->addPlatformPlugin($container);
return $container;
}
@@ -82,6 +91,31 @@ public function providePersistenceLayerDependencies(Container $container): Conta
return $this->addUtilEncodingService($container);
}
+ protected function addPlatformPlugin(Container $container): Container
+ {
+ $container->set(static::PLUGIN_PLATFORM, function (): AppKernelPlatformPluginInterface {
+ // @codeCoverageIgnoreStart
+ return $this->getPlatformPlugin();
+ // @codeCoverageIgnoreEnd
+ });
+
+ return $container;
+ }
+
+ /**
+ * This method must be overridden in the project implementation of the AppKernelDependencyProvider.
+ * This one exists only for simpler testing.
+ */
+ protected function getPlatformPlugin(): AppKernelPlatformPluginInterface
+ {
+ return new class implements AppKernelPlatformPluginInterface {
+ public function validateConfiguration(AppConfigTransfer $appConfigTransfer): AppConfigValidateResponseTransfer
+ {
+ return (new AppConfigValidateResponseTransfer())->setIsSuccessful(true);
+ }
+ };
+ }
+
protected function addMessageBrokerFacade(Container $container): Container
{
$container->set(static::FACADE_MESSAGE_BROKER, static function (Container $container): AppKernelToMessageBrokerFacadeInterface {
diff --git a/src/Spryker/Zed/AppKernel/Business/AppKernelBusinessFactory.php b/src/Spryker/Zed/AppKernel/Business/AppKernelBusinessFactory.php
index db8598a..f8846e8 100644
--- a/src/Spryker/Zed/AppKernel/Business/AppKernelBusinessFactory.php
+++ b/src/Spryker/Zed/AppKernel/Business/AppKernelBusinessFactory.php
@@ -8,6 +8,7 @@
namespace Spryker\Zed\AppKernel\Business;
use Spryker\Zed\AppKernel\AppKernelDependencyProvider;
+use Spryker\Zed\AppKernel\Business\Configuration\ConfigurationValidator;
use Spryker\Zed\AppKernel\Business\EncryptionConfigurator\PropelEncryptionConfigurator;
use Spryker\Zed\AppKernel\Business\EncryptionConfigurator\PropelEncryptionConfiguratorInterface;
use Spryker\Zed\AppKernel\Business\MessageSender\MessageSender;
@@ -20,7 +21,9 @@
use Spryker\Zed\AppKernel\Business\Writer\ConfigWriterInterface;
use Spryker\Zed\AppKernel\Dependency\Client\AppKernelToSecretsManagerClientInterface;
use Spryker\Zed\AppKernel\Dependency\Facade\AppKernelToMessageBrokerFacadeInterface;
+use Spryker\Zed\AppKernel\Dependency\Service\AppKernelToUtilEncodingServiceInterface;
use Spryker\Zed\AppKernel\Dependency\Service\AppKernelToUtilTextServiceInterface;
+use Spryker\Zed\AppKernelExtension\Dependency\Plugin\AppKernelPlatformPluginInterface;
use Spryker\Zed\Kernel\Business\AbstractBusinessFactory;
/**
@@ -30,6 +33,11 @@
*/
class AppKernelBusinessFactory extends AbstractBusinessFactory
{
+ public function createConfigurationValidator(): ConfigurationValidator
+ {
+ return new ConfigurationValidator($this->getPlatformPlugin(), $this->getUtilEncodingService());
+ }
+
public function createConfigWriter(): ConfigWriterInterface
{
return new ConfigWriter(
@@ -63,7 +71,7 @@ public function createSecretsManager(): SecretsManagerInterface
{
return new SecretsManager(
$this->getSecretsManagerClient(),
- $this->getTextServiceUtil(),
+ $this->getUtilTextService(),
);
}
@@ -72,16 +80,26 @@ public function createMessageSender(): MessageSenderInterface
return new MessageSender($this->getMessageBrokerFacade(), $this->getConfig());
}
+ public function getPlatformPlugin(): AppKernelPlatformPluginInterface
+ {
+ return $this->getProvidedDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM);
+ }
+
public function getSecretsManagerClient(): AppKernelToSecretsManagerClientInterface
{
return $this->getProvidedDependency(AppKernelDependencyProvider::CLIENT_SECRETS_MANAGER);
}
- public function getTextServiceUtil(): AppKernelToUtilTextServiceInterface
+ public function getUtilTextService(): AppKernelToUtilTextServiceInterface
{
return $this->getProvidedDependency(AppKernelDependencyProvider::SERVICE_UTIL_TEXT);
}
+ public function getUtilEncodingService(): AppKernelToUtilEncodingServiceInterface
+ {
+ return $this->getProvidedDependency(AppKernelDependencyProvider::SERVICE_UTIL_ENCODING);
+ }
+
/**
* @return array<\Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationBeforeSavePluginInterface>
*/
diff --git a/src/Spryker/Zed/AppKernel/Business/AppKernelFacade.php b/src/Spryker/Zed/AppKernel/Business/AppKernelFacade.php
index db10cea..ca6525c 100644
--- a/src/Spryker/Zed/AppKernel/Business/AppKernelFacade.php
+++ b/src/Spryker/Zed/AppKernel/Business/AppKernelFacade.php
@@ -10,6 +10,8 @@
use Generated\Shared\Transfer\AppConfigCriteriaTransfer;
use Generated\Shared\Transfer\AppConfigResponseTransfer;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
use Spryker\Zed\Kernel\Business\AbstractFacade;
/**
@@ -19,11 +21,22 @@
*/
class AppKernelFacade extends AbstractFacade implements AppKernelFacadeInterface
{
- /**
- * {@inheritDoc}
- *
- * @api
- */
+ /**
+ * @api
+ *
+ * @inheritDoc
+ */
+ public function validateConfiguration(
+ ConfigurationValidationRequestTransfer $configurationValidationRequestTransfer
+ ): ConfigurationValidationResponseTransfer {
+ return $this->getFactory()->createConfigurationValidator()->validateConfiguration($configurationValidationRequestTransfer);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @api
+ */
public function saveConfig(AppConfigTransfer $appConfigTransfer): AppConfigResponseTransfer
{
return $this->getFactory()
diff --git a/src/Spryker/Zed/AppKernel/Business/AppKernelFacadeInterface.php b/src/Spryker/Zed/AppKernel/Business/AppKernelFacadeInterface.php
index 999a87a..b48e662 100644
--- a/src/Spryker/Zed/AppKernel/Business/AppKernelFacadeInterface.php
+++ b/src/Spryker/Zed/AppKernel/Business/AppKernelFacadeInterface.php
@@ -10,9 +10,29 @@
use Generated\Shared\Transfer\AppConfigCriteriaTransfer;
use Generated\Shared\Transfer\AppConfigResponseTransfer;
use Generated\Shared\Transfer\AppConfigTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationRequestTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationResponseTransfer;
interface AppKernelFacadeInterface
{
+ /**
+ * Specification:
+ * - Converts the `GlueRequestTransfer::getContent()` data from a JSON string into a `AppConfigTransfer`.
+ * - Calls `PlatformPluginInterface::validateConfiguration()` and passes the `AppConfigTransfer`.
+ * - When `PlatformPluginInterface::validateConfiguration()` throws an exception, the exception is logged.
+ * - When `PlatformPluginInterface::validateConfiguration()` throws an exception, a `GlueRequestValidationTransfer` with a failed response is returned.
+ * - When `PlatformPluginInterface::validateConfiguration()` is successful, a `GlueRequestValidationTransfer` with HTTP Status Code 200 (OK) is returned.
+ * - When `PlatformPluginInterface::validateConfiguration()` is not successful, validation errors from the `AppConfigValidateResponseTransfer` are converted
+ * to error messages and added to the `GlueRequestValidationTransfer`.
+ * - When `PlatformPluginInterface::validateConfiguration()` is NOT successful, a `GlueRequestValidationTransfer` with HTTP Status Code 422 (UNPROCESSABLE ENTITY) is returned.
+ * - Requires `GlueRequestTransfer::getContent()`.
+ *
+ * @api
+ */
+ public function validateConfiguration(
+ ConfigurationValidationRequestTransfer $configurationValidationRequestTransfer
+ ): ConfigurationValidationResponseTransfer;
+
/**
* Specification:
* - Saves the App configuration in the DB.
diff --git a/src/Spryker/Zed/AppKernel/Business/Configuration/ConfigurationValidator.php b/src/Spryker/Zed/AppKernel/Business/Configuration/ConfigurationValidator.php
new file mode 100644
index 0000000..9f39280
--- /dev/null
+++ b/src/Spryker/Zed/AppKernel/Business/Configuration/ConfigurationValidator.php
@@ -0,0 +1,79 @@
+setIsSuccessful(true);
+
+ try {
+ $appConfigValidateResponseTransfer = $this->appKernelPlatformPlugin->validateConfiguration($configurationValidationRequestTransfer->getAppConfigOrFail());
+ } catch (Throwable $throwable) {
+ return $this->buildFailedResponseFromException($throwable, $configurationValidationResponseTransfer);
+ }
+
+ if ($appConfigValidateResponseTransfer->getIsSuccessful() === true) {
+ return $configurationValidationResponseTransfer;
+ }
+
+ return $this->mapAppConfigurationValidationResponseTransferToConfigurationValidationResponseTransfer($appConfigValidateResponseTransfer, $configurationValidationResponseTransfer);
+ }
+
+ protected function mapAppConfigurationValidationResponseTransferToConfigurationValidationResponseTransfer(
+ AppConfigValidateResponseTransfer $appConfigValidateResponseTransfer,
+ ConfigurationValidationResponseTransfer $configurationValidationResponseTransfer
+ ): ConfigurationValidationResponseTransfer {
+ $configurationValidationResponseTransfer
+ ->setIsSuccessful(false);
+
+ $messages = [];
+ foreach ($appConfigValidateResponseTransfer->getConfigurationValidationErrors() as $configurationValidationErrorTransfer) {
+ foreach ($configurationValidationErrorTransfer->getErrorMessages() as $errorMessage) {
+ $messages[$configurationValidationErrorTransfer->getProperty()][] = $errorMessage;
+ }
+
+ $messages[$configurationValidationErrorTransfer->getProperty()] = implode(', ', $messages[$configurationValidationErrorTransfer->getProperty()]);
+ }
+
+ $configurationValidationResponseTransfer->setMessage(implode(', ', $messages));
+
+ return $configurationValidationResponseTransfer;
+ }
+
+ protected function buildFailedResponseFromException(
+ Throwable $throwable,
+ ConfigurationValidationResponseTransfer $configurationValidationResponseTransfer
+ ): ConfigurationValidationResponseTransfer {
+ $this->getLogger()->error($throwable->getMessage());
+ $configurationValidationResponseTransfer
+ ->setIsSuccessful(false)
+ ->setExceptionMessage($throwable->getMessage());
+
+ return $configurationValidationResponseTransfer;
+ }
+}
diff --git a/src/Spryker/Zed/AppKernel/Business/Writer/ConfigWriter.php b/src/Spryker/Zed/AppKernel/Business/Writer/ConfigWriter.php
index bd8af4e..6c1e263 100644
--- a/src/Spryker/Zed/AppKernel/Business/Writer/ConfigWriter.php
+++ b/src/Spryker/Zed/AppKernel/Business/Writer/ConfigWriter.php
@@ -77,9 +77,9 @@ protected function doSaveAppConfig(AppConfigTransfer $appConfigTransfer): AppCon
$this->configurePropelEncryption($appConfigTransfer);
- // New configurations will be set to "connected" by default.
+ // New configurations will be set to true by default.
if ($appConfigTransfer->getStatus() === null || $appConfigTransfer->getStatus() === '' || $appConfigTransfer->getStatus() === '0') {
- $appConfigTransfer->setStatus(AppKernelConfig::APP_STATUS_CONNECTED);
+ $appConfigTransfer->setStatus(AppKernelConfig::APP_STATUS_NEW);
}
// When the app gets deactivated, we set the status to disconnected.
diff --git a/tests/SprykerTest/Glue/AppKernel/Controller/AppConfigureControllerTest.php b/tests/SprykerTest/Glue/AppKernel/Controller/AppConfigureControllerTest.php
index 527c4d3..a751e3c 100644
--- a/tests/SprykerTest/Glue/AppKernel/Controller/AppConfigureControllerTest.php
+++ b/tests/SprykerTest/Glue/AppKernel/Controller/AppConfigureControllerTest.php
@@ -7,16 +7,26 @@
namespace SprykerTest\Glue\AppKernel\Controller;
+use Codeception\Stub;
use Codeception\Test\Unit;
use Exception;
use Generated\Shared\Transfer\AppConfigTransfer;
-use Spryker\Zed\AppKernel\AppKernelConfig;
+use Generated\Shared\Transfer\AppConfigValidateResponseTransfer;
+use Generated\Shared\Transfer\ConfigurationValidationErrorTransfer;
+use Orm\Zed\AppKernel\Persistence\SpyAppConfigQuery;
+use Ramsey\Uuid\Uuid;
+use Spryker\Glue\AppKernel\AppKernelConfig;
+use Spryker\Zed\AppKernel\AppKernelConfig as SprykerAppKernelConfig;
use Spryker\Zed\AppKernel\AppKernelDependencyProvider;
+use Spryker\Zed\AppKernelExtension\Dependency\Plugin\AppKernelPlatformPluginInterface;
use Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationAfterSavePluginInterface;
use Spryker\Zed\AppKernelExtension\Dependency\Plugin\ConfigurationBeforeSavePluginInterface;
use SprykerTest\Glue\AppKernel\AppKernelTester;
+use SprykerTest\Shared\Testify\Helper\DataCleanupHelperTrait;
+use SprykerTest\Shared\Testify\Helper\DependencyHelperTrait;
use SprykerTest\Shared\Testify\Helper\LocatorHelperTrait;
use SprykerTest\Zed\Testify\Helper\Business\DependencyProviderHelperTrait;
+use Symfony\Component\HttpFoundation\Response;
/**
* Auto-generated group annotations
@@ -32,6 +42,8 @@ class AppConfigureControllerTest extends Unit
{
use LocatorHelperTrait;
use DependencyProviderHelperTrait;
+ use DependencyHelperTrait;
+ use DataCleanupHelperTrait;
/**
* @var \SprykerTest\Glue\AppKernel\AppKernelTester
@@ -86,42 +98,41 @@ public function testPostConfigureReturnsSuccessResponseAndActivatesTheAppConfigu
/**
* @return void
*/
- public function testPostConfigureReturnsSuccessResponseAndActivatesTheAppConfigurationWhenAnAppConfigurationExistsAndWasMarkedAsDisconnected(): void
+ public function testPostConfigureReturnsSuccessResponseAndKeepsPreviousConfigurationWhenAnAppConfigurationExists(): void
{
// Arrange
$glueRequest = $this->tester->createGlueRequestFromFixture('valid-config-request');
- $this->tester->havePersistedAppConfigTransfer([AppConfigTransfer::TENANT_IDENTIFIER => 'tenant-identifier', AppConfigTransfer::IS_ACTIVE => true, AppConfigTransfer::STATUS => AppKernelConfig::APP_STATUS_DISCONNECTED]);
+ $this->tester->havePersistedAppConfigTransfer([AppConfigTransfer::TENANT_IDENTIFIER => 'tenant-identifier', AppConfigTransfer::IS_ACTIVE => false, AppConfigTransfer::CONFIG => ['key' => 'value']]);
$appConfigController = $this->tester->createAppConfigController();
+ $expectedConfig = ['key' => 'value', 'clientId' => 'ClientID', 'clientSecret' => 'ClientSecret', 'isActive' => true];
+
// Act
$glueResponse = $appConfigController->postConfigureAction($glueRequest);
+ // Set the expected content for the validation
+ $glueRequest->setContent('{"data":{"type":"configuration","attributes":{"configuration":"{\"key\":\"value\",\"clientId\":\"ClientID\",\"clientSecret\":\"ClientSecret\",\"isActive\":true}"}}}');
+
// Assert
$this->tester->assertGlueResponseContainsSuccessContents($glueRequest, $glueResponse);
- $this->tester->assertAppConfigIsActivated('tenant-identifier');
+ $this->tester->assertPersistedAppConfig('tenant-identifier', $expectedConfig);
}
/**
* @return void
*/
- public function testPostConfigureReturnsSuccessResponseAndKeepsPreviousConfigurationWhenAnAppConfigurationExists(): void
+ public function testGivenAnAppConfigInStatusDisconnectedAndIsActiveTrueWhenTheConfigurationIsSavedTheStatusIsChangedToConnected(): void
{
// Arrange
$glueRequest = $this->tester->createGlueRequestFromFixture('valid-config-request');
- $this->tester->havePersistedAppConfigTransfer([AppConfigTransfer::TENANT_IDENTIFIER => 'tenant-identifier', AppConfigTransfer::IS_ACTIVE => false, AppConfigTransfer::CONFIG => ['key' => 'value']]);
+ $this->tester->havePersistedAppConfigTransfer([AppConfigTransfer::TENANT_IDENTIFIER => 'tenant-identifier', AppConfigTransfer::IS_ACTIVE => true, AppConfigTransfer::STATUS => SprykerAppKernelConfig::APP_STATUS_DISCONNECTED, AppConfigTransfer::CONFIG => ['key' => 'value']]);
$appConfigController = $this->tester->createAppConfigController();
- $expectedConfig = ['key' => 'value', 'clientId' => 'ClientID', 'clientSecret' => 'ClientSecret', 'isActive' => true];
-
// Act
- $glueResponse = $appConfigController->postConfigureAction($glueRequest);
-
- // Set the expected content for the validation
- $glueRequest->setContent('{"data":{"type":"configuration","attributes":{"configuration":"{\"key\":\"value\",\"clientId\":\"ClientID\",\"clientSecret\":\"ClientSecret\",\"isActive\":true}"}}}');
+ $appConfigController->postConfigureAction($glueRequest);
// Assert
- $this->tester->assertGlueResponseContainsSuccessContents($glueRequest, $glueResponse);
- $this->tester->assertPersistedAppConfig('tenant-identifier', $expectedConfig);
+ $this->tester->assertAppConfigStatus('tenant-identifier', SprykerAppKernelConfig::APP_STATUS_CONNECTED);
}
/**
@@ -373,4 +384,196 @@ public function beforeSave(AppConfigTransfer $appConfigTransfer): AppConfigTrans
// Assert
$this->tester->assertGlueResponseContainsErrorMessageWhenExceptionWasThrown($glueResponse);
}
+
+ public function testReceivingConfigurationFromAppStoreCatalogWithoutTheAcceptLanguageHeaderAppliesDefaultLocaleEnUSAndSavesAppConfigurationWhenPlatformValidationWasSuccessful(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $this->getDataCleanupHelper()->_addCleanup(function () use ($tenantIdentifier): void {
+ SpyAppConfigQuery::create()
+ ->filterByTenantIdentifier($tenantIdentifier)
+ ->delete();
+ });
+
+ $appConfigValidateResponseTransfer = new AppConfigValidateResponseTransfer();
+ $appConfigValidateResponseTransfer->setIsSuccessful(true);
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => $appConfigValidateResponseTransfer,
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/configure', $this->tester->getAppConfigureRequestData());
+
+ // Assert
+ $this->assertSame(200, $response->getStatusCode());
+ $this->tester->assertAppConfigForTenantEquals($tenantIdentifier);
+ }
+
+ public function testReceivingConfigurationFromAppStoreCatalogSavesAppConfigurationWhenPlatformValidationWasSuccessful(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $this->getDataCleanupHelper()->_addCleanup(function () use ($tenantIdentifier): void {
+ SpyAppConfigQuery::create()
+ ->filterByTenantIdentifier($tenantIdentifier)
+ ->delete();
+ });
+
+ $appConfigValidateResponseTransfer = new AppConfigValidateResponseTransfer();
+ $appConfigValidateResponseTransfer->setIsSuccessful(true);
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => $appConfigValidateResponseTransfer,
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ 'Accept-Language' => 'en-US, en;q=0.9,*;q=0.5',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/configure', $this->tester->getAppConfigureRequestData());
+
+ // Assert
+ $this->assertSame(200, $response->getStatusCode());
+ $this->tester->assertAppConfigForTenantEquals($tenantIdentifier);
+ }
+
+ public function testReceivingConfigurationFromAppStoreCatalogReturns422UnprocessableEntityWhenPlatformValidationFailed(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $appConfigValidateResponseTransfer = new AppConfigValidateResponseTransfer();
+ $appConfigValidateResponseTransfer->setIsSuccessful(false);
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => $appConfigValidateResponseTransfer,
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ 'Accept-Language' => 'en-US, en;q=0.9,*;q=0.5',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/configure', $this->tester->getAppConfigureRequestData());
+
+ // Assert
+ $this->assertSame(Response::HTTP_UNPROCESSABLE_ENTITY, $response->getStatusCode());
+ $this->tester->assertAppConfigurationForTenantDoesNotExist($tenantIdentifier);
+ }
+
+ public function testReceivingConfigurationFromAppStoreCatalogReturns422UnprocessableEntityWithErrorMessagesWhenPlatformValidationFailed(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $configurationValidationErrorTransfer = new ConfigurationValidationErrorTransfer();
+ $configurationValidationErrorTransfer->addErrorMessage('Something went wrong');
+
+ $appConfigValidateResponseTransfer = new AppConfigValidateResponseTransfer();
+ $appConfigValidateResponseTransfer
+ ->setIsSuccessful(false)
+ ->addConfigurationValidationError($configurationValidationErrorTransfer);
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => $appConfigValidateResponseTransfer,
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ 'Accept-Language' => 'en-US, en;q=0.9,*;q=0.5',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/configure', $this->tester->getAppConfigureRequestData());
+
+ // Assert
+ $this->assertSame(Response::HTTP_UNPROCESSABLE_ENTITY, $response->getStatusCode());
+ $this->tester->assertAppConfigurationForTenantDoesNotExist($tenantIdentifier);
+ }
+
+ public function testReceivingConfigurationFromAppStoreCatalogReturns422UnprocessableEntityWithErrorMessagesWhenPlatformValidationThrowsAnException(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => static function (): never {
+ throw new Exception('Something went wrong');
+ },
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ 'Accept-Language' => 'en-US, en;q=0.9,*;q=0.5',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/configure', $this->tester->getAppConfigureRequestData());
+
+ // Assert
+ $this->assertSame(Response::HTTP_INTERNAL_SERVER_ERROR, $response->getStatusCode());
+ $this->tester->assertAppConfigurationForTenantDoesNotExist($tenantIdentifier);
+ }
+
+ public function testDisconnectAppForAnExistingTenantDeactivatesAppConfiguration(): void
+ {
+ // Arrange
+ $tenantIdentifier = Uuid::uuid4()->toString();
+
+ $this->tester->haveAppConfigForTenant($tenantIdentifier);
+ $this->tester->assertAppConfigForTenantEquals($tenantIdentifier);
+
+ $appConfigValidateResponseTransfer = new AppConfigValidateResponseTransfer();
+ $appConfigValidateResponseTransfer->setIsSuccessful(false);
+
+ $platformPluginMock = Stub::makeEmpty(AppKernelPlatformPluginInterface::class, [
+ 'validateConfiguration' => $appConfigValidateResponseTransfer,
+ ]);
+
+ $this->getDependencyHelper()->setDependency(AppKernelDependencyProvider::PLUGIN_PLATFORM, $platformPluginMock);
+
+ $this->tester->setHeaders([
+ AppKernelConfig::HEADER_TENANT_IDENTIFIER => $tenantIdentifier,
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ 'Accept-Language' => 'en-US, en;q=0.9,*;q=0.5',
+ ]);
+
+ // Act
+ $response = $this->tester->sendPost('/private/disconnect');
+
+ // Assert
+ $this->assertSame(204, $response->getStatusCode());
+ $this->tester->assertAppConfigurationForTenantIsDeactivated($tenantIdentifier);
+ }
}
diff --git a/tests/SprykerTest/Glue/AppKernel/codeception.yml b/tests/SprykerTest/Glue/AppKernel/codeception.yml
index b97bc51..60cd1b9 100644
--- a/tests/SprykerTest/Glue/AppKernel/codeception.yml
+++ b/tests/SprykerTest/Glue/AppKernel/codeception.yml
@@ -18,6 +18,7 @@ suites:
modules:
enabled:
- \SprykerTest\Zed\Testify\Helper\Business\BusinessHelper
+ - \SprykerTest\Glue\Testify\Helper\DependencyProviderHelper
- \SprykerTest\Shared\Testify\Helper\Environment
- \SprykerTest\Zed\Propel\Helper\PropelEncryptionHelper
- \SprykerTest\Zed\Testify\Helper\Business\DependencyProviderHelper
@@ -25,7 +26,11 @@ suites:
- \SprykerTest\Glue\AppKernel\Helper\AppKernelAssertionHelper
- \SprykerTest\Zed\AppKernel\Helper\AppKernelAssertionHelper
- \SprykerTest\Zed\AppKernel\Helper\AppKernelHelper
+ - \SprykerTest\Shared\AppKernel\Helper\AppConfigHelper
- \SprykerTest\Shared\Propel\Helper\TransactionHelper
- \SprykerTest\Shared\Testify\Helper\LocatorHelper
- \SprykerTest\Shared\Testify\Helper\ConfigHelper
- \SprykerTest\Zed\MessageBroker\Helper\InMemoryMessageBrokerHelper
+ - \SprykerTest\Shared\Testify\Helper\DataCleanupHelper
+ - \SprykerTest\Shared\Testify\Helper\DependencyHelper
+ - \SprykerTest\Glue\Testify\Helper\AppKernelGlueBackendApiHelper
diff --git a/tests/SprykerTest/Glue/Testify/_support/Helper/AppKernelGlueBackendApiHelper.php b/tests/SprykerTest/Glue/Testify/_support/Helper/AppKernelGlueBackendApiHelper.php
new file mode 100644
index 0000000..f31629a
--- /dev/null
+++ b/tests/SprykerTest/Glue/Testify/_support/Helper/AppKernelGlueBackendApiHelper.php
@@ -0,0 +1,145 @@
+|string $parameters
+ */
+ protected function executeRequest(string $url, string $method, array $parameters = []): Response
+ {
+ $this->addHeader('Accept', 'application/json');
+
+ $request = Request::create($url, strtolower($method), $parameters, [], [], [], $parameters !== [] ? json_encode($parameters, JSON_PRESERVE_ZERO_FRACTION | JSON_THROW_ON_ERROR) : null);
+ $request = $this->removeServerAndHeaderDefaults($request);
+
+ $request->headers->add($this->headers);
+
+ // Set the predefined Request so that the GlueBackendApiApplication can pick it up instead of creating an empty Request.
+ $this->getRequestBuilderStub()->setRequest($request);
+
+ // Run the mocked GlueBackendApiApplication.
+ $this->getGlueBackendApiApplication()->run();
+
+ // Get the response that was created from the GlueBackendApiApplication.
+ $response = $this->getHttpSenderStub()->getResponse();
+
+ $this->persistLastConnection($request, $response);
+
+ return $response;
+ }
+
+ /**
+ * The Request::create() method adds some default headers and server values that we do not want to have in our tests.
+ */
+ protected function removeServerAndHeaderDefaults(Request $request): Request
+ {
+ foreach (['HTTP_ACCEPT', 'HTTP_ACCEPT_LANGUAGE', 'HTTP_ACCEPT_CHARSET'] as $server) {
+ $request->server->remove($server);
+ }
+ foreach (['accept', 'accept-language', 'accept-charset'] as $header) {
+ $request->headers->remove($header);
+ }
+
+ return $request;
+ }
+
+ protected function getGlueBackendApiApplication(): ApplicationInterface
+ {
+ /** @var \Spryker\Glue\GlueApplication\GlueApplicationFactory $glueApplicationFactory */
+ $glueApplicationFactory = Stub::make(GlueApplicationFactory::class, [
+ 'createHttpRequestBuilder' => $this->getRequestBuilderStub(),
+ 'createHttpSender' => $this->getHttpSenderStub(),
+ 'resolveDependencyProvider' => new GlueApplicationDependencyProvider(),
+ 'getConfig' => $this->getConfigHelper()->getModuleConfig('GlueApplication'),
+ ]);
+
+ $this->getDependencyProviderHelper()->setDependency(GlueBackendApiApplicationDependencyProvider::PLUGINS_REQUEST_BUILDER, [
+ new ApplicationIdentifierRequestBuilderPlugin(),
+ ], GlueBackendApiApplicationFactory::class);
+
+ $this->getDependencyProviderHelper()->setDependency(GlueBackendApiApplicationDependencyProvider::PLUGINS_ROUTE_PROVIDER, [
+ new AppKernelRouteProviderPlugin(),
+ ], GlueBackendApiApplicationFactory::class);
+
+ $this->getDependencyProviderHelper()->setDependency(GlueApplicationDependencyProvider::PLUGINS_RESOURCES_PROVIDER, [
+ new BackendResourcesProviderPlugin(),
+ ], get_class($glueApplicationFactory));
+
+ $this->getDependencyProviderHelper()->setDependency(GlueApplicationDependencyProvider::PLUGINS_CONVENTION, [
+ new JsonApiConventionPlugin(),
+ ], get_class($glueApplicationFactory));
+
+ $this->getDependencyProviderHelper()->setDependency(GlueApplicationDependencyProvider::PLUGINS_ROUTES_PROVIDER, [
+ new CustomRouteRoutesProviderPlugin(),
+ ], get_class($glueApplicationFactory));
+
+ $this->getDependencyProviderHelper()->setDependency(GlueApplicationDependencyProvider::PLUGINS_CONTROLLER_CACHE_COLLECTOR, [
+ new BackendControllerCacheCollectorPlugin(),
+ ], get_class($glueApplicationFactory));
+
+ $this->getDependencyProviderHelper()->setDependency(
+ GlueBackendApiApplicationDependencyProvider::PLUGINS_RESOURCE,
+ $this->getJsonApiResourcePlugins(),
+ GlueBackendApiApplicationFactory::class,
+ );
+
+ return (new GlueBackendApiBootstrap())
+ ->setFactory($glueApplicationFactory)
+ ->boot();
+ }
+
+ /**
+ * @param int $code
+ *
+ * @return void
+ */
+ public function seeResponseCodeIs(int $code): void
+ {
+ $failureMessage = sprintf(
+ 'Expected HTTP Status Code: %s. Actual Status Code: %s. Response: %s',
+ HttpCode::getDescription($code),
+ HttpCode::getDescription($this->getResponse()->getStatusCode()),
+ $this->getResponse(),
+ );
+ $this->assertSame($code, $this->getResponse()->getStatusCode(), $failureMessage);
+ }
+
+ /**
+ * Overridden to not throw an exception when we are on project level and do not need to set plugins manually.
+ *
+ * @return array<\Spryker\Glue\GlueJsonApiConventionExtension\Dependency\Plugin\JsonApiResourceInterface>
+ */
+ protected function getJsonApiResourcePlugins(): array
+ {
+ if ($this->jsonApiResourcePlugins === []) {
+ return [];
+ }
+
+ return $this->jsonApiResourcePlugins;
+ }
+}
diff --git a/tests/SprykerTest/Glue/Testify/_support/Helper/GlueApplication/Bootstrap/GlueBackendApiBootstrap.php b/tests/SprykerTest/Glue/Testify/_support/Helper/GlueApplication/Bootstrap/GlueBackendApiBootstrap.php
new file mode 100644
index 0000000..570acbe
--- /dev/null
+++ b/tests/SprykerTest/Glue/Testify/_support/Helper/GlueApplication/Bootstrap/GlueBackendApiBootstrap.php
@@ -0,0 +1,23 @@
+ $glueApplicationBootstrapPluginClassNames
+ */
+ public function boot(array $glueApplicationBootstrapPluginClassNames = []): ApplicationInterface
+ {
+ return parent::boot([BackendApiGlueApplicationBootstrapPlugin::class]);
+ }
+}
diff --git a/tests/SprykerTest/Zed/AppKernel/_support/Helper/AppKernelAssertionHelper.php b/tests/SprykerTest/Zed/AppKernel/_support/Helper/AppKernelAssertionHelper.php
index 4a9dd32..8f068a5 100644
--- a/tests/SprykerTest/Zed/AppKernel/_support/Helper/AppKernelAssertionHelper.php
+++ b/tests/SprykerTest/Zed/AppKernel/_support/Helper/AppKernelAssertionHelper.php
@@ -74,6 +74,32 @@ public function assertAppConfigIsActivated(string $tenantIdentifier): void
));
}
+ /**
+ * @param string $tenantIdentifier
+ *
+ * @return void
+ */
+ public function assertAppConfigStatus(string $tenantIdentifier, string $expectedStatus): void
+ {
+ $appConfigEntities = SpyAppConfigQuery::create()
+ ->filterByTenantIdentifier($tenantIdentifier)
+ ->find()
+ ->toArray();
+
+ $this->assertSame(1, count($appConfigEntities), sprintf(
+ 'Expected to have one persisted configurations for tenant identifier "%s" but found "%d".',
+ $tenantIdentifier,
+ count($appConfigEntities),
+ ));
+
+ $this->assertSame($expectedStatus, $appConfigEntities[0]['Status'], sprintf(
+ 'Expected to have the configuration for tenant identifier "%s" in status "%s" but it is in "%s".',
+ $tenantIdentifier,
+ $expectedStatus,
+ $appConfigEntities[0]['Status'],
+ ));
+ }
+
/**
* @param string $tenantIdentifier
* @param array $expectedConfig