CollectionValidatorTest.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Validator\Tests\Constraints;
  11. use Symfony\Component\Validator\Constraints\Collection;
  12. use Symfony\Component\Validator\Constraints\CollectionValidator;
  13. use Symfony\Component\Validator\Constraints\NotNull;
  14. use Symfony\Component\Validator\Constraints\Optional;
  15. use Symfony\Component\Validator\Constraints\Range;
  16. use Symfony\Component\Validator\Constraints\Required;
  17. use Symfony\Component\Validator\Validation;
  18. abstract class CollectionValidatorTest extends AbstractConstraintValidatorTest
  19. {
  20. protected function getApiVersion()
  21. {
  22. return Validation::API_VERSION_2_5;
  23. }
  24. protected function createValidator()
  25. {
  26. return new CollectionValidator();
  27. }
  28. abstract protected function prepareTestData(array $contents);
  29. public function testNullIsValid()
  30. {
  31. $this->validator->validate(null, new Collection(array('fields' => array(
  32. 'foo' => new Range(array('min' => 4)),
  33. ))));
  34. $this->assertNoViolation();
  35. }
  36. public function testFieldsAsDefaultOption()
  37. {
  38. $constraint = new Range(array('min' => 4));
  39. $data = $this->prepareTestData(array('foo' => 'foobar'));
  40. $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
  41. $this->validator->validate($data, new Collection(array(
  42. 'foo' => $constraint,
  43. )));
  44. $this->assertNoViolation();
  45. }
  46. /**
  47. * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
  48. */
  49. public function testThrowsExceptionIfNotTraversable()
  50. {
  51. $this->validator->validate('foobar', new Collection(array('fields' => array(
  52. 'foo' => new Range(array('min' => 4)),
  53. ))));
  54. }
  55. public function testWalkSingleConstraint()
  56. {
  57. $constraint = new Range(array('min' => 4));
  58. $array = array(
  59. 'foo' => 3,
  60. 'bar' => 5,
  61. );
  62. $i = 0;
  63. foreach ($array as $key => $value) {
  64. $this->expectValidateValueAt($i++, '['.$key.']', $value, array($constraint));
  65. }
  66. $data = $this->prepareTestData($array);
  67. $this->validator->validate($data, new Collection(array(
  68. 'fields' => array(
  69. 'foo' => $constraint,
  70. 'bar' => $constraint,
  71. ),
  72. )));
  73. $this->assertNoViolation();
  74. }
  75. public function testWalkMultipleConstraints()
  76. {
  77. $constraints = array(
  78. new Range(array('min' => 4)),
  79. new NotNull(),
  80. );
  81. $array = array(
  82. 'foo' => 3,
  83. 'bar' => 5,
  84. );
  85. $i = 0;
  86. foreach ($array as $key => $value) {
  87. $this->expectValidateValueAt($i++, '['.$key.']', $value, $constraints);
  88. }
  89. $data = $this->prepareTestData($array);
  90. $this->validator->validate($data, new Collection(array(
  91. 'fields' => array(
  92. 'foo' => $constraints,
  93. 'bar' => $constraints,
  94. ),
  95. )));
  96. $this->assertNoViolation();
  97. }
  98. public function testExtraFieldsDisallowed()
  99. {
  100. $constraint = new Range(array('min' => 4));
  101. $data = $this->prepareTestData(array(
  102. 'foo' => 5,
  103. 'baz' => 6,
  104. ));
  105. $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
  106. $this->validator->validate($data, new Collection(array(
  107. 'fields' => array(
  108. 'foo' => $constraint,
  109. ),
  110. 'extraFieldsMessage' => 'myMessage',
  111. )));
  112. $this->buildViolation('myMessage')
  113. ->setParameter('{{ field }}', '"baz"')
  114. ->atPath('property.path[baz]')
  115. ->setInvalidValue(6)
  116. ->setCode(Collection::NO_SUCH_FIELD_ERROR)
  117. ->assertRaised();
  118. }
  119. // bug fix
  120. public function testNullNotConsideredExtraField()
  121. {
  122. $data = $this->prepareTestData(array(
  123. 'foo' => null,
  124. ));
  125. $constraint = new Range(array('min' => 4));
  126. $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
  127. $this->validator->validate($data, new Collection(array(
  128. 'fields' => array(
  129. 'foo' => $constraint,
  130. ),
  131. )));
  132. $this->assertNoViolation();
  133. }
  134. public function testExtraFieldsAllowed()
  135. {
  136. $data = $this->prepareTestData(array(
  137. 'foo' => 5,
  138. 'bar' => 6,
  139. ));
  140. $constraint = new Range(array('min' => 4));
  141. $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
  142. $this->validator->validate($data, new Collection(array(
  143. 'fields' => array(
  144. 'foo' => $constraint,
  145. ),
  146. 'allowExtraFields' => true,
  147. )));
  148. $this->assertNoViolation();
  149. }
  150. public function testMissingFieldsDisallowed()
  151. {
  152. $data = $this->prepareTestData(array());
  153. $constraint = new Range(array('min' => 4));
  154. $this->validator->validate($data, new Collection(array(
  155. 'fields' => array(
  156. 'foo' => $constraint,
  157. ),
  158. 'missingFieldsMessage' => 'myMessage',
  159. )));
  160. $this->buildViolation('myMessage')
  161. ->setParameter('{{ field }}', '"foo"')
  162. ->atPath('property.path[foo]')
  163. ->setInvalidValue(null)
  164. ->setCode(Collection::MISSING_FIELD_ERROR)
  165. ->assertRaised();
  166. }
  167. public function testMissingFieldsAllowed()
  168. {
  169. $data = $this->prepareTestData(array());
  170. $constraint = new Range(array('min' => 4));
  171. $this->validator->validate($data, new Collection(array(
  172. 'fields' => array(
  173. 'foo' => $constraint,
  174. ),
  175. 'allowMissingFields' => true,
  176. )));
  177. $this->assertNoViolation();
  178. }
  179. public function testOptionalFieldPresent()
  180. {
  181. $data = $this->prepareTestData(array(
  182. 'foo' => null,
  183. ));
  184. $this->validator->validate($data, new Collection(array(
  185. 'foo' => new Optional(),
  186. )));
  187. $this->assertNoViolation();
  188. }
  189. public function testOptionalFieldNotPresent()
  190. {
  191. $data = $this->prepareTestData(array());
  192. $this->validator->validate($data, new Collection(array(
  193. 'foo' => new Optional(),
  194. )));
  195. $this->assertNoViolation();
  196. }
  197. public function testOptionalFieldSingleConstraint()
  198. {
  199. $array = array(
  200. 'foo' => 5,
  201. );
  202. $constraint = new Range(array('min' => 4));
  203. $this->expectValidateValueAt(0, '[foo]', $array['foo'], array($constraint));
  204. $data = $this->prepareTestData($array);
  205. $this->validator->validate($data, new Collection(array(
  206. 'foo' => new Optional($constraint),
  207. )));
  208. $this->assertNoViolation();
  209. }
  210. public function testOptionalFieldMultipleConstraints()
  211. {
  212. $array = array(
  213. 'foo' => 5,
  214. );
  215. $constraints = array(
  216. new NotNull(),
  217. new Range(array('min' => 4)),
  218. );
  219. $this->expectValidateValueAt(0, '[foo]', $array['foo'], $constraints);
  220. $data = $this->prepareTestData($array);
  221. $this->validator->validate($data, new Collection(array(
  222. 'foo' => new Optional($constraints),
  223. )));
  224. $this->assertNoViolation();
  225. }
  226. public function testRequiredFieldPresent()
  227. {
  228. $data = $this->prepareTestData(array(
  229. 'foo' => null,
  230. ));
  231. $this->validator->validate($data, new Collection(array(
  232. 'foo' => new Required(),
  233. )));
  234. $this->assertNoViolation();
  235. }
  236. public function testRequiredFieldNotPresent()
  237. {
  238. $data = $this->prepareTestData(array());
  239. $this->validator->validate($data, new Collection(array(
  240. 'fields' => array(
  241. 'foo' => new Required(),
  242. ),
  243. 'missingFieldsMessage' => 'myMessage',
  244. )));
  245. $this->buildViolation('myMessage')
  246. ->setParameter('{{ field }}', '"foo"')
  247. ->atPath('property.path[foo]')
  248. ->setInvalidValue(null)
  249. ->setCode(Collection::MISSING_FIELD_ERROR)
  250. ->assertRaised();
  251. }
  252. public function testRequiredFieldSingleConstraint()
  253. {
  254. $array = array(
  255. 'foo' => 5,
  256. );
  257. $constraint = new Range(array('min' => 4));
  258. $this->expectValidateValueAt(0, '[foo]', $array['foo'], array($constraint));
  259. $data = $this->prepareTestData($array);
  260. $this->validator->validate($data, new Collection(array(
  261. 'foo' => new Required($constraint),
  262. )));
  263. $this->assertNoViolation();
  264. }
  265. public function testRequiredFieldMultipleConstraints()
  266. {
  267. $array = array(
  268. 'foo' => 5,
  269. );
  270. $constraints = array(
  271. new NotNull(),
  272. new Range(array('min' => 4)),
  273. );
  274. $this->expectValidateValueAt(0, '[foo]', $array['foo'], $constraints);
  275. $data = $this->prepareTestData($array);
  276. $this->validator->validate($data, new Collection(array(
  277. 'foo' => new Required($constraints),
  278. )));
  279. $this->assertNoViolation();
  280. }
  281. public function testObjectShouldBeLeftUnchanged()
  282. {
  283. $value = new \ArrayObject(array(
  284. 'foo' => 3,
  285. ));
  286. $constraint = new Range(array('min' => 2));
  287. $this->expectValidateValueAt(0, '[foo]', $value['foo'], array($constraint));
  288. $this->validator->validate($value, new Collection(array(
  289. 'fields' => array(
  290. 'foo' => $constraint,
  291. ),
  292. )));
  293. $this->assertEquals(array(
  294. 'foo' => 3,
  295. ), (array) $value);
  296. }
  297. }