Validation.php

<?php

namespace Phad\Test\Unit;

/**
 * @test validation of an array of values based upon a property schema array
 * @test validation of individual properties (no property schema array)
 *
 */
class Validation extends \Phad\Tester {

    public function testAllowsEmptyIfNotRequired(){

        $data = [
          'brief' => 'blah blah',
          'time_text' => '@ 5:30pm',
          'time_link_text' => '2nd Thursday',
          'calendar_url' => '',
          'location_name' => '',
          'address_text' => '',
          'office_id' => '1',
          'id' => '',
        ];
        $properties_spec = [
            'default' =>  [
                'status' => '200',
                'accessIndex' => '1',
                'tagName' => 'access',
            ],
            'brief' =>  [
                'maxlength' => '750',
                'tagName' => 'textarea',
            ],
            'time_text' =>  [
                'type' => 'text',
                'placeholder' => '@ 5:30pm',
                'tagName' => 'input',
            ],
            'time_link_text' =>  [
                'type' => 'text',
                'placeholder' => '1st & 3rd Mondays',
                'tagName' => 'input',
            ],
            'calendar_url' =>  [
                'type' => 'url',
                'tagName' => 'input',
            ],
            'location_name' =>  [
                'type' => 'text',
                'tagName' => 'input',
            ],
            'address_text' =>  [
                'tagName' => 'textarea',
            ],
            'office_id' =>  [
                'type' => 'hidden',
                'tagName' => 'input',
            ],
            'id' =>  [
                'type' => 'hidden',
                'tagName' => 'input',
            ],
        ];

        $validator = new \Phad\FormValidator($properties_spec);
        $is_valid = $validator->validate($data, $failed);

        $this->is_true($is_valid);
        $this->compare([], $failed);
    }

    public function testWithValidator(){

        $spec = [
            'validate' => 'is_election_id',
            'tagName' => 'select',
            'options' => ['<?=$Election->id?>'],
            'required' => ''
        ];
        $validator = new \Phad\FormValidator(['election_id'=>$spec]);

        $validator->validators['is_election_id'] = 
            function($value, $spec){
                // $is = is_numeric($value);
                // var_dump($is);
                // exit;
                return is_numeric($value);
            };

        $data = [
            'election_id'=>1,
        ];
        
        $valid = $validator->validate($data, $failed);

        $this->is_true($valid);
        $this->compare([], $failed);
    }

    /**
     * @test minlength property validation
     */
    public function testMinlength(){
        $submitter = new \Phad\FormValidator([]);

        $this->is_true(
            $submitter->validatePropMinLength(2, 'ok')
        );


        $this->is_false(
            $submitter->validatePropMinLength(3, 'ok')
        );
    }

    /**
     * test maxlength property validation
     */
    public function testMaxlength(){
        $submitter = new \Phad\FormValidator([]);

        $this->is_true(
            $submitter->validatePropMaxLength(2, 'ok')
        );


        $this->is_false(
            $submitter->validatePropMaxLength(2, 'okay')
        );
    }

    /**
     * @test validation of single property to show an example
     */
    public function testExample(){
        $properties =
        [
            'title' => 
                [
                'type' => 'text',
                'maxlength' => '75',
                'tagName' => 'input',
                ],
        ];


        $submitter = new \Phad\FormValidator($properties);

        $passes = $submitter->validate(
            ['title'=>'okay']
        );

        $this->compare(true, $passes);
    }

    /**
     * @test overall validation of text-data based upon simple properties schema
     */
    public function testValidation(){

        $properties =
        [
            'title' => 
                [
                'type' => 'text',
                'maxlength' => '75',
                'tagName' => 'input',
                ],
            'body' => 
                [
                'maxlength' => '2000',
                'minlength' => '50',
                'tagName' => 'textarea',
                ],
            'id' => 
                [
                'tagName' => 'input',
                'type' => 'hidden',
                ],
        ];


        $pass = [
            'bothPresent' => [
                'title'=>'Pay attention to local politics and policy.',
                'body'=>'Local politics and policy are much more accessible than state or federal. Like, in my home town, I can email my council members and they actually reply. The state and fed basically limit what the city is allowed to do, but the city mostly sets the laws that impact my day to day life, like zoning, police budget, and a whole slew of other stuff.'
            ],
            'titleMissing' => [
                'body'=> '12345abcd 12345abcd 12345abcd 12345abcd 12345abcd 12345abcd 12345abcd 12345abcd 12345abcd 12345abcd',
            ], 
            'bodyMissing' => [
                'title'=> 'Blah Blah',
            ]
        ];

        $fail = [
            'bodyTooShort'=>[
                'title'=>'This title is short enough.',
                'body'=> 'Not long enough.'
            ], 
            'titleTooLong'=>[
                'title'=>'Im a rambler. I go on and on about things that no one really cares about. But I care about it. Its important to me. So I dont know what to do with that! I just keep talking and talking.',
                'body'=>$pass['titleMissing']['body']
            ]
        ];

        $failErr = [
            'bodyTooShort'=>[
                'body'=>[
                    'failed_value'=>$fail['bodyTooShort']['body'],
                    'minlength'=>50,
                ],
            ],
            'titleTooLong'=>[
                'title'=>[
                    'failed_value'=>$fail['titleTooLong']['title'],
                    'maxlength'=>75,
                ],
            ]
        ];


        $submitter = new \Phad\FormValidator($properties);

        foreach ($pass as $testName=>$goodBlog){
            $this->test($testName.' is allowed');
                $this->compare(true, $submitter->validate($goodBlog));
        }

        foreach ($fail as $testName=>$badBlog){
            $this->test($testName.' is not allowed');
                $this->compare(false, $submitter->validate($badBlog, $messages, $columns));
                $this->compare($failErr[$testName], $columns);

        }

    }


