Update to Drupal 8.1.0. For more information, see https://www.drupal.org/drupal-8.1.0-release-notes

This commit is contained in:
Pantheon Automation 2016-04-20 09:56:34 -07:00 committed by Greg Anderson
parent b11a755ba8
commit c0a0d5a94c
6920 changed files with 64395 additions and 57312 deletions

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\ConfigSubscriber.
*/
namespace Drupal\config;
use Drupal\Core\Config\ConfigEvents;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Controller\ConfigController.
*/
namespace Drupal\config\Controller;
use Drupal\Core\Archiver\ArchiveTar;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigExportForm.
*/
namespace Drupal\config\Form;
use Drupal\Core\Form\FormBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigImportForm.
*/
namespace Drupal\config\Form;
use Drupal\Core\Archiver\ArchiveTar;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigSingleExportForm.
*/
namespace Drupal\config\Form;
use Drupal\Component\Serialization\Yaml;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigSingleImportForm.
*/
namespace Drupal\config\Form;
use Drupal\Component\Serialization\Yaml;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigSync.
*/
namespace Drupal\config\Form;
use Drupal\Core\Config\ConfigImporterException;
@ -186,7 +181,7 @@ class ConfigSync extends FormBase {
if (empty($source_list) || !$storage_comparer->createChangelist()->hasChanges()) {
$form['no_changes'] = array(
'#type' => 'table',
'#header' => array('Name', 'Operations'),
'#header' => array($this->t('Name'), $this->t('Operations')),
'#rows' => array(),
'#empty' => $this->t('There are no configuration changes to import.'),
);
@ -232,7 +227,7 @@ class ConfigSync extends FormBase {
$form_state->set('storage_comparer', $storage_comparer);
// Add the AJAX library to the form for dialog support.
$form['#attached']['library'][] = 'core/drupal.ajax';
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
foreach ($storage_comparer->getAllCollectionNames() as $collection) {
if ($collection != StorageInterface::DEFAULT_COLLECTION) {
@ -272,7 +267,7 @@ class ConfigSync extends FormBase {
}
$form[$collection][$config_change_type]['list'] = array(
'#type' => 'table',
'#header' => array('Name', 'Operations'),
'#header' => array($this->t('Name'), $this->t('Operations')),
);
foreach ($config_names as $config_name) {
@ -343,9 +338,9 @@ class ConfigSync extends FormBase {
'finished' => array(get_class($this), 'finishBatch'),
'title' => t('Synchronizing configuration'),
'init_message' => t('Starting configuration synchronization.'),
'progress_message' => t('Completed @current step of @total.'),
'progress_message' => t('Completed step @current of @total.'),
'error_message' => t('Configuration synchronization has encountered an error.'),
'file' => drupal_get_path('module', 'config') . '/config.admin.inc',
'file' => __DIR__ . '/../../config.admin.inc',
);
foreach ($sync_steps as $sync_step) {
$batch['operations'][] = array(array(get_class($this), 'processBatch'), array($config_importer, $sync_step));

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\StorageReplaceDataWrapper.
*/
namespace Drupal\config;
use Drupal\Core\Config\StorageInterface;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\AssertConfigEntityImportTrait.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
@ -13,7 +8,7 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface;
* Provides test assertions for testing config entity synchronization.
*
* Can be used by test classes that extend \Drupal\simpletest\WebTestBase or
* \Drupal\simpletest\KernelTestBase.
* \Drupal\KernelTests\KernelTestBase.
*/
trait AssertConfigEntityImportTrait {

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\CacheabilityMetadataConfigOverrideIntegrationTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,95 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\CacheabilityMetadataConfigOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\config_override_test\Cache\PirateDayCacheContext;
use Drupal\simpletest\KernelTestBase;
/**
* Tests if configuration overrides correctly affect cacheability metadata.
*
* @group config
*/
class CacheabilityMetadataConfigOverrideTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'block',
'block_content',
'config',
'config_override_test',
'system',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('block_content');
$this->installConfig(['config_override_test']);
}
/**
* Tests if config overrides correctly set cacheability metadata.
*/
public function testConfigOverride() {
// It's pirate day today!
$GLOBALS['it_is_pirate_day'] = TRUE;
$config_factory = $this->container->get('config.factory');
$config = $config_factory->get('system.theme');
// Check that we are using the Pirate theme.
$theme = $config->get('default');
$this->assertEqual('pirate', $theme);
// Check that the cacheability metadata is correct.
$this->assertEqual(['pirate_day'], $config->getCacheContexts());
$this->assertEqual(['config:system.theme', 'pirate-day-tag'], $config->getCacheTags());
$this->assertEqual(PirateDayCacheContext::PIRATE_DAY_MAX_AGE, $config->getCacheMaxAge());
}
/**
* Tests if config overrides set cacheability metadata on config entities.
*/
public function testConfigEntityOverride() {
// It's pirate day today!
$GLOBALS['it_is_pirate_day'] = TRUE;
// Load the User login block and check that its cacheability metadata is
// overridden correctly. This verifies that the metadata is correctly
// applied to config entities.
/** @var EntityManagerInterface $entity_manager */
$entity_manager = $this->container->get('entity.manager');
$block = $entity_manager->getStorage('block')->load('call_to_action');
// Check that our call to action message is appealing to filibusters.
$this->assertEqual($block->label(), 'Draw yer cutlasses!');
// Check that the cacheability metadata is correct.
$this->assertEqual(['pirate_day'], $block->getCacheContexts());
$this->assertEqual(['config:block.block.call_to_action', 'pirate-day-tag'], $block->getCacheTags());
$this->assertEqual(PirateDayCacheContext::PIRATE_DAY_MAX_AGE, $block->getCacheMaxAge());
// Check that duplicating a config entity does not have the original config
// entity's cache tag.
$this->assertEqual(['config:block.block.', 'pirate-day-tag'], $block->createDuplicate()->getCacheTags());
// Check that renaming a config entity does not have the original config
// entity's cache tag.
$block->set('id', 'call_to_looting')->save();
$this->assertEqual(['pirate_day'], $block->getCacheContexts());
$this->assertEqual(['config:block.block.call_to_looting', 'pirate-day-tag'], $block->getCacheTags());
$this->assertEqual(PirateDayCacheContext::PIRATE_DAY_MAX_AGE, $block->getCacheMaxAge());
}
}

View file

@ -1,323 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigCRUDTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\ConfigNameException;
use Drupal\Core\Config\ConfigValueException;
use Drupal\Core\Config\InstallStorage;
use Drupal\simpletest\KernelTestBase;
use Drupal\Core\Config\DatabaseStorage;
use Drupal\Core\Config\UnsupportedDataTypeConfigException;
/**
* Tests CRUD operations on configuration objects.
*
* @group config
*/
class ConfigCRUDTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
*
* @var bool
*/
protected $strictConfigSchema = FALSE;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system');
/**
* Tests CRUD operations.
*/
function testCRUD() {
$storage = $this->container->get('config.storage');
$config_factory = $this->container->get('config.factory');
$name = 'config_test.crud';
$config = $this->config($name);
$this->assertIdentical($config->isNew(), TRUE);
// Create a new configuration object.
$config->set('value', 'initial');
$config->save();
$this->assertIdentical($config->isNew(), FALSE);
// Verify the active configuration contains the saved value.
$actual_data = $storage->read($name);
$this->assertIdentical($actual_data, array('value' => 'initial'));
// Update the configuration object instance.
$config->set('value', 'instance-update');
$config->save();
$this->assertIdentical($config->isNew(), FALSE);
// Verify the active configuration contains the updated value.
$actual_data = $storage->read($name);
$this->assertIdentical($actual_data, array('value' => 'instance-update'));
// Verify a call to $this->config() immediately returns the updated value.
$new_config = $this->config($name);
$this->assertIdentical($new_config->get(), $config->get());
$this->assertIdentical($config->isNew(), FALSE);
// Pollute the config factory static cache.
$config_factory->getEditable($name);
// Delete the configuration object.
$config->delete();
// Verify the configuration object is empty.
$this->assertIdentical($config->get(), array());
$this->assertIdentical($config->isNew(), TRUE);
// Verify that all copies of the configuration has been removed from the
// static cache.
$this->assertIdentical($config_factory->getEditable($name)->isNew(), TRUE);
// Verify the active configuration contains no value.
$actual_data = $storage->read($name);
$this->assertIdentical($actual_data, FALSE);
// Verify $this->config() returns no data.
$new_config = $this->config($name);
$this->assertIdentical($new_config->get(), $config->get());
$this->assertIdentical($config->isNew(), TRUE);
// Re-create the configuration object.
$config->set('value', 're-created');
$config->save();
$this->assertIdentical($config->isNew(), FALSE);
// Verify the active configuration contains the updated value.
$actual_data = $storage->read($name);
$this->assertIdentical($actual_data, array('value' => 're-created'));
// Verify a call to $this->config() immediately returns the updated value.
$new_config = $this->config($name);
$this->assertIdentical($new_config->get(), $config->get());
$this->assertIdentical($config->isNew(), FALSE);
// Rename the configuration object.
$new_name = 'config_test.crud_rename';
$this->container->get('config.factory')->rename($name, $new_name);
$renamed_config = $this->config($new_name);
$this->assertIdentical($renamed_config->get(), $config->get());
$this->assertIdentical($renamed_config->isNew(), FALSE);
// Ensure that the old configuration object is removed from both the cache
// and the configuration storage.
$config = $this->config($name);
$this->assertIdentical($config->get(), array());
$this->assertIdentical($config->isNew(), TRUE);
// Test renaming when config.factory does not have the object in its static
// cache.
$name = 'config_test.crud_rename';
// Pollute the non-overrides static cache.
$config_factory->getEditable($name);
// Pollute the overrides static cache.
$config = $config_factory->get($name);
// Rename and ensure that happened properly.
$new_name = 'config_test.crud_rename_no_cache';
$config_factory->rename($name, $new_name);
$renamed_config = $config_factory->get($new_name);
$this->assertIdentical($renamed_config->get(), $config->get());
$this->assertIdentical($renamed_config->isNew(), FALSE);
// Ensure the overrides static cache has been cleared.
$this->assertIdentical($config_factory->get($name)->isNew(), TRUE);
// Ensure the non-overrides static cache has been cleared.
$this->assertIdentical($config_factory->getEditable($name)->isNew(), TRUE);
// Merge data into the configuration object.
$new_config = $this->config($new_name);
$expected_values = array(
'value' => 'herp',
'404' => 'derp',
);
$new_config->merge($expected_values);
$new_config->save();
$this->assertIdentical($new_config->get('value'), $expected_values['value']);
$this->assertIdentical($new_config->get('404'), $expected_values['404']);
// Test that getMultiple() does not return new config objects that were
// previously accessed with get()
$new_config = $config_factory->get('non_existing_key');
$this->assertTrue($new_config->isNew());
$this->assertEqual(0, count($config_factory->loadMultiple(['non_existing_key'])), 'loadMultiple() does not return new objects');
}
/**
* Tests the validation of configuration object names.
*/
function testNameValidation() {
// Verify that an object name without namespace causes an exception.
$name = 'nonamespace';
$message = 'Expected ConfigNameException was thrown for a name without a namespace.';
try {
$this->config($name)->save();
$this->fail($message);
}
catch (ConfigNameException $e) {
$this->pass($message);
}
// Verify that a name longer than the maximum length causes an exception.
$name = 'config_test.herman_melville.moby_dick_or_the_whale.harper_1851.now_small_fowls_flew_screaming_over_the_yet_yawning_gulf_a_sullen_white_surf_beat_against_its_steep_sides_then_all_collapsed_and_the_great_shroud_of_the_sea_rolled_on_as_it_rolled_five_thousand_years_ago';
$message = 'Expected ConfigNameException was thrown for a name longer than Config::MAX_NAME_LENGTH.';
try {
$this->config($name)->save();
$this->fail($message);
}
catch (ConfigNameException $e) {
$this->pass($message);
}
// Verify that disallowed characters in the name cause an exception.
$characters = $test_characters = array(':', '?', '*', '<', '>', '"', '\'', '/', '\\');
foreach ($test_characters as $i => $c) {
try {
$name = 'namespace.object' . $c;
$config = $this->config($name);
$config->save();
}
catch (ConfigNameException $e) {
unset($test_characters[$i]);
}
}
$this->assertTrue(empty($test_characters), format_string('Expected ConfigNameException was thrown for all invalid name characters: @characters', array(
'@characters' => implode(' ', $characters),
)));
// Verify that a valid config object name can be saved.
$name = 'namespace.object';
$message = 'ConfigNameException was not thrown for a valid object name.';
try {
$config = $this->config($name);
$config->save();
$this->pass($message);
}
catch (ConfigNameException $e) {
$this->fail($message);
}
}
/**
* Tests the validation of configuration object values.
*/
function testValueValidation() {
// Verify that setData() will catch dotted keys.
$message = 'Expected ConfigValueException was thrown from setData() for value with dotted keys.';
try {
$this->config('namespace.object')->setData(array('key.value' => 12))->save();
$this->fail($message);
}
catch (ConfigValueException $e) {
$this->pass($message);
}
// Verify that set() will catch dotted keys.
$message = 'Expected ConfigValueException was thrown from set() for value with dotted keys.';
try {
$this->config('namespace.object')->set('foo', array('key.value' => 12))->save();
$this->fail($message);
}
catch (ConfigValueException $e) {
$this->pass($message);
}
}
/**
* Tests data type handling.
*/
public function testDataTypes() {
\Drupal::service('module_installer')->install(array('config_test'));
$storage = new DatabaseStorage($this->container->get('database'), 'config');
$name = 'config_test.types';
$config = $this->config($name);
$original_content = file_get_contents(drupal_get_path('module', 'config_test') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY . "/$name.yml");
$this->verbose('<pre>' . $original_content . "\n" . var_export($storage->read($name), TRUE));
// Verify variable data types are intact.
$data = array(
'array' => array(),
'boolean' => TRUE,
'exp' => 1.2e+34,
'float' => 3.14159,
'float_as_integer' => (float) 1,
'hex' => 0xC,
'int' => 99,
'octal' => 0775,
'string' => 'string',
'string_int' => '1',
);
$data['_core']['default_config_hash'] = Crypt::hashBase64(serialize($data));
$this->assertIdentical($config->get(), $data);
// Re-set each key using Config::set().
foreach($data as $key => $value) {
$config->set($key, $value);
}
$config->save();
$this->assertIdentical($config->get(), $data);
// Assert the data against the file storage.
$this->assertIdentical($storage->read($name), $data);
$this->verbose('<pre>' . $name . var_export($storage->read($name), TRUE));
// Set data using config::setData().
$config->setData($data)->save();
$this->assertIdentical($config->get(), $data);
$this->assertIdentical($storage->read($name), $data);
// Test that schema type enforcement can be overridden by trusting the data.
$this->assertIdentical(99, $config->get('int'));
$config->set('int', '99')->save(TRUE);
$this->assertIdentical('99', $config->get('int'));
// Test that re-saving without testing the data enforces the schema type.
$config->save();
$this->assertIdentical($data, $config->get());
// Test that setting an unsupported type for a config object with a schema
// fails.
try {
$config->set('stream', fopen(__FILE__, 'r'))->save();
$this->fail('No Exception thrown upon saving invalid data type.');
}
catch (UnsupportedDataTypeConfigException $e) {
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', array(
'%class' => get_class($e),
)));
}
// Test that setting an unsupported type for a config object with no schema
// also fails.
$typed_config_manager = $this->container->get('config.typed');
$config_name = 'config_test.no_schema';
$config = $this->config($config_name);
$this->assertFalse($typed_config_manager->hasConfigSchema($config_name));
try {
$config->set('stream', fopen(__FILE__, 'r'))->save();
$this->fail('No Exception thrown upon saving invalid data type.');
}
catch (UnsupportedDataTypeConfigException $e) {
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', array(
'%class' => get_class($e),
)));
}
}
}

View file

