Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023
This commit is contained in:
parent
2720a9ec4b
commit
f3791f1da3
1898 changed files with 54300 additions and 11481 deletions
129
core/tests/Drupal/KernelTests/AssertLegacyTrait.php
Normal file
129
core/tests/Drupal/KernelTests/AssertLegacyTrait.php
Normal file
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\KernelTests\AssertLegacyTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\KernelTests;
|
||||
|
||||
/**
|
||||
* Translates Simpletest assertion methods to PHPUnit.
|
||||
*
|
||||
* Protected methods are custom. Public static methods override methods of
|
||||
* \PHPUnit_Framework_Assert.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use PHPUnit's native
|
||||
* assert methods instead.
|
||||
*/
|
||||
trait AssertLegacyTrait {
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assert()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use self::assertTrue()
|
||||
* instead.
|
||||
*/
|
||||
protected function assert($actual, $message = '') {
|
||||
parent::assertTrue((bool) $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertTrue()
|
||||
*/
|
||||
public static function assertTrue($actual, $message = '') {
|
||||
if (is_bool($actual)) {
|
||||
parent::assertTrue($actual, $message);
|
||||
}
|
||||
else {
|
||||
parent::assertNotEmpty($actual, $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertFalse()
|
||||
*/
|
||||
public static function assertFalse($actual, $message = '') {
|
||||
if (is_bool($actual)) {
|
||||
parent::assertFalse($actual, $message);
|
||||
}
|
||||
else {
|
||||
parent::assertEmpty($actual, $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertEqual()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use self::assertEquals()
|
||||
* instead.
|
||||
*/
|
||||
protected function assertEqual($actual, $expected, $message = '') {
|
||||
$this->assertEquals($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertNotEqual()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use
|
||||
* self::assertNotEquals() instead.
|
||||
*/
|
||||
protected function assertNotEqual($actual, $expected, $message = '') {
|
||||
$this->assertNotEquals($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertIdentical()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use self::assertSame()
|
||||
* instead.
|
||||
*/
|
||||
protected function assertIdentical($actual, $expected, $message = '') {
|
||||
$this->assertSame($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertNotIdentical()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use
|
||||
* self::assertNotSame() instead.
|
||||
*/
|
||||
protected function assertNotIdentical($actual, $expected, $message = '') {
|
||||
$this->assertNotSame($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::assertIdenticalObject()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use self::assertEquals()
|
||||
* instead.
|
||||
*/
|
||||
protected function assertIdenticalObject($actual, $expected, $message = '') {
|
||||
// Note: ::assertSame checks whether its the same object. ::assertEquals
|
||||
// though compares
|
||||
|
||||
$this->assertEquals($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::pass()
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use self::assertTrue()
|
||||
* instead.
|
||||
*/
|
||||
protected function pass($message) {
|
||||
$this->assertTrue(TRUE, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\simpletest\TestBase::verbose()
|
||||
*/
|
||||
protected function verbose($message) {
|
||||
if (in_array('--debug', $_SERVER['argv'], TRUE)) {
|
||||
// Write directly to STDOUT to not produce unexpected test output.
|
||||
// The STDOUT stream does not obey output buffering.
|
||||
fwrite(STDOUT, $message . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
1073
core/tests/Drupal/KernelTests/KernelTestBase.php
Normal file
1073
core/tests/Drupal/KernelTests/KernelTestBase.php
Normal file
File diff suppressed because it is too large
Load diff
229
core/tests/Drupal/KernelTests/KernelTestBaseTest.php
Normal file
229
core/tests/Drupal/KernelTests/KernelTestBaseTest.php
Normal file
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\KernelTests\KernelTestBaseTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\KernelTests;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use org\bovigo\vfs\visitor\vfsStreamStructureVisitor;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\KernelTests\KernelTestBase
|
||||
* @group PHPUnit
|
||||
*/
|
||||
class KernelTestBaseTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* @covers ::setUpBeforeClass
|
||||
*/
|
||||
public function testSetUpBeforeClass() {
|
||||
// Note: PHPUnit automatically restores the original working directory.
|
||||
$this->assertSame(realpath(__DIR__ . '/../../../../'), getcwd());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::bootEnvironment
|
||||
*/
|
||||
public function testBootEnvironment() {
|
||||
$this->assertRegExp('/^simpletest\d{6}$/', $this->databasePrefix);
|
||||
$this->assertStringStartsWith('vfs://root/sites/simpletest/', $this->siteDirectory);
|
||||
$this->assertEquals(array(
|
||||
'root' => array(
|
||||
'sites' => array(
|
||||
'simpletest' => array(
|
||||
substr($this->databasePrefix, 10) => array(
|
||||
'files' => array(
|
||||
'config' => array(
|
||||
'active' => array(),
|
||||
'staging' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
), vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getDatabaseConnectionInfo
|
||||
*/
|
||||
public function testGetDatabaseConnectionInfoWithOutManualSetDbUrl() {
|
||||
$options = $this->container->get('database')->getConnectionOptions();
|
||||
$this->assertSame($this->databasePrefix, $options['prefix']['default']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::setUp
|
||||
*/
|
||||
public function testSetUp() {
|
||||
$this->assertTrue($this->container->has('request_stack'));
|
||||
$this->assertTrue($this->container->initialized('request_stack'));
|
||||
$request = $this->container->get('request_stack')->getCurrentRequest();
|
||||
$this->assertNotEmpty($request);
|
||||
$this->assertEquals('/', $request->getPathInfo());
|
||||
|
||||
$this->assertSame($request, \Drupal::request());
|
||||
|
||||
$this->assertEquals($this, $GLOBALS['conf']['container_service_providers']['test']);
|
||||
|
||||
$GLOBALS['destroy-me'] = TRUE;
|
||||
$this->assertArrayHasKey('destroy-me', $GLOBALS);
|
||||
|
||||
$schema = $this->container->get('database')->schema();
|
||||
$schema->createTable('foo', array(
|
||||
'fields' => array(
|
||||
'number' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
),
|
||||
));
|
||||
$this->assertTrue($schema->tableExists('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::setUp
|
||||
* @depends testSetUp
|
||||
*/
|
||||
public function testSetUpDoesNotLeak() {
|
||||
$this->assertArrayNotHasKey('destroy-me', $GLOBALS);
|
||||
|
||||
// Ensure that we have a different database prefix.
|
||||
$schema = $this->container->get('database')->schema();
|
||||
$this->assertFalse($schema->tableExists('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::register
|
||||
*/
|
||||
public function testRegister() {
|
||||
// Verify that this container is identical to the actual container.
|
||||
$this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $this->container);
|
||||
$this->assertSame($this->container, \Drupal::getContainer());
|
||||
|
||||
// The request service should never exist.
|
||||
$this->assertFalse($this->container->has('request'));
|
||||
|
||||
// Verify that there is a request stack.
|
||||
$request = $this->container->get('request_stack')->getCurrentRequest();
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Request', $request);
|
||||
$this->assertSame($request, \Drupal::request());
|
||||
|
||||
// Trigger a container rebuild.
|
||||
$this->enableModules(array('system'));
|
||||
|
||||
// Verify that this container is identical to the actual container.
|
||||
$this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $this->container);
|
||||
$this->assertSame($this->container, \Drupal::getContainer());
|
||||
|
||||
// The request service should never exist.
|
||||
$this->assertFalse($this->container->has('request'));
|
||||
|
||||
// Verify that there is a request stack (and that it persisted).
|
||||
$new_request = $this->container->get('request_stack')->getCurrentRequest();
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Request', $new_request);
|
||||
$this->assertSame($new_request, \Drupal::request());
|
||||
$this->assertSame($request, $new_request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getCompiledContainerBuilder
|
||||
*
|
||||
* The point of this test is to have integration level testing.
|
||||
*/
|
||||
public function testCompiledContainer() {
|
||||
$this->enableModules(['system', 'user']);
|
||||
$this->assertNull($this->installConfig('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getCompiledContainerBuilder
|
||||
* @depends testCompiledContainer
|
||||
*
|
||||
* The point of this test is to have integration level testing.
|
||||
*/
|
||||
public function testCompiledContainerIsDestructed() {
|
||||
$this->enableModules(['system', 'user']);
|
||||
$this->assertNull($this->installConfig('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::render
|
||||
*/
|
||||
public function testRender() {
|
||||
$type = 'processed_text';
|
||||
$element_info = $this->container->get('element_info');
|
||||
$this->assertSame(['#defaults_loaded' => TRUE], $element_info->getInfo($type));
|
||||
|
||||
$this->enableModules(array('filter'));
|
||||
|
||||
$this->assertNotSame($element_info, $this->container->get('element_info'));
|
||||
$this->assertNotEmpty($this->container->get('element_info')->getInfo($type));
|
||||
|
||||
$build = array(
|
||||
'#type' => 'html_tag',
|
||||
'#tag' => 'h3',
|
||||
'#value' => 'Inner',
|
||||
);
|
||||
$expected = "<h3>Inner</h3>\n";
|
||||
|
||||
$this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
|
||||
$output = \Drupal::service('renderer')->renderRoot($build);
|
||||
$this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
|
||||
|
||||
$this->assertEquals($expected, $build['#children']);
|
||||
$this->assertEquals($expected, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::render
|
||||
*/
|
||||
public function testRenderWithTheme() {
|
||||
$this->enableModules(array('system'));
|
||||
|
||||
$build = array(
|
||||
'#type' => 'textfield',
|
||||
'#name' => 'test',
|
||||
);
|
||||
$expected = '/' . preg_quote('<input type="text" name="test"', '/') . '/';
|
||||
|
||||
$this->assertArrayNotHasKey('theme', $GLOBALS);
|
||||
$output = \Drupal::service('renderer')->renderRoot($build);
|
||||
$this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
|
||||
|
||||
$this->assertRegExp($expected, (string) $build['#children']);
|
||||
$this->assertRegExp($expected, (string) $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
|
||||
// Check that all tables of the test instance have been deleted. At this
|
||||
// point the original database connection is restored so we need to prefix
|
||||
// the tables.
|
||||
$connection = Database::getConnection();
|
||||
if ($connection->databaseType() != 'sqlite') {
|
||||
$tables = $connection->schema()->findTables($this->databasePrefix . '%');
|
||||
$this->assertTrue(empty($tables), 'All test tables have been removed.');
|
||||
}
|
||||
else {
|
||||
$result = $connection->query("SELECT name FROM " . $this->databasePrefix . ".sqlite_master WHERE type = :type AND name LIKE :table_name AND name NOT LIKE :pattern", array(
|
||||
':type' => 'table',
|
||||
':table_name' => '%',
|
||||
':pattern' => 'sqlite_%',
|
||||
))->fetchAllKeyed(0, 0);
|
||||
|
||||
$this->assertTrue(empty($result), 'All test tables have been removed.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,621 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumperTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\DependencyInjection\Dumper {
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper
|
||||
* @group DependencyInjection
|
||||
*/
|
||||
class OptimizedPhpArrayDumperTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* The container builder instance.
|
||||
*
|
||||
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
|
||||
*/
|
||||
protected $containerBuilder;
|
||||
|
||||
/**
|
||||
* The definition for the container to build in tests.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $containerDefinition;
|
||||
|
||||
/**
|
||||
* Whether the dumper uses the machine-optimized format or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $machineFormat = TRUE;
|
||||
|
||||
/**
|
||||
* Stores the dumper class to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dumperClass = '\Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper';
|
||||
|
||||
/**
|
||||
* The dumper instance.
|
||||
*
|
||||
* @var \Symfony\Component\DependencyInjection\Dumper\DumperInterface
|
||||
*/
|
||||
protected $dumper;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
// Setup a mock container builder.
|
||||
$this->containerBuilder = $this->prophesize('\Symfony\Component\DependencyInjection\ContainerBuilder');
|
||||
$this->containerBuilder->getAliases()->willReturn(array());
|
||||
$this->containerBuilder->getParameterBag()->willReturn(new ParameterBag());
|
||||
$this->containerBuilder->getDefinitions()->willReturn(NULL);
|
||||
$this->containerBuilder->isFrozen()->willReturn(TRUE);
|
||||
|
||||
$definition = array();
|
||||
$definition['aliases'] = array();
|
||||
$definition['parameters'] = array();
|
||||
$definition['services'] = array();
|
||||
$definition['frozen'] = TRUE;
|
||||
$definition['machine_format'] = $this->machineFormat;
|
||||
|
||||
$this->containerDefinition = $definition;
|
||||
|
||||
// Create the dumper.
|
||||
$this->dumper = new $this->dumperClass($this->containerBuilder->reveal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an empty container works properly.
|
||||
*
|
||||
* @covers ::dump
|
||||
* @covers ::getArray
|
||||
* @covers ::supportsMachineFormat
|
||||
*/
|
||||
public function testDumpForEmptyContainer() {
|
||||
$serialized_definition = $this->dumper->dump();
|
||||
$this->assertEquals(serialize($this->containerDefinition), $serialized_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that alias processing works properly.
|
||||
*
|
||||
* @covers ::getAliases
|
||||
*
|
||||
* @dataProvider getAliasesDataProvider
|
||||
*/
|
||||
public function testGetAliases($aliases, $definition_aliases) {
|
||||
$this->containerDefinition['aliases'] = $definition_aliases;
|
||||
$this->containerBuilder->getAliases()->willReturn($aliases);
|
||||
$this->assertEquals($this->containerDefinition, $this->dumper->getArray(), 'Expected definition matches dump.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetAliases().
|
||||
*
|
||||
* @return array[]
|
||||
* Returns data-set elements with:
|
||||
* - aliases as returned by ContainerBuilder.
|
||||
* - aliases as expected in the container definition.
|
||||
*/
|
||||
public function getAliasesDataProvider() {
|
||||
return array(
|
||||
array(array(), array()),
|
||||
array(
|
||||
array('foo' => 'foo.alias'),
|
||||
array('foo' => 'foo.alias'),
|
||||
),
|
||||
array(
|
||||
array('foo' => 'foo.alias', 'foo.alias' => 'foo.alias.alias'),
|
||||
array('foo' => 'foo.alias.alias', 'foo.alias' => 'foo.alias.alias'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that parameter processing works properly.
|
||||
*
|
||||
* @covers ::getParameters
|
||||
* @covers ::prepareParameters
|
||||
* @covers ::escape
|
||||
* @covers ::dumpValue
|
||||
* @covers ::getReferenceCall
|
||||
*
|
||||
* @dataProvider getParametersDataProvider
|
||||
*/
|
||||
public function testGetParameters($parameters, $definition_parameters, $is_frozen) {
|
||||
$this->containerDefinition['parameters'] = $definition_parameters;
|
||||
$this->containerDefinition['frozen'] = $is_frozen;
|
||||
|
||||
$parameter_bag = new ParameterBag($parameters);
|
||||
$this->containerBuilder->getParameterBag()->willReturn($parameter_bag);
|
||||
$this->containerBuilder->isFrozen()->willReturn($is_frozen);
|
||||
|
||||
if (isset($parameters['reference'])) {
|
||||
$definition = new Definition('\stdClass');
|
||||
$this->containerBuilder->getDefinition('referenced_service')->willReturn($definition);
|
||||
}
|
||||
|
||||
$this->assertEquals($this->containerDefinition, $this->dumper->getArray(), 'Expected definition matches dump.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetParameters().
|
||||
*
|
||||
* @return array[]
|
||||
* Returns data-set elements with:
|
||||
* - parameters as returned by ContainerBuilder.
|
||||
* - parameters as expected in the container definition.
|
||||
* - frozen value
|
||||
*/
|
||||
public function getParametersDataProvider() {
|
||||
return array(
|
||||
array(array(), array(), TRUE),
|
||||
array(
|
||||
array('foo' => 'value_foo'),
|
||||
array('foo' => 'value_foo'),
|
||||
TRUE,
|
||||
),
|
||||
array(
|
||||
array('foo' => array('llama' => 'yes')),
|
||||
array('foo' => array('llama' => 'yes')),
|
||||
TRUE,
|
||||
),
|
||||
array(
|
||||
array('foo' => '%llama%', 'llama' => 'yes'),
|
||||
array('foo' => '%%llama%%', 'llama' => 'yes'),
|
||||
TRUE,
|
||||
),
|
||||
array(
|
||||
array('foo' => '%llama%', 'llama' => 'yes'),
|
||||
array('foo' => '%llama%', 'llama' => 'yes'),
|
||||
FALSE,
|
||||
),
|
||||
array(
|
||||
array('reference' => new Reference('referenced_service')),
|
||||
array('reference' => $this->getServiceCall('referenced_service')),
|
||||
TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that service processing works properly.
|
||||
*
|
||||
* @covers ::getServiceDefinitions
|
||||
* @covers ::getServiceDefinition
|
||||
* @covers ::dumpMethodCalls
|
||||
* @covers ::dumpCollection
|
||||
* @covers ::dumpCallable
|
||||
* @covers ::dumpValue
|
||||
* @covers ::getPrivateServiceCall
|
||||
* @covers ::getReferenceCall
|
||||
* @covers ::getServiceCall
|
||||
* @covers ::getParameterCall
|
||||
*
|
||||
* @dataProvider getDefinitionsDataProvider
|
||||
*/
|
||||
public function testGetServiceDefinitions($services, $definition_services) {
|
||||
$this->containerDefinition['services'] = $definition_services;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$this->containerBuilder->getDefinition('bar')->willReturn($bar_definition);
|
||||
|
||||
$private_definition = new Definition('\stdClass');
|
||||
$private_definition->setPublic(FALSE);
|
||||
|
||||
$this->containerBuilder->getDefinition('private_definition')->willReturn($private_definition);
|
||||
|
||||
$this->assertEquals($this->containerDefinition, $this->dumper->getArray(), 'Expected definition matches dump.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetServiceDefinitions().
|
||||
*
|
||||
* @return array[]
|
||||
* Returns data-set elements with:
|
||||
* - parameters as returned by ContainerBuilder.
|
||||
* - parameters as expected in the container definition.
|
||||
* - frozen value
|
||||
*/
|
||||
public function getDefinitionsDataProvider() {
|
||||
$base_service_definition = array(
|
||||
'class' => '\stdClass',
|
||||
'public' => TRUE,
|
||||
'file' => FALSE,
|
||||
'synthetic' => FALSE,
|
||||
'lazy' => FALSE,
|
||||
'arguments' => array(),
|
||||
'arguments_count' => 0,
|
||||
'properties' => array(),
|
||||
'calls' => array(),
|
||||
'scope' => ContainerInterface::SCOPE_CONTAINER,
|
||||
'shared' => TRUE,
|
||||
'factory' => FALSE,
|
||||
'configurator' => FALSE,
|
||||
);
|
||||
|
||||
// Test basic flags.
|
||||
$service_definitions[] = array() + $base_service_definition;
|
||||
|
||||
$service_definitions[] = array(
|
||||
'public' => FALSE,
|
||||
) + $base_service_definition;
|
||||
|
||||
$service_definitions[] = array(
|
||||
'file' => 'test_include.php',
|
||||
) + $base_service_definition;
|
||||
|
||||
$service_definitions[] = array(
|
||||
'synthetic' => TRUE,
|
||||
) + $base_service_definition;
|
||||
|
||||
$service_definitions[] = array(
|
||||
'lazy' => TRUE,
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a basic public Reference.
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array('foo', new Reference('bar')),
|
||||
'arguments_count' => 2,
|
||||
'arguments_expected' => $this->getCollection(array('foo', $this->getServiceCall('bar'))),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a public reference that should not throw an Exception.
|
||||
$reference = new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE);
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array($reference),
|
||||
'arguments_count' => 1,
|
||||
'arguments_expected' => $this->getCollection(array($this->getServiceCall('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE))),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a private shared service, denoted by having a Reference.
|
||||
$private_definition = array(
|
||||
'class' => '\stdClass',
|
||||
'public' => FALSE,
|
||||
'arguments_count' => 0,
|
||||
);
|
||||
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array('foo', new Reference('private_definition')),
|
||||
'arguments_count' => 2,
|
||||
'arguments_expected' => $this->getCollection(array(
|
||||
'foo',
|
||||
$this->getPrivateServiceCall('private_definition', $private_definition, TRUE),
|
||||
)),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a private non-shared service, denoted by having a Definition.
|
||||
$private_definition_object = new Definition('\stdClass');
|
||||
$private_definition_object->setPublic(FALSE);
|
||||
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array('foo', $private_definition_object),
|
||||
'arguments_count' => 2,
|
||||
'arguments_expected' => $this->getCollection(array(
|
||||
'foo',
|
||||
$this->getPrivateServiceCall(NULL, $private_definition),
|
||||
)),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a deep collection without a reference.
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array(array(array('foo'))),
|
||||
'arguments_count' => 1,
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a deep collection with a reference to resolve.
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array(array(new Reference('bar'))),
|
||||
'arguments_count' => 1,
|
||||
'arguments_expected' => $this->getCollection(array($this->getCollection(array($this->getServiceCall('bar'))))),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test a collection with a variable to resolve.
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array(new Parameter('llama_parameter')),
|
||||
'arguments_count' => 1,
|
||||
'arguments_expected' => $this->getCollection(array($this->getParameterCall('llama_parameter'))),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test objects that have _serviceId property.
|
||||
$drupal_service = new \stdClass();
|
||||
$drupal_service->_serviceId = 'bar';
|
||||
|
||||
$service_definitions[] = array(
|
||||
'arguments' => array($drupal_service),
|
||||
'arguments_count' => 1,
|
||||
'arguments_expected' => $this->getCollection(array($this->getServiceCall('bar'))),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test getMethodCalls.
|
||||
$calls = array(
|
||||
array('method', $this->getCollection(array())),
|
||||
array('method2', $this->getCollection(array())),
|
||||
);
|
||||
$service_definitions[] = array(
|
||||
'calls' => $calls,
|
||||
) + $base_service_definition;
|
||||
|
||||
$service_definitions[] = array(
|
||||
'scope' => ContainerInterface::SCOPE_PROTOTYPE,
|
||||
'shared' => FALSE,
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test factory.
|
||||
$service_definitions[] = array(
|
||||
'factory' => array(new Reference('bar'), 'factoryMethod'),
|
||||
'factory_expected' => array($this->getServiceCall('bar'), 'factoryMethod'),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test invalid factory - needed to test deep dumpValue().
|
||||
$service_definitions[] = array(
|
||||
'factory' => array(array('foo', 'llama'), 'factoryMethod'),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test properties.
|
||||
$service_definitions[] = array(
|
||||
'properties' => array('_value' => 'llama'),
|
||||
) + $base_service_definition;
|
||||
|
||||
// Test configurator.
|
||||
$service_definitions[] = array(
|
||||
'configurator' => array(new Reference('bar'), 'configureService'),
|
||||
'configurator_expected' => array($this->getServiceCall('bar'), 'configureService'),
|
||||
) + $base_service_definition;
|
||||
|
||||
$services_provided = array();
|
||||
$services_provided[] = array(
|
||||
array(),
|
||||
array(),
|
||||
);
|
||||
|
||||
foreach ($service_definitions as $service_definition) {
|
||||
$definition = $this->prophesize('\Symfony\Component\DependencyInjection\Definition');
|
||||
$definition->getClass()->willReturn($service_definition['class']);
|
||||
$definition->isPublic()->willReturn($service_definition['public']);
|
||||
$definition->getFile()->willReturn($service_definition['file']);
|
||||
$definition->isSynthetic()->willReturn($service_definition['synthetic']);
|
||||
$definition->isLazy()->willReturn($service_definition['lazy']);
|
||||
$definition->getArguments()->willReturn($service_definition['arguments']);
|
||||
$definition->getProperties()->willReturn($service_definition['properties']);
|
||||
$definition->getMethodCalls()->willReturn($service_definition['calls']);
|
||||
$definition->getScope()->willReturn($service_definition['scope']);
|
||||
$definition->getDecoratedService()->willReturn(NULL);
|
||||
$definition->getFactory()->willReturn($service_definition['factory']);
|
||||
$definition->getConfigurator()->willReturn($service_definition['configurator']);
|
||||
|
||||
// Preserve order.
|
||||
$filtered_service_definition = array();
|
||||
foreach ($base_service_definition as $key => $value) {
|
||||
$filtered_service_definition[$key] = $service_definition[$key];
|
||||
unset($service_definition[$key]);
|
||||
|
||||
if ($key == 'class' || $key == 'arguments_count') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($filtered_service_definition[$key] === $base_service_definition[$key]) {
|
||||
unset($filtered_service_definition[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add remaining properties.
|
||||
$filtered_service_definition += $service_definition;
|
||||
|
||||
// Allow to set _expected values.
|
||||
foreach (array('arguments', 'factory', 'configurator') as $key) {
|
||||
$expected = $key . '_expected';
|
||||
if (isset($filtered_service_definition[$expected])) {
|
||||
$filtered_service_definition[$key] = $filtered_service_definition[$expected];
|
||||
unset($filtered_service_definition[$expected]);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any remaining scope.
|
||||
unset($filtered_service_definition['scope']);
|
||||
|
||||
if (isset($filtered_service_definition['public']) && $filtered_service_definition['public'] === FALSE) {
|
||||
$services_provided[] = array(
|
||||
array('foo_service' => $definition->reveal()),
|
||||
array(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$services_provided[] = array(
|
||||
array('foo_service' => $definition->reveal()),
|
||||
array('foo_service' => $this->serializeDefinition($filtered_service_definition)),
|
||||
);
|
||||
}
|
||||
|
||||
return $services_provided;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to serialize a definition.
|
||||
*
|
||||
* Used to override serialization.
|
||||
*/
|
||||
protected function serializeDefinition(array $service_definition) {
|
||||
return serialize($service_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a service definition.
|
||||
*/
|
||||
protected function getServiceCall($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
return (object) array(
|
||||
'type' => 'service',
|
||||
'id' => $id,
|
||||
'invalidBehavior' => $invalid_behavior,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct InvalidArgumentException is thrown for getScope().
|
||||
*
|
||||
* @covers ::getServiceDefinition
|
||||
*
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testGetServiceDefinitionWithInvalidScope() {
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$bar_definition->setScope('foo_scope');
|
||||
$services['bar'] = $bar_definition;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
$this->dumper->getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that getDecoratedService() is unsupported.
|
||||
*
|
||||
* Tests that the correct InvalidArgumentException is thrown for
|
||||
* getDecoratedService().
|
||||
*
|
||||
* @covers ::getServiceDefinition
|
||||
*
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testGetServiceDefinitionForDecoratedService() {
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$bar_definition->setDecoratedService(new Reference('foo'));
|
||||
$services['bar'] = $bar_definition;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
$this->dumper->getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct RuntimeException is thrown for expressions.
|
||||
*
|
||||
* @covers ::dumpValue
|
||||
*
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
*/
|
||||
public function testGetServiceDefinitionForExpression() {
|
||||
$expression = new Expression();
|
||||
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$bar_definition->addArgument($expression);
|
||||
$services['bar'] = $bar_definition;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
$this->dumper->getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct RuntimeException is thrown for dumping an object.
|
||||
*
|
||||
* @covers ::dumpValue
|
||||
*
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
*/
|
||||
public function testGetServiceDefinitionForObject() {
|
||||
$service = new \stdClass();
|
||||
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$bar_definition->addArgument($service);
|
||||
$services['bar'] = $bar_definition;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
$this->dumper->getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct RuntimeException is thrown for dumping a resource.
|
||||
*
|
||||
* @covers ::dumpValue
|
||||
*
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
*/
|
||||
public function testGetServiceDefinitionForResource() {
|
||||
$resource = fopen('php://memory', 'r');
|
||||
|
||||
$bar_definition = new Definition('\stdClass');
|
||||
$bar_definition->addArgument($resource);
|
||||
$services['bar'] = $bar_definition;
|
||||
|
||||
$this->containerBuilder->getDefinitions()->willReturn($services);
|
||||
$this->dumper->getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a private service definition.
|
||||
*/
|
||||
protected function getPrivateServiceCall($id, $service_definition, $shared = FALSE) {
|
||||
if (!$id) {
|
||||
$hash = sha1(serialize($service_definition));
|
||||
$id = 'private__' . $hash;
|
||||
}
|
||||
return (object) array(
|
||||
'type' => 'private_service',
|
||||
'id' => $id,
|
||||
'value' => $service_definition,
|
||||
'shared' => $shared,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a machine-optimized collection.
|
||||
*/
|
||||
protected function getCollection($collection, $resolve = TRUE) {
|
||||
return (object) array(
|
||||
'type' => 'collection',
|
||||
'value' => $collection,
|
||||
'resolve' => $resolve,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a parameter definition.
|
||||
*/
|
||||
protected function getParameterCall($name) {
|
||||
return (object) array(
|
||||
'type' => 'parameter',
|
||||
'name' => $name,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* As Drupal Core does not ship with ExpressionLanguage component we need to
|
||||
* define a dummy, else it cannot be tested.
|
||||
*/
|
||||
namespace Symfony\Component\ExpressionLanguage {
|
||||
if (!class_exists('\Symfony\Component\ExpressionLanguage\Expression')) {
|
||||
/**
|
||||
* Dummy class to ensure non-existent Symfony component can be tested.
|
||||
*/
|
||||
class Expression {
|
||||
|
||||
/**
|
||||
* Gets the string representation of the expression.
|
||||
*/
|
||||
public function __toString() {
|
||||
return 'dummy_expression';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\DependencyInjection\Dumper\PhpArrayDumperTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Component\DependencyInjection\Dumper\PhpArrayDumper
|
||||
* @group DependencyInjection
|
||||
*/
|
||||
class PhpArrayDumperTest extends OptimizedPhpArrayDumperTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->machineFormat = FALSE;
|
||||
$this->dumperClass = '\Drupal\Component\DependencyInjection\Dumper\PhpArrayDumper';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function serializeDefinition(array $service_definition) {
|
||||
return $service_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getServiceCall($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($invalid_behavior !== ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
return sprintf('@?%s', $id);
|
||||
}
|
||||
|
||||
return sprintf('@%s', $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getParameterCall($name) {
|
||||
return '%' . $name . '%';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getCollection($collection, $resolve = TRUE) {
|
||||
return $collection;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains a test function for container 'file' include testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test function for container testing.
|
||||
*
|
||||
* @return string
|
||||
* A string just for testing.
|
||||
*/
|
||||
function container_test_file_service_test_service_function() {
|
||||
return 'Hello Container';
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\DependencyInjection\PhpArrayContainerTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Component\DependencyInjection\PhpArrayContainer
|
||||
* @group DependencyInjection
|
||||
*/
|
||||
class PhpArrayContainerTest extends ContainerTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->machineFormat = FALSE;
|
||||
$this->containerClass = '\Drupal\Component\DependencyInjection\PhpArrayContainer';
|
||||
$this->containerDefinition = $this->getMockContainerDefinition();
|
||||
$this->container = new $this->containerClass($this->containerDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a service definition.
|
||||
*/
|
||||
protected function getServiceCall($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($invalid_behavior !== ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
return sprintf('@?%s', $id);
|
||||
}
|
||||
|
||||
return sprintf('@%s', $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a service definition.
|
||||
*/
|
||||
protected function getParameterCall($name) {
|
||||
return '%' . $name . '%';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a machine-optimized '@notation'.
|
||||
*/
|
||||
protected function getCollection($collection, $resolve = TRUE) {
|
||||
return $collection;
|
||||
}
|
||||
|
||||
}
|
|
@ -68,15 +68,12 @@ class DrupalComponentTest extends UnitTestCase {
|
|||
*/
|
||||
protected function assertNoCoreUsage($class_path) {
|
||||
$contents = file_get_contents($class_path);
|
||||
if (preg_match_all('/^.*Drupal\\\Core.*$/m', $contents, $matches)) {
|
||||
foreach ($matches[0] as $line) {
|
||||
if ((strpos($line, '@see ') === FALSE)) {
|
||||
$this->fail(
|
||||
"Illegal reference to 'Drupal\\Core' namespace in $class_path"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
preg_match_all('/^.*Drupal\\\Core.*$/m', $contents, $matches);
|
||||
$matches = array_filter($matches[0], function($line) {
|
||||
// Filter references to @see as they don't really matter.
|
||||
return strpos($line, '@see') === FALSE;
|
||||
});
|
||||
$this->assertEmpty($matches, "Checking for illegal reference to 'Drupal\\Core' namespace in $class_path");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,6 +75,7 @@ class FileStorageReadOnlyTest extends PhpStorageTestBase {
|
|||
// Saving and deleting should always fail.
|
||||
$this->assertFalse($php_read->save($name, $code));
|
||||
$this->assertFalse($php_read->delete($name));
|
||||
unset($GLOBALS[$random]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -86,6 +86,7 @@ class FileStorageTest extends PhpStorageTestBase {
|
|||
|
||||
// Should still return TRUE if directory has already been deleted.
|
||||
$this->assertTrue($php->deleteAll(), 'Delete all succeeds with nothing to delete');
|
||||
unset($GLOBALS[$random]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ abstract class MTimeProtectedFileStorageBase extends PhpStorageTestBase {
|
|||
$this->assertSame($php->load($name), $this->expected[$i]);
|
||||
$this->assertSame($GLOBALS['hacked'], $this->expected[$i]);
|
||||
}
|
||||
unset($GLOBALS['hacked']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Tests\Component\PhpStorage;
|
||||
|
||||
use Drupal\Component\PhpStorage\PhpStorageInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
|
||||
|
@ -49,6 +50,9 @@ abstract class PhpStorageTestBase extends UnitTestCase {
|
|||
$php->load($name);
|
||||
$this->assertTrue($GLOBALS[$random], 'File saved correctly with correct value');
|
||||
|
||||
// Run additional asserts.
|
||||
$this->additionalAssertCRUD($php, $name);
|
||||
|
||||
// If the file was successfully loaded, it must also exist, but ensure the
|
||||
// exists() method returns that correctly.
|
||||
$this->assertTrue($php->exists($name), 'Exists works correctly');
|
||||
|
@ -60,6 +64,20 @@ abstract class PhpStorageTestBase extends UnitTestCase {
|
|||
// Ensure delete() can be called on a non-existing file. It should return
|
||||
// FALSE, but not trigger errors.
|
||||
$this->assertFalse($php->delete($name), 'Delete fails on missing file');
|
||||
unset($GLOBALS[$random]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional asserts to be run.
|
||||
*
|
||||
* @param \Drupal\Component\PhpStorage\PhpStorageInterface $php
|
||||
* The PHP storage object.
|
||||
* @param string $name
|
||||
* The name of an object. It should exist in the storage.
|
||||
*/
|
||||
protected function additionalAssertCRUD(PhpStorageInterface $php, $name) {
|
||||
// By default do not do any additional asserts. This is a way of extending
|
||||
// tests in contrib.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -259,4 +259,55 @@ class HtmlTest extends UnitTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Html::escape().
|
||||
*
|
||||
* @dataProvider providerEscape
|
||||
* @covers ::escape
|
||||
*/
|
||||
public function testEscape($expected, $text) {
|
||||
$this->assertEquals($expected, Html::escape($text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testEscape().
|
||||
*
|
||||
* @see testCheckPlain()
|
||||
*/
|
||||
public function providerEscape() {
|
||||
return array(
|
||||
array('Drupal', 'Drupal'),
|
||||
array('<script>', '<script>'),
|
||||
array('&lt;script&gt;', '<script>'),
|
||||
array('&#34;', '"'),
|
||||
array('"', '"'),
|
||||
array('&quot;', '"'),
|
||||
array(''', "'"),
|
||||
array('&#039;', '''),
|
||||
array('©', '©'),
|
||||
array('→', '→'),
|
||||
array('➼', '➼'),
|
||||
array('€', '€'),
|
||||
array('Drup<75>al', "Drup\x80al"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests relationship between escaping and decoding HTML entities.
|
||||
*
|
||||
* @covers ::decodeEntities
|
||||
* @covers ::escape
|
||||
*/
|
||||
public function testDecodeEntitiesAndEscape() {
|
||||
$string = "<em>répété</em>";
|
||||
$escaped = Html::escape($string);
|
||||
$this->assertSame('<em>répét&eacute;</em>', $escaped);
|
||||
$decoded = Html::decodeEntities($escaped);
|
||||
$this->assertSame('<em>répété</em>', $decoded);
|
||||
$decoded = Html::decodeEntities($decoded);
|
||||
$this->assertSame('<em>répété</em>', $decoded);
|
||||
$escaped = Html::escape($decoded);
|
||||
$this->assertSame('<em>répété</em>', $escaped);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
namespace Drupal\Tests\Component\Utility;
|
||||
|
||||
use Drupal\Component\Utility\Random;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -39,7 +38,7 @@ class RandomTest extends UnitTestCase {
|
|||
$random = new Random();
|
||||
for ($i = 0; $i <= 50; $i++) {
|
||||
$str = $random->string(1, TRUE);
|
||||
$this->assertFalse(isset($strings[$str]), SafeMarkup::format('Generated duplicate random string !string', array('!string' => $str)));
|
||||
$this->assertFalse(isset($strings[$str]), 'Generated duplicate random string ' . $str);
|
||||
$strings[$str] = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +53,7 @@ class RandomTest extends UnitTestCase {
|
|||
$random = new Random();
|
||||
for ($i = 0; $i <= 10; $i++) {
|
||||
$str = $random->name(1, TRUE);
|
||||
$this->assertFalse(isset($names[$str]), SafeMarkup::format('Generated duplicate random name !name', array('!name' => $str)));
|
||||
$this->assertFalse(isset($names[$str]), 'Generated duplicate random name ' . $str);
|
||||
$names[$str] = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
namespace Drupal\Tests\Component\Utility;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
use Drupal\Component\Utility\SafeStringTrait;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -20,54 +21,81 @@ use Drupal\Tests\UnitTestCase;
|
|||
class SafeMarkupTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::set() and SafeMarkup::isSafe().
|
||||
* Helper function to add a string to the safe list for testing.
|
||||
*
|
||||
* @dataProvider providerSet
|
||||
* @param string $string
|
||||
* The content to be marked as secure.
|
||||
* @param string $strategy
|
||||
* The escaping strategy used for this string. Two values are supported
|
||||
* by default:
|
||||
* - 'html': (default) The string is safe for use in HTML code.
|
||||
* - 'all': The string is safe for all use cases.
|
||||
* See the
|
||||
* @link http://twig.sensiolabs.org/doc/filters/escape.html Twig escape documentation @endlink
|
||||
* for more information on escaping strategies in Twig.
|
||||
*
|
||||
* @param string $text
|
||||
* The text or object to provide to SafeMarkup::set().
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
*
|
||||
* @covers ::set
|
||||
* @return string
|
||||
* The input string that was marked as safe.
|
||||
*/
|
||||
public function testSet($text, $message) {
|
||||
$returned = SafeMarkup::set($text);
|
||||
$this->assertTrue(is_string($returned), 'The return value of SafeMarkup::set() is really a string');
|
||||
$this->assertEquals($returned, $text, 'The passed in value should be equal to the string value according to PHP');
|
||||
$this->assertTrue(SafeMarkup::isSafe($text), $message);
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'The return value has been marked as safe');
|
||||
protected function safeMarkupSet($string, $strategy = 'html') {
|
||||
$reflected_class = new \ReflectionClass('\Drupal\Component\Utility\SafeMarkup');
|
||||
$reflected_property = $reflected_class->getProperty('safeStrings');
|
||||
$reflected_property->setAccessible(true);
|
||||
$current_value = $reflected_property->getValue();
|
||||
$current_value[$string][$strategy] = TRUE;
|
||||
$reflected_property->setValue($current_value);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::isSafe() with different providers.
|
||||
*
|
||||
* @covers ::isSafe
|
||||
*/
|
||||
public function testStrategy() {
|
||||
$returned = $this->safeMarkupSet('string0', 'html');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "html" provider is safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string1', 'all');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "all" provider is safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string2', 'css');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned), 'String set with "css" provider is not safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string3');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned, 'all'), 'String set with "html" provider is not safe for "all"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testSet().
|
||||
*
|
||||
* @see testSet()
|
||||
*/
|
||||
public function providerSet() {
|
||||
// Checks that invalid multi-byte sequences are rejected.
|
||||
$tests[] = array("Foo\xC0barbaz", '', 'SafeMarkup::checkPlain() rejects invalid sequence "Foo\xC0barbaz"', TRUE);
|
||||
$tests[] = array("Fooÿñ", 'SafeMarkup::set() accepts valid sequence "Fooÿñ"');
|
||||
$tests[] = array(new TextWrapper("Fooÿñ"), 'SafeMarkup::set() accepts valid sequence "Fooÿñ" in an object implementing __toString()');
|
||||
$tests[] = array("<div>", 'SafeMarkup::set() accepts HTML');
|
||||
// Checks that invalid multi-byte sequences are escaped.
|
||||
$tests[] = array(
|
||||
'Foo<6F>barbaz',
|
||||
'SafeMarkup::setMarkup() functions with valid sequence "Foo<6F>barbaz"',
|
||||
TRUE
|
||||
);
|
||||
$tests[] = array(
|
||||
"Fooÿñ",
|
||||
'SafeMarkup::setMarkup() functions with valid sequence "Fooÿñ"'
|
||||
);
|
||||
$tests[] = array("<div>", 'SafeMarkup::setMultiple() does not escape HTML');
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::set() and SafeMarkup::isSafe() with different providers.
|
||||
* Tests SafeMarkup::setMultiple().
|
||||
* @dataProvider providerSet
|
||||
*
|
||||
* @covers ::isSafe
|
||||
* @param string $text
|
||||
* The text or object to provide to SafeMarkup::setMultiple().
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
*
|
||||
* @covers ::setMultiple
|
||||
*/
|
||||
public function testStrategy() {
|
||||
$returned = SafeMarkup::set('string0', 'html');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "html" provider is safe for default (html)');
|
||||
$returned = SafeMarkup::set('string1', 'all');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "all" provider is safe for default (html)');
|
||||
$returned = SafeMarkup::set('string2', 'css');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned), 'String set with "css" provider is not safe for default (html)');
|
||||
$returned = SafeMarkup::set('string3');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned, 'all'), 'String set with "html" provider is not safe for "all"');
|
||||
public function testSet($text, $message) {
|
||||
SafeMarkup::setMultiple([$text => ['html' => TRUE]]);
|
||||
$this->assertTrue(SafeMarkup::isSafe($text), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,10 +168,10 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
* @see testCheckPlain()
|
||||
*/
|
||||
function providerCheckPlain() {
|
||||
// Checks that invalid multi-byte sequences are rejected.
|
||||
$tests[] = array("Foo\xC0barbaz", '', 'SafeMarkup::checkPlain() rejects invalid sequence "Foo\xC0barbaz"', TRUE);
|
||||
$tests[] = array("\xc2\"", '', 'SafeMarkup::checkPlain() rejects invalid sequence "\xc2\""', TRUE);
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'SafeMarkup::checkPlain() accepts valid sequence "Fooÿñ"');
|
||||
// Checks that invalid multi-byte sequences are escaped.
|
||||
$tests[] = array("Foo\xC0barbaz", 'Foo<EFBFBD>barbaz', 'SafeMarkup::checkPlain() escapes invalid sequence "Foo\xC0barbaz"', TRUE);
|
||||
$tests[] = array("\xc2\"", '<EFBFBD>"', 'SafeMarkup::checkPlain() escapes invalid sequence "\xc2\""', TRUE);
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'SafeMarkup::checkPlain() does not escape valid sequence "Fooÿñ"');
|
||||
|
||||
// Checks that special characters are escaped.
|
||||
$tests[] = array("<script>", '<script>', 'SafeMarkup::checkPlain() escapes <script>');
|
||||
|
@ -160,7 +188,7 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
*
|
||||
* @param string $string
|
||||
* The string to run through SafeMarkup::format().
|
||||
* @param string $args
|
||||
* @param string[] $args
|
||||
* The arguments to pass into SafeMarkup::format().
|
||||
* @param string $expected
|
||||
* The expected result from calling the function.
|
||||
|
@ -169,10 +197,14 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
* @param bool $expected_is_safe
|
||||
* Whether the result is expected to be safe for HTML display.
|
||||
*/
|
||||
function testFormat($string, $args, $expected, $message, $expected_is_safe) {
|
||||
public function testFormat($string, array $args, $expected, $message, $expected_is_safe) {
|
||||
$result = SafeMarkup::format($string, $args);
|
||||
$this->assertEquals($expected, $result, $message);
|
||||
$this->assertEquals($expected_is_safe, SafeMarkup::isSafe($result), 'SafeMarkup::format correctly sets the result as safe or not safe.');
|
||||
|
||||
foreach ($args as $arg) {
|
||||
$this->assertSame($arg instanceof SafeMarkupTestSafeString, SafeMarkup::isSafe($arg));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,124 +215,11 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
function providerFormat() {
|
||||
$tests[] = array('Simple text', array(), 'Simple text', 'SafeMarkup::format leaves simple text alone.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => '<script>'), 'Escaped text: <script>', 'SafeMarkup::format replaces and escapes string.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => SafeMarkup::set('<span>Safe HTML</span>')), 'Escaped text: <span>Safe HTML</span>', 'SafeMarkup::format does not escape an already safe string.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Escaped text: <span>Safe HTML</span>', 'SafeMarkup::format does not escape an already safe string.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => '<script>'), 'Placeholder text: <em class="placeholder"><script></em>', 'SafeMarkup::format replaces, escapes and themes string.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => SafeMarkup::set('<span>Safe HTML</span>')), 'Placeholder text: <em class="placeholder"><span>Safe HTML</span></em>', 'SafeMarkup::format does not escape an already safe string themed as a placeholder.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Placeholder text: <em class="placeholder"><span>Safe HTML</span></em>', 'SafeMarkup::format does not escape an already safe string themed as a placeholder.', TRUE);
|
||||
$tests[] = array('Verbatim text: !value', array('!value' => '<script>'), 'Verbatim text: <script>', 'SafeMarkup::format replaces verbatim string as-is.', FALSE);
|
||||
$tests[] = array('Verbatim text: !value', array('!value' => SafeMarkup::set('<span>Safe HTML</span>')), 'Verbatim text: <span>Safe HTML</span>', 'SafeMarkup::format replaces verbatim string as-is.', TRUE);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::placeholder().
|
||||
*
|
||||
* @covers ::placeholder
|
||||
*/
|
||||
function testPlaceholder() {
|
||||
$this->assertEquals('<em class="placeholder">Some text</em>', SafeMarkup::placeholder('Some text'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::replace().
|
||||
*
|
||||
* @dataProvider providerReplace
|
||||
* @covers ::replace
|
||||
*/
|
||||
public function testReplace($search, $replace, $subject, $expected, $is_safe) {
|
||||
$result = SafeMarkup::replace($search, $replace, $subject);
|
||||
$this->assertEquals($expected, $result);
|
||||
$this->assertEquals($is_safe, SafeMarkup::isSafe($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the interaction between the safe list and XSS filtering.
|
||||
*
|
||||
* @covers ::xssFilter
|
||||
* @covers ::escape
|
||||
*/
|
||||
public function testAdminXss() {
|
||||
// Use the predefined XSS admin tag list. This strips the <marquee> tags.
|
||||
$this->assertEquals('text', SafeMarkup::xssFilter('<marquee>text</marquee>', Xss::getAdminTagList()));
|
||||
$this->assertTrue(SafeMarkup::isSafe('text'), 'The string \'text\' is marked as safe.');
|
||||
|
||||
// This won't strip the <marquee> tags and the string with HTML will be
|
||||
// marked as safe.
|
||||
$filtered = SafeMarkup::xssFilter('<marquee>text</marquee>', array('marquee'));
|
||||
$this->assertEquals('<marquee>text</marquee>', $filtered);
|
||||
$this->assertTrue(SafeMarkup::isSafe('<marquee>text</marquee>'), 'The string \'<marquee>text</marquee>\' is marked as safe.');
|
||||
|
||||
// SafeMarkup::xssFilter() with the default tag list will strip the
|
||||
// <marquee> tag even though the string was marked safe above.
|
||||
$this->assertEquals('text', SafeMarkup::xssFilter('<marquee>text</marquee>'));
|
||||
|
||||
// SafeMarkup::escape() will not escape the markup tag since the string was
|
||||
// marked safe above.
|
||||
$this->assertEquals('<marquee>text</marquee>', SafeMarkup::escape($filtered));
|
||||
|
||||
// SafeMarkup::checkPlain() will escape the markup tag even though the
|
||||
// string was marked safe above.
|
||||
$this->assertEquals('<marquee>text</marquee>', SafeMarkup::checkPlain($filtered));
|
||||
|
||||
// Ensure that SafeMarkup::xssFilter strips all tags when passed an empty
|
||||
// array and uses the default tag list when not passed a tag list.
|
||||
$this->assertEquals('text', SafeMarkup::xssFilter('<em>text</em>', []));
|
||||
$this->assertEquals('<em>text</em>', SafeMarkup::xssFilter('<em>text</em>'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testReplace().
|
||||
*
|
||||
* @see testReplace()
|
||||
*/
|
||||
public function providerReplace() {
|
||||
$tests = [];
|
||||
|
||||
// Subject unsafe.
|
||||
$tests[] = [
|
||||
'<placeholder>',
|
||||
SafeMarkup::set('foo'),
|
||||
'<placeholder>bazqux',
|
||||
'foobazqux',
|
||||
FALSE,
|
||||
];
|
||||
|
||||
// All safe.
|
||||
$tests[] = [
|
||||
'<placeholder>',
|
||||
SafeMarkup::set('foo'),
|
||||
SafeMarkup::set('<placeholder>barbaz'),
|
||||
'foobarbaz',
|
||||
TRUE,
|
||||
];
|
||||
|
||||
// Safe subject, but should result in unsafe string because replacement is
|
||||
// unsafe.
|
||||
$tests[] = [
|
||||
'<placeholder>',
|
||||
'fubar',
|
||||
SafeMarkup::set('<placeholder>barbaz'),
|
||||
'fubarbarbaz',
|
||||
FALSE,
|
||||
];
|
||||
|
||||
// Array with all safe.
|
||||
$tests[] = [
|
||||
['<placeholder1>', '<placeholder2>', '<placeholder3>'],
|
||||
[SafeMarkup::set('foo'), SafeMarkup::set('bar'), SafeMarkup::set('baz')],
|
||||
SafeMarkup::set('<placeholder1><placeholder2><placeholder3>'),
|
||||
'foobarbaz',
|
||||
TRUE,
|
||||
];
|
||||
|
||||
// Array with unsafe replacement.
|
||||
$tests[] = [
|
||||
['<placeholder1>', '<placeholder2>', '<placeholder3>',],
|
||||
[SafeMarkup::set('bar'), SafeMarkup::set('baz'), 'qux'],
|
||||
SafeMarkup::set('<placeholder1><placeholder2><placeholder3>'),
|
||||
'barbazqux',
|
||||
FALSE,
|
||||
];
|
||||
$tests[] = array('Verbatim text: !value', array('!value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Verbatim text: <span>Safe HTML</span>', 'SafeMarkup::format replaces verbatim string as-is.', TRUE);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
@ -320,3 +239,13 @@ class SafeMarkupTestString {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks text as safe.
|
||||
*
|
||||
* SafeMarkupTestSafeString is used to mark text as safe because
|
||||
* SafeMarkup::$safeStrings is a global static that affects all tests.
|
||||
*/
|
||||
class SafeMarkupTestSafeString implements SafeStringInterface {
|
||||
use SafeStringTrait;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
namespace Drupal\Tests\Component\Utility;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -94,7 +93,7 @@ class UrlHelperTest extends UnitTestCase {
|
|||
public function testValidAbsolute($url, $scheme) {
|
||||
$test_url = $scheme . '://' . $url;
|
||||
$valid_url = UrlHelper::isValid($test_url, TRUE);
|
||||
$this->assertTrue($valid_url, SafeMarkup::format('@url is a valid URL.', array('@url' => $test_url)));
|
||||
$this->assertTrue($valid_url, $test_url . ' is a valid URL.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,7 +124,7 @@ class UrlHelperTest extends UnitTestCase {
|
|||
public function testInvalidAbsolute($url, $scheme) {
|
||||
$test_url = $scheme . '://' . $url;
|
||||
$valid_url = UrlHelper::isValid($test_url, TRUE);
|
||||
$this->assertFalse($valid_url, SafeMarkup::format('@url is NOT a valid URL.', array('@url' => $test_url)));
|
||||
$this->assertFalse($valid_url, $test_url . ' is NOT a valid URL.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,7 +158,7 @@ class UrlHelperTest extends UnitTestCase {
|
|||
public function testValidRelative($url, $prefix) {
|
||||
$test_url = $prefix . $url;
|
||||
$valid_url = UrlHelper::isValid($test_url);
|
||||
$this->assertTrue($valid_url, SafeMarkup::format('@url is a valid URL.', array('@url' => $test_url)));
|
||||
$this->assertTrue($valid_url, $test_url . ' is a valid URL.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +189,7 @@ class UrlHelperTest extends UnitTestCase {
|
|||
public function testInvalidRelative($url, $prefix) {
|
||||
$test_url = $prefix . $url;
|
||||
$valid_url = UrlHelper::isValid($test_url);
|
||||
$this->assertFalse($valid_url, SafeMarkup::format('@url is NOT a valid URL.', array('@url' => $test_url)));
|
||||
$this->assertFalse($valid_url, $test_url . ' is NOT a valid URL.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,8 +380,10 @@ class UrlHelperTest extends UnitTestCase {
|
|||
*/
|
||||
public function testFilterBadProtocol($uri, $expected, $protocols) {
|
||||
UrlHelper::setAllowedProtocols($protocols);
|
||||
$filtered = UrlHelper::filterBadProtocol($uri);
|
||||
$this->assertEquals($expected, $filtered);
|
||||
$this->assertEquals($expected, UrlHelper::filterBadProtocol($uri));
|
||||
// Multiple calls to UrlHelper::filterBadProtocol() do not cause double
|
||||
// escaping.
|
||||
$this->assertEquals($expected, UrlHelper::filterBadProtocol(UrlHelper::filterBadProtocol($uri)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -78,6 +78,11 @@ class VariableTest extends UnitTestCase {
|
|||
'"\'"',
|
||||
"'",
|
||||
),
|
||||
array(
|
||||
// Quotes with $ symbols.
|
||||
'"\$settings[\'foo\']"',
|
||||
'$settings[\'foo\']',
|
||||
),
|
||||
// Object.
|
||||
array(
|
||||
// A stdClass object.
|
||||
|
|
|
@ -22,6 +22,7 @@ class ComposerIntegrationTest extends UnitTestCase {
|
|||
*/
|
||||
protected function getErrorMessages() {
|
||||
$messages = [
|
||||
0 => 'No errors found',
|
||||
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
|
||||
JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
|
||||
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
|
||||
|
@ -63,10 +64,32 @@ class ComposerIntegrationTest extends UnitTestCase {
|
|||
$json = file_get_contents($path . '/composer.json');
|
||||
|
||||
$result = json_decode($json);
|
||||
if (is_null($result)) {
|
||||
$this->fail($this->getErrorMessages()[json_last_error()]);
|
||||
$this->assertNotNull($result, $this->getErrorMessages()[json_last_error()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests core's composer.json replace section.
|
||||
*
|
||||
* Verify that all core modules are also listed in the 'replace' section of
|
||||
* core's composer.json.
|
||||
*/
|
||||
public function testAllModulesReplaced() {
|
||||
$json = json_decode(file_get_contents($this->root . '/core/composer.json'));
|
||||
$composer_replace_packages = $json->replace;
|
||||
|
||||
$folders = scandir($this->root . '/core/modules');
|
||||
|
||||
$module_names = [];
|
||||
foreach ($folders as $file_name) {
|
||||
if ($file_name !== '.' && $file_name !== '..' && is_dir($file_name)) {
|
||||
$module_names[] = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($module_names as $module_name) {
|
||||
$this->assertTrue(array_key_exists('drupal/'.$module_name, $composer_replace_packages), 'Found ' . $module_name . ' in replace list of composer.json');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Access\AccessCheckInterface;
|
|||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Access\AccessManagerInterface;
|
||||
use Drupal\Core\Access\CheckProvider;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\Routing\RouteMatch;
|
||||
use Drupal\Core\Access\AccessManager;
|
||||
use Drupal\Core\Access\DefaultAccessCheck;
|
||||
|
@ -94,6 +95,9 @@ class AccessManagerTest extends UnitTestCase {
|
|||
parent::setUp();
|
||||
|
||||
$this->container = new ContainerBuilder();
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$this->container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($this->container);
|
||||
|
||||
$this->routeCollection = new RouteCollection();
|
||||
$this->routeCollection->add('test_route_1', new Route('/test-route-1'));
|
||||
|
|
|
@ -52,7 +52,6 @@ class AccessResultTest extends UnitTestCase {
|
|||
/**
|
||||
* Tests the construction of an AccessResult object.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::neutral
|
||||
*/
|
||||
public function testConstruction() {
|
||||
|
@ -852,8 +851,15 @@ class AccessResultTest extends UnitTestCase {
|
|||
* @covers ::allowedIfHasPermissions
|
||||
*
|
||||
* @dataProvider providerTestAllowedIfHasPermissions
|
||||
*
|
||||
* @param string[] $permissions
|
||||
* The permissions to check for.
|
||||
* @param string $conjunction
|
||||
* The conjunction to use when checking for permission. 'AND' or 'OR'.
|
||||
* @param \Drupal\Core\Access\AccessResult $expected_access
|
||||
* The expected access check result.
|
||||
*/
|
||||
public function testAllowedIfHasPermissions($permissions, $conjunction, $expected_access) {
|
||||
public function testAllowedIfHasPermissions($permissions, $conjunction, AccessResult $expected_access) {
|
||||
$account = $this->getMock('\Drupal\Core\Session\AccountInterface');
|
||||
$account->expects($this->any())
|
||||
->method('hasPermission')
|
||||
|
@ -862,6 +868,10 @@ class AccessResultTest extends UnitTestCase {
|
|||
['denied', FALSE],
|
||||
]);
|
||||
|
||||
if ($permissions) {
|
||||
$expected_access->cachePerPermissions();
|
||||
}
|
||||
|
||||
$access_result = AccessResult::allowedIfHasPermissions($account, $permissions, $conjunction);
|
||||
$this->assertEquals($expected_access, $access_result);
|
||||
}
|
||||
|
@ -875,14 +885,14 @@ class AccessResultTest extends UnitTestCase {
|
|||
return [
|
||||
[[], 'AND', AccessResult::allowedIf(FALSE)],
|
||||
[[], 'OR', AccessResult::allowedIf(FALSE)],
|
||||
[['allowed'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
|
||||
[['allowed'], 'AND', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
|
||||
[['denied'], 'OR', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
|
||||
[['denied'], 'AND', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
|
||||
[['allowed', 'denied'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
|
||||
[['denied', 'allowed'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
|
||||
[['allowed', 'denied', 'other'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
|
||||
[['allowed', 'denied'], 'AND', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
|
||||
[['allowed'], 'OR', AccessResult::allowedIf(TRUE)],
|
||||
[['allowed'], 'AND', AccessResult::allowedIf(TRUE)],
|
||||
[['denied'], 'OR', AccessResult::allowedIf(FALSE)],
|
||||
[['denied'], 'AND', AccessResult::allowedIf(FALSE)],
|
||||
[['allowed', 'denied'], 'OR', AccessResult::allowedIf(TRUE)],
|
||||
[['denied', 'allowed'], 'OR', AccessResult::allowedIf(TRUE)],
|
||||
[['allowed', 'denied', 'other'], 'OR', AccessResult::allowedIf(TRUE)],
|
||||
[['allowed', 'denied'], 'AND', AccessResult::allowedIf(FALSE)],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
$css_assets = array(
|
||||
'system.base.css' => array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.012,
|
||||
'media' => 'all',
|
||||
|
@ -49,7 +48,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
),
|
||||
'system.theme.css' => array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -62,7 +60,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
'group' => -100,
|
||||
'type' => 'file',
|
||||
'weight' => 0.004,
|
||||
'every_page' => FALSE,
|
||||
'media' => 'all',
|
||||
'preprocess' => TRUE,
|
||||
'data' => 'core/misc/ui/themes/base/jquery.ui.core.css',
|
||||
|
@ -70,7 +67,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
'basename' => 'jquery.ui.core.css',
|
||||
),
|
||||
'field.css' => array(
|
||||
'every_page' => TRUE,
|
||||
'group' => 0,
|
||||
'type' => 'file',
|
||||
'weight' => 0.011,
|
||||
|
@ -81,7 +77,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
'basename' => 'field.css',
|
||||
),
|
||||
'external.css' => array(
|
||||
'every_page' => FALSE,
|
||||
'group' => 0,
|
||||
'type' => 'external',
|
||||
'weight' => 0.009,
|
||||
|
@ -93,7 +88,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
),
|
||||
'elements.css' => array(
|
||||
'group' => 100,
|
||||
'every_page' => TRUE,
|
||||
'media' => 'all',
|
||||
'type' => 'file',
|
||||
'weight' => 0.001,
|
||||
|
@ -104,7 +98,6 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
),
|
||||
'print.css' => array(
|
||||
'group' => 100,
|
||||
'every_page' => TRUE,
|
||||
'media' => 'print',
|
||||
'type' => 'file',
|
||||
'weight' => 0.003,
|
||||
|
@ -117,62 +110,53 @@ class CssCollectionGrouperUnitTest extends UnitTestCase {
|
|||
|
||||
$groups = $this->grouper->group($css_assets);
|
||||
|
||||
$this->assertSame(count($groups), 6, "6 groups created.");
|
||||
$this->assertSame(count($groups), 5, "5 groups created.");
|
||||
|
||||
// Check group 1.
|
||||
$this->assertSame($groups[0]['group'], -100);
|
||||
$this->assertSame($groups[0]['every_page'], TRUE);
|
||||
$this->assertSame($groups[0]['type'], 'file');
|
||||
$this->assertSame($groups[0]['media'], 'all');
|
||||
$this->assertSame($groups[0]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[0]['items']), 2);
|
||||
$this->assertContains($css_assets['system.base.css'], $groups[0]['items']);
|
||||
$this->assertContains($css_assets['system.theme.css'], $groups[0]['items']);
|
||||
$group = $groups[0];
|
||||
$this->assertSame($group['group'], -100);
|
||||
$this->assertSame($group['type'], 'file');
|
||||
$this->assertSame($group['media'], 'all');
|
||||
$this->assertSame($group['preprocess'], TRUE);
|
||||
$this->assertSame(count($group['items']), 3);
|
||||
$this->assertContains($css_assets['system.base.css'], $group['items']);
|
||||
$this->assertContains($css_assets['system.theme.css'], $group['items']);
|
||||
|
||||
// Check group 2.
|
||||
$this->assertSame($groups[1]['group'], -100);
|
||||
$this->assertSame($groups[1]['every_page'], FALSE);
|
||||
$this->assertSame($groups[1]['type'], 'file');
|
||||
$this->assertSame($groups[1]['media'], 'all');
|
||||
$this->assertSame($groups[1]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[1]['items']), 1);
|
||||
$this->assertContains($css_assets['jquery.ui.core.css'], $groups[1]['items']);
|
||||
$group = $groups[1];
|
||||
$this->assertSame($group['group'], 0);
|
||||
$this->assertSame($group['type'], 'file');
|
||||
$this->assertSame($group['media'], 'all');
|
||||
$this->assertSame($group['preprocess'], TRUE);
|
||||
$this->assertSame(count($group['items']), 1);
|
||||
$this->assertContains($css_assets['field.css'], $group['items']);
|
||||
|
||||
// Check group 3.
|
||||
$this->assertSame($groups[2]['group'], 0);
|
||||
$this->assertSame($groups[2]['every_page'], TRUE);
|
||||
$this->assertSame($groups[2]['type'], 'file');
|
||||
$this->assertSame($groups[2]['media'], 'all');
|
||||
$this->assertSame($groups[2]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[2]['items']), 1);
|
||||
$this->assertContains($css_assets['field.css'], $groups[2]['items']);
|
||||
$group = $groups[2];
|
||||
$this->assertSame($group['group'], 0);
|
||||
$this->assertSame($group['type'], 'external');
|
||||
$this->assertSame($group['media'], 'all');
|
||||
$this->assertSame($group['preprocess'], TRUE);
|
||||
$this->assertSame(count($group['items']), 1);
|
||||
$this->assertContains($css_assets['external.css'], $group['items']);
|
||||
|
||||
// Check group 4.
|
||||
$this->assertSame($groups[3]['group'], 0);
|
||||
$this->assertSame($groups[3]['every_page'], FALSE);
|
||||
$this->assertSame($groups[3]['type'], 'external');
|
||||
$this->assertSame($groups[3]['media'], 'all');
|
||||
$this->assertSame($groups[3]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[3]['items']), 1);
|
||||
$this->assertContains($css_assets['external.css'], $groups[3]['items']);
|
||||
$group = $groups[3];
|
||||
$this->assertSame($group['group'], 100);
|
||||
$this->assertSame($group['type'], 'file');
|
||||
$this->assertSame($group['media'], 'all');
|
||||
$this->assertSame($group['preprocess'], TRUE);
|
||||
$this->assertSame(count($group['items']), 1);
|
||||
$this->assertContains($css_assets['elements.css'], $group['items']);
|
||||
|
||||
// Check group 5.
|
||||
$this->assertSame($groups[4]['group'], 100);
|
||||
$this->assertSame($groups[4]['every_page'], TRUE);
|
||||
$this->assertSame($groups[4]['type'], 'file');
|
||||
$this->assertSame($groups[4]['media'], 'all');
|
||||
$this->assertSame($groups[4]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[4]['items']), 1);
|
||||
$this->assertContains($css_assets['elements.css'], $groups[4]['items']);
|
||||
|
||||
// Check group 6.
|
||||
$this->assertSame($groups[5]['group'], 100);
|
||||
$this->assertSame($groups[5]['every_page'], TRUE);
|
||||
$this->assertSame($groups[5]['type'], 'file');
|
||||
$this->assertSame($groups[5]['media'], 'print');
|
||||
$this->assertSame($groups[5]['preprocess'], TRUE);
|
||||
$this->assertSame(count($groups[5]['items']), 1);
|
||||
$this->assertContains($css_assets['print.css'], $groups[5]['items']);
|
||||
$group = $groups[4];
|
||||
$this->assertSame($group['group'], 100);
|
||||
$this->assertSame($group['type'], 'file');
|
||||
$this->assertSame($group['media'], 'print');
|
||||
$this->assertSame($group['preprocess'], TRUE);
|
||||
$this->assertSame(count($group['items']), 1);
|
||||
$this->assertContains($css_assets['print.css'], $group['items']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
$this->renderer = new CssCollectionRenderer($this->state);
|
||||
$this->fileCssGroup = array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'media' => 'all',
|
||||
'preprocess' => TRUE,
|
||||
|
@ -79,7 +78,6 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
'items' => array(
|
||||
0 => array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.012,
|
||||
'media' => 'all',
|
||||
|
@ -90,7 +88,6 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
),
|
||||
1 => array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -121,7 +118,7 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
'#browsers' => $browsers,
|
||||
);
|
||||
};
|
||||
$create_style_element = function($value, $media, $browsers = array(), $wrap_in_cdata = FALSE) {
|
||||
$create_style_element = function($value, $media, $browsers = array()) {
|
||||
$style_element = array(
|
||||
'#type' => 'html_tag',
|
||||
'#tag' => 'style',
|
||||
|
@ -131,15 +128,11 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
),
|
||||
'#browsers' => $browsers,
|
||||
);
|
||||
if ($wrap_in_cdata) {
|
||||
$style_element['#value_prefix'] = "\n/* <![CDATA[ */\n";
|
||||
$style_element['#value_suffix'] = "\n/* ]]> */\n";
|
||||
}
|
||||
return $style_element;
|
||||
};
|
||||
|
||||
$create_file_css_asset = function($data, $media = 'all', $preprocess = TRUE) {
|
||||
return array('group' => 0, 'every_page' => FALSE, 'type' => 'file', 'media' => $media, 'preprocess' => $preprocess, 'data' => $data, 'browsers' => array());
|
||||
return array('group' => 0, 'type' => 'file', 'media' => $media, 'preprocess' => $preprocess, 'data' => $data, 'browsers' => array());
|
||||
};
|
||||
|
||||
return array(
|
||||
|
@ -147,7 +140,7 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
0 => array(
|
||||
// CSS assets.
|
||||
array(
|
||||
0 => array('group' => 0, 'every_page' => TRUE, 'type' => 'external', 'media' => 'all', 'preprocess' => TRUE, 'data' => 'http://example.com/popular.js', 'browsers' => array()),
|
||||
0 => array('group' => 0, 'type' => 'external', 'media' => 'all', 'preprocess' => TRUE, 'data' => 'http://example.com/popular.js', 'browsers' => array()),
|
||||
),
|
||||
// Render elements.
|
||||
array(
|
||||
|
@ -157,10 +150,10 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
// Single file CSS asset.
|
||||
2 => array(
|
||||
array(
|
||||
0 => array('group' => 0, 'every_page' => TRUE, 'type' => 'file', 'media' => 'all', 'preprocess' => TRUE, 'data' => 'public://css/file-every_page-all', 'browsers' => array()),
|
||||
0 => array('group' => 0, 'type' => 'file', 'media' => 'all', 'preprocess' => TRUE, 'data' => 'public://css/file-all', 'browsers' => array()),
|
||||
),
|
||||
array(
|
||||
0 => $create_link_element(file_create_url('public://css/file-every_page-all') . '?0', 'all'),
|
||||
0 => $create_link_element(file_create_url('public://css/file-all') . '?0', 'all'),
|
||||
),
|
||||
),
|
||||
// 31 file CSS assets: expect 31 link elements.
|
||||
|
@ -494,7 +487,6 @@ class CssCollectionRendererUnitTest extends UnitTestCase {
|
|||
|
||||
$css_group = array(
|
||||
'group' => 0,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'internal',
|
||||
'media' => 'all',
|
||||
'preprocess' => TRUE,
|
||||
|
|
|
@ -74,7 +74,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.012,
|
||||
'media' => 'all',
|
||||
|
@ -95,7 +94,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -111,7 +109,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -129,7 +126,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -146,7 +142,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -160,7 +155,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -174,7 +168,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -188,7 +181,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -202,7 +194,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -216,7 +207,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
array(
|
||||
array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.013,
|
||||
'media' => 'all',
|
||||
|
@ -247,7 +237,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
|
||||
$css_asset = array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
'type' => 'file',
|
||||
'weight' => 0.012,
|
||||
'media' => 'all',
|
||||
|
@ -268,7 +257,6 @@ class CssOptimizerUnitTest extends UnitTestCase {
|
|||
|
||||
$css_asset = array(
|
||||
'group' => -100,
|
||||
'every_page' => TRUE,
|
||||
// Type external.
|
||||
'type' => 'external',
|
||||
'weight' => 0.012,
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Breadcrumb;
|
||||
|
||||
use Drupal\Core\Breadcrumb\Breadcrumb;
|
||||
use Drupal\Core\Breadcrumb\BreadcrumbManager;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -16,6 +18,13 @@ use Drupal\Tests\UnitTestCase;
|
|||
*/
|
||||
class BreadcrumbManagerTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The breadcrumb object.
|
||||
*
|
||||
* @var \Drupal\Core\Breadcrumb\Breadcrumb
|
||||
*/
|
||||
protected $breadcrumb;
|
||||
|
||||
/**
|
||||
* The tested breadcrumb manager.
|
||||
*
|
||||
|
@ -36,14 +45,23 @@ class BreadcrumbManagerTest extends UnitTestCase {
|
|||
protected function setUp() {
|
||||
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
|
||||
$this->breadcrumbManager = new BreadcrumbManager($this->moduleHandler);
|
||||
$this->breadcrumb = new Breadcrumb();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the breadcrumb manager without any set breadcrumb.
|
||||
*/
|
||||
public function testBuildWithoutBuilder() {
|
||||
$result = $this->breadcrumbManager->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(), $result);
|
||||
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('system_breadcrumb', $this->breadcrumb, $route_match, ['builder' => NULL]);
|
||||
|
||||
$breadcrumb = $this->breadcrumbManager->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([], $breadcrumb->getLinks());
|
||||
$this->assertEquals([], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,7 +69,9 @@ class BreadcrumbManagerTest extends UnitTestCase {
|
|||
*/
|
||||
public function testBuildWithSingleBuilder() {
|
||||
$builder = $this->getMock('Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface');
|
||||
$breadcrumb = array('<a href="/example">Test</a>');
|
||||
$links = array('<a href="/example">Test</a>');
|
||||
$this->breadcrumb->setLinks($links);
|
||||
$this->breadcrumb->setCacheContexts(['foo'])->setCacheTags(['bar']);
|
||||
|
||||
$builder->expects($this->once())
|
||||
->method('applies')
|
||||
|
@ -59,17 +79,20 @@ class BreadcrumbManagerTest extends UnitTestCase {
|
|||
|
||||
$builder->expects($this->once())
|
||||
->method('build')
|
||||
->will($this->returnValue($breadcrumb));
|
||||
->willReturn($this->breadcrumb);
|
||||
|
||||
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('system_breadcrumb', $breadcrumb, $route_match, array('builder' => $builder));
|
||||
->with('system_breadcrumb', $this->breadcrumb, $route_match, array('builder' => $builder));
|
||||
|
||||
$this->breadcrumbManager->addBuilder($builder, 0);
|
||||
|
||||
$result = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($breadcrumb, $result);
|
||||
$breadcrumb = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($links, $breadcrumb->getLinks());
|
||||
$this->assertEquals(['foo'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals(['bar'], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,25 +106,30 @@ class BreadcrumbManagerTest extends UnitTestCase {
|
|||
->method('build');
|
||||
|
||||
$builder2 = $this->getMock('Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface');
|
||||
$breadcrumb2 = array('<a href="/example2">Test2</a>');
|
||||
$links2 = array('<a href="/example2">Test2</a>');
|
||||
$this->breadcrumb->setLinks($links2);
|
||||
$this->breadcrumb->setCacheContexts(['baz'])->setCacheTags(['qux']);
|
||||
$builder2->expects($this->once())
|
||||
->method('applies')
|
||||
->will($this->returnValue(TRUE));
|
||||
$builder2->expects($this->once())
|
||||
->method('build')
|
||||
->will($this->returnValue($breadcrumb2));
|
||||
->willReturn($this->breadcrumb);
|
||||
|
||||
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('system_breadcrumb', $breadcrumb2, $route_match, array('builder' => $builder2));
|
||||
->with('system_breadcrumb', $this->breadcrumb, $route_match, array('builder' => $builder2));
|
||||
|
||||
$this->breadcrumbManager->addBuilder($builder1, 0);
|
||||
$this->breadcrumbManager->addBuilder($builder2, 10);
|
||||
|
||||
$result = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($breadcrumb2, $result);
|
||||
$breadcrumb = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($links2, $breadcrumb->getLinks());
|
||||
$this->assertEquals(['baz'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals(['qux'], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,25 +144,30 @@ class BreadcrumbManagerTest extends UnitTestCase {
|
|||
->method('build');
|
||||
|
||||
$builder2 = $this->getMock('Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface');
|
||||
$breadcrumb2 = array('<a href="/example2">Test2</a>');
|
||||
$links2 = ['<a href="/example2">Test2</a>'];
|
||||
$this->breadcrumb->setLinks($links2);
|
||||
$this->breadcrumb->setCacheContexts(['baz'])->setCacheTags(['qux']);
|
||||
$builder2->expects($this->once())
|
||||
->method('applies')
|
||||
->will($this->returnValue(TRUE));
|
||||
$builder2->expects($this->once())
|
||||
->method('build')
|
||||
->will($this->returnValue($breadcrumb2));
|
||||
->willReturn($this->breadcrumb);
|
||||
|
||||
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('system_breadcrumb', $breadcrumb2, $route_match, array('builder' => $builder2));
|
||||
->with('system_breadcrumb', $this->breadcrumb, $route_match, array('builder' => $builder2));
|
||||
|
||||
$this->breadcrumbManager->addBuilder($builder1, 10);
|
||||
$this->breadcrumbManager->addBuilder($builder2, 0);
|
||||
|
||||
$result = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($breadcrumb2, $result);
|
||||
$breadcrumb = $this->breadcrumbManager->build($route_match);
|
||||
$this->assertEquals($links2, $breadcrumb->getLinks());
|
||||
$this->assertEquals(['baz'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals(['qux'], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
32
core/tests/Drupal/Tests/Core/Breadcrumb/BreadcrumbTest.php
Normal file
32
core/tests/Drupal/Tests/Core/Breadcrumb/BreadcrumbTest.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Breadcrumb\BreadcrumbTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Breadcrumb;
|
||||
|
||||
use Drupal\Core\Breadcrumb\Breadcrumb;
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Breadcrumb\Breadcrumb
|
||||
* @group Breadcrumb
|
||||
*/
|
||||
class BreadcrumbTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::setLinks
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage Once breadcrumb links are set, only additional breadcrumb links can be added.
|
||||
*/
|
||||
public function testSetLinks() {
|
||||
$breadcrumb = new Breadcrumb();
|
||||
$breadcrumb->setLinks([new Link('Home', Url::fromRoute('<front>'))]);
|
||||
$breadcrumb->setLinks([new Link('None', Url::fromRoute('<none>'))]);
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Controller\ControllerResolver
|
||||
|
@ -40,6 +42,13 @@ class ControllerResolverTest extends UnitTestCase {
|
|||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* The PSR-7 converter.
|
||||
*
|
||||
* @var \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface
|
||||
*/
|
||||
protected $httpMessageFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -49,7 +58,8 @@ class ControllerResolverTest extends UnitTestCase {
|
|||
$this->container = new ContainerBuilder();
|
||||
$class_resolver = new ClassResolver();
|
||||
$class_resolver->setContainer($this->container);
|
||||
$this->controllerResolver = new ControllerResolver($class_resolver);
|
||||
$this->httpMessageFactory = new DiactorosFactory();
|
||||
$this->controllerResolver = new ControllerResolver($this->httpMessageFactory, $class_resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,7 +71,7 @@ class ControllerResolverTest extends UnitTestCase {
|
|||
* @see \Drupal\Core\Controller\ControllerResolver::doGetArguments()
|
||||
*/
|
||||
public function testGetArguments() {
|
||||
$controller = function(EntityInterface $entity, $user, RouteMatchInterface $route_match) {
|
||||
$controller = function(EntityInterface $entity, $user, RouteMatchInterface $route_match, ServerRequestInterface $psr_7) {
|
||||
};
|
||||
$mock_entity = $this->getMockBuilder('Drupal\Core\Entity\Entity')
|
||||
->disableOriginalConstructor()
|
||||
|
@ -71,12 +81,13 @@ class ControllerResolverTest extends UnitTestCase {
|
|||
'entity' => $mock_entity,
|
||||
'user' => $mock_account,
|
||||
'_raw_variables' => new ParameterBag(array('entity' => 1, 'user' => 1)),
|
||||
));
|
||||
), array(), array(), array('HTTP_HOST' => 'drupal.org'));
|
||||
$arguments = $this->controllerResolver->getArguments($request, $controller);
|
||||
|
||||
$this->assertEquals($mock_entity, $arguments[0]);
|
||||
$this->assertEquals($mock_account, $arguments[1]);
|
||||
$this->assertEquals(RouteMatch::createFromRequest($request), $arguments[2], 'Ensure that the route match object is passed along as well');
|
||||
$this->assertInstanceOf(ServerRequestInterface::class, $arguments[3], 'Ensure that the PSR-7 object is passed along as well');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,6 +230,20 @@ class ControllerResolverTest extends UnitTestCase {
|
|||
$this->assertEquals([RouteMatch::createFromRequest($request), $request], $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getArguments with a route match and a PSR-7 request.
|
||||
*
|
||||
* @covers ::getArguments
|
||||
* @covers ::doGetArguments
|
||||
*/
|
||||
public function testGetArgumentsWithRouteMatchAndPsr7Request() {
|
||||
$request = Request::create('/test');
|
||||
$mock_controller = new MockControllerPsr7();
|
||||
$arguments = $this->controllerResolver->getArguments($request, [$mock_controller, 'getControllerWithRequestAndRouteMatch']);
|
||||
$this->assertEquals(RouteMatch::createFromRequest($request), $arguments[0], 'Ensure that the route match object is passed along as well');
|
||||
$this->assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $arguments[1], 'Ensure that the PSR-7 object is passed along as well');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MockController {
|
||||
|
@ -231,6 +256,17 @@ class MockController {
|
|||
}
|
||||
|
||||
}
|
||||
class MockControllerPsr7 {
|
||||
public function getResult() {
|
||||
return ['#markup' => 'This is a regular controller'];
|
||||
}
|
||||
|
||||
public function getControllerWithRequestAndRouteMatch(RouteMatchInterface $route_match, ServerRequestInterface $request) {
|
||||
return ['#markup' => 'this is another example controller'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MockContainerInjection implements ContainerInjectionInterface {
|
||||
protected $result;
|
||||
public function __construct($result) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Controller\TitleResolver;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
@ -151,7 +150,7 @@ class TitleCallback {
|
|||
* Returns the example string.
|
||||
*/
|
||||
public function example($value) {
|
||||
return SafeMarkup::format('test @value', array('@value' => $value));
|
||||
return 'test ' . $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -254,12 +254,12 @@ class ConnectionTest extends UnitTestCase {
|
|||
array(''),
|
||||
),
|
||||
array(
|
||||
'/* Exploit * / DROP TABLE node; -- */ ',
|
||||
'/* Exploit * / DROP TABLE node; -- */ ',
|
||||
array('Exploit * / DROP TABLE node; --'),
|
||||
),
|
||||
array(
|
||||
'/* Exploit DROP TABLE node; --; another comment */ ',
|
||||
array('Exploit */ DROP TABLE node; --', 'another comment'),
|
||||
'/* Exploit * / DROP TABLE node; --; another comment */ ',
|
||||
array('Exploit * / DROP TABLE node; --', 'another comment'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -286,8 +286,8 @@ class ConnectionTest extends UnitTestCase {
|
|||
public function providerFilterComments() {
|
||||
return array(
|
||||
array('', ''),
|
||||
array('Exploit * / DROP TABLE node; --', 'Exploit * / DROP TABLE node; --'),
|
||||
array('Exploit DROP TABLE node; --', 'Exploit */ DROP TABLE node; --'),
|
||||
array('Exploit * / DROP TABLE node; --', 'Exploit * / DROP TABLE node; --'),
|
||||
array('Exploit * / DROP TABLE node; --', 'Exploit */ DROP TABLE node; --'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Database\Driver\pgsql\PostgresqlSchemaTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Database\Driver\pgsql;
|
||||
|
||||
use Drupal\Core\Database\Driver\pgsql\Schema;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Database\Driver\pgsql\Schema
|
||||
* @group Database
|
||||
*/
|
||||
class PostgresqlSchemaTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The PostgreSql DB connection.
|
||||
*
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Database\Driver\pgsql\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->connection = $this->getMockBuilder('\Drupal\Core\Database\Driver\pgsql\Connection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the actual constraint name is correctly computed.
|
||||
*
|
||||
* @param string $table_name
|
||||
* The table name the constrained column belongs to.
|
||||
* @param string $name
|
||||
* The constraint name.
|
||||
* @param string $expected
|
||||
* The expected computed constraint name.
|
||||
*
|
||||
* @covers ::constraintExists
|
||||
* @dataProvider providerComputedConstraintName
|
||||
*/
|
||||
public function testComputedConstraintName($table_name, $name, $expected) {
|
||||
$max_identifier_length = 63;
|
||||
$schema = new Schema($this->connection);
|
||||
|
||||
$statement = $this->getMock('\Drupal\Core\Database\StatementInterface');
|
||||
$statement->expects($this->any())
|
||||
->method('fetchField')
|
||||
->willReturn($max_identifier_length);
|
||||
|
||||
$this->connection->expects($this->any())
|
||||
->method('query')
|
||||
->willReturn($statement);
|
||||
|
||||
$this->connection->expects($this->at(2))
|
||||
->method('query')
|
||||
->with("SELECT 1 FROM pg_constraint WHERE conname = '$expected'")
|
||||
->willReturn($this->getMock('\Drupal\Core\Database\StatementInterface'));
|
||||
|
||||
$schema->constraintExists($table_name, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testComputedConstraintName().
|
||||
*/
|
||||
public function providerComputedConstraintName() {
|
||||
return [
|
||||
['user_field_data', 'pkey', 'user_field_data____pkey'],
|
||||
['user_field_data', 'name__key', 'user_field_data__name__key'],
|
||||
['user_field_data', 'a_veeeery_veery_very_super_long_field_name__key', 'drupal_BGGYAXgbqlAF1rMOyFTdZGj9zIMXZtSvEjMAKZ9wGIk_key'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -169,7 +169,7 @@ class DateTest extends UnitTestCase {
|
|||
*/
|
||||
public function testGetSampleDateFormats() {
|
||||
$timestamp = strtotime('2015-03-22 14:23:00');
|
||||
$expected = $this->dateFormatter->getSampleDateFormats('en', $timestamp, 'Europe/London');
|
||||
$expected = $this->dateFormatter->getSampleDateFormats('en', $timestamp, 'Australia/Sydney');
|
||||
|
||||
// Removed characters related to timezone 'e' and 'T', as test does not have
|
||||
// timezone set.
|
||||
|
|
|
@ -70,4 +70,14 @@ class ContainerBuilderTest extends UnitTestCase {
|
|||
$container->register('Bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests serialization.
|
||||
*
|
||||
* @expectedException \AssertionError
|
||||
*/
|
||||
public function testSerialize() {
|
||||
$container = new ContainerBuilder();
|
||||
serialize($container);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class ContainerTest extends UnitTestCase {
|
|||
/**
|
||||
* Tests serialization.
|
||||
*
|
||||
* @expectedException \PHPUnit_Framework_Error
|
||||
* @expectedException \AssertionError
|
||||
*/
|
||||
public function testSerialize() {
|
||||
$container = new Container();
|
||||
|
|
|
@ -46,14 +46,20 @@ class DiscoverServiceProvidersTest extends UnitTestCase {
|
|||
|
||||
/**
|
||||
* Tests the exception when container_yamls is not set.
|
||||
*
|
||||
* @covers ::discoverServiceProviders
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testDiscoverServiceNoContainerYamls() {
|
||||
new Settings([]);
|
||||
$kernel = new DrupalKernel('prod', new \Composer\Autoload\ClassLoader());
|
||||
$kernel->discoverServiceProviders();
|
||||
|
||||
$expect = [
|
||||
'app' => [
|
||||
'core' => 'core/core.services.yml',
|
||||
],
|
||||
'site' => [
|
||||
],
|
||||
];
|
||||
$this->assertAttributeSame($expect, 'serviceYamls', $kernel);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Entity;
|
||||
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
|
@ -16,32 +21,67 @@ use Drupal\Tests\UnitTestCase;
|
|||
/**
|
||||
* Unit test of entity access checking system.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Entity\EntityAccessCheck
|
||||
*
|
||||
* @group Access
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityAccessCheckTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$container = new Container();
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method for checking access to routes.
|
||||
*/
|
||||
public function testAccess() {
|
||||
$route = new Route('/foo', array(), array('_entity_access' => 'node.update'));
|
||||
$upcasted_arguments = new ParameterBag();
|
||||
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
$route_match->expects($this->once())
|
||||
->method('getParameters')
|
||||
->will($this->returnValue($upcasted_arguments));
|
||||
$node = $this->getMockBuilder('Drupal\node\Entity\Node')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$node->expects($this->any())
|
||||
->method('access')
|
||||
->will($this->returnValue(AccessResult::allowed()->cachePerPermissions()));
|
||||
$route = new Route('/foo/{var_name}', [], ['_entity_access' => 'var_name.update'], ['parameters' => ['var_name' => ['type' => 'entity:node']]]);
|
||||
/** @var \Drupal\Core\Session\AccountInterface $account */
|
||||
$account = $this->prophesize(AccountInterface::class)->reveal();
|
||||
|
||||
/** @var \Drupal\node\NodeInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
|
||||
$node = $this->prophesize(NodeInterface::class);
|
||||
$node->access('update', $account, TRUE)->willReturn(AccessResult::allowed());
|
||||
$node = $node->reveal();
|
||||
|
||||
/** @var \Drupal\Core\Routing\RouteMatchInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
|
||||
$route_match = $this->prophesize(RouteMatchInterface::class);
|
||||
$route_match->getRawParameters()->willReturn(new ParameterBag(['var_name' => 1]));
|
||||
$route_match->getParameters()->willReturn(new ParameterBag(['var_name' => $node]));
|
||||
$route_match = $route_match->reveal();
|
||||
|
||||
$access_check = new EntityAccessCheck();
|
||||
$upcasted_arguments->set('node', $node);
|
||||
$account = $this->getMock('Drupal\Core\Session\AccountInterface');
|
||||
$access = $access_check->access($route, $route_match, $account);
|
||||
$this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $access);
|
||||
$this->assertEquals(AccessResult::allowed(), $access_check->access($route, $route_match, $account));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::access
|
||||
*/
|
||||
public function testAccessWithTypePlaceholder() {
|
||||
$route = new Route('/foo/{entity_type}/{var_name}', [], ['_entity_access' => 'var_name.update'], ['parameters' => ['var_name' => ['type' => 'entity:{entity_type}']]]);
|
||||
/** @var \Drupal\Core\Session\AccountInterface $account */
|
||||
$account = $this->prophesize(AccountInterface::class)->reveal();
|
||||
|
||||
/** @var \Drupal\node\NodeInterface|\Prophecy\Prophecy\ObjectProphecy $node */
|
||||
$node = $this->prophesize(NodeInterface::class);
|
||||
$node->access('update', $account, TRUE)->willReturn(AccessResult::allowed());
|
||||
$node = $node->reveal();
|
||||
|
||||
/** @var \Drupal\Core\Routing\RouteMatchInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
|
||||
$route_match = $this->prophesize(RouteMatchInterface::class);
|
||||
$route_match->getRawParameters()->willReturn(new ParameterBag(['entity_type' => 'node', 'var_name' => 1]));
|
||||
$route_match->getParameters()->willReturn(new ParameterBag(['entity_type' => 'node', 'var_name' => $node]));
|
||||
$route_match = $route_match->reveal();
|
||||
|
||||
$access_check = new EntityAccessCheck();
|
||||
$this->assertEquals(AccessResult::allowed(), $access_check->access($route, $route_match, $account));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
namespace Drupal\Tests\Core\Entity;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
use Drupal\Core\Entity\EntityCreateAccessCheck;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
|
@ -32,6 +34,11 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$container = new Container();
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,9 +47,8 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
* @return array
|
||||
*/
|
||||
public function providerTestAccess() {
|
||||
$no_access = AccessResult::neutral()->cachePerPermissions();
|
||||
$access = AccessResult::allowed()->cachePerPermissions();
|
||||
$no_access_due_to_errors = AccessResult::neutral();
|
||||
$no_access = FALSE;
|
||||
$access = TRUE;
|
||||
|
||||
return array(
|
||||
array('', 'entity_test', $no_access, $no_access),
|
||||
|
@ -51,10 +57,10 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
array('test_entity', 'entity_test:test_entity', $no_access, $no_access),
|
||||
array('test_entity', 'entity_test:{bundle_argument}', $access, $access),
|
||||
array('test_entity', 'entity_test:{bundle_argument}', $no_access, $no_access),
|
||||
array('', 'entity_test:{bundle_argument}', $no_access, $no_access_due_to_errors),
|
||||
array('', 'entity_test:{bundle_argument}', $no_access, $no_access, FALSE),
|
||||
// When the bundle is not provided, access should be denied even if the
|
||||
// access control handler would allow access.
|
||||
array('', 'entity_test:{bundle_argument}', $access, $no_access_due_to_errors),
|
||||
array('', 'entity_test:{bundle_argument}', $access, $no_access, FALSE),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -63,7 +69,15 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
*
|
||||
* @dataProvider providerTestAccess
|
||||
*/
|
||||
public function testAccess($entity_bundle, $requirement, $access, $expected) {
|
||||
public function testAccess($entity_bundle, $requirement, $access, $expected, $expect_permission_context = TRUE) {
|
||||
|
||||
// Set up the access result objects for allowing or denying access.
|
||||
$access_result = $access ? AccessResult::allowed()->cachePerPermissions() : AccessResult::neutral()->cachePerPermissions();
|
||||
$expected_access_result = $expected ? AccessResult::allowed() : AccessResult::neutral();
|
||||
if ($expect_permission_context) {
|
||||
$expected_access_result->cachePerPermissions();
|
||||
}
|
||||
|
||||
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
|
||||
// Don't expect a call to the access control handler when we have a bundle
|
||||
|
@ -73,7 +87,7 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
$access_control_handler->expects($this->once())
|
||||
->method('createAccess')
|
||||
->with($entity_bundle)
|
||||
->will($this->returnValue($access));
|
||||
->will($this->returnValue($access_result));
|
||||
|
||||
$entity_manager->expects($this->any())
|
||||
->method('getAccessControlHandler')
|
||||
|
@ -101,7 +115,7 @@ class EntityCreateAccessCheckTest extends UnitTestCase {
|
|||
->will($this->returnValue($raw_variables));
|
||||
|
||||
$account = $this->getMock('Drupal\Core\Session\AccountInterface');
|
||||
$this->assertEquals($expected, $applies_check->access($route, $route_match, $account));
|
||||
$this->assertEquals($expected_access_result, $applies_check->access($route, $route_match, $account));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -137,64 +137,6 @@ class EntityListBuilderTest extends UnitTestCase {
|
|||
$this->assertArrayHasKey('title', $operations[$operation_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that buildRow() returns a string which has been run through
|
||||
* SafeMarkup::checkPlain().
|
||||
*
|
||||
* @dataProvider providerTestBuildRow
|
||||
*
|
||||
* @param string $input
|
||||
* The entity label being passed into buildRow.
|
||||
* @param string $expected
|
||||
* The expected output of the label from buildRow.
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
* @param bool $ignorewarnings
|
||||
* Whether or not to ignore PHP 5.3+ invalid multibyte sequence warnings.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityListBuilder::buildRow()
|
||||
*/
|
||||
public function testBuildRow($input, $expected, $message, $ignorewarnings = FALSE) {
|
||||
$this->role->expects($this->any())
|
||||
->method('label')
|
||||
->will($this->returnValue($input));
|
||||
|
||||
if ($ignorewarnings) {
|
||||
$built_row = @$this->entityListBuilder->buildRow($this->role);
|
||||
}
|
||||
else {
|
||||
$built_row = $this->entityListBuilder->buildRow($this->role);
|
||||
}
|
||||
|
||||
$this->assertEquals($built_row['label'], $expected, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testBuildRow().
|
||||
*
|
||||
* @see self::testBuildRow()
|
||||
* @see \Drupal\Tests\Component\Utility\SafeMarkupTest::providerCheckPlain()
|
||||
*
|
||||
* @return array
|
||||
* An array containing a string, the expected return from
|
||||
* SafeMarkup::checkPlain, a message to be output for failures, and whether the
|
||||
* test should be processed as multibyte.
|
||||
*/
|
||||
public function providerTestBuildRow() {
|
||||
$tests = array();
|
||||
// Checks that invalid multi-byte sequences are rejected.
|
||||
$tests[] = array("Foo\xC0barbaz", '', 'EntityTestListBuilder::buildRow() rejects invalid sequence "Foo\xC0barbaz"', TRUE);
|
||||
$tests[] = array("\xc2\"", '', 'EntityTestListBuilder::buildRow() rejects invalid sequence "\xc2\""', TRUE);
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'EntityTestListBuilder::buildRow() accepts valid sequence "Fooÿñ"');
|
||||
|
||||
// Checks that special characters are escaped.
|
||||
$tests[] = array("<script>", '<script>', 'EntityTestListBuilder::buildRow() escapes <script>');
|
||||
$tests[] = array('<>&"\'', '<>&"'', 'EntityTestListBuilder::buildRow() escapes reserved HTML characters.');
|
||||
|
||||
return $tests;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestEntityListBuilder extends EntityTestListBuilder {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Tests\Core\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityType;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -31,6 +32,29 @@ class EntityTypeTest extends UnitTestCase {
|
|||
return new EntityType($definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::get
|
||||
*
|
||||
* @dataProvider providerTestGet
|
||||
*/
|
||||
public function testGet(array $defintion, $key, $expected) {
|
||||
$entity_type = $this->setUpEntityType($defintion);
|
||||
$this->assertSame($expected, $entity_type->get($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::set
|
||||
* @covers ::get
|
||||
*
|
||||
* @dataProvider providerTestSet
|
||||
*/
|
||||
public function testSet($key, $value) {
|
||||
$entity_type = $this->setUpEntityType([]);
|
||||
$this->assertInstanceOf('Drupal\Core\Entity\EntityTypeInterface', $entity_type->set($key, $value));
|
||||
$this->assertSame($value, $entity_type->get($key));
|
||||
$this->assertNoPublicProperties($entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getKeys() method.
|
||||
*
|
||||
|
@ -64,6 +88,34 @@ class EntityTypeTest extends UnitTestCase {
|
|||
$this->assertSame(FALSE, $entity_type->hasKey('bananas'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for testGet.
|
||||
*/
|
||||
public function providerTestGet() {
|
||||
return [
|
||||
[[], 'provider', NULL],
|
||||
[['provider' => ''], 'provider', ''],
|
||||
[['provider' => 'test'], 'provider', 'test'],
|
||||
[[], 'something_additional', NULL],
|
||||
[['something_additional' => ''], 'something_additional', ''],
|
||||
[['something_additional' => 'additional'], 'something_additional', 'additional'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for testSet.
|
||||
*/
|
||||
public function providerTestSet() {
|
||||
return [
|
||||
['provider', NULL],
|
||||
['provider', ''],
|
||||
['provider', 'test'],
|
||||
['something_additional', NULL],
|
||||
['something_additional', ''],
|
||||
['something_additional', 'additional'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data.
|
||||
*/
|
||||
|
@ -272,4 +324,14 @@ class EntityTypeTest extends UnitTestCase {
|
|||
$this->assertEquals([], $entity_type->getConstraints());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts there on no public properties on the object instance.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
*/
|
||||
protected function assertNoPublicProperties(EntityTypeInterface $entity_type) {
|
||||
$reflection = new \ReflectionObject($entity_type);
|
||||
$this->assertEmpty($reflection->getProperties(\ReflectionProperty::IS_PUBLIC));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,13 @@ use Drupal\Tests\UnitTestCase;
|
|||
*/
|
||||
class SqlContentEntityStorageSchemaTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The mocked DB schema handler.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Schema|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $dbSchemaHandler;
|
||||
|
||||
/**
|
||||
* The mocked entity manager used in this test.
|
||||
*
|
||||
|
@ -1298,7 +1305,7 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase {
|
|||
->with($this->entityType->id())
|
||||
->will($this->returnValue($this->storageDefinitions));
|
||||
|
||||
$db_schema_handler = $this->getMockBuilder('Drupal\Core\Database\Schema')
|
||||
$this->dbSchemaHandler = $this->getMockBuilder('Drupal\Core\Database\Schema')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
@ -1307,7 +1314,7 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase {
|
|||
$expected_table_names = array_keys($expected);
|
||||
$expected_table_schemas = array_values($expected);
|
||||
|
||||
$db_schema_handler->expects($this->any())
|
||||
$this->dbSchemaHandler->expects($this->any())
|
||||
->method('createTable')
|
||||
->with(
|
||||
$this->callback(function($table_name) use (&$invocation_count, $expected_table_names) {
|
||||
|
@ -1327,17 +1334,21 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase {
|
|||
->getMock();
|
||||
$connection->expects($this->any())
|
||||
->method('schema')
|
||||
->will($this->returnValue($db_schema_handler));
|
||||
->will($this->returnValue($this->dbSchemaHandler));
|
||||
|
||||
$key_value = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreInterface');
|
||||
$this->storageSchema = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema')
|
||||
->setConstructorArgs(array($this->entityManager, $this->entityType, $this->storage, $connection))
|
||||
->setMethods(array('installedStorageSchema', 'loadEntitySchemaData', 'hasSharedTableNameChanges'))
|
||||
->setMethods(array('installedStorageSchema', 'loadEntitySchemaData', 'hasSharedTableNameChanges', 'isTableEmpty'))
|
||||
->getMock();
|
||||
$this->storageSchema
|
||||
->expects($this->any())
|
||||
->method('installedStorageSchema')
|
||||
->will($this->returnValue($key_value));
|
||||
$this->storageSchema
|
||||
->expects($this->any())
|
||||
->method('isTableEmpty')
|
||||
->willReturn(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1380,4 +1391,95 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ::onEntityTypeUpdate
|
||||
*/
|
||||
public function testonEntityTypeUpdateWithNewIndex() {
|
||||
$this->entityType = $original_entity_type = new ContentEntityType(array(
|
||||
'id' => 'entity_test',
|
||||
'entity_keys' => array('id' => 'id'),
|
||||
));
|
||||
|
||||
// Add a field with a really long index.
|
||||
$this->setUpStorageDefinition('long_index_name', array(
|
||||
'columns' => array(
|
||||
'long_index_name' => array(
|
||||
'type' => 'int',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'long_index_name_really_long_long_name' => array(array('long_index_name', 10)),
|
||||
),
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
'entity_test' => array(
|
||||
'description' => 'The base table for entity_test entities.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'long_index_name' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'entity_test__b588603cb9' => array(
|
||||
array('long_index_name', 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->setUpStorageSchema($expected);
|
||||
|
||||
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
|
||||
$table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
|
||||
$table_mapping->setExtraColumns('entity_test', array('default_langcode'));
|
||||
|
||||
$this->storage->expects($this->any())
|
||||
->method('getTableMapping')
|
||||
->will($this->returnValue($table_mapping));
|
||||
|
||||
$this->storageSchema->expects($this->any())
|
||||
->method('loadEntitySchemaData')
|
||||
->willReturn([
|
||||
'entity_test' => [
|
||||
'indexes' => [
|
||||
// A changed index definition.
|
||||
'entity_test__b588603cb9' => ['longer_index_name'],
|
||||
// An index that has been removed.
|
||||
'entity_test__removed_field' => ['removed_field'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// The original indexes should be dropped before the new one is added.
|
||||
$this->dbSchemaHandler->expects($this->at(0))
|
||||
->method('dropIndex')
|
||||
->with('entity_test', 'entity_test__b588603cb9');
|
||||
$this->dbSchemaHandler->expects($this->at(1))
|
||||
->method('dropIndex')
|
||||
->with('entity_test', 'entity_test__removed_field');
|
||||
|
||||
$this->dbSchemaHandler->expects($this->atLeastOnce())
|
||||
->method('fieldExists')
|
||||
->willReturn(TRUE);
|
||||
$this->dbSchemaHandler->expects($this->atLeastOnce())
|
||||
->method('addIndex')
|
||||
->with('entity_test', 'entity_test__b588603cb9', [['long_index_name', 10]], $this->callback(function($actual_value) use ($expected) {
|
||||
$this->assertEquals($expected['entity_test']['indexes'], $actual_value['indexes']);
|
||||
$this->assertEquals($expected['entity_test']['fields'], $actual_value['fields']);
|
||||
// If the parameters don't match, the assertions above will throw an
|
||||
// exception.
|
||||
return TRUE;
|
||||
}));
|
||||
|
||||
$this->assertNull(
|
||||
$this->storageSchema->onEntityTypeUpdate($this->entityType, $original_entity_type)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use Drupal\Core\Routing\RouteBuildEvent;
|
|||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
|
||||
|
@ -20,22 +19,6 @@ use Symfony\Component\Routing\RouteCollection;
|
|||
*/
|
||||
class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The tested route subscriber.
|
||||
*
|
||||
* @var \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
|
||||
*/
|
||||
protected $specialAttributesRouteSubscriber;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->specialAttributesRouteSubscriber = new SpecialAttributesRouteSubscriber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of routes with invalid route variables.
|
||||
*
|
||||
|
@ -43,14 +26,21 @@ class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
|
|||
* An array of invalid routes.
|
||||
*/
|
||||
public function providerTestOnRouteBuildingInvalidVariables() {
|
||||
$routes = array();
|
||||
$routes[] = array(new Route('/test/{system_path}'));
|
||||
$routes[] = array(new Route('/test/{_legacy}'));
|
||||
$routes[] = array(new Route('/test/{' . RouteObjectInterface::ROUTE_OBJECT . '}'));
|
||||
$routes[] = array(new Route('/test/{' . RouteObjectInterface::ROUTE_NAME . '}'));
|
||||
$routes[] = array(new Route('/test/{_content}'));
|
||||
$routes[] = array(new Route('/test/{_form}'));
|
||||
$routes[] = array(new Route('/test/{_raw_variables}'));
|
||||
// Build an array of mock route objects based on paths.
|
||||
$routes = [];
|
||||
$paths = [
|
||||
'/test/{system_path}',
|
||||
'/test/{_legacy}',
|
||||
'/test/{' . RouteObjectInterface::ROUTE_OBJECT . '}',
|
||||
'/test/{' . RouteObjectInterface::ROUTE_NAME . '}',
|
||||
'/test/{_content}',
|
||||
'/test/{_form}',
|
||||
'/test/{_raw_variables}',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$routes[] = [new Route($path)];
|
||||
}
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
@ -62,11 +52,18 @@ class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
|
|||
* An array of valid routes.
|
||||
*/
|
||||
public function providerTestOnRouteBuildingValidVariables() {
|
||||
$routes = array();
|
||||
$routes[] = array(new Route('/test/{account}'));
|
||||
$routes[] = array(new Route('/test/{node}'));
|
||||
$routes[] = array(new Route('/test/{user}'));
|
||||
$routes[] = array(new Route('/test/{entity_test}'));
|
||||
// Build an array of mock route objects based on paths.
|
||||
$routes = [];
|
||||
$paths = [
|
||||
'/test/{account}',
|
||||
'/test/{node}',
|
||||
'/test/{user}',
|
||||
'/test/{entity_test}',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$routes[] = [new Route($path)];
|
||||
}
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
@ -78,12 +75,16 @@ class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
|
|||
* The route to check.
|
||||
*
|
||||
* @dataProvider providerTestOnRouteBuildingValidVariables
|
||||
*
|
||||
* @covers ::onAlterRoutes
|
||||
*/
|
||||
public function testOnRouteBuildingValidVariables(Route $route) {
|
||||
$route_collection = new RouteCollection();
|
||||
$route_collection = $this->getMock('Symfony\Component\Routing\RouteCollection', NULL);
|
||||
$route_collection->add('test', $route);
|
||||
|
||||
$event = new RouteBuildEvent($route_collection, 'test');
|
||||
$this->specialAttributesRouteSubscriber->onAlterRoutes($event);
|
||||
$subscriber = new SpecialAttributesRouteSubscriber();
|
||||
$this->assertNull($subscriber->onAlterRoutes($event));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,12 +96,16 @@ class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
|
|||
* @dataProvider providerTestOnRouteBuildingInvalidVariables
|
||||
* @expectedException \PHPUnit_Framework_Error_Warning
|
||||
* @expectedExceptionMessage uses reserved variable names
|
||||
*
|
||||
* @covers ::onAlterRoutes
|
||||
*/
|
||||
public function testOnRouteBuildingInvalidVariables(Route $route) {
|
||||
$route_collection = new RouteCollection();
|
||||
$route_collection = $this->getMock('Symfony\Component\Routing\RouteCollection', NULL);
|
||||
$route_collection->add('test', $route);
|
||||
|
||||
$event = new RouteBuildEvent($route_collection, 'test');
|
||||
$this->specialAttributesRouteSubscriber->onAlterRoutes($event);
|
||||
$subscriber = new SpecialAttributesRouteSubscriber();
|
||||
$subscriber->onAlterRoutes($event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
170
core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
Normal file
170
core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\Extension\InfoParserUnitTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Extension;
|
||||
|
||||
use Drupal\Core\Extension\InfoParser;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
|
||||
/**
|
||||
* Tests InfoParser class and exception.
|
||||
*
|
||||
* Files for this test are stored in core/modules/system/tests/fixtures and end
|
||||
* with .info.txt instead of info.yml in order not not be considered as real
|
||||
* extensions.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Extension\InfoParser
|
||||
*
|
||||
* @group Extension
|
||||
*/
|
||||
class InfoParserUnitTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The InfoParser object.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\InfoParser
|
||||
*/
|
||||
protected $infoParser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->infoParser = new InfoParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the functionality of the infoParser object.
|
||||
*
|
||||
* @covers ::parse
|
||||
*/
|
||||
public function testInfoParserNonExisting() {
|
||||
vfsStream::setup('modules');
|
||||
$info = $this->infoParser->parse(vfsStream::url('modules') . '/does_not_exist.info.txt');
|
||||
$this->assertTrue(empty($info), 'Non existing info.yml returns empty array.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if correct exception is thrown for a broken info file.
|
||||
*
|
||||
* @covers ::parse
|
||||
*
|
||||
* @expectedException \Drupal\Core\Extension\InfoParserException
|
||||
* @expectedExceptionMessageRegExp #broken\.info\.txt#
|
||||
*/
|
||||
public function testInfoParserBroken() {
|
||||
$broken_info = <<<BROKEN_INFO
|
||||
# info.yml for testing broken YAML parsing exception handling.
|
||||
name: File
|
||||
type: module
|
||||
description: 'Defines a file field type.'
|
||||
package: Core
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies::;;
|
||||
- field
|
||||
BROKEN_INFO;
|
||||
|
||||
vfsStream::setup('modules');
|
||||
vfsStream::create([
|
||||
'fixtures' => [
|
||||
'broken.info.txt' => $broken_info,
|
||||
],
|
||||
]);
|
||||
$filename = vfsStream::url('modules/fixtures/broken.info.txt');
|
||||
$this->infoParser->parse($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that missing required keys are detected.
|
||||
*
|
||||
* @covers ::parse
|
||||
*
|
||||
* @expectedException \Drupal\Core\Extension\InfoParserException
|
||||
* @expectedExceptionMessageRegExp #Missing required keys \(type, core, name\) in .+?missing_keys\.info\.txt#
|
||||
*/
|
||||
public function testInfoParserMissingKeys() {
|
||||
$missing_keys = <<<MISSINGKEYS
|
||||
# info.yml for testing missing name, description, and type keys.
|
||||
package: Core
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- field
|
||||
MISSINGKEYS;
|
||||
|
||||
vfsStream::setup('modules');
|
||||
vfsStream::create([
|
||||
'fixtures' => [
|
||||
'missing_keys.info.txt' => $missing_keys,
|
||||
],
|
||||
]);
|
||||
$filename = vfsStream::url('modules/fixtures/missing_keys.info.txt');
|
||||
$this->infoParser->parse($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that missing required key is detected.
|
||||
*
|
||||
* @covers ::parse
|
||||
*
|
||||
* @expectedException \Drupal\Core\Extension\InfoParserException
|
||||
* @expectedExceptionMessageRegExp #Missing required keys \(type\) in .+?missing_key\.info\.txt#
|
||||
*/
|
||||
public function testInfoParserMissingKey() {
|
||||
$missing_key = <<<MISSINGKEY
|
||||
# info.yml for testing missing type key.
|
||||
name: File
|
||||
description: 'Defines a file field type.'
|
||||
package: Core
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- field
|
||||
MISSINGKEY;
|
||||
|
||||
vfsStream::setup('modules');
|
||||
vfsStream::create([
|
||||
'fixtures' => [
|
||||
'missing_key.info.txt' => $missing_key,
|
||||
],
|
||||
]);
|
||||
$filename = vfsStream::url('modules/fixtures/missing_key.info.txt');
|
||||
$this->infoParser->parse($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests common info file.
|
||||
*
|
||||
* @covers ::parse
|
||||
*/
|
||||
public function testInfoParserCommonInfo() {
|
||||
$common = <<<COMMONTEST
|
||||
core: 8.x
|
||||
name: common_test
|
||||
type: module
|
||||
description: 'testing info file parsing'
|
||||
simple_string: 'A simple string'
|
||||
version: "VERSION"
|
||||
double_colon: dummyClassName::
|
||||
COMMONTEST;
|
||||
|
||||
vfsStream::setup('modules');
|
||||
vfsStream::create([
|
||||
'fixtures' => [
|
||||
'common_test.info.txt' => $common,
|
||||
],
|
||||
]);
|
||||
$info_values = $this->infoParser->parse(vfsStream::url('modules/fixtures/common_test.info.txt'));
|
||||
$this->assertEquals($info_values['simple_string'], 'A simple string', 'Simple string value was parsed correctly.');
|
||||
$this->assertEquals($info_values['version'], \Drupal::VERSION, 'Constant value was parsed correctly.');
|
||||
$this->assertEquals($info_values['double_colon'], 'dummyClassName::', 'Value containing double-colon was parsed correctly.');
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Extension;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +71,7 @@ class RequiredModuleUninstallValidatorTest extends UnitTestCase {
|
|||
->method('getModuleInfoByModule')
|
||||
->willReturn(['required' => TRUE, 'name' => $module]);
|
||||
|
||||
$expected = [SafeMarkup::format('The @module module is required', ['@module' => $module])];
|
||||
$expected = ["The $module module is required"];
|
||||
$reasons = $this->uninstallValidator->validate($module);
|
||||
$this->assertSame($expected, $reasons);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Field\FieldFilteredStringTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Field;
|
||||
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Field\FieldFilteredString
|
||||
* @group Field
|
||||
*/
|
||||
class FieldFilteredStringTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::create
|
||||
* @dataProvider providerTestCreate
|
||||
*/
|
||||
public function testCreate($string, $expected, $instance_of_check) {
|
||||
$filtered_string = FieldFilteredString::create($string);
|
||||
|
||||
if ($instance_of_check) {
|
||||
$this->assertInstanceOf(FieldFilteredString::class, $filtered_string);
|
||||
}
|
||||
$this->assertSame($expected, (string) $filtered_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for testCreate().
|
||||
*/
|
||||
public function providerTestCreate() {
|
||||
$data = [];
|
||||
$data[] = ['', '', FALSE];
|
||||
// Certain tags are filtered.
|
||||
$data[] = ['<script>teststring</script>', 'teststring', TRUE];
|
||||
// Certain tags are not filtered.
|
||||
$data[] = ['<em>teststring</em>', '<em>teststring</em>', TRUE];
|
||||
// HTML will be normalized.
|
||||
$data[] = ['<em>teststring', '<em>teststring</em>', TRUE];
|
||||
|
||||
// Even safe strings will be escaped.
|
||||
$safe_string = $this->prophesize(SafeStringInterface::class);
|
||||
$safe_string->__toString()->willReturn('<script>teststring</script>');
|
||||
$data[] = [$safe_string->reveal(), 'teststring', TRUE];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers: ::displayAllowedTags
|
||||
*/
|
||||
public function testdisplayAllowedTags() {
|
||||
$expected = '<a> <b> <big> <code> <del> <em> <i> <ins> <pre> <q> <small> <span> <strong> <sub> <sup> <tt> <ol> <ul> <li> <p> <br> <img>';
|
||||
|
||||
$this->assertSame($expected, FieldFilteredString::displayAllowedTags());
|
||||
}
|
||||
|
||||
}
|
|
@ -12,13 +12,18 @@ use Drupal\Core\Access\AccessResult;
|
|||
use Drupal\Core\Access\AccessResultForbidden;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Form\EnforcedResponseException;
|
||||
use Drupal\Core\Form\FormBuilder;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Session\AccountProxyInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Form\FormBuilder
|
||||
|
@ -26,6 +31,25 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
|||
*/
|
||||
class FormBuilderTest extends FormTestBase {
|
||||
|
||||
/**
|
||||
* The dependency injection container.
|
||||
*
|
||||
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->container = new ContainerBuilder();
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$this->container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getFormId() method with a string based form ID.
|
||||
*
|
||||
|
@ -571,7 +595,7 @@ class FormBuilderTest extends FormTestBase {
|
|||
$data['access-false-root'] = [$clone, $expected_access];
|
||||
|
||||
$clone = $element;
|
||||
$access_result = AccessResult::forbidden()->addCacheContexts(['user']);
|
||||
$access_result = AccessResult::forbidden();
|
||||
$clone['#access'] = $access_result;
|
||||
|
||||
$expected_access = [];
|
||||
|
@ -603,11 +627,9 @@ class FormBuilderTest extends FormTestBase {
|
|||
|
||||
// Allow access on the most outer level but forbid otherwise.
|
||||
$clone = $element;
|
||||
$access_result_allowed = AccessResult::allowed()
|
||||
->addCacheContexts(['user']);
|
||||
$access_result_allowed = AccessResult::allowed();
|
||||
$clone['#access'] = $access_result_allowed;
|
||||
$access_result_forbidden = AccessResult::forbidden()
|
||||
->addCacheContexts(['user']);
|
||||
$access_result_forbidden = AccessResult::forbidden();
|
||||
$clone['child0']['#access'] = $access_result_forbidden;
|
||||
|
||||
$expected_access = [];
|
||||
|
@ -662,6 +684,149 @@ class FormBuilderTest extends FormTestBase {
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::valueCallableIsSafe
|
||||
*
|
||||
* @dataProvider providerTestValueCallableIsSafe
|
||||
*/
|
||||
public function testValueCallableIsSafe($callback, $expected) {
|
||||
$method = new \ReflectionMethod(FormBuilder::class, 'valueCallableIsSafe');
|
||||
$method->setAccessible(true);
|
||||
$is_safe = $method->invoke($this->formBuilder, $callback);
|
||||
$this->assertSame($expected, $is_safe);
|
||||
}
|
||||
|
||||
public function providerTestValueCallableIsSafe() {
|
||||
$data = [];
|
||||
$data['string_no_slash'] = [
|
||||
'Drupal\Core\Render\Element\Token::valueCallback',
|
||||
TRUE,
|
||||
];
|
||||
$data['string_with_slash'] = [
|
||||
'\Drupal\Core\Render\Element\Token::valueCallback',
|
||||
TRUE,
|
||||
];
|
||||
$data['array_no_slash'] = [
|
||||
['Drupal\Core\Render\Element\Token', 'valueCallback'],
|
||||
TRUE,
|
||||
];
|
||||
$data['array_with_slash'] = [
|
||||
['\Drupal\Core\Render\Element\Token', 'valueCallback'],
|
||||
TRUE,
|
||||
];
|
||||
$data['closure'] = [
|
||||
function () {},
|
||||
FALSE,
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::doBuildForm
|
||||
*
|
||||
* @dataProvider providerTestInvalidToken
|
||||
*/
|
||||
public function testInvalidToken($expected, $valid_token, $user_is_authenticated) {
|
||||
$form_token = 'the_form_token';
|
||||
$form_id = 'test_form_id';
|
||||
|
||||
if (is_bool($valid_token)) {
|
||||
$this->csrfToken->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnArgument(0);
|
||||
$this->csrfToken->expects($this->atLeastOnce())
|
||||
->method('validate')
|
||||
->will($this->returnValueMap([
|
||||
[$form_token, $form_id, $valid_token],
|
||||
[$form_id, $form_id, $valid_token],
|
||||
]));
|
||||
}
|
||||
|
||||
$current_user = $this->prophesize(AccountInterface::class);
|
||||
$current_user->isAuthenticated()->willReturn($user_is_authenticated);
|
||||
$property = new \ReflectionProperty(FormBuilder::class, 'currentUser');
|
||||
$property->setAccessible(TRUE);
|
||||
$property->setValue($this->formBuilder, $current_user->reveal());
|
||||
|
||||
$expected_form = $form_id();
|
||||
$form_arg = $this->getMockForm($form_id, $expected_form);
|
||||
|
||||
$form_state = new FormState();
|
||||
$input['form_id'] = $form_id;
|
||||
$input['form_token'] = $form_token;
|
||||
$form_state->setUserInput($input);
|
||||
$this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
|
||||
$this->assertSame($expected, $form_state->hasInvalidToken());
|
||||
}
|
||||
|
||||
public function providerTestInvalidToken() {
|
||||
$data = [];
|
||||
$data['authenticated_invalid'] = [TRUE, FALSE, TRUE];
|
||||
$data['authenticated_valid'] = [FALSE, TRUE, TRUE];
|
||||
// If the user is not authenticated, we will not have a token.
|
||||
$data['anonymous'] = [FALSE, NULL, FALSE];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::prepareForm
|
||||
*
|
||||
* @dataProvider providerTestFormTokenCacheability
|
||||
*/
|
||||
function testFormTokenCacheability($token, $is_authenticated, $expected_form_cacheability, $expected_token_cacheability) {
|
||||
$user = $this->prophesize(AccountProxyInterface::class);
|
||||
$user->isAuthenticated()
|
||||
->willReturn($is_authenticated);
|
||||
$this->container->set('current_user', $user->reveal());
|
||||
\Drupal::setContainer($this->container);
|
||||
|
||||
$form_id = 'test_form_id';
|
||||
$form = $form_id();
|
||||
|
||||
if (isset($token)) {
|
||||
$form['#token'] = $token;
|
||||
}
|
||||
|
||||
$form_arg = $this->getMock('Drupal\Core\Form\FormInterface');
|
||||
$form_arg->expects($this->once())
|
||||
->method('getFormId')
|
||||
->will($this->returnValue($form_id));
|
||||
$form_arg->expects($this->once())
|
||||
->method('buildForm')
|
||||
->will($this->returnValue($form));
|
||||
|
||||
$form_state = new FormState();
|
||||
$built_form = $this->formBuilder->buildForm($form_arg, $form_state);
|
||||
if (!isset($expected_form_cacheability)) {
|
||||
$this->assertFalse(isset($built_form['#cache']));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(isset($built_form['#cache']));
|
||||
$this->assertEquals($expected_form_cacheability, $built_form['#cache']);
|
||||
}
|
||||
if (!isset($expected_token_cacheability)) {
|
||||
$this->assertFalse(isset($built_form['form_token']));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(isset($built_form['form_token']));
|
||||
$this->assertEquals($expected_token_cacheability, $built_form['form_token']['#cache']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testFormTokenCacheability.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function providerTestFormTokenCacheability() {
|
||||
return [
|
||||
'token:none,authenticated:true' => [NULL, TRUE, ['contexts' => ['user.roles:authenticated']], ['max-age' => 0]],
|
||||
'token:false,authenticated:true' => [FALSE, TRUE, NULL, NULL],
|
||||
'token:none,authenticated:false' => [NULL, FALSE, ['contexts' => ['user.roles:authenticated']], NULL],
|
||||
'token:false,authenticated:false' => [FALSE, FALSE, NULL, NULL],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestForm implements FormInterface {
|
||||
|
|
|
@ -427,9 +427,9 @@ class FormCacheTest extends UnitTestCase {
|
|||
* @covers ::setCache
|
||||
*/
|
||||
public function testSetCacheWithSafeStrings() {
|
||||
// A call to SafeMarkup::set() is appropriate in this test as a way to add a
|
||||
// string to the safe list in the simplest way possible. Normally, avoid it.
|
||||
SafeMarkup::set('a_safe_string');
|
||||
// A call to SafeMarkup::format() is appropriate in this test as a way to
|
||||
// add a string to the safe list in the simplest way possible.
|
||||
SafeMarkup::format('@value', ['@value' => 'a_safe_string']);
|
||||
$form_build_id = 'the_form_build_id';
|
||||
$form = [
|
||||
'#form_id' => 'the_form_id'
|
||||
|
|
|
@ -25,8 +25,9 @@ class FormErrorHandlerTest extends UnitTestCase {
|
|||
$link_generator->expects($this->any())
|
||||
->method('generate')
|
||||
->willReturnArgument(0);
|
||||
$renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
|
||||
$form_error_handler = $this->getMockBuilder('Drupal\Core\Form\FormErrorHandler')
|
||||
->setConstructorArgs([$this->getStringTranslationStub(), $link_generator])
|
||||
->setConstructorArgs([$this->getStringTranslationStub(), $link_generator, $renderer])
|
||||
->setMethods(['drupalSetMessage'])
|
||||
->getMock();
|
||||
|
||||
|
@ -41,7 +42,13 @@ class FormErrorHandlerTest extends UnitTestCase {
|
|||
->with('this missing element is invalid', 'error');
|
||||
$form_error_handler->expects($this->at(3))
|
||||
->method('drupalSetMessage')
|
||||
->with('3 errors have been found: Test 1, Test 2 & a half, Test 3', 'error');
|
||||
->with('3 errors have been found: <ul-comma-list-mock><li-mock>Test 1</li-mock><li-mock>Test 2 & a half</li-mock><li-mock>Test 3</li-mock></ul-comma-list-mock>', 'error');
|
||||
|
||||
$renderer->expects($this->any())
|
||||
->method('renderPlain')
|
||||
->will($this->returnCallback(function ($render_array) {
|
||||
return $render_array[0]['#markup'] . '<ul-comma-list-mock><li-mock>' . implode(array_map('htmlspecialchars', $render_array[1]['#items']), '</li-mock><li-mock>') . '</li-mock></ul-comma-list-mock>';
|
||||
}));
|
||||
|
||||
$form = [
|
||||
'#parents' => [],
|
||||
|
@ -103,7 +110,7 @@ class FormErrorHandlerTest extends UnitTestCase {
|
|||
*/
|
||||
public function testSetElementErrorsFromFormState() {
|
||||
$form_error_handler = $this->getMockBuilder('Drupal\Core\Form\FormErrorHandler')
|
||||
->setConstructorArgs([$this->getStringTranslationStub(), $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface')])
|
||||
->setConstructorArgs([$this->getStringTranslationStub(), $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface'), $this->getMock('\Drupal\Core\Render\RendererInterface')])
|
||||
->setMethods(['drupalSetMessage'])
|
||||
->getMock();
|
||||
|
||||
|
|
|
@ -209,8 +209,7 @@ abstract class FormTestBase extends UnitTestCase {
|
|||
* Provides a mocked form object.
|
||||
*
|
||||
* @param string $form_id
|
||||
* (optional) The form ID to be used. If none is provided, the form will be
|
||||
* set with no expectation about getFormId().
|
||||
* The form ID to be used.
|
||||
* @param mixed $expected_form
|
||||
* (optional) If provided, the expected form response for buildForm() to
|
||||
* return. Defaults to NULL.
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Form;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@ -468,7 +467,7 @@ class FormValidatorTest extends UnitTestCase {
|
|||
'#maxlength' => 7,
|
||||
'#value' => $this->randomMachineName(8),
|
||||
),
|
||||
SafeMarkup::format('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => 'Test', '%max' => '7', '%length' => 8)),
|
||||
'Test cannot be longer than <em class="placeholder">7</em> characters but is currently <em class="placeholder">8</em> characters long.',
|
||||
FALSE,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
namespace Drupal\Tests\Core\Menu;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
use Drupal\Core\Menu\DefaultMenuLinkTreeManipulators;
|
||||
use Drupal\Core\Menu\MenuLinkTreeElement;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
@ -76,6 +78,11 @@ class DefaultMenuLinkTreeManipulatorsTest extends UnitTestCase {
|
|||
->getMock();
|
||||
|
||||
$this->defaultMenuTreeManipulators = new DefaultMenuLinkTreeManipulators($this->accessManager, $this->currentUser, $this->queryFactory);
|
||||
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$container = new Container();
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace Drupal\Tests\Core\Menu;
|
|||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\Component\Plugin\Factory\FactoryInterface;
|
||||
use Drupal\Core\Access\AccessManagerInterface;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Access\AccessResultForbidden;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
@ -109,10 +111,11 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
|
||||
$this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
|
||||
|
||||
$access_result = new AccessResultForbidden();
|
||||
$this->accessManager = $this->getMock('Drupal\Core\Access\AccessManagerInterface');
|
||||
$this->accessManager->expects($this->any())
|
||||
->method('checkNamedRoute')
|
||||
->will($this->returnValue(FALSE));
|
||||
->willReturn($access_result);
|
||||
$this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
|
||||
$this->discovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface');
|
||||
$this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface');
|
||||
|
@ -202,7 +205,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_2'),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 0,
|
||||
),
|
||||
),
|
||||
|
@ -236,7 +239,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_2'),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 0,
|
||||
),
|
||||
),
|
||||
|
@ -271,7 +274,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_2'),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 1,
|
||||
),
|
||||
'plugin_id_2' => array(
|
||||
|
@ -281,7 +284,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_3'),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 0,
|
||||
),
|
||||
),
|
||||
|
@ -318,7 +321,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_2', ['test1']),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 1,
|
||||
),
|
||||
'plugin_id_2' => array(
|
||||
|
@ -328,7 +331,7 @@ class LocalActionManagerTest extends UnitTestCase {
|
|||
'url' => Url::fromRoute('test_route_2', ['test2']),
|
||||
'localized_options' => '',
|
||||
),
|
||||
'#access' => FALSE,
|
||||
'#access' => AccessResult::forbidden(),
|
||||
'#weight' => 0,
|
||||
),
|
||||
),
|
||||
|
|
68
core/tests/Drupal/Tests/Core/Menu/MenuLinkDefaultTest.php
Normal file
68
core/tests/Drupal/Tests/Core/Menu/MenuLinkDefaultTest.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Menu\MenuLinkDefaultTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Menu;
|
||||
|
||||
use Drupal\Core\Menu\MenuLinkDefault;
|
||||
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Menu\MenuLinkDefault
|
||||
* @group Menu
|
||||
*/
|
||||
class MenuLinkDefaultTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::updateLink
|
||||
*/
|
||||
public function testUpdateLink() {
|
||||
$plugin_definition = [
|
||||
'title' => 'Hey jude',
|
||||
'enabled' => 1,
|
||||
'expanded' => 1,
|
||||
'menu_name' => 'admin',
|
||||
'parent' => '',
|
||||
'weight' => 10,
|
||||
];
|
||||
$expected_plugin_definition = $plugin_definition;
|
||||
$expected_plugin_definition['weight'] = -10;
|
||||
|
||||
$static_override = $this->prophesize(StaticMenuLinkOverridesInterface::class);
|
||||
$static_override->saveOverride('example_menu_link', $expected_plugin_definition);
|
||||
$static_override = $static_override->reveal();
|
||||
|
||||
$menu_link = new MenuLinkDefault([], 'example_menu_link', $plugin_definition, $static_override);
|
||||
|
||||
$this->assertEquals($expected_plugin_definition, $menu_link->updateLink(['weight' => -10], TRUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::updateLink
|
||||
*/
|
||||
public function testUpdateLinkWithoutPersist() {
|
||||
$plugin_definition = [
|
||||
'title' => 'Hey jude',
|
||||
'enabled' => 1,
|
||||
'expanded' => 1,
|
||||
'menu_name' => 'admin',
|
||||
'parent' => '',
|
||||
'weight' => 10,
|
||||
];
|
||||
$expected_plugin_definition = $plugin_definition;
|
||||
$expected_plugin_definition['weight'] = -10;
|
||||
|
||||
$static_override = $this->prophesize(StaticMenuLinkOverridesInterface::class);
|
||||
$static_override->saveOverride()->shouldNotBeCalled();
|
||||
$static_override = $static_override->reveal();
|
||||
|
||||
$menu_link = new MenuLinkDefault([], 'example_menu_link', $plugin_definition, $static_override);
|
||||
|
||||
$this->assertEquals($expected_plugin_definition, $menu_link->updateLink(['weight' => -10], FALSE));
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Path;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Path\PathMatcher;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -49,12 +48,7 @@ class PathMatcherTest extends UnitTestCase {
|
|||
public function testMatchPath($patterns, $paths) {
|
||||
foreach ($paths as $path => $expected_result) {
|
||||
$actual_result = $this->pathMatcher->matchPath($path, $patterns);
|
||||
$this->assertEquals($actual_result, $expected_result, SafeMarkup::format('Tried matching the path <code>@path</code> to the pattern <pre>@patterns</pre> - expected @expected, got @actual.', array(
|
||||
'@path' => $path,
|
||||
'@patterns' => $patterns,
|
||||
'@expected' => var_export($expected_result, TRUE),
|
||||
'@actual' => var_export($actual_result, TRUE),
|
||||
)));
|
||||
$this->assertEquals($actual_result, $expected_result, "Tried matching the path '$path' to the pattern '$patterns'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\Core\Render\Element\HtmlTag;
|
||||
|
||||
|
@ -34,7 +35,7 @@ class HtmlTagTest extends UnitTestCase {
|
|||
public function testPreRenderHtmlTag($element, $expected) {
|
||||
$result = HtmlTag::preRenderHtmlTag($element);
|
||||
$this->assertArrayHasKey('#markup', $result);
|
||||
$this->assertSame($expected, $result['#markup']);
|
||||
$this->assertEquals($expected, $result['#markup']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,12 +46,10 @@ class HtmlTagTest extends UnitTestCase {
|
|||
|
||||
// Value prefix/suffix.
|
||||
$element = array(
|
||||
'#value_prefix' => 'value_prefix|',
|
||||
'#value_suffix' => '|value_suffix',
|
||||
'#value' => 'value',
|
||||
'#tag' => 'p',
|
||||
);
|
||||
$tags[] = array($element, '<p>value_prefix|value|value_suffix</p>' . "\n");
|
||||
$tags[] = array($element, '<p>value</p>' . "\n");
|
||||
|
||||
// Normal element without a value should not result in a void element.
|
||||
$element = array(
|
||||
|
@ -77,6 +76,27 @@ class HtmlTagTest extends UnitTestCase {
|
|||
$element['#noscript'] = TRUE;
|
||||
$tags[] = array($element, '<noscript><div class="test" id="id">value</div>' . "\n" . '</noscript>');
|
||||
|
||||
// Ensure that #tag is sanitised.
|
||||
$element = array(
|
||||
'#tag' => 'p><script>alert()</script><p',
|
||||
'#value' => 'value',
|
||||
);
|
||||
$tags[] = array($element, "<p><script>alert()</script><p>value</p><script>alert()</script><p>\n");
|
||||
|
||||
// Ensure that #value is not filtered if it is marked as safe.
|
||||
$element = array(
|
||||
'#tag' => 'p',
|
||||
'#value' => SafeString::create('<script>value</script>'),
|
||||
);
|
||||
$tags[] = array($element, "<p><script>value</script></p>\n");
|
||||
|
||||
// Ensure that #value is filtered if it is not safe.
|
||||
$element = array(
|
||||
'#tag' => 'p',
|
||||
'#value' => '<script>value</script>',
|
||||
);
|
||||
$tags[] = array($element, "<p>value</p>\n");
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
@ -84,8 +104,12 @@ class HtmlTagTest extends UnitTestCase {
|
|||
* @covers ::preRenderConditionalComments
|
||||
* @dataProvider providerPreRenderConditionalComments
|
||||
*/
|
||||
public function testPreRenderConditionalComments($element, $expected) {
|
||||
$this->assertSame($expected, HtmlTag::preRenderConditionalComments($element));
|
||||
public function testPreRenderConditionalComments($element, $expected, $set_safe = FALSE) {
|
||||
if ($set_safe) {
|
||||
$element['#prefix'] = SafeString::create($element['#prefix']);
|
||||
$element['#suffix'] = SafeString::create($element['#suffix']);
|
||||
}
|
||||
$this->assertEquals($expected, HtmlTag::preRenderConditionalComments($element));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,6 +166,26 @@ class HtmlTagTest extends UnitTestCase {
|
|||
$expected['#suffix'] = "<!--<![endif]-->\n";
|
||||
$tags[] = array($element, $expected);
|
||||
|
||||
// Prefix and suffix filtering if not safe.
|
||||
$element = array(
|
||||
'#tag' => 'link',
|
||||
'#browsers' => array(
|
||||
'IE' => FALSE,
|
||||
),
|
||||
'#prefix' => '<blink>prefix</blink>',
|
||||
'#suffix' => '<blink>suffix</blink>',
|
||||
);
|
||||
$expected = $element;
|
||||
$expected['#prefix'] = "\n<!--[if !IE]><!-->\nprefix";
|
||||
$expected['#suffix'] = "suffix<!--<![endif]-->\n";
|
||||
$tags[] = array($element, $expected);
|
||||
|
||||
// Prefix and suffix filtering if marked as safe. This has to come after the
|
||||
// previous test case.
|
||||
$expected['#prefix'] = "\n<!--[if !IE]><!-->\n<blink>prefix</blink>";
|
||||
$expected['#suffix'] = "<blink>suffix</blink><!--<![endif]-->\n";
|
||||
$tags[] = array($element, $expected, TRUE);
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\MachineNameTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\MachineName;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\MachineName
|
||||
* @group Render
|
||||
*/
|
||||
class MachineNameTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, MachineName::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\PasswordConfirmTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\PasswordConfirm;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\PasswordConfirm
|
||||
* @group Render
|
||||
*/
|
||||
class PasswordConfirmTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $element, $input) {
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, PasswordConfirm::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [['pass1' => '', 'pass2' => ''], [], NULL];
|
||||
$data[] = [['pass1' => '', 'pass2' => ''], ['#default_value' => ['pass2' => 'value']], NULL];
|
||||
$data[] = [['pass2' => 'value', 'pass1' => ''], ['#default_value' => ['pass2' => 'value']], FALSE];
|
||||
$data[] = [['pass1' => '123456', 'pass2' => 'qwerty'], [], ['pass1' => '123456', 'pass2' => 'qwerty']];
|
||||
$data[] = [['pass1' => '123', 'pass2' => '234'], [], ['pass1' => 123, 'pass2' => 234]];
|
||||
$data[] = [['pass1' => '', 'pass2' => '234'], [], ['pass1' => ['array'], 'pass2' => 234]];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
45
core/tests/Drupal/Tests/Core/Render/Element/PasswordTest.php
Normal file
45
core/tests/Drupal/Tests/Core/Render/Element/PasswordTest.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\PasswordTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Password;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Password
|
||||
* @group Render
|
||||
*/
|
||||
class PasswordTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Password::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
45
core/tests/Drupal/Tests/Core/Render/Element/TextareaTest.php
Normal file
45
core/tests/Drupal/Tests/Core/Render/Element/TextareaTest.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TextareaTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Textarea;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Textarea
|
||||
* @group Render
|
||||
*/
|
||||
class TextareaTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Textarea::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TextfieldTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Textfield;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Textfield
|
||||
* @group Render
|
||||
*/
|
||||
class TextfieldTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Textfield::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
$data[] = ['testwithnewline', "test\nwith\rnewline"];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
45
core/tests/Drupal/Tests/Core/Render/Element/TokenTest.php
Normal file
45
core/tests/Drupal/Tests/Core/Render/Element/TokenTest.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Render\Element\TokenTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Render\Element;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element\Token;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Element\Token
|
||||
* @group Render
|
||||
*/
|
||||
class TokenTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::valueCallback
|
||||
*
|
||||
* @dataProvider providerTestValueCallback
|
||||
*/
|
||||
public function testValueCallback($expected, $input) {
|
||||
$element = [];
|
||||
$form_state = $this->prophesize(FormStateInterface::class)->reveal();
|
||||
$this->assertSame($expected, Token::valueCallback($element, $input, $form_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testValueCallback().
|
||||
*/
|
||||
public function providerTestValueCallback() {
|
||||
$data = [];
|
||||
$data[] = [NULL, FALSE];
|
||||
$data[] = [NULL, NULL];
|
||||
$data[] = ['', ['test']];
|
||||
$data[] = ['test', 'test'];
|
||||
$data[] = ['123', 123];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -66,101 +66,6 @@ class ElementInfoManagerTest extends UnitTestCase {
|
|||
$this->elementInfo = new ElementInfoManager(new \ArrayObject(), $this->cache, $this->cacheTagsInvalidator, $this->moduleHandler, $this->themeManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getInfo method.
|
||||
*
|
||||
* @covers ::getInfo
|
||||
* @covers ::buildInfo
|
||||
*
|
||||
* @dataProvider providerTestGetInfo
|
||||
*/
|
||||
public function testGetInfo($type, $expected_info, $element_info, callable $alter_callback = NULL) {
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('invokeAll')
|
||||
->with('element_info')
|
||||
->will($this->returnValue($element_info));
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('element_info', $this->anything())
|
||||
->will($this->returnCallback($alter_callback ?: function($info) {
|
||||
return $info;
|
||||
}));
|
||||
$this->themeManager->expects($this->once())
|
||||
->method('getActiveTheme')
|
||||
->willReturn(new ActiveTheme(['name' => 'test']));
|
||||
$this->themeManager->expects($this->once())
|
||||
->method('alter')
|
||||
->with('element_info', $this->anything())
|
||||
->will($this->returnCallback($alter_callback ?: function($info) {
|
||||
return $info;
|
||||
}));
|
||||
|
||||
$this->cache->expects($this->at(0))
|
||||
->method('get')
|
||||
->with('element_info_build:test')
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->cache->expects($this->at(1))
|
||||
->method('get')
|
||||
->with('element_info')
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->cache->expects($this->at(2))
|
||||
->method('set')
|
||||
->with('element_info');
|
||||
$this->cache->expects($this->at(3))
|
||||
->method('set')
|
||||
->with('element_info_build:test');
|
||||
|
||||
$this->assertEquals($expected_info, $this->elementInfo->getInfo($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides tests data for getInfo.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerTestGetInfo() {
|
||||
$data = array();
|
||||
// Provide an element and expect it is returned.
|
||||
$data[] = array(
|
||||
'page',
|
||||
array(
|
||||
'#type' => 'page',
|
||||
'#theme' => 'page',
|
||||
'#defaults_loaded' => TRUE,
|
||||
),
|
||||
array('page' => array(
|
||||
'#theme' => 'page',
|
||||
)),
|
||||
);
|
||||
// Provide an element but request an non existent one.
|
||||
$data[] = array(
|
||||
'form',
|
||||
array(
|
||||
'#defaults_loaded' => TRUE,
|
||||
),
|
||||
array('page' => array(
|
||||
'#theme' => 'page',
|
||||
)),
|
||||
);
|
||||
// Provide an element and alter it to ensure it is altered.
|
||||
$data[] = array(
|
||||
'page',
|
||||
array(
|
||||
'#type' => 'page',
|
||||
'#theme' => 'page',
|
||||
'#number' => 597219,
|
||||
'#defaults_loaded' => TRUE,
|
||||
),
|
||||
array('page' => array(
|
||||
'#theme' => 'page',
|
||||
)),
|
||||
function ($alter_name, array &$info) {
|
||||
$info['page']['#number'] = 597219;
|
||||
}
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getInfo() method when render element plugins are used.
|
||||
*
|
||||
|
@ -170,10 +75,6 @@ class ElementInfoManagerTest extends UnitTestCase {
|
|||
* @dataProvider providerTestGetInfoElementPlugin
|
||||
*/
|
||||
public function testGetInfoElementPlugin($plugin_class, $expected_info) {
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('invokeAll')
|
||||
->with('element_info')
|
||||
->willReturn(array());
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('element_info', $this->anything())
|
||||
|
|
|
@ -38,9 +38,6 @@ class RendererBubblingTest extends RendererTestBase {
|
|||
$this->setUpRequest();
|
||||
$this->setupMemoryCache();
|
||||
|
||||
$this->elementInfo->expects($this->any())
|
||||
->method('getInfo')
|
||||
->willReturn([]);
|
||||
$this->cacheContextsManager->expects($this->any())
|
||||
->method('convertTokensToKeys')
|
||||
->willReturnArgument(0);
|
||||
|
@ -302,7 +299,7 @@ class RendererBubblingTest extends RendererTestBase {
|
|||
* Tests the self-healing of the redirect with conditional cache contexts.
|
||||
*/
|
||||
public function testConditionalCacheContextBubblingSelfHealing() {
|
||||
global $current_user_role;
|
||||
$current_user_role = &$this->currentUserRole;
|
||||
|
||||
$this->setUpRequest();
|
||||
$this->setupMemoryCache();
|
||||
|
@ -319,8 +316,7 @@ class RendererBubblingTest extends RendererTestBase {
|
|||
'tags' => ['b'],
|
||||
],
|
||||
'grandchild' => [
|
||||
'#access_callback' => function () {
|
||||
global $current_user_role;
|
||||
'#access_callback' => function() use (&$current_user_role) {
|
||||
// Only role A cannot access this subtree.
|
||||
return $current_user_role !== 'A';
|
||||
},
|
||||
|
@ -331,8 +327,7 @@ class RendererBubblingTest extends RendererTestBase {
|
|||
'max-age' => 1800,
|
||||
],
|
||||
'grandgrandchild' => [
|
||||
'#access_callback' => function () {
|
||||
global $current_user_role;
|
||||
'#access_callback' => function () use (&$current_user_role) {
|
||||
// Only role C can access this subtree.
|
||||
return $current_user_role === 'C';
|
||||
},
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
namespace Drupal\Tests\Core\Render;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Render\Renderer
|
||||
|
@ -37,13 +37,24 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
* Also, different types:
|
||||
* - A) automatically generated placeholder
|
||||
* - 1) manually triggered (#create_placeholder = TRUE)
|
||||
* - 2) automatically triggered (based on max-age = 0 in its subtree)
|
||||
* - 2) automatically triggered (based on max-age = 0 at the top level)
|
||||
* - 3) automatically triggered (based on high cardinality cache contexts at
|
||||
* the top level)
|
||||
* - 4) automatically triggered (based on high-invalidation frequency cache
|
||||
* tags at the top level)
|
||||
* - 5) automatically triggered (based on max-age = 0 in its subtree, i.e.
|
||||
* via bubbling)
|
||||
* - 6) automatically triggered (based on high cardinality cache contexts in
|
||||
* its subtree, i.e. via bubbling)
|
||||
* - 7) automatically triggered (based on high-invalidation frequency cache
|
||||
* tags in its subtree, i.e. via bubbling)
|
||||
* - B) manually generated placeholder
|
||||
*
|
||||
* So, in total 2*3 = 6 permutations.
|
||||
* So, in total 2*5 = 10 permutations.
|
||||
*
|
||||
* @todo Case A2 is not yet supported by core. So that makes for only 4
|
||||
* permutations currently.
|
||||
* @todo Cases A5, A6 and A7 are not yet supported by core. So that makes for
|
||||
* only 10 permutations currently, instead of 16. That will be done in
|
||||
* https://www.drupal.org/node/2543334
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
@ -52,23 +63,23 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
|
||||
$generate_placeholder_markup = function($cache_keys = NULL) use ($args) {
|
||||
$token_render_array = [
|
||||
'#cache' => [],
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
];
|
||||
if (is_array($cache_keys)) {
|
||||
$token_render_array['#cache']['keys'] = $cache_keys;
|
||||
}
|
||||
else {
|
||||
unset($token_render_array['#cache']);
|
||||
}
|
||||
$token = hash('sha1', serialize($token_render_array));
|
||||
return SafeMarkup::format('<drupal-render-placeholder callback="@callback" arguments="@arguments" token="@token"></drupal-render-placeholder>', [
|
||||
'@callback' => 'Drupal\Tests\Core\Render\PlaceholdersTest::callback',
|
||||
'@arguments' => '0=' . $args[0],
|
||||
'@token' => $token,
|
||||
]);
|
||||
$token = hash('crc32b', serialize($token_render_array));
|
||||
// \Drupal\Core\Render\SafeString::create() is necessary as the render
|
||||
// system would mangle this markup. As this is exactly what happens at
|
||||
// runtime this is a valid use-case.
|
||||
return SafeString::create('<drupal-render-placeholder callback="Drupal\Tests\Core\Render\PlaceholdersTest::callback" arguments="' . '0=' . $args[0] . '" token="' . $token . '"></drupal-render-placeholder>');
|
||||
};
|
||||
|
||||
$extract_placeholder_render_array = function ($placeholder_render_array) {
|
||||
return array_intersect_key($placeholder_render_array, ['#lazy_builder' => TRUE, '#cache' => TRUE]);
|
||||
};
|
||||
|
||||
// Note the presence of '#create_placeholder'.
|
||||
$base_element_a1 = [
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
|
@ -83,9 +94,55 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
],
|
||||
];
|
||||
// Note the absence of '#create_placeholder', presence of max-age=0 at the
|
||||
// top level.
|
||||
$base_element_a2 = [
|
||||
// @todo, see docblock
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
],
|
||||
'placeholder' => [
|
||||
'#cache' => [
|
||||
'contexts' => [],
|
||||
'max-age' => 0,
|
||||
],
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
],
|
||||
];
|
||||
// Note the absence of '#create_placeholder', presence of high cardinality
|
||||
// cache context at the top level.
|
||||
$base_element_a3 = [
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
],
|
||||
'placeholder' => [
|
||||
'#cache' => [
|
||||
'contexts' => ['user'],
|
||||
],
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
],
|
||||
];
|
||||
// Note the absence of '#create_placeholder', presence of high-invalidation
|
||||
// frequency cache tag at the top level.
|
||||
$base_element_a4 = [
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
],
|
||||
'placeholder' => [
|
||||
'#cache' => [
|
||||
'contexts' => [],
|
||||
'tags' => ['current-temperature'],
|
||||
],
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
],
|
||||
];
|
||||
// Note the absence of '#create_placeholder', but the presence of
|
||||
// '#attached[placeholders]'.
|
||||
$base_element_b = [
|
||||
'#markup' => $generate_placeholder_markup(),
|
||||
'#attached' => [
|
||||
|
@ -93,8 +150,7 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
'foo' => 'bar',
|
||||
],
|
||||
'placeholders' => [
|
||||
$generate_placeholder_markup() => [
|
||||
'#cache' => [],
|
||||
(string) $generate_placeholder_markup() => [
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
],
|
||||
],
|
||||
|
@ -109,9 +165,11 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
// - automatically created, but manually triggered (#create_placeholder = TRUE)
|
||||
// - uncacheable
|
||||
$element_without_cache_keys = $base_element_a1;
|
||||
$expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a1['placeholder']);
|
||||
$cases[] = [
|
||||
$element_without_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[],
|
||||
];
|
||||
|
@ -121,9 +179,11 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
// - cacheable
|
||||
$element_with_cache_keys = $base_element_a1;
|
||||
$element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
|
||||
$expected_placeholder_render_array['#cache']['keys'] = $keys;
|
||||
$cases[] = [
|
||||
$element_with_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
$keys,
|
||||
[
|
||||
'#markup' => '<p>This is a rendered placeholder!</p>',
|
||||
|
@ -141,31 +201,149 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
];
|
||||
|
||||
// Case three: render array that has a placeholder that is:
|
||||
// - manually created
|
||||
// - automatically created, and automatically triggered due to max-age=0
|
||||
// - uncacheable
|
||||
$x = $base_element_b;
|
||||
unset($x['#attached']['placeholders'][$generate_placeholder_markup()]['#cache']);
|
||||
$element_without_cache_keys = $base_element_a2;
|
||||
$expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a2['placeholder']);
|
||||
$cases[] = [
|
||||
$x,
|
||||
$element_without_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[],
|
||||
];
|
||||
|
||||
// Case four: render array that has a placeholder that is:
|
||||
// - automatically created, but automatically triggered due to max-age=0
|
||||
// - cacheable
|
||||
$element_with_cache_keys = $base_element_a2;
|
||||
$element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
|
||||
$expected_placeholder_render_array['#cache']['keys'] = $keys;
|
||||
$cases[] = [
|
||||
$element_with_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[]
|
||||
];
|
||||
|
||||
// Case five: render array that has a placeholder that is:
|
||||
// - automatically created, and automatically triggered due to high
|
||||
// cardinality cache contexts
|
||||
// - uncacheable
|
||||
$element_without_cache_keys = $base_element_a3;
|
||||
$expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a3['placeholder']);
|
||||
$cases[] = [
|
||||
$element_without_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[],
|
||||
];
|
||||
|
||||
// Case six: render array that has a placeholder that is:
|
||||
// - automatically created, and automatically triggered due to high
|
||||
// cardinality cache contexts
|
||||
// - cacheable
|
||||
$element_with_cache_keys = $base_element_a3;
|
||||
$element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
|
||||
$expected_placeholder_render_array['#cache']['keys'] = $keys;
|
||||
// The CID parts here consist of the cache keys plus the 'user' cache
|
||||
// context, which in this unit test is simply the given cache context token,
|
||||
// see \Drupal\Tests\Core\Render\RendererTestBase::setUp().
|
||||
$cid_parts = array_merge($keys, ['user']);
|
||||
$cases[] = [
|
||||
$element_with_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
$cid_parts,
|
||||
[
|
||||
'#markup' => '<p>This is a rendered placeholder!</p>',
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'dynamic_animal' => $args[0],
|
||||
],
|
||||
],
|
||||
'#cache' => [
|
||||
'contexts' => ['user'],
|
||||
'tags' => [],
|
||||
'max-age' => Cache::PERMANENT,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// Case seven: render array that has a placeholder that is:
|
||||
// - automatically created, and automatically triggered due to high
|
||||
// invalidation frequency cache tags
|
||||
// - uncacheable
|
||||
$element_without_cache_keys = $base_element_a4;
|
||||
$expected_placeholder_render_array = $extract_placeholder_render_array($base_element_a4['placeholder']);
|
||||
$cases[] = [
|
||||
$element_without_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[],
|
||||
];
|
||||
|
||||
// Case eight: render array that has a placeholder that is:
|
||||
// - automatically created, and automatically triggered due to high
|
||||
// invalidation frequency cache tags
|
||||
// - cacheable
|
||||
$element_with_cache_keys = $base_element_a4;
|
||||
$element_with_cache_keys['placeholder']['#cache']['keys'] = $keys;
|
||||
$expected_placeholder_render_array['#cache']['keys'] = $keys;
|
||||
$cases[] = [
|
||||
$element_with_cache_keys,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
$keys,
|
||||
[
|
||||
'#markup' => '<p>This is a rendered placeholder!</p>',
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'dynamic_animal' => $args[0],
|
||||
],
|
||||
],
|
||||
'#cache' => [
|
||||
'contexts' => [],
|
||||
'tags' => ['current-temperature'],
|
||||
'max-age' => Cache::PERMANENT,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// Case nine: render array that has a placeholder that is:
|
||||
// - manually created
|
||||
// - uncacheable
|
||||
$x = $base_element_b;
|
||||
$expected_placeholder_render_array = $x['#attached']['placeholders'][(string) $generate_placeholder_markup()];
|
||||
unset($x['#attached']['placeholders'][(string) $generate_placeholder_markup()]['#cache']);
|
||||
$cases[] = [
|
||||
$x,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
FALSE,
|
||||
[],
|
||||
];
|
||||
|
||||
// Case ten: render array that has a placeholder that is:
|
||||
// - manually created
|
||||
// - cacheable
|
||||
$x = $base_element_b;
|
||||
$x['#markup'] = $generate_placeholder_markup($keys);
|
||||
$x['#markup'] = $placeholder_markup = $generate_placeholder_markup($keys);
|
||||
$placeholder_markup = (string) $placeholder_markup;
|
||||
$x['#attached']['placeholders'] = [
|
||||
$generate_placeholder_markup($keys) => [
|
||||
$placeholder_markup => [
|
||||
'#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args],
|
||||
'#cache' => ['keys' => $keys],
|
||||
],
|
||||
];
|
||||
$expected_placeholder_render_array = $x['#attached']['placeholders'][$placeholder_markup];
|
||||
$cases[] = [
|
||||
$x,
|
||||
$args,
|
||||
$expected_placeholder_render_array,
|
||||
$keys,
|
||||
[
|
||||
'#markup' => '<p>This is a rendered placeholder!</p>',
|
||||
|
@ -224,8 +402,8 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
*
|
||||
* @dataProvider providerPlaceholders
|
||||
*/
|
||||
public function testUncacheableParent($element, $args, $placeholder_cid_keys, array $placeholder_expected_render_cache_array) {
|
||||
if ($placeholder_cid_keys) {
|
||||
public function testUncacheableParent($element, $args, array $expected_placeholder_render_array, $placeholder_cid_parts, array $placeholder_expected_render_cache_array) {
|
||||
if ($placeholder_cid_parts) {
|
||||
$this->setupMemoryCache();
|
||||
}
|
||||
else {
|
||||
|
@ -244,7 +422,7 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
'dynamic_animal' => $args[0],
|
||||
];
|
||||
$this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the one added by the placeholder #lazy_builder callback exist.');
|
||||
$this->assertPlaceholderRenderCache($placeholder_cid_keys, $placeholder_expected_render_cache_array);
|
||||
$this->assertPlaceholderRenderCache($placeholder_cid_parts, $placeholder_expected_render_cache_array);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,26 +434,13 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
*
|
||||
* @dataProvider providerPlaceholders
|
||||
*/
|
||||
public function testCacheableParent($test_element, $args, $placeholder_cid_keys, array $placeholder_expected_render_cache_array) {
|
||||
public function testCacheableParent($test_element, $args, array $expected_placeholder_render_array, $placeholder_cid_parts, array $placeholder_expected_render_cache_array) {
|
||||
$element = $test_element;
|
||||
$this->setupMemoryCache();
|
||||
|
||||
$this->setUpRequest('GET');
|
||||
|
||||
// Generate the expected placeholder render array, so that we can generate
|
||||
// the expected placeholder markup.
|
||||
$expected_placeholder_render_array = [];
|
||||
// When there was a child element that created a placeholder, the Renderer
|
||||
// automatically initializes #cache[contexts].
|
||||
if (Element::children($test_element)) {
|
||||
$expected_placeholder_render_array['#cache']['contexts'] = [];
|
||||
}
|
||||
// When the placeholder itself is cacheable, its cache keys are present.
|
||||
if ($placeholder_cid_keys) {
|
||||
$expected_placeholder_render_array['#cache']['keys'] = $placeholder_cid_keys;
|
||||
}
|
||||
$expected_placeholder_render_array['#lazy_builder'] = ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args];
|
||||
$token = hash('sha1', serialize($expected_placeholder_render_array));
|
||||
$token = hash('crc32b', serialize($expected_placeholder_render_array));
|
||||
$expected_placeholder_markup = '<drupal-render-placeholder callback="Drupal\Tests\Core\Render\PlaceholdersTest::callback" arguments="0=' . $args[0] . '" token="' . $token . '"></drupal-render-placeholder>';
|
||||
$this->assertSame($expected_placeholder_markup, Html::normalize($expected_placeholder_markup), 'Placeholder unaltered by Html::normalize() which is used by FilterHtmlCorrector.');
|
||||
|
||||
|
@ -291,7 +456,7 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
'dynamic_animal' => $args[0],
|
||||
];
|
||||
$this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the one added by the placeholder #lazy_builder callback exist.');
|
||||
$this->assertPlaceholderRenderCache($placeholder_cid_keys, $placeholder_expected_render_cache_array);
|
||||
$this->assertPlaceholderRenderCache($placeholder_cid_parts, $placeholder_expected_render_cache_array);
|
||||
|
||||
// GET request: validate cached data.
|
||||
$cached_element = $this->memoryCache->get('placeholder_test_GET')->data;
|
||||
|
@ -434,7 +599,9 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
'null' => NULL,
|
||||
]];
|
||||
|
||||
$this->renderer->renderRoot($element);
|
||||
$result = $this->renderer->renderRoot($element);
|
||||
$this->assertInstanceOf('\Drupal\Core\Render\SafeString', $result);
|
||||
$this->assertEquals('<p>This is a rendered placeholder!</p>', (string) $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -521,10 +688,6 @@ class RendererPlaceholdersTest extends RendererTestBase {
|
|||
$this->cacheContextsManager->expects($this->any())
|
||||
->method('convertTokensToKeys')
|
||||
->willReturnArgument(0);
|
||||
$this->elementInfo->expects($this->any())
|
||||
->method('getInfo')
|
||||
->with('details')
|
||||
->willReturn(['#theme_wrappers' => ['details']]);
|
||||
$this->controllerResolver->expects($this->any())
|
||||
->method('getControllerFromDefinition')
|
||||
->willReturnArgument(0);
|
||||
|
|
|
@ -35,6 +35,18 @@ class RendererTest extends RendererTestBase {
|
|||
'#children' => '',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Reset the static list of SafeStrings to prevent bleeding between tests.
|
||||
$reflected_class = new \ReflectionClass('\Drupal\Component\Utility\SafeMarkup');
|
||||
$reflected_property = $reflected_class->getProperty('safeStrings');
|
||||
$reflected_property->setAccessible(true);
|
||||
$reflected_property->setValue([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::render
|
||||
* @covers ::doRender
|
||||
|
@ -47,7 +59,15 @@ class RendererTest extends RendererTestBase {
|
|||
$setup_code();
|
||||
}
|
||||
|
||||
$this->assertSame($expected, (string) $this->renderer->renderRoot($build));
|
||||
if (isset($build['#markup'])) {
|
||||
$this->assertFalse(SafeMarkup::isSafe($build['#markup']), 'The #markup value is not marked safe before rendering.');
|
||||
}
|
||||
$render_output = $this->renderer->renderRoot($build);
|
||||
$this->assertSame($expected, (string) $render_output);
|
||||
if ($render_output !== '') {
|
||||
$this->assertTrue(SafeMarkup::isSafe($render_output), 'Output of render is marked safe.');
|
||||
$this->assertTrue(SafeMarkup::isSafe($build['#markup']), 'The #markup value is marked safe after rendering.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,6 +100,19 @@ class RendererTest extends RendererTestBase {
|
|||
$data[] = [[
|
||||
'#markup' => 'foo',
|
||||
], 'foo'];
|
||||
// Basic #plain_text based renderable array.
|
||||
$data[] = [[
|
||||
'#plain_text' => 'foo',
|
||||
], 'foo'];
|
||||
// Mixing #plain_text and #markup based renderable array.
|
||||
$data[] = [[
|
||||
'#plain_text' => '<em>foo</em>',
|
||||
'#markup' => 'bar',
|
||||
], '<em>foo</em>'];
|
||||
// Safe strings in #plain_text are are still escaped.
|
||||
$data[] = [[
|
||||
'#plain_text' => SafeString::create('<em>foo</em>'),
|
||||
], '<em>foo</em>'];
|
||||
// Renderable child element.
|
||||
$data[] = [[
|
||||
'child' => ['#markup' => 'bar'],
|
||||
|
@ -88,6 +121,22 @@ class RendererTest extends RendererTestBase {
|
|||
$data[] = [[
|
||||
'child' => ['#markup' => "This is <script>alert('XSS')</script> test"],
|
||||
], "This is alert('XSS') test"];
|
||||
// XSS filtering test.
|
||||
$data[] = [[
|
||||
'child' => ['#markup' => "This is <script>alert('XSS')</script> test", '#allowed_tags' => ['script']],
|
||||
], "This is <script>alert('XSS')</script> test"];
|
||||
// XSS filtering test.
|
||||
$data[] = [[
|
||||
'child' => ['#markup' => "This is <script><em>alert('XSS')</em></script> <strong>test</strong>", '#allowed_tags' => ['em', 'strong']],
|
||||
], "This is <em>alert('XSS')</em> <strong>test</strong>"];
|
||||
// Html escaping test.
|
||||
$data[] = [[
|
||||
'child' => ['#plain_text' => "This is <script><em>alert('XSS')</em></script> <strong>test</strong>"],
|
||||
], "This is <script><em>alert('XSS')</em></script> <strong>test</strong>"];
|
||||
// XSS filtering by default test.
|
||||
$data[] = [[
|
||||
'child' => ['#markup' => "This is <script><em>alert('XSS')</em></script> <strong>test</strong>"],
|
||||
], "This is <em>alert('XSS')</em> <strong>test</strong>"];
|
||||
// Ensure non-XSS tags are not filtered out.
|
||||
$data[] = [[
|
||||
'child' => ['#markup' => "This is <strong><script>alert('not a giraffe')</script></strong> test"],
|
||||
|
@ -150,10 +199,6 @@ class RendererTest extends RendererTestBase {
|
|||
$attributes = new Attribute(['href' => $vars['#url']] + (isset($vars['#attributes']) ? $vars['#attributes'] : []));
|
||||
return '<a' . (string) $attributes . '>' . $vars['#title'] . '</a>';
|
||||
});
|
||||
$this->elementInfo->expects($this->atLeastOnce())
|
||||
->method('getInfo')
|
||||
->with('link')
|
||||
->willReturn(['#theme' => 'link']);
|
||||
};
|
||||
$data[] = [$build, '<div class="baz"><a href="https://www.drupal.org" id="foo">bar</a></div>' . "\n", $setup_code_type_link];
|
||||
|
||||
|
|
|
@ -79,6 +79,13 @@ class RendererTestBase extends UnitTestCase {
|
|||
*/
|
||||
protected $memoryCache;
|
||||
|
||||
/**
|
||||
* The simulated "current" user role, for use in tests with cache contexts.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $currentUserRole;
|
||||
|
||||
/**
|
||||
* The mocked renderer configuration.
|
||||
*
|
||||
|
@ -89,6 +96,11 @@ class RendererTestBase extends UnitTestCase {
|
|||
'languages:language_interface',
|
||||
'theme',
|
||||
],
|
||||
'auto_placeholder_conditions' => [
|
||||
'max-age' => 0,
|
||||
'contexts' => ['session', 'user'],
|
||||
'tags' => ['current-temperature'],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -100,6 +112,22 @@ class RendererTestBase extends UnitTestCase {
|
|||
$this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
|
||||
$this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
|
||||
$this->elementInfo = $this->getMock('Drupal\Core\Render\ElementInfoManagerInterface');
|
||||
$this->elementInfo->expects($this->any())
|
||||
->method('getInfo')
|
||||
->willReturnCallback(function ($type) {
|
||||
switch ($type) {
|
||||
case 'details':
|
||||
$info = ['#theme_wrappers' => ['details']];
|
||||
break;
|
||||
case 'link':
|
||||
$info = ['#theme' => 'link'];
|
||||
break;
|
||||
default:
|
||||
$info = [];
|
||||
}
|
||||
$info['#defaults_loaded'] = TRUE;
|
||||
return $info;
|
||||
});
|
||||
$this->requestStack = new RequestStack();
|
||||
$request = new Request();
|
||||
$request->server->set('REQUEST_TIME', $_SERVER['REQUEST_TIME']);
|
||||
|
@ -108,10 +136,10 @@ class RendererTestBase extends UnitTestCase {
|
|||
$this->cacheContextsManager = $this->getMockBuilder('Drupal\Core\Cache\Context\CacheContextsManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$current_user_role = &$this->currentUserRole;
|
||||
$this->cacheContextsManager->expects($this->any())
|
||||
->method('convertTokensToKeys')
|
||||
->willReturnCallback(function($context_tokens) {
|
||||
global $current_user_role;
|
||||
->willReturnCallback(function($context_tokens) use (&$current_user_role) {
|
||||
$keys = [];
|
||||
foreach ($context_tokens as $context_id) {
|
||||
switch ($context_id) {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
namespace Drupal\Tests\Core\Route;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
use Drupal\Core\Session\UserSession;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\user\Access\RoleAccessCheck;
|
||||
|
@ -143,6 +145,11 @@ class RoleAccessCheckTest extends UnitTestCase {
|
|||
* @dataProvider roleAccessProvider
|
||||
*/
|
||||
public function testRoleAccess($path, $grant_accounts, $deny_accounts) {
|
||||
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
|
||||
$container = new Container();
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($container);
|
||||
|
||||
$role_access_check = new RoleAccessCheck();
|
||||
$collection = $this->getTestRouteCollection();
|
||||
|
||||
|
|
|
@ -41,13 +41,21 @@ class RoutePreloaderTest extends UnitTestCase {
|
|||
*/
|
||||
protected $preloader;
|
||||
|
||||
/**
|
||||
* The mocked cache.
|
||||
*
|
||||
* @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->routeProvider = $this->getMock('Drupal\Core\Routing\PreloadableRouteProviderInterface');
|
||||
$this->state = $this->getMock('\Drupal\Core\State\StateInterface');
|
||||
$this->preloader = new RoutePreloader($this->routeProvider, $this->state);
|
||||
$this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
|
||||
$this->preloader = new RoutePreloader($this->routeProvider, $this->state, $this->cache);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,6 +61,13 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
|
|||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* The mocked cache backend.
|
||||
*
|
||||
* @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $staticCache;
|
||||
|
||||
/**
|
||||
* The permission hash class being tested.
|
||||
*
|
||||
|
@ -138,12 +145,15 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
|
|||
$this->cache = $this->getMockBuilder('Drupal\Core\Cache\CacheBackendInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->staticCache = $this->getMockBuilder('Drupal\Core\Cache\CacheBackendInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache);
|
||||
$this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache, $this->staticCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the generate() method.
|
||||
* @covers ::generate
|
||||
*/
|
||||
public function testGenerate() {
|
||||
// Ensure that the super user (user 1) always gets the same hash.
|
||||
|
@ -162,15 +172,23 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests the generate method with cache returned.
|
||||
* @covers ::generate
|
||||
*/
|
||||
public function testGenerateCache() {
|
||||
public function testGeneratePersistentCache() {
|
||||
// Set expectations for the mocked cache backend.
|
||||
$expected_cid = 'user_permissions_hash:administrator,authenticated';
|
||||
|
||||
$mock_cache = new \stdClass();
|
||||
$mock_cache->data = 'test_hash_here';
|
||||
|
||||
$this->staticCache->expects($this->once())
|
||||
->method('get')
|
||||
->with($expected_cid)
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->staticCache->expects($this->once())
|
||||
->method('set')
|
||||
->with($expected_cid, $this->isType('string'));
|
||||
|
||||
$this->cache->expects($this->once())
|
||||
->method('get')
|
||||
->with($expected_cid)
|
||||
|
@ -181,6 +199,31 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
|
|||
$this->permissionsHash->generate($this->account2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::generate
|
||||
*/
|
||||
public function testGenerateStaticCache() {
|
||||
// Set expectations for the mocked cache backend.
|
||||
$expected_cid = 'user_permissions_hash:administrator,authenticated';
|
||||
|
||||
$mock_cache = new \stdClass();
|
||||
$mock_cache->data = 'test_hash_here';
|
||||
|
||||
$this->staticCache->expects($this->once())
|
||||
->method('get')
|
||||
->with($expected_cid)
|
||||
->will($this->returnValue($mock_cache));
|
||||
$this->staticCache->expects($this->never())
|
||||
->method('set');
|
||||
|
||||
$this->cache->expects($this->never())
|
||||
->method('get');
|
||||
$this->cache->expects($this->never())
|
||||
->method('set');
|
||||
|
||||
$this->permissionsHash->generate($this->account2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the generate method with no cache returned.
|
||||
*/
|
||||
|
@ -188,6 +231,14 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
|
|||
// Set expectations for the mocked cache backend.
|
||||
$expected_cid = 'user_permissions_hash:administrator,authenticated';
|
||||
|
||||
$this->staticCache->expects($this->once())
|
||||
->method('get')
|
||||
->with($expected_cid)
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->staticCache->expects($this->once())
|
||||
->method('set')
|
||||
->with($expected_cid, $this->isType('string'));
|
||||
|
||||
$this->cache->expects($this->once())
|
||||
->method('get')
|
||||
->with($expected_cid)
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\StackMiddleware\NegotiationMiddlewareTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\StackMiddleware;
|
||||
|
||||
use Drupal\Core\StackMiddleware\NegotiationMiddleware;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\StackMiddleware\NegotiationMiddleware
|
||||
* @group NegotiationMiddleware
|
||||
*/
|
||||
class NegotiationMiddlewareTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Tests\Core\StackMiddleware\StubNegotiationMiddleware
|
||||
*/
|
||||
protected $contentNegotiation;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->app = $this->prophesize(HttpKernelInterface::class);
|
||||
$this->contentNegotiation = new StubNegotiationMiddleware($this->app->reveal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getContentType() method with AJAX iframe upload.
|
||||
*
|
||||
* @covers ::getContentType
|
||||
*/
|
||||
public function testAjaxIframeUpload() {
|
||||
$request = new Request();
|
||||
$request->attributes->set('ajax_iframe_upload', '1');
|
||||
|
||||
$this->assertSame('iframeupload', $this->contentNegotiation->getContentType($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the specifying a format via query parameters gets used.
|
||||
*
|
||||
* @covers ::getContentType
|
||||
*/
|
||||
public function testFormatViaQueryParameter() {
|
||||
$request = new Request();
|
||||
$request->query->set('_format', 'bob');
|
||||
|
||||
$this->assertSame('bob', $this->contentNegotiation->getContentType($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getContentType() method when no priority format is found.
|
||||
*
|
||||
* @covers ::getContentType
|
||||
*/
|
||||
public function testUnknowContentTypeReturnsHtmlByDefault() {
|
||||
$request = new Request();
|
||||
|
||||
$this->assertSame('html', $this->contentNegotiation->getContentType($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getContentType() method when no priority format is found but it's an AJAX request.
|
||||
*
|
||||
* @covers ::getContentType
|
||||
*/
|
||||
public function testUnknowContentTypeButAjaxRequest() {
|
||||
$request = new Request();
|
||||
$request->headers->set('X-Requested-With', 'XMLHttpRequest');
|
||||
|
||||
$this->assertSame('html', $this->contentNegotiation->getContentType($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that handle() correctly hands off to sub application.
|
||||
*
|
||||
* @covers ::handle
|
||||
*/
|
||||
public function testHandle() {
|
||||
$request = $this->prophesize(Request::class);
|
||||
|
||||
// Default empty format list should not set any formats.
|
||||
$request->setFormat()->shouldNotBeCalled();
|
||||
|
||||
// Request format will be set with default format.
|
||||
$request->setRequestFormat('html')->shouldBeCalled();
|
||||
|
||||
// Some getContentType calls we don't really care about but have to mock.
|
||||
$request->get('ajax_iframe_upload', false)->shouldBeCalled();
|
||||
$request_mock = $request->reveal();
|
||||
$request_mock->query = new ParameterBag([]);
|
||||
|
||||
// Calling kernel app with default arguments.
|
||||
$this->app->handle($request_mock, HttpKernelInterface::MASTER_REQUEST, TRUE)
|
||||
->shouldBeCalled();
|
||||
$this->contentNegotiation->handle($request_mock);
|
||||
// Calling kernel app with specified arguments.
|
||||
$this->app->handle($request_mock, HttpKernelInterface::SUB_REQUEST, FALSE)
|
||||
->shouldBeCalled();
|
||||
$this->contentNegotiation->handle($request_mock, HttpKernelInterface::SUB_REQUEST, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::registerFormat
|
||||
*/
|
||||
public function testSetFormat() {
|
||||
$request = $this->prophesize(Request::class);
|
||||
|
||||
// Default empty format list should not set any formats.
|
||||
$request->setFormat('david', 'geeky/david')->shouldBeCalled();
|
||||
|
||||
// Some calls we don't care about.
|
||||
$request->setRequestFormat('html')->shouldBeCalled();
|
||||
$request->get('ajax_iframe_upload', false)->shouldBeCalled();
|
||||
$request_mock = $request->reveal();
|
||||
$request_mock->query = new ParameterBag([]);
|
||||
|
||||
// Trigger handle.
|
||||
$this->contentNegotiation->registerFormat('david', 'geeky/david');
|
||||
$this->contentNegotiation->handle($request_mock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class StubNegotiationMiddleware extends NegotiationMiddleware {
|
||||
public function getContentType(Request $request) { return parent::getContentType($request); }
|
||||
}
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Template;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Template\TwigEnvironment;
|
||||
use Drupal\Core\Template\TwigExtension;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -124,6 +127,31 @@ class TwigExtensionTest extends UnitTestCase {
|
|||
$this->assertSame('<script>alert('here');</script>', $twig_extension->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::safeJoin
|
||||
*/
|
||||
public function testSafeJoin() {
|
||||
$renderer = $this->prophesize(RendererInterface::class);
|
||||
$renderer->render(['#markup' => '<strong>will be rendered</strong>', '#printed' => FALSE])->willReturn('<strong>will be rendered</strong>');
|
||||
$renderer = $renderer->reveal();
|
||||
|
||||
$twig_extension = new TwigExtension($renderer);
|
||||
$twig_environment = $this->prophesize(TwigEnvironment::class)->reveal();
|
||||
|
||||
|
||||
// Simulate t().
|
||||
$string = '<em>will be markup</em>';
|
||||
SafeMarkup::setMultiple([$string => ['html' => TRUE]]);
|
||||
|
||||
$items = [
|
||||
'<em>will be escaped</em>',
|
||||
$string,
|
||||
['#markup' => '<strong>will be rendered</strong>']
|
||||
];
|
||||
$result = $twig_extension->safeJoin($twig_environment, $items, '<br/>');
|
||||
$this->assertEquals('<em>will be escaped</em><br/><em>will be markup</em><br/><strong>will be rendered</strong>', $result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TwigExtensionTestString {
|
||||
|
|
|
@ -105,6 +105,9 @@ class RegistryTest extends UnitTestCase {
|
|||
->method('getImplementations')
|
||||
->with('theme')
|
||||
->will($this->returnValue(array('theme_test')));
|
||||
$this->moduleHandler->expects($this->atLeastOnce())
|
||||
->method('getModuleList')
|
||||
->willReturn([]);
|
||||
|
||||
$registry = $this->registry->get();
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
namespace Drupal\Tests\Core\Transliteration;
|
||||
|
||||
use Drupal\Component\Utility\Random;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Transliteration\PhpTransliteration;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -59,12 +58,7 @@ class PhpTransliterationTest extends UnitTestCase {
|
|||
$transliteration = new PhpTransliteration(NULL, $module_handler);
|
||||
|
||||
$actual = $transliteration->transliterate($original, $langcode);
|
||||
$this->assertSame($expected, $actual, SafeMarkup::format('@original transliteration to @actual is identical to @expected for language @langcode in service instance.', array(
|
||||
'@original' => $printable,
|
||||
'@langcode' => $langcode,
|
||||
'@expected' => $expected,
|
||||
'@actual' => $actual,
|
||||
)));
|
||||
$this->assertSame($expected, $actual, "'$printable' transliteration to '$actual' is identical to '$expected' for language '$langcode' in service instance.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Utility {
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\GeneratedUrl;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\LinkGenerator;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
@ -372,11 +372,11 @@ class LinkGeneratorTest extends UnitTestCase {
|
|||
), $result);
|
||||
|
||||
// Test that safe HTML is output inside the anchor tag unescaped. The
|
||||
// SafeMarkup::set() call is an intentional unit test for the interaction
|
||||
// between SafeMarkup and the LinkGenerator.
|
||||
// SafeString::create() call is an intentional unit test for the interaction
|
||||
// between SafeStringInterface and the LinkGenerator.
|
||||
$url = new Url('test_route_5', array());
|
||||
$url->setUrlGenerator($this->urlGenerator);
|
||||
$result = $this->linkGenerator->generate(SafeMarkup::set('<em>HTML output</em>'), $url);
|
||||
$result = $this->linkGenerator->generate(SafeString::create('<em>HTML output</em>'), $url);
|
||||
$this->assertLink(array(
|
||||
'attributes' => array('href' => '/test-route-5'),
|
||||
'child' => array(
|
||||
|
|
165
core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php
Normal file
165
core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Listeners\DrupalStandardsListener.
|
||||
*
|
||||
* Listener for PHPUnit tests, to enforce various coding standards within test
|
||||
* runs.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Listeners;
|
||||
|
||||
/**
|
||||
* Listens for PHPUnit tests and fails those with invalid coverage annotations.
|
||||
*/
|
||||
class DrupalStandardsListener extends \PHPUnit_Framework_BaseTestListener {
|
||||
|
||||
/**
|
||||
* Signals a coding standards failure to the user.
|
||||
*
|
||||
* @param \PHPUnit_Framework_TestCase $test
|
||||
* The test where we should insert our test failure.
|
||||
* @param string $message
|
||||
* The message to add to the failure notice. The test class name and test
|
||||
* name will be appended to this message automatically.
|
||||
*/
|
||||
protected function fail(\PHPUnit_Framework_TestCase $test, $message) {
|
||||
// Add the report to the test's results.
|
||||
$message .= ': ' . get_class($test) . '::' . $test->getName();
|
||||
$fail = new \PHPUnit_Framework_AssertionFailedError($message);
|
||||
$result = $test->getTestResultObject();
|
||||
$result->addFailure($test, $fail, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if a string names a valid class or trait.
|
||||
*
|
||||
* @param string $class
|
||||
* Name of the class to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the class exists, FALSE otherwise.
|
||||
*/
|
||||
protected function classExists($class) {
|
||||
return class_exists($class, TRUE) || trait_exists($class, TRUE) || interface_exists($class, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an individual test run for valid @covers annotation.
|
||||
*
|
||||
* This method is called from $this::endTest().
|
||||
*
|
||||
* @param \PHPUnit_Framework_TestCase $test
|
||||
* The test to examine.
|
||||
*/
|
||||
public function checkValidCoversForTest(\PHPUnit_Framework_TestCase $test) {
|
||||
// If we're generating a coverage report already, don't do anything here.
|
||||
if ($test->getTestResultObject() && $test->getTestResultObject()->getCollectCodeCoverageInformation()) {
|
||||
return;
|
||||
}
|
||||
// Gather our annotations.
|
||||
$annotations = $test->getAnnotations();
|
||||
// Glean the @coversDefaultClass annotation.
|
||||
$default_class = '';
|
||||
$valid_default_class = FALSE;
|
||||
if (isset($annotations['class']['coversDefaultClass'])) {
|
||||
if (count($annotations['class']['coversDefaultClass']) > 1) {
|
||||
$this->fail($test, '@coversDefaultClass has too many values');
|
||||
}
|
||||
// Grab the first one.
|
||||
$default_class = reset($annotations['class']['coversDefaultClass']);
|
||||
// Check whether the default class exists.
|
||||
$valid_default_class = $this->classExists($default_class);
|
||||
if (!$valid_default_class) {
|
||||
$this->fail($test, "@coversDefaultClass does not exist '$default_class'");
|
||||
}
|
||||
}
|
||||
// Glean @covers annotation.
|
||||
if (isset($annotations['method']['covers'])) {
|
||||
// Drupal allows multiple @covers per test method, so we have to check
|
||||
// them all.
|
||||
foreach ($annotations['method']['covers'] as $covers) {
|
||||
// Ensure the annotation isn't empty.
|
||||
if (trim($covers) === '') {
|
||||
$this->fail($test, '@covers should not be empty');
|
||||
// If @covers is empty, we can't proceed.
|
||||
return;
|
||||
}
|
||||
// Ensure we don't have ().
|
||||
if (strpos($covers, '()') !== FALSE) {
|
||||
$this->fail($test, "@covers invalid syntax: Do not use '()'");
|
||||
}
|
||||
// Glean the class and method from @covers.
|
||||
$class = $covers;
|
||||
$method = '';
|
||||
if (strpos($covers, '::') !== FALSE) {
|
||||
list($class, $method) = explode('::', $covers);
|
||||
}
|
||||
// Check for the existence of the class if it's specified by @covers.
|
||||
if (!empty($class)) {
|
||||
// If the class doesn't exist we have either a bad classname or
|
||||
// are missing the :: for a method. Either way we can't proceed.
|
||||
if (!$this->classExists($class)) {
|
||||
if (empty($method)) {
|
||||
$this->fail($test, "@covers invalid syntax: Needs '::' or class does not exist in $covers");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$this->fail($test, '@covers class does not exist ' . $class);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The class isn't specified and we have the ::, so therefore this
|
||||
// test either covers a function, or relies on a default class.
|
||||
if (empty($default_class)) {
|
||||
// If there's no default class, then we need to check if the global
|
||||
// function exists. Since this listener should always be listening
|
||||
// for endTest(), the function should have already been loaded from
|
||||
// its .module or .inc file.
|
||||
if (!function_exists($method)) {
|
||||
$this->fail($test, '@covers global method does not exist ' . $method);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We have a default class and this annotation doesn't act like a
|
||||
// global function, so we should use the default class if it's
|
||||
// valid.
|
||||
if ($valid_default_class) {
|
||||
$class = $default_class;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally, after all that, let's see if the method exists.
|
||||
if (!empty($class) && !empty($method)) {
|
||||
$ref_class = new \ReflectionClass($class);
|
||||
if (!$ref_class->hasMethod($method)) {
|
||||
$this->fail($test, '@covers method does not exist ' . $class . '::' . $method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function endTest(\PHPUnit_Framework_Test $test, $time) {
|
||||
// \PHPUnit_Framework_Test does not have any useful methods of its own for
|
||||
// our purpose, so we have to distinguish between the different known
|
||||
// subclasses.
|
||||
if ($test instanceof \PHPUnit_Framework_TestCase) {
|
||||
$this->checkValidCoversForTest($test);
|
||||
}
|
||||
elseif ($test instanceof \PHPUnit_Framework_TestSuite) {
|
||||
foreach ($test->getGroupDetails() as $tests) {
|
||||
foreach ($tests as $test) {
|
||||
$this->endTest($test, $time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
core/tests/Drupal/Tests/Listeners/SafeMarkupSideEffects.php
Normal file
35
core/tests/Drupal/Tests/Listeners/SafeMarkupSideEffects.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Listeners\SafeMarkupSideEffects.
|
||||
*
|
||||
* Listener for PHPUnit tests, to enforce that data providers don't add to the
|
||||
* SafeMarkup static safe string list.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Listeners;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
|
||||
/**
|
||||
* Listens for PHPUnit tests and fails those with SafeMarkup side effects.
|
||||
*/
|
||||
class SafeMarkupSideEffects extends \PHPUnit_Framework_BaseTestListener {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function startTestSuite(\PHPUnit_Framework_TestSuite $suite) {
|
||||
// Use a static so we only do this test once after all the data providers
|
||||
// have run.
|
||||
static $tested = FALSE;
|
||||
if ($suite->getName() !== '' && !$tested) {
|
||||
$tested = TRUE;
|
||||
if (!empty(SafeMarkup::getAll())) {
|
||||
throw new \RuntimeException('SafeMarkup string list polluted by data providers');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -48,6 +48,12 @@ abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
|
|||
FileCacheFactory::setConfiguration(['default' => ['class' => '\Drupal\Component\FileCache\NullFileCache']]);
|
||||
|
||||
$this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
|
||||
|
||||
// Reset the static list of SafeStrings to prevent bleeding between tests.
|
||||
$reflected_class = new \ReflectionClass('\Drupal\Component\Utility\SafeMarkup');
|
||||
$reflected_property = $reflected_class->getProperty('safeStrings');
|
||||
$reflected_property->setAccessible(true);
|
||||
$reflected_property->setValue([]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Reference in a new issue