Update to Drupal 8.1.5. For more information, see https://www.drupal.org/project/drupal/releases/8.1.5

This commit is contained in:
Pantheon Automation 2016-07-07 09:44:38 -07:00 committed by Greg Anderson
parent 13b6ca7cc2
commit 38ba7c357d
342 changed files with 7814 additions and 1534 deletions

View file

@ -188,7 +188,8 @@ class ConfigDependencyTest extends EntityKernelTestBase {
/** @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');
$storage = $this->container->get('entity.manager')
->getStorage('config_test');
// Test dependencies between modules.
$entity1 = $storage->create(
array(
@ -221,14 +222,42 @@ class ConfigDependencyTest extends EntityKernelTestBase {
$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(
/**
* Data provider for self::testConfigEntityUninstallComplex().
*/
public function providerConfigEntityUninstallComplex() {
// Ensure that alphabetical order has no influence on dependency fixing and
// removal.
return [
[['a', 'b', 'c', 'd']],
[['d', 'c', 'b', 'a']],
[['c', 'd', 'a', 'b']],
];
}
/**
* Tests complex configuration entity dependency handling during uninstall.
*
* Configuration entities can be deleted or updated during module uninstall
* because they have dependencies on the module.
*
* @param array $entity_id_suffixes
* The suffixes to add to the 4 entities created by the test.
*
* @dataProvider providerConfigEntityUninstallComplex
*/
public function testConfigEntityUninstallComplex(array $entity_id_suffixes) {
/** @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');
// Entity 1 will be deleted because it depends on node.
$entity_1 = $storage->create(
array(
'id' => 'entity1',
'id' => 'entity_' . $entity_id_suffixes[0],
'dependencies' => array(
'enforced' => array(
'module' => array('node', 'config_test')
@ -236,77 +265,85 @@ class ConfigDependencyTest extends EntityKernelTestBase {
),
)
);
$entity1->save();
$entity_1->save();
// Entity2 has a dependency on Entity1 but it can be fixed because
// Entity 2 has a dependency on entity 1 but it can be fixed because
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
// dependency before config entities are deleted.
$entity2 = $storage->create(
$entity_2 = $storage->create(
array(
'id' => 'entity2',
'id' => 'entity_' . $entity_id_suffixes[1],
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
'config' => array($entity_1->getConfigDependencyName()),
),
),
)
);
$entity2->save();
$entity_2->save();
// Entity3 will be unchanged because it is dependent on Entity2 which can
// Entity 3 will be unchanged because it is dependent on entity 2 which can
// be fixed. The ConfigEntityInterface::onDependencyRemoval() method will
// not be called for this entity.
$entity3 = $storage->create(
$entity_3 = $storage->create(
array(
'id' => 'entity3',
'id' => 'entity_' . $entity_id_suffixes[2],
'dependencies' => array(
'enforced' => array(
'config' => array($entity2->getConfigDependencyName()),
'config' => array($entity_2->getConfigDependencyName()),
),
),
)
);
$entity3->save();
$entity_3->save();
// Entity4's config dependency will be fixed but it will still be deleted
// Entity 4's config dependency will be fixed but it will still be deleted
// because it also depends on the node module.
$entity4 = $storage->create(
$entity_4 = $storage->create(
array(
'id' => 'entity4',
'id' => 'entity_' . $entity_id_suffixes[3],
'dependencies' => array(
'enforced' => array(
'config' => array($entity1->getConfigDependencyName()),
'config' => array($entity_1->getConfigDependencyName()),
'module' => array('node', 'config_test')
),
),
)
);
$entity4->save();
$entity_4->save();
// Set a more complicated test where dependencies will be fixed.
\Drupal::state()->set('config_test.fix_dependencies', array($entity_1->getConfigDependencyName()));
\Drupal::state()->set('config_test.on_dependency_removal_called', []);
// 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.');
$this->assertEqual($entity_1->uuid(), $config_entities['delete'][1]->uuid(), 'Entity 1 will be deleted.');
$this->assertEqual($entity_2->uuid(), reset($config_entities['update'])->uuid(), 'Entity 2 will be updated.');
$this->assertEqual($entity_3->uuid(), reset($config_entities['unchanged'])->uuid(), 'Entity 3 is not changed.');
$this->assertEqual($entity_4->uuid(), $config_entities['delete'][0]->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.');
$this->assertFalse(in_array($entity_3->id(), $called), 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
$this->assertIdentical([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
// 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();
// 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');
$this->assertFalse($storage->load($entity_1->id()), 'Entity 1 deleted');
$entity_2 = $storage->load($entity_2->id());
$this->assertTrue($entity_2, 'Entity 2 not deleted');
$this->assertEqual($entity_2->calculateDependencies()->getDependencies()['config'], array(), 'Entity 2 dependencies updated to remove dependency on entity 1.');
$entity_3 = $storage->load($entity_3->id());
$this->assertTrue($entity_3, 'Entity 3 not deleted');
$this->assertEqual($entity_3->calculateDependencies()->getDependencies()['config'], [$entity_2->getConfigDependencyName()], 'Entity 3 still depends on entity 2.');
$this->assertFalse($storage->load($entity_4->id()), 'Entity 4 deleted');
}
/**
@ -456,8 +493,8 @@ class ConfigDependencyTest extends EntityKernelTestBase {
$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->assertEqual($entity1->uuid(), $config_entities['delete'][1]->uuid(), 'Entity 1 will be deleted.');
$this->assertEqual($entity2->uuid(), $config_entities['delete'][0]->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.');
}

View file

@ -97,6 +97,8 @@ class ConnectionTest extends DatabaseTestBase {
// Set up identical replica and confirm connection options are identical.
Database::addConnectionInfo('default', 'replica', $connection_info['default']);
$db2 = Database::getConnection('replica', 'default');
// Getting a driver class ensures the namespace option is set.
$this->assertEquals($db->getDriverClass('select'), $db2->getDriverClass('select'));
$connectionOptions2 = $db2->getConnectionOptions();
// Get a fresh copy of the default connection options.

View file

@ -375,4 +375,50 @@ class SelectComplexTest extends DatabaseTestBase {
$this->assertTrue($exception, 'Exception was thrown');
}
/**
* Test that join conditions can use Condition objects.
*/
public function testJoinConditionObject() {
// Same test as testDefaultJoin, but with a Condition object.
$query = db_select('test_task', 't');
$join_cond = db_and()->where('t.pid = p.id');
$people_alias = $query->join('test', 'p', $join_cond);
$name_field = $query->addField($people_alias, 'name', 'name');
$query->addField('t', 'task', 'task');
$priority_field = $query->addField('t', 'priority', 'priority');
$query->orderBy($priority_field);
$result = $query->execute();
$num_records = 0;
$last_priority = 0;
foreach ($result as $record) {
$num_records++;
$this->assertTrue($record->$priority_field >= $last_priority, 'Results returned in correct order.');
$this->assertNotEqual($record->$name_field, 'Ringo', 'Taskless person not selected.');
$last_priority = $record->$priority_field;
}
$this->assertEqual($num_records, 7, 'Returned the correct number of rows.');
// Test a condition object that creates placeholders.
$t1_name = 'John';
$t2_name = 'George';
$join_cond = db_and()
->condition('t1.name', $t1_name)
->condition('t2.name', $t2_name);
$query = db_select('test', 't1');
$query->innerJoin('test', 't2', $join_cond);
$query->addField('t1', 'name', 't1_name');
$query->addField('t2', 'name', 't2_name');
$num_records = $query->countQuery()->execute()->fetchField();
$this->assertEqual($num_records, 1, 'Query expected to return 1 row. Actual: ' . $num_records);
if ($num_records == 1) {
$record = $query->execute()->fetchObject();
$this->assertEqual($record->t1_name, $t1_name, 'Query expected to retrieve name ' . $t1_name . ' from table t1. Actual: ' . $record->t1_name);
$this->assertEqual($record->t2_name, $t2_name, 'Query expected to retrieve name ' . $t2_name . ' from table t2. Actual: ' . $record->t2_name);
}
}
}

View file

@ -0,0 +1,184 @@
<?php
namespace Drupal\KernelTests\Core\DrupalKernel;
use Drupal\Core\DrupalKernel;
use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests DIC compilation to disk.
*
* @group DrupalKernel
*/
class DrupalKernelTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
// DrupalKernel relies on global $config_directories and requires those
// directories to exist. Therefore, create the directories, but do not
// invoke KernelTestBase::setUp(), since that would set up further
// environment aspects, which would distort this test, because it tests
// the DrupalKernel (re-)building itself.
$this->root = static::getDrupalRoot();
$this->bootEnvironment();
}
/**
* Build a kernel for testings.
*
* Because the bootstrap is in DrupalKernel::boot and that involved loading
* settings from the filesystem we need to go to extra lengths to build a kernel
* for testing.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* A request object to use in booting the kernel.
* @param array $modules_enabled
* A list of modules to enable on the kernel.
*
* @return \Drupal\Core\DrupalKernel
* New kernel for testing.
*/
protected function getTestKernel(Request $request, array $modules_enabled = NULL) {
// Manually create kernel to avoid replacing settings.
$class_loader = require $this->root . '/autoload.php';
$kernel = DrupalKernel::createFromRequest($request, $class_loader, 'testing');
$this->setSetting('container_yamls', []);
$this->setSetting('hash_salt', $this->databasePrefix);
if (isset($modules_enabled)) {
$kernel->updateModules($modules_enabled);
}
$kernel->boot();
return $kernel;
}
/**
* Tests DIC compilation.
*/
public function testCompileDIC() {
// @todo: write a memory based storage backend for testing.
$modules_enabled = array(
'system' => 'system',
'user' => 'user',
);
$request = Request::createFromGlobals();
$this->getTestKernel($request, $modules_enabled);
// Instantiate it a second time and we should get the compiled Container
// class.
$kernel = $this->getTestKernel($request);
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
$is_compiled_container = !$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($modules_enabled), $module_list);
// Get the container another time, simulating a "production" environment.
$container = $this->getTestKernel($request, NULL)
->getContainer();
$refClass = new \ReflectionClass($container);
$is_compiled_container = !$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($modules_enabled), $module_list);
// Test that our synthetic services are there.
$class_loader = $container->get('class_loader');
$refClass = new \ReflectionClass($class_loader);
$this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a class loader');
// We make this assertion here purely to show that the new container below
// is functioning correctly, i.e. we get a brand new ContainerBuilder
// which has the required new services, after changing the list of enabled
// modules.
$this->assertFalse($container->has('service_provider_test_class'));
// Add another module so that we can test that the new module's bundle is
// registered to the new container.
$modules_enabled['service_provider_test'] = 'service_provider_test';
$this->getTestKernel($request, $modules_enabled);
// Instantiate it a second time and we should not get a ContainerBuilder
// class because we are loading the container definition from cache.
$kernel = $this->getTestKernel($request, $modules_enabled);
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
$is_container_builder = $refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertFalse($is_container_builder, 'Container is not a builder');
// Assert that the new module's bundle was registered to the new container.
$this->assertTrue($container->has('service_provider_test_class'), 'Container has test service');
// Test that our synthetic services are there.
$class_loader = $container->get('class_loader');
$refClass = new \ReflectionClass($class_loader);
$this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a class loader');
// Check that the location of the new module is registered.
$modules = $container->getParameter('container.modules');
$this->assertEqual($modules['service_provider_test'], array(
'type' => 'module',
'pathname' => drupal_get_filename('module', 'service_provider_test'),
'filename' => NULL,
));
}
/**
* Tests repeated loading of compiled DIC with different environment.
*/
public function testRepeatedBootWithDifferentEnvironment() {
$request = Request::createFromGlobals();
$class_loader = require $this->root . '/autoload.php';
$environments = [
'testing1',
'testing1',
'testing2',
'testing2',
];
foreach ($environments as $environment) {
$kernel = DrupalKernel::createFromRequest($request, $class_loader, $environment);
$this->setSetting('container_yamls', []);
$this->setSetting('hash_salt', $this->databasePrefix);
$kernel->boot();
}
$this->pass('Repeatedly loaded compiled DIC with different environment');
}
/**
* Tests setting of site path after kernel boot.
*/
public function testPreventChangeOfSitePath() {
// @todo: write a memory based storage backend for testing.
$modules_enabled = array(
'system' => 'system',
'user' => 'user',
);
$request = Request::createFromGlobals();
$kernel = $this->getTestKernel($request, $modules_enabled);
$pass = FALSE;
try {
$kernel->setSitePath('/dev/null');
}
catch (\LogicException $e) {
$pass = TRUE;
}
$this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot');
}
}

