config_preview_deploy-1.0.0-alpha3/tests/src/Kernel/PreviewControllerTest.php

tests/src/Kernel/PreviewControllerTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\config_preview_deploy\Kernel;

use Drupal\config_preview_deploy\ConfigDiff;
use Drupal\config_preview_deploy\Controller\PreviewController;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;

/**
 * Tests the PreviewController.
 *
 * @group config_preview_deploy
 */
class PreviewControllerTest extends KernelTestBase {

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

  /**
   * {@inheritdoc}
   *
   * We disable strict config schema checking because config_ignore module's
   * schema seems incomplete.
   */
  protected $strictConfigSchema = FALSE;

  /**
   * The config diff service.
   */
  protected ConfigDiff $configDiff;

  /**
   * The preview controller.
   */
  protected PreviewController $controller;

  /**
   * Test user.
   */
  protected User $testUser;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->installConfig(['system', 'user']);
    $this->installEntitySchema('user');

    // Create a test user with appropriate permissions.
    $role = Role::create([
      'id' => 'test_role',
      'label' => 'Test Role',
    ]);
    $role->grantPermission('deploy config from preview');
    $role->save();

    $this->testUser = User::create([
      'name' => 'testuser',
      'mail' => 'test@example.com',
      'roles' => ['test_role'],
    ]);
    $this->testUser->save();

