Issue #2553733 by alexpott, dawehner, Wim Leers, jibran: BrowserTestBase should be adding the config schema checker like WebTestBase

8.3.x
Nathaniel Catchpole 2016-08-05 15:58:10 +01:00
parent 3fa22c4bf0
commit 937b9f228d
4 changed files with 142 additions and 38 deletions

View File

@ -0,0 +1,22 @@
<?php
namespace Drupal\FunctionalTests\Core\Config;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\Traits\Core\Config\SchemaConfigListenerTestTrait;
/**
* Tests the functionality of ConfigSchemaChecker in KernelTestBase tests.
*
* @group config
*/
class SchemaConfigListenerTest extends BrowserTestBase {
use SchemaConfigListenerTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = array('config_test');
}

View File

@ -2,8 +2,8 @@
namespace Drupal\KernelTests\Core\Config;
use Drupal\Core\Config\Schema\SchemaIncompleteException;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\Traits\Core\Config\SchemaConfigListenerTestTrait;
/**
* Tests the functionality of ConfigSchemaChecker in KernelTestBase tests.
@ -12,50 +12,22 @@ use Drupal\KernelTests\KernelTestBase;
*/
class SchemaConfigListenerTest extends KernelTestBase {
use SchemaConfigListenerTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = array('config_test');
/**
* Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker.
* {@inheritdoc}
*/
public function testConfigSchemaChecker() {
// Test a non-existing schema.
$message = 'Expected SchemaIncompleteException thrown';
try {
$this->config('config_schema_test.schemaless')->set('foo', 'bar')->save();
$this->fail($message);
}
catch (SchemaIncompleteException $e) {
$this->pass($message);
$this->assertEqual('No schema for config_schema_test.schemaless', $e->getMessage());
}
// Test a valid schema.
$message = 'Unexpected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')->set('int', 10);
try {
$config->save();
$this->pass($message);
}
catch (SchemaIncompleteException $e) {
$this->fail($message);
}
// Test an invalid schema.
$message = 'Expected SchemaIncompleteException thrown';
$config = $this->config('config_test.types')
->set('foo', 'bar')
->set('array', 1);
try {
$config->save();
$this->fail($message);
}
catch (SchemaIncompleteException $e) {
$this->pass($message);
$this->assertEqual('Schema errors for config_test.types with the following errors: config_test.types:foo missing schema, config_test.types:array variable type is integer but applied schema class is Drupal\Core\Config\Schema\Sequence', $e->getMessage());
}
protected function setUp() {
parent::setUp();
// Install configuration provided by the module so that the order of the
// config keys is the same as
// \Drupal\FunctionalTests\Core\Config\SchemaConfigListenerTest.
$this->installConfig(['config_test']);
}
}

View File

@ -12,6 +12,7 @@ use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Testing\ConfigSchemaChecker;
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Serialization\Yaml;
@ -154,6 +155,31 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
*/
protected $configImporter;
/**
* Set to TRUE to strict check all configuration saved.
*
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
*
* @var bool
*/
protected $strictConfigSchema = TRUE;
/**
* An array of config object names that are excluded from schema checking.
*
* @var string[]
*/
protected static $configSchemaCheckerExclusions = array(
// Following are used to test lack of or partial schema. Where partial
// schema is provided, that is explicitly tested in specific tests.
'config_schema_test.noschema',
'config_schema_test.someschema',
'config_schema_test.schema_data_types',
'config_schema_test.no_schema_data_types',
// Used to test application of schema to filtering of configuration.
'config_test.dynamic.system',
);
/**
* The profile to install as a basis for testing.
*
@ -990,6 +1016,17 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
}
// Copy the testing-specific service overrides in place.
copy($settings_services_file, $directory . '/services.yml');
if ($this->strictConfigSchema) {
// Add a listener to validate configuration schema on save.
$content = file_get_contents($directory . '/services.yml');
$services = Yaml::decode($content);
$services['services']['simpletest.config_schema_checker'] = [
'class' => ConfigSchemaChecker::class,
'arguments' => ['@config.typed', $this->getConfigSchemaExclusions()],
'tags' => [['name' => 'event_subscriber']]
];
file_put_contents($directory . '/services.yml', Yaml::encode($services));
}
// Since Drupal is bootstrapped already, install_begin_request() will not
// bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to
@ -1686,4 +1723,23 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
$file_cache->delete($filename);
}
/**
* Gets the config schema exclusions for this test.
*
* @return string[]
* An array of config object names that are excluded from schema checking.
*/
protected function getConfigSchemaExclusions() {
$class = get_class($this);
$exceptions = [];
while ($class) {
if (property_exists($class, 'configSchemaCheckerExclusions')) {
$exceptions = array_merge($exceptions, $class::$configSchemaCheckerExclusions);
}
$class = get_parent_class($class);
}
// Filter out any duplicates.
return array_unique($exceptions);
}
}

View File

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