@ -1,486 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigDependencyTest.
*/
namespace Drupal\config\Tests;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\system\Tests\Entity\EntityUnitTestBase;
/**
* Tests for configuration dependencies.
*
* @group config
*/
class ConfigDependencyTest extends EntityUnitTestBase {
/**
* Modules to enable.
*
* The entity_test module is enabled to provide content entity types.
*
* @var array
*/
public static $modules = array('config_test', 'entity_test', 'user');
/**
* Tests that calculating dependencies for system module.
*/
public function testNonEntity() {
$this->installConfig(array('system'));
$config_manager = \Drupal::service('config.manager');
$dependents = $config_manager->findConfigEntityDependents('module', array('system'));
$this->assertTrue(isset($dependents['system.site']), 'Simple configuration system.site has a UUID key even though it is not a configuration entity and therefore is found when looking for dependencies of the System module.');
// Ensure that calling
// \Drupal\Core\Config\ConfigManager::findConfigEntityDependentsAsEntities()
// does not try to load system.site as an entity.
$config_manager->findConfigEntityDependentsAsEntities('module', array('system'));
}
/**
* Tests creating dependencies on configuration entities.
*/
public function testDependencyManagement() {
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = \Drupal::service('config.manager');
$storage = $this->container->get('entity.manager')->getStorage('config_test');
// Test dependencies between modules.
$entity1 = $storage->create(
array(
'id' => 'entity1',
'dependencies' => array(
'enforced' => array(
'module' => array('node')
)
)
)
);
$entity1->save();
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the Node module.');
$dependents = $config_manager->findConfigEntityDependents('module', array('config_test'));
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the config_test module.');
$dependents = $config_manager->findConfigEntityDependents('module', array('views'));
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the Views module.');
// Ensure that the provider of the config entity is not actually written to
// the dependencies array.
$raw_config = $this->config('config_test.dynamic.entity1');
$root_module_dependencies = $raw_config->get('dependencies.module');
$this->assertTrue(empty($root_module_dependencies), 'Node module is not written to the root dependencies array as it is enforced.');
// Create additional entities to test dependencies on config entities.
$entity2 = $storage->create(array('id' => 'entity2', 'dependencies' => array('enforced' => array('config' => array($entity1->getConfigDependencyName())))));
$entity2->save();
$entity3 = $storage->create(array('id' => 'entity3', 'dependencies' => array('enforced' => array('config' => array($entity2->getConfigDependencyName())))));
$entity3->save();
$entity4 = $storage->create(array('id' => 'entity4', 'dependencies' => array('enforced' => array('config' => array($entity3->getConfigDependencyName())))));
$entity4->save();
// Test getting $entity1's dependencies as configuration dependency objects.
$dependents = $config_manager->findConfigEntityDependents('config', array($entity1->getConfigDependencyName()));
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on itself.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on config_test.dynamic.entity1.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on config_test.dynamic.entity1.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on config_test.dynamic.entity1.');
// Test getting $entity2's dependencies as entities.
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', array($entity2->getConfigDependencyName()));
$dependent_ids = $this->getDependentIds($dependents);
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on config_test.dynamic.entity1.');
$this->assertFalse(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 does not have a dependency on itself.');
$this->assertTrue(in_array('config_test:entity3', $dependent_ids), 'config_test.dynamic.entity3 has a dependency on config_test.dynamic.entity2.');
$this->assertTrue(in_array('config_test:entity4', $dependent_ids), 'config_test.dynamic.entity4 has a dependency on config_test.dynamic.entity2.');
// Test getting node module's dependencies as configuration dependency
// objects.
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the Node module.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on the Node module.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the Node module.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on the Node module.');
// Test getting node module's dependencies as configuration dependency
// objects after making $entity3 also dependent on node module but $entity1
// no longer depend on node module.
$entity1->setEnforcedDependencies([])->save();
$entity3->setEnforcedDependencies(['module' => ['node'], 'config' => [$entity2->getConfigDependencyName()]])->save();
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the Node module.');
$this->assertFalse(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 does not have a dependency on the Node module.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the Node module.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on the Node module.');
// Test dependency on a content entity.
$entity_test = entity_create('entity_test', array(
'name' => $this->randomString(),
'type' => 'entity_test',
));
$entity_test->save();
$entity2->setEnforcedDependencies(['config' => [$entity1->getConfigDependencyName()], 'content' => [$entity_test->getConfigDependencyName()]])->save();;
$dependents = $config_manager->findConfigEntityDependents('content', array($entity_test->getConfigDependencyName()));
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the content entity.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on the content entity.');
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the content entity (via entity2).');
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on the content entity (via entity3).');
// Create a configuration entity of a different type with the same ID as one
// of the entities already created.
$alt_storage = $this->container->get('entity.manager')->getStorage('config_query_test');
$alt_storage->create(array('id' => 'entity1', 'dependencies' => array('enforced' => array('config' => array($entity1->getConfigDependencyName())))))->save();
$alt_storage->create(array('id' => 'entity2', 'dependencies' => array('enforced' => array('module' => array('views')))))->save();
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', array($entity1->getConfigDependencyName()));
$dependent_ids = $this->getDependentIds($dependents);
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on itself.');
$this->assertTrue(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 has a dependency on config_test.dynamic.entity1.');
$this->assertTrue(in_array('config_test:entity3', $dependent_ids), 'config_test.dynamic.entity3 has a dependency on config_test.dynamic.entity1.');
$this->assertTrue(in_array('config_test:entity4', $dependent_ids), 'config_test.dynamic.entity4 has a dependency on config_test.dynamic.entity1.');
$this->assertTrue(in_array('config_query_test:entity1', $dependent_ids), 'config_query_test.dynamic.entity1 has a dependency on config_test.dynamic.entity1.');
$this->assertFalse(in_array('config_query_test:entity2', $dependent_ids), 'config_query_test.dynamic.entity2 does not have a dependency on config_test.dynamic.entity1.');
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', array('node', 'views'));
$dependent_ids = $this->getDependentIds($dependents);
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on Views or Node.');
$this->assertFalse(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 does not have a dependency on Views or Node.');
$this->assertTrue(in_array('config_test:entity3', $dependent_ids), 'config_test.dynamic.entity3 has a dependency on Views or Node.');
$this->assertTrue(in_array('config_test:entity4', $dependent_ids), 'config_test.dynamic.entity4 has a dependency on Views or Node.');
$this->assertFalse(in_array('config_query_test:entity1', $dependent_ids), 'config_test.query.entity1 does not have a dependency on Views or Node.');
$this->assertTrue(in_array('config_query_test:entity2', $dependent_ids), 'config_test.query.entity2 has a dependency on Views or Node.');
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', array('config_test'));
$dependent_ids = $this->getDependentIds($dependents);
$this->assertTrue(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 has a dependency on config_test module.');
$this->assertTrue(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 has a dependency on config_test module.');
$this->assertTrue(in_array('config_test:entity3', $dependent_ids), 'config_test.dynamic.entity3 has a dependency on config_test module.');
$this->assertTrue(in_array('config_test:entity4', $dependent_ids), 'config_test.dynamic.entity4 has a dependency on config_test module.');
$this->assertTrue(in_array('config_query_test:entity1', $dependent_ids), 'config_test.query.entity1 has a dependency on config_test module.');
$this->assertTrue(in_array('config_query_test:entity2', $dependent_ids), 'config_test.query.entity2 has a dependency on config_test module.');
// Test the ability to find missing content dependencies.
$missing_dependencies = $config_manager->findMissingContentDependencies();
$this->assertEqual([], $missing_dependencies);
$expected = [$entity_test->uuid() => [
'entity_type' => 'entity_test',
'bundle' => $entity_test->bundle(),
'uuid' => $entity_test->uuid(),
]];
// Delete the content entity so that is it now missing.
$entity_test->delete();
$missing_dependencies = $config_manager->findMissingContentDependencies();
$this->assertEqual($expected, $missing_dependencies);
// Add a fake missing dependency to ensure multiple missing dependencies
// work.
$entity1->setEnforcedDependencies(['content' => [$entity_test->getConfigDependencyName(), 'entity_test:bundle:uuid']])->save();;
$expected['uuid'] = [
'entity_type' => 'entity_test',
'bundle' => 'bundle',
'uuid' => 'uuid',
];
$missing_dependencies = $config_manager->findMissingContentDependencies();
$this->assertEqual($expected, $missing_dependencies);
}
/**
* Tests ConfigManager::uninstall() and config entity dependency management.
*/
public function testConfigEntityUninstall() {
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = \Drupal::service('config.manager');
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = $this->container->get('entity.manager')->getStorage('config_test');
// Test dependencies between modules.
$entity1 = $storage->create(
array(
'id' => 'entity1',
'dependencies' => array(
'enforced' => array(
'module' => array('node', 'config_test')
),
),
)
);
$entity1->save();
$entity2 = $storage->create(
array(
'id' => 'entity2',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
),
),
)
);
$entity2->save();
// Perform a module rebuild so we can know where the node module is located
// and uninstall it.
// @todo Remove as part of https://www.drupal.org/node/2186491
system_rebuild_module_data();
// Test that doing a config uninstall of the node module deletes entity2
// since it is dependent on entity1 which is dependent on the node module.
$config_manager->uninstall('module', 'node');
$this->assertFalse($storage->load('entity1'), 'Entity 1 deleted');
$this->assertFalse($storage->load('entity2'), 'Entity 2 deleted');
// Set a more complicated test where dependencies will be fixed.
\Drupal::state()->set('config_test.fix_dependencies', array($entity1->getConfigDependencyName()));
\Drupal::state()->set('config_test.on_dependency_removal_called', []);
// Entity1 will be deleted because it depends on node.
$entity1 = $storage->create(
array(
'id' => 'entity1',
'dependencies' => array(
'enforced' => array(
'module' => array('node', 'config_test')
),
),
)
);
$entity1->save();
// Entity2 has a dependency on Entity1 but it can be fixed because
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
// dependency before config entities are deleted.
$entity2 = $storage->create(
array(
'id' => 'entity2',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
),
),
)
);
$entity2->save();
// Entity3 will be unchanged because it is dependent on Entity2 which can
// be fixed. The ConfigEntityInterface::onDependencyRemoval() method will
// not be called for this entity.
$entity3 = $storage->create(
array(
'id' => 'entity3',
'dependencies' => array(
'enforced' => array(
'config' => array($entity2->getConfigDependencyName()),
),
),
)
);
$entity3->save();
// Entity4's config dependency will be fixed but it will still be deleted
// because it also depends on the node module.
$entity4 = $storage->create(
array(
'id' => 'entity4',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
'module' => array('node', 'config_test')
),
),
)
);
$entity4->save();
// Do a dry run using
// \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval().
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('module', ['node']);
$this->assertEqual($entity1->uuid(), $config_entities['delete'][0]->uuid(), 'Entity 1 will be deleted.');
$this->assertEqual($entity2->uuid(), reset($config_entities['update'])->uuid(), 'Entity 2 will be updated.');
$this->assertEqual($entity3->uuid(), reset($config_entities['unchanged'])->uuid(), 'Entity 3 is not changed.');
$this->assertEqual($entity4->uuid(), $config_entities['delete'][1]->uuid(), 'Entity 4 will be deleted.');
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
$this->assertFalse(in_array($entity3->id(), $called), 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertIdentical(['entity1', 'entity2', 'entity4'], $called, 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
// Perform the uninstall.
$config_manager->uninstall('module', 'node');
// Test that expected actions have been performed.
$this->assertFalse($storage->load('entity1'), 'Entity 1 deleted');
$entity2 = $storage->load('entity2');
$this->assertTrue($entity2, 'Entity 2 not deleted');
$this->assertEqual($entity2->calculateDependencies()->getDependencies()['config'], array(), 'Entity 2 dependencies updated to remove dependency on Entity1.');
$entity3 = $storage->load('entity3');
$this->assertTrue($entity3, 'Entity 3 not deleted');
$this->assertEqual($entity3->calculateDependencies()->getDependencies()['config'], [$entity2->getConfigDependencyName()], 'Entity 3 still depends on Entity 2.');
$this->assertFalse($storage->load('entity4'), 'Entity 4 deleted');
}
/**
* Tests deleting a configuration entity and dependency management.
*/
public function testConfigEntityDelete() {
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = \Drupal::service('config.manager');
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = $this->container->get('entity.manager')->getStorage('config_test');
// Test dependencies between configuration entities.
$entity1 = $storage->create(
array(
'id' => 'entity1'
)
);
$entity1->save();
$entity2 = $storage->create(
array(
'id' => 'entity2',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
),
),
)
);
$entity2->save();
// Do a dry run using
// \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval().
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('config', [$entity1->getConfigDependencyName()]);
$this->assertEqual($entity2->uuid(), reset($config_entities['delete'])->uuid(), 'Entity 2 will be deleted.');
$this->assertTrue(empty($config_entities['update']), 'No dependent configuration entities will be updated.');
$this->assertTrue(empty($config_entities['unchanged']), 'No dependent configuration entities will be unchanged.');
// Test that doing a delete of entity1 deletes entity2 since it is dependent
// on entity1.
$entity1->delete();
$this->assertFalse($storage->load('entity1'), 'Entity 1 deleted');
$this->assertFalse($storage->load('entity2'), 'Entity 2 deleted');
// Set a more complicated test where dependencies will be fixed.
\Drupal::state()->set('config_test.fix_dependencies', array($entity1->getConfigDependencyName()));
// Entity1 will be deleted by the test.
$entity1 = $storage->create(
array(
'id' => 'entity1',
)
);
$entity1->save();
// Entity2 has a dependency on Entity1 but it can be fixed because
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
// dependency before config entities are deleted.
$entity2 = $storage->create(
array(
'id' => 'entity2',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
),
),
)
);
$entity2->save();
// Entity3 will be unchanged because it is dependent on Entity2 which can
// be fixed.
$entity3 = $storage->create(
array(
'id' => 'entity3',
'dependencies' => array(
'enforced' => array(
'config' => array($entity2->getConfigDependencyName()),
),
),
)
);
$entity3->save();
// Do a dry run using
// \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval().
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('config', [$entity1->getConfigDependencyName()]);
$this->assertTrue(empty($config_entities['delete']), 'No dependent configuration entities will be deleted.');
$this->assertEqual($entity2->uuid(), reset($config_entities['update'])->uuid(), 'Entity 2 will be updated.');
$this->assertEqual($entity3->uuid(), reset($config_entities['unchanged'])->uuid(), 'Entity 3 is not changed.');
// Perform the uninstall.
$entity1->delete();
// Test that expected actions have been performed.
$this->assertFalse($storage->load('entity1'), 'Entity 1 deleted');
$entity2 = $storage->load('entity2');
$this->assertTrue($entity2, 'Entity 2 not deleted');
$this->assertEqual($entity2->calculateDependencies()->getDependencies()['config'], array(), 'Entity 2 dependencies updated to remove dependency on Entity1.');
$entity3 = $storage->load('entity3');
$this->assertTrue($entity3, 'Entity 3 not deleted');
$this->assertEqual($entity3->calculateDependencies()->getDependencies()['config'], [$entity2->getConfigDependencyName()], 'Entity 3 still depends on Entity 2.');
}
/**
* Tests getConfigEntitiesToChangeOnDependencyRemoval() with content entities.
*
* At the moment there is no runtime code that calculates configuration
* dependencies on content entity delete because this calculation is expensive
* and all content dependencies are soft. This test ensures that the code
* works for content entities.
*
* @see \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval()
*/
public function testContentEntityDelete() {
$this->installEntitySchema('entity_test');
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = \Drupal::service('config.manager');
$content_entity = EntityTest::create();
$content_entity->save();
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = $this->container->get('entity.manager')->getStorage('config_test');
$entity1 = $storage->create(
array(
'id' => 'entity1',
'dependencies' => array(
'enforced' => array(
'content' => array($content_entity->getConfigDependencyName())
),
),
)
);
$entity1->save();
$entity2 = $storage->create(
array(
'id' => 'entity2',
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName())
),
),
)
);
$entity2->save();
// Create a configuration entity that is not in the dependency chain.
$entity3 = $storage->create(array('id' => 'entity3'));
$entity3->save();
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('content', [$content_entity->getConfigDependencyName()]);
$this->assertEqual($entity1->uuid(), $config_entities['delete'][0]->uuid(), 'Entity 1 will be deleted.');
$this->assertEqual($entity2->uuid(), $config_entities['delete'][1]->uuid(), 'Entity 2 will be deleted.');
$this->assertTrue(empty($config_entities['update']), 'No dependencies of the content entity will be updated.');
$this->assertTrue(empty($config_entities['unchanged']), 'No dependencies of the content entity will be unchanged.');
}
/**
* Gets a list of identifiers from an array of configuration entities.
*
* @param \Drupal\Core\Config\Entity\ConfigEntityInterface[] $dependents
* An array of configuration entities.
*
* @return array
* An array with values of entity_type_id:ID
*/
protected function getDependentIds(array $dependents) {
$dependent_ids = array();
foreach($dependents as $dependent) {
$dependent_ids[] = $dependent->getEntityTypeId() . ':' . $dependent->id();
}
return $dependent_ids;
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigDependencyWebTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Entity\ConfigEntityStorage;

View file

@ -1,147 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigDiffTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Calculating the difference between two sets of configuration.
*
* @group config
*/
class ConfigDiffTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test', 'system');
/**
* Tests calculating the difference between two sets of configuration.
*/
function testDiff() {
$active = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$config_name = 'config_test.system';
$change_key = 'foo';
$remove_key = '404';
$add_key = 'biff';
$add_data = 'bangpow';
$change_data = 'foobar';
// Install the default config.
$this->installConfig(array('config_test'));
$original_data = \Drupal::config($config_name)->get();
// Change a configuration value in sync.
$sync_data = $original_data;
$sync_data[$change_key] = $change_data;
$sync_data[$add_key] = $add_data;
$sync->write($config_name, $sync_data);
// Verify that the diff reflects a change.
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'change', 'The first item in the diff is a change.');
$this->assertEqual($edits[0]->orig[0], $change_key . ': ' . $original_data[$change_key], format_string("The active value for key '%change_key' is '%original_data'.", array('%change_key' => $change_key, '%original_data' => $original_data[$change_key])));
$this->assertEqual($edits[0]->closing[0], $change_key . ': ' . $change_data, format_string("The sync value for key '%change_key' is '%change_data'.", array('%change_key' => $change_key, '%change_data' => $change_data)));
// Reset data back to original, and remove a key
$sync_data = $original_data;
unset($sync_data[$remove_key]);
$sync->write($config_name, $sync_data);
// Verify that the diff reflects a removed key.
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
$this->assertEqual($edits[1]->type, 'delete', 'The second item in the diff is a delete.');
$this->assertEqual($edits[1]->orig[0], $remove_key . ': ' . $original_data[$remove_key], format_string("The active value for key '%remove_key' is '%original_data'.", array('%remove_key' => $remove_key, '%original_data' => $original_data[$remove_key])));
$this->assertFalse($edits[1]->closing, format_string("The key '%remove_key' does not exist in sync.", array('%remove_key' => $remove_key)));
// Reset data back to original and add a key
$sync_data = $original_data;
$sync_data[$add_key] = $add_data;
$sync->write($config_name, $sync_data);
// Verify that the diff reflects an added key.
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
$this->assertEqual($edits[1]->type, 'add', 'The second item in the diff is an add.');
$this->assertFalse($edits[1]->orig, format_string("The key '%add_key' does not exist in active.", array('%add_key' => $add_key)));
$this->assertEqual($edits[1]->closing[0], $add_key . ': ' . $add_data, format_string("The sync value for key '%add_key' is '%add_data'.", array('%add_key' => $add_key, '%add_data' => $add_data)));
// Test diffing a renamed config entity.
$test_entity_id = $this->randomMachineName();
$test_entity = entity_create('config_test', array(
'id' => $test_entity_id,
'label' => $this->randomMachineName(),
));
$test_entity->save();
$data = $active->read('config_test.dynamic.' . $test_entity_id);
$sync->write('config_test.dynamic.' . $test_entity_id, $data);
$config_name = 'config_test.dynamic.' . $test_entity_id;
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, $config_name);
// Prove the fields match.
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
$this->assertEqual(count($edits), 1, 'There is one item in the diff');
// Rename the entity.
$new_test_entity_id = $this->randomMachineName();
$test_entity->set('id', $new_test_entity_id);
$test_entity->save();
$diff = \Drupal::service('config.manager')->diff($active, $sync, 'config_test.dynamic.' . $new_test_entity_id, $config_name);
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
$this->assertEqual($edits[1]->type, 'change', 'The second item in the diff is a change.');
$this->assertEqual($edits[1]->orig, array('id: ' . $new_test_entity_id));
$this->assertEqual($edits[1]->closing, array('id: ' . $test_entity_id));
$this->assertEqual($edits[2]->type, 'copy', 'The third item in the diff is a copy.');
$this->assertEqual(count($edits), 3, 'There are three items in the diff.');
}
/**
* Tests calculating the difference between two sets of config collections.
*/
function testCollectionDiff() {
/** @var \Drupal\Core\Config\StorageInterface $active */
$active = $this->container->get('config.storage');
/** @var \Drupal\Core\Config\StorageInterface $sync */
$sync = $this->container->get('config.storage.sync');
$active_test_collection = $active->createCollection('test');
$sync_test_collection = $sync->createCollection('test');
$config_name = 'config_test.test';
$data = array('foo' => 'bar');
$active->write($config_name, $data);
$sync->write($config_name, $data);
$active_test_collection->write($config_name, $data);
$sync_test_collection->write($config_name, array('foo' => 'baz'));
// Test the fields match in the default collection diff.
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
$this->assertEqual(count($edits), 1, 'There is one item in the diff');
// Test that the differences are detected when diffing the collection.
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, NULL, 'test');
$edits = $diff->getEdits();
$this->assertEqual($edits[0]->type, 'change', 'The second item in the diff is a copy.');
$this->assertEqual($edits[0]->orig, array('foo: bar'));
$this->assertEqual($edits[0]->closing, array('foo: baz'));
$this->assertEqual($edits[1]->type, 'copy', 'The second item in the diff is a copy.');
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityFormOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityListMultilingualTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityListTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,51 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityNormalizeTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the listing of configuration entities.
*
* @group config
*/
class ConfigEntityNormalizeTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('config_test');
protected function setUp() {
parent::setUp();
$this->installConfig(static::$modules);
}
public function testNormalize() {
$config_entity = entity_create('config_test', array('id' => 'system', 'label' => 'foobar', 'weight' => 1));
$config_entity->save();
// Modify stored config entity, this is comparable with a schema change.
$config = $this->config('config_test.dynamic.system');
$data = array(
'label' => 'foobar',
'additional_key' => TRUE
) + $config->getRawData();
$config->setData($data)->save();
$this->assertNotIdentical($config_entity->toArray(), $config->getRawData(), 'Stored config entity is not is equivalent to config schema.');
$config_entity = entity_load('config_test', 'system', TRUE);
$config_entity->save();
$config = $this->config('config_test.dynamic.system');
$this->assertIdentical($config_entity->toArray(), $config->getRawData(), 'Stored config entity is equivalent to config schema.');
}
}

