|
10 | 10 | namespace ZendTest\InputFilter; |
11 | 11 |
|
12 | 12 | use ArrayObject; |
| 13 | +use PHPUnit_Framework_MockObject_MockObject as MockObject; |
13 | 14 | use PHPUnit_Framework_TestCase as TestCase; |
14 | 15 | use stdClass; |
15 | 16 | use Zend\InputFilter\Input; |
| 17 | +use Zend\InputFilter\InputInterface; |
16 | 18 | use Zend\InputFilter\FileInput; |
17 | 19 | use Zend\InputFilter\BaseInputFilter as InputFilter; |
18 | 20 | use Zend\Filter; |
@@ -433,44 +435,77 @@ public function testCanGetValidationMessages() |
433 | 435 | } |
434 | 436 | } |
435 | 437 |
|
436 | | - /** |
437 | | - * Idea for this one is that one input may only need to be validated if another input is present. |
438 | | - * |
439 | | - * Commenting out for now, as validation context may make this irrelevant, and unsure what API to expose. |
440 | | - public function testCanConditionallyInvokeValidators() |
| 438 | + /* |
| 439 | + * Idea for this one is that validation may need to rely on context -- e.g., a "password confirmation" |
| 440 | + * field may need to know what the original password entered was in order to compare. |
| 441 | + */ |
| 442 | + |
| 443 | + public function contextProvider() |
441 | 444 | { |
442 | | - $this->markTestIncomplete(); |
| 445 | + $data = ['fooInput' => 'fooValue']; |
| 446 | + $arrayAccessData = new ArrayObject(['fooInput' => 'fooValue']); |
| 447 | + $expectedFromData = ['fooInput' => 'fooValue']; |
| 448 | + |
| 449 | + return [ |
| 450 | + // Description => [$data, $customContext, $expectedContext] |
| 451 | + 'by default get context from data (array)' => [$data, null, $expectedFromData], |
| 452 | + 'by default get context from data (ArrayAccess)' => [$arrayAccessData, null, $expectedFromData], |
| 453 | + 'use custom context' => [[], 'fooContext', 'fooContext'], |
| 454 | + ]; |
443 | 455 | } |
444 | | - */ |
445 | 456 |
|
446 | 457 | /** |
447 | | - * Idea for this one is that validation may need to rely on context -- e.g., a "password confirmation" |
448 | | - * field may need to know what the original password entered was in order to compare. |
| 458 | + * @dataProvider contextProvider |
| 459 | + * |
| 460 | + * @param mixed $data |
| 461 | + * @param mixed $customContext |
| 462 | + * @param mixed $expectedContext |
449 | 463 | */ |
450 | | - public function testValidationCanUseContext() |
| 464 | + public function testValidationContext($data, $customContext, $expectedContext) |
451 | 465 | { |
452 | 466 | $filter = new InputFilter(); |
453 | 467 |
|
454 | | - $store = new stdClass; |
455 | | - $foo = new Input(); |
456 | | - $foo->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) use ($store) { |
457 | | - $store->value = $value; |
458 | | - $store->context = $context; |
459 | | - return true; |
460 | | - })); |
| 468 | + $input = $this->createInputInterfaceMock(true, $expectedContext); |
| 469 | + $filter->add($input, 'fooInput'); |
461 | 470 |
|
462 | | - $bar = new Input(); |
463 | | - $bar->getValidatorChain()->attach(new Validator\Digits()); |
| 471 | + $filter->setData($data); |
464 | 472 |
|
465 | | - $filter->add($foo, 'foo') |
466 | | - ->add($bar, 'bar'); |
| 473 | + $this->assertTrue($filter->isValid($customContext), json_encode($filter->getMessages())); |
| 474 | + } |
| 475 | + |
| 476 | + public function testBuildValidationContextUsingInputGetRawValue() |
| 477 | + { |
| 478 | + $data = []; |
| 479 | + $expectedContext = ['fooInput' => 'fooRawValue']; |
| 480 | + $filter = new InputFilter(); |
| 481 | + |
| 482 | + $input = $this->createInputInterfaceMock(true, $expectedContext, 'fooRawValue'); |
| 483 | + $filter->add($input, 'fooInput'); |
467 | 484 |
|
468 | | - $data = ['foo' => 'foo', 'bar' => 123]; |
469 | 485 | $filter->setData($data); |
470 | 486 |
|
471 | | - $this->assertTrue($filter->isValid()); |
472 | | - $this->assertEquals('foo', $store->value); |
473 | | - $this->assertEquals($data, $store->context); |
| 487 | + $this->assertTrue($filter->isValid(), json_encode($filter->getMessages())); |
| 488 | + } |
| 489 | + |
| 490 | + public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsMissing() |
| 491 | + { |
| 492 | + $data = [ |
| 493 | + 'inputRequired' => 'inputRequiredValue', |
| 494 | + ]; |
| 495 | + $expectedContext = [ |
| 496 | + 'inputRequired' => 'inputRequiredValue', |
| 497 | + 'inputOptional' => null, |
| 498 | + ]; |
| 499 | + $inputRequired = $this->createInputInterfaceMock(true, $expectedContext); |
| 500 | + $inputOptional = $this->createInputInterfaceMock(true, $expectedContext); |
| 501 | + |
| 502 | + $filter = new InputFilter(); |
| 503 | + $filter->add($inputRequired, 'inputRequired'); |
| 504 | + $filter->add($inputOptional, 'inputOptional'); |
| 505 | + |
| 506 | + $filter->setData($data); |
| 507 | + |
| 508 | + $this->assertTrue($filter->isValid(), json_encode($filter->getMessages())); |
474 | 509 | } |
475 | 510 |
|
476 | 511 | /** |
@@ -627,48 +662,6 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa |
627 | 662 | $this->assertFalse($filter->isValid()); |
628 | 663 | } |
629 | 664 |
|
630 | | - public static function contextDataProvider() |
631 | | - { |
632 | | - return [ |
633 | | - ['', 'y', true], |
634 | | - ['', 'n', false], |
635 | | - ]; |
636 | | - } |
637 | | - |
638 | | - /** |
639 | | - * Idea here is that an empty field may or may not be valid based on |
640 | | - * context. |
641 | | - */ |
642 | | - /** |
643 | | - * @dataProvider contextDataProvider() |
644 | | - */ |
645 | | - // @codingStandardsIgnoreStart |
646 | | - public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid) |
647 | | - { |
648 | | - // @codingStandardsIgnoreEnd |
649 | | - $filter = new InputFilter(); |
650 | | - |
651 | | - $data = [ |
652 | | - 'allowEmpty' => $allowEmpty, |
653 | | - 'blankIsValid' => $blankIsValid, |
654 | | - ]; |
655 | | - |
656 | | - $allowEmpty = new Input(); |
657 | | - $allowEmpty->setAllowEmpty(true) |
658 | | - ->setContinueIfEmpty(true); |
659 | | - |
660 | | - $blankIsValid = new Input(); |
661 | | - $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) { |
662 | | - return ('y' === $value && empty($context['allowEmpty'])); |
663 | | - })); |
664 | | - |
665 | | - $filter->add($allowEmpty, 'allowEmpty') |
666 | | - ->add($blankIsValid, 'blankIsValid'); |
667 | | - $filter->setData($data); |
668 | | - |
669 | | - $this->assertSame($valid, $filter->isValid()); |
670 | | - } |
671 | | - |
672 | 665 | public function testCanRetrieveRawValuesIndividuallyWithoutValidating() |
673 | 666 | { |
674 | 667 | if (!extension_loaded('intl')) { |
@@ -1114,4 +1107,33 @@ public function testAllowsValidatingArrayAccessData() |
1114 | 1107 | $filter->setData($data); |
1115 | 1108 | $this->assertTrue($filter->isValid()); |
1116 | 1109 | } |
| 1110 | + |
| 1111 | + /** |
| 1112 | + * @param null|bool $isValid |
| 1113 | + * @param mixed $expectedContext |
| 1114 | + * @param mixed $getRawValue |
| 1115 | + * |
| 1116 | + * @return MockObject|InputInterface |
| 1117 | + */ |
| 1118 | + protected function createInputInterfaceMock($isValid = null, $expectedContext = 'not-set', $getRawValue = 'not-set') |
| 1119 | + { |
| 1120 | + /** @var InputInterface|MockObject $input */ |
| 1121 | + $input = $this->getMock(InputInterface::class); |
| 1122 | + if ($getRawValue !== 'not-set') { |
| 1123 | + $input->method('getRawValue') |
| 1124 | + ->willReturn($getRawValue) |
| 1125 | + ; |
| 1126 | + } |
| 1127 | + if ($isValid !== null) { |
| 1128 | + $mockMethod = $input->expects($this->once()) |
| 1129 | + ->method('isValid') |
| 1130 | + ->willReturn($isValid) |
| 1131 | + ; |
| 1132 | + if ($expectedContext !== 'not-set') { |
| 1133 | + $mockMethod->with($expectedContext); |
| 1134 | + } |
| 1135 | + } |
| 1136 | + |
| 1137 | + return $input; |
| 1138 | + } |
1117 | 1139 | } |
0 commit comments