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. 10 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 552

Class

ConfigImporterTest
Tests importing configuration from files into active configuration.

Namespace

Drupal\KernelTests\Core\Config

Code

public function testUnmetDependency() {
    $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']['book'] = 0;
    $extensions['theme']['bartik'] = 0;
    $sync->write('core.extension', $extensions);
    try {
        $this->configImporter
            ->reset()
            ->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">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User</em> modules.',
            'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Classy</em> theme.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Stable</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 = $this->configImporter
            ->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">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User</em> modules.',
            'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Classy</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.',
        ];
        foreach ($expected as $expected_message) {
            $this->assertContains($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',
            'seven',
        ],
    ];
    $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);
    try {
        $this->configImporter
            ->reset()
            ->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">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User</em> modules.',
            'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Classy</em> theme.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Stable</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.',
            'Unable to install the <em class="placeholder">unknown_module</em> module since it does not exist.',
            'Unable to install the <em class="placeholder">Book</em> module since it requires the <em class="placeholder">Node, Text, Field, Filter, User</em> modules.',
            'Unable to install the <em class="placeholder">unknown_theme</em> theme since it does not exist.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Classy</em> theme.',
            'Unable to install the <em class="placeholder">Bartik</em> theme since it requires the <em class="placeholder">Stable</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, Seven</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 = $this->configImporter
            ->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, Seven</em>) that will not be installed after import.',
        ];
        foreach ($expected as $expected_message) {
            $this->assertContains($expected_message, $error_log, $expected_message);
        }
    }
}

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