View file

@ -1,110 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityStaticCacheTest.
*/
namespace Drupal\config\Tests;
use Drupal\config_entity_static_cache_test\ConfigOverrider;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the entity static cache when used by config entities.
*
* @group config
*/
class ConfigEntityStaticCacheTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test', 'config_entity_static_cache_test');
/**
* The type ID of the entity under test.
*
* @var string
*/
protected $entityTypeId;
/**
* The entity ID of the entity under test.
*
* @var string
*/
protected $entityId;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->entityTypeId = 'config_test';
$this->entityId = 'test_1';
entity_create($this->entityTypeId, array('id' => $this->entityId, 'label' => 'Original label'))->save();
}
/**
* Tests that the static cache is working.
*/
public function testCacheHit() {
$entity_1 = entity_load($this->entityTypeId, $this->entityId);
$entity_2 = entity_load($this->entityTypeId, $this->entityId);
// config_entity_static_cache_test_config_test_load() sets _loadStamp to a
// random string. If they match, it means $entity_2 was retrieved from the
// static cache rather than going through a separate load sequence.
$this->assertIdentical($entity_1->_loadStamp, $entity_2->_loadStamp);
}
/**
* Tests that the static cache is reset on entity save and delete.
*/
public function testReset() {
$entity = entity_load($this->entityTypeId, $this->entityId);
// Ensure loading after a save retrieves the updated entity rather than an
// obsolete cached one.
$entity->label = 'New label';
$entity->save();
$entity = entity_load($this->entityTypeId, $this->entityId);
$this->assertIdentical($entity->label, 'New label');
// Ensure loading after a delete retrieves NULL rather than an obsolete
// cached one.
$entity->delete();
$this->assertNull(entity_load($this->entityTypeId, $this->entityId));
}
/**
* Tests that the static cache is sensitive to config overrides.
*/
public function testConfigOverride() {
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
// Prime the cache prior to adding a config override.
$storage->load($this->entityId);
// Add the config override, and ensure that what is loaded is correct
// despite the prior cache priming.
\Drupal::configFactory()->addOverride(new ConfigOverrider());
$entity_override = $storage->load($this->entityId);
$this->assertIdentical($entity_override->label, 'Overridden label');
// Load override free to ensure that loading the config entity again does
// not return the overridden value.
$entity_no_override = $storage->loadOverrideFree($this->entityId);
$this->assertNotIdentical($entity_no_override->label, 'Overridden label');
$this->assertNotIdentical($entity_override->_loadStamp, $entity_no_override->_loadStamp);
// Reload the entity and ensure the cache is used.
$this->assertIdentical($storage->loadOverrideFree($this->entityId)->_loadStamp, $entity_no_override->_loadStamp);
// Enable overrides and reload the entity and ensure the cache is used.
$this->assertIdentical($storage->load($this->entityId)->_loadStamp, $entity_override->_loadStamp);
}
}

View file

