function ConfigImportUITest::testImport

Same name in other branches
  1. 9 core/modules/config/tests/src/Functional/ConfigImportUITest.php \Drupal\Tests\config\Functional\ConfigImportUITest::testImport()
  2. 8.9.x core/modules/config/tests/src/Functional/ConfigImportUITest.php \Drupal\Tests\config\Functional\ConfigImportUITest::testImport()
  3. 11.x core/modules/config/tests/src/Functional/ConfigImportUITest.php \Drupal\Tests\config\Functional\ConfigImportUITest::testImport()

Tests importing configuration.

File

core/modules/config/tests/src/Functional/ConfigImportUITest.php, line 56

Class

ConfigImportUITest
Tests the user interface for importing configuration.

Namespace

Drupal\Tests\config\Functional

Code

public function testImport() : void {
    $name = 'system.site';
    $dynamic_name = 'config_test.dynamic.new';
    
    /** @var \Drupal\Core\Config\StorageInterface $sync */
    $sync = $this->container
        ->get('config.storage.sync');
    $this->drupalGet('admin/config/development/configuration');
    $this->assertSession()
        ->pageTextContains('The staged configuration is identical to the active configuration.');
    $this->assertSession()
        ->buttonNotExists('Import all');
    // Create updated configuration object.
    $new_site_name = 'Config import test ' . $this->randomString();
    $this->prepareSiteNameUpdate($new_site_name);
    $this->assertTrue($sync->exists($name), $name . ' found.');
    // Create new config entity.
    $original_dynamic_data = [
        'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651',
        'langcode' => \Drupal::languageManager()->getDefaultLanguage()
            ->getId(),
        'status' => TRUE,
        'dependencies' => [],
        'id' => 'new',
        'label' => 'New',
        'weight' => 0,
        'style' => '',
        'size' => '',
        'size_value' => '',
        'protected_property' => '',
    ];
    $sync->write($dynamic_name, $original_dynamic_data);
    $this->assertTrue($sync->exists($dynamic_name), $dynamic_name . ' found.');
    // Enable the Automated Cron and Ban modules during import. The Ban
    // module is used because it creates a table during the install.
    // The Automated Cron module is used because it creates a single simple
    // configuration file during the install.
    $core_extension = $this->config('core.extension')
        ->get();
    $core_extension['module']['automated_cron'] = 0;
    $core_extension['module']['ban'] = 0;
    $core_extension['module'] = module_config_sort($core_extension['module']);
    $core_extension['theme']['olivero'] = 0;
    $sync->write('core.extension', $core_extension);
    // Olivero ships with configuration.
    $sync->write('olivero.settings', Yaml::decode(file_get_contents('core/themes/olivero/config/install/olivero.settings.yml')));
    // Use the install storage so that we can read configuration from modules
    // and themes that are not installed.
    $install_storage = new InstallStorage();
    // Set the Olivero theme as default.
    $system_theme = $this->config('system.theme')
        ->get();
    $system_theme['default'] = 'olivero';
    $sync->write('system.theme', $system_theme);
    // Read the automated_cron config from module default config folder.
    $settings = $install_storage->read('automated_cron.settings');
    $settings['interval'] = 10000;
    $sync->write('automated_cron.settings', $settings);
    // Uninstall the Options and Text modules to ensure that dependencies are
    // handled correctly. Options depends on Text so Text should be installed
    // first. Since they were enabled during the test setup the core.extension
    // file in sync will already contain them.
    \Drupal::service('module_installer')->uninstall([
        'text',
        'options',
    ]);
    // Set the state system to record installations and uninstallations.
    \Drupal::state()->set('ConfigImportUITest.core.extension.modules_installed', []);
    \Drupal::state()->set('ConfigImportUITest.core.extension.modules_uninstalled', []);
    // Verify that both appear as ready to import.
    $this->drupalGet('admin/config/development/configuration');
    $this->assertSession()
        ->responseContains('<td>' . $name);
    $this->assertSession()
        ->responseContains('<td>' . $dynamic_name);
    $this->assertSession()
        ->responseContains('<td>core.extension');
    $this->assertSession()
        ->responseContains('<td>system.theme');
    $this->assertSession()
        ->responseContains('<td>automated_cron.settings');
    $this->assertSession()
        ->buttonExists('Import all');
    // Import and verify that both do not appear anymore.
    $this->submitForm([], 'Import all');
    $this->assertSession()
        ->responseNotContains('<td>' . $name);
    $this->assertSession()
        ->responseNotContains('<td>' . $dynamic_name);
    $this->assertSession()
        ->responseNotContains('<td>core.extension');
    $this->assertSession()
        ->responseNotContains('<td>system.theme');
    $this->assertSession()
        ->responseNotContains('<td>automated_cron.settings');
    $this->assertSession()
        ->buttonNotExists('Import all');
    // Verify that there are no further changes to import.
    $this->assertSession()
        ->pageTextContains('The staged configuration is identical to the active configuration.');
    $this->rebuildContainer();
    // Verify site name has changed.
    $this->assertSame($new_site_name, $this->config('system.site')
        ->get('name'));
    // Verify that new config entity exists.
    $this->assertSame($original_dynamic_data, $this->config($dynamic_name)
        ->get());
    // Verify the cache got cleared.
    $this->assertTrue(isset($GLOBALS['hook_cache_flush']));
    $this->rebuildContainer();
    $this->assertTrue(\Drupal::moduleHandler()->moduleExists('ban'), 'Ban module installed during import.');
    $this->assertTrue(\Drupal::database()->schema()
        ->tableExists('ban_ip'), 'The database table ban_ip exists.');
    $this->assertTrue(\Drupal::moduleHandler()->moduleExists('automated_cron'), 'Automated Cron module installed during import.');
    $this->assertTrue(\Drupal::moduleHandler()->moduleExists('options'), 'Options module installed during import.');
    $this->assertTrue(\Drupal::moduleHandler()->moduleExists('text'), 'Text module installed during import.');
    $this->assertTrue(\Drupal::service('theme_handler')->themeExists('olivero'), 'Olivero theme installed during import.');
    // Ensure installations and uninstallation occur as expected.
    $installed = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_installed', []);
    $uninstalled = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_uninstalled', []);
    $expected = [
        'automated_cron',
        'ban',
        'text',
        'options',
    ];
    $this->assertSame($expected, $installed, 'Automated Cron, Ban, Text and Options modules installed in the correct order.');
    $this->assertEmpty($uninstalled, 'No modules uninstalled during import');
    // Verify that the automated_cron configuration object was only written
    // once during the import process and only with the value set in the staged
    // configuration. This verifies that the module's default configuration is
    // used during configuration import and, additionally, that after installing
    // a module, that configuration is not synced twice.
    $interval_values = \Drupal::state()->get('ConfigImportUITest.automated_cron.settings.interval', []);
    $this->assertSame([
        10000,
    ], $interval_values);
    $core_extension = $this->config('core.extension')
        ->get();
    unset($core_extension['module']['automated_cron']);
    unset($core_extension['module']['ban']);
    unset($core_extension['module']['options']);
    unset($core_extension['module']['text']);
    unset($core_extension['theme']['olivero']);
    $sync->write('core.extension', $core_extension);
    $sync->delete('automated_cron.settings');
    $sync->delete('text.settings');
    $sync->delete('olivero.settings');
    $system_theme = $this->config('system.theme')
        ->get();
    $system_theme = [
        '_core' => $system_theme['_core'],
        'admin' => 'stark',
        'default' => 'stark',
    ];
    $sync->write('system.theme', $system_theme);
    // Set the state system to record installations and uninstallations.
    \Drupal::state()->set('ConfigImportUITest.core.extension.modules_installed', []);
    \Drupal::state()->set('ConfigImportUITest.core.extension.modules_uninstalled', []);
    // Verify that both appear as ready to import.
    $this->drupalGet('admin/config/development/configuration');
    $this->assertSession()
        ->responseContains('<td>core.extension');
    $this->assertSession()
        ->responseContains('<td>system.theme');
    $this->assertSession()
        ->responseContains('<td>automated_cron.settings');
    // Import and verify that both do not appear anymore.
    $this->submitForm([], 'Import all');
    $this->assertSession()
        ->responseNotContains('<td>core.extension');
    $this->assertSession()
        ->responseNotContains('<td>system.theme');
    $this->assertSession()
        ->responseNotContains('<td>automated_cron.settings');
    $this->rebuildContainer();
    $this->assertFalse(\Drupal::moduleHandler()->moduleExists('ban'), 'Ban module uninstalled during import.');
    $this->assertFalse(\Drupal::database()->schema()
        ->tableExists('ban_ip'), 'The database table ban_ip does not exist.');
    $this->assertFalse(\Drupal::moduleHandler()->moduleExists('automated_cron'), 'Automated cron module uninstalled during import.');
    $this->assertFalse(\Drupal::moduleHandler()->moduleExists('options'), 'Options module uninstalled during import.');
    $this->assertFalse(\Drupal::moduleHandler()->moduleExists('text'), 'Text module uninstalled during import.');
    // Ensure installations and uninstallation occur as expected.
    $installed = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_installed', []);
    $uninstalled = \Drupal::state()->get('ConfigImportUITest.core.extension.modules_uninstalled', []);
    $expected = [
        'options',
        'text',
        'ban',
        'automated_cron',
    ];
    $this->assertSame($expected, $uninstalled, 'Options, Text, Ban and Automated Cron modules uninstalled in the correct order.');
    $this->assertEmpty($installed, 'No modules installed during import');
    $theme_info = \Drupal::service('theme_handler')->listInfo();
    $this->assertFalse(isset($theme_info['olivero']), 'Olivero theme uninstalled during import.');
    // Verify that the automated_cron.settings configuration object was only
    // deleted once during the import process.
    $delete_called = \Drupal::state()->get('ConfigImportUITest.automated_cron.settings.delete', 0);
    $this->assertSame(1, $delete_called, "The automated_cron.settings configuration was deleted once during configuration import.");
}

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