config_preview_deploy-1.0.0-alpha3/tests/src/Kernel/ConfigDiffTest.php
tests/src/Kernel/ConfigDiffTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\config_preview_deploy\Kernel;
use Drupal\config_preview_deploy\ConfigDiff;
use Drupal\Core\Config\Checkpoint\CheckpointStorage;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests the CheckpointDiff service.
*
* @group config_preview_deploy
*/
class ConfigDiffTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['config_preview_deploy', 'system'];
/**
* The configuration diff service.
*/
protected ConfigDiff $configDiff;
/**
* The checkpoint storage.
*/
protected CheckpointStorage $checkpointStorage;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig(['system']);
$this->configDiff = $this->container->get('config_preview_deploy.config_diff');
// Create checkpoint storage for testing.
$this->checkpointStorage = new CheckpointStorage(
$this->container->get('config.storage'),
$this->container->get('config.checkpoints'),
$this->container->get('keyvalue')
);
}
/**
* Tests checkpoint basic operations and base version functionality.
*/
public function testCheckpointBasicOperations(): void {
// Test 1: Initially no base version.
$this->assertNull($this->configDiff->getBaseVersion());
// Test 2: Creating base checkpoint.
$checkpointId = $this->configDiff->createBaseCheckpoint();
$this->assertNotEmpty($checkpointId);
$this->assertIsString($checkpointId);
// Test 3: Verify base version is stored correctly.
$baseVersion = $this->configDiff->getBaseVersion();
$this->assertNotNull($baseVersion);
$this->assertEquals($checkpointId, $baseVersion['checkpoint_id']);
$this->assertIsInt($baseVersion['timestamp']);
$this->assertArrayHasKey('timestamp', $baseVersion);
// Test 4: The error handling for no base checkpoint is tested separately
// in a different test method since it requires a fresh service instance.
}
/**
* Tests configuration change detection after checkpoint initialization.
*/
public function testConfigurationChangeDetection(): void {
// Create base checkpoint.
$this->configDiff->createBaseCheckpoint();
// Test 1: Generate diff with no changes (should be empty).
$diff = $this->configDiff->generateDiff();
$this->assertIsString($diff);
$this->assertEmpty($diff);
// Test 2: Initially no changes detected.
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertIsArray($changedConfigs);
$this->assertEmpty($changedConfigs);
// Test 3: Has changes should return false initially.
$this->assertFalse($this->configDiff->hasChanges());
// Test 4: Make configuration changes and verify detection.
$newSiteName = 'Test Site Modified';
$this->config('system.site')
->set('name', $newSiteName)
->set('slogan', 'New test slogan')
->save();
// Test 5: Generate diff with changes.
$diff = $this->configDiff->generateDiff();
$this->assertNotEmpty($diff);
$this->assertStringContainsString('system.site', $diff);
$this->assertStringContainsString('--- a/system.site', $diff);
$this->assertStringContainsString('+++ b/system.site', $diff);
// Test 6: Get changed configurations.
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertContains('system.site', $changedConfigs);
// Test 7: Has changes should return true after modifications.
$this->assertTrue($this->configDiff->hasChanges());
}
/**
* Tests checkpoint initialization regression scenarios.
*/
public function testCheckpointInitializationRegression(): void {
// Create base checkpoint.
$this->configDiff->createBaseCheckpoint();
// Test 1: Immediately after checkpoint creation, no changes should be
// detected.
// This is a regression test for the bug where checkpoint initialization
// incorrectly showed all configurations as changed instead of 0.
$this->assertFalse($this->configDiff->hasChanges(), 'Checkpoint initialization should show 0 changes');
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertEmpty($changedConfigs, 'No configurations should be marked as changed immediately after checkpoint creation');
// Generated diff should be empty.
$diff = $this->configDiff->generateDiff();
$this->assertEmpty($diff, 'Diff should be empty immediately after checkpoint creation');
// Test 2: Verify that actual configuration changes are properly detected.
// This verifies that the fix for the checkpoint initialization bug
// doesn't prevent detection of real changes.
// Make actual configuration changes.
$this->config('system.site')
->set('name', 'Modified Site Name')
->set('slogan', 'Modified Slogan')
->save();
// Now changes should be detected.
$this->assertTrue($this->configDiff->hasChanges(), 'Real configuration changes should be detected');
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertContains('system.site', $changedConfigs, 'Modified configuration should appear in changed configs list');
$this->assertCount(1, $changedConfigs, 'Only one configuration should be changed');
// Generated diff should contain the changes.
$diff = $this->configDiff->generateDiff();
$this->assertNotEmpty($diff, 'Diff should contain actual changes');
$this->assertStringContainsString('system.site', $diff);
$this->assertStringContainsString('Modified Site Name', $diff);
}
/**
* Tests diff generation with multiple configuration files.
*/
public function testMultipleConfigurationDiff(): void {
// Create base checkpoint.
$this->configDiff->createBaseCheckpoint();
// Make multiple configuration changes across different files.
$this->config('system.site')
->set('name', 'New Site Name')
->set('slogan', 'New Slogan')
->save();
$this->config('system.theme')
->set('default', 'test_theme')
->save();
// Test 1: Generate diff with multiple changes.
$diff = $this->configDiff->generateDiff();
$this->assertNotEmpty($diff);
$this->assertStringContainsString('system.site', $diff);
$this->assertStringContainsString('system.theme', $diff);
// Test 2: Get changed configurations should include both files.
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertContains('system.site', $changedConfigs);
$this->assertContains('system.theme', $changedConfigs);
$this->assertCount(2, $changedConfigs);
// Test 3: Has changes should detect multiple changes.
$this->assertTrue($this->configDiff->hasChanges());
}
/**
* Tests configuration change workflow scenarios.
*/
public function testConfigurationWorkflowScenarios(): void {
// Create base checkpoint.
$checkpointId = $this->configDiff->createBaseCheckpoint();
// Test 1: Verify checkpoint creation returns valid ID.
$this->assertNotEmpty($checkpointId);
$this->assertIsString($checkpointId);
// Test 2: Verify base version reflects the checkpoint.
$baseVersion = $this->configDiff->getBaseVersion();
$this->assertEquals($checkpointId, $baseVersion['checkpoint_id']);
// Test 3: Make and verify single configuration change.
$this->config('system.site')->set('name', 'Changed Site Name')->save();
$this->assertTrue($this->configDiff->hasChanges());
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertContains('system.site', $changedConfigs);
// Test 4: Generate and verify diff content.
$diff = $this->configDiff->generateDiff();
$this->assertNotEmpty($diff);
$this->assertStringContainsString('system.site', $diff);
$this->assertStringContainsString('Changed Site Name', $diff);
}
/**
* Tests comprehensive checkpoint and diff functionality.
*
* Includes error handling scenarios.
*/
public function testComprehensiveCheckpointFunctionality(): void {
// Test 1: Error handling when no base checkpoint exists.
// Get a fresh service instance to test error case.
$freshCheckpointDiff = $this->container->get('config_preview_deploy.config_diff');
try {
$freshCheckpointDiff->generateDiff();
$this->fail('Expected RuntimeException was not thrown');
}
catch (\RuntimeException $e) {
$this->assertStringContainsString('No base checkpoint found', $e->getMessage());
}
// Test 2: Full workflow from checkpoint creation to diff generation.
// Step 1: Create checkpoint and verify state.
$checkpointId = $this->configDiff->createBaseCheckpoint();
$this->assertNotEmpty($checkpointId);
$baseVersion = $this->configDiff->getBaseVersion();
$this->assertNotNull($baseVersion);
$this->assertEquals($checkpointId, $baseVersion['checkpoint_id']);
// Step 2: Verify clean state immediately after checkpoint.
$this->assertFalse($this->configDiff->hasChanges());
$this->assertEmpty($this->configDiff->getChangedConfigs());
$this->assertEmpty($this->configDiff->generateDiff());
// Step 3: Make comprehensive configuration changes.
$this->config('system.site')
->set('name', 'Comprehensive Test Site')
->set('slogan', 'Testing comprehensive functionality')
->save();
// Step 4: Verify all detection methods work correctly.
$this->assertTrue($this->configDiff->hasChanges());
$changedConfigs = $this->configDiff->getChangedConfigs();
$this->assertContains('system.site', $changedConfigs);
$this->assertCount(1, $changedConfigs);
$diff = $this->configDiff->generateDiff();
$this->assertNotEmpty($diff);
$this->assertStringContainsString('system.site', $diff);
$this->assertStringContainsString('Comprehensive Test Site', $diff);
$this->assertStringContainsString('Testing comprehensive functionality', $diff);
}
}