@ -1,47 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityStatusTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Tests configuration entity status functionality.
*
* @group config
*/
class ConfigEntityStatusTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test');
/**
* Tests the enabling/disabling of entities.
*/
function testCRUD() {
$entity = entity_create('config_test', array(
'id' => strtolower($this->randomMachineName()),
));
$this->assertTrue($entity->status(), 'Default status is enabled.');
$entity->save();
$this->assertTrue($entity->status(), 'Status is enabled after saving.');
$entity->disable()->save();
$this->assertFalse($entity->status(), 'Entity is disabled after disabling.');
$entity->enable()->save();
$this->assertTrue($entity->status(), 'Entity is enabled after enabling.');
$entity = entity_load('config_test', $entity->id());
$this->assertTrue($entity->status(), 'Status is enabled after reload.');
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityStatusUITest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,57 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityStorageTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
use Drupal\Core\Config\ConfigDuplicateUUIDException;
/**
* Tests sync and importing config entities with IDs and UUIDs that match
* existing config.
*
* @group config
*/
class ConfigEntityStorageTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test');
/**
* Tests creating configuration entities with changed UUIDs.
*/
public function testUUIDConflict() {
$entity_type = 'config_test';
$id = 'test_1';
// Load the original configuration entity.
entity_create($entity_type, array('id' => $id))->save();
$entity = entity_load($entity_type, $id);
$original_properties = $entity->toArray();
// Override with a new UUID and try to save.
$new_uuid = $this->container->get('uuid')->generate();
$entity->set('uuid', $new_uuid);
try {
$entity->save();
$this->fail('Exception thrown when attempting to save a configuration entity with a UUID that does not match the existing UUID.');
}
catch (ConfigDuplicateUUIDException $e) {
$this->pass(format_string('Exception thrown when attempting to save a configuration entity with a UUID that does not match existing data: %e.', array('%e' => $e)));
}
// Ensure that the config entity was not corrupted.
$entity = entity_load('config_test', $entity->id(), TRUE);
$this->assertIdentical($entity->toArray(), $original_properties);
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\SafeMarkup;

View file

@ -1,116 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEntityUnitTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Unit tests for configuration entity base methods.
*
* @group config
*/
class ConfigEntityUnitTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
*
* @var bool
*/
protected $strictConfigSchema = FALSE;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test');
/**
* The config_test entity storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $storage;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->storage = $this->container->get('entity.manager')->getStorage('config_test');
}
/**
* Tests storage methods.
*/
public function testStorageMethods() {
$entity_type = \Drupal::entityManager()->getDefinition('config_test');
// Test the static extractID() method.
$expected_id = 'test_id';
$config_name = $entity_type->getConfigPrefix() . '.' . $expected_id;
$storage = $this->storage;
$this->assertIdentical($storage::getIDFromConfigName($config_name, $entity_type->getConfigPrefix()), $expected_id);
// Create three entities, two with the same style.
$style = $this->randomMachineName(8);
for ($i = 0; $i < 2; $i++) {
$entity = $this->storage->create(array(
'id' => $this->randomMachineName(),
'label' => $this->randomString(),
'style' => $style,
));
$entity->save();
}
$entity = $this->storage->create(array(
'id' => $this->randomMachineName(),
'label' => $this->randomString(),
// Use a different length for the entity to ensure uniqueness.
'style' => $this->randomMachineName(9),
));
$entity->save();
// Ensure that the configuration entity can be loaded by UUID.
$entity_loaded_by_uuid = \Drupal::entityManager()->loadEntityByUuid($entity_type->id(), $entity->uuid());
if (!$entity_loaded_by_uuid) {
$this->fail(sprintf("Failed to load '%s' entity ID '%s' by UUID '%s'.", $entity_type->id(), $entity->id(), $entity->uuid()));
}
// Compare UUIDs as the objects are not identical since
// $entity->enforceIsNew is FALSE and $entity_loaded_by_uuid->enforceIsNew
// is NULL.
$this->assertIdentical($entity->uuid(), $entity_loaded_by_uuid->uuid());
$entities = $this->storage->loadByProperties();
$this->assertEqual(count($entities), 3, 'Three entities are loaded when no properties are specified.');
$entities = $this->storage->loadByProperties(array('style' => $style));
$this->assertEqual(count($entities), 2, 'Two entities are loaded when the style property is specified.');
// Assert that both returned entities have a matching style property.
foreach ($entities as $entity) {
$this->assertIdentical($entity->get('style'), $style, 'The loaded entity has the correct style value specified.');
}
// Test that schema type enforcement can be overridden by trusting the data.
$entity = $this->storage->create(array(
'id' => $this->randomMachineName(),
'label' => $this->randomString(),
'style' => 999
));
$entity->save();
$this->assertIdentical('999', $entity->style);
$entity->style = 999;
$entity->trustData()->save();
$this->assertIdentical(999, $entity->style);
$entity->save();
$this->assertIdentical('999', $entity->style);
}
}

View file

@ -1,86 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigEventsTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigEvents;
use Drupal\simpletest\KernelTestBase;
/**
* Tests events fired on configuration objects.
*
* @group config
*/
class ConfigEventsTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_events_test');
/**
* Tests configuration events.
*/
function testConfigEvents() {
$name = 'config_events_test.test';
$config = new Config($name, \Drupal::service('config.storage'), \Drupal::service('event_dispatcher'), \Drupal::service('config.typed'));
$config->set('key', 'initial');
$this->assertIdentical(\Drupal::state()->get('config_events_test.event', array()), array(), 'No events fired by creating a new configuration object');
$config->save();
$event = \Drupal::state()->get('config_events_test.event', array());
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
$this->assertIdentical($event['current_config_data'], array('key' => 'initial'));
$this->assertIdentical($event['raw_config_data'], array('key' => 'initial'));
$this->assertIdentical($event['original_config_data'], array());
$config->set('key', 'updated')->save();
$event = \Drupal::state()->get('config_events_test.event', array());
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
$this->assertIdentical($event['current_config_data'], array('key' => 'updated'));
$this->assertIdentical($event['raw_config_data'], array('key' => 'updated'));
$this->assertIdentical($event['original_config_data'], array('key' => 'initial'));
$config->delete();
$event = \Drupal::state()->get('config_events_test.event', array());
$this->assertIdentical($event['event_name'], ConfigEvents::DELETE);
$this->assertIdentical($event['current_config_data'], array());
$this->assertIdentical($event['raw_config_data'], array());
$this->assertIdentical($event['original_config_data'], array('key' => 'updated'));
}
/**
* Tests configuration rename event that is fired from the ConfigFactory.
*/
function testConfigRenameEvent() {
$name = 'config_events_test.test';
$new_name = 'config_events_test.test_rename';
$GLOBALS['config'][$name] = array('key' => 'overridden');
$GLOBALS['config'][$new_name] = array('key' => 'new overridden');
$config = $this->config($name);
$config->set('key', 'initial')->save();
$event = \Drupal::state()->get('config_events_test.event', array());
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
$this->assertIdentical($event['current_config_data'], array('key' => 'initial'));
// Override applies when getting runtime config.
$this->assertEqual($GLOBALS['config'][$name], \Drupal::config($name)->get());
\Drupal::configFactory()->rename($name, $new_name);
$event = \Drupal::state()->get('config_events_test.event', array());
$this->assertIdentical($event['event_name'], ConfigEvents::RENAME);
$this->assertIdentical($event['current_config_data'], array('key' => 'new overridden'));
$this->assertIdentical($event['raw_config_data'], array('key' => 'initial'));
$this->assertIdentical($event['original_config_data'], array('key' => 'new overridden'));
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigExportImportUITest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Unicode;
@ -108,16 +103,16 @@ class ConfigExportImportUITest extends WebTestBase {
// Create a field.
$this->fieldName = Unicode::strtolower($this->randomMachineName());
$this->fieldStorage = entity_create('field_storage_config', array(
$this->fieldStorage = FieldStorageConfig::create(array(
'field_name' => $this->fieldName,
'entity_type' => 'node',
'type' => 'text',
));
$this->fieldStorage->save();
entity_create('field_config', array(
FieldConfig::create([
'field_storage' => $this->fieldStorage,
'bundle' => $this->contentType->id(),
))->save();
])->save();
// Update the displays so that configuration does not change unexpectedly on
// import.
entity_get_form_display('node', $this->contentType->id(), 'default')

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigExportUITest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Serialization\Yaml;

View file

@ -1,235 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigFileContentTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\FileStorage;
use Drupal\simpletest\KernelTestBase;
/**
* Tests reading and writing of configuration files.
*
* @group config
*/
class ConfigFileContentTest extends KernelTestBase {
/**
* Exempt from strict schema checking.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
*
* @var bool
*/
protected $strictConfigSchema = FALSE;
/**
* Tests setting, writing, and reading of a configuration setting.
*/
function testReadWriteConfig() {
$storage = $this->container->get('config.storage');
$name = 'foo.bar';
$key = 'foo';
$value = 'bar';
$nested_key = 'biff.bang';
$nested_value = 'pow';
$array_key = 'array';
$array_value = array(
'foo' => 'bar',
'biff' => array(
'bang' => 'pow',
),
);
$casting_array_key = 'casting_array';
$casting_array_false_value_key = 'casting_array.cast.false';
$casting_array_value = array(
'cast' => array(
'false' => FALSE,
),
);
$nested_array_key = 'nested.array';
$true_key = 'true';
$false_key = 'false';
// Attempt to read non-existing configuration.
$config = $this->config($name);
// Verify a configuration object is returned.
$this->assertEqual($config->getName(), $name);
$this->assertTrue($config, 'Config object created.');
// Verify the configuration object is empty.
$this->assertEqual($config->get(), array(), 'New config object is empty.');
// Verify nothing was saved.
$data = $storage->read($name);
$this->assertIdentical($data, FALSE);
// Add a top level value.
$config = $this->config($name);
$config->set($key, $value);
// Add a nested value.
$config->set($nested_key, $nested_value);
// Add an array.
$config->set($array_key, $array_value);
// Add a nested array.
$config->set($nested_array_key, $array_value);
// Add a boolean false value. Should get cast to 0.
$config->set($false_key, FALSE);
// Add a boolean true value. Should get cast to 1.
$config->set($true_key, TRUE);
// Add a null value. Should get cast to an empty string.
$config->set('null', NULL);
// Add an array with a nested boolean false that should get cast to 0.
$config->set($casting_array_key, $casting_array_value);
$config->save();
// Verify the database entry exists.
$data = $storage->read($name);
$this->assertTrue($data);
// Read top level value.
$config = $this->config($name);
$this->assertEqual($config->getName(), $name);
$this->assertTrue($config, 'Config object created.');
$this->assertEqual($config->get($key), 'bar', 'Top level configuration value found.');
// Read nested value.
$this->assertEqual($config->get($nested_key), $nested_value, 'Nested configuration value found.');
// Read array.
$this->assertEqual($config->get($array_key), $array_value, 'Top level array configuration value found.');
// Read nested array.
$this->assertEqual($config->get($nested_array_key), $array_value, 'Nested array configuration value found.');
// Read a top level value that doesn't exist.
$this->assertNull($config->get('i_dont_exist'), 'Non-existent top level value returned NULL.');
// Read a nested value that doesn't exist.
$this->assertNull($config->get('i.dont.exist'), 'Non-existent nested value returned NULL.');
// Read false value.
$this->assertEqual($config->get($false_key), '0', "Boolean FALSE value returned the string '0'.");
// Read true value.
$this->assertEqual($config->get($true_key), '1', "Boolean TRUE value returned the string '1'.");
// Read null value.
$this->assertIdentical($config->get('null'), NULL);
// Read false that had been nested in an array value.
$this->assertEqual($config->get($casting_array_false_value_key), '0', "Nested boolean FALSE value returned the string '0'.");
// Unset a top level value.
$config->clear($key);
// Unset a nested value.
$config->clear($nested_key);
$config->save();
$config = $this->config($name);
// Read unset top level value.
$this->assertNull($config->get($key), 'Top level value unset.');
// Read unset nested value.
$this->assertNull($config->get($nested_key), 'Nested value unset.');
// Create two new configuration files to test listing.
$config = $this->config('foo.baz');
$config->set($key, $value);
$config->save();
// Test chained set()->save().
$chained_name = 'biff.bang';
$config = $this->config($chained_name);
$config->set($key, $value)->save();
// Verify the database entry exists from a chained save.
$data = $storage->read($chained_name);
$this->assertEqual($data, $config->get());
// Get file listing for all files starting with 'foo'. Should return
// two elements.
$files = $storage->listAll('foo');
$this->assertEqual(count($files), 2, 'Two files listed with the prefix \'foo\'.');
// Get file listing for all files starting with 'biff'. Should return
// one element.
$files = $storage->listAll('biff');
$this->assertEqual(count($files), 1, 'One file listed with the prefix \'biff\'.');
// Get file listing for all files starting with 'foo.bar'. Should return
// one element.
$files = $storage->listAll('foo.bar');
$this->assertEqual(count($files), 1, 'One file listed with the prefix \'foo.bar\'.');
// Get file listing for all files starting with 'bar'. Should return
// an empty array.
$files = $storage->listAll('bar');
$this->assertEqual($files, array(), 'No files listed with the prefix \'bar\'.');
// Delete the configuration.
$config = $this->config($name);
$config->delete();
// Verify the database entry no longer exists.
$data = $storage->read($name);
$this->assertIdentical($data, FALSE);
}
/**
* Tests serialization of configuration to file.
*/
function testSerialization() {
$name = $this->randomMachineName(10) . '.' . $this->randomMachineName(10);
$config_data = array(
// Indexed arrays; the order of elements is essential.
'numeric keys' => array('i', 'n', 'd', 'e', 'x', 'e', 'd'),
// Infinitely nested keys using arbitrary element names.
'nested keys' => array(
// HTML/XML in values.
'HTML' => '<strong> <bold> <em> <blockquote>',
// UTF-8 in values.
'UTF-8' => 'FrançAIS is ÜBER-åwesome',
// Unicode in keys and values.
'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ' => 'αβγδεζηθικλμνξοσὠ',
),
'invalid xml' => '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' ',
);
// Encode and write, and reload and decode the configuration data.
$filestorage = new FileStorage($this->configDirectories[CONFIG_SYNC_DIRECTORY]);
$filestorage->write($name, $config_data);
$config_parsed = $filestorage->read($name);
$key = 'numeric keys';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
$key = 'nested keys';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
$key = 'HTML';
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$key = 'UTF-8';
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$key = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ';
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$key = 'invalid xml';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigFormOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;
@ -35,7 +30,7 @@ class ConfigFormOverrideTest extends WebTestBase {
// Test that everything on the form is the same, but that the override
// worked for the actual site name.
$this->drupalGet('admin/config/system/site-information');
$this->assertTitle('Site information | ' . $overridden_name);
$this->assertTitle('Basic site settings | ' . $overridden_name);
$elements = $this->xpath('//input[@name="site_name"]');
$this->assertIdentical((string) $elements[0]['value'], 'Drupal');
@ -44,7 +39,7 @@ class ConfigFormOverrideTest extends WebTestBase {
'site_name' => 'Custom site name',
);
$this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
$this->assertTitle('Site information | ' . $overridden_name);
$this->assertTitle('Basic site settings | ' . $overridden_name);
$elements = $this->xpath('//input[@name="site_name"]');
$this->assertIdentical((string) $elements[0]['value'], $edit['site_name']);
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportAllTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\StorageComparer;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportInstallProfileTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,110 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportRecreateTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\StorageComparer;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\KernelTestBase;
/**
* Tests importing recreated configuration entities.
*
* @group config
*/
class ConfigImportRecreateTest extends KernelTestBase {
/**
* Config Importer object used for testing.
*
* @var \Drupal\Core\Config\ConfigImporter
*/
protected $configImporter;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['system', 'field', 'text', 'user', 'node'];
protected function setUp() {
parent::setUp();
$this->installEntitySchema('node');
$this->installConfig(array('field', 'node'));
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.sync'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$this->configImporter = new ConfigImporter(
$storage_comparer->createChangelist(),
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
}
public function testRecreateEntity() {
$type_name = Unicode::strtolower($this->randomMachineName(16));
$content_type = entity_create('node_type', array(
'type' => $type_name,
'name' => 'Node type one',
));
$content_type->save();
node_add_body_field($content_type);
/** @var \Drupal\Core\Config\StorageInterface $active */
$active = $this->container->get('config.storage');
/** @var \Drupal\Core\Config\StorageInterface $sync */
$sync = $this->container->get('config.storage.sync');
$config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
$this->copyConfig($active, $sync);
// Delete the content type. This will also delete a field storage, a field,
// an entity view display and an entity form display.
$content_type->delete();
$this->assertFalse($active->exists($config_name), 'Content type\'s old name does not exist active store.');
// Recreate with the same type - this will have a different UUID.
$content_type = entity_create('node_type', array(
'type' => $type_name,
'name' => 'Node type two',
));
$content_type->save();
node_add_body_field($content_type);
$this->configImporter->reset();
// A node type, a field, an entity view display and an entity form display
// will be recreated.
$creates = $this->configImporter->getUnprocessedConfiguration('create');
$deletes = $this->configImporter->getUnprocessedConfiguration('delete');
$this->assertEqual(5, count($creates), 'There are 5 configuration items to create.');
$this->assertEqual(5, count($deletes), 'There are 5 configuration items to delete.');
$this->assertEqual(0, count($this->configImporter->getUnprocessedConfiguration('update')), 'There are no configuration items to update.');
$this->assertIdentical($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
$this->configImporter->import();
// Verify that there is nothing more to import.
$this->assertFalse($this->configImporter->reset()->hasUnprocessedConfigurationChanges());
$content_type = NodeType::load($type_name);
$this->assertEqual('Node type one', $content_type->label());
}
}

View file

@ -1,162 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportRenameValidationTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Uuid\Php;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\StorageComparer;
use Drupal\simpletest\KernelTestBase;
/**
* Tests validating renamed configuration in a configuration import.
*
* @group config
*/
class ConfigImportRenameValidationTest extends KernelTestBase {
/**
* Config Importer object used for testing.
*
* @var \Drupal\Core\Config\ConfigImporter
*/
protected $configImporter;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['system', 'user', 'node', 'field', 'text', 'config_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$this->installConfig(array('field'));
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.sync'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$this->configImporter = new ConfigImporter(
$storage_comparer->createChangelist(),
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock.persistent'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
}
/**
* Tests configuration renaming validation.
*/
public function testRenameValidation() {
// Create a test entity.
$test_entity_id = $this->randomMachineName();
$test_entity = entity_create('config_test', array(
'id' => $test_entity_id,
'label' => $this->randomMachineName(),
));
$test_entity->save();
$uuid = $test_entity->uuid();
// Stage the test entity and then delete it from the active storage.
$active = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$this->copyConfig($active, $sync);
$test_entity->delete();
// Create a content type with a matching UUID in the active storage.
$content_type = entity_create('node_type', array(
'type' => Unicode::strtolower($this->randomMachineName(16)),
'name' => $this->randomMachineName(),
'uuid' => $uuid,
));
$content_type->save();
// Confirm that the staged configuration is detected as a rename since the
// UUIDs match.
$this->configImporter->reset();
$expected = array(
'node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id,
);
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
$this->assertIdentical($expected, $renames);
// Try to import the configuration. We expect an exception to be thrown
// because the staged entity is of a different type.
try {
$this->configImporter->import();
$this->fail('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.');
}
catch (ConfigImporterException $e) {
$this->pass('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.');
$expected = array(
SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', array('@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id))
);
$this->assertEqual($expected, $this->configImporter->getErrors());
}
}
/**
* Tests configuration renaming validation for simple configuration.
*/
public function testRenameSimpleConfigValidation() {
$uuid = new Php();
// Create a simple configuration with a UUID.
$config = $this->config('config_test.new');
$uuid_value = $uuid->generate();
$config->set('uuid', $uuid_value)->save();
$active = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$this->copyConfig($active, $sync);
$config->delete();
// Create another simple configuration with the same UUID.
$config = $this->config('config_test.old');
$config->set('uuid', $uuid_value)->save();
// Confirm that the staged configuration is detected as a rename since the
// UUIDs match.
$this->configImporter->reset();
$expected = array(
'config_test.old::config_test.new'
);
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
$this->assertIdentical($expected, $renames);
// Try to import the configuration. We expect an exception to be thrown
// because the rename is for simple configuration.
try {
$this->configImporter->import();
$this->fail('Expected ConfigImporterException thrown when simple configuration is renamed.');
}
catch (ConfigImporterException $e) {
$this->pass('Expected ConfigImporterException thrown when simple configuration is renamed.');
$expected = array(
SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', array('@old_name' => 'config_test.old', '@new_name' => 'config_test.new'))
);
$this->assertEqual($expected, $this->configImporter->getErrors());
}
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportUITest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Html;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImportUploadTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,105 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImporterMissingContentTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\StorageComparer;
use Drupal\simpletest\KernelTestBase;
/**
* Tests importing configuration which has missing content dependencies.
*
* @group config
*/
class ConfigImporterMissingContentTest extends KernelTestBase {
/**
* Config Importer object used for testing.
*
* @var \Drupal\Core\Config\ConfigImporter
*/
protected $configImporter;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system', 'user', 'entity_test', 'config_test', 'config_import_test');
protected function setUp() {
parent::setUp();
$this->installSchema('system', 'sequences');
$this->installEntitySchema('entity_test');
$this->installEntitySchema('user');
$this->installConfig(array('config_test'));
// Installing config_test's default configuration pollutes the global
// variable being used for recording hook invocations by this test already,
// so it has to be cleared out manually.
unset($GLOBALS['hook_config_test']);
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.sync'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$this->configImporter = new ConfigImporter(
$storage_comparer->createChangelist(),
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
}
/**
* Tests the missing content event is fired.
*
* @see \Drupal\Core\Config\ConfigImporter::processMissingContent()
* @see \Drupal\config_import_test\EventSubscriber
*/
function testMissingContent() {
\Drupal::state()->set('config_import_test.config_import_missing_content', TRUE);
// Update a configuration entity in the sync directory to have a dependency
// on two content entities that do not exist.
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$entity_one = entity_create('entity_test', array('name' => 'one'));
$entity_two = entity_create('entity_test', array('name' => 'two'));
$entity_three = entity_create('entity_test', array('name' => 'three'));
$dynamic_name = 'config_test.dynamic.dotted.default';
$original_dynamic_data = $storage->read($dynamic_name);
// Entity one will be resolved by
// \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentOne().
$original_dynamic_data['dependencies']['content'][] = $entity_one->getConfigDependencyName();
// Entity two will be resolved by
// \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentTwo().
$original_dynamic_data['dependencies']['content'][] = $entity_two->getConfigDependencyName();
// Entity three will be resolved by
// \Drupal\Core\Config\Importer\FinalMissingContentSubscriber.
$original_dynamic_data['dependencies']['content'][] = $entity_three->getConfigDependencyName();
$sync->write($dynamic_name, $original_dynamic_data);
// Import.
$this->configImporter->reset()->import();
$this->assertEqual([], $this->configImporter->getErrors(), 'There were no errors during the import.');
$this->assertEqual($entity_one->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_one'), 'The missing content event is fired during configuration import.');
$this->assertEqual($entity_two->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_two'), 'The missing content event is fired during configuration import.');
$original_dynamic_data = $storage->read($dynamic_name);
$this->assertEqual([$entity_one->getConfigDependencyName(), $entity_two->getConfigDependencyName(), $entity_three->getConfigDependencyName()], $original_dynamic_data['dependencies']['content'], 'The imported configuration entity has the missing content entity dependency.');
}
}

View file

@ -1,693 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigImporterTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\StorageComparer;
use Drupal\simpletest\KernelTestBase;
/**
* Tests importing configuration from files into active configuration.
*
* @group config
*/
class ConfigImporterTest extends KernelTestBase {
/**
* Config Importer object used for testing.
*
* @var \Drupal\Core\Config\ConfigImporter
*/
protected $configImporter;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test', 'system', 'config_import_test');
protected function setUp() {
parent::setUp();
$this->installConfig(array('config_test'));
// Installing config_test's default configuration pollutes the global
// variable being used for recording hook invocations by this test already,
// so it has to be cleared out manually.
unset($GLOBALS['hook_config_test']);
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.sync'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$this->configImporter = new ConfigImporter(
$storage_comparer->createChangelist(),
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
}
/**
* Tests omission of module APIs for bare configuration operations.
*/
function testNoImport() {
$dynamic_name = 'config_test.dynamic.dotted.default';
// Verify the default configuration values exist.
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('id'), 'dotted.default');
// Verify that a bare $this->config() does not involve module APIs.
$this->assertFalse(isset($GLOBALS['hook_config_test']));
}
/**
* Tests that trying to import from an empty sync configuration directory
* fails.
*/
function testEmptyImportFails() {
try {
$this->container->get('config.storage.sync')->deleteAll();
$this->configImporter->reset()->import();
$this->fail('ConfigImporterException thrown, successfully stopping an empty import.');
}
catch (ConfigImporterException $e) {
$this->pass('ConfigImporterException thrown, successfully stopping an empty import.');
}
}
/**
* Tests verification of site UUID before importing configuration.
*/
function testSiteUuidValidate() {
$sync = \Drupal::service('config.storage.sync');
// Create updated configuration object.
$config_data = $this->config('system.site')->get();
// Generate a new site UUID.
$config_data['uuid'] = \Drupal::service('uuid')->generate();
$sync->write('system.site', $config_data);
try {
$this->configImporter->reset()->import();
$this->fail('ConfigImporterException not thrown, invalid import was not stopped due to mis-matching site UUID.');
}
catch (ConfigImporterException $e) {
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
$error_log = $this->configImporter->getErrors();
$expected = array('Site UUID in source storage does not match the target storage.');
$this->assertEqual($expected, $error_log);
}
}
/**
* Tests deletion of configuration during import.
*/
function testDeleted() {
$dynamic_name = 'config_test.dynamic.dotted.default';
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
// Verify the default configuration values exist.
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('id'), 'dotted.default');
// Delete the file from the sync directory.
$sync->delete($dynamic_name);
// Import.
$this->configImporter->reset()->import();
// Verify the file has been removed.
$this->assertIdentical($storage->read($dynamic_name), FALSE);
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('id'), NULL);
// Verify that appropriate module API hooks have been invoked.
$this->assertTrue(isset($GLOBALS['hook_config_test']['load']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['presave']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['insert']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['update']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['predelete']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['delete']));
$this->assertFalse($this->configImporter->hasUnprocessedConfigurationChanges());
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 0);
}
/**
* Tests creation of configuration during import.
*/
function testNew() {
$dynamic_name = 'config_test.dynamic.new';
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
// Verify the configuration to create does not exist yet.
$this->assertIdentical($storage->exists($dynamic_name), FALSE, $dynamic_name . ' not found.');
// Create new config entity.
$original_dynamic_data = array(
'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651',
'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
'status' => TRUE,
'dependencies' => array(),
'id' => 'new',
'label' => 'New',
'weight' => 0,
'style' => '',
'size' => '',
'size_value' => '',
'protected_property' => '',
);
$sync->write($dynamic_name, $original_dynamic_data);
$this->assertIdentical($sync->exists($dynamic_name), TRUE, $dynamic_name . ' found.');
// Import.
$this->configImporter->reset()->import();
// Verify the values appeared.
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('label'), $original_dynamic_data['label']);
// Verify that appropriate module API hooks have been invoked.
$this->assertFalse(isset($GLOBALS['hook_config_test']['load']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['insert']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['update']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
// Verify that hook_config_import_steps_alter() can add steps to
// configuration synchronization.
$this->assertTrue(isset($GLOBALS['hook_config_test']['config_import_steps_alter']));
// Verify that there is nothing more to import.
$this->assertFalse($this->configImporter->hasUnprocessedConfigurationChanges());
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 0);
}
/**
* Tests that secondary writes are overwritten.
*/
function testSecondaryWritePrimaryFirst() {
$name_primary = 'config_test.dynamic.primary';
$name_secondary = 'config_test.dynamic.secondary';
$sync = $this->container->get('config.storage.sync');
$uuid = $this->container->get('uuid');
$values_primary = array(
'id' => 'primary',
'label' => 'Primary',
'weight' => 0,
'uuid' => $uuid->generate(),
);
$sync->write($name_primary, $values_primary);
$values_secondary = array(
'id' => 'secondary',
'label' => 'Secondary Sync',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on primary, to ensure that is synced first.
'dependencies' => array(
'config' => array($name_primary),
)
);
$sync->write($name_secondary, $values_secondary);
// Import.
$this->configImporter->reset()->import();
$entity_storage = \Drupal::entityManager()->getStorage('config_test');
$primary = $entity_storage->load('primary');
$this->assertEqual($primary->id(), 'primary');
$this->assertEqual($primary->uuid(), $values_primary['uuid']);
$this->assertEqual($primary->label(), $values_primary['label']);
$secondary = $entity_storage->load('secondary');
$this->assertEqual($secondary->id(), 'secondary');
$this->assertEqual($secondary->uuid(), $values_secondary['uuid']);
$this->assertEqual($secondary->label(), $values_secondary['label']);
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 1);
$this->assertEqual($logs[0], SafeMarkup::format('Deleted and replaced configuration entity "@name"', array('@name' => $name_secondary)));
}
/**
* Tests that secondary writes are overwritten.
*/
function testSecondaryWriteSecondaryFirst() {
$name_primary = 'config_test.dynamic.primary';
$name_secondary = 'config_test.dynamic.secondary';
$sync = $this->container->get('config.storage.sync');
$uuid = $this->container->get('uuid');
$values_primary = array(
'id' => 'primary',
'label' => 'Primary',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on secondary, so that is synced first.
'dependencies' => array(
'config' => array($name_secondary),
)
);
$sync->write($name_primary, $values_primary);
$values_secondary = array(
'id' => 'secondary',
'label' => 'Secondary Sync',
'weight' => 0,
'uuid' => $uuid->generate(),
);
$sync->write($name_secondary, $values_secondary);
// Import.
$this->configImporter->reset()->import();
$entity_storage = \Drupal::entityManager()->getStorage('config_test');
$primary = $entity_storage->load('primary');
$this->assertEqual($primary->id(), 'primary');
$this->assertEqual($primary->uuid(), $values_primary['uuid']);
$this->assertEqual($primary->label(), $values_primary['label']);
$secondary = $entity_storage->load('secondary');
$this->assertEqual($secondary->id(), 'secondary');
$this->assertEqual($secondary->uuid(), $values_secondary['uuid']);
$this->assertEqual($secondary->label(), $values_secondary['label']);
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 1);
$this->assertEqual($logs[0], Html::escape("Unexpected error during import with operation create for $name_primary: 'config_test' entity with ID 'secondary' already exists."));
}
/**
* Tests that secondary updates for deleted files work as expected.
*/
function testSecondaryUpdateDeletedDeleterFirst() {
$name_deleter = 'config_test.dynamic.deleter';
$name_deletee = 'config_test.dynamic.deletee';
$name_other = 'config_test.dynamic.other';
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$uuid = $this->container->get('uuid');
$values_deleter = array(
'id' => 'deleter',
'label' => 'Deleter',
'weight' => 0,
'uuid' => $uuid->generate(),
);
$storage->write($name_deleter, $values_deleter);
$values_deleter['label'] = 'Updated Deleter';
$sync->write($name_deleter, $values_deleter);
$values_deletee = array(
'id' => 'deletee',
'label' => 'Deletee',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on deleter, to make sure that is synced first.
'dependencies' => array(
'config' => array($name_deleter),
)
);
$storage->write($name_deletee, $values_deletee);
$values_deletee['label'] = 'Updated Deletee';
$sync->write($name_deletee, $values_deletee);
// Ensure that import will continue after the error.
$values_other = array(
'id' => 'other',
'label' => 'Other',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on deleter, to make sure that is synced first. This
// will also be synced after the deletee due to alphabetical ordering.
'dependencies' => array(
'config' => array($name_deleter),
)
);
$storage->write($name_other, $values_other);
$values_other['label'] = 'Updated other';
$sync->write($name_other, $values_other);
// Check update changelist order.
$updates = $this->configImporter->reset()->getStorageComparer()->getChangelist('update');
$expected = array(
$name_deleter,
$name_deletee,
$name_other,
);
$this->assertIdentical($expected, $updates);
// Import.
$this->configImporter->import();
$entity_storage = \Drupal::entityManager()->getStorage('config_test');
$deleter = $entity_storage->load('deleter');
$this->assertEqual($deleter->id(), 'deleter');
$this->assertEqual($deleter->uuid(), $values_deleter['uuid']);
$this->assertEqual($deleter->label(), $values_deleter['label']);
// The deletee was deleted in
// \Drupal\config_test\Entity\ConfigTest::postSave().
$this->assertFalse($entity_storage->load('deletee'));
$other = $entity_storage->load('other');
$this->assertEqual($other->id(), 'other');
$this->assertEqual($other->uuid(), $values_other['uuid']);
$this->assertEqual($other->label(), $values_other['label']);
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 1);
$this->assertEqual($logs[0], SafeMarkup::format('Update target "@name" is missing.', array('@name' => $name_deletee)));
}
/**
* Tests that secondary updates for deleted files work as expected.
*
* This test is completely hypothetical since we only support full
* configuration tree imports. Therefore, any configuration updates that cause
* secondary deletes should be reflected already in the staged configuration.
*/
function testSecondaryUpdateDeletedDeleteeFirst() {
$name_deleter = 'config_test.dynamic.deleter';
$name_deletee = 'config_test.dynamic.deletee';
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$uuid = $this->container->get('uuid');
$values_deleter = array(
'id' => 'deleter',
'label' => 'Deleter',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on deletee, to make sure that is synced first.
'dependencies' => array(
'config' => array($name_deletee),
),
);
$storage->write($name_deleter, $values_deleter);
$values_deleter['label'] = 'Updated Deleter';
$sync->write($name_deleter, $values_deleter);
$values_deletee = array(
'id' => 'deletee',
'label' => 'Deletee',
'weight' => 0,
'uuid' => $uuid->generate(),
);
$storage->write($name_deletee, $values_deletee);
$values_deletee['label'] = 'Updated Deletee';
$sync->write($name_deletee, $values_deletee);
// Import.
$this->configImporter->reset()->import();
$entity_storage = \Drupal::entityManager()->getStorage('config_test');
// Both entities are deleted. ConfigTest::postSave() causes updates of the
// deleter entity to delete the deletee entity. Since the deleter depends on
// the deletee, removing the deletee causes the deleter to be removed.
$this->assertFalse($entity_storage->load('deleter'));
$this->assertFalse($entity_storage->load('deletee'));
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 0);
}
/**
* Tests that secondary deletes for deleted files work as expected.
*/
function testSecondaryDeletedDeleteeSecond() {
$name_deleter = 'config_test.dynamic.deleter';
$name_deletee = 'config_test.dynamic.deletee';
$storage = $this->container->get('config.storage');
$uuid = $this->container->get('uuid');
$values_deleter = array(
'id' => 'deleter',
'label' => 'Deleter',
'weight' => 0,
'uuid' => $uuid->generate(),
// Add a dependency on deletee, to make sure this delete is synced first.
'dependencies' => array(
'config' => array($name_deletee),
),
);
$storage->write($name_deleter, $values_deleter);
$values_deletee = array(
'id' => 'deletee',
'label' => 'Deletee',
'weight' => 0,
'uuid' => $uuid->generate(),
);
$storage->write($name_deletee, $values_deletee);
// Import.
$this->configImporter->reset()->import();
$entity_storage = \Drupal::entityManager()->getStorage('config_test');
$this->assertFalse($entity_storage->load('deleter'));
$this->assertFalse($entity_storage->load('deletee'));
// The deletee entity does not exist as the delete worked and although the
// delete occurred in \Drupal\config_test\Entity\ConfigTest::postDelete()
// this does not matter.
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 0);
}
/**
* Tests updating of configuration during import.
*/
function testUpdated() {
$name = 'config_test.system';
$dynamic_name = 'config_test.dynamic.dotted.default';
$storage = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
// Verify that the configuration objects to import exist.
$this->assertIdentical($storage->exists($name), TRUE, $name . ' found.');
$this->assertIdentical($storage->exists($dynamic_name), TRUE, $dynamic_name . ' found.');
// Replace the file content of the existing configuration objects in the
// sync directory.
$original_name_data = array(
'foo' => 'beer',
);
$sync->write($name, $original_name_data);
$original_dynamic_data = $storage->read($dynamic_name);
$original_dynamic_data['label'] = 'Updated';
$sync->write($dynamic_name, $original_dynamic_data);
// Verify the active configuration still returns the default values.
$config = $this->config($name);
$this->assertIdentical($config->get('foo'), 'bar');
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('label'), 'Default');
// Import.
$this->configImporter->reset()->import();
// Verify the values were updated.
\Drupal::configFactory()->reset($name);
$config = $this->config($name);
$this->assertIdentical($config->get('foo'), 'beer');
$config = $this->config($dynamic_name);
$this->assertIdentical($config->get('label'), 'Updated');
// Verify that the original file content is still the same.
$this->assertIdentical($sync->read($name), $original_name_data);
$this->assertIdentical($sync->read($dynamic_name), $original_dynamic_data);
// Verify that appropriate module API hooks have been invoked.
$this->assertTrue(isset($GLOBALS['hook_config_test']['load']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['insert']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['update']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
// Verify that there is nothing more to import.
$this->assertFalse($this->configImporter->hasUnprocessedConfigurationChanges());
$logs = $this->configImporter->getErrors();
$this->assertEqual(count($logs), 0);
}
/**
* Tests the isInstallable method()
*/
function testIsInstallable() {
$config_name = 'config_test.dynamic.isinstallable';
$this->assertFalse($this->container->get('config.storage')->exists($config_name));
\Drupal::state()->set('config_test.isinstallable', TRUE);
$this->installConfig(array('config_test'));
$this->assertTrue($this->container->get('config.storage')->exists($config_name));
}
/**
* Tests dependency validation during configuration import.
*
* @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
* @see \Drupal\Core\Config\ConfigImporter::createExtensionChangelist()
*/
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) {
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
$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->assertTrue(in_array($expected_message, $error_log), $expected_message);
}
}
// Make a config entity have mulitple 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) {
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
$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->assertTrue(in_array($expected_message, $error_log), $expected_message);
}
}
}
/**
* Tests missing core.extension during configuration import.
*
* @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
*/
public function testMissingCoreExtension() {
$sync = $this->container->get('config.storage.sync');
$sync->delete('core.extension');
try {
$this->configImporter->reset()->import();
$this->fail('ConfigImporterException not thrown, invalid import was not stopped due to missing dependencies.');
}
catch (ConfigImporterException $e) {
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
$error_log = $this->configImporter->getErrors();
$this->assertEqual(['The core.extension configuration does not exist.'], $error_log);
}
}
/**
* Tests install profile validation during configuration import.
*
* @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
*/
public function testInstallProfile() {
$sync = $this->container->get('config.storage.sync');
$extensions = $sync->read('core.extension');
// Add an install profile.
$extensions['module']['standard'] = 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) {
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
$error_log = $this->configImporter->getErrors();
// Install profiles should not even be scanned at this point.
$this->assertEqual(['Unable to install the <em class="placeholder">standard</em> module since it does not exist.'], $error_log);
}
}
/**
* Tests config_get_config_directory().
*/
public function testConfigGetConfigDirectory() {
$directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$this->assertEqual($this->configDirectories[CONFIG_SYNC_DIRECTORY], $directory);
$message = 'Calling config_get_config_directory() with CONFIG_ACTIVE_DIRECTORY results in an exception.';
try {
config_get_config_directory(CONFIG_ACTIVE_DIRECTORY);
$this->fail($message);
}
catch (\Exception $e) {
$this->pass($message);
}
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigInstallProfileOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Utility\Crypt;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigInstallProfileUnmetDependenciesTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Serialization\Yaml;

View file

@ -1,254 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigInstallTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\PreExistingConfigException;
use Drupal\Core\Config\UnmetDependenciesException;
use Drupal\simpletest\KernelTestBase;
/**
* Tests installation of configuration objects in installation functionality.
*
* @group config
* @see \Drupal\Core\Config\ConfigInstaller
*/
class ConfigInstallTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', ['router']);
// Ensure the global variable being asserted by this test does not exist;
// a previous test executed in this request/process might have set it.
unset($GLOBALS['hook_config_test']);
}
/**
* Tests module installation.
*/
function testModuleInstallation() {
$default_config = 'config_test.system';
$default_configuration_entity = 'config_test.dynamic.dotted.default';
// Verify that default module config does not exist before installation yet.
$config = $this->config($default_config);
$this->assertIdentical($config->isNew(), TRUE);
$config = $this->config($default_configuration_entity);
$this->assertIdentical($config->isNew(), TRUE);
// Ensure that schema provided by modules that are not installed is not
// available.
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
// Install the test module.
$this->installModules(array('config_test'));
// Verify that default module config exists.
\Drupal::configFactory()->reset($default_config);
\Drupal::configFactory()->reset($default_configuration_entity);
$config = $this->config($default_config);
$this->assertIdentical($config->isNew(), FALSE);
$config = $this->config($default_configuration_entity);
$this->assertIdentical($config->isNew(), FALSE);
// Verify that config_test API hooks were invoked for the dynamic default
// configuration entity.
$this->assertFalse(isset($GLOBALS['hook_config_test']['load']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
$this->assertTrue(isset($GLOBALS['hook_config_test']['insert']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['update']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
$this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
// Install the schema test module.
$this->enableModules(array('config_schema_test'));
$this->installConfig(array('config_schema_test'));
// After module installation the new schema should exist.
$this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.');
// Test that uninstalling configuration removes configuration schema.
$this->config('core.extension')->set('module', array())->save();
\Drupal::service('config.manager')->uninstall('module', 'config_test');
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
}
/**
* Tests that collections are ignored if the event does not return anything.
*/
public function testCollectionInstallationNoCollections() {
// Install the test module.
$this->enableModules(array('config_collection_install_test'));
$this->installConfig(array('config_collection_install_test'));
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
$active_storage = \Drupal::service('config.storage');
$this->assertEqual(array(), $active_storage->getAllCollectionNames());
}
/**
* Tests config objects in collections are installed as expected.
*/
public function testCollectionInstallationCollections() {
$collections = array(
'another_collection',
'collection.test1',
'collection.test2',
);
// Set the event listener to return three possible collections.
// @see \Drupal\config_collection_install_test\EventSubscriber
\Drupal::state()->set('config_collection_install_test.collection_names', $collections);
// Install the test module.
$this->enableModules(array('config_collection_install_test'));
$this->installConfig(array('config_collection_install_test'));
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
$active_storage = \Drupal::service('config.storage');
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
foreach ($collections as $collection) {
$collection_storage = $active_storage->createCollection($collection);
$data = $collection_storage->read('config_collection_install_test.test');
$this->assertEqual($collection, $data['collection']);
}
// Tests that clashing configuration in collections is detected.
try {
\Drupal::service('module_installer')->install(['config_collection_clash_install_test']);
$this->fail('Expected PreExistingConfigException not thrown.');
}
catch (PreExistingConfigException $e) {
$this->assertEqual($e->getExtension(), 'config_collection_clash_install_test');
$this->assertEqual($e->getConfigObjects(), [
'another_collection' => ['config_collection_install_test.test'],
'collection.test1' => ['config_collection_install_test.test'],
'collection.test2' => ['config_collection_install_test.test'],
]);
$this->assertEqual($e->getMessage(), 'Configuration objects (another_collection/config_collection_install_test.test, collection/test1/config_collection_install_test.test, collection/test2/config_collection_install_test.test) provided by config_collection_clash_install_test already exist in active configuration');
}
// Test that the we can use the config installer to install all the
// available default configuration in a particular collection for enabled
// extensions.
\Drupal::service('config.installer')->installCollectionDefaultConfig('entity');
// The 'entity' collection will not exist because the 'config_test' module
// is not enabled.
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
// Enable the 'config_test' module and try again.
$this->enableModules(array('config_test'));
\Drupal::service('config.installer')->installCollectionDefaultConfig('entity');
$collections[] = 'entity';
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
$collection_storage = $active_storage->createCollection('entity');
$data = $collection_storage->read('config_test.dynamic.dotted.default');
$this->assertIdentical(array('label' => 'entity'), $data);
// Test that the config manager uninstalls configuration from collections
// as expected.
\Drupal::service('config.manager')->uninstall('module', 'config_collection_install_test');
$this->assertEqual(array('entity'), $active_storage->getAllCollectionNames());
\Drupal::service('config.manager')->uninstall('module', 'config_test');
$this->assertEqual(array(), $active_storage->getAllCollectionNames());
}
/**
* Tests collections which do not support config entities install correctly.
*
* Config entity detection during config installation is done by matching
* config name prefixes. If a collection provides a configuration with a
* matching name but does not support config entities it should be created
* using simple configuration.
*/
public function testCollectionInstallationCollectionConfigEntity() {
$collections = array(
'entity',
);
\Drupal::state()->set('config_collection_install_test.collection_names', $collections);
// Install the test module.
$this->installModules(array('config_test', 'config_collection_install_test'));
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
$active_storage = \Drupal::service('config.storage');
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
$collection_storage = $active_storage->createCollection('entity');
// The config_test.dynamic.dotted.default configuration object saved in the
// active store should be a configuration entity complete with UUID. Because
// the entity collection does not support configuration entities the
// configuration object stored there with the same name should only contain
// a label.
$name = 'config_test.dynamic.dotted.default';
$data = $active_storage->read($name);
$this->assertTrue(isset($data['uuid']));
$data = $collection_storage->read($name);
$this->assertIdentical(array('label' => 'entity'), $data);
}
/**
* Tests the configuration with unmet dependencies is not installed.
*/
public function testDependencyChecking() {
$this->installModules(['config_test']);
try {
$this->installModules(['config_install_dependency_test']);
$this->fail('Expected UnmetDependenciesException not thrown.');
}
catch (UnmetDependenciesException $e) {
$this->assertEqual($e->getExtension(), 'config_install_dependency_test');
$this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency']);
$this->assertEqual($e->getMessage(), 'Configuration objects (config_test.dynamic.other_module_test_with_dependency) provided by config_install_dependency_test have unmet dependencies');
}
$this->installModules(['config_other_module_config_test']);
$this->installModules(['config_install_dependency_test']);
$entity = \Drupal::entityManager()->getStorage('config_test')->load('other_module_test_with_dependency');
$this->assertTrue($entity, 'The config_test.dynamic.other_module_test_with_dependency configuration has been created during install.');
// Ensure that dependencies can be added during module installation by
// hooks.
$this->assertIdentical('config_install_dependency_test', $entity->getDependencies()['module'][0]);
}
/**
* Tests imported configuration entities with and without language information.
*/
function testLanguage() {
$this->installModules(['config_test_language']);
// Test imported configuration with implicit language code.
$storage = new InstallStorage();
$data = $storage->read('config_test.dynamic.dotted.english');
$this->assertTrue(!isset($data['langcode']));
$this->assertEqual(
$this->config('config_test.dynamic.dotted.english')->get('langcode'),
'en'
);
// Test imported configuration with explicit language code.
$data = $storage->read('config_test.dynamic.dotted.french');
$this->assertEqual($data['langcode'], 'fr');
$this->assertEqual(
$this->config('config_test.dynamic.dotted.french')->get('langcode'),
'fr'
);
}
/**
* Installs a module.
*
* @param array $modules
* The module names.
*/
protected function installModules(array $modules) {
$this->container->get('module_installer')->install($modules);
$this->container = \Drupal::getContainer();
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigInstallWebTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\PreExistingConfigException;

View file

@ -1,125 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigLanguageOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\KernelTestBase;
/**
* Confirm that language overrides work.
*
* @group config
*/
class ConfigLanguageOverrideTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user', 'language', 'config_test', 'system', 'field');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(array('config_test'));
}
/**
* Tests locale override based on language.
*/
function testConfigLanguageOverride() {
// The language module implements a config factory override object that
// overrides configuration when the Language module is enabled. This test ensures that
// English overrides work.
\Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('en'));
$config = \Drupal::config('config_test.system');
$this->assertIdentical($config->get('foo'), 'en bar');
// Ensure that the raw data is not translated.
$raw = $config->getRawData();
$this->assertIdentical($raw['foo'], 'bar');
ConfigurableLanguage::createFromLangcode('fr')->save();
ConfigurableLanguage::createFromLangcode('de')->save();
\Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('fr'));
$config = \Drupal::config('config_test.system');
$this->assertIdentical($config->get('foo'), 'fr bar');
\Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('de'));
$config = \Drupal::config('config_test.system');
$this->assertIdentical($config->get('foo'), 'de bar');
// Test overrides of completely new configuration objects. In normal runtime
// this should only happen for configuration entities as we should not be
// creating simple configuration objects on the fly.
\Drupal::languageManager()
->getLanguageConfigOverride('de', 'config_test.new')
->set('language', 'override')
->save();
$config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$this->assertIdentical($config->get('language'), 'override');
$this->assertIdentical($config->getOriginal('language', FALSE), NULL);
// Test how overrides react to base configuration changes. Set up some base
// values.
\Drupal::configFactory()->getEditable('config_test.foo')
->set('value', array('key' => 'original'))
->set('label', 'Original')
->save();
\Drupal::languageManager()
->getLanguageConfigOverride('de', 'config_test.foo')
->set('value', array('key' => 'override'))
->set('label', 'Override')
->save();
\Drupal::languageManager()
->getLanguageConfigOverride('fr', 'config_test.foo')
->set('value', array('key' => 'override'))
->save();
\Drupal::configFactory()->clearStaticCache();
$config = \Drupal::config('config_test.foo');
$this->assertIdentical($config->get('value'), array('key' => 'override'));
// Ensure renaming the config will rename the override.
\Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('en'));
\Drupal::configFactory()->rename('config_test.foo', 'config_test.bar');
$config = \Drupal::config('config_test.bar');
$this->assertEqual($config->get('value'), array('key' => 'original'));
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.foo');
$this->assertTrue($override->isNew());
$this->assertEqual($override->get('value'), NULL);
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
$this->assertFalse($override->isNew());
$this->assertEqual($override->get('value'), array('key' => 'override'));
$override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar');
$this->assertFalse($override->isNew());
$this->assertEqual($override->get('value'), array('key' => 'override'));
// Ensure changing data in the config will update the overrides.
$config = \Drupal::configFactory()->getEditable('config_test.bar')->clear('value.key')->save();
$this->assertEqual($config->get('value'), array());
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
$this->assertFalse($override->isNew());
$this->assertEqual($override->get('value'), NULL);
// The French override will become empty and therefore removed.
$override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar');
$this->assertTrue($override->isNew());
$this->assertEqual($override->get('value'), NULL);
// Ensure deleting the config will delete the override.
\Drupal::configFactory()->getEditable('config_test.bar')->delete();
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
$this->assertTrue($override->isNew());
$this->assertEqual($override->get('value'), NULL);
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigLanguageOverrideWebTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Language\LanguageInterface;

View file

@ -1,55 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigModuleOverridesTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Tests module overrides of configuration using event subscribers.
*
* @group config
*/
class ConfigModuleOverridesTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('system', 'config', 'config_override_test');
public function testSimpleModuleOverrides() {
$GLOBALS['config_test_run_module_overrides'] = TRUE;
$name = 'system.site';
$overridden_name = 'ZOMG overridden site name';
$non_overridden_name = 'ZOMG this name is on disk mkay';
$overridden_slogan = 'Yay for overrides!';
$non_overridden_slogan = 'Yay for defaults!';
$config_factory = $this->container->get('config.factory');
$config_factory
->getEditable($name)
->set('name', $non_overridden_name)
->set('slogan', $non_overridden_slogan)
->save();
$this->assertEqual($non_overridden_name, $config_factory->get('system.site')->getOriginal('name', FALSE));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->getOriginal('slogan', FALSE));
$this->assertEqual($overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($overridden_slogan, $config_factory->get('system.site')->get('slogan'));
// Test overrides of completely new configuration objects. In normal runtime
// this should only happen for configuration entities as we should not be
// creating simple configuration objects on the fly.
$config = $config_factory->get('config_override_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_override_test.new is new');
$this->assertIdentical($config->get('module'), 'override');
$this->assertIdentical($config->getOriginal('module', FALSE), NULL);
unset($GLOBALS['config_test_run_module_overrides']);
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigOtherModuleTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,143 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\KernelTestBase;
/**
* Tests configuration overrides via $config in settings.php.
*
* @group config
*/
class ConfigOverrideTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system', 'config_test');
protected function setUp() {
parent::setUp();
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
}
/**
* Tests configuration override.
*/
function testConfOverride() {
$expected_original_data = array(
'foo' => 'bar',
'baz' => NULL,
'404' => 'herp',
);
// Set globals before installing to prove that the installed file does not
// contain these values.
$overrides['config_test.system']['foo'] = 'overridden';
$overrides['config_test.system']['baz'] = 'injected';
$overrides['config_test.system']['404'] = 'derp';
$GLOBALS['config'] = $overrides;
$this->installConfig(array('config_test'));
// Verify that the original configuration data exists. Have to read storage
// directly otherwise overrides will apply.
$active = $this->container->get('config.storage');
$data = $active->read('config_test.system');
$this->assertIdentical($data['foo'], $expected_original_data['foo']);
$this->assertFalse(isset($data['baz']));
$this->assertIdentical($data['404'], $expected_original_data['404']);
// Get the configuration object with overrides.
$config = \Drupal::configFactory()->get('config_test.system');
// Verify that it contains the overridden data from $config.
$this->assertIdentical($config->get('foo'), $overrides['config_test.system']['foo']);
$this->assertIdentical($config->get('baz'), $overrides['config_test.system']['baz']);
$this->assertIdentical($config->get('404'), $overrides['config_test.system']['404']);
// Get the configuration object which does not have overrides.
$config = \Drupal::configFactory()->getEditable('config_test.system');
// Verify that it does not contains the overridden data from $config.
$this->assertIdentical($config->get('foo'), $expected_original_data['foo']);
$this->assertIdentical($config->get('baz'), NULL);
$this->assertIdentical($config->get('404'), $expected_original_data['404']);
// Set the value for 'baz' (on the original data).
$expected_original_data['baz'] = 'original baz';
$config->set('baz', $expected_original_data['baz']);
// Set the value for '404' (on the original data).
$expected_original_data['404'] = 'original 404';
$config->set('404', $expected_original_data['404']);
// Save the configuration object (having overrides applied).
$config->save();
// Reload it and verify that it still contains overridden data from $config.
$config = \Drupal::config('config_test.system');
$this->assertIdentical($config->get('foo'), $overrides['config_test.system']['foo']);
$this->assertIdentical($config->get('baz'), $overrides['config_test.system']['baz']);
$this->assertIdentical($config->get('404'), $overrides['config_test.system']['404']);
// Verify that raw config data has changed.
$this->assertIdentical($config->getOriginal('foo', FALSE), $expected_original_data['foo']);
$this->assertIdentical($config->getOriginal('baz', FALSE), $expected_original_data['baz']);
$this->assertIdentical($config->getOriginal('404', FALSE), $expected_original_data['404']);
// Write file to sync.
$sync = $this->container->get('config.storage.sync');
$expected_new_data = array(
'foo' => 'barbar',
'404' => 'herpderp',
);
$sync->write('config_test.system', $expected_new_data);
// Import changed data from sync to active.
$this->configImporter()->import();
$data = $active->read('config_test.system');
// Verify that the new configuration data exists. Have to read storage
// directly otherwise overrides will apply.
$this->assertIdentical($data['foo'], $expected_new_data['foo']);
$this->assertFalse(isset($data['baz']));
$this->assertIdentical($data['404'], $expected_new_data['404']);
// Verify that the overrides are still working.
$config = \Drupal::config('config_test.system');
$this->assertIdentical($config->get('foo'), $overrides['config_test.system']['foo']);
$this->assertIdentical($config->get('baz'), $overrides['config_test.system']['baz']);
$this->assertIdentical($config->get('404'), $overrides['config_test.system']['404']);
// Test overrides of completely new configuration objects. In normal runtime
// this should only happen for configuration entities as we should not be
// creating simple configuration objects on the fly.
$GLOBALS['config']['config_test.new']['key'] = 'override';
$config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$this->assertIdentical($config->get('key'), 'override');
$config_raw = \Drupal::configFactory()->getEditable('config_test.new');
$this->assertIdentical($config_raw->get('key'), NULL);
$config_raw
->set('key', 'raw')
->set('new_key', 'new_value')
->save();
// Ensure override is preserved but all other data has been updated
// accordingly.
$config = \Drupal::config('config_test.new');
$this->assertFalse($config->isNew(), 'The configuration object config_test.new is not new');
$this->assertIdentical($config->get('key'), 'override');
$this->assertIdentical($config->get('new_key'), 'new_value');
$raw_data = $config->getRawData();
$this->assertIdentical($raw_data['key'], 'raw');
}
}

View file

@ -1,100 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigOverridesPriorityTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Language\Language;
use Drupal\simpletest\KernelTestBase;
/**
* Tests that language, module and settings.php are applied in the correct
* order.
*
* @group config
*/
class ConfigOverridesPriorityTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('system', 'config', 'config_override_test', 'language');
public function testOverridePriorities() {
$GLOBALS['config_test_run_module_overrides'] = FALSE;
$non_overridden_mail = 'site@example.com';
$language_overridden_mail = 'french@example.com';
$language_overridden_name = 'French site name';
$module_overridden_name = 'ZOMG overridden site name';
$non_overridden_name = 'ZOMG this name is on disk mkay';
$module_overridden_slogan = 'Yay for overrides!';
$non_overridden_slogan = 'Yay for defaults!';
/** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */
$config_factory = $this->container->get('config.factory');
$config_factory
->getEditable('system.site')
->set('name', $non_overridden_name)
->set('slogan', $non_overridden_slogan)
->set('mail', $non_overridden_mail)
->set('weight_select_max', 50)
->save();
// Ensure that no overrides are applying.
$this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($non_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
// Override using language.
$language = new Language(array(
'name' => 'French',
'id' => 'fr',
));
\Drupal::languageManager()->setConfigOverrideLanguage($language);
\Drupal::languageManager()
->getLanguageConfigOverride($language->getId(), 'system.site')
->set('name', $language_overridden_name)
->set('mail', $language_overridden_mail)
->save();
$this->assertEqual($language_overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
// Enable module overrides. Do not override system.site:mail to prove that
// the language override still applies.
$GLOBALS['config_test_run_module_overrides'] = TRUE;
$config_factory->reset('system.site');
$this->assertEqual($module_overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($module_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
// Configure a global override to simulate overriding using settings.php. Do
// not override system.site:mail or system.site:slogan to prove that the
// language and module overrides still apply.
$GLOBALS['config']['system.site']['name'] = 'Site name global conf override';
$config_factory->reset('system.site');
$this->assertEqual('Site name global conf override', $config_factory->get('system.site')->get('name'));
$this->assertEqual($module_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
$this->assertEqual($non_overridden_name, $config_factory->get('system.site')->getOriginal('name', FALSE));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->getOriginal('slogan', FALSE));
$this->assertEqual($non_overridden_mail, $config_factory->get('system.site')->getOriginal('mail', FALSE));
$this->assertEqual(50, $config_factory->get('system.site')->getOriginal('weight_select_max', FALSE));
unset($GLOBALS['config_test_run_module_overrides']);
}
}

View file

@ -1,575 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigSchemaTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\Schema\ConfigSchemaAlterException;
use Drupal\Core\TypedData\Type\IntegerInterface;
use Drupal\Core\TypedData\Type\StringInterface;
use Drupal\simpletest\KernelTestBase;
/**
* Tests schema for configuration objects.
*
* @group config
*/
class ConfigSchemaTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system', 'language', 'field', 'image', 'config_test', 'config_schema_test');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(array('system', 'image', 'config_schema_test'));
}
/**
* Tests the basic metadata retrieval layer.
*/
function testSchemaMapping() {
// Nonexistent configuration key will have Undefined as metadata.
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
$expected = array();
$expected['label'] = 'Undefined';
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
// Configuration file without schema will return Undefined as well.
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema');
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.');
// Configuration file with only some schema.
$this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'));
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema');
$expected = array();
$expected['label'] = 'Schema test data';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['mapping']['testitem'] = array('label' => 'Test item');
$expected['mapping']['testlist'] = array('label' => 'Test list');
$expected['type'] = 'config_schema_test.someschema';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.');
// Check type detection on elements with undefined types.
$config = \Drupal::service('config.typed')->get('config_schema_test.someschema');
$definition = $config->get('testitem')->getDataDefinition()->toArray();
$expected = array();
$expected['label'] = 'Test item';
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
$definition = $config->get('testlist')->getDataDefinition()->toArray();
$expected = array();
$expected['label'] = 'Test list';
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
$definition = $config->get('testnoschema')->getDataDefinition()->toArray();
$expected = array();
$expected['label'] = 'Undefined';
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.');
// Simple case, straight metadata.
$definition = \Drupal::service('config.typed')->getDefinition('system.maintenance');
$expected = array();
$expected['label'] = 'Maintenance mode';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['mapping']['message'] = array(
'label' => 'Message to display when in maintenance mode',
'type' => 'text',
);
$expected['mapping']['langcode'] = array(
'label' => 'Language code',
'type' => 'string',
);
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['type'] = 'system.maintenance';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
// Mixed schema with ignore elements.
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.ignore');
$expected = array();
$expected['label'] = 'Ignore test';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['mapping']['langcode'] = array(
'type' => 'string',
'label' => 'Language code',
);
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['mapping']['label'] = array(
'label' => 'Label',
'type' => 'label',
);
$expected['mapping']['irrelevant'] = array(
'label' => 'Irrelevant',
'type' => 'ignore',
);
$expected['mapping']['indescribable'] = array(
'label' => 'Indescribable',
'type' => 'ignore',
);
$expected['mapping']['weight'] = array(
'label' => 'Weight',
'type' => 'integer',
);
$expected['type'] = 'config_schema_test.ignore';
$this->assertEqual($definition, $expected);
// The ignore elements themselves.
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('irrelevant')->getDataDefinition()->toArray();
$expected = array();
$expected['type'] = 'ignore';
$expected['label'] = 'Irrelevant';
$expected['class'] = '\Drupal\Core\Config\Schema\Ignore';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$this->assertEqual($definition, $expected);
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray();
$expected['label'] = 'Indescribable';
$this->assertEqual($definition, $expected);
// More complex case, generic type. Metadata for image style.
$definition = \Drupal::service('config.typed')->getDefinition('image.style.large');
$expected = array();
$expected['label'] = 'Image style';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['mapping']['name']['type'] = 'string';
$expected['mapping']['uuid']['type'] = 'string';
$expected['mapping']['uuid']['label'] = 'UUID';
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
$expected['mapping']['status']['type'] = 'boolean';
$expected['mapping']['status']['label'] = 'Status';
$expected['mapping']['dependencies']['type'] = 'config_dependencies';
$expected['mapping']['dependencies']['label'] = 'Dependencies';
$expected['mapping']['name']['type'] = 'string';
$expected['mapping']['label']['type'] = 'label';
$expected['mapping']['label']['label'] = 'Label';
$expected['mapping']['effects']['type'] = 'sequence';
$expected['mapping']['effects']['sequence']['type'] = 'mapping';
$expected['mapping']['effects']['sequence']['mapping']['id']['type'] = 'string';
$expected['mapping']['effects']['sequence']['mapping']['data']['type'] = 'image.effect.[%parent.id]';
$expected['mapping']['effects']['sequence']['mapping']['weight']['type'] = 'integer';
$expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'string';
$expected['mapping']['third_party_settings']['type'] = 'sequence';
$expected['mapping']['third_party_settings']['label'] = 'Third party settings';
$expected['mapping']['third_party_settings']['sequence']['type'] = '[%parent.%parent.%type].third_party.[%key]';
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['type'] = 'image.style.*';
$this->assertEqual($definition, $expected);
// More complex, type based on a complex one.
$definition = \Drupal::service('config.typed')->getDefinition('image.effect.image_scale');
// This should be the schema for image.effect.image_scale.
$expected = array();
$expected['label'] = 'Image scale';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['mapping']['width']['type'] = 'integer';
$expected['mapping']['width']['label'] = 'Width';
$expected['mapping']['height']['type'] = 'integer';
$expected['mapping']['height']['label'] = 'Height';
$expected['mapping']['upscale']['type'] = 'boolean';
$expected['mapping']['upscale']['label'] = 'Upscale';
$expected['type'] = 'image.effect.image_scale';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for image.effect.image_scale');
// Most complex case, get metadata for actual configuration element.
$effects = \Drupal::service('config.typed')->get('image.style.medium')->get('effects');
$definition = $effects->get('bddf0d06-42f9-4c75-a700-a33cafa25ea0')->get('data')->getDataDefinition()->toArray();
// This should be the schema for image.effect.image_scale, reuse previous one.
$expected['type'] = 'image.effect.image_scale';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium');
$a = \Drupal::config('config_test.dynamic.third_party');
$test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test');
$definition = $test->getDataDefinition()->toArray();
$expected = array();
$expected['type'] = 'config_test.dynamic.*.third_party.config_schema_test';
$expected['label'] = 'Mapping';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['mapping'] = [
'integer' => ['type' => 'integer'],
'string' => ['type' => 'string'],
];
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.dynamic.third_party:third_party_settings.config_schema_test');
// More complex, several level deep test.
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection');
// This should be the schema of config_schema_test.someschema.somemodule.*.*.
$expected = array();
$expected['label'] = 'Schema multiple filesystem marker test';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['mapping']['testid']['type'] = 'string';
$expected['mapping']['testid']['label'] = 'ID';
$expected['mapping']['testdescription']['type'] = 'text';
$expected['mapping']['testdescription']['label'] = 'Description';
$expected['type'] = 'config_schema_test.someschema.somemodule.*.*';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection');
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_two.subsection');
// The other file should have the same schema.
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_two.subsection');
}
/**
* Tests metadata retrieval with several levels of %parent indirection.
*/
function testSchemaMappingWithParents() {
$config_data = \Drupal::service('config.typed')->get('config_schema_test.someschema.with_parents');
// Test fetching parent one level up.
$entry = $config_data->get('one_level');
$definition = $entry->get('testitem')->getDataDefinition()->toArray();
$expected = array(
'type' => 'config_schema_test.someschema.with_parents.key_1',
'label' => 'Test item nested one level',
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
);
$this->assertEqual($definition, $expected);
// Test fetching parent two levels up.
$entry = $config_data->get('two_levels');
$definition = $entry->get('wrapper')->get('testitem')->getDataDefinition()->toArray();
$expected = array(
'type' => 'config_schema_test.someschema.with_parents.key_2',
'label' => 'Test item nested two levels',
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
);
$this->assertEqual($definition, $expected);
// Test fetching parent three levels up.
$entry = $config_data->get('three_levels');
$definition = $entry->get('wrapper_1')->get('wrapper_2')->get('testitem')->getDataDefinition()->toArray();
$expected = array(
'type' => 'config_schema_test.someschema.with_parents.key_3',
'label' => 'Test item nested three levels',
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
);
$this->assertEqual($definition, $expected);
}
/**
* Tests metadata applied to configuration objects.
*/
function testSchemaData() {
// Try a simple property.
$meta = \Drupal::service('config.typed')->get('system.site');
$property = $meta->get('page')->get('front');
$this->assertTrue($property instanceof StringInterface, 'Got the right wrapper fo the page.front property.');
$this->assertEqual($property->getValue(), '/user/login', 'Got the right value for page.front data.');
$definition = $property->getDataDefinition();
$this->assertTrue(empty($definition['translatable']), 'Got the right translatability setting for page.front data.');
// Check nested array of properties.
$list = $meta->get('page')->getElements();
$this->assertEqual(count($list), 3, 'Got a list with the right number of properties for site page data');
$this->assertTrue(isset($list['front']) && isset($list['403']) && isset($list['404']), 'Got a list with the right properties for site page data.');
$this->assertEqual($list['front']->getValue(), '/user/login', 'Got the right value for page.front data from the list.');
// And test some TypedConfigInterface methods.
$properties = $list;
$this->assertTrue(count($properties) == 3 && $properties['front'] == $list['front'], 'Got the right properties for site page.');
$values = $meta->get('page')->toArray();
$this->assertTrue(count($values) == 3 && $values['front'] == '/user/login', 'Got the right property values for site page.');
// Now let's try something more complex, with nested objects.
$wrapper = \Drupal::service('config.typed')->get('image.style.large');
$effects = $wrapper->get('effects');
$this->assertTrue(count($effects->toArray()) == 1, 'Got an array with effects for image.style.large data');
$uuid = key($effects->getValue());
$effect = $effects->get($uuid)->getElements();
$this->assertTrue(!$effect['data']->isEmpty() && $effect['id']->getValue() == 'image_scale', 'Got data for the image scale effect from metadata.');
$this->assertTrue($effect['data']->get('width') instanceof IntegerInterface, 'Got the right type for the scale effect width.');
$this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.' );
}
/**
* Test configuration value data type enforcement using schemas.
*/
public function testConfigSaveWithSchema() {
$untyped_values = array(
'string' => 1,
'empty_string' => '',
'null_string' => NULL,
'integer' => '100',
'null_integer' => '',
'boolean' => 1,
// If the config schema doesn't have a type it shouldn't be casted.
'no_type' => 1,
'mapping' => array(
'string' => 1
),
'float' => '3.14',
'null_float' => '',
'sequence' => array (1, 0, 1),
'sequence_bc' => array(1, 0, 1),
// Not in schema and therefore should be left untouched.
'not_present_in_schema' => TRUE,
// Test a custom type.
'config_schema_test_integer' => '1',
'config_schema_test_integer_empty_string' => '',
);
$untyped_to_typed = $untyped_values;
$typed_values = array(
'string' => '1',
'empty_string' => '',
'null_string' => NULL,
'integer' => 100,
'null_integer' => NULL,
'boolean' => TRUE,
'no_type' => 1,
'mapping' => array(
'string' => '1'
),
'float' => 3.14,
'null_float' => NULL,
'sequence' => array (TRUE, FALSE, TRUE),
'sequence_bc' => array(TRUE, FALSE, TRUE),
'not_present_in_schema' => TRUE,
'config_schema_test_integer' => 1,
'config_schema_test_integer_empty_string' => NULL,
);
// Save config which has a schema that enforces types.
$this->config('config_schema_test.schema_data_types')
->setData($untyped_to_typed)
->save();
$this->assertIdentical($this->config('config_schema_test.schema_data_types')->get(), $typed_values);
// Save config which does not have a schema that enforces types.
$this->config('config_schema_test.no_schema_data_types')
->setData($untyped_values)
->save();
$this->assertIdentical($this->config('config_schema_test.no_schema_data_types')->get(), $untyped_values);
// Ensure that configuration objects with keys marked as ignored are not
// changed when saved. The 'config_schema_test.ignore' will have been saved
// during the installation of configuration in the setUp method.
$extension_path = drupal_get_path('module', 'config_schema_test');
$install_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY);
$original_data = $install_storage->read('config_schema_test.ignore');
$installed_data = $this->config('config_schema_test.ignore')->get();
unset($installed_data['_core']);
$this->assertIdentical($installed_data, $original_data);
}
/**
* Tests fallback to a greedy wildcard.
*/
function testSchemaFallback() {
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something');
// This should be the schema of config_schema_test.wildcard_fallback.*.
$expected = array();
$expected['label'] = 'Schema wildcard fallback test';
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['mapping']['testid']['type'] = 'string';
$expected['mapping']['testid']['label'] = 'ID';
$expected['mapping']['testdescription']['type'] = 'text';
$expected['mapping']['testdescription']['label'] = 'Description';
$expected['type'] = 'config_schema_test.wildcard_fallback.*';
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.wildcard_fallback.something');
$definition2 = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something.something');
// This should be the schema of config_schema_test.wildcard_fallback.* as
//well.
$this->assertIdentical($definition, $definition2);
}
/**
* Tests use of colons in schema type determination.
*
* @see \Drupal\Core\Config\TypedConfigManager::getFallbackName()
*/
function testColonsInSchemaTypeDetermination() {
$tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('tests')->getElements();
$definition = $tests[0]->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test.plugin_types.boolean');
$definition = $tests[1]->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test.plugin_types.boolean:*');
$definition = $tests[2]->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test.plugin_types.*');
$definition = $tests[3]->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test.plugin_types.*');
$tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('test_with_parents')->getElements();
$definition = $tests[0]->get('settings')->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test_with_parents.plugin_types.boolean');
$definition = $tests[1]->get('settings')->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test_with_parents.plugin_types.boolean:*');
$definition = $tests[2]->get('settings')->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test_with_parents.plugin_types.*');
$definition = $tests[3]->get('settings')->getDataDefinition()->toArray();
$this->assertEqual($definition['type'], 'test_with_parents.plugin_types.*');
}
/**
* Tests hook_config_schema_info_alter().
*/
public function testConfigSchemaInfoAlter() {
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
$typed_config = \Drupal::service('config.typed');
$typed_config->clearCachedDefinitions();
// Ensure that keys can not be added or removed by
// hook_config_schema_info_alter().
\Drupal::state()->set('config_schema_test_exception_remove', TRUE);
$message = 'Expected ConfigSchemaAlterException thrown.';
try {
$typed_config->getDefinitions();
$this->fail($message);
}
catch (ConfigSchemaAlterException $e) {
$this->pass($message);
$this->assertEqual($e->getMessage(), 'Invoking hook_config_schema_info_alter() has removed (config_schema_test.hook) schema definitions');
}
\Drupal::state()->set('config_schema_test_exception_add', TRUE);
$message = 'Expected ConfigSchemaAlterException thrown.';
try {
$typed_config->getDefinitions();
$this->fail($message);
}
catch (ConfigSchemaAlterException $e) {
$this->pass($message);
$this->assertEqual($e->getMessage(), 'Invoking hook_config_schema_info_alter() has added (config_schema_test.hook_added_defintion) and removed (config_schema_test.hook) schema definitions');
}
\Drupal::state()->set('config_schema_test_exception_remove', FALSE);
$message = 'Expected ConfigSchemaAlterException thrown.';
try {
$typed_config->getDefinitions();
$this->fail($message);
}
catch (ConfigSchemaAlterException $e) {
$this->pass($message);
$this->assertEqual($e->getMessage(), 'Invoking hook_config_schema_info_alter() has added (config_schema_test.hook_added_defintion) schema definitions');
}
// Tests that hook_config_schema_info_alter() can add additional metadata to
// existing configuration schema.
\Drupal::state()->set('config_schema_test_exception_add', FALSE);
$definitions = $typed_config->getDefinitions();
$this->assertEqual($definitions['config_schema_test.hook']['additional_metadata'], 'new schema info');
}
/**
* Tests saving config when the type is wrapped by a dynamic type.
*/
public function testConfigSaveWithWrappingSchema() {
$untyped_values = [
'tests' => [
[
'wrapper_value' => 'foo',
'plugin_id' => 'wrapper:foo',
'internal_value' => 100,
],
],
];
$typed_values = [
'tests' => [
[
'wrapper_value' => 'foo',
'plugin_id' => 'wrapper:foo',
'internal_value' => '100',
],
],
];
// Save config which has a schema that enforces types.
\Drupal::configFactory()->getEditable('wrapping.config_schema_test.plugin_types')
->setData($untyped_values)
->save();
$this->assertIdentical(\Drupal::config('wrapping.config_schema_test.plugin_types')
->get(), $typed_values);
}
/**
* Tests dynamic config schema type with multiple sub-key references.
*/
public function testConfigSaveWithWrappingSchemaDoubleBrackets() {
$untyped_values = [
'tests' => [
[
'wrapper_value' => 'foo',
'foo' => 'cat',
'bar' => 'dog',
'another_key' => 100,
],
],
];
$typed_values = [
'tests' => [
[
'wrapper_value' => 'foo',
'foo' => 'cat',
'bar' => 'dog',
'another_key' => '100',
],
],
];
// Save config which has a schema that enforces types.
\Drupal::configFactory()->getEditable('wrapping.config_schema_test.double_brackets')
->setData($untyped_values)
->save();
$this->assertIdentical(\Drupal::config('wrapping.config_schema_test.double_brackets')
->get(), $typed_values);
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigSingleImportExportTest.
*/
namespace Drupal\config\Tests;
use Drupal\Component\Serialization\Yaml;

View file

@ -1,91 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\ConfigSnapshotTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\StorageComparer;
use Drupal\simpletest\KernelTestBase;
/**
* Tests config snapshot creation and updating.
*
* @group config
*/
class ConfigSnapshotTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test', 'system');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Update the config snapshot. This allows the parent::setUp() to write
// configuration files.
\Drupal::service('config.manager')->createSnapshot(\Drupal::service('config.storage'), \Drupal::service('config.storage.snapshot'));
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
}
/**
* Tests config snapshot creation and updating.
*/
function testSnapshot() {
$active = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$snapshot = $this->container->get('config.storage.snapshot');
$config_manager = $this->container->get('config.manager');
$config_name = 'config_test.system';
$config_key = 'foo';
$new_data = 'foobar';
$active_snapshot_comparer = new StorageComparer($active, $snapshot, $config_manager);
$sync_snapshot_comparer = new StorageComparer($sync, $snapshot, $config_manager);
// Verify that we have an initial snapshot that matches the active
// configuration. This has to be true as no config should be installed.
$this->assertFalse($active_snapshot_comparer->createChangelist()->hasChanges());
// Install the default config.
$this->installConfig(array('config_test'));
// Although we have imported config this has not affected the snapshot.
$this->assertTrue($active_snapshot_comparer->reset()->hasChanges());
// Update the config snapshot.
\Drupal::service('config.manager')->createSnapshot($active, $snapshot);
// The snapshot and active config should now contain the same config
// objects.
$this->assertFalse($active_snapshot_comparer->reset()->hasChanges());
// Change a configuration value in sync.
$sync_data = $this->config($config_name)->get();
$sync_data[$config_key] = $new_data;
$sync->write($config_name, $sync_data);
// Verify that active and snapshot match, and that sync doesn't match
// active.
$this->assertFalse($active_snapshot_comparer->reset()->hasChanges());
$this->assertTrue($sync_snapshot_comparer->createChangelist()->hasChanges());
// Import changed data from sync to active.
$this->configImporter()->import();
// Verify changed config was properly imported.
\Drupal::configFactory()->reset($config_name);
$this->assertIdentical($this->config($config_name)->get($config_key), $new_data);
// Verify that a new snapshot was created which and that it matches
// the active config.
$this->assertFalse($active_snapshot_comparer->reset()->hasChanges());
}
}

View file

@ -1,84 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\DefaultConfigTest.
*/
namespace Drupal\config\Tests;
use Drupal\config_test\TestInstallStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\simpletest\KernelTestBase;
use Symfony\Component\DependencyInjection\Reference;
/**
* Tests that default configuration provided by all modules matches schema.
*
* @group config
*/
class DefaultConfigTest extends KernelTestBase {
use SchemaCheckTestTrait;
/**
* Modules to enable.
*
* Enable the system module so that system_config_schema_info_alter() fires.
*
* @var array
*/
public static $modules = array('system', 'config_test');
/**
* Themes which provide default configuration and need enabling.
*
* If a theme provides default configuration but does not have a schema
* because it can rely on schemas added by system_config_schema_info_alter()
* then this test needs to enable it.
*
* @var array
*/
protected $themes = ['seven'];
protected function setUp() {
parent::setUp();
\Drupal::service('theme_handler')->install($this->themes);
}
/**
* {@inheritdoc}
*/
public function containerBuild(ContainerBuilder $container) {
parent::containerBuild($container);
$container->register('default_config_test.schema_storage')
->setClass('\Drupal\config_test\TestInstallStorage')
->addArgument(InstallStorage::CONFIG_SCHEMA_DIRECTORY);
$definition = $container->getDefinition('config.typed');
$definition->replaceArgument(1, new Reference('default_config_test.schema_storage'));
}
/**
* Tests default configuration data type.
*/
public function testDefaultConfig() {
$typed_config = \Drupal::service('config.typed');
// Create a configuration storage with access to default configuration in
// every module, profile and theme.
$default_config_storage = new TestInstallStorage();
foreach ($default_config_storage->listAll() as $config_name) {
// Skip files provided by the config_schema_test module since that module
// is explicitly for testing schema.
if (strpos($config_name, 'config_schema_test') === 0) {
continue;
}
$data = $default_config_storage->read($config_name);
$this->assertConfigSchema($typed_config, $config_name, $data);
}
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\LanguageNegotiationFormOverrideTest.
*/
namespace Drupal\config\Tests;
use Drupal\simpletest\WebTestBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\SchemaCheckTestTrait.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\TypedConfigManagerInterface;

View file

@ -1,72 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\SchemaCheckTraitTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the functionality of SchemaCheckTrait.
*
* @group config
*/
class SchemaCheckTraitTest extends KernelTestBase {
use SchemaCheckTrait;
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfig;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('config_test', 'config_schema_test');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(array('config_test', 'config_schema_test'));
$this->typedConfig = \Drupal::service('config.typed');
}
/**
* Tests \Drupal\Core\Config\Schema\SchemaCheckTrait.
*/
public function testTrait() {
// Test a non existing schema.
$ret = $this->checkConfigSchema($this->typedConfig, 'config_schema_test.noschema', $this->config('config_schema_test.noschema')->get());
$this->assertIdentical($ret, FALSE);
// Test an existing schema with valid data.
$config_data = $this->config('config_test.types')->get();
$ret = $this->checkConfigSchema($this->typedConfig, 'config_test.types', $config_data);
$this->assertIdentical($ret, TRUE);
// Add a new key, a new array and overwrite boolean with array to test the
// error messages.
$config_data = array('new_key' => 'new_value', 'new_array' => array()) + $config_data;
$config_data['boolean'] = array();
$ret = $this->checkConfigSchema($this->typedConfig, 'config_test.types', $config_data);
$expected = array(
'config_test.types:new_key' => 'missing schema',
'config_test.types:new_array' => 'missing schema',
'config_test.types:boolean' => 'non-scalar value but not defined as an array (such as mapping or sequence)',
);
$this->assertEqual($ret, $expected);
}
}

View file

@ -1,66 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\SchemaConfigListenerTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Schema\SchemaIncompleteException;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the functionality of ConfigSchemaChecker in KernelTestBase tests.
*
* @group config
*/
class SchemaConfigListenerTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('config_test');
/**
* Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker.
*/
public function testConfigSchemaChecker() {
// Test a non-existing schema.
$message = 'Expected SchemaIncompleteException thrown';
try {
$this->config('config_schema_test.schemaless')->set('foo', 'bar')->save();
$this->fail($message);
}
catch (SchemaIncompleteException $e) {
$this->pass($message);
$this->assertEqual('No schema for config_schema_test.schemaless', $e->getMessage());
}
// Test a valid schema.
$message = 'Unexpected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')->set('int', 10);
try {
$config->save();
$this->pass($message);
}
catch (SchemaIncompleteException $e) {
$this->fail($message);
}
// Test an invalid schema.
$message = 'Expected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')
->set('foo', 'bar')
->set('array', 1);
try {
$config->save();
$this->fail($message);
}
catch (SchemaIncompleteException $e) {
$this->pass($message);
$this->assertEqual('Schema errors for config_test.types with the following errors: config_test.types:foo missing schema, config_test.types:array variable type is integer but applied schema class is Drupal\Core\Config\Schema\Sequence', $e->getMessage());
}
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\SchemaConfigListenerWebTest.
*/
namespace Drupal\config\Tests;
use Drupal\Core\Config\Schema\SchemaIncompleteException;

View file

@ -1,99 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\Storage\CachedStorageTest.
*/
namespace Drupal\config\Tests\Storage;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Tests CachedStorage operations.
*
* @group config
*/
class CachedStorageTest extends ConfigStorageTestBase {
/**
* The cache backend the cached storage is using.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The file storage the cached storage is using.
*
* @var \Drupal\Core\Config\FileStorage
*/
protected $fileStorage;
protected function setUp() {
parent::setUp();
// Create a directory.
$dir = $this->publicFilesDirectory . '/config';
mkdir($dir);
$this->fileStorage = new FileStorage($dir);
$this->storage = new CachedStorage($this->fileStorage, \Drupal::service('cache.config'));
$this->cache = \Drupal::service('cache_factory')->get('config');
// ::listAll() verifications require other configuration data to exist.
$this->storage->write('system.performance', array());
}
/**
* {@inheritdoc}
*/
public function testInvalidStorage() {
// No-op as this test does not make sense.
}
/**
* {@inheritdoc}
*/
protected function read($name) {
$data = $this->cache->get($name);
// Cache misses fall through to the underlying storage.
return $data ? $data->data : $this->fileStorage->read($name);
}
/**
* {@inheritdoc}
*/
protected function insert($name, $data) {
$this->fileStorage->write($name, $data);
$this->cache->set($name, $data);
}
/**
* {@inheritdoc}
*/
protected function update($name, $data) {
$this->fileStorage->write($name, $data);
$this->cache->set($name, $data);
}
/**
* {@inheritdoc}
*/
protected function delete($name) {
$this->cache->delete($name);
unlink($this->fileStorage->getFilePath($name));
}
/**
* {@inheritdoc}
*/
public function containerBuild(ContainerBuilder $container) {
parent::containerBuild($container);
// Use the regular database cache backend to aid testing.
$container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory')
->addArgument(new Reference('database'))
->addArgument(new Reference('cache_tags.invalidator.checksum'));
}
}

View file

@ -1,271 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\Storage\ConfigStorageTestBase.
*/
namespace Drupal\config\Tests\Storage;
use Drupal\simpletest\KernelTestBase;
/**
* Base class for testing storage operations.
*
* All configuration storages are expected to behave identically in
* terms of reading, writing, listing, deleting, as well as error handling.
*
* Therefore, storage tests use an uncommon test case class structure;
* the base class defines the test method(s) to execute, which are identical
* for all storages. The storage specific test case classes supply the
* necessary helper methods to interact with the raw/native storage
* directly.
*/
abstract class ConfigStorageTestBase extends KernelTestBase {
/**
* @var \Drupal\Core\Config\StorageInterface
*/
protected $storage;
/**
* @var \Drupal\Core\Config\StorageInterface
*/
protected $invalidStorage;
/**
* Tests storage CRUD operations.
*
* @todo Coverage: Trigger PDOExceptions / Database exceptions.
*/
function testCRUD() {
$name = 'config_test.storage';
// Checking whether a non-existing name exists returns FALSE.
$this->assertIdentical($this->storage->exists($name), FALSE);
// Reading a non-existing name returns FALSE.
$data = $this->storage->read($name);
$this->assertIdentical($data, FALSE);
// Writing data returns TRUE and the data has been written.
$data = array('foo' => 'bar');
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$raw_data = $this->read($name);
$this->assertIdentical($raw_data, $data);
// Checking whether an existing name exists returns TRUE.
$this->assertIdentical($this->storage->exists($name), TRUE);
// Writing the identical data again still returns TRUE.
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
// Listing all names returns all.
$names = $this->storage->listAll();
$this->assertTrue(in_array('system.performance', $names));
$this->assertTrue(in_array($name, $names));
// Listing all names with prefix returns names with that prefix only.
$names = $this->storage->listAll('config_test.');
$this->assertFalse(in_array('system.performance', $names));
$this->assertTrue(in_array($name, $names));
// Rename the configuration storage object.
$new_name = 'config_test.storage_rename';
$this->storage->rename($name, $new_name);
$raw_data = $this->read($new_name);
$this->assertIdentical($raw_data, $data);
// Rename it back so further tests work.
$this->storage->rename($new_name, $name);
// Deleting an existing name returns TRUE.
$result = $this->storage->delete($name);
$this->assertIdentical($result, TRUE);
// Deleting a non-existing name returns FALSE.
$result = $this->storage->delete($name);
$this->assertIdentical($result, FALSE);
// Deleting all names with prefix deletes the appropriate data and returns
// TRUE.
$files = array(
'config_test.test.biff',
'config_test.test.bang',
'config_test.test.pow',
);
foreach ($files as $name) {
$this->storage->write($name, $data);
}
$result = $this->storage->deleteAll('config_test.');
$names = $this->storage->listAll('config_test.');
$this->assertIdentical($result, TRUE);
$this->assertIdentical($names, array());
// Test renaming an object that does not exist throws an exception.
try {
$this->storage->rename('config_test.storage_does_not_exist', 'config_test.storage_does_not_exist_rename');
}
catch (\Exception $e) {
$class = get_class($e);
$this->pass($class . ' thrown upon renaming a nonexistent storage bin.');
}
// Test renaming to an object that already exists throws an exception.
try {
$this->storage->rename('system.cron', 'system.performance');
}
catch (\Exception $e) {
$class = get_class($e);
$this->pass($class . ' thrown upon renaming a nonexistent storage bin.');
}
}
/**
* Tests an invalid storage.
*/
public function testInvalidStorage() {
$name = 'config_test.storage';
// Write something to the valid storage to prove that the storages do not
// pollute one another.
$data = array('foo' => 'bar');
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$raw_data = $this->read($name);
$this->assertIdentical($raw_data, $data);
// Reading from a non-existing storage bin returns FALSE.
$result = $this->invalidStorage->read($name);
$this->assertIdentical($result, FALSE);
// Deleting from a non-existing storage bin throws an exception.
try {
$this->invalidStorage->delete($name);
$this->fail('Exception not thrown upon deleting from a non-existing storage bin.');
}
catch (\Exception $e) {
$class = get_class($e);
$this->pass($class . ' thrown upon deleting from a non-existing storage bin.');
}
// Listing on a non-existing storage bin returns an empty array.
$result = $this->invalidStorage->listAll();
$this->assertIdentical($result, array());
// Writing to a non-existing storage bin creates the bin.
$this->invalidStorage->write($name, array('foo' => 'bar'));
$result = $this->invalidStorage->read($name);
$this->assertIdentical($result, array('foo' => 'bar'));
}
/**
* Tests storage writing and reading data preserving data type.
*/
function testDataTypes() {
$name = 'config_test.types';
$data = array(
'array' => array(),
'boolean' => TRUE,
'exp' => 1.2e+34,
'float' => 3.14159,
'hex' => 0xC,
'int' => 99,
'octal' => 0775,
'string' => 'string',
'string_int' => '1',
);
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$read_data = $this->storage->read($name);
$this->assertIdentical($read_data, $data);
}
/**
* Tests that the storage supports collections.
*/
public function testCollection() {
$name = 'config_test.storage';
$data = array('foo' => 'bar');
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($data, $this->storage->read($name));
// Create configuration in a new collection.
$new_storage = $this->storage->createCollection('collection.sub.new');
$this->assertFalse($new_storage->exists($name));
$this->assertEqual(array(), $new_storage->listAll());
$new_storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($data, $new_storage->read($name));
$this->assertEqual(array($name), $new_storage->listAll());
$this->assertTrue($new_storage->exists($name));
$new_data = array('foo' => 'baz');
$new_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $new_storage->read($name));
// Create configuration in another collection.
$another_storage = $this->storage->createCollection('collection.sub.another');
$this->assertFalse($another_storage->exists($name));
$this->assertEqual(array(), $another_storage->listAll());
$another_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $another_storage->read($name));
$this->assertEqual(array($name), $another_storage->listAll());
$this->assertTrue($another_storage->exists($name));
// Create configuration in yet another collection.
$alt_storage = $this->storage->createCollection('alternate');
$alt_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $alt_storage->read($name));
// Switch back to the collection-less mode and check the data still exists
// add has not been touched.
$this->assertIdentical($data, $this->storage->read($name));
// Check that the getAllCollectionNames() method works.
$this->assertIdentical(array('alternate', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
// Check that the collections are removed when they are empty.
$alt_storage->delete($name);
$this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
// Create configuration in collection called 'collection'. This ensures that
// FileStorage's collection storage works regardless of its use of
// subdirectories.
$parent_storage = $this->storage->createCollection('collection');
$this->assertFalse($parent_storage->exists($name));
$this->assertEqual(array(), $parent_storage->listAll());
$parent_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $parent_storage->read($name));
$this->assertEqual(array($name), $parent_storage->listAll());
$this->assertTrue($parent_storage->exists($name));
$this->assertIdentical(array('collection', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
$parent_storage->deleteAll();
$this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
// Check that the having an empty collection-less storage does not break
// anything. Before deleting check that the previous delete did not affect
// data in another collection.
$this->assertIdentical($data, $this->storage->read($name));
$this->storage->delete($name);
$this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
}
abstract protected function read($name);
abstract protected function insert($name, $data);
abstract protected function update($name, $data);
abstract protected function delete($name);
}

View file

@ -1,48 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\Storage\DatabaseStorageTest.
*/
namespace Drupal\config\Tests\Storage;
use Drupal\Core\Config\DatabaseStorage;
/**
* Tests DatabaseStorage operations.
*
* @group config
*/
class DatabaseStorageTest extends ConfigStorageTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->storage = new DatabaseStorage($this->container->get('database'), 'config');
$this->invalidStorage = new DatabaseStorage($this->container->get('database'), 'invalid');
// ::listAll() verifications require other configuration data to exist.
$this->storage->write('system.performance', array());
}
protected function read($name) {
$data = db_query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name))->fetchField();
return unserialize($data);
}
protected function insert($name, $data) {
db_insert('config')->fields(array('name' => $name, 'data' => $data))->execute();
}
protected function update($name, $data) {
db_update('config')->fields(array('data' => $data))->condition('name', $name)->execute();
}
protected function delete($name) {
db_delete('config')->condition('name', $name)->execute();
}
}

