function ConfigImporterTest::testUnmetDependency

Same name and namespace in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php \Drupal\KernelTests\Core\Config\ConfigImporterTest::testUnmetDependency()
  2. 8.9.x core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php \Drupal\KernelTests\Core\Config\ConfigImporterTest::testUnmetDependency()
  3. 11.x core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php \Drupal\KernelTests\Core\Config\ConfigImporterTest::testUnmetDependency()

Tests dependency validation during configuration import.

See also

\Drupal\Core\EventSubscriber\ConfigImportSubscriber

\Drupal\Core\Config\ConfigImporter::createExtensionChangelist()

File

core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php, line 539

Class

ConfigImporterTest
Tests importing configuration from files into active configuration.

Namespace

Drupal\KernelTests\Core\Config

Code

public function testUnmetDependency() : void {
  $storage = $this->container
    ->get('config.storage');
  $sync = $this->container
    ->get('config.storage.sync');
  // Test an unknown configuration owner.
  $sync->write('unknown.config', [
    'test' => 'test',
  ]);
  // Make a config entity have unmet dependencies.
  $config_entity_data = $sync->read('config_test.dynamic.dotted.default');
  $config_entity_data['dependencies'] = [
    'module' => [
      'unknown',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.module', $config_entity_data);
  $config_entity_data['dependencies'] = [
    'theme' => [
      'unknown',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.theme', $config_entity_data);
  $config_entity_data['dependencies'] = [
    'config' => [
      'unknown',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.config', $config_entity_data);
  // Make an active config depend on something that is missing in sync.
  // The whole configuration needs to be consistent, not only the updated one.
  $config_entity_data['dependencies'] = [];
  $storage->write('config_test.dynamic.dotted.deleted', $config_entity_data);
  $config_entity_data['dependencies'] = [
    'config' => [
      'config_test.dynamic.dotted.deleted',
    ],
  ];
  $storage->write('config_test.dynamic.dotted.existing', $config_entity_data);
  $sync->write('config_test.dynamic.dotted.existing', $config_entity_data);
  $extensions = $sync->read('core.extension');
  // Add a module and a theme that do not exist.
  $extensions['module']['unknown_module'] = 0;
  $extensions['theme']['unknown_theme'] = 0;
  // Add a module and a theme that depend on uninstalled extensions.
  $extensions['module']['new_dependency_test'] = 0;
  $extensions['theme']['test_subtheme'] = 0;
  $sync->write('core.extension', $extensions);
  $config_importer = $this->configImporter();
  try {
    $config_importer->import();
    $this->fail('ConfigImporterException not thrown; an invalid import was not stopped due to missing dependencies.');
  } catch (ConfigImporterException $e) {
    $expected = [
      static::FAIL_MESSAGE,
      'Unable to install the <em class="placeholder">unknown_module</em> module since it does not exist.',
      'Unable to install the <em class="placeholder">New Dependency test</em> module since it requires the <em class="placeholder">New Dependency test with service</em> module.',
      'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
      'Unable to install the <em class="placeholder">Theme test subtheme</em> theme since it requires the <em class="placeholder">Theme test base theme</em> theme.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.config</em> depends on the <em class="placeholder">unknown</em> configuration that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.existing</em> depends on the <em class="placeholder">config_test.dynamic.dotted.deleted</em> configuration that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.module</em> depends on the <em class="placeholder">unknown</em> module that will not be installed after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.theme</em> depends on the <em class="placeholder">unknown</em> theme that will not be installed after import.',
      'Configuration <em class="placeholder">unknown.config</em> depends on the <em class="placeholder">unknown</em> extension that will not be installed after import.',
    ];
    $this->assertEquals(implode(PHP_EOL, $expected), $e->getMessage());
    $error_log = $config_importer->getErrors();
    $expected = [
      'Unable to install the <em class="placeholder">unknown_module</em> module since it does not exist.',
      'Unable to install the <em class="placeholder">New Dependency test</em> module since it requires the <em class="placeholder">New Dependency test with service</em> module.',
      'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.config</em> depends on the <em class="placeholder">unknown</em> configuration that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.existing</em> depends on the <em class="placeholder">config_test.dynamic.dotted.deleted</em> configuration that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.module</em> depends on the <em class="placeholder">unknown</em> module that will not be installed after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.theme</em> depends on the <em class="placeholder">unknown</em> theme that will not be installed after import.',
      'Configuration <em class="placeholder">unknown.config</em> depends on the <em class="placeholder">unknown</em> extension that will not be installed after import.',
    ];
    foreach ($expected as $expected_message) {
      $this->assertContainsEquals($expected_message, $error_log, $expected_message);
    }
  }
  // Make a config entity have multiple unmet dependencies.
  $config_entity_data = $sync->read('config_test.dynamic.dotted.default');
  $config_entity_data['dependencies'] = [
    'module' => [
      'unknown',
      'dblog',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.module', $config_entity_data);
  $config_entity_data['dependencies'] = [
    'theme' => [
      'unknown',
      'stark',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.theme', $config_entity_data);
  $config_entity_data['dependencies'] = [
    'config' => [
      'unknown',
      'unknown2',
    ],
  ];
  $sync->write('config_test.dynamic.dotted.config', $config_entity_data);
  $config_importer = $this->configImporter();
  try {
    $this->configImporter
      ->import();
    $this->fail('ConfigImporterException not thrown, invalid import was not stopped due to missing dependencies.');
  } catch (ConfigImporterException $e) {
    $expected = [
      static::FAIL_MESSAGE,
      'Unable to install the <em class="placeholder">unknown_module</em> module since it does not exist.',
      'Unable to install the <em class="placeholder">New Dependency test</em> module since it requires the <em class="placeholder">New Dependency test with service</em> module.',
      'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
      'Unable to install the <em class="placeholder">Theme test subtheme</em> theme since it requires the <em class="placeholder">Theme test base theme</em> theme.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.config</em> depends on configuration (<em class="placeholder">unknown, unknown2</em>) that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.existing</em> depends on the <em class="placeholder">config_test.dynamic.dotted.deleted</em> configuration that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.module</em> depends on modules (<em class="placeholder">unknown, Database Logging</em>) that will not be installed after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.theme</em> depends on themes (<em class="placeholder">unknown, Stark</em>) that will not be installed after import.',
      'Configuration <em class="placeholder">unknown.config</em> depends on the <em class="placeholder">unknown</em> extension that will not be installed after import.',
    ];
    $this->assertEquals(implode(PHP_EOL, $expected), $e->getMessage());
    $error_log = $config_importer->getErrors();
    $expected = [
      'Configuration <em class="placeholder">config_test.dynamic.dotted.config</em> depends on configuration (<em class="placeholder">unknown, unknown2</em>) that will not exist after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.module</em> depends on modules (<em class="placeholder">unknown, Database Logging</em>) that will not be installed after import.',
      'Configuration <em class="placeholder">config_test.dynamic.dotted.theme</em> depends on themes (<em class="placeholder">unknown, Stark</em>) that will not be installed after import.',
    ];
    foreach ($expected as $expected_message) {
      $this->assertContainsEquals($expected_message, $error_log, $expected_message);
    }
  }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.