@@ -435,44 +435,82 @@ public function testCanGetValidationMessages()
435
435
}
436
436
}
437
437
438
- /**
439
- * Idea for this one is that one input may only need to be validated if another input is present.
440
- *
441
- * Commenting out for now, as validation context may make this irrelevant, and unsure what API to expose.
442
- 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 ()
443
444
{
444
- $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
+ ];
445
455
}
446
- */
447
456
448
457
/**
449
- * Idea for this one is that validation may need to rely on context -- e.g., a "password confirmation"
450
- * field may need to know what the original password entered was in order to compare.
458
+ * @dataProvider contextProvider
451
459
*/
452
- public function testValidationCanUseContext ( )
460
+ public function testValidationContext ( $ data , $ customContext , $ expectedContext )
453
461
{
454
462
$ filter = new InputFilter ();
455
463
456
- $ store = new stdClass ;
457
- $ foo = new Input ();
458
- $ foo ->getValidatorChain ()->attach (new Validator \Callback (function ($ value , $ context ) use ($ store ) {
459
- $ store ->value = $ value ;
460
- $ store ->context = $ context ;
461
- return true ;
462
- }));
464
+ $ input = $ this ->createInputInterfaceMock (true , true , $ expectedContext );
465
+ $ filter ->add ($ input , 'fooInput ' );
463
466
464
- $ bar = new Input ();
465
- $ bar ->getValidatorChain ()->attach (new Validator \Digits ());
467
+ $ filter ->setData ($ data );
466
468
467
- $ filter ->add ($ foo , 'foo ' )
468
- ->add ($ bar , 'bar ' );
469
+ $ this ->assertTrue (
470
+ $ filter ->isValid ($ customContext ),
471
+ 'isValid() value not match. Detail: ' . json_encode ($ filter ->getMessages ())
472
+ );
473
+ }
474
+
475
+ public function testBuildValidationContextUsingInputGetRawValue ()
476
+ {
477
+ $ data = [];
478
+ $ expectedContext = ['fooInput ' => 'fooRawValue ' ];
479
+ $ filter = new InputFilter ();
480
+
481
+ $ input = $ this ->createInputInterfaceMock (true , true , $ expectedContext , 'fooRawValue ' );
482
+ $ filter ->add ($ input , 'fooInput ' );
469
483
470
- $ data = ['foo ' => 'foo ' , 'bar ' => 123 ];
471
484
$ filter ->setData ($ data );
472
485
473
- $ this ->assertTrue ($ filter ->isValid ());
474
- $ this ->assertEquals ('foo ' , $ store ->value );
475
- $ this ->assertEquals ($ data , $ store ->context );
486
+ $ this ->assertTrue (
487
+ $ filter ->isValid (),
488
+ 'isValid() value not match. Detail: ' . json_encode ($ filter ->getMessages ())
489
+ );
490
+ }
491
+
492
+ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsMissing ()
493
+ {
494
+ $ data = [
495
+ 'inputRequired ' => 'inputRequiredValue ' ,
496
+ ];
497
+ $ expectedContext = [
498
+ 'inputRequired ' => 'inputRequiredValue ' ,
499
+ 'inputOptional ' => null ,
500
+ ];
501
+ $ inputRequired = $ this ->createInputInterfaceMock (true , true , $ expectedContext );
502
+ $ inputOptional = $ this ->createInputInterfaceMock (false );
503
+
504
+ $ filter = new InputFilter ();
505
+ $ filter ->add ($ inputRequired , 'inputRequired ' );
506
+ $ filter ->add ($ inputOptional , 'inputOptional ' );
507
+
508
+ $ filter ->setData ($ data );
509
+
510
+ $ this ->assertTrue (
511
+ $ filter ->isValid (),
512
+ 'isValid() value not match. Detail: ' . json_encode ($ filter ->getMessages ())
513
+ );
476
514
}
477
515
478
516
/**
@@ -640,48 +678,6 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa
640
678
$ this ->assertFalse ($ filter ->isValid ());
641
679
}
642
680
643
- public static function contextDataProvider ()
644
- {
645
- return [
646
- ['' , 'y ' , true ],
647
- ['' , 'n ' , false ],
648
- ];
649
- }
650
-
651
- /**
652
- * Idea here is that an empty field may or may not be valid based on
653
- * context.
654
- */
655
- /**
656
- * @dataProvider contextDataProvider()
657
- */
658
- // @codingStandardsIgnoreStart
659
- public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField ($ allowEmpty , $ blankIsValid , $ valid )
660
- {
661
- // @codingStandardsIgnoreEnd
662
- $ filter = new InputFilter ();
663
-
664
- $ data = [
665
- 'allowEmpty ' => $ allowEmpty ,
666
- 'blankIsValid ' => $ blankIsValid ,
667
- ];
668
-
669
- $ allowEmpty = new Input ();
670
- $ allowEmpty ->setAllowEmpty (true )
671
- ->setContinueIfEmpty (true );
672
-
673
- $ blankIsValid = new Input ();
674
- $ blankIsValid ->getValidatorChain ()->attach (new Validator \Callback (function ($ value , $ context ) {
675
- return ('y ' === $ value && empty ($ context ['allowEmpty ' ]));
676
- }));
677
-
678
- $ filter ->add ($ allowEmpty , 'allowEmpty ' )
679
- ->add ($ blankIsValid , 'blankIsValid ' );
680
- $ filter ->setData ($ data );
681
-
682
- $ this ->assertSame ($ valid , $ filter ->isValid ());
683
- }
684
-
685
681
public function testCanRetrieveRawValuesIndividuallyWithoutValidating ()
686
682
{
687
683
if (!extension_loaded ('intl ' )) {
@@ -1051,4 +1047,36 @@ public function testAllowsValidatingArrayAccessData()
1051
1047
$ filter ->setData ($ data );
1052
1048
$ this ->assertTrue ($ filter ->isValid ());
1053
1049
}
1050
+
1051
+ /**
1052
+ * @param null|bool $isValid
1053
+ * @param mixed $expectedContext
1054
+ * @param mixed $getRawValue
1055
+ *
1056
+ * @return MockObject|InputInterface
1057
+ */
1058
+ protected function createInputInterfaceMock ($ isRequired , $ isValid = null , $ expectedContext = 'not-set ' , $ getRawValue = 'not-set ' )
1059
+ {
1060
+ /** @var InputInterface|MockObject $input */
1061
+ $ input = $ this ->getMock (InputInterface::class);
1062
+ $ input ->method ('isRequired ' )
1063
+ ->willReturn ($ isRequired )
1064
+ ;
1065
+ if ($ getRawValue !== 'not-set ' ) {
1066
+ $ input ->method ('getRawValue ' )
1067
+ ->willReturn ($ getRawValue )
1068
+ ;
1069
+ }
1070
+ if ($ isValid !== null ) {
1071
+ $ mockMethod = $ input ->expects ($ this ->once ())
1072
+ ->method ('isValid ' )
1073
+ ->willReturn ($ isValid )
1074
+ ;
1075
+ if ($ expectedContext !== 'not-set ' ) {
1076
+ $ mockMethod ->with ($ expectedContext );
1077
+ }
1078
+ }
1079
+
1080
+ return $ input ;
1081
+ }
1054
1082
}
0 commit comments