config_preview_deploy-1.0.0-alpha3/tests/src/Kernel/ProductionUIProtectionTest.php
tests/src/Kernel/ProductionUIProtectionTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\config_preview_deploy\Kernel;
use Drupal\config_preview_deploy\Access\PreviewEnvironmentAccess;
use Drupal\config_preview_deploy\ConfigVerifier;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\user\Traits\UserCreationTrait;
/**
* Tests production environment UI protection.
*
* Verifies that forms and actions are properly hidden/disabled when
* running in production mode to prevent accidental configuration
* deployments from production.
*
* @group config_preview_deploy
*/
class ProductionUIProtectionTest extends KernelTestBase {
use UserCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'config_preview_deploy',
'system',
'user',
];
/**
* The preview environment access service.
*/
protected PreviewEnvironmentAccess $previewAccess;
/**
* The config verifier service.
*/
protected ConfigVerifier $configVerifier;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('user');
$this->installConfig(['system', 'user']);
$this->previewAccess = $this->container->get('config_preview_deploy.preview_environment_access');
$this->configVerifier = $this->container->get('config_preview_deploy.config_verifier');
}
/**
* Tests deploy form access in both preview and production environments.
*/
public function testDeployFormAccess(): void {
// Test in preview environment.
$this->configureAsPreviewEnvironment();
// Create user with deployment permission.
$user = $this->createUser(['deploy config from preview']);
// Test access allowed in preview.
$access = $this->previewAccess->deployFormAccess($user);
$this->assertTrue($access->isAllowed(), 'Deploy form should be accessible in preview environment');
// Test user without permission.
$userNoPermission = $this->createUser();
$access = $this->previewAccess->deployFormAccess($userNoPermission);
$this->assertFalse($access->isAllowed(), 'Deploy form should not be allowed for user without permission');
// Test in production environment.
$this->configureAsProductionEnvironment();
// Test access forbidden in production.
$access = $this->previewAccess->deployFormAccess($user);
$this->assertTrue($access->isForbidden(), 'Deploy form should be forbidden in production environment');
$this->assertStringContainsString('production', $access->getReason(), 'Should mention production in reason');
}
/**
* Tests rebase form access in both preview and production environments.
*/
public function testRebaseFormAccess(): void {
// Test in preview environment.
$this->configureAsPreviewEnvironment();
// Create user with deployment permission.
$user = $this->createUser(['deploy config from preview']);
// Test access allowed in preview.
$access = $this->previewAccess->rebaseFormAccess($user);
$this->assertTrue($access->isAllowed(), 'Rebase form should be accessible in preview environment');
// Test user without permission.
$userNoPermission = $this->createUser();
$access = $this->previewAccess->rebaseFormAccess($userNoPermission);
$this->assertFalse($access->isAllowed(), 'Rebase form should not be allowed for user without permission');
// Test in production environment.
$this->configureAsProductionEnvironment();
// Test access forbidden in production.
$access = $this->previewAccess->rebaseFormAccess($user);
$this->assertTrue($access->isForbidden(), 'Rebase form should be forbidden in production environment');
$this->assertStringContainsString('production', $access->getReason(), 'Should mention production in reason');
}
/**
* Tests download diff access in both preview and production environments.
*/
public function testDownloadDiffAccess(): void {
// Test in preview environment.
$this->configureAsPreviewEnvironment();
// Create user with deployment permission.
$user = $this->createUser(['deploy config from preview']);
// Test access allowed in preview.
$access = $this->previewAccess->downloadDiffAccess($user);
$this->assertTrue($access->isAllowed(), 'Download diff should be accessible in preview environment');
// Test user without permission.
$userNoPermission = $this->createUser();
$access = $this->previewAccess->downloadDiffAccess($userNoPermission);
$this->assertFalse($access->isAllowed(), 'Download diff should not be allowed for user without permission');
// Test in production environment.
$this->configureAsProductionEnvironment();
// Test access forbidden in production.
$access = $this->previewAccess->downloadDiffAccess($user);
$this->assertTrue($access->isForbidden(), 'Download diff should be forbidden in production environment');
$this->assertStringContainsString('production', $access->getReason(), 'Should mention production in reason');
}
/**
* Tests production detection via environment variables and domain matching.
*/
public function testProductionDetection(): void {
// Test production detection via environment variable.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=1');
$this->assertTrue($this->previewAccess->isProduction(), 'Should detect production via environment variable');
// Test with environment variable set to false.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=0');
$this->assertFalse($this->previewAccess->isProduction(), 'Should not detect production when env var is 0');
// Clean up environment variable.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION');
// Test production detection via domain matching.
// Configure production URL that definitely won't match test environment.
$this->config('config_preview_deploy.settings')
->set('production_url', 'https://definitely-not-test-host.example.com')
->save();
// Should not detect production with different domain.
$this->assertFalse($this->previewAccess->isProduction(), 'Should not detect production with different domain');
// Test without production URL configured.
$this->config('config_preview_deploy.settings')
->set('production_url', '')
->save();
$this->assertFalse($this->previewAccess->isProduction(), 'Should not detect production without URL configured');
// Test environment variable precedence over domain matching.
$this->config('config_preview_deploy.settings')
->set('production_url', 'https://example.com')
->save();
// Override with environment variable set to false.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=0');
$this->assertFalse($this->previewAccess->isProduction(), 'Environment variable should override domain matching');
// Now set environment variable to true.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=1');
$this->assertTrue($this->previewAccess->isProduction(), 'Environment variable should force production mode');
// Clean up.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION');
}
/**
* Tests comprehensive access control scenarios and production endpoints.
*/
public function testAccessControlAndProductionEndpoints(): void {
// Test access control with various permission combinations.
$this->configureAsPreviewEnvironment();
// Create user and check baseline permissions.
$testUser = $this->createUser(['deploy config from preview']);
$access = $this->previewAccess->deployFormAccess($testUser);
$this->assertTrue($access->isAllowed(), 'User with deploy permission should have access');
// Test that production access restriction works.
$this->configureAsProductionEnvironment();
$this->assertTrue($this->previewAccess->isProduction(), 'Should be in production mode');
$access = $this->previewAccess->deployFormAccess($testUser);
$this->assertTrue($access->isForbidden(), 'Access should be forbidden in production environment');
// Test rebase form access.
$this->configureAsPreviewEnvironment();
$access = $this->previewAccess->rebaseFormAccess($testUser);
$this->assertTrue($access->isAllowed(), 'Rebase form should be accessible in preview');
// Test download diff access.
$access = $this->previewAccess->downloadDiffAccess($testUser);
$this->assertTrue($access->isAllowed(), 'Download diff should be accessible in preview');
}
/**
* Configures the environment as preview.
*/
protected function configureAsPreviewEnvironment(): void {
// Clear any production indicators.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION');
// Set different domain than production (test environment won't match).
$this->config('config_preview_deploy.settings')
->set('production_url', 'https://production.example.com')
->save();
}
/**
* Configures the environment as production.
*/
protected function configureAsProductionEnvironment(): void {
// Set environment variable to force production mode.
putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=1');
}
}
