config_preview_deploy-1.0.0-alpha3/tests/src/Kernel/PreviewControllerProductionStatusTest.php
tests/src/Kernel/PreviewControllerProductionStatusTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\config_preview_deploy\Kernel;
use Drupal\config_preview_deploy\Controller\PreviewController;
use Drupal\KernelTests\KernelTestBase;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
/**
* Tests for PreviewController production status integration.
*
* @group config_preview_deploy
*/
class PreviewControllerProductionStatusTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'config_preview_deploy',
'system',
'user',
'config',
];
/**
* The preview controller.
*
* @var \Drupal\config_preview_deploy\Controller\PreviewController
*/
protected $previewController;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('user');
$this->installConfig(['system', 'user']);
// Set up production URL in config.
$this->config('config_preview_deploy.settings')
->set('production_url', 'https://production.example.com')
->save();
}
/**
* Tests dashboard shows production status when available.
*/
public function testDashboardWithProductionStatus(): void {
// Create base checkpoint.
$configDiff = $this->container->get('config_preview_deploy.config_diff');
$baseTimestamp = time() - 3600;
$configDiff->createBaseCheckpoint();
// Make a configuration change to ensure there are pending changes.
$this->config('system.site')->set('name', 'Test Site Changed')->save();
// Set up mock HTTP client with successful production status response.
// Production changed 30 minutes ago.
$prodLastChange = time() - 1800;
$mockHandler = new MockHandler([
new Response(200, ['Content-Type' => 'application/json'], json_encode([
'last_change' => $prodLastChange,
'last_deployed_from' => 'staging',
'environment' => 'production',
'timestamp' => time(),
])),
]);
$handlerStack = HandlerStack::create($mockHandler);
$mockClient = new Client(['handler' => $handlerStack]);
// Replace HTTP client service with mock.
$this->container->set('http_client', $mockClient);
// Create controller instance.
$this->previewController = PreviewController::create($this->container);
// Call dashboard method.
$build = $this->previewController->dashboard();
// Assert environment info is present.
$this->assertArrayHasKey('environment_info', $build);
$this->assertArrayHasKey('details', $build['environment_info']);
// Check that production info section is present.
$this->assertArrayHasKey('production_info', $build);
$this->assertArrayHasKey('details', $build['production_info']);
// Check production status items.
$prodItems = $build['production_info']['details']['#items'];
$prodItemsText = implode(' ', array_map('strval', $prodItems));
$this->assertStringContainsString('Production last changed:', $prodItemsText);
$this->assertStringContainsString('Ready to deploy', $prodItemsText);
}
/**
* Tests dashboard shows rebase required when production is newer.
*/
public function testDashboardWithRebaseRequired(): void {
// Create base checkpoint with old timestamp.
$configDiff = $this->container->get('config_preview_deploy.config_diff');
$configDiff->createBaseCheckpoint();
// Mock production status with newer timestamp (1 hour newer).
// Production changed 1 hour from now.
$prodLastChange = time() + 3600;
$mockHandler = new MockHandler([
new Response(200, ['Content-Type' => 'application/json'], json_encode([
'last_change' => $prodLastChange,
'last_deployed_from' => 'staging',
'environment' => 'production',
'timestamp' => time(),
])),
]);
$handlerStack = HandlerStack::create($mockHandler);
$mockClient = new Client(['handler' => $handlerStack]);
$this->container->set('http_client', $mockClient);
// Set up config settings.
$configSettings = $this->config('config_preview_deploy.settings');
$configSettings->save();
// Create controller instance.
$this->previewController = PreviewController::create($this->container);
// Call dashboard method.
$build = $this->previewController->dashboard();
// Check that rebase warning is shown in production info.
$prodItems = $build['production_info']['details']['#items'];
$prodItemsText = implode(' ', array_map('strval', $prodItems));
$this->assertStringContainsString('Rebase required', $prodItemsText);
$this->assertStringNotContainsString('Ready to deploy', $prodItemsText);
}
/**
* Tests dashboard handles production status API failure gracefully.
*/
public function testDashboardWithProductionStatusFailure(): void {
// Create base checkpoint.
$configDiff = $this->container->get('config_preview_deploy.config_diff');
$configDiff->createBaseCheckpoint();
// Mock HTTP client to return error.
$mockHandler = new MockHandler([
new Response(500, [], 'Internal Server Error'),
]);
$handlerStack = HandlerStack::create($mockHandler);
$mockClient = new Client(['handler' => $handlerStack]);
$this->container->set('http_client', $mockClient);
// Create controller instance.
$this->previewController = PreviewController::create($this->container);
// Call dashboard method.
$build = $this->previewController->dashboard();
// Check that error is handled gracefully in production info.
$prodItems = $build['production_info']['details']['#items'];
$prodItemsText = implode(' ', array_map('strval', $prodItems));
$this->assertStringContainsString('Production server error', $prodItemsText);
}
}