    // Set up services.
    $this->configDiff = $this->container->get('config_preview_deploy.config_diff');
    $this->controller = PreviewController::create($this->container);
  }

  /**
   * Tests the changes() method with various scenarios.
   */
  public function testChangesViewScenarios(): void {
    // Test 1: Changes view when no base checkpoint exists.
    $build = $this->controller->changes();
    $this->assertArrayHasKey('#title', $build);
    $this->assertEquals('Configuration Changes', $build['#title']->render());
    $this->assertArrayHasKey('no_changes', $build);
    $this->assertStringContainsString('No base checkpoint found', $build['no_changes']['#markup']);

    // Test 2: Changes view when no changes exist (but base checkpoint exists).
    $this->configDiff->createBaseCheckpoint();
    $build = $this->controller->changes();
    $this->assertArrayHasKey('#title', $build);
    $this->assertEquals('Configuration Changes', $build['#title']->render());
    $this->assertArrayHasKey('no_changes', $build);
    $this->assertStringContainsString('No configuration changes detected', $build['no_changes']['#markup']);

    // Test 3: Changes view when changes exist.
    $this->config('system.site')
      ->set('name', 'Modified Site Name')
      ->save();

    $build = $this->controller->changes();
    $this->assertArrayHasKey('#title', $build);
    $this->assertEquals('Configuration Changes', $build['#title']->render());
    $this->assertArrayHasKey('changes_table', $build);
    $this->assertArrayHasKey('#attached', $build);
    $this->assertContains('core/drupal.dialog.ajax', $build['#attached']['library']);
    $this->assertArrayHasKey('download', $build, 'Download button should be present');
  }

  /**
   * Tests the diff() method with various scenarios.
   */
  public function testDiffViewScenarios(): void {
    // Test 1: Diff view with no base checkpoint.
    $build = $this->controller->diff('system.site');
    $this->assertArrayHasKey('#markup', $build);
    $this->assertStringContainsString('No base checkpoint found', $build['#markup']);

    // Test 2: Diff view with changes.
    $this->configDiff->createBaseCheckpoint();
    $this->config('system.site')
      ->set('name', 'Modified Site Name')
      ->save();

    $build = $this->controller->diff('system.site');
    $this->assertArrayHasKey('#title', $build);
    $this->assertStringContainsString('system.site', $build['#title']->render());
    $this->assertArrayHasKey('diff', $build);
    $this->assertArrayHasKey('#attached', $build);
    $this->assertContains('system/diff', $build['#attached']['library']);
    $this->assertArrayHasKey('back', $build);
  }

  /**
   * Tests access control scenarios for changes route.
   */
  public function testAccessControlScenarios(): void {
    $access = $this->container->get('config_preview_deploy.preview_environment_access');

    // Test 1: Access control allowed in preview environment.
    $this->container->get('current_user')->setAccount($this->testUser);
    $result = $access->changesAccess($this->testUser);
    $this->assertTrue($result->isAllowed(), 'Changes access should be allowed in preview environment');

    // Test 2: Access forbidden on production.
    putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION=1');
    $result = $access->changesAccess($this->testUser);
    $this->assertTrue($result->isForbidden(), 'Changes access should be forbidden in production environment');

    // Clean up.
    putenv('DRUPAL_CONFIG_PREVIEW_DEPLOY_IS_PRODUCTION');
  }

  /**
   * Tests dashboard functionality and change count display.
   */
  public function testDashboardFunctionality(): void {
    // Create a base checkpoint first.
    $this->configDiff->createBaseCheckpoint();

    // Modify some configuration.
    $this->config('system.site')
      ->set('name', 'Modified Site Name')
      ->save();

    $build = $this->controller->dashboard();

    $this->assertArrayHasKey('environment_info', $build);
    $this->assertArrayHasKey('actions', $build);

    // Check that environment info contains change count.
    $envItems = $build['environment_info']['details']['#items'];
    $hasChangeCount = FALSE;
    foreach ($envItems as $item) {
      if (strpos($item->render(), 'Pending changes:') !== FALSE) {
        $hasChangeCount = TRUE;
        break;
      }
    }
    $this->assertTrue($hasChangeCount, 'Environment info should contain pending changes count');
  }

  /**
   * Tests download diff functionality.
   */
  public function testDownloadDiff(): void {
    // Create a base checkpoint and make changes.
    $this->configDiff->createBaseCheckpoint();
    $this->config('system.site')
      ->set('name', 'Modified Site Name')
      ->save();

    // Test that download functionality is available.
    $response = $this->controller->downloadDiff();
    $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
    $this->assertEquals(200, $response->getStatusCode());
    $this->assertStringContainsString('text/plain', $response->headers->get('Content-Type'));
  }

  /**
   * Tests dashboard with config_ignore filtering.
   */
  public function testDashboardWithConfigIgnoreFiltering(): void {
    // Check if config_ignore module exists.
    $module_list = \Drupal::service('extension.list.module');
    if (!$module_list->exists('config_ignore')) {
      $this->markTestSkipped('Config ignore module not available in codebase');
    }

    // Create base checkpoint BEFORE enabling config_ignore.
    $this->configDiff->createBaseCheckpoint();

    // Enable config_ignore module.
    $this->enableModules(['config_ignore']);
    $this->installConfig(['config_ignore']);

    // Configure config_ignore to ignore system.site.
    $this->config('config_ignore.settings')
      ->set('ignored_config_entities', ['system.site'])
      ->save();

    // Clear caches to ensure services are updated.
    drupal_flush_all_caches();

    // Re-fetch services after enabling module.
    $this->configDiff = $this->container->get('config_preview_deploy.config_diff');
    $this->controller = PreviewController::create($this->container);

    // Make configuration changes.
    $this->config('system.site')
      ->set('name', 'Ignored Site Name')
      ->save();

    $this->config('system.performance')
      ->set('cache.page.max_age', 3600)
      ->save();

    $build = $this->controller->dashboard();

    // Check that environment info contains correct change count.
    // Should only count system.performance (not system.site which is ignored).
    $envItems = $build['environment_info']['details']['#items'];
    $hasCorrectCount = FALSE;
    foreach ($envItems as $item) {
      $rendered = $item->render();
      if (strpos($rendered, 'Pending changes:') !== FALSE) {
        // Should show 2 configurations (system.performance and
        // config_ignore.settings).
        $this->assertStringContainsString('2 configurations', $rendered);
        $hasCorrectCount = TRUE;
        break;
      }
    }
    $this->assertTrue($hasCorrectCount, 'Dashboard should show filtered change count');
  }

  /**
   * Tests changes view with config_ignore filtering.
   */
  public function testChangesViewWithConfigIgnoreFiltering(): void {
    // Check if config_ignore module exists.
    $module_list = \Drupal::service('extension.list.module');
    if (!$module_list->exists('config_ignore')) {
      $this->markTestSkipped('Config ignore module not available in codebase');
    }

    // Create base checkpoint BEFORE enabling config_ignore.
    $this->configDiff->createBaseCheckpoint();

    // Enable config_ignore module.
    $this->enableModules(['config_ignore']);
    $this->installConfig(['config_ignore']);

    // Configure config_ignore to ignore system.site.
    $this->config('config_ignore.settings')
      ->set('ignored_config_entities', ['system.site'])
      ->save();

    // Clear caches.
    drupal_flush_all_caches();

    // Re-fetch services.
    $this->configDiff = $this->container->get('config_preview_deploy.config_diff');
    $this->controller = PreviewController::create($this->container);

    // Make configuration changes.
    $this->config('system.site')
      ->set('name', 'Ignored Site Name')
      ->save();

    $this->config('system.performance')
      ->set('cache.page.max_age', 3600)
      ->save();

    $build = $this->controller->changes();

    // Check that changes table exists.
    $this->assertArrayHasKey('changes_table', $build);

    // The changes table should not include system.site (which is ignored).
    $rows = $build['changes_table']['#rows'];
    $foundSystemSite = FALSE;
    $foundSystemPerformance = FALSE;
    $foundConfigIgnore = FALSE;

    foreach ($rows as $row) {
      // Extract config name from the row data structure.
      $configName = $row['data'][0];
      if ($configName === 'system.site') {
        $foundSystemSite = TRUE;
      }
      if ($configName === 'system.performance') {
        $foundSystemPerformance = TRUE;
      }
      if ($configName === 'config_ignore.settings') {
        $foundConfigIgnore = TRUE;
      }
    }

    $this->assertFalse($foundSystemSite, 'Ignored config system.site should not appear in changes');
    $this->assertTrue($foundSystemPerformance, 'Non-ignored config system.performance should appear in changes');
    $this->assertTrue($foundConfigIgnore, 'Config ignore settings should appear in changes');
  }

  /**
   * Tests diff download with config_ignore filtering.
   */
  public function testDownloadDiffWithConfigIgnoreFiltering(): void {
    // Check if config_ignore module exists.
    $module_list = \Drupal::service('extension.list.module');
    if (!$module_list->exists('config_ignore')) {
      $this->markTestSkipped('Config ignore module not available in codebase');
    }

    // Create base checkpoint BEFORE enabling config_ignore.
    $this->configDiff->createBaseCheckpoint();

    // Enable config_ignore module.
    $this->enableModules(['config_ignore']);
    $this->installConfig(['config_ignore']);

    // Configure config_ignore to ignore system.site:name but not slogan.
    $this->config('config_ignore.settings')
      ->set('ignored_config_entities', ['system.site:name'])
      ->save();

    // Clear caches.
    drupal_flush_all_caches();

    // Re-fetch services.
    $this->configDiff = $this->container->get('config_preview_deploy.config_diff');
    $this->controller = PreviewController::create($this->container);

    // Make configuration changes.
    $this->config('system.site')
      ->set('name', 'Ignored Site Name')
      ->set('slogan', 'Not Ignored Slogan')
      ->save();

    // Download diff.
    $response = $this->controller->downloadDiff();
    $content = $response->getContent();

    // Should NOT contain ignored change.
    $this->assertStringNotContainsString('Ignored Site Name', $content);

    // Should contain non-ignored change.
    $this->assertStringContainsString('Not Ignored Slogan', $content);
  }

}

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

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