upgrades core to 8.4.2

This commit is contained in:
Bachir Soussi Chiadmi
2017-11-14 16:09:54 +01:00
parent bd60eff9b3
commit c2b4e25be4
3504 changed files with 140306 additions and 38684 deletions
@@ -6,7 +6,7 @@ namespace Drupal\KernelTests;
* Translates Simpletest assertion methods to PHPUnit.
*
* Protected methods are custom. Public static methods override methods of
* \PHPUnit_Framework_Assert.
* \PHPUnit\Framework\Assert.
*
* @deprecated Scheduled for removal in Drupal 9.0.0. Use PHPUnit's native
* assert methods instead.
@@ -0,0 +1,165 @@
<?php
namespace Drupal\KernelTests\Config;
use Drupal\Core\Config\Schema\SequenceDataDefinition;
use Drupal\Core\Config\Schema\TypedConfigInterface;
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\Type\IntegerInterface;
use Drupal\Core\TypedData\Type\StringInterface;
use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\Validator\ConstraintViolationListInterface;
/**
* Tests config validation mechanism.
*
* @group Config
*/
class TypedConfigTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['config_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig('config_test');
}
/**
* Verifies that the Typed Data API is implemented correctly.
*/
public function testTypedDataAPI() {
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
$typed_config_manager = \Drupal::service('config.typed');
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
$typed_config = $typed_config_manager->get('config_test.validation');
// Test a primitive.
$string_data = $typed_config->get('llama');
$this->assertInstanceOf(StringInterface::class, $string_data);
$this->assertEquals('llama', $string_data->getValue());
// Test complex data.
$mapping = $typed_config->get('cat');
/** @var \Drupal\Core\TypedData\ComplexDataInterface $mapping */
$this->assertInstanceOf(ComplexDataInterface::class, $mapping);
$this->assertInstanceOf(StringInterface::class, $mapping->get('type'));
$this->assertEquals('kitten', $mapping->get('type')->getValue());
$this->assertInstanceOf(IntegerInterface::class, $mapping->get('count'));
$this->assertEquals(2, $mapping->get('count')->getValue());
// Verify the item metadata is available.
$this->assertInstanceOf(ComplexDataDefinitionInterface::class, $mapping->getDataDefinition());
$this->assertArrayHasKey('type', $mapping->getProperties());
$this->assertArrayHasKey('count', $mapping->getProperties());
// Test accessing sequences.
$sequence = $typed_config->get('giraffe');
/** @var \Drupal\Core\TypedData\ListInterface $sequence */
$this->assertInstanceOf(ComplexDataInterface::class, $sequence);
$this->assertInstanceOf(StringInterface::class, $sequence->get('hum1'));
$this->assertEquals('hum1', $sequence->get('hum1')->getValue());
$this->assertEquals('hum2', $sequence->get('hum2')->getValue());
$this->assertEquals(2, count($sequence->getIterator()));
// Verify the item metadata is available.
$this->assertInstanceOf(SequenceDataDefinition::class, $sequence->getDataDefinition());
// Test accessing typed config objects for simple config and config
// entities.
$typed_config_manager = \Drupal::service('config.typed');
$typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get());
$this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
$this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements()));
$config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
'id' => 'asterix',
'label' => 'Asterix',
'weight' => 11,
'style' => 'test_style',
]);
$typed_config = $typed_config_manager->createFromNameAndData($config_test_entity->getConfigDependencyName(), $config_test_entity->toArray());
$this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
$this->assertEquals(['uuid', 'langcode', 'status', 'dependencies', 'id', 'label', 'weight', 'style', 'size', 'size_value', 'protected_property'], array_keys($typed_config->getElements()));
}
/**
* Tests config validation via the Typed Data API.
*/
public function testSimpleConfigValidation() {
$config = \Drupal::configFactory()->getEditable('config_test.validation');
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
$typed_config_manager = \Drupal::service('config.typed');
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
$this->assertInstanceOf(ConstraintViolationListInterface::class, $result);
$this->assertEmpty($result);
// Test constraints on primitive types.
$config->set('llama', 'elephant');
$config->save();
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
// Its not a valid llama anymore.
$this->assertCount(1, $result);
$this->assertEquals('no valid llama', $result->get(0)->getMessage());
// Test constraints on mapping.
$config->set('llama', 'llama');
$config->set('cat.type', 'nyans');
$config->save();
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
$this->assertEmpty($result);
// Test constrains on nested mapping.
$config->set('cat.type', 'miaus');
$config->save();
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
$this->assertCount(1, $result);
$this->assertEquals('no valid cat', $result->get(0)->getMessage());
// Test constrains on sequences elements.
$config->set('cat.type', 'nyans');
$config->set('giraffe', ['muh', 'hum2']);
$config->save();
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
$this->assertCount(1, $result);
$this->assertEquals('Giraffes just hum', $result->get(0)->getMessage());
// Test constrains on the sequence itself.
$config->set('giraffe', ['hum', 'hum2', 'invalid-key' => 'hum']);
$config->save();
$typed_config = $typed_config_manager->get('config_test.validation');
$result = $typed_config->validate();
$this->assertCount(1, $result);
$this->assertEquals('giraffe', $result->get(0)->getPropertyPath());
$this->assertEquals('Invalid giraffe key.', $result->get(0)->getMessage());
// Validates mapping.
$typed_config = $typed_config_manager->get('config_test.validation');
$value = $typed_config->getValue();
unset($value['giraffe']);
$value['elephant'] = 'foo';
$typed_config->setValue($value);
$result = $typed_config->validate();
$this->assertCount(1, $result);
$this->assertEquals('', $result->get(0)->getPropertyPath());
$this->assertEquals('Missing giraffe.', $result->get(0)->getMessage());
}
}
@@ -70,7 +70,7 @@ class AttachedAssetsTest extends KernelTestBase {
$build['#attached']['library'][] = 'core/unknown';
$assets = AttachedAssets::createFromRenderArray($build);
$this->assertIdentical([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.');
$this->assertSame([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.');
}
/**
@@ -299,7 +299,8 @@ class AttachedAssetsTest extends KernelTestBase {
"-8_2",
"-8_3",
"-8_4",
"-5_1", // The external script.
// The external script.
"-5_1",
"-3_1",
"-3_2",
"0_1",
@@ -435,12 +436,12 @@ class AttachedAssetsTest extends KernelTestBase {
$dynamic_library = $library_discovery->getLibraryByName('common_test', 'dynamic_library');
$this->assertTrue(is_array($dynamic_library));
if ($this->assertTrue(isset($dynamic_library['version']))) {
$this->assertIdentical('1.0', $dynamic_library['version']);
$this->assertSame('1.0', $dynamic_library['version']);
}
// Make sure the dynamic library definition could be altered.
// @see common_test_library_info_alter()
if ($this->assertTrue(isset($dynamic_library['dependencies']))) {
$this->assertIdentical(['core/jquery'], $dynamic_library['dependencies']);
$this->assertSame(['core/jquery'], $dynamic_library['dependencies']);
}
}
@@ -0,0 +1,40 @@
<?php
namespace Drupal\KernelTests\Core\Batch;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests batch functionality.
*
* @group Batch
*/
class BatchKernelTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
require_once $this->root . '/core/includes/batch.inc';
}
/**
* Tests _batch_needs_update().
*/
public function testNeedsUpdate() {
// Before ever being called, the return value should be FALSE.
$this->assertEquals(FALSE, _batch_needs_update());
// Set the value to TRUE.
$this->assertEquals(TRUE, _batch_needs_update(TRUE));
// Check that without a parameter TRUE is returned.
$this->assertEquals(TRUE, _batch_needs_update());
// Set the value to FALSE.
$this->assertEquals(FALSE, _batch_needs_update(FALSE));
$this->assertEquals(FALSE, _batch_needs_update());
}
}
@@ -54,7 +54,7 @@ class GetFilenameTest extends KernelTestBase {
$non_existing_module = uniqid("", TRUE);
// Set a custom error handler so we can ignore the file not found error.
set_error_handler(function($severity, $message, $file, $line) {
set_error_handler(function ($severity, $message, $file, $line) {
// Skip error handling if this is a "file not found" error.
if (strstr($message, 'is missing from the file system:')) {
\Drupal::state()->set('get_filename_test_triggered_error', TRUE);
@@ -20,7 +20,7 @@ class ChainedFastBackendTest extends GenericCacheBackendUnitTestBase {
* A new ChainedFastBackend object.
*/
protected function createCacheBackend($bin) {
$consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin);
$consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin, 100);
$fast_backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum'));
$backend = new ChainedFastBackend($consistent_backend, $fast_backend, $bin);
// Explicitly register the cache bin as it can not work through the
@@ -11,6 +11,13 @@ use Drupal\Core\Cache\DatabaseBackend;
*/
class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
/**
* The max rows to use for test bins.
*
* @var int
*/
protected static $maxRows = 100;
/**
* Modules to enable.
*
@@ -25,7 +32,7 @@ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
* A new DatabaseBackend object.
*/
protected function createCacheBackend($bin) {
return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin);
return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin, static::$maxRows);
}
/**
@@ -40,12 +47,60 @@ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
$cid_long = str_repeat('愛€', 500);
$cached_value_long = $this->randomMachineName();
$backend->set($cid_long, $cached_value_long);
$this->assertIdentical($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");
$this->assertSame($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");
$cid_short = '愛1€';
$cached_value_short = $this->randomMachineName();
$backend->set($cid_short, $cached_value_short);
$this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
$this->assertSame($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
}
/**
* Tests the row count limiting of cache bin database tables.
*/
public function testGarbageCollection() {
$backend = $this->getCacheBackend();
$max_rows = static::$maxRows;
$this->assertSame(0, (int) $this->getNumRows());
// Fill to just the limit.
for ($i = 0; $i < $max_rows; $i++) {
// Ensure that each cache item created happens in a different millisecond,
// by waiting 1 ms (1000 microseconds). The garbage collection might
// otherwise keep less than exactly 100 records (which is acceptable for
// real-world cases, but not for this test).
usleep(1000);
$backend->set("test$i", $i);
}
$this->assertSame($max_rows, $this->getNumRows());
// Garbage collection has no effect.
$backend->garbageCollection();
$this->assertSame($max_rows, $this->getNumRows());
// Go one row beyond the limit.
$backend->set('test' . ($max_rows + 1), $max_rows + 1);
$this->assertSame($max_rows + 1, $this->getNumRows());
// Garbage collection removes one row: the oldest.
$backend->garbageCollection();
$this->assertSame($max_rows, $this->getNumRows());
$this->assertFalse($backend->get('test0'));
}
/**
* Gets the number of rows in the test cache bin database table.
*
* @return int
* The number of rows in the test cache bin database table.
*/
protected function getNumRows() {
$table = 'cache_' . $this->testBin;
$connection = $this->container->get('database');
$query = $connection->select($table);
$query->addExpression('COUNT(cid)', 'cid');
return (int) $query->execute()->fetchField();
}
}
@@ -66,7 +66,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
* @return \Drupal\Core\Cache\CacheBackendInterface
* Cache backend to test.
*/
protected abstract function createCacheBackend($bin);
abstract protected function createCacheBackend($bin);
/**
* Allows specific implementation to change the environment before a test run.
@@ -130,22 +130,22 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
public function testSetGet() {
$backend = $this->getCacheBackend();
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
$with_backslash = ['foo' => '\Drupal\foo\Bar'];
$backend->set('test1', $with_backslash);
$cached = $backend->get('test1');
$this->assert(is_object($cached), "Backend returned an object for cache id test1.");
$this->assertIdentical($with_backslash, $cached->data);
$this->assertSame($with_backslash, $cached->data);
$this->assertTrue($cached->valid, 'Item is marked as valid.');
// We need to round because microtime may be rounded up in the backend.
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
$backend->set('test2', ['value' => 3], REQUEST_TIME + 3);
$cached = $backend->get('test2');
$this->assert(is_object($cached), "Backend returned an object for cache id test2.");
$this->assertIdentical(['value' => 3], $cached->data);
$this->assertSame(['value' => 3], $cached->data);
$this->assertTrue($cached->valid, 'Item is marked as valid.');
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
$this->assertEqual($cached->expire, REQUEST_TIME + 3, 'Expire time is correct.');
@@ -158,22 +158,22 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
$this->assertEqual($cached->expire, REQUEST_TIME - 3, 'Expire time is correct.');
$this->assertIdentical(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4.");
$this->assertSame(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4.");
$with_eof = ['foo' => "\nEOF\ndata"];
$backend->set('test4', $with_eof);
$cached = $backend->get('test4');
$this->assert(is_object($cached), "Backend returned an object for cache id test4.");
$this->assertIdentical($with_eof, $cached->data);
$this->assertSame($with_eof, $cached->data);
$this->assertTrue($cached->valid, 'Item is marked as valid.');
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
$this->assertIdentical(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5.");
$this->assertSame(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5.");
$with_eof_and_semicolon = ['foo' => "\nEOF;\ndata"];
$backend->set('test5', $with_eof_and_semicolon);
$cached = $backend->get('test5');
$this->assert(is_object($cached), "Backend returned an object for cache id test5.");
$this->assertIdentical($with_eof_and_semicolon, $cached->data);
$this->assertSame($with_eof_and_semicolon, $cached->data);
$this->assertTrue($cached->valid, 'Item is marked as valid.');
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
@@ -182,7 +182,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
$backend->set('test6', $with_variable);
$cached = $backend->get('test6');
$this->assert(is_object($cached), "Backend returned an object for cache id test6.");
$this->assertIdentical($with_variable, $cached->data);
$this->assertSame($with_variable, $cached->data);
// Make sure that a cached object is not affected by changing the original.
$data = new \stdClass();
@@ -229,26 +229,26 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
public function testDelete() {
$backend = $this->getCacheBackend();
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
$backend->set('test1', 7);
$this->assert(is_object($backend->get('test1')), "Backend returned an object for cache id test1.");
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
$backend->set('test2', 3);
$this->assert(is_object($backend->get('test2')), "Backend returned an object for cache id %cid.");
$backend->delete('test1');
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion.");
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion.");
$this->assert(is_object($backend->get('test2')), "Backend still has an object for cache id test2.");
$backend->delete('test2');
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
$long_cid = str_repeat('a', 300);
$backend->set($long_cid, 'test');
$backend->delete($long_cid);
$this->assertIdentical(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
$this->assertSame(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
}
/**
@@ -275,7 +275,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
foreach ($variables as $cid => $value) {
$object = $backend->get($cid);
$this->assert(is_object($object), sprintf("Backend returned an object for cache id %s.", $cid));
$this->assertIdentical($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid));
$this->assertSame($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid));
}
}
@@ -300,9 +300,11 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
$reference = [
'test3',
'test7',
'test21', // Cid does not exist.
// Cid does not exist.
'test21',
'test6',
'test19', // Cid does not exist until added before second getMultiple().
// Cid does not exist until added before second getMultiple().
'test19',
'test2',
];
@@ -440,20 +442,23 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
$backend->set('test7', 17);
$backend->delete('test1');
$backend->delete('test23'); // Nonexistent key should not cause an error.
// Nonexistent key should not cause an error.
$backend->delete('test23');
$backend->deleteMultiple([
'test3',
'test5',
'test7',
'test19', // Nonexistent key should not cause an error.
'test21', // Nonexistent key should not cause an error.
// Nonexistent key should not cause an error.
'test19',
// Nonexistent key should not cause an error.
'test21',
]);
// Test if expected keys have been deleted.
$this->assertIdentical(FALSE, $backend->get('test1'), "Cache id test1 deleted.");
$this->assertIdentical(FALSE, $backend->get('test3'), "Cache id test3 deleted.");
$this->assertIdentical(FALSE, $backend->get('test5'), "Cache id test5 deleted.");
$this->assertIdentical(FALSE, $backend->get('test7'), "Cache id test7 deleted.");
$this->assertSame(FALSE, $backend->get('test1'), "Cache id test1 deleted.");
$this->assertSame(FALSE, $backend->get('test3'), "Cache id test3 deleted.");
$this->assertSame(FALSE, $backend->get('test5'), "Cache id test5 deleted.");
$this->assertSame(FALSE, $backend->get('test7'), "Cache id test7 deleted.");
// Test if expected keys exist.
$this->assertNotIdentical(FALSE, $backend->get('test2'), "Cache id test2 exists.");
@@ -461,8 +466,8 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
$this->assertNotIdentical(FALSE, $backend->get('test6'), "Cache id test6 exists.");
// Test if that expected keys do not exist.
$this->assertIdentical(FALSE, $backend->get('test19'), "Cache id test19 does not exist.");
$this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
$this->assertSame(FALSE, $backend->get('test19'), "Cache id test19 does not exist.");
$this->assertSame(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
// Calling deleteMultiple() with an empty array should not cause an error.
$this->assertFalse($backend->deleteMultiple([]));
@@ -70,7 +70,8 @@ class DbDumpTest extends KernelTestBase {
parent::register($container);
$container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory')
->addArgument(new Reference('database'))
->addArgument(new Reference('cache_tags.invalidator.checksum'));
->addArgument(new Reference('cache_tags.invalidator.checksum'))
->addArgument(new Reference('settings'));
}
/**
@@ -205,8 +206,8 @@ class DbDumpTest extends KernelTestBase {
$this->assertTrue(Database::getConnection()
->schema()
->tableExists($table), SafeMarkup::format('Table @table created by the database script.', ['@table' => $table]));
$this->assertIdentical($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table]));
$this->assertIdentical($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table]));
$this->assertSame($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table]));
$this->assertSame($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table]));
}
// Ensure the test config has been replaced.
@@ -31,10 +31,14 @@ class SizeTest extends KernelTestBase {
];
$this->roundedTestCases = [
'2 bytes' => 2,
'1 MB' => ($kb * $kb) - 1, // rounded to 1 MB (not 1000 or 1024 kilobyte!)
round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651, // megabytes
round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124, // petabytes
round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827, // yottabytes
// Rounded to 1 MB (not 1000 or 1024 kilobyte!).
'1 MB' => ($kb * $kb) - 1,
// Megabytes.
round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651,
// Petabytes.
round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124,
// Yottabytes.
round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827,
];
}
@@ -278,12 +278,12 @@ class ConfigCRUDTest extends KernelTestBase {
$this->assertIdentical($storage->read($name), $data);
// Test that schema type enforcement can be overridden by trusting the data.
$this->assertIdentical(99, $config->get('int'));
$this->assertSame(99, $config->get('int'));
$config->set('int', '99')->save(TRUE);
$this->assertIdentical('99', $config->get('int'));
$this->assertSame('99', $config->get('int'));
// Test that re-saving without testing the data enforces the schema type.
$config->save();
$this->assertIdentical($data, $config->get());
$this->assertSame($data, $config->get());
// Test that setting an unsupported type for a config object with a schema
// fails.
@@ -161,11 +161,13 @@ class ConfigDependencyTest extends EntityKernelTestBase {
$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(),
]];
$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();
@@ -328,7 +330,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
$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.');
$this->assertSame([$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.
@@ -57,7 +57,7 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
// 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);
$this->assertSame($entity_1->_loadStamp, $entity_2->_loadStamp);
}
/**
@@ -51,4 +51,18 @@ class ConfigEntityStorageTest extends KernelTestBase {
$this->assertIdentical($entity->toArray(), $original_properties);
}
/**
* Tests the hasData() method for config entity storage.
*
* @covers \Drupal\Core\Config\Entity\ConfigEntityStorage::hasData
*/
public function testHasData() {
$storage = \Drupal::entityTypeManager()->getStorage('config_test');
$this->assertFalse($storage->hasData());
// Add a test config entity and check again.
$storage->create(['id' => $this->randomMachineName()])->save();
$this->assertTrue($storage->hasData());
}
}
@@ -80,7 +80,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
// 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());
$this->assertSame($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.');
@@ -100,12 +100,12 @@ class ConfigEntityUnitTest extends KernelTestBase {
'style' => 999
]);
$entity->save();
$this->assertIdentical('999', $entity->style);
$this->assertSame('999', $entity->style);
$entity->style = 999;
$entity->trustData()->save();
$this->assertIdentical(999, $entity->style);
$this->assertSame(999, $entity->style);
$entity->save();
$this->assertIdentical('999', $entity->style);
$this->assertSame('999', $entity->style);
}
}
@@ -210,22 +210,22 @@ class ConfigFileContentTest extends KernelTestBase {
$config_parsed = $filestorage->read($name);
$key = 'numeric keys';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
$this->assertSame($config_data[$key], $config_parsed[$key]);
$key = 'nested keys';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
$this->assertSame($config_data[$key], $config_parsed[$key]);
$key = 'HTML';
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$this->assertSame($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]);
$this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$key = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ';
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
$key = 'invalid xml';
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
$this->assertSame($config_data[$key], $config_parsed[$key]);
}
}
@@ -92,7 +92,7 @@ class ConfigImportRecreateTest extends KernelTestBase {
$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->assertSame($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
$this->configImporter->import();
@@ -95,7 +95,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
'node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id,
];
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
$this->assertIdentical($expected, $renames);
$this->assertSame($expected, $renames);
// Try to import the configuration. We expect an exception to be thrown
// because the staged entity is of a different type.
@@ -138,7 +138,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
'config_test.old::config_test.new'
];
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
$this->assertIdentical($expected, $renames);
$this->assertSame($expected, $renames);
// Try to import the configuration. We expect an exception to be thrown
// because the rename is for simple configuration.
@@ -351,7 +351,7 @@ class ConfigImporterTest extends KernelTestBase {
$name_deletee,
$name_other,
];
$this->assertIdentical($expected, $updates);
$this->assertSame($expected, $updates);
// Import.
$this->configImporter->import();
@@ -146,7 +146,7 @@ class ConfigInstallTest extends KernelTestBase {
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
$collection_storage = $active_storage->createCollection('entity');
$data = $collection_storage->read('config_test.dynamic.dotted.default');
$this->assertIdentical(['label' => 'entity'], $data);
$this->assertSame(['label' => 'entity'], $data);
// Test that the config manager uninstalls configuration from collections
// as expected.
@@ -185,7 +185,7 @@ class ConfigInstallTest extends KernelTestBase {
$data = $active_storage->read($name);
$this->assertTrue(isset($data['uuid']));
$data = $collection_storage->read($name);
$this->assertIdentical(['label' => 'entity'], $data);
$this->assertSame(['label' => 'entity'], $data);
}
/**
@@ -227,7 +227,7 @@ class ConfigInstallTest extends KernelTestBase {
$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]);
$this->assertSame('config_install_dependency_test', $entity->getDependencies()['module'][0]);
}
/**
@@ -40,22 +40,23 @@ class ConfigSchemaTest extends KernelTestBase {
*/
public function testSchemaMapping() {
// Nonexistent configuration key will have Undefined as metadata.
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
$this->assertSame(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 = [];
$expected['label'] = 'Undefined';
$expected['class'] = Undefined::class;
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$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'));
$this->assertSame(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'));
$this->assertSame(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'));
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema');
$expected = [];
$expected['label'] = 'Schema test data';
@@ -67,6 +68,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['mapping']['testlist'] = ['label' => 'Test list'];
$expected['type'] = 'config_schema_test.someschema';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.');
// Check type detection on elements with undefined types.
@@ -77,6 +79,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['class'] = Undefined::class;
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
$definition = $config->get('testlist')->getDataDefinition()->toArray();
$expected = [];
@@ -84,6 +87,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['class'] = Undefined::class;
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
$definition = $config->get('testnoschema')->getDataDefinition()->toArray();
$expected = [];
@@ -91,6 +95,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['class'] = Undefined::class;
$expected['type'] = 'undefined';
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.');
// Simple case, straight metadata.
@@ -109,6 +114,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['mapping']['_core']['type'] = '_core_config_info';
$expected['type'] = 'system.maintenance';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
// Mixed schema with ignore elements.
@@ -139,6 +145,7 @@ class ConfigSchemaTest extends KernelTestBase {
'type' => 'integer',
];
$expected['type'] = 'config_schema_test.ignore';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected);
@@ -149,6 +156,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['label'] = 'Irrelevant';
$expected['class'] = Ignore::class;
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected);
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray();
$expected['label'] = 'Indescribable';
@@ -160,8 +168,9 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['label'] = 'Image style';
$expected['class'] = Mapping::class;
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$expected['mapping']['name']['type'] = 'string';
$expected['mapping']['uuid']['type'] = 'string';
$expected['mapping']['uuid']['type'] = 'uuid';
$expected['mapping']['uuid']['label'] = 'UUID';
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
@@ -177,7 +186,7 @@ class ConfigSchemaTest extends KernelTestBase {
$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']['effects']['sequence']['mapping']['uuid']['type'] = 'uuid';
$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]';
@@ -193,6 +202,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['label'] = 'Image scale';
$expected['class'] = Mapping::class;
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$expected['mapping']['width']['type'] = 'integer';
$expected['mapping']['width']['label'] = 'Width';
$expected['mapping']['height']['type'] = 'integer';
@@ -220,6 +230,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['label'] = 'Mapping';
$expected['class'] = Mapping::class;
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$expected['mapping'] = [
'integer' => ['type' => 'integer'],
'string' => ['type' => 'string'],
@@ -241,6 +252,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['mapping']['testdescription']['label'] = 'Description';
$expected['type'] = 'config_schema_test.someschema.somemodule.*.*';
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection');
@@ -263,6 +275,7 @@ class ConfigSchemaTest extends KernelTestBase {
'label' => 'Test item nested one level',
'class' => StringData::class,
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
'unwrap_for_canonical_representation' => TRUE,
];
$this->assertEqual($definition, $expected);
@@ -274,6 +287,7 @@ class ConfigSchemaTest extends KernelTestBase {
'label' => 'Test item nested two levels',
'class' => StringData::class,
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
'unwrap_for_canonical_representation' => TRUE,
];
$this->assertEqual($definition, $expected);
@@ -285,6 +299,7 @@ class ConfigSchemaTest extends KernelTestBase {
'label' => 'Test item nested three levels',
'class' => StringData::class,
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
'unwrap_for_canonical_representation' => TRUE,
];
$this->assertEqual($definition, $expected);
}
@@ -321,7 +336,7 @@ class ConfigSchemaTest extends KernelTestBase {
$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.' );
$this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.');
}
/**
@@ -395,6 +410,76 @@ class ConfigSchemaTest extends KernelTestBase {
$this->assertIdentical($installed_data, $original_data);
}
/**
* Tests configuration sequence sorting using schemas.
*/
public function testConfigSaveWithSequenceSorting() {
$data = [
'keyed_sort' => [
'b' => '1',
'a' => '2',
],
'no_sort' => [
'b' => '2',
'a' => '1',
],
];
// Save config which has a schema that enforces sorting.
$this->config('config_schema_test.schema_sequence_sort')
->setData($data)
->save();
$this->assertSame(['a' => '2', 'b' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('keyed_sort'));
$this->assertSame(['b' => '2', 'a' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
$data = [
'value_sort' => ['b', 'a'],
'no_sort' => ['b', 'a'],
];
// Save config which has a schema that enforces sorting.
$this->config('config_schema_test.schema_sequence_sort')
->setData($data)
->save();
$this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
$this->assertSame(['b', 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
// Value sort does not preserve keys - this is intentional.
$data = [
'value_sort' => [1 => 'b', 2 => 'a'],
'no_sort' => [1 => 'b', 2 => 'a'],
];
// Save config which has a schema that enforces sorting.
$this->config('config_schema_test.schema_sequence_sort')
->setData($data)
->save();
$this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
$this->assertSame([1 => 'b', 2 => 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
// Test sorts do not destroy complex values.
$data = [
'complex_sort_value' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
'complex_sort_key' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
];
$this->config('config_schema_test.schema_sequence_sort')
->setData($data)
->save();
$this->assertSame([['foo' => 'a', 'bar' => 'a'], ['foo' => 'b', 'bar' => 'b']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
$this->assertSame(['a' => ['foo' => '2', 'bar' => '2'], 'b' => ['foo' => '1', 'bar' => '1']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
// Swap the previous test scenario around.
$data = [
'complex_sort_value' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
'complex_sort_key' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
];
$this->config('config_schema_test.schema_sequence_sort')
->setData($data)
->save();
$this->assertSame([['foo' => '1', 'bar' => '1'], ['foo' => '2', 'bar' => '2']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
$this->assertSame([['foo' => 'b', 'bar' => 'b'], ['foo' => 'a', 'bar' => 'a']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
}
/**
* Tests fallback to a greedy wildcard.
*/
@@ -405,6 +490,7 @@ class ConfigSchemaTest extends KernelTestBase {
$expected['label'] = 'Schema wildcard fallback test';
$expected['class'] = Mapping::class;
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
$expected['unwrap_for_canonical_representation'] = TRUE;
$expected['mapping']['langcode']['type'] = 'string';
$expected['mapping']['langcode']['label'] = 'Language code';
$expected['mapping']['_core']['type'] = '_core_config_info';
@@ -418,8 +504,8 @@ class ConfigSchemaTest extends KernelTestBase {
$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);
// well.
$this->assertSame($definition, $definition2);
}
/**
@@ -5,7 +5,6 @@ namespace Drupal\KernelTests\Core\Config;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests the functionality of SchemaCheckTrait.
*
@@ -189,7 +189,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
$data = ['foo' => 'bar'];
$result = $this->storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($data, $this->storage->read($name));
$this->assertSame($data, $this->storage->read($name));
// Create configuration in a new collection.
$new_storage = $this->storage->createCollection('collection.sub.new');
@@ -197,13 +197,13 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
$this->assertEqual([], $new_storage->listAll());
$new_storage->write($name, $data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($data, $new_storage->read($name));
$this->assertSame($data, $new_storage->read($name));
$this->assertEqual([$name], $new_storage->listAll());
$this->assertTrue($new_storage->exists($name));
$new_data = ['foo' => 'baz'];
$new_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $new_storage->read($name));
$this->assertSame($new_data, $new_storage->read($name));
// Create configuration in another collection.
$another_storage = $this->storage->createCollection('collection.sub.another');
@@ -211,7 +211,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
$this->assertEqual([], $another_storage->listAll());
$another_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $another_storage->read($name));
$this->assertSame($new_data, $another_storage->read($name));
$this->assertEqual([$name], $another_storage->listAll());
$this->assertTrue($another_storage->exists($name));
@@ -219,18 +219,18 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
$alt_storage = $this->storage->createCollection('alternate');
$alt_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $alt_storage->read($name));
$this->assertSame($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));
$this->assertSame($data, $this->storage->read($name));
// Check that the getAllCollectionNames() method works.
$this->assertIdentical(['alternate', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$this->assertSame(['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(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$this->assertSame(['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
@@ -240,19 +240,19 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
$this->assertEqual([], $parent_storage->listAll());
$parent_storage->write($name, $new_data);
$this->assertIdentical($result, TRUE);
$this->assertIdentical($new_data, $parent_storage->read($name));
$this->assertSame($new_data, $parent_storage->read($name));
$this->assertEqual([$name], $parent_storage->listAll());
$this->assertTrue($parent_storage->exists($name));
$this->assertIdentical(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$this->assertSame(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$parent_storage->deleteAll();
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$this->assertSame(['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->assertSame($data, $this->storage->read($name));
$this->storage->delete($name);
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
$this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
}
abstract protected function read($name);
@@ -68,8 +68,8 @@ class FileStorageTest extends ConfigStorageTestBase {
// @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.');
$this->assertSame(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.');
$this->assertSame([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.');
}
/**
@@ -16,14 +16,15 @@ class CaseSensitivityTest extends DatabaseTestBase {
db_insert('test')
->fields([
'name' => 'john', // <- A record already exists with name 'John'.
// A record already exists with name 'John'.
'name' => 'john',
'age' => 2,
'job' => 'Baby',
])
->execute();
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
$this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
$this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'john'])->fetchField();
$this->assertIdentical($saved_age, '2', 'Can retrieve after inserting.');
}
@@ -32,18 +32,18 @@ class ConnectionTest extends DatabaseTestBase {
// Try to open those targets another time, that should return the same objects.
$db1b = Database::getConnection('default', 'default');
$db2b = Database::getConnection('replica', 'default');
$this->assertIdentical($db1, $db1b, 'A second call to getConnection() returns the same object.');
$this->assertIdentical($db2, $db2b, 'A second call to getConnection() returns the same object.');
$this->assertSame($db1, $db1b, 'A second call to getConnection() returns the same object.');
$this->assertSame($db2, $db2b, 'A second call to getConnection() returns the same object.');
// Try to open an unknown target.
$unknown_target = $this->randomMachineName();
$db3 = Database::getConnection($unknown_target, 'default');
$this->assertNotNull($db3, 'Opening an unknown target returns a real connection object.');
$this->assertIdentical($db1, $db3, 'An unknown target opens the default connection.');
$this->assertSame($db1, $db3, 'An unknown target opens the default connection.');
// Try to open that unknown target another time, that should return the same object.
$db3b = Database::getConnection($unknown_target, 'default');
$this->assertIdentical($db3, $db3b, 'A second call to getConnection() returns the same object.');
$this->assertSame($db3, $db3b, 'A second call to getConnection() returns the same object.');
}
/**
@@ -61,7 +61,7 @@ class ConnectionTest extends DatabaseTestBase {
$db1 = Database::getConnection('default', 'default');
$db2 = Database::getConnection('replica', 'default');
$this->assertIdentical($db1, $db2, 'Both targets refer to the same connection.');
$this->assertSame($db1, $db2, 'Both targets refer to the same connection.');
}
/**
@@ -131,7 +131,7 @@ class ConnectionTest extends DatabaseTestBase {
try {
$db->query('SELECT * FROM {test}; SELECT * FROM {test_people}',
[],
[ 'allow_delimiter_in_query' => TRUE ]
['allow_delimiter_in_query' => TRUE]
);
$this->fail('No PDO exception thrown for multiple statements.');
}
@@ -40,7 +40,7 @@ class InsertDefaultsTest extends DatabaseTestBase {
}
$num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
$this->assertIdentical($num_records_before, $num_records_after, 'Do nothing as no fields are specified.');
$this->assertSame($num_records_before, $num_records_after, 'Do nothing as no fields are specified.');
}
/**
@@ -26,7 +26,7 @@ class InsertTest extends DatabaseTestBase {
$query->execute();
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
$this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
$this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField();
$this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.');
}
@@ -61,7 +61,7 @@ class InsertTest extends DatabaseTestBase {
$query->execute();
$num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
$this->assertIdentical($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
$this->assertSame($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
@@ -84,7 +84,8 @@ class InsertTest extends DatabaseTestBase {
]);
// Check how many records are queued for insertion.
$this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
$query->execute(); // This should run the insert, but leave the fields intact.
// This should run the insert, but leave the fields intact.
$query->execute();
// We should be able to specify values in any order if named.
$query->values([
@@ -103,7 +104,7 @@ class InsertTest extends DatabaseTestBase {
$query->execute();
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
$this->assertIdentical((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
$this->assertSame((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
@@ -24,7 +24,8 @@ class InvalidDataTest extends DatabaseTestBase {
'age' => 63,
'job' => 'Singer',
])->values([
'name' => 'John', // <-- Duplicate value on unique field.
// Duplicate value on unique field.
'name' => 'John',
'age' => 17,
'job' => 'Consultant',
])
@@ -66,4 +67,81 @@ class InvalidDataTest extends DatabaseTestBase {
}
}
/**
* Tests inserting with invalid data from a select query.
*/
public function testInsertDuplicateDataFromSelect() {
// Insert multiple records in 'test_people' where one has bad data
// (duplicate key). A 'Meredith' record has already been inserted
// in ::setUp.
db_insert('test_people')
->fields(['name', 'age', 'job'])
->values([
'name' => 'Elvis',
'age' => 63,
'job' => 'Singer',
])->values([
// Duplicate value on unique field 'name' for later INSERT in 'test'
// table.
'name' => 'John',
'age' => 17,
'job' => 'Consultant',
])
->values([
'name' => 'Frank',
'age' => 75,
'job' => 'Bass',
])
->execute();
try {
// Define the subselect query. Add ORDER BY to ensure we have consistent
// order in results. Will return:
// 0 => [name] => Elvis, [age] => 63, [job] => Singer
// 1 => [name] => Frank, [age] => 75, [job] => Bass
// 2 => [name] => John, [age] => 17, [job] => Consultant
// 3 => [name] => Meredith, [age] => 30, [job] => Speaker
// Records 0 and 1 should pass, record 2 should lead to integrity
// constraint violation.
$query = db_select('test_people', 'tp')
->fields('tp', ['name', 'age', 'job'])
->orderBy('name');
// Try inserting from the subselect.
db_insert('test')
->from($query)
->execute();
$this->fail('Insert succeeded when it should not have.');
}
catch (IntegrityConstraintViolationException $e) {
// Check if the second record was inserted.
$name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 75])->fetchField();
if ($name == 'Frank') {
if (!Database::getConnection()->supportsTransactions()) {
// This is an expected fail.
// Database engines that don't support transactions can leave partial
// inserts in place when an error occurs. This is the case for MySQL
// when running on a MyISAM table.
$this->pass("The whole transaction has not been rolled-back when a duplicate key insert occurs, this is expected because the database doesn't support transactions");
}
else {
$this->fail('The whole transaction is rolled back when a duplicate key insert occurs.');
}
}
else {
$this->pass('The whole transaction is rolled back when a duplicate key insert occurs.');
}
// Ensure the values for records 2 and 3 were not inserted.
$record = db_select('test')
->fields('test', ['name', 'age'])
->condition('age', [17, 30], 'IN')
->execute()->fetchObject();
$this->assertFalse($record, 'The rest of the insert aborted as expected.');
}
}
}
@@ -64,7 +64,7 @@ class LoggingTest extends DatabaseTestBase {
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica']);//->fetchCol();
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica'])->fetchCol();
$queries1 = Database::getLog('testing1');
@@ -30,31 +30,31 @@ class RegressionTest extends DatabaseTestBase {
])->execute();
$from_database = db_query('SELECT job FROM {test} WHERE job = :job', [':job' => $job])->fetchField();
$this->assertIdentical($job, $from_database, 'The database handles UTF-8 characters cleanly.');
$this->assertSame($job, $from_database, 'The database handles UTF-8 characters cleanly.');
}
/**
* Tests the db_table_exists() function.
*/
public function testDBTableExists() {
$this->assertIdentical(TRUE, db_table_exists('test'), 'Returns true for existent table.');
$this->assertIdentical(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.');
$this->assertSame(TRUE, db_table_exists('test'), 'Returns true for existent table.');
$this->assertSame(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.');
}
/**
* Tests the db_field_exists() function.
*/
public function testDBFieldExists() {
$this->assertIdentical(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.');
$this->assertIdentical(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.');
$this->assertSame(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.');
$this->assertSame(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.');
}
/**
* Tests the db_index_exists() function.
*/
public function testDBIndexExists() {
$this->assertIdentical(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.');
$this->assertIdentical(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.');
$this->assertSame(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.');
$this->assertSame(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.');
}
}
@@ -3,6 +3,7 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\RowCountException;
use Drupal\user\Entity\User;
@@ -312,7 +313,7 @@ class SelectComplexTest extends DatabaseTestBase {
$query = db_select('test');
$query->addField('test', 'job');
$query->condition('name', 'Paul');
$query->condition(db_or()->condition('age', 26)->condition('age', 27));
$query->condition((new Condition('OR'))->condition('age', 26)->condition('age', 27));
$job = $query->execute()->fetchField();
$this->assertEqual($job, 'Songwriter', 'Correct data retrieved.');
@@ -395,7 +396,7 @@ class SelectComplexTest extends DatabaseTestBase {
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');
$join_cond = (new Condition('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');
@@ -418,7 +419,7 @@ class SelectComplexTest extends DatabaseTestBase {
// Test a condition object that creates placeholders.
$t1_name = 'John';
$t2_name = 'George';
$join_cond = db_and()
$join_cond = (new Condition('AND'))
->condition('t1.name', $t1_name)
->condition('t2.name', $t2_name);
$query = db_select('test', 't1');
@@ -1,6 +1,7 @@
<?php
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\InvalidQueryException;
use Drupal\Core\Database\Database;
@@ -496,8 +497,7 @@ class SelectTest extends DatabaseTestBase {
];
$test_groups[] = [
'regex' => '#Singer',
'expected' => [
],
'expected' => [],
];
foreach ($test_groups as $test_group) {
@@ -2,6 +2,8 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Query\Condition;
/**
* Tests the Update query builder, complex queries.
*
@@ -15,7 +17,7 @@ class UpdateComplexTest extends DatabaseTestBase {
public function testOrConditionUpdate() {
$update = db_update('test')
->fields(['job' => 'Musician'])
->condition(db_or()
->condition((new Condition('OR'))
->condition('name', 'John')
->condition('name', 'Paul')
);
@@ -137,7 +137,7 @@ class DrupalKernelTest extends KernelTestBase {
// Check that the container itself is not among the persist IDs because it
// does not make sense to persist the container itself.
$persist_ids = $container->getParameter('persist_ids');
$this->assertIdentical(FALSE, array_search('service_container', $persist_ids));
$this->assertSame(FALSE, array_search('service_container', $persist_ids));
}
/**
@@ -184,6 +184,11 @@ class DrupalKernelTest extends KernelTestBase {
$pass = TRUE;
}
$this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot');
// Ensure no LogicException if DrupalKernel::setSitePath() is called with
// identical path after boot.
$path = $kernel->getSitePath();
$kernel->setSitePath($path);
}
}
@@ -572,6 +572,33 @@ class ConfigEntityQueryTest extends KernelTestBase {
->condition('*.level1.level2', 41)
->execute();
$this->assertResults([]);
// Make sure that "IS NULL" and "IS NOT NULL" work correctly with
// array-valued fields/keys.
$all = ['1', '2', '3', '4', '5'];
$this->queryResults = $this->factory->get('config_query_test')
->exists('array.level1.level2')
->execute();
$this->assertResults($all);
$this->queryResults = $this->factory->get('config_query_test')
->exists('array.level1')
->execute();
$this->assertResults($all);
$this->queryResults = $this->factory->get('config_query_test')
->exists('array')
->execute();
$this->assertResults($all);
$this->queryResults = $this->factory->get('config_query_test')
->notExists('array.level1.level2')
->execute();
$this->assertResults([]);
$this->queryResults = $this->factory->get('config_query_test')
->notExists('array.level1')
->execute();
$this->assertResults([]);
$this->queryResults = $this->factory->get('config_query_test')
->notExists('array')
->execute();
$this->assertResults([]);
}
/**
@@ -74,7 +74,7 @@ class ContentEntityChangedTest extends EntityKernelTestBase {
// We can't assert equality here because the created time is set to the
// request time, while instances of ChangedTestItem use the current
// timestamp every time. Therefor we check if the changed timestamp is
// timestamp every time. Therefore we check if the changed timestamp is
// between the created time and now.
$this->assertTrue(
($entity->getChangedTime() >= $entity->get('created')->value) &&
@@ -30,10 +30,10 @@ class ContentEntityNullStorageTest extends KernelTestBase {
* @see \Drupal\Core\Entity\Query\Null\Query
*/
public function testEntityQuery() {
$this->assertIdentical(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.');
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.');
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.');
$this->assertIdentical([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array');
$this->assertSame(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.');
$this->assertSame([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.');
$this->assertSame([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.');
$this->assertSame([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array');
}
@@ -179,12 +179,12 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) { }
public function submitForm(array &$form, FormStateInterface $form_state) {}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) { }
public function validateForm(array &$form, FormStateInterface $form_state) {}
/**
* Tests valid entries in the EntityAutocomplete Form API element.
@@ -353,7 +353,7 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
public function testEntityAutocompleteIdInput() {
/** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */
$form_builder = $this->container->get('form_builder');
//$form = $form_builder->getForm($this);
// $form = $form_builder->getForm($this);
$form_state = (new FormState())
->setMethod('GET')
->setValues([
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityTypeEvents;
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldException;
use Drupal\Core\Field\FieldStorageDefinitionEvents;
use Drupal\Core\Language\LanguageInterface;
use Drupal\entity_test_update\Entity\EntityTestUpdate;
@@ -114,7 +115,7 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
t('The %field_name field needs to be installed.', ['%field_name' => 'Revision ID']),
],
];
$this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
$this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
// Run the update and ensure the revision table is created.
$this->entityDefinitionUpdateManager->applyUpdates();
@@ -776,6 +777,11 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
// of a NOT NULL constraint.
$this->makeBaseFieldEntityKey();
// Field storage CRUD operations use the last installed entity type
// definition so we need to update it before doing any other field storage
// updates.
$this->entityDefinitionUpdateManager->updateEntityType($this->state->get('entity_test_update.entity_type'));
// Try to apply the update and verify they fail since we have a NULL value.
$message = 'An error occurs when trying to enabling NOT NULL constraints with NULL data.';
try {
@@ -817,4 +823,119 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
$this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'Entity and field schema data are correctly detected.');
}
/**
* Tests adding a base field with initial values.
*/
public function testInitialValue() {
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
$db_schema = $this->database->schema();
// Create two entities before adding the base field.
/** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */
$storage->create()->save();
$storage->create()->save();
// Add a base field with an initial value.
$this->addBaseField();
$storage_definition = BaseFieldDefinition::create('string')
->setLabel(t('A new base field'))
->setInitialValue('test value');
$this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update.");
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
$this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table.");
// Check that the initial values have been applied.
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
$entities = $storage->loadMultiple();
$this->assertEquals('test value', $entities[1]->get('new_base_field')->value);
$this->assertEquals('test value', $entities[2]->get('new_base_field')->value);
}
/**
* Tests adding a base field with initial values inherited from another field.
*/
public function testInitialValueFromField() {
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
$db_schema = $this->database->schema();
// Create two entities before adding the base field.
/** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */
$storage->create(['name' => 'First entity'])->save();
$storage->create(['name' => 'Second entity'])->save();
// Add a base field with an initial value inherited from another field.
$this->addBaseField();
$storage_definition = BaseFieldDefinition::create('string')
->setLabel(t('A new base field'))
->setInitialValueFromField('name');
$this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update.");
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
$this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table.");
// Check that the initial values have been applied.
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
$entities = $storage->loadMultiple();
$this->assertEquals('First entity', $entities[1]->get('new_base_field')->value);
$this->assertEquals('Second entity', $entities[2]->get('new_base_field')->value);
}
/**
* Tests the error handling when using initial values from another field.
*/
public function testInitialValueFromFieldErrorHandling() {
// Check that setting invalid values for 'initial value from field' doesn't
// work.
try {
$this->addBaseField();
$storage_definition = BaseFieldDefinition::create('string')
->setLabel(t('A new base field'))
->setInitialValueFromField('field_that_does_not_exist');
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
$this->fail('Using a non-existent field as initial value does not work.');
}
catch (FieldException $e) {
$this->assertEquals('Illegal initial value definition on new_base_field: The field field_that_does_not_exist does not exist.', $e->getMessage());
$this->pass('Using a non-existent field as initial value does not work.');
}
try {
$this->addBaseField();
$storage_definition = BaseFieldDefinition::create('integer')
->setLabel(t('A new base field'))
->setInitialValueFromField('name');
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
$this->fail('Using a field of a different type as initial value does not work.');
}
catch (FieldException $e) {
$this->assertEquals('Illegal initial value definition on new_base_field: The field types do not match.', $e->getMessage());
$this->pass('Using a field of a different type as initial value does not work.');
}
try {
// Add a base field that will not be stored in the shared tables.
$initial_field = BaseFieldDefinition::create('string')
->setName('initial_field')
->setLabel(t('An initial field'))
->setCardinality(2);
$this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field]);
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('initial_field', 'entity_test_update', 'entity_test', $initial_field);
// Now add the base field which will try to use the previously added field
// as the source of its initial values.
$new_base_field = BaseFieldDefinition::create('string')
->setName('new_base_field')
->setLabel(t('A new base field'))
->setInitialValueFromField('initial_field');
$this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field, 'new_base_field' => $new_base_field]);
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $new_base_field);
$this->fail('Using a field that is not stored in the shared tables as initial value does not work.');
}
catch (FieldException $e) {
$this->assertEquals('Illegal initial value definition on new_base_field: Both fields have to be stored in the shared entity tables.', $e->getMessage());
$this->pass('Using a field that is not stored in the shared tables as initial value does not work.');
}
}
}
@@ -16,6 +16,7 @@ use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\ListInterface;
use Drupal\Core\TypedData\Type\StringInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\entity_test\Entity\EntityTestComputedField;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
@@ -471,30 +472,30 @@ class EntityFieldTest extends EntityKernelTestBase {
// Make sure provided contextual information is right.
$entity_adapter = $entity->getTypedData();
$this->assertIdentical($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.');
$this->assertSame($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.');
$this->assertEqual($entity_adapter->getPropertyPath(), '');
$this->assertEqual($entity_adapter->getName(), '');
$this->assertEqual($entity_adapter->getParent(), NULL);
$field = $entity->user_id;
$this->assertIdentical($field->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertIdentical($field->getEntity(), $entity, 'getEntity() returns the entity.');
$this->assertSame($field->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertSame($field->getEntity(), $entity, 'getEntity() returns the entity.');
$this->assertEqual($field->getPropertyPath(), 'user_id');
$this->assertEqual($field->getName(), 'user_id');
$this->assertIdentical($field->getParent()->getValue(), $entity, 'Parent object matches.');
$this->assertSame($field->getParent()->getValue(), $entity, 'Parent object matches.');
$field_item = $field[0];
$this->assertIdentical($field_item->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertIdentical($field_item->getEntity(), $entity, 'getEntity() returns the entity.');
$this->assertSame($field_item->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertSame($field_item->getEntity(), $entity, 'getEntity() returns the entity.');
$this->assertEqual($field_item->getPropertyPath(), 'user_id.0');
$this->assertEqual($field_item->getName(), '0');
$this->assertIdentical($field_item->getParent(), $field, 'Parent object matches.');
$this->assertSame($field_item->getParent(), $field, 'Parent object matches.');
$item_value = $field_item->get('entity');
$this->assertIdentical($item_value->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertSame($item_value->getRoot()->getValue(), $entity, 'Entity is root object.');
$this->assertEqual($item_value->getPropertyPath(), 'user_id.0.entity');
$this->assertEqual($item_value->getName(), 'entity');
$this->assertIdentical($item_value->getParent(), $field_item, 'Parent object matches.');
$this->assertSame($item_value->getParent(), $field_item, 'Parent object matches.');
}
/**
@@ -737,6 +738,16 @@ class EntityFieldTest extends EntityKernelTestBase {
}
}
/**
* Test computed fields.
*/
public function testComputedFields() {
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
$entity = EntityTestComputedField::create([]);
$this->assertEquals($entity->computed_string_field->value, 'foo computed');
}
/**
* Executes the computed properties tests for the given entity type.
*
@@ -0,0 +1,53 @@
<?php
namespace Drupal\KernelTests\Core\Entity;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests loading entities by UUID.
*
* @group entity
*/
class EntityLoadByUuidTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['entity_test', 'user'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('entity_test');
}
/**
* Ensures that ::loadEntityByUuid() doesn't apply access checking.
*/
public function testLoadEntityByUuidAccessChecking() {
\Drupal::state()->set('entity_test_query_access', TRUE);
// Create two test entities.
$entity_0 = EntityTest::create([
'type' => 'entity_test',
'name' => 'published entity'
]);
$entity_0->save();
$entity_1 = EntityTest::create([
'type' => 'entity_test',
'name' => 'unpublished entity'
]);
$entity_1->save();
/** @var \Drupal\Core\Entity\EntityRepositoryInterface $repository */
$repository = \Drupal::service('entity.repository');
$this->assertEquals($entity_0->id(), $repository->loadEntityByUuid('entity_test', $entity_0->uuid())->id());
$this->assertEquals($entity_1->id(), $repository->loadEntityByUuid('entity_test', $entity_1->uuid())->id());
}
}
@@ -1,6 +1,7 @@
<?php
namespace Drupal\KernelTests\Core\Entity;
use Drupal\entity_test\Entity\EntityTestMulRev;
use Drupal\language\Entity\ConfigurableLanguage;
@@ -7,6 +7,7 @@ use Drupal\entity_test\Entity\EntityTest;
use Drupal\entity_test\Entity\EntityTestMulRev;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
@@ -19,6 +20,8 @@ use Symfony\Component\HttpFoundation\Request;
*/
class EntityQueryTest extends EntityKernelTestBase {
use EntityReferenceTestTrait;
/**
* Modules to enable.
*
@@ -94,23 +97,27 @@ class EntityQueryTest extends EntityKernelTestBase {
}
// Each unit is a list of field name, langcode and a column-value array.
$units[] = [$figures, 'en', [
'color' => 'red',
'shape' => 'triangle',
]];
'color' => 'red',
'shape' => 'triangle',
],
];
$units[] = [$figures, 'en', [
'color' => 'blue',
'shape' => 'circle',
]];
'color' => 'blue',
'shape' => 'circle',
],
];
// To make it easier to test sorting, the greetings get formats according
// to their langcode.
$units[] = [$greetings, 'tr', [
'value' => 'merhaba',
'format' => 'format-tr'
]];
'value' => 'merhaba',
'format' => 'format-tr',
],
];
$units[] = [$greetings, 'pl', [
'value' => 'siema',
'format' => 'format-pl'
]];
'value' => 'siema',
'format' => 'format-pl',
],
];
// Make these languages available to the greetings field.
ConfigurableLanguage::createFromLangcode('tr')->save();
ConfigurableLanguage::createFromLangcode('pl')->save();
@@ -311,6 +318,16 @@ class EntityQueryTest extends EntityKernelTestBase {
// Now we get everything.
$assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'];
$this->assertIdentical($results, $assert);
// Check that a query on the latest revisions without any condition returns
// the correct results.
$results = $this->factory->get('entity_test_mulrev')
->latestRevision()
->sort('id')
->sort('revision_id')
->execute();
$expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
$this->assertSame($expected, $results);
}
/**
@@ -866,7 +883,8 @@ class EntityQueryTest extends EntityKernelTestBase {
'description' => [
'value' => $this->randomString(),
'format' => 'format1',
]]);
],
]);
$term1->save();
$term2 = Term::create([
@@ -875,7 +893,8 @@ class EntityQueryTest extends EntityKernelTestBase {
'description' => [
'value' => $this->randomString(),
'format' => 'format2',
]]);
],
]);
$term2->save();
$ids = \Drupal::entityQuery('taxonomy_term')
@@ -887,9 +906,9 @@ class EntityQueryTest extends EntityKernelTestBase {
}
/**
* Test forward-revisions.
* Test pending revisions.
*/
public function testForwardRevisions() {
public function testPendingRevisions() {
// Ensure entity 14 is returned.
$result = \Drupal::entityQuery('entity_test_mulrev')
->condition('id', [14], 'IN')
@@ -914,7 +933,7 @@ class EntityQueryTest extends EntityKernelTestBase {
->execute();
$this->assertEqual(count($result), 1);
// Verify that field conditions on the default and forward revision are
// Verify that field conditions on the default and pending revision are
// work as expected.
$result = \Drupal::entityQuery('entity_test_mulrev')
->condition('id', [14], 'IN')
@@ -927,6 +946,54 @@ class EntityQueryTest extends EntityKernelTestBase {
->allRevisions()
->execute();
$this->assertEqual($result, [16 => '14']);
// Add another pending revision on the same entity and repeat the checks.
$entity->setNewRevision(TRUE);
$entity->isDefaultRevision(FALSE);
$entity->{$this->figures}->setValue([
'color' => 'red',
'shape' => 'square'
]);
$entity->save();
// A non-revisioned entity query should still return entity 14.
$result = $this->factory->get('entity_test_mulrev')
->condition('id', [14], 'IN')
->execute();
$this->assertCount(1, $result);
$this->assertSame([14 => '14'], $result);
// Now check an entity query on the latest revision.
$result = $this->factory->get('entity_test_mulrev')
->condition('id', [14], 'IN')
->latestRevision()
->execute();
$this->assertCount(1, $result);
$this->assertSame([17 => '14'], $result);
// Verify that field conditions on the default and pending revision still
// work as expected.
$result = $this->factory->get('entity_test_mulrev')
->condition('id', [14], 'IN')
->condition("$this->figures.color", $current_values[0]['color'])
->execute();
$this->assertSame([14 => '14'], $result);
// Now there are two revisions with same value for the figure color.
$result = $this->factory->get('entity_test_mulrev')
->condition('id', [14], 'IN')
->condition("$this->figures.color", 'red')
->allRevisions()
->execute();
$this->assertSame([16 => '14', 17 => '14'], $result);
// Check that querying for the latest revision returns the correct one.
$result = $this->factory->get('entity_test_mulrev')
->condition('id', [14], 'IN')
->condition("$this->figures.color", 'red')
->latestRevision()
->execute();
$this->assertSame([17 => '14'], $result);
}
/**
@@ -946,4 +1013,54 @@ class EntityQueryTest extends EntityKernelTestBase {
}
}
/**
* Tests that EntityQuery works when querying the same entity from two fields.
*/
public function testWithTwoEntityReferenceFieldsToSameEntityType() {
// Create two entity reference fields referring 'entity_test' entities.
$this->createEntityReferenceField('entity_test', 'entity_test', 'ref1', $this->randomMachineName(), 'entity_test');
$this->createEntityReferenceField('entity_test', 'entity_test', 'ref2', $this->randomMachineName(), 'entity_test');
// Create two entities to be referred.
$ref1 = EntityTest::create(['type' => 'entity_test']);
$ref1->save();
$ref2 = EntityTest::create(['type' => 'entity_test']);
$ref2->save();
// Create a main entity referring the previous created entities.
$entity = EntityTest::create([
'type' => 'entity_test',
'ref1' => $ref1->id(),
'ref2' => $ref2->id(),
]);
$entity->save();
// Check that works when referring with "{$field_name}".
$result = $this->factory->get('entity_test')
->condition('type', 'entity_test')
->condition('ref1', $ref1->id())
->condition('ref2', $ref2->id())
->execute();
$this->assertCount(1, $result);
$this->assertEquals($entity->id(), reset($result));
// Check that works when referring with "{$field_name}.target_id".
$result = $this->factory->get('entity_test')
->condition('type', 'entity_test')
->condition('ref1.target_id', $ref1->id())
->condition('ref2.target_id', $ref2->id())
->execute();
$this->assertCount(1, $result);
$this->assertEquals($entity->id(), reset($result));
// Check that works when referring with "{$field_name}.entity.id".
$result = $this->factory->get('entity_test')
->condition('type', 'entity_test')
->condition('ref1.entity.id', $ref1->id())
->condition('ref2.entity.id', $ref2->id())
->execute();
$this->assertCount(1, $result);
$this->assertEquals($entity->id(), reset($result));
}
}
@@ -247,24 +247,24 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
->create(['name' => $this->randomString()]);
// Test content entity autocreation.
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->set('user_id', $user);
});
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->set('user_id', $user, FALSE);
});
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->user_id->setValue($user);
});
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->user_id[0]->get('entity')->setValue($user);
});
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->user_id->setValue(['entity' => $user, 'target_id' => NULL]);
});
try {
$message = 'Setting both the entity and an invalid target_id property fails.';
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$user->save();
$entity->user_id->setValue(['entity' => $user, 'target_id' => $this->generateRandomEntityId()]);
});
@@ -273,32 +273,32 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
catch (\InvalidArgumentException $e) {
$this->pass($message);
}
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->user_id = $user;
});
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
$entity->user_id->entity = $user;
});
// Test config entity autocreation.
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->set('user_role', $role);
});
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->set('user_role', $role, FALSE);
});
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->user_role->setValue($role);
});
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->user_role[0]->get('entity')->setValue($role);
});
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->user_role->setValue(['entity' => $role, 'target_id' => NULL]);
});
try {
$message = 'Setting both the entity and an invalid target_id property fails.';
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$role->save();
$entity->user_role->setValue(['entity' => $role, 'target_id' => $this->generateRandomEntityId(TRUE)]);
});
@@ -307,10 +307,10 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
catch (\InvalidArgumentException $e) {
$this->pass($message);
}
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->user_role = $role;
});
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
$entity->user_role->entity = $role;
});
@@ -96,13 +96,11 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
$selection_options = [
'target_type' => 'node',
'handler' => 'default',
'handler_settings' => [
'target_bundles' => NULL,
// Add sorting.
'sort' => [
'field' => 'field_text.value',
'direction' => 'DESC',
],
'target_bundles' => NULL,
// Add sorting.
'sort' => [
'field' => 'field_text.value',
'direction' => 'DESC',
],
];
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
@@ -117,7 +115,7 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
$this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
// Assert sort by base field.
$selection_options['handler_settings']['sort'] = [
$selection_options['sort'] = [
'field' => 'nid',
'direction' => 'ASC',
];
@@ -88,9 +88,9 @@ class EntityRevisionTranslationTest extends EntityKernelTestBase {
}
/**
* Tests the translation values when saving a forward revision.
* Tests the translation values when saving a pending revision.
*/
public function testTranslationValuesWhenSavingForwardRevisions() {
public function testTranslationValuesWhenSavingPendingRevisions() {
$user = $this->createUser();
$storage = $this->entityManager->getStorage('entity_test_mulrev');
@@ -103,33 +103,33 @@ class EntityRevisionTranslationTest extends EntityKernelTestBase {
$entity->addTranslation('de', ['name' => 'default revision - de']);
$entity->save();
// Create a forward revision for the entity and change a field value for
// Create a pending revision for the entity and change a field value for
// both languages.
$forward_revision = $this->reloadEntity($entity);
$pending_revision = $this->reloadEntity($entity);
$forward_revision->setNewRevision();
$forward_revision->isDefaultRevision(FALSE);
$pending_revision->setNewRevision();
$pending_revision->isDefaultRevision(FALSE);
$forward_revision->name = 'forward revision - en';
$forward_revision->save();
$pending_revision->name = 'pending revision - en';
$pending_revision->save();
$forward_revision_translation = $forward_revision->getTranslation('de');
$forward_revision_translation->name = 'forward revision - de';
$forward_revision_translation->save();
$pending_revision_translation = $pending_revision->getTranslation('de');
$pending_revision_translation->name = 'pending revision - de';
$pending_revision_translation->save();
$forward_revision_id = $forward_revision->getRevisionId();
$forward_revision = $storage->loadRevision($forward_revision_id);
$pending_revision_id = $pending_revision->getRevisionId();
$pending_revision = $storage->loadRevision($pending_revision_id);
// Change the value of the field in the default language, save the forward
// Change the value of the field in the default language, save the pending
// revision and check that the value of the field in the second language is
// also taken from the forward revision, *not* from the default revision.
$forward_revision->name = 'updated forward revision - en';
$forward_revision->save();
// also taken from the pending revision, *not* from the default revision.
$pending_revision->name = 'updated pending revision - en';
$pending_revision->save();
$forward_revision = $storage->loadRevision($forward_revision_id);
$pending_revision = $storage->loadRevision($pending_revision_id);
$this->assertEquals($forward_revision->name->value, 'updated forward revision - en');
$this->assertEquals($forward_revision->getTranslation('de')->name->value, 'forward revision - de');
$this->assertEquals($pending_revision->name->value, 'updated pending revision - en');
$this->assertEquals($pending_revision->getTranslation('de')->name->value, 'pending revision - de');
}
/**
@@ -341,12 +341,12 @@ class EntityTranslationTest extends EntityLanguageTestBase {
// retrieve a translation referring to it.
$translation = $entity->getTranslation(LanguageInterface::LANGCODE_NOT_SPECIFIED);
$this->assertFalse($translation->isNewTranslation(), 'Existing translations are not marked as new.');
$this->assertIdentical($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.');
$this->assertSame($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.');
$entity->{$langcode_key}->value = $default_langcode;
$translation = $entity->getTranslation($default_langcode);
$this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.');
$this->assertSame($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.');
$translation = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT);
$this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.');
$this->assertSame($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.');
$this->assertTrue($entity->{$default_langcode_key}->value, 'The translation object is the default one.');
// Verify that trying to retrieve a translation for a locked language when
@@ -657,7 +657,7 @@ class EntityTranslationTest extends EntityLanguageTestBase {
$translation = $this->entityManager->getTranslationFromContext($entity2, $default_langcode);
$translation_build = $controller->view($translation);
$translation_output = (string) $renderer->renderRoot($translation_build);
$this->assertIdentical($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.');
$this->assertSame($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.');
// Checks that entity translations are rendered properly.
$controller = $this->entityManager->getViewBuilder($entity_type);
@@ -41,7 +41,7 @@ class EntityTypeConstraintsTest extends EntityKernelTestBase {
$this->assertEqual($default_constraints + $extra_constraints, $entity_type->getConstraints());
// Test altering constraints.
$altered_constraints = ['Test' => [ 'some_setting' => TRUE]];
$altered_constraints = ['Test' => ['some_setting' => TRUE]];
$this->state->set('entity_test_constraints.alter', $altered_constraints);
// Clear the cache in state instance in the Drupal container, so it can pick
// up the modified value.
@@ -101,8 +101,8 @@ class EntityTypedDataDefinitionTest extends KernelTestBase {
// Test that the definition factory creates the right definitions for all
// entity data types variants.
$this->assertEqual($this->typedDataManager->createDataDefinition('entity'), EntityDataDefinition::create());
$this->assertEqual($this->typedDataManager->createDataDefinition('entity:node'), EntityDataDefinition::create('node'));
$this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity')), serialize(EntityDataDefinition::create()));
$this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity:node')), serialize(EntityDataDefinition::create('node')));
// Config entities don't support typed data.
$entity_definition = EntityDataDefinition::create('node_type');
@@ -123,7 +123,7 @@ class EntityTypedDataDefinitionTest extends KernelTestBase {
// Test that the definition factory creates the right definition object.
$reference_definition2 = $this->typedDataManager->createDataDefinition('entity_reference');
$this->assertTrue($reference_definition2 instanceof DataReferenceDefinitionInterface);
$this->assertEqual($reference_definition2, $reference_definition);
$this->assertEqual(serialize($reference_definition2), serialize($reference_definition));
}
}
@@ -68,7 +68,7 @@ class FieldSqlStorageTest extends EntityKernelTestBase {
/**
* The table mapping for the tested entity type.
*
* @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping
* @var \Drupal\Core\Entity\Sql\DefaultTableMapping
*/
protected $tableMapping;
@@ -149,6 +149,10 @@ class FieldWidgetConstraintValidatorTest extends KernelTestBase {
$errors = $this->getErrorsForEntity($entity);
$this->assertEqual($errors[''], 'Entity level validation');
$entity->name->value = 'entity-level-violation-with-path';
$errors = $this->getErrorsForEntity($entity);
$this->assertEqual($errors['test][form][element'], 'Entity level validation');
}
}
@@ -2,9 +2,12 @@
namespace Drupal\KernelTests\Core\Entity;
use Drupal\entity_test\Entity\EntityTestWithRevisionLog;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
/**
* @coversDefaultClass \Drupal\Core\Entity\RevisionableContentEntityBase
@@ -15,7 +18,7 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['entity_test', 'system', 'user'];
public static $modules = ['entity_test_revlog', 'system', 'user'];
/**
* {@inheritdoc}
@@ -23,34 +26,102 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
protected function setUp() {
parent::setUp();
$this->installEntitySchema('entity_test_revlog');
$this->installEntitySchema('entity_test_mul_revlog');
$this->installEntitySchema('user');
$this->installSchema('system', 'sequences');
}
/**
* Tests the correct functionality CRUD operations of entity revisions.
*/
public function testRevisionableContentEntity() {
$entity_type = 'entity_test_mul_revlog';
$definition = \Drupal::entityManager()->getDefinition($entity_type);
$user = User::create(['name' => 'test name']);
$user->save();
/** @var \Drupal\entity_test\Entity\EntityTestWithRevisionLog $entity */
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
/** @var \Drupal\entity_test_mul_revlog\Entity\EntityTestMulWithRevisionLog $entity */
$entity = EntityTestMulWithRevisionLog::create([
'type' => $entity_type,
]);
$entity->save();
// Save the entity, this creates the first revision.
$entity->save();
$revision_ids[] = $entity->getRevisionId();
$this->assertItemsTableCount(1, $definition);
// Create the second revision.
$entity->setNewRevision(TRUE);
$random_timestamp = rand(1e8, 2e8);
$entity->setRevisionCreationTime($random_timestamp);
$entity->setRevisionUserId($user->id());
$entity->setRevisionLogMessage('This is my log message');
$entity->save();
$this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
$revision_id = $entity->getRevisionId();
$revision_ids[] = $revision_id;
$entity = \Drupal::entityTypeManager()->getStorage('entity_test_revlog')->loadRevision($revision_id);
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul_revlog');
$entity = $storage->loadRevision($revision_id);
$this->assertEquals($random_timestamp, $entity->getRevisionCreationTime());
$this->assertEquals($user->id(), $entity->getRevisionUserId());
$this->assertEquals($user->id(), $entity->getRevisionUser()->id());
$this->assertEquals('This is my log message', $entity->getRevisionLogMessage());
// Create the third revision.
$random_timestamp = rand(1e8, 2e8);
$this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
$this->assertItemsTableCount(3, $definition);
$revision_ids[] = $entity->getRevisionId();
// Create another 3 revisions.
foreach (range(1, 3) as $count) {
$timestamp = rand(1e8, 2e8);
$this->createRevision($entity, $user, $timestamp, 'This is my log message number: ' . $count);
$revision_ids[] = $entity->getRevisionId();
}
$this->assertItemsTableCount(6, $definition);
$this->assertEqual(6, count($revision_ids));
// Delete the first 3 revisions.
foreach (range(0, 2) as $key) {
$storage->deleteRevision($revision_ids[$key]);
}
// We should have only data for three revisions.
$this->assertItemsTableCount(3, $definition);
}
/**
* Asserts the ammount of items on entity related tables.
*
* @param int $count
* The number of items expected to be in revisions related tables.
* @param \Drupal\Core\Entity\EntityTypeInterface $definition
* The definition and metada of the entity being tested.
*/
protected function assertItemsTableCount($count, EntityTypeInterface $definition) {
$this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField());
$this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getDataTable() . '}')->fetchField());
$this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionTable() . '}')->fetchField());
$this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionDataTable() . '}')->fetchField());
}
/**
* Creates a new revision in the entity of this test class.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity where revision will be created.
* @param \Drupal\user\UserInterface $user
* The author of the new revision.
* @param int $timestamp
* The timestamp of the new revision.
* @param string $log_message
* The log message of the new revision.
*/
protected function createRevision(EntityInterface $entity, UserInterface $user, $timestamp, $log_message) {
$entity->setNewRevision(TRUE);
$entity->setRevisionCreationTime($timestamp);
$entity->setRevisionUserId($user->id());
$entity->setRevisionLogMessage($log_message);
$entity->save();
}
}
@@ -3,6 +3,15 @@
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
/**
* Tests validation constraints for ValidReferenceConstraintValidator.
@@ -11,6 +20,9 @@ use Drupal\Core\Field\BaseFieldDefinition;
*/
class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
use EntityReferenceTestTrait;
use ContentTypeCreationTrait;
/**
* The typed data manager to use.
*
@@ -21,7 +33,7 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'user'];
public static $modules = ['field', 'node', 'user'];
/**
* {@inheritdoc}
@@ -29,7 +41,12 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
protected function setUp() {
parent::setUp();
$this->installSchema('user', ['users_data']);
$this->installSchema('node', ['node_access']);
$this->installConfig('node');
$this->typedData = $this->container->get('typed_data_manager');
$this->createContentType(['type' => 'article', 'name' => 'Article']);
$this->createContentType(['type' => 'page', 'name' => 'Basic page']);
}
/**
@@ -66,4 +83,152 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
$this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.');
}
/**
* Tests the validation of pre-existing items in an entity reference field.
*/
public function testPreExistingItemsValidation() {
// Create two types of users, with and without access to bypass content
// access.
/** @var \Drupal\user\RoleInterface $role_with_access */
$role_with_access = Role::create(['id' => 'role_with_access']);
$role_with_access->grantPermission('access content');
$role_with_access->grantPermission('bypass node access');
$role_with_access->save();
/** @var \Drupal\user\RoleInterface $role_without_access */
$role_without_access = Role::create(['id' => 'role_without_access']);
$role_without_access->grantPermission('access content');
$role_without_access->save();
$user_with_access = User::create(['roles' => ['role_with_access']]);
$user_without_access = User::create(['roles' => ['role_without_access']]);
// Add an entity reference field.
$this->createEntityReferenceField(
'entity_test',
'entity_test',
'field_test',
'Field test',
'node',
'default',
['target_bundles' => ['article', 'page']],
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
);
// Create four test nodes.
$published_node = Node::create([
'title' => 'Test published node',
'type' => 'article',
'status' => NodeInterface::PUBLISHED,
]);
$published_node->save();
$unpublished_node = Node::create([
'title' => 'Test unpublished node',
'type' => 'article',
'status' => NodeInterface::NOT_PUBLISHED,
]);
$unpublished_node->save();
$different_bundle_node = Node::create([
'title' => 'Test page node',
'type' => 'page',
'status' => NodeInterface::PUBLISHED,
]);
$different_bundle_node->save();
$deleted_node = Node::create([
'title' => 'Test deleted node',
'type' => 'article',
'status' => NodeInterface::PUBLISHED,
]);
$deleted_node->save();
$referencing_entity = EntityTest::create([
'field_test' => [
['entity' => $published_node],
['entity' => $unpublished_node],
['entity' => $different_bundle_node],
['entity' => $deleted_node],
]
]);
// Check that users with access are able pass the validation for fields
// without pre-existing content.
$this->container->get('account_switcher')->switchTo($user_with_access);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(0, $violations);
// Check that users without access are not able pass the validation for
// fields without pre-existing content.
$this->container->get('account_switcher')->switchTo($user_without_access);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(1, $violations);
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
'%type' => 'node',
'%id' => $unpublished_node->id(),
]), $violations[0]->getMessage());
// Now save the referencing entity which will create a pre-existing state
// for it and repeat the checks. This time, the user without access should
// be able to pass the validation as well because it's not changing the
// pre-existing state.
$referencing_entity->save();
$this->container->get('account_switcher')->switchTo($user_with_access);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(0, $violations);
// Check that users without access are able pass the validation for fields
// with pre-existing content.
$this->container->get('account_switcher')->switchTo($user_without_access);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(0, $violations);
// Re-save the referencing entity and check that the referenced entity is
// not affected.
$referencing_entity->name->value = $this->randomString();
$referencing_entity->save();
$this->assertEquals($published_node->id(), $referencing_entity->field_test[0]->target_id);
$this->assertEquals($unpublished_node->id(), $referencing_entity->field_test[1]->target_id);
$this->assertEquals($different_bundle_node->id(), $referencing_entity->field_test[2]->target_id);
$this->assertEquals($deleted_node->id(), $referencing_entity->field_test[3]->target_id);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(0, $violations);
// Remove one of the referencable bundles and check that a pre-existing node
// of that bundle can not be referenced anymore.
$field = FieldConfig::loadByName('entity_test', 'entity_test', 'field_test');
$field->setSetting('handler_settings', ['target_bundles' => ['article']]);
$field->save();
$referencing_entity = $this->reloadEntity($referencing_entity);
$violations = $referencing_entity->field_test->validate();
$this->assertCount(1, $violations);
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
'%type' => 'node',
'%id' => $different_bundle_node->id(),
]), $violations[0]->getMessage());
// Delete the last node and check that the pre-existing reference is not
// valid anymore.
$deleted_node->delete();
$violations = $referencing_entity->field_test->validate();
$this->assertCount(2, $violations);
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
'%type' => 'node',
'%id' => $different_bundle_node->id(),
]), $violations[0]->getMessage());
$this->assertEquals(t('The referenced entity (%type: %id) does not exist.', [
'%type' => 'node',
'%id' => $deleted_node->id(),
]), $violations[1]->getMessage());
}
}
@@ -37,7 +37,7 @@ class IgnoreReplicaSubscriberTest extends KernelTestBase {
$db1 = Database::getConnection('default', 'default');
$db2 = Database::getConnection('replica', 'default');
$this->assertIdentical($db1, $db2, 'System Init ignores secondaries when requested.');
$this->assertSame($db1, $db2, 'System Init ignores secondaries when requested.');
}
}
@@ -44,4 +44,20 @@ class ModuleInstallerTest extends KernelTestBase {
$this->container->get('router.route_provider')->getRouteByName('router_test.1');
}
/**
* Tests config changes by hook_install() are saved for dependent modules.
*
* @covers ::install
*/
public function testConfigChangeOnInstall() {
// Install the child module so the parent is installed automatically.
$this->container->get('module_installer')->install(['module_handler_test_multiple_child']);
$modules = $this->config('core.extension')->get('module');
$this->assertArrayHasKey('module_handler_test_multiple', $modules, 'Module module_handler_test_multiple is installed');
$this->assertArrayHasKey('module_handler_test_multiple_child', $modules, 'Module module_handler_test_multiple_child is installed');
$this->assertEquals(1, $modules['module_handler_test_multiple'], 'Weight of module_handler_test_multiple is set.');
$this->assertEquals(1, $modules['module_handler_test_multiple_child'], 'Weight of module_handler_test_multiple_child is set.');
}
}
@@ -0,0 +1,65 @@
<?php
namespace Drupal\KernelTests\Core\Field\Entity;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\Entity\BaseFieldOverride;
use Drupal\Core\Field\FieldItemList;
use Drupal\KernelTests\KernelTestBase;
/**
* @coversDefaultClass \Drupal\Core\Field\Entity\BaseFieldOverride
* @group Field
*/
class BaseFieldOverrideTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = ['system'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('base_field_override');
}
/**
* @covers ::getClass
*
* @dataProvider getClassTestCases
*/
public function testGetClass($field_type, $base_field_class, $expected_override_class) {
$base_field = BaseFieldDefinition::create($field_type)
->setName('Test Field')
->setTargetEntityTypeId('entity_test');
if ($base_field_class) {
$base_field->setClass($base_field_class);
}
$override = BaseFieldOverride::createFromBaseFieldDefinition($base_field, 'test_bundle');
$this->assertEquals($expected_override_class, ltrim($override->getClass(), '\\'));
}
/**
* Test cases for ::testGetClass.
*/
public function getClassTestCases() {
return [
'String (default class)' => [
'string',
FALSE,
FieldItemList::class,
],
'String (overriden class)' => [
'string',
static::class,
static::class,
],
];
}
}
@@ -59,7 +59,7 @@ class NameMungingTest extends FileTestBase {
public function testMungeIgnoreInsecure() {
$this->config('system.file')->set('allow_insecure_uploads', 1)->save();
$munged_name = file_munge_filename($this->name, '');
$this->assertIdentical($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', ['%munged' => $munged_name, '%original' => $this->name]));
$this->assertSame($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', ['%munged' => $munged_name, '%original' => $this->name]));
}
/**
@@ -69,10 +69,10 @@ class NameMungingTest extends FileTestBase {
// Declare our extension as whitelisted. The declared extensions should
// be case insensitive so test using one with a different case.
$munged_name = file_munge_filename($this->nameWithUcExt, $this->badExtension);
$this->assertIdentical($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', ['%munged' => $munged_name, '%original' => $this->nameWithUcExt]));
$this->assertSame($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', ['%munged' => $munged_name, '%original' => $this->nameWithUcExt]));
// The allowed extensions should also be normalized.
$munged_name = file_munge_filename($this->name, strtoupper($this->badExtension));
$this->assertIdentical($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', ['%munged' => $munged_name, '%original' => $this->name]));
$this->assertSame($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', ['%munged' => $munged_name, '%original' => $this->name]));
}
/**
@@ -81,7 +81,7 @@ class NameMungingTest extends FileTestBase {
public function testUnMunge() {
$munged_name = file_munge_filename($this->name, '', FALSE);
$unmunged_name = file_unmunge_filename($munged_name);
$this->assertIdentical($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', ['%unmunged' => $unmunged_name, '%original' => $this->name]));
$this->assertSame($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', ['%unmunged' => $unmunged_name, '%original' => $this->name]));
}
}
@@ -106,13 +106,13 @@ class UrlRewritingTest extends FileTestBase {
// Shipped file.
$filepath = 'core/assets/vendor/jquery/jquery.min.js';
$url = file_create_url($filepath);
$this->assertIdentical(base_path() . $filepath, file_url_transform_relative($url));
$this->assertSame(base_path() . $filepath, file_url_transform_relative($url));
// Managed file.
$uri = $this->createUri();
$url = file_create_url($uri);
$public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath();
$this->assertIdentical(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url));
$this->assertSame(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url));
}
}
@@ -5,6 +5,7 @@ namespace Drupal\KernelTests\Core\Form;
use Drupal\Core\Form\FormState;
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\Core\Session\UserSession;
use Drupal\Core\Site\Settings;
use Drupal\KernelTests\KernelTestBase;
/**
@@ -101,4 +102,16 @@ class FormCacheTest extends KernelTestBase {
$account_switcher->switchBack();
}
/**
* Tests the form cache with an overridden cache expiration.
*/
public function testCacheCustomExpiration() {
// Override form cache expiration so that the cached form expired yesterday.
new Settings(['form_cache_expiration' => -1 * (24 * 60 * 60), 'hash_salt' => $this->randomMachineName()]);
\Drupal::formBuilder()->setCache($this->formBuildId, $this->form, $this->formState);
$cached_form_state = new FormState();
$this->assertFalse(\Drupal::formBuilder()->getCache($this->formBuildId, $cached_form_state), 'Expired form not returned from cache');
}
}
@@ -0,0 +1,92 @@
<?php
namespace Drupal\KernelTests\Core\Form;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests form validation mesages are displayed in the same order as the fields.
*
* @group Form
*/
class FormValidationMessageOrderTest extends KernelTestBase implements FormInterface {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'form_validation_error_message_order_test';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Prepare fields with weights specified.
$form['one'] = [
'#type' => 'textfield',
'#title' => 'One',
'#required' => TRUE,
'#weight' => 40,
];
$form['two'] = [
'#type' => 'textfield',
'#title' => 'Two',
'#required' => TRUE,
'#weight' => 30,
];
$form['three'] = [
'#type' => 'textfield',
'#title' => 'Three',
'#required' => TRUE,
'#weight' => 10,
];
$form['four'] = [
'#type' => 'textfield',
'#title' => 'Four',
'#required' => TRUE,
'#weight' => 20,
];
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => 'Submit',
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
/**
* Tests that fields validation messages are sorted in the fields order.
*/
public function testLimitValidationErrors() {
$form_state = new FormState();
$form_builder = $this->container->get('form_builder');
$form_builder->submitForm($this, $form_state);
$messages = drupal_get_messages();
$this->assertTrue(isset($messages['error']));
$error_messages = $messages['error'];
$this->assertEqual($error_messages[0], 'Three field is required.');
$this->assertEqual($error_messages[1], 'Four field is required.');
$this->assertEqual($error_messages[2], 'Two field is required.');
$this->assertEqual($error_messages[3], 'One field is required.');
}
}
@@ -218,14 +218,16 @@ class ToolkitGdTest extends KernelTestBase {
$operations += [
'rotate_5' => [
'function' => 'rotate',
'arguments' => ['degrees' => 5, 'background' => '#FF00FF'], // Fuchsia background.
// Fuchsia background.
'arguments' => ['degrees' => 5, 'background' => '#FF00FF'],
'width' => 41,
'height' => 23,
'corners' => array_fill(0, 4, $this->fuchsia),
],
'rotate_90' => [
'function' => 'rotate',
'arguments' => ['degrees' => 90, 'background' => '#FF00FF'], // Fuchsia background.
// Fuchsia background.
'arguments' => ['degrees' => 90, 'background' => '#FF00FF'],
'width' => 20,
'height' => 40,
'corners' => [$this->transparent, $this->red, $this->green, $this->blue],
@@ -365,7 +367,7 @@ class ToolkitGdTest extends KernelTestBase {
if ($image->getToolkit()->getType() == $image_original_type || $corner != $this->transparent) {
$correct_colors = $this->colorsAreEqual($color, $corner);
$this->assertTrue($correct_colors, SafeMarkup::format('Image %file object after %action action has the correct color placement at corner %corner.',
['%file' => $file, '%action' => $op, '%corner' => $key]));
['%file' => $file, '%action' => $op, '%corner' => $key]));
}
}
}
@@ -78,7 +78,7 @@ class DatabaseStorageExpirableTest extends StorageTestBase {
// Ensure that an item with the same name exists in the other collection.
$stores[1]->set('foo', $this->objects[5]);
$result = $stores[0]->getAll();
// Not using assertIdentical(), since the order is not defined for getAll().
// Not using assertSame(), since the order is not defined for getAll().
$this->assertEqual(count($result), count($values));
foreach ($result as $key => $value) {
$this->assertEqual($values[$key], $value);
@@ -39,7 +39,7 @@ class GarbageCollectionTest extends KernelTestBase {
for ($i = 0; $i <= 3; $i++) {
$store->setWithExpire('key_' . $i, $this->randomObject(), rand(500, 100000));
}
$this->assertIdentical(sizeof($store->getAll()), 4, 'Four items were written to the storage.');
$this->assertIdentical(count($store->getAll()), 4, 'Four items were written to the storage.');
// Manually expire the data.
for ($i = 0; $i <= 3; $i++) {
@@ -31,9 +31,15 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
/**
* Tests CRUD operations.
*
* @covers \Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage::hasData
*/
public function testCRUD() {
$default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_label');
$this->assertFalse($storage->hasData());
// Verify default properties on a newly created empty entity.
$empty = EntityTestLabel::create();
$this->assertIdentical($empty->id->value, NULL);
@@ -108,6 +114,9 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
$this->fail('EntityMalformedException was not thrown.');
}
// Verify that hasData() returns the expected result.
$this->assertTrue($storage->hasData());
// Verify that the correct status is returned and properties did not change.
$this->assertIdentical($status, SAVED_NEW);
$this->assertIdentical($entity_test->id(), $expected['id']);
@@ -157,4 +166,12 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
}
}
/**
* Tests uninstallation of a module that does not use the SQL entity storage.
*/
public function testUninstall() {
$uninstall_validator_reasons = \Drupal::service('content_uninstall_validator')->validate('keyvalue_test');
$this->assertEmpty($uninstall_validator_reasons);
}
}
@@ -102,7 +102,7 @@ abstract class StorageTestBase extends KernelTestBase {
// Ensure that an item with the same name exists in the other collection.
$stores[1]->set('foo', $this->objects[5]);
$result = $stores[0]->getAll();
// Not using assertIdentical(), since the order is not defined for getAll().
// Not using assertSame(), since the order is not defined for getAll().
$this->assertEqual(count($result), count($values));
foreach ($result as $key => $value) {
$this->assertEqual($values[$key], $value);
@@ -47,6 +47,21 @@ class LockTest extends KernelTestBase {
$this->assertTrue($success, 'Could acquire second lock a second time within the same request.');
$this->lock->release('lock_b');
// Test acquiring an releasing a lock with a long key (over 255 chars).
$long_key = 'long_key:BZoMiSf9IIPULsJ98po18TxJ6T4usd3MZrLE0d3qMgG6iAgDlOi1G3oMap7zI5df84l7LtJBg4bOj6XvpO6vDRmP5h5QbA0Bj9rVFiPIPAIQZ9qFvJqTALiK1OR3GpOkWQ4vgEA4LkY0UfznrWBeuK7IWZfv1um6DLosnVXd1z1cJjvbEUqYGJj92rwHfhYihLm8IO9t3P2gAvEkH5Mhc8GBoiTsIDnP01Te1kxGFHO3RuvJIxPnHmZtSdBggmuVN7x9';
$success = $this->lock->acquire($long_key);
$this->assertTrue($success, 'Could acquire long key lock.');
// This function is not part of the backend, but the default database
// backend implement it, we can here use it safely.
$is_free = $this->lock->lockMayBeAvailable($long_key);
$this->assertFalse($is_free, 'Long key lock is unavailable.');
$this->lock->release($long_key);
$is_free = $this->lock->lockMayBeAvailable($long_key);
$this->assertTrue($is_free, 'Long key lock has been released.');
}
/**
@@ -26,7 +26,7 @@ class MenuLinkTreeTest extends KernelTestBase {
/**
* The menu link plugin manager.
*
* @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
*/
protected $menuLinkManager;
@@ -111,7 +111,7 @@ class MenuLinkTreeTest extends KernelTestBase {
$parameters = new MenuTreeParameters();
$tree = $this->linkTree->load('mock', $parameters);
$count = function(array $tree) {
$count = function (array $tree) {
$sum = function ($carry, MenuLinkTreeElement $item) {
return $carry + $item->count();
};
@@ -16,16 +16,16 @@ use Drupal\Core\Path\AliasWhitelist;
class AliasTest extends PathUnitTestBase {
public function testCRUD() {
//Prepare database table.
// Prepare database table.
$connection = Database::getConnection();
$this->fixtures->createTables($connection);
//Create Path object.
// Create Path object.
$aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
$aliases = $this->fixtures->sampleUrlAliases();
//Create a few aliases
// Create a few aliases
foreach ($aliases as $idx => $alias) {
$aliasStorage->save($alias['source'], $alias['alias'], $alias['langcode']);
@@ -34,11 +34,11 @@ class AliasTest extends PathUnitTestBase {
$this->assertEqual(count($rows), 1, format_string('Created an entry for %alias.', ['%alias' => $alias['alias']]));
//Cache the pid for further tests.
// Cache the pid for further tests.
$aliases[$idx]['pid'] = $rows[0]->pid;
}
//Load a few aliases
// Load a few aliases
foreach ($aliases as $alias) {
$pid = $alias['pid'];
$loadedAlias = $aliasStorage->load(['pid' => $pid]);
@@ -49,7 +49,7 @@ class AliasTest extends PathUnitTestBase {
$loadedAlias = $aliasStorage->load(['source' => '/node/1']);
$this->assertEqual($loadedAlias['alias'], '/alias_for_node_1_und', 'The last created alias loaded by default.');
//Update a few aliases
// Update a few aliases
foreach ($aliases as $alias) {
$fields = $aliasStorage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']);
@@ -61,7 +61,7 @@ class AliasTest extends PathUnitTestBase {
$this->assertEqual($pid, $alias['pid'], format_string('Updated entry for pid %pid.', ['%pid' => $pid]));
}
//Delete a few aliases
// Delete a few aliases
foreach ($aliases as $alias) {
$pid = $alias['pid'];
$aliasStorage->delete(['pid' => $pid]);
@@ -74,11 +74,11 @@ class AliasTest extends PathUnitTestBase {
}
public function testLookupPath() {
//Prepare database table.
// Prepare database table.
$connection = Database::getConnection();
$this->fixtures->createTables($connection);
//Create AliasManager and Path object.
// Create AliasManager and Path object.
$aliasManager = $this->container->get('path.alias_manager');
$aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
@@ -44,8 +44,10 @@ class PathValidatorTest extends KernelTestBase {
'PUT',
'PATCH',
'DELETE',
NULL, // Used in CLI context.
FALSE, // If no request was even pushed onto the request stack, and hence
// Used in CLI context.
NULL,
// If no request was even pushed onto the request stack, and hence.
FALSE,
];
foreach ($methods as $method) {
if ($method === FALSE) {
@@ -59,7 +59,7 @@ class ContextPluginTest extends KernelTestBase {
$plugin->getContextValue('user');
}
catch (ContextException $e) {
$this->assertIdentical("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.');
$this->assertSame("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.');
}
// Try to pass the wrong class type as a context value.
@@ -71,7 +71,7 @@ abstract class DiscoveryTestBase extends KernelTestBase {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertDefinitionIdentical(array $definition, array $expected_definition) {
$func = function (&$item){
$func = function (&$item) {
if ($item instanceof TranslatableMarkup) {
$item = (string) $item;
}
@@ -24,7 +24,7 @@ class QueueTest extends KernelTestBase {
$queue2 = new DatabaseQueue($this->randomMachineName(), Database::getConnection());
$queue2->createQueue();
$this->queueTest($queue1, $queue2);
$this->runQueueTest($queue1, $queue2);
}
/**
@@ -37,7 +37,7 @@ class QueueTest extends KernelTestBase {
$queue2 = new Memory($this->randomMachineName());
$queue2->createQueue();
$this->queueTest($queue1, $queue2);
$this->runQueueTest($queue1, $queue2);
}
/**
@@ -48,7 +48,7 @@ class QueueTest extends KernelTestBase {
* @param \Drupal\Core\Queue\QueueInterface $queue2
* An instantiated queue object.
*/
protected function queueTest($queue1, $queue2) {
protected function runQueueTest($queue1, $queue2) {
// Create four items.
$data = [];
for ($i = 0; $i < 4; $i++) {
@@ -111,8 +111,10 @@ class ContentNegotiationRoutingTest extends KernelTestBase {
$tests = [
// ['path', 'accept', 'content-type'],
['conneg/negotiate', '', 'text/html'], // 406?
['conneg/negotiate', '', 'text/html'], // 406?
// 406?
['conneg/negotiate', '', 'text/html'],
// 406?
['conneg/negotiate', '', 'text/html'],
// ['conneg/negotiate', '*/*', '??'],
['conneg/negotiate', 'application/json', 'application/json'],
['conneg/negotiate', 'application/xml', 'application/xml'],
@@ -155,7 +155,7 @@ class ExceptionHandlingTest extends KernelTestBase {
$kernel = \Drupal::getContainer()->get('http_kernel');
$response = $kernel->handle($request)->prepare($request);
$this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
$this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
// Test both that the backtrace is properly escaped, and that the unescaped
// string is not output at all.
@@ -178,7 +178,7 @@ class ExceptionHandlingTest extends KernelTestBase {
$kernel = \Drupal::getContainer()->get('http_kernel');
$response = $kernel->handle($request)->prepare($request);
$this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
$this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
// Test message is properly escaped, and that the unescaped string is not
// output at all.
@@ -192,10 +192,11 @@ class ExceptionHandlingTest extends KernelTestBase {
$kernel = \Drupal::getContainer()->get('http_kernel');
$response = $kernel->handle($request)->prepare($request);
// As the Content-type is text/plain the fact that the raw string is
// contained in the output does not matter.
// contained in the output would not matter, but because it is output by the
// final exception subscriber, it is printed as partial HTML, and hence
// escaped.
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
$this->setRawContent($response->getContent());
$this->assertRaw($string);
$this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException</em>: Not acceptable format: json&lt;script&gt;alert(123);&lt;/script&gt; in <em class="placeholder">', $response->getContent());
}
}
@@ -0,0 +1,71 @@
<?php
namespace Drupal\KernelTests\Core\Test;
use Drupal\FunctionalTests\BrowserMissingDependentModuleMethodTest;
use Drupal\FunctionalTests\BrowserMissingDependentModuleTest;
use Drupal\KernelTests\KernelTestBase;
/**
* @group Test
* @group FunctionalTests
*
* @coversDefaultClass \Drupal\Tests\BrowserTestBase
*/
class BrowserTestBaseTest extends KernelTestBase {
/**
* Tests that a test method is skipped when it requires a module not present.
*
* In order to catch checkRequirements() regressions, we have to make a new
* test object and run checkRequirements() here.
*
* @covers ::checkRequirements
* @covers ::checkModuleRequirements
*/
public function testMethodRequiresModule() {
require __DIR__ . '/../../../../fixtures/BrowserMissingDependentModuleMethodTest.php';
$stub_test = new BrowserMissingDependentModuleMethodTest();
// We have to setName() to the method name we're concerned with.
$stub_test->setName('testRequiresModule');
// We cannot use $this->setExpectedException() because PHPUnit would skip
// the test before comparing the exception type.
try {
$stub_test->publicCheckRequirements();
$this->fail('Missing required module throws skipped test exception.');
}
catch (\PHPUnit_Framework_SkippedTestError $e) {
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
}
}
/**
* Tests that a test case is skipped when it requires a module not present.
*
* In order to catch checkRequirements() regressions, we have to make a new
* test object and run checkRequirements() here.
*
* @covers ::checkRequirements
* @covers ::checkModuleRequirements
*/
public function testRequiresModule() {
require __DIR__ . '/../../../../fixtures/BrowserMissingDependentModuleTest.php';
$stub_test = new BrowserMissingDependentModuleTest();
// We have to setName() to the method name we're concerned with.
$stub_test->setName('testRequiresModule');
// We cannot use $this->setExpectedException() because PHPUnit would skip
// the test before comparing the exception type.
try {
$stub_test->publicCheckRequirements();
$this->fail('Missing required module throws skipped test exception.');
}
catch (\PHPUnit_Framework_SkippedTestError $e) {
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
}
}
}
@@ -77,7 +77,7 @@ class RegistryTest extends KernelTestBase {
$registry_base_theme->setThemeManager(\Drupal::theme());
$preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions'];
$this->assertIdentical([
$this->assertSame([
'template_preprocess',
'test_basetheme_preprocess_theme_test_template_test',
'test_subtheme_preprocess_theme_test_template_test',
@@ -85,20 +85,20 @@ class RegistryTest extends KernelTestBase {
], $preprocess_functions);
$preprocess_functions = $registry_sub_theme->get()['theme_test_template_test']['preprocess functions'];
$this->assertIdentical([
$this->assertSame([
'template_preprocess',
'test_basetheme_preprocess_theme_test_template_test',
'test_subtheme_preprocess_theme_test_template_test',
], $preprocess_functions);
$preprocess_functions = $registry_base_theme->get()['theme_test_template_test']['preprocess functions'];
$this->assertIdentical([
$this->assertSame([
'template_preprocess',
'test_basetheme_preprocess_theme_test_template_test',
], $preprocess_functions);
$preprocess_functions = $registry_base_theme->get()['theme_test_function_suggestions']['preprocess functions'];
$this->assertIdentical([
$this->assertSame([
'template_preprocess_theme_test_function_suggestions',
'test_basetheme_preprocess_theme_test_function_suggestions',
], $preprocess_functions, "Theme functions don't have template_preprocess but do have template_preprocess_HOOK");
@@ -125,7 +125,7 @@ class RegistryTest extends KernelTestBase {
$hook .= "$suggestion";
$expected_preprocess_functions[] = "test_theme_preprocess_$hook";
$preprocess_functions = $registry_theme->get()[$hook]['preprocess functions'];
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions.");
$this->assertSame($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions.");
} while ($suggestion = array_shift($suggestions));
$expected_preprocess_functions = [
@@ -136,10 +136,10 @@ class RegistryTest extends KernelTestBase {
];
$preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat']['preprocess functions'];
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.');
$this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.');
$preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__bearcat']['preprocess functions'];
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.');
$this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.');
$this->assertTrue(isset($registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose']), 'Preprocess function with an unimplemented lower-level suggestion is added to the registry.');
}
@@ -134,4 +134,4 @@ class ThemeRenderAndAutoescapeTest extends KernelTestBase {
}
class NonPrintable { }
class NonPrintable {}
@@ -42,6 +42,7 @@ class TwigWhiteListTest extends KernelTestBase {
*/
protected function setUp() {
parent::setUp();
\Drupal::service('theme_handler')->install(['test_theme']);
$this->installSchema('system', ['sequences']);
$this->installEntitySchema('node');
$this->installEntitySchema('user');
@@ -77,7 +77,7 @@ class TypedDataDefinitionTest extends KernelTestBase {
$map_definition2->setPropertyDefinition('one', DataDefinition::create('string'))
->setPropertyDefinition('two', DataDefinition::create('string'))
->setPropertyDefinition('three', DataDefinition::create('string'));
$this->assertEqual($map_definition, $map_definition2);
$this->assertEqual(serialize($map_definition), serialize($map_definition2));
}
/**
@@ -93,7 +93,7 @@ class TypedDataDefinitionTest extends KernelTestBase {
// Test using the definition factory.
$language_reference_definition2 = $this->typedDataManager->createDataDefinition('language_reference');
$this->assertTrue($language_reference_definition2 instanceof DataReferenceDefinitionInterface);
$this->assertEqual($language_reference_definition, $language_reference_definition2);
$this->assertEqual(serialize($language_reference_definition), serialize($language_reference_definition2));
}
}
@@ -399,7 +399,7 @@ class TypedDataTest extends KernelTestBase {
// Check that an all-pass filter leaves the list untouched.
$value = ['zero', 'one'];
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
$typed_data->filter(function(TypedDataInterface $item) {
$typed_data->filter(function (TypedDataInterface $item) {
return TRUE;
});
$this->assertEqual($typed_data->count(), 2);
@@ -411,7 +411,7 @@ class TypedDataTest extends KernelTestBase {
// Check that a none-pass filter empties the list.
$value = ['zero', 'one'];
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
$typed_data->filter(function(TypedDataInterface $item) {
$typed_data->filter(function (TypedDataInterface $item) {
return FALSE;
});
$this->assertEqual($typed_data->count(), 0);
@@ -419,7 +419,7 @@ class TypedDataTest extends KernelTestBase {
// Check that filtering correctly renumbers elements.
$value = ['zero', 'one', 'two'];
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
$typed_data->filter(function(TypedDataInterface $item) {
$typed_data->filter(function (TypedDataInterface $item) {
return $item->getValue() !== 'one';
});
$this->assertEqual($typed_data->count(), 2);
@@ -0,0 +1,45 @@
<?php
namespace Drupal\KernelTests\Core\Validation;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests various low level constrains provided by core.
*
* @group Validation
*/
class ConstraintsTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['config_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig('config_test');
}
/**
* @see \Drupal\Core\Validation\Plugin\Validation\Constraint\UuidConstraint
*/
public function testUuid() {
$typed_config_manager = \Drupal::service('config.typed');
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
$typed_config = $typed_config_manager->get('config_test.validation');
$typed_config->get('uuid')
->setValue(\Drupal::service('uuid')->generate());
$this->assertCount(0, $typed_config->validate());
$typed_config->get('uuid')
->setValue(\Drupal::service('uuid')->generate() . '-invalid');
$this->assertCount(1, $typed_config->validate());
}
}
@@ -15,7 +15,7 @@ trait FileSystemModuleDiscoveryDataProviderTrait {
*/
public function coreModuleListDataProvider() {
$module_dirs = array_keys(iterator_to_array(new \FilesystemIterator(__DIR__ . '/../../../modules/')));
$module_names = array_map(function($path) {
$module_names = array_map(function ($path) {
return str_replace(__DIR__ . '/../../../modules/', '', $path);
}, $module_dirs);
$modules_keyed = array_combine($module_names, $module_names);
@@ -18,10 +18,12 @@ use Drupal\Core\Language\Language;
use Drupal\Core\Site\Settings;
use Drupal\Core\Test\TestDatabase;
use Drupal\simpletest\AssertContentTrait;
use Drupal\simpletest\AssertHelperTrait;
use Drupal\Tests\AssertHelperTrait;
use Drupal\Tests\ConfigTestTrait;
use Drupal\Tests\RandomGeneratorTrait;
use Drupal\Tests\TestRequirementsTrait;
use Drupal\simpletest\TestServiceProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
use org\bovigo\vfs\vfsStream;
@@ -30,32 +32,50 @@ use org\bovigo\vfs\visitor\vfsStreamPrintVisitor;
/**
* Base class for functional integration tests.
*
* Tests extending this base class can access files and the database, but the
* entire environment is initially empty. Drupal runs in a minimal mocked
* environment, comparable to the one in the early installer.
* This base class should be useful for testing some types of integrations which
* don't require the overhead of a fully-installed Drupal instance, but which
* have many dependencies on parts of Drupal which can't or shouldn't be mocked.
*
* Unlike \Drupal\Tests\UnitTestCase, modules specified in the $modules
* property are automatically added to the service container for each test.
* The module/hook system is functional and operates on a fixed module list.
* Additional modules needed in a test may be loaded and added to the fixed
* module list.
* This base class partially boots a fixture Drupal. The state of the fixture
* Drupal is comparable to the state of a system during the early part of the
* installation process.
*
* Unlike \Drupal\simpletest\WebTestBase, the modules are only loaded, but not
* installed. Modules have to be installed manually, if needed.
* Tests extending this base class can access services and the database, but the
* system is initially empty. This Drupal runs in a minimal mocked filesystem
* which operates within vfsStream.
*
* Modules specified in the $modules property are added to the service container
* for each test. The module/hook system is functional. Additional modules
* needed in a test should override $modules. Modules specified in this way will
* be added to those specified in superclasses.
*
* Unlike \Drupal\Tests\BrowserTestBase, the modules are not installed. They are
* loaded such that their services and hooks are available, but the install
* process has not been performed.
*
* Other modules can be made available in this way using
* KernelTestBase::enableModules().
*
* Some modules can be brought into a fully-installed state using
* KernelTestBase::installConfig(), KernelTestBase::installSchema(), and
* KernelTestBase::installEntitySchema(). Alternately, tests which need modules
* to be fully installed could inherit from \Drupal\Tests\BrowserTestBase.
*
* @see \Drupal\Tests\KernelTestBase::$modules
* @see \Drupal\Tests\KernelTestBase::enableModules()
*
* @todo Extend ::setRequirementsFromAnnotation() and ::checkRequirements() to
* account for '@requires module'.
* @see \Drupal\Tests\KernelTestBase::installConfig()
* @see \Drupal\Tests\KernelTestBase::installEntitySchema()
* @see \Drupal\Tests\KernelTestBase::installSchema()
* @see \Drupal\Tests\BrowserTestBase
*/
abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements ServiceProviderInterface {
abstract class KernelTestBase extends TestCase implements ServiceProviderInterface {
use AssertLegacyTrait;
use AssertContentTrait;
use AssertHelperTrait;
use RandomGeneratorTrait;
use ConfigTestTrait;
use TestRequirementsTrait;
/**
* {@inheritdoc}
@@ -211,15 +231,6 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
chdir(static::getDrupalRoot());
}
/**
* Returns the drupal root directory.
*
* @return string
*/
protected static function getDrupalRoot() {
return dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
}
/**
* {@inheritdoc}
*/
@@ -678,7 +689,7 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
* Installs default configuration for a given list of modules.
*
* @param string|string[] $modules
* A list of modules for which to install default configuration.
* A module or list of modules for which to install default configuration.
*
* @throws \LogicException
* If any module in $modules is not enabled.
@@ -769,6 +780,9 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
/**
* Enables modules for this test.
*
* This method does not install modules fully. Services and hooks for the
* module are available, but the install process is not performed.
*
* To install test modules outside of the testing environment, add
* @code
* $settings['extension_discovery_scan_tests'] = TRUE;
@@ -9,6 +9,7 @@ use org\bovigo\vfs\visitor\vfsStreamStructureVisitor;
/**
* @coversDefaultClass \Drupal\KernelTests\KernelTestBase
*
* @group PHPUnit
* @group Test
* @group KernelTests
@@ -182,7 +183,7 @@ class KernelTestBaseTest extends KernelTestBase {
$output = \Drupal::service('renderer')->renderRoot($build);
$this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
$this->assertEquals($expected, $build['#children']);
$this->assertEquals($expected, $build['#markup']);
$this->assertEquals($expected, $output);
}
@@ -222,6 +223,60 @@ class KernelTestBaseTest extends KernelTestBase {
$this->assertEquals('Australia/Sydney', date_default_timezone_get());
}
/**
* Tests that a test method is skipped when it requires a module not present.
*
* In order to catch checkRequirements() regressions, we have to make a new
* test object and run checkRequirements() here.
*
* @covers ::checkRequirements
* @covers ::checkModuleRequirements
*/
public function testMethodRequiresModule() {
require __DIR__ . '/../../fixtures/KernelMissingDependentModuleMethodTest.php';
$stub_test = new KernelMissingDependentModuleMethodTest();
// We have to setName() to the method name we're concerned with.
$stub_test->setName('testRequiresModule');
// We cannot use $this->setExpectedException() because PHPUnit would skip
// the test before comparing the exception type.
try {
$stub_test->publicCheckRequirements();
$this->fail('Missing required module throws skipped test exception.');
}
catch (\PHPUnit_Framework_SkippedTestError $e) {
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
}
}
/**
* Tests that a test case is skipped when it requires a module not present.
*
* In order to catch checkRequirements() regressions, we have to make a new
* test object and run checkRequirements() here.
*
* @covers ::checkRequirements
* @covers ::checkModuleRequirements
*/
public function testRequiresModule() {
require __DIR__ . '/../../fixtures/KernelMissingDependentModuleTest.php';
$stub_test = new KernelMissingDependentModuleTest();
// We have to setName() to the method name we're concerned with.
$stub_test->setName('testRequiresModule');
// We cannot use $this->setExpectedException() because PHPUnit would skip
// the test before comparing the exception type.
try {
$stub_test->publicCheckRequirements();
$this->fail('Missing required module throws skipped test exception.');
}
catch (\PHPUnit_Framework_SkippedTestError $e) {
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
}
}
/**
* {@inheritdoc}
*/