Update core 8.3.0

This commit is contained in:
Rob Davies 2017-04-13 15:53:35 +01:00
parent da7a7918f8
commit cd7a898e66
6144 changed files with 132297 additions and 87747 deletions

View file

@ -33,7 +33,7 @@ class EventSubscriber implements EventSubscriberInterface {
* The configuration collection info event.
*/
public function addCollections(ConfigCollectionInfo $collection_info) {
$collections = $this->state->get('config_collection_install_test.collection_names', array());
$collections = $this->state->get('config_collection_install_test.collection_names', []);
foreach ($collections as $collection) {
$collection_info->addCollection($collection);
}
@ -42,8 +42,8 @@ class EventSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
$events[ConfigEvents::COLLECTION_INFO][] = array('addCollections');
public static function getSubscribedEvents() {
$events[ConfigEvents::COLLECTION_INFO][] = ['addCollections'];
return $events;
}

View file

@ -15,11 +15,11 @@ class ConfigOverrider implements ConfigFactoryOverrideInterface {
* {@inheritdoc}
*/
public function loadOverrides($names) {
return array(
'config_test.dynamic.test_1' => array(
return [
'config_test.dynamic.test_1' => [
'label' => 'Overridden label',
)
);
]
];
}
/**

View file

@ -37,21 +37,21 @@ class EventSubscriber implements EventSubscriberInterface {
*/
public function configEventRecorder(ConfigCrudEvent $event, $name) {
$config = $event->getConfig();
$this->state->set('config_events_test.event', array(
$this->state->set('config_events_test.event', [
'event_name' => $name,
'current_config_data' => $config->get(),
'original_config_data' => $config->getOriginal(),
'raw_config_data' => $config->getRawData()
));
]);
}
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = array('configEventRecorder');
$events[ConfigEvents::DELETE][] = array('configEventRecorder');
$events[ConfigEvents::RENAME][] = array('configEventRecorder');
public static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = ['configEventRecorder'];
$events[ConfigEvents::DELETE][] = ['configEventRecorder'];
$events[ConfigEvents::RENAME][] = ['configEventRecorder'];
return $events;
}

View file

@ -88,14 +88,14 @@ class EventSubscriber implements EventSubscriberInterface {
public function onConfigSave(ConfigCrudEvent $event) {
$config = $event->getConfig();
if ($config->getName() == 'action.settings') {
$values = $this->state->get('ConfigImportUITest.action.settings.recursion_limit', array());
$values = $this->state->get('ConfigImportUITest.action.settings.recursion_limit', []);
$values[] = $config->get('recursion_limit');
$this->state->set('ConfigImportUITest.action.settings.recursion_limit', $values);
}
if ($config->getName() == 'core.extension') {
$installed = $this->state->get('ConfigImportUITest.core.extension.modules_installed', array());
$uninstalled = $this->state->get('ConfigImportUITest.core.extension.modules_uninstalled', array());
$installed = $this->state->get('ConfigImportUITest.core.extension.modules_installed', []);
$uninstalled = $this->state->get('ConfigImportUITest.core.extension.modules_uninstalled', []);
$original = $config->getOriginal('module');
$data = $config->get('module');
$install = array_diff_key($data, $original);
@ -131,11 +131,11 @@ class EventSubscriber implements EventSubscriberInterface {
* @return array
* An array of event listener definitions.
*/
static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = array('onConfigSave', 40);
$events[ConfigEvents::DELETE][] = array('onConfigDelete', 40);
$events[ConfigEvents::IMPORT_VALIDATE] = array('onConfigImporterValidate');
$events[ConfigEvents::IMPORT_MISSING_CONTENT] = array(array('onConfigImporterMissingContentOne'), array('onConfigImporterMissingContentTwo', -100));
public static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = ['onConfigSave', 40];
$events[ConfigEvents::DELETE][] = ['onConfigDelete', 40];
$events[ConfigEvents::IMPORT_VALIDATE] = ['onConfigImporterValidate'];
$events[ConfigEvents::IMPORT_MISSING_CONTENT] = [['onConfigImporterMissingContentOne'], ['onConfigImporterMissingContentTwo', -100]];
return $events;
}

View file

@ -9,3 +9,5 @@ dependencies:
enforced:
module:
- config_other_module_config_test
config:
- config_test.dynamic.dotted.english

View file

@ -1,4 +1,4 @@
threshold:
requirements_warning: 172800
requirements_error: 1209600
logging: 1

View file

@ -14,13 +14,13 @@ class ConfigOverrider implements ConfigFactoryOverrideInterface {
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = array();
$overrides = [];
if (!empty($GLOBALS['config_test_run_module_overrides'])) {
if (in_array('system.site', $names)) {
$overrides = $overrides + array('system.site' => array('name' => 'ZOMG overridden site name'));
$overrides = $overrides + ['system.site' => ['name' => 'ZOMG overridden site name']];
}
if (in_array('config_override_test.new', $names)) {
$overrides = $overrides + array('config_override_test.new' => array('module' => 'override'));
$overrides = $overrides + ['config_override_test.new' => ['module' => 'override']];
}
}
return $overrides;

View file

@ -15,17 +15,17 @@ class ConfigOverriderLowPriority implements ConfigFactoryOverrideInterface {
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = array();
$overrides = [];
if (!empty($GLOBALS['config_test_run_module_overrides'])) {
if (in_array('system.site', $names)) {
$overrides = array('system.site' =>
array(
$overrides = ['system.site' =>
[
'name' => 'Should not apply because of higher priority listener',
// This override should apply because it is not overridden by the
// higher priority listener.
'slogan' => 'Yay for overrides!',
)
);
]
];
}
}
return $overrides;

View file

@ -270,3 +270,30 @@ test.double_brackets.turtle.horse:
test.double_brackets.*:
type: mapping
wrapping.config_schema_test.other_double_brackets:
type: config_object
mapping:
tests:
type: sequence
sequence:
- type: wrapping.test.other_double_brackets.[id]
wrapping.test.other_double_brackets.*:
type: test.double_brackets.[id]
mapping:
id:
type: string
foo:
type: string
bar:
type: string
test.double_brackets.cat:*.*:
type: test.double_brackets.breed
test.double_brackets.breed:
type: test.double_brackets
mapping:
breed:
type: string

View file

@ -21,7 +21,7 @@ class ConfigTestController extends ControllerBase {
* The title for the ConfigTest edit form.
*/
public function editTitle(ConfigTest $config_test) {
return $this->t('Edit %label', array('%label' => $config_test->label()));
return $this->t('Edit %label', ['%label' => $config_test->label()]);
}
/**
@ -33,9 +33,9 @@ class ConfigTestController extends ControllerBase {
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* A redirect response to the config_test listing page.
*/
function enable(ConfigTest $config_test) {
public function enable(ConfigTest $config_test) {
$config_test->enable()->save();
return new RedirectResponse($config_test->url('collection', array('absolute' => TRUE)));
return new RedirectResponse($config_test->url('collection', ['absolute' => TRUE]));
}
/**
@ -47,9 +47,9 @@ class ConfigTestController extends ControllerBase {
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* A redirect response to the config_test listing page.
*/
function disable(ConfigTest $config_test) {
public function disable(ConfigTest $config_test) {
$config_test->disable()->save();
return new RedirectResponse($config_test->url('collection', array('absolute' => TRUE)));
return new RedirectResponse($config_test->url('collection', ['absolute' => TRUE]));
}
}

View file

@ -3,42 +3,14 @@
namespace Drupal\config_test;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form controller for the test config edit forms.
*/
class ConfigTestForm extends EntityForm {
/**
* The entity query.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $entityQuery;
/**
* Constructs a new ConfigTestForm.
*
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
* The entity query.
*/
public function __construct(QueryFactory $entity_query) {
$this->entityQuery = $entity_query;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.query')
);
}
/**
* {@inheritdoc}
*/
@ -46,33 +18,33 @@ class ConfigTestForm extends EntityForm {
$form = parent::form($form, $form_state);
$entity = $this->entity;
$form['label'] = array(
$form['label'] = [
'#type' => 'textfield',
'#title' => 'Label',
'#default_value' => $entity->label(),
'#required' => TRUE,
);
$form['id'] = array(
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $entity->id(),
'#required' => TRUE,
'#machine_name' => array(
'#machine_name' => [
'exists' => [$this, 'exists'],
'replace_pattern' => '[^a-z0-9_.]+',
),
);
$form['weight'] = array(
],
];
$form['weight'] = [
'#type' => 'weight',
'#title' => 'Weight',
'#default_value' => $entity->get('weight'),
);
$form['style'] = array(
];
$form['style'] = [
'#type' => 'select',
'#title' => 'Image style',
'#options' => array(),
'#options' => [],
'#default_value' => $entity->get('style'),
'#access' => FALSE,
);
];
if ($this->moduleHandler->moduleExists('image')) {
$form['style']['#access'] = TRUE;
$form['style']['#options'] = image_style_options();
@ -83,61 +55,61 @@ class ConfigTestForm extends EntityForm {
// state.
$size = $entity->get('size');
$form['size_wrapper'] = array(
$form['size_wrapper'] = [
'#type' => 'container',
'#attributes' => array(
'#attributes' => [
'id' => 'size-wrapper',
),
);
$form['size_wrapper']['size'] = array(
],
];
$form['size_wrapper']['size'] = [
'#type' => 'select',
'#title' => 'Size',
'#options' => array(
'#options' => [
'custom' => 'Custom',
),
],
'#empty_option' => '- None -',
'#default_value' => $size,
'#ajax' => array(
'#ajax' => [
'callback' => '::updateSize',
'wrapper' => 'size-wrapper',
),
);
$form['size_wrapper']['size_submit'] = array(
],
];
$form['size_wrapper']['size_submit'] = [
'#type' => 'submit',
'#value' => t('Change size'),
'#attributes' => array(
'class' => array('js-hide'),
),
'#submit' => array(array(get_class($this), 'changeSize')),
);
$form['size_wrapper']['size_value'] = array(
'#attributes' => [
'class' => ['js-hide'],
],
'#submit' => [[get_class($this), 'changeSize']],
];
$form['size_wrapper']['size_value'] = [
'#type' => 'select',
'#title' => 'Custom size value',
'#options' => array(
'#options' => [
'small' => 'Small',
'medium' => 'Medium',
'large' => 'Large',
),
],
'#default_value' => $entity->get('size_value'),
'#access' => !empty($size),
);
];
$form['langcode'] = array(
$form['langcode'] = [
'#type' => 'language_select',
'#title' => t('Language'),
'#languages' => LanguageInterface::STATE_ALL,
'#default_value' => $entity->language()->getId(),
);
];
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => 'Save',
);
$form['actions']['delete'] = array(
];
$form['actions']['delete'] = [
'#type' => 'submit',
'#value' => 'Delete',
);
];
return $form;
}
@ -164,10 +136,10 @@ class ConfigTestForm extends EntityForm {
$status = $entity->save();
if ($status === SAVED_UPDATED) {
drupal_set_message(format_string('%label configuration has been updated.', array('%label' => $entity->label())));
drupal_set_message(format_string('%label configuration has been updated.', ['%label' => $entity->label()]));
}
else {
drupal_set_message(format_string('%label configuration has been created.', array('%label' => $entity->label())));
drupal_set_message(format_string('%label configuration has been created.', ['%label' => $entity->label()]));
}
$form_state->setRedirectUrl($this->entity->urlInfo('collection'));
@ -189,7 +161,8 @@ class ConfigTestForm extends EntityForm {
public function exists($entity_id, array $element, FormStateInterface $form_state) {
/** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */
$entity = $form_state->getFormObject()->getEntity();
return (bool) $this->entityQuery->get($entity->getEntityTypeId())
return (bool) $this->entityTypeManager->getStorage($entity->getEntityTypeId())
->getQuery()
->condition($entity->getEntityType()->getKey('id'), $entity_id)
->execute();
}

View file

@ -38,6 +38,6 @@ class ConfigQueryTest extends ConfigTest {
*
* @var array
*/
public $array = array();
public $array = [];
}

View file

@ -88,10 +88,10 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface {
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// Used to test secondary writes during config sync.
if ($this->id() == 'primary') {
$secondary = $storage->create(array(
$secondary = $storage->create([
'id' => 'secondary',
'label' => 'Secondary Default',
));
]);
$secondary->save();
}
if ($this->id() == 'deleter') {
@ -126,7 +126,7 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface {
if (!isset($this->dependencies['enforced']['config'])) {
return $changed;
}
$fix_deps = \Drupal::state()->get('config_test.fix_dependencies', array());
$fix_deps = \Drupal::state()->get('config_test.fix_dependencies', []);
foreach ($dependencies['config'] as $entity) {
if (in_array($entity->getConfigDependencyName(), $fix_deps)) {
$key = array_search($entity->getConfigDependencyName(), $this->dependencies['enforced']['config']);

View file

@ -8,7 +8,7 @@ use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller for testing \Drupal\Core\Config\Testing\ConfigSchemaChecker.
* Controller for testing \Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
class SchemaListenerController extends ControllerBase {

View file

@ -20,7 +20,7 @@ class TestInstallStorage extends InstallStorage {
if (!isset($this->folders)) {
$this->folders = $this->getCoreNames();
$listing = new ExtensionDiscovery(\Drupal::root());
$listing->setProfileDirectories(array());
$listing->setProfileDirectories([]);
$this->folders += $this->getComponentNames($listing->scan('profile'));
$this->folders += $this->getComponentNames($listing->scan('module'));
$this->folders += $this->getComponentNames($listing->scan('theme'));

View file

@ -0,0 +1,130 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Tests\BrowserTestBase;
/**
* Tests configuration entities.
*
* @group config
*/
class ConfigDependencyWebTest extends BrowserTestBase {
/**
* The maximum length for the entity storage used in this test.
*/
const MAX_ID_LENGTH = ConfigEntityStorage::MAX_ID_LENGTH;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['config_test'];
/**
* Tests ConfigDependencyDeleteFormTrait.
*
* @see \Drupal\Core\Config\Entity\ConfigDependencyDeleteFormTrait
*/
public function testConfigDependencyDeleteFormTrait() {
$this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
$storage = $this->container->get('entity.manager')->getStorage('config_test');
// Entity1 will be deleted by the test.
$entity1 = $storage->create(
[
'id' => 'entity1',
'label' => 'Entity One',
]
);
$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(
[
'id' => 'entity2',
'dependencies' => [
'enforced' => [
'config' => [$entity1->getConfigDependencyName()],
],
],
]
);
$entity2->save();
$this->drupalGet($entity2->urlInfo('delete-form'));
$this->assertNoText(t('Configuration updates'), 'No configuration updates found.');
$this->assertNoText(t('Configuration deletions'), 'No configuration deletes found.');
$this->drupalGet($entity1->urlInfo('delete-form'));
$this->assertNoText(t('Configuration updates'), 'No configuration updates found.');
$this->assertText(t('Configuration deletions'), 'Configuration deletions found.');
$this->assertText($entity2->id(), 'Entity2 id found');
$this->drupalPostForm($entity1->urlInfo('delete-form'), [], 'Delete');
$storage->resetCache();
$this->assertFalse($storage->loadMultiple([$entity1->id(), $entity2->id()]), 'Test entities deleted');
// Set a more complicated test where dependencies will be fixed.
// Entity1 will be deleted by the test.
$entity1 = $storage->create(
[
'id' => 'entity1',
]
);
$entity1->save();
\Drupal::state()->set('config_test.fix_dependencies', [$entity1->getConfigDependencyName()]);
// 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(
[
'id' => 'entity2',
'label' => 'Entity Two',
'dependencies' => [
'enforced' => [
'config' => [$entity1->getConfigDependencyName()],
],
],
]
);
$entity2->save();
// Entity3 will be unchanged because it is dependent on Entity2 which can
// be fixed.
$entity3 = $storage->create(
[
'id' => 'entity3',
'dependencies' => [
'enforced' => [
'config' => [$entity2->getConfigDependencyName()],
],
],
]
);
$entity3->save();
$this->drupalGet($entity1->urlInfo('delete-form'));
$this->assertText(t('Configuration updates'), 'Configuration updates found.');
$this->assertNoText(t('Configuration deletions'), 'No configuration deletions found.');
$this->assertNoText($entity2->id(), 'Entity2 id not found');
$this->assertText($entity2->label(), 'Entity2 label not found');
$this->assertNoText($entity3->id(), 'Entity3 id not found');
$this->drupalPostForm($entity1->urlInfo('delete-form'), [], 'Delete');
$storage->resetCache();
$this->assertFalse($storage->load('entity1'), 'Test entity 1 deleted');
$entity2 = $storage->load('entity2');
$this->assertTrue($entity2, 'Entity 2 not deleted');
$this->assertEqual($entity2->calculateDependencies()->getDependencies()['config'], [], '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.');
}
}

View file

@ -15,13 +15,13 @@ class ConfigDraggableListBuilderTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('config_test');
public static $modules = ['config_test'];
/**
* Test draggable lists.
*/
public function testDraggableList() {
$this->drupalLogin($this->drupalCreateUser(array('administer permissions')));
$this->drupalLogin($this->drupalCreateUser(['administer permissions']));
// Create more than 50 roles.
for ($i = 0; $i < 51; $i++) {

View file

@ -0,0 +1,63 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Tests\BrowserTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Tests the listing of configuration entities in a multilingual scenario.
*
* @group config
*/
class ConfigEntityListMultilingualTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['config_test', 'language', 'block'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Delete the override config_test entity. It is not required by this test.
\Drupal::entityManager()->getStorage('config_test')->load('override')->delete();
ConfigurableLanguage::createFromLangcode('hu')->save();
$this->drupalPlaceBlock('local_actions_block');
}
/**
* Tests the listing UI with different language scenarios.
*/
public function testListUI() {
// Log in as an administrative user to access the full menu trail.
$this->drupalLogin($this->drupalCreateUser(['access administration pages', 'administer site configuration']));
// Get the list page.
$this->drupalGet('admin/structure/config_test');
$this->assertLinkByHref('admin/structure/config_test/manage/dotted.default');
// Add a new entity using the action link.
$this->clickLink('Add test configuration');
$edit = [
'label' => 'Antilop',
'id' => 'antilop',
'langcode' => 'hu',
];
$this->drupalPostForm(NULL, $edit, t('Save'));
// Ensure that operations for editing the Hungarian entity appear in English.
$this->assertLinkByHref('admin/structure/config_test/manage/antilop');
// Get the list page in Hungarian and assert Hungarian admin links
// regardless of language of config entities.
$this->drupalGet('hu/admin/structure/config_test');
$this->assertLinkByHref('hu/admin/structure/config_test/manage/dotted.default');
$this->assertLinkByHref('hu/admin/structure/config_test/manage/antilop');
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests configuration entity status UI functionality.
*
* @group config
*/
class ConfigEntityStatusUITest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['config_test'];
/**
* Tests status operations.
*/
public function testCRUD() {
$this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
$id = strtolower($this->randomMachineName());
$edit = [
'id' => $id,
'label' => $this->randomMachineName(),
];
$this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save');
$entity = entity_load('config_test', $id);
// Disable an entity.
$disable_url = $entity->urlInfo('disable');
$this->assertLinkByHref($disable_url->toString());
$this->drupalGet($disable_url);
$this->assertResponse(200);
$this->assertNoLinkByHref($disable_url->toString());
// Enable an entity.
$enable_url = $entity->urlInfo('enable');
$this->assertLinkByHref($enable_url->toString());
$this->drupalGet($enable_url);
$this->assertResponse(200);
$this->assertNoLinkByHref($enable_url->toString());
}
}

View file

@ -0,0 +1,114 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\InstallStorage;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Config\FileStorage;
use Drupal\system\Entity\Action;
use Drupal\tour\Entity\Tour;
/**
* Tests installation and removal of configuration objects in install, disable
* and uninstall functionality.
*
* @group config
*/
class ConfigInstallProfileOverrideTest extends BrowserTestBase {
/**
* The profile to install as a basis for testing.
*
* @var string
*/
protected $profile = 'testing_config_overrides';
/**
* Tests install profile config changes.
*/
public function testInstallProfileConfigOverwrite() {
$config_name = 'system.cron';
// The expected configuration from the system module.
$expected_original_data = [
'threshold' => [
'requirements_warning' => 172800,
'requirements_error' => 1209600,
],
'logging' => 1,
];
// The expected active configuration altered by the install profile.
$expected_profile_data = [
'threshold' => [
'requirements_warning' => 259200,
'requirements_error' => 1209600,
],
'logging' => 1,
];
$expected_profile_data['_core']['default_config_hash'] = Crypt::hashBase64(serialize($expected_profile_data));
// Verify that the original data matches. We have to read the module config
// file directly, because the install profile default system.cron.yml
// configuration file was used to create the active configuration.
$config_dir = drupal_get_path('module', 'system') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
$this->assertTrue(is_dir($config_dir));
$source_storage = new FileStorage($config_dir);
$data = $source_storage->read($config_name);
$this->assertIdentical($data, $expected_original_data);
// Verify that active configuration matches the expected data, which was
// created from the testing install profile's system.cron.yml file.
$config = $this->config($config_name);
$this->assertIdentical($config->get(), $expected_profile_data);
// Ensure that the configuration entity has the expected dependencies and
// overrides.
$action = Action::load('user_block_user_action');
$this->assertEqual($action->label(), 'Overridden block the selected user(s)');
$action = Action::load('user_cancel_user_action');
$this->assertEqual($action->label(), 'Cancel the selected user account(s)', 'Default configuration that is not overridden is not affected.');
// Ensure that optional configuration can be overridden.
$tour = Tour::load('language');
$this->assertEqual(count($tour->getTips()), 1, 'Optional configuration can be overridden. The language tour only has one tip');
$tour = Tour::load('language-add');
$this->assertEqual(count($tour->getTips()), 3, 'Optional configuration that is not overridden is not affected.');
// Ensure that optional configuration from a profile is created if
// dependencies are met.
$this->assertEqual(Tour::load('testing_config_overrides')->label(), 'Config override test');
// Ensure that optional configuration from a profile is not created if
// dependencies are not met. Cannot use the entity system since the entity
// type does not exist.
$optional_dir = drupal_get_path('module', 'testing_config_overrides') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
$optional_storage = new FileStorage($optional_dir);
foreach (['config_test.dynamic.dotted.default', 'config_test.dynamic.override', 'config_test.dynamic.override_unmet'] as $id) {
$this->assertTrue(\Drupal::config($id)->isNew(), "The config_test entity $id contained in the profile's optional directory does not exist.");
// Make that we don't get false positives from the assertion above.
$this->assertTrue($optional_storage->exists($id), "The config_test entity $id does exist in the profile's optional directory.");
}
// Install the config_test module and ensure that the override from the
// install profile is used. Optional configuration can override
// configuration in a modules config/install directory.
$this->container->get('module_installer')->install(['config_test']);
$this->rebuildContainer();
$config_test_storage = \Drupal::entityManager()->getStorage('config_test');
$this->assertEqual($config_test_storage->load('dotted.default')->label(), 'Default install profile override', 'The config_test entity is overridden by the profile optional configuration.');
// Test that override of optional configuration does work.
$this->assertEqual($config_test_storage->load('override')->label(), 'Override', 'The optional config_test entity is overridden by the profile optional configuration.');
// Test that override of optional configuration which introduces an unmet
// dependency does not get created.
$this->assertNull($config_test_storage->load('override_unmet'), 'The optional config_test entity with unmet dependencies is not created.');
$this->assertNull($config_test_storage->load('completely_new'), 'The completely new optional config_test entity with unmet dependencies is not created.');
// Installing dblog creates the optional configuration.
$this->container->get('module_installer')->install(['dblog']);
$this->rebuildContainer();
$this->assertEqual($config_test_storage->load('override_unmet')->label(), 'Override', 'The optional config_test entity is overridden by the profile optional configuration and is installed when its dependencies are met.');
$this->assertEqual($config_test_storage->load('completely_new')->label(), 'Completely new optional configuration', 'The optional config_test entity is provided by the profile optional configuration and is installed when its dependencies are met.');
}
}

View file

@ -0,0 +1,90 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Core\Language\LanguageInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
/**
* Tests language overrides applied through the website.
*
* @group config
*/
class ConfigLanguageOverrideWebTest extends BrowserTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = [
'block',
'language',
'system'
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}
/**
* Tests translating the site name.
*/
public function testSiteNameTranslation() {
$adminUser = $this->drupalCreateUser(['administer site configuration', 'administer languages']);
$this->drupalLogin($adminUser);
// Add a custom language.
$langcode = 'xx';
$name = $this->randomMachineName(16);
$edit = [
'predefined_langcode' => 'custom',
'langcode' => $langcode,
'label' => $name,
'direction' => LanguageInterface::DIRECTION_LTR,
];
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
\Drupal::languageManager()
->getLanguageConfigOverride($langcode, 'system.site')
->set('name', 'XX site name')
->save();
// Place branding block with site name into header region.
$this->drupalPlaceBlock('system_branding_block', ['region' => 'header']);
$this->drupalLogout();
// The home page in English should not have the override.
$this->drupalGet('');
$this->assertNoText('XX site name');
// During path resolution the system.site configuration object is used to
// determine the front page. This occurs before language negotiation causing
// the configuration factory to cache an object without the correct
// overrides. We are testing that the configuration factory is
// re-initialised after language negotiation. Ensure that it applies when
// we access the XX front page.
// @see \Drupal\Core\PathProcessor::processInbound()
$this->drupalGet('xx');
$this->assertText('XX site name');
// Set the xx language to be the default language and delete the English
// language so the site is no longer multilingual and confirm configuration
// overrides still work.
$language_manager = \Drupal::languageManager()->reset();
$this->assertTrue($language_manager->isMultilingual(), 'The test site is multilingual.');
$this->config('system.site')->set('default_langcode', 'xx')->save();
ConfigurableLanguage::load('en')->delete();
$this->assertFalse($language_manager->isMultilingual(), 'The test site is monolingual.');
$this->drupalGet('xx');
$this->assertText('XX site name');
}
}

View file

@ -0,0 +1,123 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests default configuration provided by a module that does not own it.
*
* @group config
*/
class ConfigOtherModuleTest extends BrowserTestBase {
/**
* Tests enabling the provider of the default configuration first.
*/
public function testInstallOtherModuleFirst() {
$this->installModule('config_other_module_config_test');
// Check that the config entity doesn't exist before the config_test module
// is enabled. We cannot use the entity system because the config_test
// entity type does not exist.
$config = $this->config('config_test.dynamic.other_module_test');
$this->assertTrue($config->isNew(), 'Default configuration for other modules is not installed if that module is not enabled.');
// Install the module that provides the entity type. This installs the
// default configuration.
$this->installModule('config_test');
$this->assertTrue(entity_load('config_test', 'other_module_test', TRUE), 'Default configuration has been installed.');
// Uninstall the module that provides the entity type. This will remove the
// default configuration.
$this->uninstallModule('config_test');
$config = $this->config('config_test.dynamic.other_module_test');
$this->assertTrue($config->isNew(), 'Default configuration for other modules is removed when the config entity provider is disabled.');
// Install the module that provides the entity type again. This installs the
// default configuration.
$this->installModule('config_test');
$other_module_config_entity = entity_load('config_test', 'other_module_test', TRUE);
$this->assertTrue($other_module_config_entity, "Default configuration has been recreated.");
// Update the default configuration to test that the changes are preserved
// if the module that provides the default configuration is uninstalled.
$other_module_config_entity->set('style', "The piano ain't got no wrong notes.");
$other_module_config_entity->save();
// Uninstall the module that provides the default configuration.
$this->uninstallModule('config_other_module_config_test');
$this->assertTrue(entity_load('config_test', 'other_module_test', TRUE), 'Default configuration for other modules is not removed when the module that provides it is uninstalled.');
// Default configuration provided by config_test should still exist.
$this->assertTrue(entity_load('config_test', 'dotted.default', TRUE), 'The configuration is not deleted.');
// Re-enable module to test that pre-existing optional configuration does
// not throw an error.
$this->installModule('config_other_module_config_test');
$this->assertTrue(\Drupal::moduleHandler()->moduleExists('config_other_module_config_test'), 'The config_other_module_config_test module is installed.');
// Ensure that optional configuration with unmet dependencies is only
// installed once all the dependencies are met.
$this->assertNull(entity_load('config_test', 'other_module_test_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_unmet whose dependencies are not met is not created.');
$this->assertNull(entity_load('config_test', 'other_module_test_optional_entity_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet whose dependencies are not met is not created.');
$this->installModule('config_test_language');
$this->installModule('config_install_dependency_test');
$this->assertTrue(entity_load('config_test', 'other_module_test_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_unmet whose dependencies are met is now created.');
// Although the following configuration entity's are now met it is not
// installed because it does not have a direct dependency on the
// config_install_dependency_test module.
$this->assertNull(entity_load('config_test', 'other_module_test_optional_entity_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet whose dependencies are met is not created.');
}
/**
* Tests enabling the provider of the config entity type first.
*/
public function testInstallConfigEntityModuleFirst() {
$this->installModule('config_test');
$this->assertFalse(entity_load('config_test', 'other_module_test', TRUE), 'Default configuration provided by config_other_module_config_test does not exist.');
$this->installModule('config_other_module_config_test');
$this->assertTrue(entity_load('config_test', 'other_module_test', TRUE), 'Default configuration provided by config_other_module_config_test has been installed.');
}
/**
* Tests uninstalling Node module removes views which are dependent on it.
*/
public function testUninstall() {
$this->installModule('views');
$storage = $this->container->get('entity_type.manager')->getStorage('view');
$storage->resetCache(['frontpage']);
$this->assertTrue($storage->load('frontpage') === NULL, 'After installing Views, frontpage view which is dependant on the Node and Views modules does not exist.');
$this->installModule('node');
$storage->resetCache(['frontpage']);
$this->assertTrue($storage->load('frontpage') !== NULL, 'After installing Node, frontpage view which is dependant on the Node and Views modules exists.');
$this->uninstallModule('node');
$storage = $this->container->get('entity_type.manager')->getStorage('view');
$storage->resetCache(['frontpage']);
$this->assertTrue($storage->load('frontpage') === NULL, 'After uninstalling Node, frontpage view which is dependant on the Node and Views modules does not exist.');
}
/**
* Installs a module.
*
* @param string $module
* The module name.
*/
protected function installModule($module) {
$this->container->get('module_installer')->install([$module]);
$this->container = \Drupal::getContainer();
}
/**
* Uninstalls a module.
*
* @param string $module
* The module name.
*/
protected function uninstallModule($module) {
$this->container->get('module_installer')->uninstall([$module]);
$this->container = \Drupal::getContainer();
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace Drupal\Tests\config\Functional;
use Drupal\Core\Config\Schema\SchemaIncompleteException;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the functionality of ConfigSchemaChecker in WebTestBase tests.
*
* @group config
*/
class SchemaConfigListenerWebTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['config_test'];
/**
* Tests \Drupal\Core\Config\Development\ConfigSchemaChecker.
*/
public function testConfigSchemaChecker() {
$this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
// Test a non-existing schema.
$msg = 'Expected SchemaIncompleteException thrown';
try {
$this->config('config_schema_test.schemaless')->set('foo', 'bar')->save();
$this->fail($msg);
}
catch (SchemaIncompleteException $e) {
$this->pass($msg);
$this->assertEqual('No schema for config_schema_test.schemaless', $e->getMessage());
}
// Test a valid schema.
$msg = 'Unexpected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')->set('int', 10);
try {
$config->save();
$this->pass($msg);
}
catch (SchemaIncompleteException $e) {
$this->fail($msg);
}
// Test an invalid schema.
$msg = 'Expected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')
->set('foo', 'bar')
->set('array', 1);
try {
$config->save();
$this->fail($msg);
}
catch (SchemaIncompleteException $e) {
$this->pass($msg);
$this->assertEqual('Schema errors for config_test.types with the following errors: config_test.types:array variable type is integer but applied schema class is Drupal\Core\Config\Schema\Sequence, config_test.types:foo missing schema', $e->getMessage());
}
// Test that the config event listener is working in the child site.
$this->drupalGet('config_test/schema_listener');
$this->assertText('No schema for config_schema_test.schemaless');
}
}

View file

@ -12,7 +12,7 @@ use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
class ConfigLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = array('config' => 'core/modules/config');
$this->directoryList = ['config' => 'core/modules/config'];
parent::setUp();
}
@ -29,13 +29,13 @@ class ConfigLocalTasksTest extends LocalTaskIntegrationTestBase {
* Provides a list of routes to test.
*/
public function getConfigAdminRoutes() {
return array(
array('config.sync', array(array('config.sync', 'config.import', 'config.export'))),
array('config.import_full', array(array('config.sync', 'config.import', 'config.export'), array('config.import_full', 'config.import_single'))),
array('config.import_single', array(array('config.sync', 'config.import', 'config.export'), array('config.import_full', 'config.import_single'))),
array('config.export_full', array(array('config.sync', 'config.import', 'config.export'), array('config.export_full', 'config.export_single'))),
array('config.export_single', array(array('config.sync', 'config.import', 'config.export'), array('config.export_full', 'config.export_single'))),
);
return [
['config.sync', [['config.sync', 'config.import', 'config.export']]],
['config.import_full', [['config.sync', 'config.import', 'config.export'], ['config.import_full', 'config.import_single']]],
['config.import_single', [['config.sync', 'config.import', 'config.export'], ['config.import_full', 'config.import_single']]],
['config.export_full', [['config.sync', 'config.import', 'config.export'], ['config.export_full', 'config.export_single']]],
['config.export_single', [['config.sync', 'config.import', 'config.export'], ['config.export_full', 'config.export_single']]],
];
}
}