View file

@ -1,101 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\config\Tests\Storage\FileStorageTest.
*/
namespace Drupal\config\Tests\Storage;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\UnsupportedDataTypeConfigException;
/**
* Tests FileStorage operations.
*
* @group config
*/
class FileStorageTest extends ConfigStorageTestBase {
/**
* A directory to store configuration in.
*
* @var string
*/
protected $directory;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create a directory.
$this->directory = $this->publicFilesDirectory . '/config';
mkdir($this->directory);
$this->storage = new FileStorage($this->directory);
$this->invalidStorage = new FileStorage($this->directory . '/nonexisting');
// FileStorage::listAll() requires other configuration data to exist.
$this->storage->write('system.performance', $this->config('system.performance')->get());
$this->storage->write('core.extension', array('module' => array()));
}
protected function read($name) {
$data = file_get_contents($this->storage->getFilePath($name));
return Yaml::decode($data);
}
protected function insert($name, $data) {
file_put_contents($this->storage->getFilePath($name), $data);
}
protected function update($name, $data) {
file_put_contents($this->storage->getFilePath($name), $data);
}
protected function delete($name) {
unlink($this->storage->getFilePath($name));
}
/**
* Tests the FileStorage::listAll method with a relative and absolute path.
*/
public function testlistAll() {
$expected_files = array(
'core.extension',
'system.performance',
);
$config_files = $this->storage->listAll();
$this->assertIdentical($config_files, $expected_files, 'Relative path, two config files found.');
// @todo https://www.drupal.org/node/2666954 FileStorage::listAll() is
// case-sensitive. However, \Drupal\Core\Config\DatabaseStorage::listAll()
// is case-insensitive.
$this->assertIdentical(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.');
$this->assertIdentical([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.');
// Initialize FileStorage with absolute file path.
$absolute_path = realpath($this->directory);
$storage_absolute_path = new FileStorage($absolute_path);
$config_files = $storage_absolute_path->listAll();
$this->assertIdentical($config_files, $expected_files, 'Absolute path, two config files found.');
}
/**
* Test UnsupportedDataTypeConfigException displays path of
* erroneous file during read.
*/
public function testReadUnsupportedDataTypeConfigException() {
file_put_contents($this->storage->getFilePath('core.extension'), PHP_EOL . 'foo : [bar}', FILE_APPEND);
try {
$config_parsed = $this->storage->read('core.extension');
}
catch (UnsupportedDataTypeConfigException $e) {
$this->pass('Exception thrown when trying to read a field containing invalid data type.');
$this->assertTrue((strpos($e->getMessage(), $this->storage->getFilePath('core.extension')) !== FALSE), 'Erroneous file path is displayed.');
}
}
}

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_collection_install_test\EventSubscriber.
*/
namespace Drupal\config_collection_install_test;
use Drupal\Core\Config\ConfigCollectionInfo;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_entity_static_cache_test\ConfigOverrider.
*/
namespace Drupal\config_entity_static_cache_test;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_events_test\EventSubscriber.
*/
namespace Drupal\config_events_test;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_import_test\EventSubscriber.
*/
namespace Drupal\config_import_test;
use Drupal\Core\Config\ConfigCrudEvent;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_integration_test\Cache\ConfigOverrideIntegrationTestCacheContext.
*/
namespace Drupal\config_override_integration_test\Cache;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_integration_test\CacheabilityMetadataConfigOverride.
*/
namespace Drupal\config_override_integration_test;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_test\Cache\PirateDayCacheContext.
*/
namespace Drupal\config_override_test\Cache;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_test\ConfigOverrider.
*/
namespace Drupal\config_override_test;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_test\ConfigOverriderLowPriority.
*/
namespace Drupal\config_override_test;
use Drupal\Core\Cache\CacheableMetadata;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_override_test\PirateDayCacheabilityMetadataConfigOverride.
*/
namespace Drupal\config_override_test;
use Drupal\config_override_test\Cache\PirateDayCacheContext;

View file

@ -258,5 +258,15 @@ test.double_brackets.cat.dog:
bar:
type: string
test.double_brackets.turtle.horse:
type: test.double_brackets
mapping:
another_key:
type: integer
foo:
type: string
bar:
type: string
test.double_brackets.*:
type: mapping

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestAccessControlHandler.
*/
namespace Drupal\config_test;
use Drupal\Core\Access\AccessResult;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestController.
*/
namespace Drupal\config_test;
use Drupal\Core\Controller\ControllerBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestForm.
*/
namespace Drupal\config_test;
use Drupal\Core\Entity\EntityForm;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestInterface.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\Entity\ConfigEntityInterface;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestListBuilder.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestStorage.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\Entity\ConfigEntityStorage;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\Entity\ConfigQueryTest.
*/
namespace Drupal\config_test\Entity;
/**

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\Entity\ConfigTest.
*/
namespace Drupal\config_test\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBase;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\SchemaListenerController.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\ConfigFactoryInterface;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\config_test\TestInstallStorage.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\InstallStorage;

View file

@ -1,10 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\Tests\config\Unit\Menu\ConfigLocalTasksTest.
*/
namespace Drupal\Tests\config\Unit\Menu;
use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;