GraphWalkerTest.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <?php
  2. namespace Symfony\Tests\Component\Validator;
  3. require_once __DIR__.'/Fixtures/Entity.php';
  4. require_once __DIR__.'/Fixtures/Reference.php';
  5. require_once __DIR__.'/Fixtures/ConstraintA.php';
  6. require_once __DIR__.'/Fixtures/ConstraintAValidator.php';
  7. require_once __DIR__.'/Fixtures/FailingConstraint.php';
  8. require_once __DIR__.'/Fixtures/FailingConstraintValidator.php';
  9. require_once __DIR__.'/Fixtures/FakeClassMetadataFactory.php';
  10. use Symfony\Tests\Component\Validator\Fixtures\Entity;
  11. use Symfony\Tests\Component\Validator\Fixtures\Reference;
  12. use Symfony\Tests\Component\Validator\Fixtures\FakeClassMetadataFactory;
  13. use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
  14. use Symfony\Tests\Component\Validator\Fixtures\FailingConstraint;
  15. use Symfony\Component\Validator\GraphWalker;
  16. use Symfony\Component\Validator\ConstraintViolation;
  17. use Symfony\Component\Validator\ConstraintViolationList;
  18. use Symfony\Component\Validator\ConstraintValidatorFactory;
  19. use Symfony\Component\Validator\Mapping\ClassMetadata;
  20. use Symfony\Component\Validator\Constraints\Valid;
  21. class GraphWalkerTest extends \PHPUnit_Framework_TestCase
  22. {
  23. const CLASSNAME = 'Symfony\Tests\Component\Validator\Fixtures\Entity';
  24. protected $factory;
  25. protected $walker;
  26. protected $metadata;
  27. public function setUp()
  28. {
  29. $this->factory = new FakeClassMetadataFactory();
  30. $this->walker = new GraphWalker('Root', $this->factory, new ConstraintValidatorFactory());
  31. $this->metadata = new ClassMetadata(self::CLASSNAME);
  32. }
  33. public function testWalkClassValidatesConstraints()
  34. {
  35. $this->metadata->addConstraint(new ConstraintA());
  36. $this->walker->walkClass($this->metadata, new Entity(), 'Default', '');
  37. $this->assertEquals(1, count($this->walker->getViolations()));
  38. }
  39. public function testWalkClassValidatesPropertyConstraints()
  40. {
  41. $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
  42. $this->walker->walkClass($this->metadata, new Entity(), 'Default', '');
  43. $this->assertEquals(1, count($this->walker->getViolations()));
  44. }
  45. public function testWalkClassValidatesGetterConstraints()
  46. {
  47. $this->metadata->addGetterConstraint('lastName', new ConstraintA());
  48. $this->walker->walkClass($this->metadata, new Entity(), 'Default', '');
  49. $this->assertEquals(1, count($this->walker->getViolations()));
  50. }
  51. public function testWalkClassInDefaultGroupTraversesGroupSequence()
  52. {
  53. $entity = new Entity();
  54. $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
  55. 'groups' => 'First',
  56. )));
  57. $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
  58. 'groups' => 'Default',
  59. )));
  60. $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
  61. $this->walker->walkClass($this->metadata, $entity, 'Default', '');
  62. // After validation of group "First" failed, no more group was
  63. // validated
  64. $violations = new ConstraintViolationList();
  65. $violations->add(new ConstraintViolation(
  66. '',
  67. array(),
  68. 'Root',
  69. 'firstName',
  70. ''
  71. ));
  72. $this->assertEquals($violations, $this->walker->getViolations());
  73. }
  74. public function testWalkClassInGroupSequencePropagatesDefaultGroup()
  75. {
  76. $entity = new Entity();
  77. $entity->reference = new Reference();
  78. $this->metadata->addPropertyConstraint('reference', new Valid());
  79. $this->metadata->setGroupSequence(array($this->metadata->getDefaultGroup()));
  80. $referenceMetadata = new ClassMetadata(get_class($entity->reference));
  81. $referenceMetadata->addConstraint(new FailingConstraint(array(
  82. // this constraint is only evaluated if group "Default" is
  83. // propagated to the reference
  84. 'groups' => 'Default',
  85. )));
  86. $this->factory->addClassMetadata($referenceMetadata);
  87. $this->walker->walkClass($this->metadata, $entity, 'Default', '');
  88. // The validation of the reference's FailingConstraint in group
  89. // "Default" was launched
  90. $violations = new ConstraintViolationList();
  91. $violations->add(new ConstraintViolation(
  92. '',
  93. array(),
  94. 'Root',
  95. 'reference',
  96. $entity->reference
  97. ));
  98. $this->assertEquals($violations, $this->walker->getViolations());
  99. }
  100. public function testWalkClassInOtherGroupTraversesNoGroupSequence()
  101. {
  102. $entity = new Entity();
  103. $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
  104. 'groups' => 'First',
  105. )));
  106. $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
  107. 'groups' => $this->metadata->getDefaultGroup(),
  108. )));
  109. $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
  110. $this->walker->walkClass($this->metadata, $entity, $this->metadata->getDefaultGroup(), '');
  111. // Only group "Second" was validated
  112. $violations = new ConstraintViolationList();
  113. $violations->add(new ConstraintViolation(
  114. '',
  115. array(),
  116. 'Root',
  117. 'lastName',
  118. ''
  119. ));
  120. $this->assertEquals($violations, $this->walker->getViolations());
  121. }
  122. public function testWalkPropertyValueValidatesConstraints()
  123. {
  124. $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
  125. $this->walker->walkPropertyValue($this->metadata, 'firstName', 'value', 'Default', '');
  126. $this->assertEquals(1, count($this->walker->getViolations()));
  127. }
  128. public function testWalkCascadedPropertyValidatesReferences()
  129. {
  130. $entity = new Entity();
  131. $entityMetadata = new ClassMetadata(get_class($entity));
  132. $this->factory->addClassMetadata($entityMetadata);
  133. // add a constraint for the entity that always fails
  134. $entityMetadata->addConstraint(new FailingConstraint());
  135. // validate entity when validating the property "reference"
  136. $this->metadata->addPropertyConstraint('reference', new Valid());
  137. // invoke validation on an object
  138. $this->walker->walkPropertyValue(
  139. $this->metadata,
  140. 'reference',
  141. $entity, // object!
  142. 'Default',
  143. 'path'
  144. );
  145. $violations = new ConstraintViolationList();
  146. $violations->add(new ConstraintViolation(
  147. '',
  148. array(),
  149. 'Root',
  150. 'path',
  151. $entity
  152. ));
  153. $this->assertEquals($violations, $this->walker->getViolations());
  154. }
  155. public function testWalkCascadedPropertyValidatesArrays()
  156. {
  157. $entity = new Entity();
  158. $entityMetadata = new ClassMetadata(get_class($entity));
  159. $this->factory->addClassMetadata($entityMetadata);
  160. // add a constraint for the entity that always fails
  161. $entityMetadata->addConstraint(new FailingConstraint());
  162. // validate array when validating the property "reference"
  163. $this->metadata->addPropertyConstraint('reference', new Valid());
  164. $this->walker->walkPropertyValue(
  165. $this->metadata,
  166. 'reference',
  167. array('key' => $entity), // array!
  168. 'Default',
  169. 'path'
  170. );
  171. $violations = new ConstraintViolationList();
  172. $violations->add(new ConstraintViolation(
  173. '',
  174. array(),
  175. 'Root',
  176. 'path[key]',
  177. $entity
  178. ));
  179. $this->assertEquals($violations, $this->walker->getViolations());
  180. }
  181. public function testWalkCascadedPropertyDoesNotValidateNullValues()
  182. {
  183. $this->metadata->addPropertyConstraint('reference', new Valid());
  184. $this->walker->walkPropertyValue(
  185. $this->metadata,
  186. 'reference',
  187. null,
  188. 'Default',
  189. ''
  190. );
  191. $this->assertEquals(0, count($this->walker->getViolations()));
  192. }
  193. public function testWalkCascadedPropertyRequiresObjectOrArray()
  194. {
  195. $this->metadata->addPropertyConstraint('reference', new Valid());
  196. $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException');
  197. $this->walker->walkPropertyValue(
  198. $this->metadata,
  199. 'reference',
  200. 'no object',
  201. 'Default',
  202. ''
  203. );
  204. }
  205. public function testWalkConstraintBuildsAViolationIfFailed()
  206. {
  207. $constraint = new ConstraintA();
  208. $this->walker->walkConstraint($constraint, 'foobar', 'Default', 'firstName.path');
  209. $violations = new ConstraintViolationList();
  210. $violations->add(new ConstraintViolation(
  211. 'message',
  212. array('param' => 'value'),
  213. 'Root',
  214. 'firstName.path',
  215. 'foobar'
  216. ));
  217. $this->assertEquals($violations, $this->walker->getViolations());
  218. }
  219. public function testWalkConstraintBuildsNoViolationIfSuccessful()
  220. {
  221. $constraint = new ConstraintA();
  222. $this->walker->walkConstraint($constraint, 'VALID', 'Default', 'firstName.path');
  223. $this->assertEquals(0, count($this->walker->getViolations()));
  224. }
  225. }