config_preview_deploy-1.0.0-alpha3/tests/src/Functional/DrushWorkflowIntegrationTest.php

tests/src/Functional/DrushWorkflowIntegrationTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\config_preview_deploy\Functional;

use Drupal\Tests\BrowserTestBase;
use Drush\TestTraits\DrushTestTrait;

/**
 * Integration tests for the complete Drush workflow.
 *
 * Tests the real-world workflow: init -> make changes -> diff -> apply
 * This ensures the complete loop works end-to-end.
 *
 * @group config_preview_deploy
 */
class DrushWorkflowIntegrationTest extends BrowserTestBase {

  use DrushTestTrait;

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'config_preview_deploy',
    'system',
    'user',
  ];

  /**
   * Tests complete workflow: init -> change -> diff -> revert -> apply.
   */
  public function testCompleteWorkflow(): void {
    // Step 1: Get the original site name for proper baseline.
    $this->drush('config:get', ['system.site', 'name']);
    $originalName = trim(str_replace(['\'', '"'], '', $this->getOutput()));

    // Step 2: Initialize the base checkpoint.
    $this->drush('config:preview-deploy:init');
    $this->assertStringContainsString('Base checkpoint created', $this->getOutput());

    // Step 3: Make a configuration change.
    $this->drush('config:set', ['system.site', 'name', 'Test Site for Workflow Integration']);

    // Step 4: Verify the change is detected.
    $this->drush('config:preview-deploy:status');
    $statusOutput = $this->getOutput();
    $this->assertStringContainsString('Changes: 1 configuration(s) modified', $statusOutput);
    $this->assertStringContainsString('- system.site', $statusOutput);

    // Step 5: Generate diff and save to file.
    $tempFile = $this->getTemporaryFile('workflow-test.patch');
    $this->drush('config:preview-deploy:diff', [], ['output' => $tempFile]);
    $diffOutput = $this->getOutput();
    $this->assertStringContainsString('Found 1 changed configuration(s)', $diffOutput);
    $this->assertStringContainsString('Diff saved to:', $diffOutput);

    // Step 6: Verify the diff file exists and has proper format.
    $this->assertFileExists($tempFile);
    $diffContent = file_get_contents($tempFile);
    $this->assertNotEmpty($diffContent, 'Diff file should not be empty');

    // Verify proper unified diff format with line numbers.
    $this->assertStringContainsString('--- a/system.site.yml', $diffContent);
    $this->assertStringContainsString('+++ b/system.site.yml', $diffContent);
    $this->assertMatchesRegularExpression('/@@ -\d+,\d+ \+\d+,\d+ @@/', $diffContent);
    $this->assertStringContainsString('Test Site for Workflow Integration', $diffContent);

    // Step 7: Revert to the exact original state that was in the checkpoint.
    $this->drush('config:set', ['system.site', 'name', $originalName]);

    // Step 8: Verify the change was reverted to original state.
    $this->drush('config:get', ['system.site', 'name']);
    $this->assertStringContainsString($originalName, $this->getOutput());

    // Step 9: Test applying the diff from file.
    // Note: In test environment, the patch may fail due to context differences,
    // but we verify the command executes properly and gives informative errors.
    $this->drush('config:preview-deploy:apply', [$tempFile], [], NULL, NULL, 2);
    $applyOutput = $this->getOutput() . $this->getErrorOutput();

    // Verify the command executed with proper messaging.
    $this->assertStringContainsString('Applying diff from workflow-test.patch', $applyOutput);
    $this->assertStringContainsString('Created checkpoint:', $applyOutput);

    // The patch may fail in test environment due to context differences,
    // but if it fails, we should get a clear error message, not a crash.
    $this->assertTrue(
      str_contains($applyOutput, 'Configuration diff applied successfully') ||
      str_contains($applyOutput, 'Patch application failed'),
      'Command should either succeed or fail with clear error message'
    );

    // Step 10: Clean up the temporary file.
    unlink($tempFile);
  }

  /**
   * Tests workflow with custom environment label.
   */
  public function testWorkflowWithEnvironmentLabel(): void {
    // Step 1: Initialize and make changes.
    $this->drush('config:preview-deploy:init');
    $this->drush('config:set', ['system.site', 'slogan', 'Environment Test Slogan']);

    // Step 2: Generate diff.
    $tempFile = $this->getTemporaryFile('env-test.patch');
    $this->drush('config:preview-deploy:diff', [], ['output' => $tempFile]);

    // Step 3: Revert change.
    $this->drush('config:set', ['system.site', 'slogan', 'NULL']);

    // Step 4: Apply with custom environment (may fail due to context, but
    // test messaging).
    $this->drush('config:preview-deploy:apply', [$tempFile], ['environment' => 'staging'], NULL, NULL, 2);
    $applyOutput = $this->getOutput() . $this->getErrorOutput();

    // Verify environment label is used instead of filename.
    $this->assertStringContainsString('Applying diff from staging', $applyOutput);
    // Note: The checkpoint label with environment might not appear in
    // visible output.
    // Command should execute properly even if patch fails.
    $this->assertTrue(
      str_contains($applyOutput, 'Configuration diff applied successfully') ||
      str_contains($applyOutput, 'Patch application failed'),
      'Command should either succeed or fail with clear error message'
    );

    // Clean up.
    unlink($tempFile);
  }

  /**
   * Tests workflow with multiple configuration changes.
   */
  public function testMultipleConfigurationsWorkflow(): void {
    // Step 1: Initialize.
    $this->drush('config:preview-deploy:init');

    // Step 2: Make multiple changes.
    $this->drush('config:set', ['system.site', 'name', 'Multi-Config Test Site']);
    $this->drush('config:set', ['system.site', 'slogan', 'Testing multiple configs']);
    $this->drush('config:set', ['system.maintenance', 'message', 'Multi-config maintenance message']);

    // Step 3: Verify multiple changes detected.
    $this->drush('config:preview-deploy:status');
    $statusOutput = $this->getOutput();
    $this->assertStringContainsString('Changes:', $statusOutput);
    $this->assertStringContainsString('- system.site', $statusOutput);
    $this->assertStringContainsString('- system.maintenance', $statusOutput);

    // Step 4: Generate diff.
    $tempFile = $this->getTemporaryFile('multi-config.patch');
    $this->drush('config:preview-deploy:diff', [], ['output' => $tempFile]);
    $diffOutput = $this->getOutput();
    $this->assertStringContainsString('Found', $diffOutput);
    $this->assertStringContainsString('changed configuration(s)', $diffOutput);

    // Step 5: Verify diff contains all changes.
    $diffContent = file_get_contents($tempFile);
    $this->assertStringContainsString('--- a/system.site.yml', $diffContent);
    $this->assertStringContainsString('--- a/system.maintenance.yml', $diffContent);
    $this->assertStringContainsString('Multi-Config Test Site', $diffContent);
    $this->assertStringContainsString('Testing multiple configs', $diffContent);
    $this->assertStringContainsString('Multi-config maintenance message', $diffContent);

    // Step 6: Revert all changes.
    $this->drush('config:set', ['system.site', 'name', 'Original Site Name']);
    $this->drush('config:set', ['system.site', 'slogan', 'NULL']);
    $this->drush('config:set', ['system.maintenance', 'message', 'Original maintenance message']);

    // Step 7: Test applying the multi-config diff (may fail due to context
    // differences).
    $this->drush('config:preview-deploy:apply', [$tempFile], [], NULL, NULL, 2);
    $applyOutput = $this->getOutput() . $this->getErrorOutput();

    // Verify the command executed with proper file handling.
    $this->assertStringContainsString('Applying diff from multi-config.patch', $applyOutput);
    $this->assertStringContainsString('Created checkpoint:', $applyOutput);

    // Command should execute properly even if patch fails.
    $this->assertTrue(
      str_contains($applyOutput, 'Configuration diff applied successfully') ||
      str_contains($applyOutput, 'Patch application failed'),
      'Command should either succeed or fail with clear error message'
    );

    // Clean up.
    unlink($tempFile);
  }

  /**
   * Tests error handling in workflow.
   */
  public function testWorkflowErrorHandling(): void {
    // Test 1: Apply non-existent file.
    $this->drush('config:preview-deploy:apply', ['/nonexistent/file.patch'], [], NULL, NULL, 2);
    $this->assertStringContainsString('Diff file not found', $this->getOutput());

    // Test 2: Apply invalid diff content.
    $invalidFile = $this->getTemporaryFile('invalid.patch');
    file_put_contents($invalidFile, "This is not a valid diff\nInvalid content");

    $this->drush('config:preview-deploy:apply', [$invalidFile], [], NULL, NULL, 2);
    $errorOutput = $this->getOutput() . $this->getErrorOutput();
    $this->assertStringContainsString('Applying diff from invalid.patch', $errorOutput);
    $this->assertStringContainsString('Patch application failed', $errorOutput);

    // Clean up.
    unlink($invalidFile);
  }

  /**
   * Tests consistency between status and diff commands.
   */
  public function testStatusDiffConsistency(): void {
    // Step 1: Initialize.
    $this->drush('config:preview-deploy:init');

    // Step 2: No changes - both should be consistent.
    $this->drush('config:preview-deploy:status');
    $this->assertStringContainsString('Changes: None', $this->getOutput());

    $this->drush('config:preview-deploy:diff');
    $this->assertStringContainsString('No configuration changes detected', $this->getOutput());

    // Step 3: Make changes.
    $this->drush('config:set', ['system.site', 'name', 'Consistency Test Site']);

    // Step 4: Both should detect the same change.
    $this->drush('config:preview-deploy:status');
    $statusOutput = $this->getOutput();
    $this->assertStringContainsString('Changes: 1 configuration(s) modified', $statusOutput);
    $this->assertStringContainsString('- system.site', $statusOutput);

    $this->drush('config:preview-deploy:diff');
    $diffOutput = $this->getOutput();
    $this->assertStringContainsString('Found 1 changed configuration(s)', $diffOutput);
    $this->assertStringContainsString('- system.site', $diffOutput);
    $this->assertStringContainsString('Consistency Test Site', $diffOutput);
  }

  /**
   * Gets a temporary file path.
   */
  protected function getTemporaryFile(string $filename): string {
    $tempDir = sys_get_temp_dir();
    return $tempDir . '/' . $filename;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc