function ValidKeysConstraintValidatorTest::testValidation
Same name and namespace in other branches
- 11.x core/tests/Drupal/KernelTests/Core/TypedData/ValidKeysConstraintValidatorTest.php \Drupal\KernelTests\Core\TypedData\ValidKeysConstraintValidatorTest::testValidation()
Tests the ValidKeys constraint validator.
File
-
core/
tests/ Drupal/ KernelTests/ Core/ TypedData/ ValidKeysConstraintValidatorTest.php, line 232
Class
- ValidKeysConstraintValidatorTest
- Tests the ValidKeys validation constraint.
Namespace
Drupal\KernelTests\Core\TypedDataCode
public function testValidation() : void {
// Create a data definition that specifies certain allowed keys.
$definition = MapDataDefinition::create('mapping')->addConstraint('ValidKeys', [
'north',
'south',
'west',
]);
$definition['mapping'] = [
'north' => [
'type' => 'string',
'requiredKey' => FALSE,
],
'east' => [
'type' => 'string',
'requiredKey' => FALSE,
],
'south' => [
'type' => 'string',
'requiredKey' => FALSE,
],
'west' => [
'type' => 'string',
'requiredKey' => FALSE,
],
];
// @todo Remove this line in https://www.drupal.org/project/drupal/issues/3403782
$definition->setClass('Drupal\\Core\\Config\\Schema\\Mapping');
/** @var \Drupal\Core\TypedData\TypedDataManagerInterface $typed_config */
$typed_config = $this->container
->get('config.typed');
// @see \Drupal\Core\Config\TypedConfigManager::buildDataDefinition()
// @see \Drupal\Core\TypedData\TypedDataManager::createDataDefinition()
$definition->setTypedDataManager($typed_config);
// Passing a non-array value should raise an exception.
try {
// TRICKY: we must clone the definition because the instance is modified
// when processing.
// @see \Drupal\Core\Config\Schema\Mapping::processRequiredKeyFlags()
$typed_config->create(clone $definition, 2501)
->validate();
$this->fail('Expected an exception but none was raised.');
} catch (UnexpectedTypeException $e) {
$this->assertSame('Expected argument of type "array", "int" given', $e->getMessage());
}
// Empty arrays are valid.
$this->assertCount(0, $typed_config->create(clone $definition, [])
->validate());
// Indexed arrays are never valid.
$violations = $typed_config->create(clone $definition, [
'north',
'south',
])
->validate();
$this->assertCount(1, $violations);
$this->assertSame('Numerically indexed arrays are not allowed.', (string) $violations->get(0)
->getMessage());
// Arrays with automatically assigned keys, AND a valid key, should be
// considered invalid overall.
$violations = $typed_config->create(clone $definition, [
'north',
'south' => 'west',
])
->validate();
$this->assertCount(1, $violations);
$this->assertSame("'0' is not a supported key.", (string) $violations->get(0)
->getMessage());
// Associative arrays with an invalid key should be invalid.
$violations = $typed_config->create(clone $definition, [
'north' => 'south',
'east' => 'west',
])
->validate();
$this->assertCount(1, $violations);
$this->assertSame("'east' is not a supported key.", (string) $violations->get(0)
->getMessage());
// If the array only contains the allowed keys, it's fine.
$value = [
'north' => 'Boston',
'south' => 'Atlanta',
'west' => 'San Francisco',
];
$violations = $typed_config->create(clone $definition, $value)
->validate();
$this->assertCount(0, $violations);
// If, in the mapping definition, some keys do NOT have
// `requiredKey: false` set, then they MUST be set. In other
// words, all keys are required unless they individually
// specify otherwise.
// First test without changing the value: no error should occur because all
// keys passed to the ValidKeys constraint have a value.
unset($definition['mapping']['south']['requiredKey']);
unset($definition['mapping']['east']['requiredKey']);
$violations = $typed_config->create(clone $definition, $value)
->validate();
$this->assertCount(0, $violations);
// If in the mapping definition some keys that do NOT have
// `requiredKey: false` set, then they MUST be set.
// First test without changing the value: no error should occur because all
// keys passed to the ValidKeys constraint have a value.
unset($definition['mapping']['south']['requiredKey']);
unset($definition['mapping']['east']['requiredKey']);
$violations = $typed_config->create(clone $definition, $value)
->validate();
$this->assertCount(0, $violations);
// Then remove the required key-value pair: this must trigger an error, but
// only if the root type has opted in.
unset($value['south']);
$violations = $typed_config->create(clone $definition, $value)
->validate();
$this->assertCount(0, $violations);
$definition->addConstraint('FullyValidatable', NULL);
$violations = $typed_config->create(clone $definition, $value)
->validate();
$this->assertCount(1, $violations);
$this->assertSame("'south' is a required key.", (string) $violations->get(0)
->getMessage());
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.