    /**
     * @test individual attributes for validity
     */
    public function testAttributeValidation(){
        $toTest = [
            'required'=>[
                'pass'=>[
                    [true, 'something'],
                    [true, 1],
                    [true, 0],
                ], 
                'fail'=>[
                    [true, null],
                    [true, ''],
                ]
            ],
            'maxlength'=>[
                'pass'=>[
                    [3,'oka'],
                    [2,'op'],
                    [9001, 'over 9000'],
                    [0,''],
                    [1,1],
                    [10, 1345.001],
                    [0,false],
                    [0,null],
                    [1,true],
                    [6, 10.003],
                ],
                'fail'=>[
                    [0,true],
                    [3, 'longer than 3'],
                    [10, 'longer than 10 probably i hope'],
                    [5, 10.003],
                    [-1, '']
                ]
            ],
            'minlength'=>[
                'pass'=>[
                    [1,'k'],
                    [10,'okay okay okay'],
                    [5, 10.04],
                    [1, true],
                    [0, false],
                    [0, null],
                    [0,''],
                ],
                'fail'=>[
                    [1, false],
                    [1, null],
                    [1, ''],
                    [10,10.5],
                    [100, 'not enough'],
                ]
            ],
            'type'=>[
                'pass'=>[
                    ['text', ''],
                    ['text', 'abc'],


                    ['number', 0],
                    ['number', 1],
                    ['number', 13.5],
                    ['number', -1],
                    ['number', '1'],
                    ['number', '13.5'],
                    ['number', '-1'],
                ],
                'fail'=>[
                    ['text', null],
                    ['text', 123],
                    ['text', false],
                    ['text', true],


                    ['number', ''],
                    ['number', 'abc'],
                    ['number', false],
                    ['number', true],
                    ['number', null],
                ]
            ],
            'options'=>[
                'pass'=>[
                    [['cat', 'dog', 'bear'], 'bear'],
                ],
                'fail'=>[
                    [['cat', 'dog', 'bear'], 'salamander'],
                ]
            ],
        ];

        $validator = new \Phad\FormValidator([]);

        foreach ($toTest as $attributeName => $allTests){
            echo "\n\n\n///////////\nTesting '$attributeName'\n////////////";
            $pass = $allTests['pass'];
            $fail = $allTests['fail'];
            foreach ($pass as $index => $entry){
                list($attributeValue, $propertyValue) = $entry;
                $validationMethod = 'validateProp'.ucfirst($attributeName);
                $didPass = $validator->$validationMethod($attributeValue,$propertyValue);
                $this->handleDidPass($didPass);
                echo "  $attributeName: ".var_export($attributeValue,true);
                echo "\n  Prop Value: ".var_export($propertyValue,true);
                if ($didPass){
                    echo "\n    is valid (test passed)";
                } else {
                    echo "\n    is not valid (test failed)";
                }
            }
            echo "\n\n\n\\\\\\\\\\\\\\Testing invalid prop values for '$attributeName'";
            foreach ($fail as $entry){
                list($attributeValue, $propertyValue) = $entry;
                $validationMethod = 'validateProp'.ucfirst($attributeName);
                $didPass = $validator->$validationMethod($attributeValue,$propertyValue);
                /** because these should all FAIL validation  */
                $didPass = !$didPass; 
                $this->handleDidPass($didPass);
                echo "  $attributeName: ".var_export($attributeValue,true);
                echo "\n  Prop Value: ".var_export($propertyValue,true);
                if ($didPass){
                    echo "\n    is not valid (test passed)";
                } else {
                    echo "\n    is valid (test failed)";
                }
            }
        }
    }
}