TypedConfigTest.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. namespace Drupal\KernelTests\Config;
  3. use Drupal\Core\Config\Schema\SequenceDataDefinition;
  4. use Drupal\Core\Config\Schema\TypedConfigInterface;
  5. use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
  6. use Drupal\Core\TypedData\ComplexDataInterface;
  7. use Drupal\Core\TypedData\Type\IntegerInterface;
  8. use Drupal\Core\TypedData\Type\StringInterface;
  9. use Drupal\KernelTests\KernelTestBase;
  10. use Symfony\Component\Validator\ConstraintViolationListInterface;
  11. /**
  12. * Tests config validation mechanism.
  13. *
  14. * @group Config
  15. */
  16. class TypedConfigTest extends KernelTestBase {
  17. /**
  18. * {@inheritdoc}
  19. */
  20. public static $modules = ['config_test'];
  21. /**
  22. * {@inheritdoc}
  23. */
  24. protected function setUp() {
  25. parent::setUp();
  26. $this->installConfig('config_test');
  27. }
  28. /**
  29. * Verifies that the Typed Data API is implemented correctly.
  30. */
  31. public function testTypedDataAPI() {
  32. /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
  33. $typed_config_manager = \Drupal::service('config.typed');
  34. /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
  35. $typed_config = $typed_config_manager->get('config_test.validation');
  36. // Test a primitive.
  37. $string_data = $typed_config->get('llama');
  38. $this->assertInstanceOf(StringInterface::class, $string_data);
  39. $this->assertEquals('llama', $string_data->getValue());
  40. // Test complex data.
  41. $mapping = $typed_config->get('cat');
  42. /** @var \Drupal\Core\TypedData\ComplexDataInterface $mapping */
  43. $this->assertInstanceOf(ComplexDataInterface::class, $mapping);
  44. $this->assertInstanceOf(StringInterface::class, $mapping->get('type'));
  45. $this->assertEquals('kitten', $mapping->get('type')->getValue());
  46. $this->assertInstanceOf(IntegerInterface::class, $mapping->get('count'));
  47. $this->assertEquals(2, $mapping->get('count')->getValue());
  48. // Verify the item metadata is available.
  49. $this->assertInstanceOf(ComplexDataDefinitionInterface::class, $mapping->getDataDefinition());
  50. $this->assertArrayHasKey('type', $mapping->getProperties());
  51. $this->assertArrayHasKey('count', $mapping->getProperties());
  52. // Test accessing sequences.
  53. $sequence = $typed_config->get('giraffe');
  54. /** @var \Drupal\Core\TypedData\ListInterface $sequence */
  55. $this->assertInstanceOf(ComplexDataInterface::class, $sequence);
  56. $this->assertInstanceOf(StringInterface::class, $sequence->get('hum1'));
  57. $this->assertEquals('hum1', $sequence->get('hum1')->getValue());
  58. $this->assertEquals('hum2', $sequence->get('hum2')->getValue());
  59. $this->assertCount(2, $sequence->getIterator());
  60. // Verify the item metadata is available.
  61. $this->assertInstanceOf(SequenceDataDefinition::class, $sequence->getDataDefinition());
  62. // Test accessing typed config objects for simple config and config
  63. // entities.
  64. $typed_config_manager = \Drupal::service('config.typed');
  65. $typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get());
  66. $this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
  67. $this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements()));
  68. $config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
  69. 'id' => 'asterix',
  70. 'label' => 'Asterix',
  71. 'weight' => 11,
  72. 'style' => 'test_style',
  73. ]);
  74. $typed_config = $typed_config_manager->createFromNameAndData($config_test_entity->getConfigDependencyName(), $config_test_entity->toArray());
  75. $this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
  76. $this->assertEquals(['uuid', 'langcode', 'status', 'dependencies', 'id', 'label', 'weight', 'style', 'size', 'size_value', 'protected_property'], array_keys($typed_config->getElements()));
  77. }
  78. /**
  79. * Tests config validation via the Typed Data API.
  80. */
  81. public function testSimpleConfigValidation() {
  82. $config = \Drupal::configFactory()->getEditable('config_test.validation');
  83. /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
  84. $typed_config_manager = \Drupal::service('config.typed');
  85. /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
  86. $typed_config = $typed_config_manager->get('config_test.validation');
  87. $result = $typed_config->validate();
  88. $this->assertInstanceOf(ConstraintViolationListInterface::class, $result);
  89. $this->assertEmpty($result);
  90. // Test constraints on primitive types.
  91. $config->set('llama', 'elephant');
  92. $config->save();
  93. $typed_config = $typed_config_manager->get('config_test.validation');
  94. $result = $typed_config->validate();
  95. // Its not a valid llama anymore.
  96. $this->assertCount(1, $result);
  97. $this->assertEquals('no valid llama', $result->get(0)->getMessage());
  98. // Test constraints on mapping.
  99. $config->set('llama', 'llama');
  100. $config->set('cat.type', 'nyans');
  101. $config->save();
  102. $typed_config = $typed_config_manager->get('config_test.validation');
  103. $result = $typed_config->validate();
  104. $this->assertEmpty($result);
  105. // Test constrains on nested mapping.
  106. $config->set('cat.type', 'miaus');
  107. $config->save();
  108. $typed_config = $typed_config_manager->get('config_test.validation');
  109. $result = $typed_config->validate();
  110. $this->assertCount(1, $result);
  111. $this->assertEquals('no valid cat', $result->get(0)->getMessage());
  112. // Test constrains on sequences elements.
  113. $config->set('cat.type', 'nyans');
  114. $config->set('giraffe', ['muh', 'hum2']);
  115. $config->save();
  116. $typed_config = $typed_config_manager->get('config_test.validation');
  117. $result = $typed_config->validate();
  118. $this->assertCount(1, $result);
  119. $this->assertEquals('Giraffes just hum', $result->get(0)->getMessage());
  120. // Test constrains on the sequence itself.
  121. $config->set('giraffe', ['hum', 'hum2', 'invalid-key' => 'hum']);
  122. $config->save();
  123. $typed_config = $typed_config_manager->get('config_test.validation');
  124. $result = $typed_config->validate();
  125. $this->assertCount(1, $result);
  126. $this->assertEquals('giraffe', $result->get(0)->getPropertyPath());
  127. $this->assertEquals('Invalid giraffe key.', $result->get(0)->getMessage());
  128. // Validates mapping.
  129. $typed_config = $typed_config_manager->get('config_test.validation');
  130. $value = $typed_config->getValue();
  131. unset($value['giraffe']);
  132. $value['elephant'] = 'foo';
  133. $value['zebra'] = 'foo';
  134. $typed_config->setValue($value);
  135. $result = $typed_config->validate();
  136. $this->assertCount(1, $result);
  137. $this->assertEquals('', $result->get(0)->getPropertyPath());
  138. $this->assertEquals('Unexpected keys: elephant, zebra', $result->get(0)->getMessage());
  139. }
  140. }