View file

@ -146,7 +146,7 @@ class EntityAutocompleteTest extends EntityKernelTestBase {
* The label of the entity to query by.
*
* @return mixed
* The JSON value encoded in its appropriate PHP type.
* The JSON value encoded in its appropriate PHP type.
*/
protected function getAutocompleteResult($input) {
$request = Request::create('entity_reference_autocomplete/' . $this->entityType . '/default');

View file

@ -512,6 +512,89 @@ class EntityQueryTest extends EntityKernelTestBase {
$this->assertResult(6, 14);
}
/**
* Test queries with delta conditions.
*/
public function testDelta() {
$figures = $this->figures;
// Test numeric delta value in field condition.
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("$figures.0.color", 'red')
->sort('id')
->execute();
// As unit 0 at delta 0 was the red triangle bit 0 needs to be set.
$this->assertResult(1, 3, 5, 7, 9, 11, 13, 15);
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("$figures.1.color", 'red')
->sort('id')
->execute();
// Delta 1 is not red.
$this->assertResult();
// Test on two different deltas.
$query = $this->factory->get('entity_test_mulrev');
$or = $query->andConditionGroup()
->condition("$figures.0.color", 'red')
->condition("$figures.1.color", 'blue');
$this->queryResults = $query
->condition($or)
->sort('id')
->execute();
$this->assertResult(3, 7, 11, 15);
// Test the delta range condition.
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("$figures.%delta.color", array('blue', 'red'), 'IN')
->condition("$figures.%delta", array(0, 1), 'IN')
->sort('id')
->execute();
// Figure delta 0 or 1 can be blue or red, this matches a lot of entities.
$this->assertResult(1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15);
// Test the delta range condition without conditions on the value.
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("$figures.%delta", 1)
->sort('id')
->execute();
// Entity needs to have atleast two figures.
$this->assertResult(3, 7, 11, 15);
// Numeric delta on single value base field should return results only if
// the first item is being targeted.
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("id.0.value", array(1, 3, 5), 'IN')
->sort('id')
->execute();
$this->assertResult(1, 3, 5);
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("id.1.value", array(1, 3, 5), 'IN')
->sort('id')
->execute();
$this->assertResult();
// Delta range condition on single value base field should return results
// only if just the field value is targeted.
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("id.%delta.value", array(1, 3, 5), 'IN')
->sort('id')
->execute();
$this->assertResult(1, 3, 5);
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("id.%delta.value", array(1, 3, 5), 'IN')
->condition("id.%delta", 0, '=')
->sort('id')
->execute();
$this->assertResult(1, 3, 5);
$this->queryResults = $this->factory->get('entity_test_mulrev')
->condition("id.%delta.value", array(1, 3, 5), 'IN')
->condition("id.%delta", 1, '=')
->sort('id')
->execute();
$this->assertResult();
}
protected function assertResult() {
$assert = array();
$expected = func_get_args();

View file

@ -1179,7 +1179,7 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
'kernel',
// @see \Drupal\simpletest\TestBase::prepareEnvironment()
'generatedTestFiles',
// @see \Drupal\simpletest\KernelTestBase::containerBuild()
// Properties from the old KernelTestBase class that has been removed.
'keyValueFactory',
);
if (in_array($name, $denied) || strpos($name, 'original') === 0) {
@ -1209,6 +1209,9 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
* {@inheritdoc}
*/
public static function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE) {
// Cast objects implementing MarkupInterface to string instead of
// relying on PHP casting them to string depending on what they are being
// comparing with.
$expected = static::castSafeStrings($expected);
$actual = static::castSafeStrings($actual);
parent::assertEquals($expected, $actual, $message, $delta, $maxDepth, $canonicalize, $ignoreCase);