/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php

https://github.com/pulzarraider/symfony · PHP · 384 lines · 281 code · 91 blank · 12 comment · 0 complexity · 0ddffcceb50d8d8ad9523b0d6f5276f7 MD5 · raw file

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