diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index 07b0384..822830e 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -215,8 +215,11 @@ public function clearCachedDefinitions() { * definition in below order: * breakpoint.breakpoint.module.toolbar.* * breakpoint.breakpoint.module.*.* + * breakpoint.breakpoint.module.* * breakpoint.breakpoint.*.*.* + * breakpoint.breakpoint.* * breakpoint.*.*.*.* + * breakpoint.* * Returns null, if no matching element. */ protected function getFallbackName($name) { @@ -227,8 +230,16 @@ protected function getFallbackName($name) { return $replaced; } else { - // No definition for this level(for example, breakpoint.breakpoint.*), - // check for next level (which is, breakpoint.*.*). + // No definition for this level. Collapse multiple wildcards to a single + // wildcard to see if there is a greedy match. For example, + // breakpoint.breakpoint.*.* becomes + // breakpoint.breakpoint.* + $one_star = preg_replace('/\.([\.\*]*)$/', '.*', $replaced); + if ($one_star != $replaced && isset($this->definitions[$one_star])) { + return $one_star; + } + // Check for next level. For example, if breakpoint.breakpoint.* has + // been checked and no match found then check breakpoint.*.* return $this->getFallbackName($replaced); } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php index f2a10f3..3e97adf 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php @@ -44,14 +44,14 @@ function testModuleInstallation() { // Ensure that schema provided by modules that are not installed is not // available. - $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_test.schema_in_install'), 'Configuration schema for config_test.schema_in_install does not exist.'); + $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.'); // Install the test module. - $this->enableModules(array('config_test')); - $this->installConfig(array('config_test')); + $this->enableModules(array('config_test', 'config_schema_test')); + $this->installConfig(array('config_test', 'config_schema_test')); // After module installation the new schema should exist. - $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_test.schema_in_install'), 'Configuration schema for config_test.schema_in_install exists.'); + $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install exists.'); // Verify that default module config exists. \Drupal::configFactory()->reset($default_config); @@ -71,13 +71,13 @@ function testModuleInstallation() { $this->assertFalse(isset($GLOBALS['hook_config_test']['delete'])); // Ensure that data type casting is applied during config installation. - $config = \Drupal::config('config_test.schema_in_install'); + $config = \Drupal::config('config_schema_test.schema_in_install'); $this->assertIdentical($config->get('integer'), 1); // Test that uninstalling configuration removes configuration schema. \Drupal::config('core.extension')->set('module', array())->save(); \Drupal::service('config.manager')->uninstall('module', 'config_test'); - $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_test.schema_in_install'), 'Configuration schema for config_test.schema_in_install does not exist.'); + $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.'); } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php index e09f603..1ac6573 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php @@ -21,7 +21,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase { * * @var array */ - public static $modules = array('system', 'language', 'locale', 'field', 'image', 'config_test'); + public static $modules = array('system', 'language', 'locale', 'field', 'image', 'config_schema_test'); public static function getInfo() { return array( @@ -33,7 +33,7 @@ public static function getInfo() { public function setUp() { parent::setUp(); - $this->installConfig(array('system', 'image', 'config_test')); + $this->installConfig(array('system', 'image', 'config_schema_test')); } /** @@ -41,21 +41,21 @@ public function setUp() { */ function testSchemaMapping() { // Nonexistent configuration key will have Unknown as metadata. - $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_test.no_such_key')); - $definition = \Drupal::service('config.typed')->getDefinition('config_test.no_such_key'); + $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key')); + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key'); $expected = array(); $expected['label'] = 'Unknown'; $expected['class'] = '\Drupal\Core\Config\Schema\Property'; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.'); // Configuration file without schema will return Unknown as well. - $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_test.noschema')); - $definition = \Drupal::service('config.typed')->getDefinition('config_test.noschema'); + $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema')); + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema'); $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.'); // Configuration file with only some schema. - $this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_test.someschema')); - $definition = \Drupal::service('config.typed')->getDefinition('config_test.someschema'); + $this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema')); + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema'); $expected = array(); $expected['label'] = 'Schema test data'; $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; @@ -64,7 +64,7 @@ function testSchemaMapping() { $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.'); // Check type detection on elements with undefined types. - $config = \Drupal::service('config.typed')->get('config_test.someschema'); + $config = \Drupal::service('config.typed')->get('config_schema_test.someschema'); $definition = $config['testitem']->getDataDefinition(); $expected = array(); $expected['label'] = 'Test item'; @@ -139,8 +139,8 @@ function testSchemaMapping() { $this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium'); // More complex, multiple filesystem marker test. - $definition = \Drupal::service('config.typed')->getDefinition('config_test.someschema.somemodule.section_one.subsection'); - // This should be the schema of config_test.someschema.somemodule.*.*. + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection'); + // This should be the schema of config_schema_test.someschema.somemodule.*.*. $expected = array(); $expected['label'] = 'Schema multiple filesytem marker test'; $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; @@ -149,24 +149,24 @@ function testSchemaMapping() { $expected['mapping']['testdescription']['type'] = 'text'; $expected['mapping']['testdescription']['label'] = 'Description'; - $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.someschema.somemodule.section_one.subsection'); + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection'); - $definition = \Drupal::service('config.typed')->getDefinition('config_test.someschema.somemodule.section_two.subsection'); + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_two.subsection'); // The other file should have the same schema. - $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.someschema.somemodule.section_two.subsection'); + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_two.subsection'); } /** * Tests metadata retrieval with several levels of %parent indirection. */ function testSchemaMappingWithParents() { - $config_data = \Drupal::service('config.typed')->get('config_test.someschema.with_parents'); + $config_data = \Drupal::service('config.typed')->get('config_schema_test.someschema.with_parents'); // Test fetching parent one level up. $entry = $config_data->get('one_level'); $definition = $entry['testitem']->getDataDefinition(); $expected = array( - 'type' => 'config_test.someschema.with_parents.key_1', + 'type' => 'config_schema_test.someschema.with_parents.key_1', 'label' => 'Test item nested one level', 'class' => '\Drupal\Core\TypedData\Plugin\DataType\String', ); @@ -176,7 +176,7 @@ function testSchemaMappingWithParents() { $entry = $config_data->get('two_levels'); $definition = $entry['wrapper']['testitem']->getDataDefinition(); $expected = array( - 'type' => 'config_test.someschema.with_parents.key_2', + 'type' => 'config_schema_test.someschema.with_parents.key_2', 'label' => 'Test item nested two levels', 'class' => '\Drupal\Core\TypedData\Plugin\DataType\String', ); @@ -186,7 +186,7 @@ function testSchemaMappingWithParents() { $entry = $config_data->get('three_levels'); $definition = $entry['wrapper_1']['wrapper_2']['testitem']->getDataDefinition(); $expected = array( - 'type' => 'config_test.someschema.with_parents.key_3', + 'type' => 'config_schema_test.someschema.with_parents.key_3', 'label' => 'Test item nested three levels', 'class' => '\Drupal\Core\TypedData\Plugin\DataType\String', ); @@ -265,8 +265,8 @@ public function testConfigSaveWithSchema() { // Not in schema and therefore should be left untouched. 'not_present_in_schema' => TRUE, // Test a custom type. - 'config_test_integer' => '1', - 'config_test_integer_empty_string' => '', + 'config_schema_test_integer' => '1', + 'config_schema_test_integer_empty_string' => '', ); $untyped_to_typed = $untyped_values; @@ -285,21 +285,43 @@ public function testConfigSaveWithSchema() { 'null_float' => NULL, 'sequence' => array (TRUE, FALSE, TRUE), 'not_present_in_schema' => TRUE, - 'config_test_integer' => 1, - 'config_test_integer_empty_string' => NULL, + 'config_schema_test_integer' => 1, + 'config_schema_test_integer_empty_string' => NULL, ); // Save config which has a schema that enforces types. - \Drupal::config('config_test.schema_data_types') + \Drupal::config('config_schema_test.schema_data_types') ->setData($untyped_to_typed) ->save(); - $this->assertIdentical(\Drupal::config('config_test.schema_data_types')->get(), $typed_values); + $this->assertIdentical(\Drupal::config('config_schema_test.schema_data_types')->get(), $typed_values); // Save config which does not have a schema that enforces types. - \Drupal::config('config_test.no_schema_data_types') + \Drupal::config('config_schema_test.no_schema_data_types') ->setData($untyped_values) ->save(); - $this->assertIdentical(\Drupal::config('config_test.no_schema_data_types')->get(), $untyped_values); + $this->assertIdentical(\Drupal::config('config_schema_test.no_schema_data_types')->get(), $untyped_values); + } + + /** + * Tests fallback to a greedy wildcard. + */ + function testSchemaFallback() { + $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something'); + // This should be the schema of config_schema_test.wildcard_fallback.*. + $expected = array(); + $expected['label'] = 'Schema wildcard fallback test'; + $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['mapping']['testid']['type'] = 'string'; + $expected['mapping']['testid']['label'] = 'ID'; + $expected['mapping']['testdescription']['type'] = 'text'; + $expected['mapping']['testdescription']['label'] = 'Description'; + + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.wildcard_fallback.something'); + + $definition2 = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something.something'); + // This should be the schema of config_schema_test.wildcard_fallback.* as + //well. + $this->assertIdentical($definition, $definition2); } } diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php index 8a5d022..9ce5cea 100644 --- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php @@ -57,13 +57,9 @@ public function testDefaultConfig() { continue; } - // 1. config_test.noschema has to be skipped as it tests - // TypedConfigManagerInterface::hasConfigSchema() method. - // 2. config.someschema has to be skipped as it tests schema default data - // type fallback. - // 3. config_test.schema_in_install is testing that schema are used during - // configuration installation. - if ($config_name == 'config_test.noschema' || $config_name == 'config_test.someschema' || $config_name == 'config_test.schema_in_install') { + // Skip files provided by the config_schema_test module since that module + // is explicitly for testing schema. + if (strpos($config_name, 'config_schema_test') === 0) { continue; } diff --git a/core/modules/config/tests/config_test/config/install/config_test.noschema.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.noschema.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.noschema.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.noschema.yml diff --git a/core/modules/config/tests/config_test/config/install/config_test.schema_in_install.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.schema_in_install.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml diff --git a/core/modules/config/tests/config_test/config/install/config_test.someschema.somemodule.section_one.subsection.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.somemodule.section_one.subsection.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.someschema.somemodule.section_one.subsection.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.somemodule.section_one.subsection.yml diff --git a/core/modules/config/tests/config_test/config/install/config_test.someschema.somemodule.section_two.subsection.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.somemodule.section_two.subsection.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.someschema.somemodule.section_two.subsection.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.somemodule.section_two.subsection.yml diff --git a/core/modules/config/tests/config_test/config/install/config_test.someschema.with_parents.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.with_parents.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.someschema.with_parents.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.with_parents.yml diff --git a/core/modules/config/tests/config_test/config/install/config_test.someschema.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/config_test.someschema.yml rename to core/modules/config/tests/config_schema_test/config/install/config_schema_test.someschema.yml diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml new file mode 100644 index 0000000..9eec7d7 --- /dev/null +++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml @@ -0,0 +1,134 @@ +# Schema for the configuration files of the Configuration Schema Test module. + +config_schema_test.someschema: + type: mapping + label: 'Schema test data' + mapping: + testitem: + label: 'Test item' + testlist: + label: 'Test list' + +config_schema_test.someschema.with_parents: + label: 'Schema test data with parenting' + type: mapping + mapping: + one_level: + label: 'Parenting one level up' + type: mapping + mapping: + target_key: + label: 'Key used in parent relation' + type: string + testitem: + type: config_schema_test.someschema.with_parents.[%parent.target_key] + two_levels: + label: 'Parenting two levels up' + type: mapping + mapping: + target_key: + label: 'Key used in parent relation' + type: string + wrapper: + label: 'Wrapper' + type: mapping + mapping: + testitem: + type: config_schema_test.someschema.with_parents.[%parent.%parent.target_key] + three_levels: + label: 'Parenting three levels up' + type: mapping + mapping: + target_key: + label: 'Key used in parent relation' + type: string + wrapper_1: + label: 'Wrapper 1' + type: mapping + mapping: + wrapper_2: + label: 'Wrapper 2' + type: mapping + mapping: + testitem: + type: config_schema_test.someschema.with_parents.[%parent.%parent.%parent.target_key] + +config_schema_test.someschema.with_parents.key_1: + label: 'Test item nested one level' + type: string +config_schema_test.someschema.with_parents.key_2: + label: 'Test item nested two levels' + type: string +config_schema_test.someschema.with_parents.key_3: + label: 'Test item nested three levels' + type: string + +config_schema_test.someschema.somemodule.*.*: + type: mapping + label: 'Schema multiple filesytem marker test' + mapping: + testid: + type: string + label: 'ID' + testdescription: + type: text + label: 'Description' + +config_schema_test.wildcard_fallback.*: + type: mapping + label: 'Schema wildcard fallback test' + mapping: + testid: + type: string + label: 'ID' + testdescription: + type: text + label: 'Description' + +config_schema_test.schema_data_types: + type: mapping + label: 'Config test schema' + mapping: + config_schema_test_integer: + type: config_schema_test_integer + config_schema_test_integer_empty_string: + type: config_schema_test_integer + integer: + type: integer + null_integer: + type: integer + float: + type: float + null_float: + type: float + string: + type: string + null_string: + type: string + empty_string: + type: string + boolean: + type: boolean + no_type: + label: 'No label' + mapping: + type: mapping + mapping: + string: + type: string + sequence: + type: sequence + sequence: + - type: boolean + +config_schema_test.schema_in_install: + label: 'Schema test data with parenting' + type: mapping + mapping: + integer: + type: integer + label: 'Integer' + +config_schema_test_integer: + type: integer + label: 'Config test integer' diff --git a/core/modules/config/tests/config_schema_test/config_schema_test.info.yml b/core/modules/config/tests/config_schema_test/config_schema_test.info.yml new file mode 100644 index 0000000..9836e8b --- /dev/null +++ b/core/modules/config/tests/config_schema_test/config_schema_test.info.yml @@ -0,0 +1,6 @@ +name: 'Configuration schema test' +type: module +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml index 5a594e4..984026f 100644 --- a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml +++ b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml @@ -1,79 +1,5 @@ # Schema for the configuration files of the Configuration Test module. -config_test.someschema: - type: mapping - label: 'Schema test data' - mapping: - testitem: - label: 'Test item' - testlist: - label: 'Test list' - -config_test.someschema.with_parents: - label: 'Schema test data with parenting' - type: mapping - mapping: - one_level: - label: 'Parenting one level up' - type: mapping - mapping: - target_key: - label: 'Key used in parent relation' - type: string - testitem: - type: config_test.someschema.with_parents.[%parent.target_key] - two_levels: - label: 'Parenting two levels up' - type: mapping - mapping: - target_key: - label: 'Key used in parent relation' - type: string - wrapper: - label: 'Wrapper' - type: mapping - mapping: - testitem: - type: config_test.someschema.with_parents.[%parent.%parent.target_key] - three_levels: - label: 'Parenting three levels up' - type: mapping - mapping: - target_key: - label: 'Key used in parent relation' - type: string - wrapper_1: - label: 'Wrapper 1' - type: mapping - mapping: - wrapper_2: - label: 'Wrapper 2' - type: mapping - mapping: - testitem: - type: config_test.someschema.with_parents.[%parent.%parent.%parent.target_key] - -config_test.someschema.with_parents.key_1: - label: 'Test item nested one level' - type: string -config_test.someschema.with_parents.key_2: - label: 'Test item nested two levels' - type: string -config_test.someschema.with_parents.key_3: - label: 'Test item nested three levels' - type: string - -config_test.someschema.somemodule.*.*: - type: mapping - label: 'Schema multiple filesytem marker test' - mapping: - testid: - type: string - label: 'ID' - testdescription: - type: text - label: 'Description' - config_test.dynamic.*: type: mapping label: 'Config test entity' @@ -94,54 +20,6 @@ config_test.dynamic.*: type: string label: 'Protected property' -config_test_integer: - type: integer - label: 'Config test integer' - -config_test.schema_data_types: - type: mapping - label: 'Config test schema' - mapping: - config_test_integer: - type: config_test_integer - config_test_integer_empty_string: - type: config_test_integer - integer: - type: integer - null_integer: - type: integer - float: - type: float - null_float: - type: float - string: - type: string - null_string: - type: string - empty_string: - type: string - boolean: - type: boolean - no_type: - label: 'No label' - mapping: - type: mapping - mapping: - string: - type: string - sequence: - type: sequence - sequence: - - type: boolean - -config_test.schema_in_install: - label: 'Schema test data with parenting' - type: mapping - mapping: - integer: - type: integer - label: 'Integer' - config_test_dynamic: type: mapping mapping: diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index 2d9d11d..690a3ec 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -330,7 +330,7 @@ system.action.*: type: string label: 'Plugin' configuration: - type: action.configuration.[plugin] + type: action.configuration.[%parent.plugin] dependencies: type: config_dependencies label: 'Dependencies' diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml index 23a688a..7f61921 100644 --- a/core/modules/user/config/schema/user.schema.yml +++ b/core/modules/user/config/schema/user.schema.yml @@ -145,8 +145,12 @@ user.role.*: label: 'Default language' action.configuration.user_add_role_action: - type: action_configuration_default - label: 'Add a role to the selected users configuration' + type: mapping + label: 'Configuration for the add role action' + mapping: + rid: + type: string + label: 'The ID of the role to add' action.configuration.user_block_user_action: type: action_configuration_default @@ -158,14 +162,11 @@ action.configuration.user_cancel_user_action: action.configuration.user_remove_role_action: type: mapping - label: 'Remove a role from the selected users configuration' + label: 'Configuration for the remove role action' mapping: rid: - type: sequence - label: 'Roles' - sequence: - - type: sequence - label: 'Role' + type: string + label: 'The ID of the role to remove' action.configuration.user_unblock_user_action: type: action_configuration_default diff --git a/core/modules/user/lib/Drupal/user/Tests/UserActionConfigSchemaTest.php b/core/modules/user/lib/Drupal/user/Tests/UserActionConfigSchemaTest.php new file mode 100644 index 0000000..3e616d5 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/Tests/UserActionConfigSchemaTest.php @@ -0,0 +1,56 @@ + 'User action config schema', + 'description' => 'Ensures the user action for adding and removing roles have valid config schema.', + 'group' => 'User', + ); + } + + /** + * Tests whether the user action config schema are valid. + */ + function testValidUserActionConfigSchema() { + $rid = $this->drupalCreateRole(array()); + + // Test user_add_role_action configuration. + $config = \Drupal::config('system.action.user_add_role_action.' . $rid); + $this->assertEqual($config->get('id'), 'user_add_role_action.' . $rid); + $this->assertConfigSchema(\Drupal::service('config.typed'), $config->getName(), $config->get()); + + // Test user_remove_role_action configuration. + $config = \Drupal::config('system.action.user_remove_role_action.' . $rid); + $this->assertEqual($config->get('id'), 'user_remove_role_action.' . $rid); + $this->assertConfigSchema(\Drupal::service('config.typed'), $config->getName(), $config->get()); + } + +}