diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 4297873e..be9e3d06 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -20,7 +20,7 @@ * @category Zend * @package Zend_InputFilter */ -class BaseInputFilter implements InputFilterInterface +class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInterface { protected $data; protected $inputs = array(); @@ -165,6 +165,11 @@ public function isValid() if (!array_key_exists($name, $this->data) || (null === $this->data[$name]) || (is_string($this->data[$name]) && strlen($this->data[$name]) === 0) + // Single and Multi File Uploads + || (is_array($this->data[$name]) + && isset($this->data[$name]['error']) && $this->data[$name]['error'] === UPLOAD_ERR_NO_FILE) + || (is_array($this->data[$name]) && count($this->data[$name]) === 1 + && isset($this->data[$name][0]['error']) && $this->data[$name][0]['error'] === UPLOAD_ERR_NO_FILE) ) { if ($input instanceof InputInterface) { // - test if input is required @@ -437,4 +442,59 @@ protected function populate() $input->setValue($value); } } + + /** + * Is the data set has unknown input ? + * + * @throws Exception\RuntimeException + * @return bool + */ + public function hasUnknown() + { + if (null === $this->data) { + throw new Exception\RuntimeException(sprintf( + '%s: no data present!', + __METHOD__ + )); + } + + $data = array_keys($this->data); + $inputs = array_keys($this->inputs); + $diff = array_diff($data, $inputs); + if (!empty($diff)) { + return count(array_intersect($diff, $inputs)) == 0; + } + + return false; + } + + /** + * Return the unknown input + * + * @throws Exception\RuntimeException + * @return array + */ + public function getUnknown() + { + if (null === $this->data) { + throw new Exception\RuntimeException(sprintf( + '%s: no data present!', + __METHOD__ + )); + } + + $data = array_keys($this->data); + $inputs = array_keys($this->inputs); + $diff = array_diff($data, $inputs); + + $unknownInputs = array(); + $intersect = array_intersect($diff, $data); + if (!empty($intersect)) { + foreach ($intersect as $key) { + $unknownInputs[$key] = $this->data[$key]; + } + } + + return $unknownInputs; + } } diff --git a/src/Factory.php b/src/Factory.php index f4d15cac..a5c81e42 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -287,7 +287,7 @@ protected function populateValidators(ValidatorChain $chain, $validators) { foreach ($validators as $validator) { if ($validator instanceof ValidatorInterface) { - $chain->addValidator($validator); + $chain->attach($validator); continue; } @@ -306,7 +306,7 @@ protected function populateValidators(ValidatorChain $chain, $validators) if (isset($validator['break_chain_on_failure'])) { $breakChainOnFailure = $validator['break_chain_on_failure']; } - $chain->addByName($name, $options, $breakChainOnFailure); + $chain->attachByName($name, $options, $breakChainOnFailure); continue; } diff --git a/src/FileInput.php b/src/FileInput.php new file mode 100644 index 00000000..50651b20 --- /dev/null +++ b/src/FileInput.php @@ -0,0 +1,157 @@ +autoPrependUploadValidator = $value; + return $this; + } + + /** + * @return boolean + */ + public function getAutoPrependUploadValidator() + { + return $this->autoPrependUploadValidator; + } + + /** + * @return mixed + */ + public function getValue() + { + $filter = $this->getFilterChain(); + $value = (is_array($this->value) && isset($this->value['tmp_name'])) + ? $this->value['tmp_name'] : $this->value; + if (is_scalar($value) && $this->isValid) { + // Single file input + $value = $filter->filter($value); + } elseif (is_array($value)) { + // Multi file input (multiple attribute set) + $newValue = array(); + foreach ($value as $multiFileData) { + $fileName = (is_array($multiFileData) && isset($multiFileData['tmp_name'])) + ? $multiFileData['tmp_name'] : $multiFileData; + $newValue[] = ($this->isValid) ? $filter->filter($fileName) : $fileName; + } + $value = $newValue; + } + return $value; + } + + /** + * @param mixed $context Extra "context" to provide the validator + * @return boolean + */ + public function isValid($context = null) + { + $this->injectUploadValidator(); + $validator = $this->getValidatorChain(); + //$value = $this->getValue(); // Do not run the filters yet for File uploads + + $rawValue = $this->getRawValue(); + if (!is_array($rawValue)) { + // This can happen in an AJAX POST, where the input comes across as a string + $rawValue = array( + 'tmp_name' => $rawValue, + 'name' => $rawValue, + 'size' => 0, + 'type' => '', + 'error' => UPLOAD_ERR_NO_FILE, + ); + } + if (is_array($rawValue) && isset($rawValue['tmp_name'])) { + // Single file input + $this->isValid = $validator->isValid($rawValue, $context); + } elseif (is_array($rawValue) && !empty($rawValue) && isset($rawValue[0]['tmp_name'])) { + // Multi file input (multiple attribute set) + $this->isValid = true; + foreach ($rawValue as $value) { + if (!$validator->isValid($value, $context)) { + $this->isValid = false; + break; // Do not continue processing files if validation fails + } + } + } + + return $this->isValid; + } + + /** + * @return void + */ + protected function injectUploadValidator() + { + if (!$this->autoPrependUploadValidator) { + return; + } + $chain = $this->getValidatorChain(); + + // Check if Upload validator is already first in chain + $validators = $chain->getValidators(); + if (isset($validators[0]['instance']) + && $validators[0]['instance'] instanceof UploadValidator + ) { + $this->autoPrependUploadValidator = false; + return; + } + + $chain->prependByName('fileupload', array(), true); + $this->autoPrependUploadValidator = false; + } + + /** + * No-op, NotEmpty validator does not apply for FileInputs. + * See also: BaseInputFilter::isValid() + * + * @return void + */ + protected function injectNotEmptyValidator() + { + $this->notEmptyValidator = true; + } + + /** + * @param InputInterface $input + * @return FileInput + */ + public function merge(InputInterface $input) + { + parent::merge($input); + if ($input instanceof FileInput) { + $this->setAutoPrependUploadValidator($input->getAutoPrependUploadValidator()); + } + return $this; + } +} diff --git a/src/Input.php b/src/Input.php index 4c93b45e..d890b764 100644 --- a/src/Input.php +++ b/src/Input.php @@ -308,6 +308,9 @@ public function getMessages() return $validator->getMessages(); } + /** + * @return void + */ protected function injectNotEmptyValidator() { if ((!$this->isRequired() && $this->allowEmpty()) || $this->notEmptyValidator) { diff --git a/src/InputFilterAwareTrait.php b/src/InputFilterAwareTrait.php new file mode 100644 index 00000000..4613eb05 --- /dev/null +++ b/src/InputFilterAwareTrait.php @@ -0,0 +1,48 @@ +inputFilter = $inputFilter; + + return $this; + } + + /** + * Retrieve input filter + * + * @return InputFilterInterface + */ + public function getInputFilter() + { + return $this->inputFilter; + } +} diff --git a/src/UnknownInputsCapableInterface.php b/src/UnknownInputsCapableInterface.php new file mode 100644 index 00000000..8e854000 --- /dev/null +++ b/src/UnknownInputsCapableInterface.php @@ -0,0 +1,24 @@ +getFilterChain()->attachByName('stringtrim') ->attachByName('alpha'); - $foo->getValidatorChain()->addValidator(new Validator\StringLength(3, 6)); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6)); $bar = new Input(); $bar->getFilterChain()->attachByName('stringtrim'); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $baz = new Input(); $baz->setRequired(false); $baz->getFilterChain()->attachByName('stringtrim'); - $baz->getValidatorChain()->addValidator(new Validator\StringLength(1, 6)); + $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); $filter->add($foo, 'foo') ->add($bar, 'bar') @@ -99,16 +100,16 @@ public function getChildInputFilter() $foo = new Input(); $foo->getFilterChain()->attachByName('stringtrim') ->attachByName('alpha'); - $foo->getValidatorChain()->addValidator(new Validator\StringLength(3, 6)); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6)); $bar = new Input(); $bar->getFilterChain()->attachByName('stringtrim'); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $baz = new Input(); $baz->setRequired(false); $baz->getFilterChain()->attachByName('stringtrim'); - $baz->getValidatorChain()->addValidator(new Validator\StringLength(1, 6)); + $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6)); $filter->add($foo, 'foo') ->add($bar, 'bar') @@ -342,14 +343,14 @@ public function testValidationCanUseContext() $store = new stdClass; $foo = new Input(); - $foo->getValidatorChain()->addValidator(new Validator\Callback(function ($value, $context) use ($store) { + $foo->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) use ($store) { $store->value = $value; $store->context = $context; return true; })); $bar = new Input(); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $filter->add($foo, 'foo') ->add($bar, 'bar'); @@ -372,14 +373,14 @@ public function testInputBreakOnFailureFlagIsHonoredWhenValidating() $store = new stdClass; $foo = new Input(); - $foo->getValidatorChain()->addValidator(new Validator\Callback(function ($value, $context) use ($store) { + $foo->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) use ($store) { $store->value = $value; $store->context = $context; return true; })); $bar = new Input(); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $bar->setBreakOnFailure(true); $filter->add($bar, 'bar') // adding bar first, as we want it to validate first and break the chain @@ -398,11 +399,11 @@ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() $filter = new InputFilter(); $foo = new Input(); - $foo->getValidatorChain()->addValidator(new Validator\StringLength(3, 5)); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5)); $foo->setRequired(false); $bar = new Input(); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $bar->setRequired(true); $filter->add($foo, 'foo') @@ -414,17 +415,70 @@ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() $this->assertTrue($filter->isValid()); } + public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoFileDataIsPresent() + { + $filter = new InputFilter(); + + $foo = new FileInput(); + $foo->getValidatorChain()->attach(new Validator\File\Upload()); + $foo->setRequired(false); + + $filter->add($foo, 'foo'); + + $data = array( + 'foo' => array( + 'tmp_name' => '/tmp/barfile', + 'name' => 'barfile', + 'type' => 'text', + 'size' => 0, + 'error' => 4, // UPLOAD_ERR_NO_FILE + ) + ); + $filter->setData($data); + $this->assertTrue($filter->isValid()); + + // Negative test + $foo->setRequired(true); + $filter->setData($data); + $this->assertFalse($filter->isValid()); + } + + public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoMultiFileDataIsPresent() + { + $filter = new InputFilter(); + $foo = new FileInput(); + $foo->setRequired(false); + $filter->add($foo, 'foo'); + + $data = array( + 'foo' => array(array( + 'tmp_name' => '/tmp/barfile', + 'name' => 'barfile', + 'type' => 'text', + 'size' => 0, + 'error' => 4, // UPLOAD_ERR_NO_FILE + )), + ); + $filter->setData($data); + $this->assertTrue($filter->isValid()); + + // Negative test + $foo->setRequired(true); + $filter->setData($data); + $this->assertFalse($filter->isValid()); + } + public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlagIsTrue() { $filter = new InputFilter(); $foo = new Input('foo'); - $foo->getValidatorChain()->addValidator(new Validator\StringLength(3, 5)); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5)); $foo->setRequired(true); $foo->setAllowEmpty(true); $bar = new Input(); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $bar->setRequired(true); $filter->add($foo, '') @@ -442,12 +496,12 @@ public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFa $filter = new InputFilter(); $foo = new Input(); - $foo->getValidatorChain()->addValidator(new Validator\StringLength(3, 5)); + $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5)); $foo->setRequired(true); $foo->setAllowEmpty(false); $bar = new Input(); - $bar->getValidatorChain()->addValidator(new Validator\Digits()); + $bar->getValidatorChain()->attach(new Validator\Digits()); $bar->setRequired(true); $filter->add($foo, '') @@ -509,4 +563,51 @@ public function testGetRequiredNotEmptyValidationMessages() $this->assertArrayHasKey('foo', $messages); $this->assertNotEmpty($messages['foo']); } + public function testHasUnknown() + { + $filter = $this->getInputFilter(); + $validData = array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '' + ); + $filter->setData($validData); + $this->assertFalse($filter->hasUnknown()); + + $filter = $this->getInputFilter(); + $invalidData = array( + 'bar' => '12345', + 'baz' => '', + 'gru' => '', + ); + $filter->setData($invalidData); + $this->assertTrue($filter->hasUnknown()); + } + public function testGetUknown() + { + $filter = $this->getInputFilter(); + $unknown = array( + 'bar' => '12345', + 'baz' => '', + 'gru' => 10, + 'test' => 'ok', + ); + $filter->setData($unknown); + $unknown = $filter->getUnknown(); + $this->assertEquals(2, count($unknown)); + $this->assertTrue(array_key_exists('gru', $unknown)); + $this->assertEquals(10, $unknown['gru']); + $this->assertTrue(array_key_exists('test', $unknown)); + $this->assertEquals('ok', $unknown['test']); + + $filter = $this->getInputFilter(); + $validData = array( + 'foo' => ' bazbat ', + 'bar' => '12345', + 'baz' => '' + ); + $filter->setData($validData); + $unknown = $filter->getUnknown(); + $this->assertEquals(0, count($unknown)); + } } diff --git a/test/FileInputTest.php b/test/FileInputTest.php new file mode 100644 index 00000000..23fea2fa --- /dev/null +++ b/test/FileInputTest.php @@ -0,0 +1,348 @@ +input = new FileInput('foo'); + // Upload validator does not work in CLI test environment, disable + $this->input->setAutoPrependUploadValidator(false); + } + + public function testConstructorRequiresAName() + { + $this->assertEquals('foo', $this->input->getName()); + } + + public function testInputHasEmptyFilterChainByDefault() + { + $filters = $this->input->getFilterChain(); + $this->assertInstanceOf('Zend\Filter\FilterChain', $filters); + $this->assertEquals(0, count($filters)); + } + + public function testInputHasEmptyValidatorChainByDefault() + { + $validators = $this->input->getValidatorChain(); + $this->assertInstanceOf('Zend\Validator\ValidatorChain', $validators); + $this->assertEquals(0, count($validators)); + } + + public function testCanInjectFilterChain() + { + $chain = new Filter\FilterChain(); + $this->input->setFilterChain($chain); + $this->assertSame($chain, $this->input->getFilterChain()); + } + + public function testCanInjectValidatorChain() + { + $chain = new Validator\ValidatorChain(); + $this->input->setValidatorChain($chain); + $this->assertSame($chain, $this->input->getValidatorChain()); + } + + public function testInputIsMarkedAsRequiredByDefault() + { + $this->assertTrue($this->input->isRequired()); + } + + public function testRequiredFlagIsMutable() + { + $this->input->setRequired(false); + $this->assertFalse($this->input->isRequired()); + } + + public function testInputDoesNotAllowEmptyValuesByDefault() + { + $this->assertFalse($this->input->allowEmpty()); + } + + public function testAllowEmptyFlagIsMutable() + { + $this->input->setAllowEmpty(true); + $this->assertTrue($this->input->allowEmpty()); + } + + public function testValueIsNullByDefault() + { + $this->assertNull($this->input->getValue()); + } + + public function testValueMayBeInjected() + { + $this->input->setValue(array('tmp_name' => 'bar')); + $this->assertEquals('bar', $this->input->getValue()); + } + + public function testRetrievingValueFiltersTheValueOnlyAfterValidating() + { + $this->input->setValue(array('tmp_name' => 'bar')); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals('bar', $this->input->getValue()); + $this->assertTrue($this->input->isValid()); + $this->assertEquals('BAR', $this->input->getValue()); + } + + public function testCanFilterArrayOfFileData() + { + $value = array('tmp_name' => 'foo'); + $this->input->setValue($value); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals('foo', $this->input->getValue()); + $this->assertTrue($this->input->isValid()); + $this->assertEquals('FOO', $this->input->getValue()); + } + + public function testCanFilterArrayOfMultiFileData() + { + $values = array( + array('tmp_name' => 'foo'), + array('tmp_name' => 'bar'), + array('tmp_name' => 'baz'), + ); + $this->input->setValue($values); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals(array('foo', 'bar', 'baz'), $this->input->getValue()); + $this->assertTrue($this->input->isValid()); + $this->assertEquals(array('FOO', 'BAR', 'BAZ'), $this->input->getValue()); + } + + public function testCanRetrieveRawValue() + { + $value = array('tmp_name' => 'bar'); + $this->input->setValue($value); + $filter = new Filter\StringToUpper(); + $this->input->getFilterChain()->attach($filter); + $this->assertEquals($value, $this->input->getRawValue()); + } + + public function testIsValidReturnsFalseIfValidationChainFails() + { + $this->input->setValue(array('tmp_name' => 'bar')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->assertFalse($this->input->isValid()); + } + + public function testIsValidReturnsTrueIfValidationChainSucceeds() + { + $this->input->setValue(array('tmp_name' => 'bar')); + $validator = new Validator\NotEmpty(); + $this->input->getValidatorChain()->attach($validator); + $this->assertTrue($this->input->isValid()); + } + + public function testValidationOperatesBeforeFiltering() + { + $this->input->setValue(array( + 'tmp_name' => ' ' . __FILE__ . ' ', + 'name' => 'foo', + 'size' => 1, + 'error' => 0, + )); + $filter = new Filter\StringTrim(); + $this->input->getFilterChain()->attach($filter); + $validator = new Validator\File\Exists(); + $this->input->getValidatorChain()->attach($validator); + $this->assertFalse($this->input->isValid()); + $this->input->setValue(array( + 'tmp_name' => __FILE__, + 'name' => 'foo', + 'size' => 1, + 'error' => 0, + )); + $this->assertTrue($this->input->isValid()); + } + + public function testGetMessagesReturnsValidationMessages() + { + $this->input->setAutoPrependUploadValidator(true); + $this->input->setValue(array( + 'tmp_name' => __FILE__, + 'name' => 'foo', + 'size' => 1, + 'error' => 0, + )); + $this->assertFalse($this->input->isValid()); + $messages = $this->input->getMessages(); + $this->assertArrayHasKey(Validator\File\Upload::ATTACK, $messages); + } + + public function testCanValidateArrayOfMultiFileData() + { + $values = array( + array( + 'tmp_name' => __FILE__, + 'name' => 'foo', + ), + array( + 'tmp_name' => __FILE__, + 'name' => 'bar', + ), + array( + 'tmp_name' => __FILE__, + 'name' => 'baz', + ), + ); + $this->input->setValue($values); + $validator = new Validator\File\Exists(); + $this->input->getValidatorChain()->attach($validator); + $this->assertTrue($this->input->isValid()); + + // Negative test + $values[1]['tmp_name'] = 'file-not-found'; + $this->input->setValue($values); + $this->assertFalse($this->input->isValid()); + } + + public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation() + { + $this->input->setValue(array('tmp_name' => 'bar')); + $validator = new Validator\Digits(); + $this->input->getValidatorChain()->attach($validator); + $this->input->setErrorMessage('Please enter only digits'); + $this->assertFalse($this->input->isValid()); + $messages = $this->input->getMessages(); + $this->assertArrayNotHasKey(Validator\Digits::NOT_DIGITS, $messages); + $this->assertContains('Please enter only digits', $messages); + } + + public function testBreakOnFailureFlagIsOffByDefault() + { + $this->assertFalse($this->input->breakOnFailure()); + } + + public function testBreakOnFailureFlagIsMutable() + { + $this->input->setBreakOnFailure(true); + $this->assertTrue($this->input->breakOnFailure()); + } + + public function testAutoPrependUploadValidatorIsOnByDefault() + { + $input = new FileInput('foo'); + $this->assertTrue($input->getAutoPrependUploadValidator()); + } + + public function testUploadValidatorIsAddedWhenIsValidIsCalled() + { + $this->input->setAutoPrependUploadValidator(true); + $this->assertTrue($this->input->getAutoPrependUploadValidator()); + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array( + 'tmp_name' => __FILE__, + 'name' => 'foo', + 'size' => 1, + 'error' => 0, + )); + $validatorChain = $this->input->getValidatorChain(); + $this->assertEquals(0, count($validatorChain->getValidators())); + + $this->assertFalse($this->input->isValid()); + $validators = $validatorChain->getValidators(); + $this->assertEquals(1, count($validators)); + $this->assertInstanceOf('Zend\Validator\File\Upload', $validators[0]['instance']); + } + + public function testUploadValidatorIsNotAddedWhenIsValidIsCalled() + { + $this->assertFalse($this->input->getAutoPrependUploadValidator()); + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array('tmp_name' => 'bar')); + $validatorChain = $this->input->getValidatorChain(); + $this->assertEquals(0, count($validatorChain->getValidators())); + + $this->assertTrue($this->input->isValid()); + $this->assertEquals(0, count($validatorChain->getValidators())); + } + + public function testRequiredUploadValidatorValidatorNotAddedWhenOneExists() + { + $this->input->setAutoPrependUploadValidator(true); + $this->assertTrue($this->input->getAutoPrependUploadValidator()); + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(array('tmp_name' => 'bar')); + + $uploadMock = $this->getMock('Zend\Validator\File\Upload', array('isValid')); + $uploadMock->expects($this->exactly(1)) + ->method('isValid') + ->will($this->returnValue(true)); + + $validatorChain = $this->input->getValidatorChain(); + $validatorChain->prependValidator($uploadMock); + $this->assertTrue($this->input->isValid()); + + $validators = $validatorChain->getValidators(); + $this->assertEquals(1, count($validators)); + $this->assertEquals($uploadMock, $validators[0]['instance']); + } + + public function testValidationsRunWithoutFileArrayDueToAjaxPost() + { + $this->input->setAutoPrependUploadValidator(true); + $this->assertTrue($this->input->getAutoPrependUploadValidator()); + $this->assertTrue($this->input->isRequired()); + $this->input->setValue(''); + + $uploadMock = $this->getMock('Zend\Validator\File\Upload', array('isValid')); + $uploadMock->expects($this->exactly(1)) + ->method('isValid') + ->will($this->returnValue(false)); + + $validatorChain = $this->input->getValidatorChain(); + $validatorChain->prependValidator($uploadMock); + $this->assertFalse($this->input->isValid()); + + $validators = $validatorChain->getValidators(); + $this->assertEquals(1, count($validators)); + $this->assertEquals($uploadMock, $validators[0]['instance']); + } + + public function testMerge() + { + $value = array('tmp_name' => 'bar'); + + $input = new FileInput('foo'); + $input->setAutoPrependUploadValidator(false); + $input->setValue($value); + $filter = new Filter\StringTrim(); + $input->getFilterChain()->attach($filter); + $validator = new Validator\Digits(); + $input->getValidatorChain()->attach($validator); + + $input2 = new FileInput('bar'); + $input2->merge($input); + $validatorChain = $input->getValidatorChain(); + $filterChain = $input->getFilterChain(); + + $this->assertFalse($input2->getAutoPrependUploadValidator()); + $this->assertEquals($value, $input2->getRawValue()); + $this->assertEquals(1, $validatorChain->count()); + $this->assertEquals(1, $filterChain->count()); + + $validators = $validatorChain->getValidators(); + $this->assertInstanceOf('Zend\Validator\Digits', $validators[0]['instance']); + + $filters = $filterChain->getFilters()->toArray(); + $this->assertInstanceOf('Zend\Filter\StringTrim', $filters[0]); + } +} diff --git a/test/InputFilterAwareTraitTest.php b/test/InputFilterAwareTraitTest.php new file mode 100644 index 00000000..aaa8c491 --- /dev/null +++ b/test/InputFilterAwareTraitTest.php @@ -0,0 +1,46 @@ +getObjectForTrait('\Zend\InputFilter\InputFilterAwareTrait'); + + $this->assertAttributeEquals(null, 'inputFilter', $object); + + $inputFilter = new InputFilter; + + $object->setInputFilter($inputFilter); + + $this->assertAttributeEquals($inputFilter, 'inputFilter', $object); + } + + public function testGetInputFilter() + { + $object = $this->getObjectForTrait('\Zend\InputFilter\InputFilterAwareTrait'); + + $this->assertNull($object->getInputFilter()); + + $inputFilter = new InputFilter; + + $object->setInputFilter($inputFilter); + + $this->assertEquals($inputFilter, $object->getInputFilter()); + } +} diff --git a/test/InputTest.php b/test/InputTest.php index 68416b4b..3b4e0c29 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -117,7 +117,7 @@ public function testIsValidReturnsFalseIfValidationChainFails() $input = new Input('foo'); $input->setValue('bar'); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $this->assertFalse($input->isValid()); } @@ -126,7 +126,7 @@ public function testIsValidReturnsTrueIfValidationChainSucceeds() $input = new Input('foo'); $input->setValue('123'); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $this->assertTrue($input->isValid()); } @@ -137,7 +137,7 @@ public function testValidationOperatesOnFilteredValue() $filter = new Filter\StringTrim(); $input->getFilterChain()->attach($filter); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $this->assertTrue($input->isValid()); } @@ -146,7 +146,7 @@ public function testGetMessagesReturnsValidationMessages() $input = new Input('foo'); $input->setValue('bar'); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $this->assertFalse($input->isValid()); $messages = $input->getMessages(); $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $messages); @@ -157,7 +157,7 @@ public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation() $input = new Input('foo'); $input->setValue('bar'); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $input->setErrorMessage('Please enter only digits'); $this->assertFalse($input->isValid()); $messages = $input->getMessages(); @@ -223,7 +223,7 @@ public function testMerge() $filter = new Filter\StringTrim(); $input->getFilterChain()->attach($filter); $validator = new Validator\Digits(); - $input->getValidatorChain()->addValidator($validator); + $input->getValidatorChain()->attach($validator); $input2 = new Input('bar'); $input2->merge($input);